fix(Commands): .go creature and .appear support transports (#23969)

Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
Co-authored-by: sudlud <sudlud@users.noreply.github.com>
This commit is contained in:
blinkysc
2026-02-06 05:48:33 -06:00
committed by GitHub
parent 4f5a63f1d1
commit 193da38f74
2 changed files with 115 additions and 5 deletions

View File

@@ -23,6 +23,7 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "TicketMgr.h"
#include "Transport.h"
#include "boost/algorithm/string.hpp"
#include <regex>
@@ -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<Hyperlink<creature_entry>, uint32> cId, Optional<uint32> _pos)
{
uint32 pos = 1;

View File

@@ -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