diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 782c53a78..be992f4fe 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2055,12 +2055,12 @@ void GameObject::CastSpell(Unit* target, uint32 spellId) if (!spellInfo) return; - bool self = false; + bool self = true; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (spellInfo->Effects[i].TargetA.GetReferenceType() == TARGET_REFERENCE_TYPE_CASTER && !spellInfo->Effects[i].TargetB.GetTarget()) + if (spellInfo->Effects[i].TargetA.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER || spellInfo->Effects[i].TargetB.GetTarget()) { - self = true; + self = false; break; } } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index f894f9355..ac23ffbaf 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1230,9 +1230,9 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool return distsq < maxdist * maxdist; } -Position WorldObject::GetHitSpherePointFor(Position const& dest) const +Position WorldObject::GetHitSpherePointFor(Position const& dest, Optional collisionHeight) const { - G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight()); + 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()); @@ -1341,7 +1341,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) const +bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags, LineOfSightChecks checks, Optional collisionHeight /*= {}*/) const { if (!IsInMap(obj)) return false; @@ -1353,7 +1353,7 @@ bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlag oz += obj->GetCollisionHeight(); } else - obj->GetHitSpherePointFor({ GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight() }, ox, oy, oz); + obj->GetHitSpherePointFor({ GetPositionX(), GetPositionY(), GetPositionZ() + (collisionHeight ? *collisionHeight : GetCollisionHeight()) }, ox, oy, oz); float x, y, z; if (GetTypeId() == TYPEID_PLAYER) @@ -1362,14 +1362,14 @@ bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlag z += GetCollisionHeight(); } else - GetHitSpherePointFor({ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ() + obj->GetCollisionHeight() }, x, y, z); + GetHitSpherePointFor({ obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ() + obj->GetCollisionHeight() }, x, y, z, collisionHeight); return GetMap()->isInLineOfSight(x, y, z, ox, oy, oz, GetPhaseMask(), checks, ignoreFlags); } -void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const +void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z, Optional collisionHeight) const { - Position pos = GetHitSpherePointFor(dest); + Position pos = GetHitSpherePointFor(dest, collisionHeight); 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 306a30db7..a3ba74bbd 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -463,9 +463,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) const; - [[nodiscard]] Position GetHitSpherePointFor(Position const& dest) const; - void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) 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; 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/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 3d5eff4b1..d14d20479 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -925,7 +925,19 @@ namespace Acore return false; } - if (!i_obj->IsWithinDistInMap(u, i_range) || !i_owner->IsValidAttackTarget(u) || !i_obj->IsWithinLOSInMap(u)) + uint32 losChecks = LINEOFSIGHT_ALL_CHECKS; + Optional collisionHeight = { }; + if (i_obj->GetTypeId() == TYPEID_GAMEOBJECT) + { + losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2; + if (i_owner->IsPlayer()) + { + collisionHeight = i_owner->GetCollisionHeight(); + } + } + + if (!i_obj->IsWithinDistInMap(u, i_range) || !i_owner->IsValidAttackTarget(u) || + !i_obj->IsWithinLOSInMap(u, VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks(losChecks), collisionHeight)) { return false; }