diff options
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 92 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 1 |
4 files changed, 54 insertions, 48 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b0c89960fa8..abee8b5a8e1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -511,11 +511,17 @@ bool Unit::IsWithinMeleeRange(Unit const* obj) const float dz = GetPositionZMinusOffset() - obj->GetPositionZMinusOffset(); float distsq = dx*dx + dy*dy + dz*dz; - float maxdist = GetCombatReach() + obj->GetCombatReach() + 4.0f / 3.0f; + float maxdist = GetMeleeRange(obj); return distsq <= maxdist * maxdist; } +float Unit::GetMeleeRange(Unit const* target) const +{ + float range = GetCombatReach() + target->GetCombatReach() + 4.0f / 3.0f; + return std::max(range, NOMINAL_MELEE_RANGE); +} + bool Unit::IsWithinBoundaryRadius(const Unit* obj) const { if (!obj || !IsInMap(obj) || !IsInPhase(obj)) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 2ffb78a4fc8..0f379a7326a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1386,6 +1386,7 @@ class TC_GAME_API Unit : public WorldObject float GetBoundaryRadius() const { return m_floatValues[UNIT_FIELD_BOUNDINGRADIUS]; } bool IsWithinCombatRange(const Unit* obj, float dist2compare) const; bool IsWithinMeleeRange(Unit const* obj) const; + float GetMeleeRange(Unit const* target) const; bool IsWithinBoundaryRadius(const Unit* obj) const; void GetRandomContactPoint(const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const; uint32 m_extraAttacks; 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() diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 53a9de5436f..be4bed12718 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -666,6 +666,7 @@ class TC_GAME_API Spell void CancelGlobalCooldown(); void SendLoot(ObjectGuid guid, LootType loottype); + std::pair<float, float> GetMinMaxRange(bool strict); Unit* const m_caster; |