diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index d2cbc7e12..45f001630 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1233,11 +1233,11 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool return distsq < maxdist * maxdist; } -Position WorldObject::GetHitSpherePointFor(Position const& dest, Optional collisionHeight) const +Position WorldObject::GetHitSpherePointFor(Position const& dest, Optional collisionHeight, Optional combatReach) const { G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ() + (collisionHeight ? *collisionHeight : GetCollisionHeight())); G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ()); - G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetCombatReach()); + G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), (combatReach ? *combatReach : GetCombatReach())); return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y)); } @@ -1344,7 +1344,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFla return true; } -bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags, LineOfSightChecks checks, Optional collisionHeight /*= {}*/) const +bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags, LineOfSightChecks checks, Optional collisionHeight /*= { }*/, Optional combatReach /*= { }*/) const { if (!IsInMap(obj)) return false; @@ -1365,14 +1365,14 @@ bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlag z += GetCollisionHeight(); } else - GetHitSpherePointFor({ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ() + obj->GetCollisionHeight() }, x, y, z, collisionHeight); + GetHitSpherePointFor({ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ() + obj->GetCollisionHeight() }, x, y, z, collisionHeight, combatReach); return GetMap()->isInLineOfSight(x, y, z, ox, oy, oz, GetPhaseMask(), checks, ignoreFlags); } -void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z, Optional collisionHeight) const +void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z, Optional collisionHeight, Optional combatReach) const { - Position pos = GetHitSpherePointFor(dest, collisionHeight); + Position pos = GetHitSpherePointFor(dest, collisionHeight, combatReach); x = pos.GetPositionX(); y = pos.GetPositionY(); z = pos.GetPositionZ(); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index a7dcd97e3..da57d6f04 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -465,9 +465,9 @@ public: bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true, bool useBoundingRadius = true) const; bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true, bool useBoundingRadius = true) const; [[nodiscard]] bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS) const; - [[nodiscard]] bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS, Optional collisionHeight = { }) const; - [[nodiscard]] Position GetHitSpherePointFor(Position const& dest, Optional collisionHeight = { }) const; - void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z, Optional collisionHeight = { }) const; + [[nodiscard]] bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS, Optional collisionHeight = { }, Optional combatReach = { }) const; + [[nodiscard]] Position GetHitSpherePointFor(Position const& dest, Optional collisionHeight = { }, Optional combatReach = { }) const; + void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z, Optional collisionHeight = { }, Optional combatReach = { }) const; bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const; [[nodiscard]] bool IsInRange2d(float x, float y, float minRange, float maxRange) const; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index f2c4a25e8..73668ac89 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2926,13 +2926,15 @@ void DynObjAura::FillTargetMap(std::map& targets, Unit* /*caster*/ Unit* target = *itr; Optional collisionHeight = { }; + Optional combatReach = { }; if (Unit* dynObjCaster = GetDynobjOwner()->GetCaster()) { collisionHeight = dynObjCaster->GetCollisionHeight(); + combatReach = dynObjCaster->GetCombatReach(); } if (!spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) && !spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT) && - !target->IsWithinLOSInMap(GetDynobjOwner(), VMAP::ModelIgnoreFlags::Nothing, LINEOFSIGHT_ALL_CHECKS, collisionHeight)) + !GetDynobjOwner()->IsWithinLOSInMap(target, VMAP::ModelIgnoreFlags::Nothing, LINEOFSIGHT_ALL_CHECKS, collisionHeight, combatReach)) { continue; }