diff options
| author | Chaouki Dhib <chaodhib@gmail.com> | 2017-03-23 00:43:04 +0100 |
|---|---|---|
| committer | Treeston <treeston.mmoc@gmail.com> | 2017-03-23 00:43:04 +0100 |
| commit | a1f2f30c145f6ad9c4baeffeff32618e71ff537c (patch) | |
| tree | a4c6205c64f22b66d887585aa2778cbf443d9764 /src/server/game/Entities | |
| parent | a88d4e9b0014c7204249fc354168878b0e3abb8e (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.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 81 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 16 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Position.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Position.h | 5 | ||||
| -rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 4 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 |
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; |
