From a6fca96307aa3d6403faa0c83147346052f810ab Mon Sep 17 00:00:00 2001 From: killerwife Date: Wed, 1 Nov 2023 22:12:33 +0100 Subject: [PATCH] GameObject: Fix sitting on chairs on a transport --- src/game/Entities/GameObject.cpp | 17 +++++++++-------- src/game/Entities/Object.cpp | 7 ++++--- src/game/Entities/Object.h | 2 +- src/game/Entities/Unit.cpp | 2 +- src/game/Spells/SpellHandler.cpp | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/game/Entities/GameObject.cpp b/src/game/Entities/GameObject.cpp index 0fe8b849c4b..7a9dc07a74d 100644 --- a/src/game/Entities/GameObject.cpp +++ b/src/game/Entities/GameObject.cpp @@ -2930,29 +2930,30 @@ SpellEntry const* GameObject::GetSpellForLock(Player const* player) const std::pair GameObject::GetClosestChairSlotPosition(Unit* user) const { + Position pos = GetPosition(GetTransport()); float outX, outY; // check if the db is sane if (GetGOInfo()->chair.slots > 0) { float lowestDist = DEFAULT_VISIBILITY_DISTANCE; - float x_lowest = GetPositionX(); - float y_lowest = GetPositionY(); + float x_lowest = pos.GetPositionX(); + float y_lowest = pos.GetPositionY(); // the object orientation + 1/2 pi // every slot will be on that straight line - float orthogonalOrientation = GetOrientation() + M_PI_F * 0.5f; + float orthogonalOrientation = pos.GetPositionO() + M_PI_F * 0.5f; // find nearest slot for (uint32 i = 0; i < GetGOInfo()->chair.slots; ++i) { // the distance between this slot and the center of the go - imagine a 1D space float relativeDistance = (GetGOInfo()->size * i) - (GetGOInfo()->size * (GetGOInfo()->chair.slots - 1) / 2.0f); - float slotX = GetPositionX() + relativeDistance * cos(orthogonalOrientation); - float slotY = GetPositionY() + relativeDistance * sin(orthogonalOrientation); + float slotX = pos.GetPositionX() + relativeDistance * cos(orthogonalOrientation); + float slotY = pos.GetPositionY() + relativeDistance * sin(orthogonalOrientation); // calculate the distance between the user and this slot - float thisDistance = user->GetDistance2d(slotX, slotY, DIST_CALC_NONE); + float thisDistance = user->GetDistance2d(slotX, slotY, DIST_CALC_NONE, GetTransport()); if (thisDistance <= lowestDist) { @@ -2966,8 +2967,8 @@ std::pair GameObject::GetClosestChairSlotPosition(Unit* user) cons } else { - outX = GetPositionX(); - outY = GetPositionY(); + outX = pos.GetPositionX(); + outY = pos.GetPositionY(); } return {outX, outY}; diff --git a/src/game/Entities/Object.cpp b/src/game/Entities/Object.cpp index da514380eb4..6a0110e3a4e 100644 --- a/src/game/Entities/Object.cpp +++ b/src/game/Entities/Object.cpp @@ -1471,10 +1471,11 @@ float WorldObject::GetDistance(float x, float y, float z, DistanceCalculation di } } -float WorldObject::GetDistance2d(float x, float y, DistanceCalculation distcalc) const +float WorldObject::GetDistance2d(float x, float y, DistanceCalculation distcalc, bool transport) const { - float dx = GetPositionX() - x; - float dy = GetPositionY() - y; + Position const& pos = GetPosition(transport ? GetTransport() : nullptr); + float dx = pos.x - x; + float dy = pos.y - y; float dist = dx * dx + dy * dy; switch (distcalc) diff --git a/src/game/Entities/Object.h b/src/game/Entities/Object.h index 87c105de309..34d23996388 100644 --- a/src/game/Entities/Object.h +++ b/src/game/Entities/Object.h @@ -1068,7 +1068,7 @@ class WorldObject : public Object float GetDistance(const WorldObject* obj, bool is3D = true, DistanceCalculation distcalc = DIST_CALC_BOUNDING_RADIUS) const; float GetDistance(float x, float y, float z, DistanceCalculation distcalc = DIST_CALC_BOUNDING_RADIUS, bool transport = false) const; - float GetDistance2d(float x, float y, DistanceCalculation distcalc = DIST_CALC_BOUNDING_RADIUS) const; + float GetDistance2d(float x, float y, DistanceCalculation distcalc = DIST_CALC_BOUNDING_RADIUS, bool transport = false) const; float GetDistanceZ(const WorldObject* obj) const; bool IsInMapIgnorePhase(const WorldObject* obj) const // only to be used by spells which ignore phase during search and similar { diff --git a/src/game/Entities/Unit.cpp b/src/game/Entities/Unit.cpp index b84ef4324aa..d58ef5a7393 100644 --- a/src/game/Entities/Unit.cpp +++ b/src/game/Entities/Unit.cpp @@ -11796,7 +11796,7 @@ void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool cas uint32 options = (transportLeave ? 0 : TELE_TO_NOT_LEAVE_TRANSPORT) | (casting ? TELE_TO_SPELL : 0); if (GetDistance(x, y, z, DIST_CALC_NONE) < 100.f * 100.f) options |= TELE_TO_NOT_LEAVE_COMBAT; - static_cast(this)->TeleportTo(GetMapId(), x, y, z, orientation, options); + static_cast(this)->TeleportTo(GetMapId(), x, y, z, orientation, options, nullptr, !transportLeave ? GetTransport() : nullptr); } else { diff --git a/src/game/Spells/SpellHandler.cpp b/src/game/Spells/SpellHandler.cpp index 4ed5a58ed29..3f0ac07f19e 100644 --- a/src/game/Spells/SpellHandler.cpp +++ b/src/game/Spells/SpellHandler.cpp @@ -346,7 +346,7 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPacket& recv_data) { float x, y; std::tie(x, y) = obj->GetClosestChairSlotPosition(_player); - if (_player->GetDistance(x, y, obj->GetPositionZ(), DIST_CALC_NONE) > 3.f * 3.f) + if (_player->GetDistance(x, y, obj->GetPositionZ(), DIST_CALC_NONE, obj->GetTransport()) > 3.f * 3.f) return; }