aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
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 /src/server/game/Entities
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.
Diffstat (limited to 'src/server/game/Entities')
-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
10 files changed, 63 insertions, 65 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;