diff options
author | Chaouki Dhib <chaodhib@gmail.com> | 2016-08-15 18:17:07 +0200 |
---|---|---|
committer | joschiwald <joschiwald.trinity@gmail.com> | 2017-02-12 15:32:29 +0100 |
commit | 66d36839f092bb1016391a93b6b03733d1cd42bb (patch) | |
tree | cc5041929963090c5114e163fb9805c173486c93 /src/server/game/Spells/Spell.cpp | |
parent | 2560066b847dc2131ecda459227229b25fbc52a1 (diff) |
Core/Units: Fixed melee range check (#17693)
* Split Spell::CheckRange() into 2 methods since that method had more than one responsibility.
* Moved melee range logic into its own function
* Moved melee range logic method GetMeleeRange from Spell to Unit class. Unit::IsWithinMeleeRange() and Spell::GetMinMaxRange() both use that method.
(cherry picked from commit d7600f1126d2780fecdfcdfc66a598a48cee0136)
# Conflicts:
# src/server/game/Entities/Unit/Unit.cpp
# src/server/game/Entities/Unit/Unit.h
# src/server/game/Spells/Spell.cpp
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 45d681ac71a..0f5d7a13ce2 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5975,46 +5975,69 @@ SpellCastResult Spell::CheckRange(bool strict) if (!strict && m_casttime == 0) return SPELL_CAST_OK; + float minRange, maxRange; + std::tie(minRange, maxRange) = GetMinMaxRange(strict); + + // get square values for sqr distance checks + minRange *= minRange; + maxRange *= maxRange; + Unit* target = m_targets.GetUnitTarget(); + if (target && target != m_caster) + { + if (m_caster->GetExactDistSq(target) > maxRange) + return SPELL_FAILED_OUT_OF_RANGE; + + if (minRange > 0.0f && m_caster->GetExactDistSq(target) < minRange) + return SPELL_FAILED_OUT_OF_RANGE; + + if (m_caster->GetTypeId() == TYPEID_PLAYER && + (((m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target)) + && !m_caster->IsWithinBoundaryRadius(target))) + return SPELL_FAILED_UNIT_NOT_INFRONT; + } + + if (m_targets.HasDst() && !m_targets.HasTraj()) + { + if (m_caster->GetExactDistSq(m_targets.GetDstPos()) > maxRange) + return SPELL_FAILED_OUT_OF_RANGE; + if (minRange > 0.0f && m_caster->GetExactDistSq(m_targets.GetDstPos()) < minRange) + return SPELL_FAILED_OUT_OF_RANGE; + } + + return SPELL_CAST_OK; +} + +std::pair<float, float> Spell::GetMinMaxRange(bool strict) +{ + float rangeMod = 0.0f; float minRange = 0.0f; float maxRange = 0.0f; - float rangeMod = 0.0f; if (strict && IsNextMeleeSwingSpell()) + { maxRange = 100.0f; - else if (m_spellInfo->RangeEntry) + return std::pair<float, float>(minRange, maxRange); + } + + if (m_spellInfo->RangeEntry) { + Unit* target = m_targets.GetUnitTarget(); if (m_spellInfo->RangeEntry->Flags & SPELL_RANGE_MELEE) { - rangeMod = m_caster->GetCombatReach() + 4.0f / 3.0f; - if (target) - rangeMod += target->GetCombatReach(); - else - rangeMod += m_caster->GetCombatReach(); - - rangeMod = std::max(rangeMod, NOMINAL_MELEE_RANGE); + rangeMod = m_caster->GetMeleeRange(target ? target : m_caster); // when the target is not a unit, take the caster's combat reach as the target's combat reach. } else { float meleeRange = 0.0f; if (m_spellInfo->RangeEntry->Flags & SPELL_RANGE_RANGED) - { - meleeRange = m_caster->GetCombatReach() + 4.0f / 3.0f; - if (target) - meleeRange += target->GetCombatReach(); - else - meleeRange += m_caster->GetCombatReach(); - - meleeRange = std::max(meleeRange, NOMINAL_MELEE_RANGE); - } + meleeRange = m_caster->GetMeleeRange(target ? target : m_caster); // when the target is not a unit, take the caster's combat reach as the target's combat reach. minRange = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo) + meleeRange; maxRange = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo); if (target || m_targets.GetCorpseTarget()) { - rangeMod = m_caster->GetCombatReach(); - if (target) - rangeMod += target->GetCombatReach(); + rangeMod = m_caster->GetCombatReach() + (target ? target->GetCombatReach() : m_caster->GetCombatReach()); if (minRange > 0.0f && !(m_spellInfo->RangeEntry->Flags & SPELL_RANGE_RANGED)) minRange += rangeMod; @@ -6035,32 +6058,7 @@ SpellCastResult Spell::CheckRange(bool strict) maxRange += rangeMod; - minRange *= minRange; - maxRange *= maxRange; - - if (target && target != m_caster) - { - if (m_caster->GetExactDistSq(target) > maxRange) - return SPELL_FAILED_OUT_OF_RANGE; - - if (minRange > 0.0f && m_caster->GetExactDistSq(target) < minRange) - return SPELL_FAILED_OUT_OF_RANGE; - - if (m_caster->GetTypeId() == TYPEID_PLAYER && - (((m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target)) - && !m_caster->IsWithinBoundaryRadius(target))) - return SPELL_FAILED_UNIT_NOT_INFRONT; - } - - if (m_targets.HasDst() && !m_targets.HasTraj()) - { - if (m_caster->GetExactDistSq(m_targets.GetDstPos()) > maxRange) - return SPELL_FAILED_OUT_OF_RANGE; - if (minRange > 0.0f && m_caster->GetExactDistSq(m_targets.GetDstPos()) < minRange) - return SPELL_FAILED_OUT_OF_RANGE; - } - - return SPELL_CAST_OK; + return std::pair<float, float>(minRange, maxRange); } SpellCastResult Spell::CheckPower() |