Skip to content

Commit

Permalink
Revise spell and ranged accuracy
Browse files Browse the repository at this point in the history
  • Loading branch information
kphoenix137 committed Feb 27, 2024
1 parent 8010b90 commit fc9393a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 33 deletions.
52 changes: 32 additions & 20 deletions Source/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,23 @@ bool DoAttack(Player &player)

bool DoRangeAttack(Player &player)
{
WorldTilePosition dst = player.position.temp;

if (player.isOnArenaLevel() && player.AnimInfo.currentFrame == player._pAFNum - 6) {
// PVP REBALANCE: Obtain target position 6 frames before the action frame to ensure same accuracy regardless of ranged speed.
// 6 frames should ensure the accuracy of shooting a bow for all classes is similar to that of Rogue with Swiftness in vanilla.
auto id = player.targetId;
if (player.hasPlayerTarget) {
assert(id >= 0 && id < Players.size());
auto &targetPlayer = Players[id];
dst = targetPlayer.position.future;
} else if (player.hasMonsterTarget) {
assert(id >= 0 && id < MaxMonsters);
auto &targetMonster = Monsters[id];
dst = targetMonster.position.future;
}
}

int arrows = 0;
if (player.AnimInfo.currentFrame == player._pAFNum - 1) {
arrows = 1;
Expand All @@ -949,20 +966,6 @@ bool DoRangeAttack(Player &player)
arrows = 2;
}

// PVP REBALANCE: Obtain target position upon arrow shot, rather than when initiating the cast for accuracy in arenas.
if (player.isOnArenaLevel()) {
auto targetId = player.targetId;
if (player.hasPlayerTarget) {
assert(targetId >= 0 && targetId < Players.size());
auto &targetPlayer = Players[player.targetId];
player.position.temp = targetPlayer.position.future;
} else if (player.hasMonsterTarget) {
assert(targetId >= 0 && targetId < MaxMonsters);
auto &targetMonster = Monsters[player.targetId];
player.position.temp = targetMonster.position.future;
}
}

for (int arrow = 0; arrow < arrows; arrow++) {
int xoff = 0;
int yoff = 0;
Expand Down Expand Up @@ -991,7 +994,7 @@ bool DoRangeAttack(Player &player)

AddMissile(
player.position.tile,
player.position.temp + Displacement { xoff, yoff },
dst + Displacement { xoff, yoff },
player._pdir,
mistype,
TARGET_MONSTERS,
Expand Down Expand Up @@ -1113,16 +1116,25 @@ void DamageArmor(Player &player)

bool DoSpell(Player &player)
{
WorldTilePosition dst = player.position.temp;
if (player.isOnArenaLevel() && player.AnimInfo.currentFrame == player._pSFNum - 7) {
// PVP REBALANCE: Obtain target position 7 frames before the action frame to ensure same accuracy regardless of casting speed.
// 7 frames should ensure the accuracy of casting spells for all classes is similar to that of Sorcerer in vanilla.
if (player.hasPlayerTarget) {
assert(player.targetId >= 0 && player.targetId < Players.size());
dst = Players[player.targetId].position.future;
} else if (player.hasMonsterTarget) {
assert(player.targetId >= 0 && player.targetId < MaxMonsters);
dst = Monsters[player.targetId].position.future;
}
}
if (player.AnimInfo.currentFrame == player._pSFNum) {
CastSpell(
player,
player.executedSpell.spellId,
player.position.tile,
player.position.temp,
player.executedSpell.spellLevel,
player.hasMonsterTarget,
player.hasPlayerTarget,
player.targetId);
dst,
player.executedSpell.spellLevel);

if (IsAnyOf(player.executedSpell.spellType, SpellType::Scroll, SpellType::Charges)) {
EnsureValidReadiedSpell(player);
Expand Down
13 changes: 1 addition & 12 deletions Source/spells.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,24 +209,13 @@ SpellCheckResult CheckSpell(const Player &player, SpellID sn, SpellType st, bool
return SpellCheckResult::Success;
}

void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl, bool hasMonsterTarget /*= false*/, bool hasPlayerTarget /*= false*/, int targetId /*= 0*/)
void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl)
{
Direction dir = player._pdir;
if (IsWallSpell(spl)) {
dir = player.tempDirection;
}

// PVP REBALANCE: Obtain target position upon spell effect, rather than when initiating the cast for accuracy in arenas.
if (player.isOnArenaLevel() && spl != SpellID::Teleport) {
if (hasPlayerTarget) {
assert(targetId >= 0 && targetId < Players.size());
dst = Players[targetId].position.future;
} else if (hasMonsterTarget) {
assert(targetId >= 0 && targetId < MaxMonsters);
dst = Monsters[targetId].position.future;
}
}

bool fizzled = false;
const SpellData &spellData = GetSpellData(spl);
for (size_t i = 0; i < sizeof(spellData.sMissiles) / sizeof(spellData.sMissiles[0]) && spellData.sMissiles[i] != MissileID::Null; i++) {
Expand Down
2 changes: 1 addition & 1 deletion Source/spells.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ SpellCheckResult CheckSpell(const Player &player, SpellID sn, SpellType st, bool
* @param player The player whose readied spell is to be checked.
*/
void EnsureValidReadiedSpell(Player &player);
void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl, bool hasMonsterTarget = false, bool hasPlayerTarget = false, int targetId = 0);
void CastSpell(Player &player, SpellID spl, WorldTilePosition src, WorldTilePosition dst, int spllvl);

/**
* @param pnum player index
Expand Down

0 comments on commit fc9393a

Please sign in to comment.