From 193da38f749ad9eff4bb39fcb5febe1d3ddca131 Mon Sep 17 00:00:00 2001 From: blinkysc <37940565+blinkysc@users.noreply.github.com> Date: Fri, 6 Feb 2026 05:48:33 -0600 Subject: [PATCH] fix(Commands): .go creature and .appear support transports (#23969) Co-authored-by: blinkysc Co-authored-by: sudlud --- src/server/scripts/Commands/cs_go.cpp | 85 ++++++++++++++++++++++++- src/server/scripts/Commands/cs_misc.cpp | 35 ++++++++-- 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 2e59bf7cf..88a7df172 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -23,6 +23,7 @@ #include "ObjectMgr.h" #include "Player.h" #include "TicketMgr.h" +#include "Transport.h" #include "boost/algorithm/string.hpp" #include @@ -66,7 +67,11 @@ public: if (mapId == MAPID_INVALID) mapId = player->GetMapId(); - if (!MapMgr::IsValidMapCoord(mapId, pos) || sObjectMgr->IsTransportMap(mapId)) + + if (sObjectMgr->IsTransportMap(mapId)) + return DoTeleportToTransport(handler, pos, mapId); + + if (!MapMgr::IsValidMapCoord(mapId, pos)) { handler->SendErrorMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), mapId); return false; @@ -86,6 +91,84 @@ public: return true; } + static bool DoTeleportToTransport(ChatHandler* handler, Position pos, uint32 transportMapId) + { + Player* player = handler->GetSession()->GetPlayer(); + + uint32 transportEntry = 0; + for (auto const& [entry, goTemplate] : *sObjectMgr->GetGameObjectTemplates()) + { + if (goTemplate.type == GAMEOBJECT_TYPE_MO_TRANSPORT && goTemplate.moTransport.mapID == transportMapId) + { + transportEntry = entry; + break; + } + } + + if (!transportEntry) + { + handler->SendErrorMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), transportMapId); + return false; + } + + MotionTransport* transport = nullptr; + sMapMgr->DoForAllMaps([&](Map* map) + { + if (transport) + return; + + for (Transport* t : map->GetAllTransports()) + { + if (MotionTransport* mt = t->ToMotionTransport()) + { + if (mt->GetEntry() == transportEntry) + { + transport = mt; + return; + } + } + } + }); + + if (!transport) + { + handler->SendErrorMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), transportMapId); + return false; + } + + if (player->IsInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); + } + else + player->SaveRecallPosition(); + + if (Transport* oldTransport = player->GetTransport()) + oldTransport->RemovePassenger(player, true); + + float const localX = pos.GetPositionX(); + float const localY = pos.GetPositionY(); + float const localZ = pos.GetPositionZ(); + float const localO = pos.GetOrientation(); + + player->SetTransport(transport); + player->m_movementInfo.transport.guid = transport->GetGUID(); + player->m_movementInfo.transport.pos.Relocate(localX, localY, localZ, localO); + player->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + + float worldX = localX; + float worldY = localY; + float worldZ = localZ; + float worldO = localO; + transport->CalculatePassengerPosition(worldX, worldY, worldZ, &worldO); + + transport->AddPassenger(player, false); + + player->TeleportTo(transport->GetMapId(), worldX, worldY, worldZ, worldO, TELE_TO_NOT_LEAVE_TRANSPORT); + return true; + } + static bool HandleGoCreatureCIdCommand(ChatHandler* handler, Variant, uint32> cId, Optional _pos) { uint32 pos = 1; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 6c53573b6..559b6eb67 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -46,6 +46,7 @@ #include "SpellAuras.h" #include "TargetedMovementGenerator.h" #include "Tokenize.h" +#include "Transport.h" #include "WeatherMgr.h" #include "WorldSessionMgr.h" @@ -877,13 +878,39 @@ public: _player->CleanupAfterTaxiFlight(); } else // save only in non-flight case - { _player->SaveRecallPosition(); - } - if (_player->TeleportTo(targetPlayer->GetMapId(), targetPlayer->GetPositionX(), targetPlayer->GetPositionY(), targetPlayer->GetPositionZ() + 0.25f, _player->GetOrientation(), TELE_TO_GM_MODE, targetPlayer)) + if (Transport* transport = targetPlayer->GetTransport()) { - _player->SetPhaseMask(targetPlayer->GetPhaseMask() | 1, false); + if (Transport* oldTransport = _player->GetTransport()) + oldTransport->RemovePassenger(_player, true); + + float x; + float y; + float z; + float o; + targetPlayer->m_movementInfo.transport.pos.GetPosition(x, y, z, o); + + _player->SetTransport(transport); + _player->m_movementInfo.transport.guid = transport->GetGUID(); + _player->m_movementInfo.transport.pos.Relocate(x, y, z, o); + _player->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + + float worldX = x; + float worldY = y; + float worldZ = z; + float worldO = o; + transport->CalculatePassengerPosition(worldX, worldY, worldZ, &worldO); + + transport->AddPassenger(_player, false); + + if (_player->TeleportTo(transport->GetMapId(), worldX, worldY, worldZ + 0.25f, worldO, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_GM_MODE, targetPlayer)) + _player->SetPhaseMask(targetPlayer->GetPhaseMask() | 1, false); + } + else + { + if (_player->TeleportTo(targetPlayer->GetMapId(), targetPlayer->GetPositionX(), targetPlayer->GetPositionY(), targetPlayer->GetPositionZ() + 0.25f, _player->GetOrientation(), TELE_TO_GM_MODE, targetPlayer)) + _player->SetPhaseMask(targetPlayer->GetPhaseMask() | 1, false); } } else