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 | 91 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.h | 1 | 
4 files changed, 54 insertions, 47 deletions
| diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index a3e20b7c07d..80f2531e223 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -485,11 +485,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); +} +  void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const  {      float combat_reach = GetCombatReach(); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4589ec9a180..5162d2398c3 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1291,6 +1291,7 @@ class TC_GAME_API Unit : public WorldObject          float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; }          bool IsWithinCombatRange(const Unit* obj, float dist2compare) const;          bool IsWithinMeleeRange(Unit const* obj) const; +        float GetMeleeRange(Unit const* target) const;          void GetRandomContactPoint(const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const;          uint32 m_extraAttacks;          bool m_canDualWield; 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() diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 46384fc54ec..c834d187720 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -507,6 +507,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; | 
