diff options
| author | Chaouki Dhib <chaodhib@gmail.com> | 2016-08-15 18:17:07 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-08-15 18:17:07 +0200 |
| commit | d7600f1126d2780fecdfcdfc66a598a48cee0136 (patch) | |
| tree | 4570f34a1732aa51aa384bef0f04b28e8463fc4b /src/server/game/Spells/Spell.cpp | |
| parent | 4a38773e3e74af329aa13e2a506ef824f2a6e4d3 (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.
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 91 |
1 files changed, 45 insertions, 46 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 5e58a602a43..8fc8282b549 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5831,46 +5831,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)) + return SPELL_FAILED_UNIT_NOT_INFRONT; + } + + if (m_targets.HasDst() && !m_targets.HasTraj()) + { + if (m_caster->GetExactDistSq(m_targets.GetDstPos()) > maxRange) + return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; + if (minRange > 0.0f && m_caster->GetExactDistSq(m_targets.GetDstPos()) < minRange) + return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; + } + + 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->type & 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->type & 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->type & SPELL_RANGE_RANGED)) minRange += rangeMod; @@ -5891,31 +5914,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)) - return SPELL_FAILED_UNIT_NOT_INFRONT; - } - - if (m_targets.HasDst() && !m_targets.HasTraj()) - { - if (m_caster->GetExactDistSq(m_targets.GetDstPos()) > maxRange) - return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; - if (minRange > 0.0f && m_caster->GetExactDistSq(m_targets.GetDstPos()) < minRange) - return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; - } - - return SPELL_CAST_OK; + return std::pair<float, float>(minRange, maxRange); } SpellCastResult Spell::CheckPower() |
