aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChaouki Dhib <chaodhib@gmail.com>2017-03-23 00:43:04 +0100
committerTreeston <treeston.mmoc@gmail.com>2017-03-23 00:43:04 +0100
commita1f2f30c145f6ad9c4baeffeff32618e71ff537c (patch)
treea4c6205c64f22b66d887585aa2778cbf443d9764
parenta88d4e9b0014c7204249fc354168878b0e3abb8e (diff)
Core/Spells: fix wrong distance calculations in AoE spells [Needs testing] (#16290)
Core/Spells: Fix wrong distance calculations in AoE spells. Pull request #16290 by chaodhib. God bless, finally.
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp6
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp81
-rw-r--r--src/server/game/Entities/Object/Object.h16
-rw-r--r--src/server/game/Entities/Object/Position.cpp6
-rw-r--r--src/server/game/Entities/Object/Position.h5
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Grids/Cells/CellImpl.h2
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h59
-rw-r--r--src/server/game/Movement/MotionMaster.cpp4
-rw-r--r--src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp6
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp10
-rw-r--r--src/server/game/Spells/Spell.cpp36
-rw-r--r--src/server/game/Spells/SpellEffects.cpp18
-rw-r--r--src/server/game/Spells/SpellInfo.cpp29
-rw-r--r--src/server/game/Spells/SpellInfo.h1
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp2
-rw-r--r--src/server/scripts/Commands/cs_group.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp2
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp6
-rw-r--r--src/server/scripts/Northrend/zone_zuldrak.cpp4
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp2
-rw-r--r--src/server/scripts/World/go_scripts.cpp2
-rw-r--r--src/server/scripts/World/item_scripts.cpp2
34 files changed, 207 insertions, 122 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 3aec5cc1876..8da23deffd2 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2343,7 +2343,7 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
else
{
// include sizes for huge npcs
- dist += GetObjectSize() + victim->GetObjectSize();
+ dist += GetCombatReach() + victim->GetCombatReach();
// to prevent creatures in air ignore attacks because distance is already too high...
if (GetCreatureTemplate()->InhabitType & INHABIT_AIR)
@@ -2946,7 +2946,7 @@ void Creature::SetObjectScale(float scale)
if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(GetDisplayId()))
{
SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, (IsPet() ? 1.0f : minfo->bounding_radius) * scale);
- SetFloatValue(UNIT_FIELD_COMBATREACH, (IsPet() ? DEFAULT_COMBAT_REACH : minfo->combat_reach) * scale);
+ SetFloatValue(UNIT_FIELD_COMBATREACH, (IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : minfo->combat_reach) * scale);
}
}
@@ -2957,7 +2957,7 @@ void Creature::SetDisplayId(uint32 modelId)
if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId))
{
SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, (IsPet() ? 1.0f : minfo->bounding_radius) * GetObjectScale());
- SetFloatValue(UNIT_FIELD_COMBATREACH, (IsPet() ? DEFAULT_COMBAT_REACH : minfo->combat_reach) * GetObjectScale());
+ SetFloatValue(UNIT_FIELD_COMBATREACH, (IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : minfo->combat_reach) * GetObjectScale());
}
}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 4ef0c9c2e5f..bad48e0693d 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -946,7 +946,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void UpdatePackedRotation();
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
- bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const override
+ bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/, bool /*incOwnRadius*/, bool /*incTargetRadius*/) const override
{
//! Following check does check 3d distance
return IsInRange(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), dist2compare);
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 70c8e2f46c2..39a058b80d8 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1108,39 +1108,31 @@ InstanceScript* WorldObject::GetInstanceScript()
float WorldObject::GetDistanceZ(const WorldObject* obj) const
{
float dz = std::fabs(GetPositionZ() - obj->GetPositionZ());
- float sizefactor = GetObjectSize() + obj->GetObjectSize();
+ float sizefactor = GetCombatReach() + obj->GetCombatReach();
float dist = dz - sizefactor;
return (dist > 0 ? dist : 0);
}
-bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
+bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool incOwnRadius, bool incTargetRadius) const
{
- float sizefactor = GetObjectSize() + obj->GetObjectSize();
+ float sizefactor = 0;
+ sizefactor += incOwnRadius ? GetCombatReach() : 0.0f;
+ sizefactor += incTargetRadius ? obj->GetCombatReach() : 0.0f;
float maxdist = dist2compare + sizefactor;
+ Position const* thisOrTransport = this;
+ Position const* objOrObjTransport = obj;
+
if (GetTransport() && obj->GetTransport() && obj->GetTransport()->GetGUID().GetCounter() == GetTransport()->GetGUID().GetCounter())
{
- float dtx = m_movementInfo.transport.pos.m_positionX - obj->m_movementInfo.transport.pos.m_positionX;
- float dty = m_movementInfo.transport.pos.m_positionY - obj->m_movementInfo.transport.pos.m_positionY;
- float disttsq = dtx * dtx + dty * dty;
- if (is3D)
- {
- float dtz = m_movementInfo.transport.pos.m_positionZ - obj->m_movementInfo.transport.pos.m_positionZ;
- disttsq += dtz * dtz;
- }
- return disttsq < (maxdist * maxdist);
+ thisOrTransport = &m_movementInfo.transport.pos;
+ objOrObjTransport = &obj->m_movementInfo.transport.pos;
}
- float dx = GetPositionX() - obj->GetPositionX();
- float dy = GetPositionY() - obj->GetPositionY();
- float distsq = dx*dx + dy*dy;
if (is3D)
- {
- float dz = GetPositionZ() - obj->GetPositionZ();
- distsq += dz*dz;
- }
-
- return distsq < maxdist * maxdist;
+ return thisOrTransport->IsInDist(objOrObjTransport, maxdist);
+ else
+ return thisOrTransport->IsInDist2d(objOrObjTransport, maxdist);
}
bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, VMAP::ModelIgnoreFlags ignoreFlags) const
@@ -1159,31 +1151,31 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, VMAP::ModelIgnoreFlag
float WorldObject::GetDistance(const WorldObject* obj) const
{
- float d = GetExactDist(obj) - GetObjectSize() - obj->GetObjectSize();
+ float d = GetExactDist(obj) - GetCombatReach() - obj->GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance(const Position &pos) const
{
- float d = GetExactDist(&pos) - GetObjectSize();
+ float d = GetExactDist(&pos) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance(float x, float y, float z) const
{
- float d = GetExactDist(x, y, z) - GetObjectSize();
+ float d = GetExactDist(x, y, z) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance2d(const WorldObject* obj) const
{
- float d = GetExactDist2d(obj) - GetObjectSize() - obj->GetObjectSize();
+ float d = GetExactDist2d(obj) - GetCombatReach() - obj->GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
float WorldObject::GetDistance2d(float x, float y) const
{
- float d = GetExactDist2d(x, y) - GetObjectSize();
+ float d = GetExactDist2d(x, y) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
@@ -1203,22 +1195,22 @@ bool WorldObject::IsInMap(const WorldObject* obj) const
bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist) const
{
- return IsInDist(x, y, z, dist + GetObjectSize());
+ return IsInDist(x, y, z, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist3d(const Position* pos, float dist) const
{
- return IsInDist(pos, dist + GetObjectSize());
+ return IsInDist(pos, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist2d(float x, float y, float dist) const
{
- return IsInDist2d(x, y, dist + GetObjectSize());
+ return IsInDist2d(x, y, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist2d(const Position* pos, float dist) const
{
- return IsInDist2d(pos, dist + GetObjectSize());
+ return IsInDist2d(pos, dist + GetCombatReach());
}
bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const
@@ -1226,9 +1218,9 @@ bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool
return obj && _IsWithinDist(obj, dist2compare, is3D);
}
-bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const
+bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/, bool incOwnRadius /*= true*/, bool incTargetRadius /*= true*/) const
{
- return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D);
+ return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D, incOwnRadius, incTargetRadius);
}
bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFlags ignoreFlags) const
@@ -1255,7 +1247,7 @@ Position WorldObject::GetHitSpherePointFor(Position const& dest) const
{
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ());
G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
- G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(GetPosition()), GetObjectSize());
+ G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(GetPosition()), GetCombatReach());
return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y));
}
@@ -1302,7 +1294,7 @@ bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRan
distsq += dz*dz;
}
- float sizefactor = GetObjectSize() + obj->GetObjectSize();
+ float sizefactor = GetCombatReach() + obj->GetCombatReach();
// check only for real range
if (minRange > 0.0f)
@@ -1322,7 +1314,7 @@ bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange)
float dy = GetPositionY() - y;
float distsq = dx*dx + dy*dy;
- float sizefactor = GetObjectSize();
+ float sizefactor = GetCombatReach();
// check only for real range
if (minRange > 0.0f)
@@ -1343,7 +1335,7 @@ bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float m
float dz = GetPositionZ() - z;
float distsq = dx*dx + dy*dy + dz*dz;
- float sizefactor = GetObjectSize();
+ float sizefactor = GetCombatReach();
// check only for real range
if (minRange > 0.0f)
@@ -1366,7 +1358,7 @@ bool WorldObject::IsInBetween(Position const& pos1, Position const& pos2, float
return false;
if (!size)
- size = GetObjectSize() / 2;
+ size = GetCombatReach() / 2;
float angle = pos1.GetAngle(pos2);
@@ -1993,7 +1985,7 @@ TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, fl
{
if (!x && !y && !z)
{
- GetClosePoint(x, y, z, GetObjectSize());
+ GetClosePoint(x, y, z, GetCombatReach());
ang = GetOrientation();
}
@@ -2036,7 +2028,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
{
if (!x && !y && !z)
{
- GetClosePoint(x, y, z, GetObjectSize());
+ GetClosePoint(x, y, z, GetCombatReach());
ang = GetOrientation();
}
@@ -2162,8 +2154,8 @@ void WorldObject::GetPlayerListInGrid(Container& playerContainer, float maxSearc
void WorldObject::GetNearPoint2D(float &x, float &y, float distance2d, float absAngle) const
{
- x = GetPositionX() + (GetObjectSize() + distance2d) * std::cos(absAngle);
- y = GetPositionY() + (GetObjectSize() + distance2d) * std::sin(absAngle);
+ x = GetPositionX() + (GetCombatReach() + distance2d) * std::cos(absAngle);
+ y = GetPositionY() + (GetCombatReach() + distance2d) * std::sin(absAngle);
Trinity::NormalizeMapCoord(x);
Trinity::NormalizeMapCoord(y);
@@ -2235,12 +2227,7 @@ Position WorldObject::GetRandomNearPosition(float radius)
void WorldObject::GetContactPoint(const WorldObject* obj, float &x, float &y, float &z, float distance2d /*= CONTACT_DISTANCE*/) const
{
// angle to face `obj` to `this` using distance includes size of `obj`
- GetNearPoint(obj, x, y, z, obj->GetObjectSize(), distance2d, GetAngle(obj));
-}
-
-float WorldObject::GetObjectSize() const
-{
- return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE;
+ GetNearPoint(obj, x, y, z, obj->GetCombatReach(), distance2d, GetAngle(obj));
}
void WorldObject::MovePosition(Position &pos, float dist, float angle)
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 55d3efed548..ffa7183a8b1 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -42,11 +42,11 @@
#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
-#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
-#define DEFAULT_COMBAT_REACH 1.5f
-#define MIN_MELEE_REACH 2.0f
-#define NOMINAL_MELEE_RANGE 5.0f
-#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
+#define DEFAULT_PLAYER_BOUNDING_RADIUS 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
+#define DEFAULT_PLAYER_COMBAT_REACH 1.5f
+#define MIN_MELEE_REACH 2.0f
+#define NOMINAL_MELEE_RANGE 5.0f
+#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
enum TempSummonType
{
@@ -448,7 +448,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
Position GetRandomNearPosition(float radius);
void GetContactPoint(WorldObject const* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const;
- float GetObjectSize() const;
+ virtual float GetCombatReach() const { return 0.0f; } // overridden (only) in Unit
void UpdateGroundPositionZ(float x, float y, float &z) const;
void UpdateAllowedPositionZ(float x, float y, float &z) const;
@@ -488,7 +488,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
bool IsWithinDist2d(Position const* pos, float dist) const;
// use only if you will sure about placing both object at same map
bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const;
- bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const;
+ bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true, bool incOwnRadius = true, bool incTargetRadius = true) const;
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const;
bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const;
Position GetHitSpherePointFor(Position const& dest) const;
@@ -647,7 +647,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
uint16 m_notifyflags;
uint16 m_executed_notifies;
- virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
+ virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool incOwnRadius = true, bool incTargetRadius = true) const;
bool CanNeverSee(WorldObject const* obj) const;
virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; }
diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp
index 0fdbaf8e008..a8cb363e272 100644
--- a/src/server/game/Entities/Object/Position.cpp
+++ b/src/server/game/Entities/Object/Position.cpp
@@ -137,6 +137,12 @@ bool Position::IsWithinBox(const Position& center, float xradius, float yradius,
return true;
}
+bool Position::IsWithinDoubleVerticalCylinder(Position const* center, float radius, float height) const
+{
+ float verticalDelta = GetPositionZ() - center->GetPositionZ();
+ return IsInDist2d(center, radius) && std::abs(verticalDelta) <= height;
+}
+
bool Position::HasInArc(float arc, const Position* obj, float border) const
{
// always have self in arc
diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h
index db694a51bfd..4dba3d1f330 100644
--- a/src/server/game/Entities/Object/Position.h
+++ b/src/server/game/Entities/Object/Position.h
@@ -229,6 +229,11 @@ public:
}
bool IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const;
+
+ /*
+ search using this relation: dist2d < radius && abs(dz) < height
+ */
+ bool IsWithinDoubleVerticalCylinder(Position const* center, float radius, float height) const;
bool HasInArc(float arcangle, Position const* pos, float border = 2.0f) const;
bool HasInLine(Position const* pos, float objSize, float width) const;
std::string ToString() const;
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 5e2619890ec..72fb329b672 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -186,7 +186,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
if (IsCritter())
{
float px, py, pz;
- owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle());
+ owner->GetClosePoint(px, py, pz, GetCombatReach(), PET_FOLLOW_DIST, GetFollowAngle());
Relocate(px, py, pz, owner->GetOrientation());
if (!IsPositionValid())
@@ -245,7 +245,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
// Set pet's position after setting level, its size depends on it
float px, py, pz;
- owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle());
+ owner->GetClosePoint(px, py, pz, GetCombatReach(), PET_FOLLOW_DIST, GetFollowAngle());
Relocate(px, py, pz, owner->GetOrientation());
if (!IsPositionValid())
{
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 3d2ccc388a4..291325dc759 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1047,8 +1047,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SetObjectScale(float scale) override
{
Unit::SetObjectScale(scale);
- SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, scale * DEFAULT_WORLD_OBJECT_SIZE);
- SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_COMBAT_REACH);
+ SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, scale * DEFAULT_PLAYER_BOUNDING_RADIUS);
+ SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_PLAYER_COMBAT_REACH);
}
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index f813fe3121c..a5f8c98c290 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -581,7 +581,7 @@ void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z,
{
float combat_reach = GetCombatReach();
if (combat_reach < 0.1f) // sometimes bugged for players
- combat_reach = DEFAULT_COMBAT_REACH;
+ combat_reach = DEFAULT_PLAYER_COMBAT_REACH;
uint32 attacker_number = getAttackers().size();
if (attacker_number > 0)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index a0ebe4ddf10..bd2a564de61 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1321,7 +1321,7 @@ class TC_GAME_API Unit : public WorldObject
bool haveOffhandWeapon() const;
bool CanDualWield() const { return m_canDualWield; }
virtual void SetCanDualWield(bool value) { m_canDualWield = value; }
- float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; }
+ float GetCombatReach() const override { 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;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index b7a1788871f..43681910ac0 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1396,7 +1396,7 @@ void ObjectMgr::LoadCreatureModelInfo()
}
if (modelInfo.combat_reach < 0.1f)
- modelInfo.combat_reach = DEFAULT_COMBAT_REACH;
+ modelInfo.combat_reach = DEFAULT_PLAYER_COMBAT_REACH;
if (CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(creatureDisplay->ModelId))
modelInfo.is_trigger = strstr(modelData->ModelPath, "InvisibleStalker") != nullptr;
diff --git a/src/server/game/Grids/Cells/CellImpl.h b/src/server/game/Grids/Cells/CellImpl.h
index 36a15346b8b..aa567051e86 100644
--- a/src/server/game/Grids/Cells/CellImpl.h
+++ b/src/server/game/Grids/Cells/CellImpl.h
@@ -123,7 +123,7 @@ inline void Cell::Visit(CellCoord const& standing_cell, TypeContainerVisitor<T,
{
//we should increase search radius by object's radius, otherwise
//we could have problems with huge creatures, which won't attack nearest players etc
- Visit(standing_cell, visitor, map, radius + obj.GetObjectSize(), obj.GetPositionX(), obj.GetPositionY());
+ Visit(standing_cell, visitor, map, radius + obj.GetCombatReach(), obj.GetPositionX(), obj.GetPositionY());
}
template<class T, class CONTAINER>
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 04857f5c52a..1378b4a5778 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -927,14 +927,27 @@ namespace Trinity
class AnyFriendlyUnitInObjectRangeCheck
{
public:
- AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool playerOnly = false) : i_obj(obj), i_funit(funit), i_range(range), i_playerOnly(playerOnly) { }
+ AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool playerOnly = false, bool incOwnRadius = true, bool incTargetRadius = true)
+ : i_obj(obj), i_funit(funit), i_range(range), i_playerOnly(playerOnly), i_incOwnRadius(incOwnRadius), i_incTargetRadius(incTargetRadius) { }
bool operator()(Unit* u) const
{
- if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u) && (!i_playerOnly || u->GetTypeId() == TYPEID_PLAYER))
- return true;
- else
+ if (!u->IsAlive())
+ return false;
+
+ float searchRadius = i_range;
+ if (i_incOwnRadius)
+ searchRadius += i_obj->GetCombatReach();
+ if (i_incTargetRadius)
+ searchRadius += u->GetCombatReach();
+
+ if (!u->IsInMap(i_obj) || !u->InSamePhase(i_obj) || !u->IsWithinDoubleVerticalCylinder(i_obj, searchRadius, searchRadius))
return false;
+
+ if (!i_funit->IsFriendlyTo(u))
+ return false;
+
+ return !i_playerOnly || u->GetTypeId() == TYPEID_PLAYER;
}
private:
@@ -942,12 +955,15 @@ namespace Trinity
Unit const* i_funit;
float i_range;
bool i_playerOnly;
+ bool i_incOwnRadius;
+ bool i_incTargetRadius;
};
class AnyGroupedUnitInObjectRangeCheck
{
public:
- AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false) : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly) { }
+ AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false, bool incOwnRadius = true, bool incTargetRadius = true)
+ : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly), i_incOwnRadius(incOwnRadius), i_incTargetRadius(incTargetRadius) { }
bool operator()(Unit* u) const
{
@@ -965,7 +981,19 @@ namespace Trinity
else if (!_refUnit->IsInPartyWith(u))
return false;
- return !_refUnit->IsHostileTo(u) && u->IsAlive() && _source->IsWithinDistInMap(u, _range);
+ if (_refUnit->IsHostileTo(u))
+ return false;
+
+ if (!u->IsAlive())
+ return false;
+
+ float searchRadius = _range;
+ if (i_incOwnRadius)
+ searchRadius += _source->GetCombatReach();
+ if (i_incTargetRadius)
+ searchRadius += u->GetCombatReach();
+
+ return u->IsInMap(_source) && u->InSamePhase(_source) && u->IsWithinDoubleVerticalCylinder(_source, searchRadius, searchRadius);
}
private:
@@ -974,6 +1002,8 @@ namespace Trinity
float _range;
bool _raid;
bool _playerOnly;
+ bool i_incOwnRadius;
+ bool i_incTargetRadius;
};
class AnyUnitInObjectRangeCheck
@@ -1024,8 +1054,8 @@ namespace Trinity
class AnyAoETargetUnitInObjectRangeCheck
{
public:
- AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr)
- : i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range)
+ AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr, bool incOwnRadius = true, bool incTargetRadius = true)
+ : i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range), i_incOwnRadius(incOwnRadius), i_incTargetRadius(incTargetRadius)
{
if (!_spellInfo)
if (DynamicObject const* dynObj = i_obj->ToDynObject())
@@ -1041,7 +1071,16 @@ namespace Trinity
if (_spellInfo && _spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS) && u->GetTypeId() != TYPEID_PLAYER)
return false;
- return i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range);
+ if (!i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr))
+ return false;
+
+ float searchRadius = i_range;
+ if (i_incOwnRadius)
+ searchRadius += i_obj->GetCombatReach();
+ if (i_incTargetRadius)
+ searchRadius += u->GetCombatReach();
+
+ return u->IsInMap(i_obj) && u->InSamePhase(i_obj) && u->IsWithinDoubleVerticalCylinder(i_obj, searchRadius, searchRadius);
}
private:
@@ -1049,6 +1088,8 @@ namespace Trinity
Unit const* i_funit;
SpellInfo const* _spellInfo;
float i_range;
+ bool i_incOwnRadius;
+ bool i_incTargetRadius;
};
// do attack at call of help to friendly crearture
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 888bec05284..a308369ec65 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -430,7 +430,7 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa
float dist = 2 * moveTimeHalf * speedXY;
float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ);
- _owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + float(M_PI));
+ _owner->GetNearPoint(_owner, x, y, z, _owner->GetCombatReach(), dist, _owner->GetAngle(srcX, srcY) + float(M_PI));
Movement::MoveSplineInit init(_owner);
init.MoveTo(x, y, z);
@@ -451,7 +451,7 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
float moveTimeHalf = speedZ / Movement::gravity;
float dist = 2 * moveTimeHalf * speedXY;
- _owner->GetClosePoint(x, y, z, _owner->GetObjectSize(), dist, angle);
+ _owner->GetClosePoint(x, y, z, _owner->GetCombatReach(), dist, angle);
MoveJump(x, y, z, 0.0f, speedXY, speedZ);
}
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index 0280b939efb..48e55c9960f 100644
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -66,7 +66,7 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up
float size;
// Pets need special handling.
- // We need to subtract GetObjectSize() because it gets added back further down the chain
+ // We need to subtract GetCombatReach() because it gets added back further down the chain
// and that makes pets too far away. Subtracting it allows pets to properly
// be (GetCombatReach() + i_offset) away.
// Only applies when i_target is pet's owner otherwise pets and mobs end up
@@ -74,12 +74,12 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up
if (owner->IsPet() && i_target->GetTypeId() == TYPEID_PLAYER)
{
dist = 1.0f; //i_target->GetCombatReach();
- size = 1.0f; //i_target->GetCombatReach() - i_target->GetObjectSize();
+ size = 1.0f; //i_target->GetCombatReach() - i_target->GetCombatReach();
}
else
{
dist = i_offset + 1.0f;
- size = owner->GetObjectSize();
+ size = owner->GetCombatReach();
}
if (i_target->IsWithinDistInMap(owner, dist))
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index c9abf8896b7..9430086f288 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -2487,7 +2487,7 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* ca
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
{
units.push_back(GetUnitOwner());
- Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS), false, true);
Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
@@ -2495,14 +2495,14 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* ca
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
units.push_back(GetUnitOwner());
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS), false, true);
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
}
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
{
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo); // No GetCharmer in searcher
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo, false, true); // No GetCharmer in searcher
Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
@@ -2564,13 +2564,13 @@ void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit*
if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
|| GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
{
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS));
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_TARGET_PLAYERS), false, true);
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
GetDynobjOwner()->VisitNearbyObject(radius, searcher);
}
else
{
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, nullptr, false, true);
Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
GetDynobjOwner()->VisitNearbyObject(radius, searcher);
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 60a719a8fb2..302579da128 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1220,6 +1220,10 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
radius *= m_spellValue->RadiusMod;
+ // if this is a proximity based aoe (Frost Nova, Psychic Scream, ...), include the caster's own combat reach
+ if (targetType.IsProximityBasedAoe())
+ radius += GetCaster()->GetCombatReach();
+
SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
@@ -1278,7 +1282,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
float dist = frand(minDist, maxDist);
float x, y, z;
float angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS, dist, angle);
float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z, true, 50.0f);
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
@@ -1309,7 +1313,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
{
float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
float angle = targetType.CalcDirectionAngle();
- float objSize = m_caster->GetObjectSize();
+ float objSize = m_caster->GetCombatReach();
switch (targetType.GetTarget())
{
@@ -1364,7 +1368,7 @@ void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplici
default:
{
float angle = targetType.CalcDirectionAngle();
- float objSize = target->GetObjectSize();
+ float objSize = target->GetCombatReach();
float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
if (dist < objSize)
dist = objSize;
@@ -1576,7 +1580,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
}
- const float size = std::max((*itr)->GetObjectSize(), 1.0f);
+ const float size = std::max((*itr)->GetCombatReach(), 1.0f);
const float objDist2d = srcPos.GetExactDist2d(*itr);
const float dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
@@ -5234,12 +5238,12 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
return SPELL_FAILED_LINE_OF_SIGHT;
- float objSize = target->GetObjectSize();
+ float objSize = target->GetCombatReach();
float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
m_preGeneratedPath.SetPathLengthLimit(range);
// first try with raycast, if it fails fall back to normal path
- float targetObjectSize = std::min(target->GetObjectSize(), 4.0f);
+ float targetObjectSize = std::min(target->GetCombatReach(), 4.0f);
bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, true);
if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_OUT_OF_RANGE;
@@ -7761,8 +7765,20 @@ WorldObjectSpellAreaTargetCheck::WorldObjectSpellAreaTargetCheck(float range, Po
bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target)
{
- if (!target->IsWithinDist3d(_position, _range) && !(target->ToGameObject() && target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range)))
- return false;
+ if (target->ToGameObject())
+ {
+ // isInRange including the dimension of the GO
+ bool isInRange = target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range);
+ if (!isInRange)
+ return false;
+ }
+ else
+ {
+ bool isInsideCylinder = target->IsWithinDist2d(_position, _range) && std::abs(target->GetPositionZ() - _position->GetPositionZ()) <= _range;
+ if (!isInsideCylinder)
+ return false;
+ }
+
return WorldObjectSpellTargetCheck::operator ()(target);
}
@@ -7779,7 +7795,7 @@ bool WorldObjectSpellConeTargetCheck::operator()(WorldObject* target)
}
else if (_spellInfo->HasAttribute(SPELL_ATTR0_CU_CONE_LINE))
{
- if (!_caster->HasInLine(target, target->GetObjectSize(), _caster->GetObjectSize()))
+ if (!_caster->HasInLine(target, target->GetCombatReach(), _caster->GetCombatReach()))
return false;
}
else
@@ -7796,7 +7812,7 @@ WorldObjectSpellTrajTargetCheck::WorldObjectSpellTrajTargetCheck(float range, Po
bool WorldObjectSpellTrajTargetCheck::operator()(WorldObject* target)
{
// return all targets on missile trajectory (0 - size of a missile)
- if (!_caster->HasInLine(target, target->GetObjectSize(), TRAJECTORY_MISSILE_SIZE))
+ if (!_caster->HasInLine(target, target->GetCombatReach(), TRAJECTORY_MISSILE_SIZE))
return false;
if (target->GetExactDist2d(_position) > _range)
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index e8ff2ced069..d98bf2e4812 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2565,7 +2565,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex effIndex)
float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
float fx, fy, fz;
- m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetObjectSize(), dis);
+ m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetCombatReach(), dis);
unitTarget->NearTeleportTo(fx, fy, fz, -m_caster->GetOrientation(), unitTarget == m_caster);
}
@@ -2990,7 +2990,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
//OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
float px, py, pz;
- owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
+ owner->GetClosePoint(px, py, pz, OldSummon->GetCombatReach());
OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
//OldSummon->Relocate(px, py, pz, OldSummon->GetOrientation());
@@ -3016,7 +3016,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
}
float x, y, z;
- owner->GetClosePoint(x, y, z, owner->GetObjectSize());
+ owner->GetClosePoint(x, y, z, owner->GetCombatReach());
Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET, 0);
if (!pet)
return;
@@ -3474,7 +3474,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
if (m_targets.HasDst())
destTarget->GetPosition(x, y, z);
else
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS);
Map* map = target->GetMap();
@@ -4412,7 +4412,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
destTarget->GetPosition(x, y, z);
// Summon in random point all other units if location present
else
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS);
Map* map = m_caster->GetMap();
G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f);
@@ -4669,7 +4669,7 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
if (m_preGeneratedPath.GetPathType() == PATHFIND_BLANK)
{
//unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
- Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetObjectSize(), unitTarget->GetRelativeAngle(m_caster));
+ Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetCombatReach(), unitTarget->GetRelativeAngle(m_caster));
m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed);
}
else
@@ -4902,7 +4902,7 @@ void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/)
// Reposition the pet's corpse before reviving so as not to grab aggro
// We can use a different, more accurate version of GetClosePoint() since we have a pet
float x, y, z; // Will be used later to reposition the pet if we have one
- player->GetClosePoint(x, y, z, pet->GetObjectSize(), PET_FOLLOW_DIST, pet->GetFollowAngle());
+ player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
pet->NearTeleportTo(x, y, z, player->GetOrientation());
pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
}
@@ -5051,7 +5051,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
{
float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
- m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
+ m_caster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
}
else
{
@@ -5060,7 +5060,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
float max_dis = m_spellInfo->GetMaxRange(true);
float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
- m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
+ m_caster->GetClosePoint(fx, fy, fz, DEFAULT_PLAYER_BOUNDING_RADIUS, dis);
}
Map* cMap = m_caster->GetMap();
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 1a3b58afa83..efa3d6e8c70 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -66,6 +66,35 @@ bool SpellImplicitTargetInfo::IsArea() const
return GetSelectionCategory() == TARGET_SELECT_CATEGORY_AREA || GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE;
}
+bool SpellImplicitTargetInfo::IsProximityBasedAoe() const
+{
+ switch (_target)
+ {
+ case TARGET_UNIT_SRC_AREA_ENTRY:
+ case TARGET_UNIT_SRC_AREA_ENEMY:
+ case TARGET_UNIT_CASTER_AREA_PARTY:
+ case TARGET_UNIT_SRC_AREA_ALLY:
+ case TARGET_UNIT_SRC_AREA_PARTY:
+ case TARGET_UNIT_LASTTARGET_AREA_PARTY:
+ case TARGET_GAMEOBJECT_SRC_AREA:
+ case TARGET_UNIT_CASTER_AREA_RAID:
+ case TARGET_CORPSE_SRC_AREA_ENEMY:
+ return true;
+
+ case TARGET_UNIT_DEST_AREA_ENTRY:
+ case TARGET_UNIT_DEST_AREA_ENEMY:
+ case TARGET_UNIT_DEST_AREA_ALLY:
+ case TARGET_UNIT_DEST_AREA_PARTY:
+ case TARGET_GAMEOBJECT_DEST_AREA:
+ case TARGET_UNIT_TARGET_AREA_RAID_CLASS:
+ return false;
+
+ default:
+ TC_LOG_WARN("spells", "SpellImplicitTargetInfo::IsProximityBasedAoe called a non-aoe spell");
+ return false;
+ }
+}
+
SpellTargetSelectionCategories SpellImplicitTargetInfo::GetSelectionCategory() const
{
return _data[_target].SelectionCategory;
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 31bf975428c..4550719b691 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -210,6 +210,7 @@ public:
SpellImplicitTargetInfo(uint32 target);
bool IsArea() const;
+ bool IsProximityBasedAoe() const;
SpellTargetSelectionCategories GetSelectionCategory() const;
SpellTargetReferenceTypes GetReferenceType() const;
SpellTargetObjectTypes GetObjectType() const;
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 32a299589a0..c907b8f41ad 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -927,7 +927,7 @@ public:
uint32 entry = (uint32)atoi(e);
float x, y, z, o = handler->GetSession()->GetPlayer()->GetOrientation();
- handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, handler->GetSession()->GetPlayer()->GetObjectSize());
+ handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, handler->GetSession()->GetPlayer()->GetCombatReach());
if (!i)
return handler->GetSession()->GetPlayer()->SummonCreature(entry, x, y, z, o) != nullptr;
diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp
index ec09e960303..60d6f3116b5 100644
--- a/src/server/scripts/Commands/cs_group.cpp
+++ b/src/server/scripts/Commands/cs_group.cpp
@@ -135,7 +135,7 @@ public:
// before GM
float x, y, z;
- gmPlayer->GetClosePoint(x, y, z, player->GetObjectSize());
+ gmPlayer->GetClosePoint(x, y, z, player->GetCombatReach());
player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation());
}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 2cf1f39b394..5b8764c0e45 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -561,7 +561,7 @@ public:
// before GM
float x, y, z;
- handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize());
+ handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetCombatReach());
target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation());
target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), true);
}
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index f80c6519b29..22bb02ae547 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -1372,7 +1372,7 @@ public:
// place pet before player
float x, y, z;
- player->GetClosePoint (x, y, z, creatureTarget->GetObjectSize(), CONTACT_DISTANCE);
+ player->GetClosePoint (x, y, z, creatureTarget->GetCombatReach(), CONTACT_DISTANCE);
pet->Relocate(x, y, z, float(M_PI) - player->GetOrientation());
// set pet to defensive mode by default (some classes can't control controlled pets in fact).
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
index 607edc61423..1d738d56984 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
@@ -123,7 +123,7 @@ class boss_selin_fireheart : public CreatureScript
Crystals.remove(CrystalChosen);
float x, y, z;
- CrystalChosen->GetClosePoint(x, y, z, me->GetObjectSize(), CONTACT_DISTANCE);
+ CrystalChosen->GetClosePoint(x, y, z, me->GetCombatReach(), CONTACT_DISTANCE);
events.SetPhase(PHASE_DRAIN);
me->SetWalk(false);
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
index f1904a50e04..fdc3cb622c4 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
@@ -99,7 +99,7 @@ public:
FlyBackTimer = 500;
break;
case 1:
- player->GetClosePoint(x, y, z, me->GetObjectSize());
+ player->GetClosePoint(x, y, z, me->GetCombatReach());
z += 2.5f;
x -= 2.0f;
y -= 1.5f;
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp
index 58c7f780adb..84734e48381 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_king_dred.cpp
@@ -144,7 +144,7 @@ class boss_king_dred : public CreatureScript
float x, y, z;
- me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 10.0f);
+ me->GetClosePoint(x, y, z, me->GetCombatReach() / 3, 10.0f);
me->SummonCreature(RAND(NPC_DRAKKARI_GUTRIPPER, NPC_DRAKKARI_SCYTHECLAW), x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000);
events.ScheduleEvent(EVENT_RAPTOR_CALL, urand(20000, 25000));
break;
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
index a71214b7974..a7e679433c5 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
@@ -127,7 +127,7 @@ class boss_bronjahm : public CreatureScript
{
summons.Summon(summon);
summon->SetReactState(REACT_PASSIVE);
- summon->GetMotionMaster()->MoveFollow(me, me->GetObjectSize(), 0.0f);
+ summon->GetMotionMaster()->MoveFollow(me, me->GetCombatReach(), 0.0f);
summon->CastSpell(summon, SPELL_PURPLE_BANISH_VISUAL, true);
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index c907aa14c3c..e8110a32438 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -788,7 +788,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_DEATHBRINGER_SAURFANG)))
{
float x, y, z;
- deathbringer->GetClosePoint(x, y, z, deathbringer->GetObjectSize());
+ deathbringer->GetClosePoint(x, y, z, deathbringer->GetCombatReach());
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_CORPSE, x, y, z);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
index 6a794e36b56..361516582c6 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
@@ -383,7 +383,7 @@ class npc_coldflame : public CreatureScript
{
float ang = Position::NormalizeOrientation(pos.GetAngle(me));
me->SetOrientation(ang);
- owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 5.0f - owner->GetObjectSize(), ang);
+ owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 5.0f - owner->GetCombatReach(), ang);
}
else
{
@@ -396,7 +396,7 @@ class npc_coldflame : public CreatureScript
float ang = Position::NormalizeOrientation(pos.GetAngle(target));
me->SetOrientation(ang);
- owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 15.0f - owner->GetObjectSize(), ang);
+ owner->GetNearPoint2D(pos.m_positionX, pos.m_positionY, 15.0f - owner->GetCombatReach(), ang);
}
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me->GetPositionZ(), me->GetOrientation());
@@ -514,7 +514,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader
{
targets.clear();
// select any unit but not the tank (by owners threatlist)
- Unit* target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 1, -GetCaster()->GetObjectSize(), true, -SPELL_IMPALED);
+ Unit* target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 1, -GetCaster()->GetCombatReach(), true, -SPELL_IMPALED);
if (!target)
target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); // or the tank if its solo
if (!target)
diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp
index 26b521a95c7..0199340d0b9 100644
--- a/src/server/scripts/Northrend/zone_zuldrak.cpp
+++ b/src/server/scripts/Northrend/zone_zuldrak.cpp
@@ -55,7 +55,7 @@ public:
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
float x, y, z;
- me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 0.1f);
+ me->GetClosePoint(x, y, z, me->GetCombatReach() / 3, 0.1f);
if (Creature* summon = me->SummonCreature(NPC_RAGECLAW, x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000))
{
@@ -180,7 +180,7 @@ public:
void Reset() override
{
float x, y, z;
- me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 25.0f);
+ me->GetClosePoint(x, y, z, me->GetCombatReach() / 3, 25.0f);
me->GetMotionMaster()->MovePoint(0, x, y, z);
}
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 3e8b3e4ca95..1f3a7c569ea 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -521,7 +521,7 @@ public:
Tapped = true;
float x, y, z;
- caster->GetClosePoint(x, y, z, me->GetObjectSize());
+ caster->GetClosePoint(x, y, z, me->GetCombatReach());
me->SetWalk(false);
me->GetMotionMaster()->MovePoint(1, x, y, z);
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index ccdde9eb799..12e89755963 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -356,7 +356,7 @@ public:
uint32 BirdEntry = 0;
float fX, fY, fZ;
- go->GetClosePoint(fX, fY, fZ, go->GetObjectSize(), INTERACTION_DISTANCE);
+ go->GetClosePoint(fX, fY, fZ, go->GetCombatReach(), INTERACTION_DISTANCE);
switch (go->GetEntry())
{
diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp
index 5ce6a8301dd..64caa7ec4d1 100644
--- a/src/server/scripts/World/item_scripts.cpp
+++ b/src/server/scripts/World/item_scripts.cpp
@@ -240,7 +240,7 @@ public:
return true;
float x, y, z;
- go->GetClosePoint(x, y, z, go->GetObjectSize() / 3, 7.0f);
+ go->GetClosePoint(x, y, z, go->GetCombatReach() / 3, 7.0f);
go->SummonGameObject(GO_HIGH_QUALITY_FUR, *go, G3D::Quat(), 1);
if (TempSummon* summon = player->SummonCreature(NPC_NESINGWARY_TRAPPER, x, y, z, go->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 1000))
{