diff options
author | Shauren <shauren.trinity@gmail.com> | 2016-07-09 13:03:03 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2016-07-09 13:03:03 +0200 |
commit | 14b93c04ee07e9fe6e2767460e7fc7cc2b3e6808 (patch) | |
tree | 977f96debfd94275dbf63d770823a0701f58b35d | |
parent | 0b9854428657bd5c988e7aeda5b6e4df9a72131a (diff) |
Core/Units: Fixed autoattack range
Closes #17539
-rw-r--r-- | src/server/game/AI/CoreAI/UnitAI.cpp | 68 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 |
3 files changed, 56 insertions, 21 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 844bd45ffeb..70324c7b03a 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -274,28 +274,64 @@ bool SpellTargetSelector::operator()(Unit const* target) const return false; // copypasta from Spell::CheckRange - uint32 range_type = _spellInfo->RangeEntry ? _spellInfo->RangeEntry->type : 0; - float max_range = _caster->GetSpellMaxRangeForTarget(target, _spellInfo); - float min_range = _caster->GetSpellMinRangeForTarget(target, _spellInfo); + float minRange = 0.0f; + float maxRange = 0.0f; + float rangeMod = 0.0f; + if (_spellInfo->RangeEntry) + { + if (_spellInfo->RangeEntry->type & SPELL_RANGE_MELEE) + { + rangeMod = _caster->GetCombatReach() + 4.0f / 3.0f; + if (target) + rangeMod += target->GetCombatReach(); + else + rangeMod += _caster->GetCombatReach(); + + rangeMod = std::max(rangeMod, NOMINAL_MELEE_RANGE); + } + else + { + float meleeRange = 0.0f; + if (_spellInfo->RangeEntry->type & SPELL_RANGE_RANGED) + { + meleeRange = _caster->GetCombatReach() + 4.0f / 3.0f; + if (target) + meleeRange += target->GetCombatReach(); + else + meleeRange += _caster->GetCombatReach(); + + meleeRange = std::max(meleeRange, NOMINAL_MELEE_RANGE); + } + + minRange = _caster->GetSpellMinRangeForTarget(target, _spellInfo) + meleeRange; + maxRange = _caster->GetSpellMaxRangeForTarget(target, _spellInfo); + if (target) + { + rangeMod = _caster->GetCombatReach(); + rangeMod += target->GetCombatReach(); + + if (minRange > 0.0f && !(_spellInfo->RangeEntry->type & SPELL_RANGE_RANGED)) + minRange += rangeMod; + } + } + + if (target && _caster->isMoving() && target->isMoving() && !_caster->IsWalking() && !target->IsWalking() && + (_spellInfo->RangeEntry->type & SPELL_RANGE_MELEE || target->GetTypeId() == TYPEID_PLAYER)) + rangeMod += 5.0f / 3.0f; + } + + maxRange += rangeMod; + + minRange *= minRange; + maxRange *= maxRange; if (target && target != _caster) { - if (range_type == SPELL_RANGE_MELEE) - { - // Because of lag, we can not check too strictly here. - if (!_caster->IsWithinMeleeRange(target, max_range)) - return false; - } - else if (!_caster->IsWithinCombatRange(target, max_range)) + if (_caster->GetExactDistSq(target) > maxRange) return false; - if (range_type == SPELL_RANGE_RANGED) - { - if (_caster->IsWithinMeleeRange(target)) - return false; - } - else if (min_range && _caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0 + if (minRange > 0.0f && _caster->GetExactDistSq(target) < minRange) return false; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 6b66780f328..e39cad81ae1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -475,7 +475,7 @@ bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const return distsq < maxdist * maxdist; } -bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const +bool Unit::IsWithinMeleeRange(Unit const* obj) const { if (!obj || !IsInMap(obj) || !InSamePhase(obj)) return false; @@ -485,10 +485,9 @@ bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const float dz = GetPositionZMinusOffset() - obj->GetPositionZMinusOffset(); float distsq = dx*dx + dy*dy + dz*dz; - float sizefactor = GetCombatReach() + obj->GetCombatReach() + 4.0f / 3.0f; - float maxdist = dist + sizefactor; + float maxdist = GetCombatReach() + obj->GetCombatReach() + 4.0f / 3.0f; - return distsq < maxdist * maxdist; + return distsq <= maxdist * maxdist; } void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index baeae4987c0..0f48f31b9c0 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1290,7 +1290,7 @@ class TC_GAME_API Unit : public WorldObject virtual void SetCanDualWield(bool value) { m_canDualWield = value; } float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; } bool IsWithinCombatRange(const Unit* obj, float dist2compare) const; - bool IsWithinMeleeRange(const Unit* obj, float dist = MELEE_RANGE) const; + bool IsWithinMeleeRange(Unit const* obj) const; void GetRandomContactPoint(const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const; uint32 m_extraAttacks; bool m_canDualWield; |