diff options
| author | Chaouki Dhib <chaodhib@gmail.com> | 2017-03-23 00:43:04 +0100 |
|---|---|---|
| committer | funjoker <funjoker109@gmail.com> | 2020-04-24 17:18:49 +0200 |
| commit | 5d076cfe291980bc5be9d44ffbae887e3dd5ad59 (patch) | |
| tree | ac91fc74a4643ce7c1a525c2739af2dcfa3f05ed /src/server/game/Entities/Object | |
| parent | b8b6fd9ca0defda540f122bedf5f187d45bc11c7 (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.
(cherry picked from commit a1f2f30c145f6ad9c4baeffeff32618e71ff537c)
Diffstat (limited to 'src/server/game/Entities/Object')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 84 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 6 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/ObjectDefines.h | 10 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Position.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Position.h | 5 |
5 files changed, 53 insertions, 58 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index c0fbdaaf530..94fd3e932c8 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -969,39 +969,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() == GetTransport()->GetGUID()) { - 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 @@ -1020,31 +1012,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; } @@ -1064,22 +1056,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 @@ -1087,9 +1079,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) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D); + return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D, incOwnRadius, incTargetRadius); } bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFlags ignoreFlags) const @@ -1116,7 +1108,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)); } @@ -1163,7 +1155,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) @@ -1183,7 +1175,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) @@ -1204,7 +1196,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) @@ -1227,7 +1219,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); @@ -1837,7 +1829,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(); } @@ -1879,7 +1871,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(); } @@ -1993,8 +1985,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); @@ -2066,15 +2058,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 -{ - if (Unit const* thisUnit = ToUnit()) - return thisUnit->m_unitData->CombatReach; - - return 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 c5e22c86c3a..1d48e1f2384 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -395,7 +395,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; @@ -445,7 +445,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; @@ -605,7 +605,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/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index b0db49bcf9f..43f2ea15a4d 100644 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -36,11 +36,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 class VisibilityDistanceType : uint8 { diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp index ae0fc14e173..a63a3da76d6 100644 --- a/src/server/game/Entities/Object/Position.cpp +++ b/src/server/game/Entities/Object/Position.cpp @@ -148,6 +148,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 37f1231e709..f247c7fb860 100644 --- a/src/server/game/Entities/Object/Position.h +++ b/src/server/game/Entities/Object/Position.h @@ -218,6 +218,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; |
