Skip to content

Commit

Permalink
Transport: Enable corpse boarding onto transport and sending proper p…
Browse files Browse the repository at this point in the history
…rotocol
  • Loading branch information
killerwife committed Feb 20, 2025
1 parent d5bf5e1 commit f51a7d0
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 35 deletions.
11 changes: 9 additions & 2 deletions src/game/Entities/GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ bool GameObject::Create(uint32 dbGuid, uint32 guidlow, uint32 name_id, Map* map,
return false;
}

Object::_Create(dbGuid, guidlow, goinfo->id, HIGHGUID_GAMEOBJECT);
Object::_Create(dbGuid, guidlow, goinfo->id, goinfo->GetHighGuid());

m_goInfo = goinfo;

Expand Down Expand Up @@ -944,8 +944,15 @@ bool GameObject::LoadFromDB(uint32 dbGuid, Map* map, uint32 newGuid, uint32 forc
dynguid = true;
}

GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(entry);
if (!goinfo)
{
sLog.outErrorDb("Gameobject (GUID: %u) not created: Entry %u does not exist in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f) ang: %f", dbGuid, entry, map->GetId(), x, y, z, ang);
return false;
}

if (dynguid || newGuid == 0)
newGuid = map->GenerateLocalLowGuid(HIGHGUID_GAMEOBJECT);
newGuid = map->GenerateLocalLowGuid(goinfo->GetHighGuid());

if (!Create(dbGuid, newGuid, entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, GO_STATE_READY))
return false;
Expand Down
12 changes: 12 additions & 0 deletions src/game/Entities/GameObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,18 @@ struct GameObjectInfo
default: return false;
}
}

HighGuid GetHighGuid() const
{
switch (type)
{
case GAMEOBJECT_TYPE_TRANSPORT:
case GAMEOBJECT_TYPE_MO_TRANSPORT:
case GAMEOBJECT_TYPE_TRAPDOOR:
return HIGHGUID_MO_TRANSPORT;
default: return HIGHGUID_GAMEOBJECT;
}
}
};

// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
Expand Down
2 changes: 1 addition & 1 deletion src/game/Entities/ObjectGuid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid)
template uint32 ObjectGuidGenerator<HIGHGUID_ITEM>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_PLAYER>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_GAMEOBJECT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_TRANSPORT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_UNIT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_PET>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_VEHICLE>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_CORPSE>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_INSTANCE>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_GROUP>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_MO_TRANSPORT>::Generate();
4 changes: 3 additions & 1 deletion src/game/Entities/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4890,6 +4890,8 @@ void Player::BuildPlayerRepop()
return;
}
GetMap()->Add(corpse);
if (GenericTransport* transport = GetTransport())
transport->AddPassenger(corpse, true);

// convert player body to ghost
SetHealth(1);
Expand Down Expand Up @@ -5369,7 +5371,7 @@ void Player::RepopAtGraveyard()
AreaTableEntry const* zone = GetAreaEntryByAreaID(GetAreaId());

// Such zones are considered unreachable as a ghost and the player must be automatically revived
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) || GetTransport())
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) || (GetTransport() && GetTransport()->IsCrossMapTransport()))
{
ResurrectPlayer(0.5f);
SpawnCorpseBones();
Expand Down
46 changes: 30 additions & 16 deletions src/game/Entities/QueryHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "Entities/NPCHandler.h"
#include "Server/SQLStorages.h"
#include "Maps/GridDefines.h"
#include "Entities/Transports.h"

void WorldSession::SendNameQueryResponse(CharacterNameQueryResponse& response) const
{
Expand Down Expand Up @@ -306,9 +307,7 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recv_data*/)
}

uint32 corpsemapid = corpse->GetMapId();
float x = corpse->GetPositionX();
float y = corpse->GetPositionY();
float z = corpse->GetPositionZ();
Position pos = corpse->GetPosition(corpse->GetTransport());
int32 mapid = corpsemapid;

// if corpse at different map
Expand All @@ -323,9 +322,9 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recv_data*/)
if (TerrainInfo const* entranceMap = sTerrainMgr.LoadTerrain(corpseMapEntry->ghost_entrance_map))
{
mapid = corpseMapEntry->ghost_entrance_map;
x = corpseMapEntry->ghost_entrance_x;
y = corpseMapEntry->ghost_entrance_y;
z = entranceMap->GetHeightStatic(x, y, MAX_HEIGHT);
pos.x = corpseMapEntry->ghost_entrance_x;
pos.y = corpseMapEntry->ghost_entrance_y;
pos.z = entranceMap->GetHeightStatic(pos.x, pos.y, MAX_HEIGHT);
}
}
}
Expand All @@ -334,11 +333,11 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recv_data*/)
WorldPacket data(MSG_CORPSE_QUERY, 1 + (6 * 4));
data << uint8(1); // corpse found
data << int32(mapid);
data << float(x);
data << float(y);
data << float(z);
data << float(pos.GetPositionX());
data << float(pos.GetPositionY());
data << float(pos.GetPositionZ());
data << uint32(corpsemapid);
data << uint32(0); // unknown
data << uint32(corpse->GetTransport() != nullptr ? corpse->GetTransport()->GetObjectGuid().GetCounter() : 0);
SendPacket(data);
}

Expand Down Expand Up @@ -476,14 +475,29 @@ void WorldSession::HandleCorpseMapPositionQueryOpcode(WorldPacket& recv_data)
{
DEBUG_LOG("WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY");

uint32 unk;
recv_data >> unk;
uint32 transportCounter;
recv_data >> transportCounter;

Corpse* corpse = GetPlayer()->GetCorpse();

if (!corpse || !corpse->GetTransport() || corpse->GetTransport()->GetObjectGuid().GetCounter() != transportCounter)
{
WorldPacket data(SMSG_CORPSE_TRANSPORT_QUERY, 4 + 4 + 4 + 4);
data << float(0);
data << float(0);
data << float(0);
data << float(0);
SendPacket(data);
return;
}

Position pos = corpse->GetTransport()->GetPosition();

WorldPacket data(SMSG_CORPSE_TRANSPORT_QUERY, 4 + 4 + 4 + 4);
data << float(0);
data << float(0);
data << float(0);
data << float(0);
data << float(pos.GetPositionX());
data << float(pos.GetPositionY());
data << float(pos.GetPositionZ());
data << float(pos.GetPositionO());
SendPacket(data);
}

Expand Down
23 changes: 17 additions & 6 deletions src/game/Entities/Transports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ void MapManager::LoadTransports()

transportTemplate->pathTime = period;
transportTemplate->keyFrames.back().DepartureTime = period;
transportTemplate->counter = count + 1;

m_transportsByMap[pMapInfo->MapID].push_back(transportTemplate);
m_transportsByEntry[entry].push_back(transportTemplate);
Expand All @@ -116,6 +117,8 @@ void MapManager::LoadTransports()
while (queryResult->NextRow());
}

m_transportCounter = count + 2;

sLog.outString(">> Loaded %u transports", count);
sLog.outString();
}
Expand Down Expand Up @@ -167,7 +170,7 @@ void Transport::LoadTransport(TransportTemplate const& transportTemplate, Map* m
t->Object::AddToWorld();

// creates the Gameobject
if (!t->Create(transportTemplate.entry, map->GetId(), x, y, z, o, GO_ANIMPROGRESS_DEFAULT, 0))
if (!t->Create(transportTemplate.counter, transportTemplate.entry, map->GetId(), x, y, z, o, GO_ANIMPROGRESS_DEFAULT, 0))
{
delete t;
return;
Expand All @@ -181,25 +184,25 @@ void Transport::LoadTransport(TransportTemplate const& transportTemplate, Map* m
t->UpdateForMap(map, true);
}

bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint8 animprogress, uint16 dynamicHighValue)
bool Transport::Create(uint32 counter, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint8 animprogress, uint16 dynamicHighValue)
{
Relocate(x, y, z, ang);
// instance id and phaseMask isn't set to values different from std.

if (!IsPositionValid())
{
sLog.outError("Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
guidlow, x, y);
counter, x, y);
return false;
}

Object::_Create(guidlow, guidlow, 0, HIGHGUID_MO_TRANSPORT);
Object::_Create(counter, counter, 0, HIGHGUID_MO_TRANSPORT);

GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(guidlow);
GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(entry);

if (!goinfo)
{
sLog.outErrorDb("Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, x, y, z, ang);
sLog.outErrorDb("Transport not created: entry in `gameobject_template` not found, entry: %u map: %u (X: %f Y: %f Z: %f) ang: %f", entry, mapid, x, y, z, ang);
return false;
}

Expand Down Expand Up @@ -281,6 +284,11 @@ void Transport::DespawnPassengers()
m_staticPassengers.clear();
}

bool Transport::IsCrossMapTransport() const
{
return m_transportTemplate.mapsUsed.size() > 1;
}

void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, float /*o*/)
{
Map* oldMap = GetMap();
Expand Down Expand Up @@ -802,6 +810,9 @@ void GenericTransport::UpdatePassengerPosition(WorldObject* passenger)
case TYPEID_DYNAMICOBJECT:
GetMap()->DynamicObjectRelocation(static_cast<DynamicObject*>(passenger), x, y, z, o);
break;
case TYPEID_CORPSE:
GetMap()->CorpseRelocation(static_cast<Corpse*>(passenger), x, y, z, o);
break;
default:
break;
}
Expand Down
8 changes: 7 additions & 1 deletion src/game/Entities/Transports.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class GenericTransport : public GameObject
virtual void SpawnPassengers() {}
virtual void SpawnPassengersIfDespawned() {}
virtual void DespawnPassengers() {}

virtual bool IsCrossMapTransport() const = 0;
protected:
void UpdatePassengerPositions(PassengerSet& passengers);

Expand All @@ -85,6 +87,8 @@ class ElevatorTransport : public GenericTransport
void Update(const uint32 diff) override;

void SetGoState(GOState state) override;

bool IsCrossMapTransport() const { return false; }
private:
TransportAnimation const* m_animationInfo;
uint32 m_currentSeg;
Expand All @@ -98,7 +102,7 @@ class Transport : public GenericTransport

static bool IsSpawnedByDefault(uint32 entry, Team team);
static void LoadTransport(TransportTemplate const& transportTemplate, Map* map, bool spawnOnDemand = false);
bool Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint8 animprogress, uint16 dynamicHighValue);
bool Create(uint32 counter, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint8 animprogress, uint16 dynamicHighValue);
void Update(const uint32 diff) override;

uint32 GetPeriod() const { return m_period; }
Expand All @@ -109,6 +113,8 @@ class Transport : public GenericTransport
void SpawnPassengers() override;
void SpawnPassengersIfDespawned() override;
void DespawnPassengers() override;

bool IsCrossMapTransport() const override;
private:
void TeleportTransport(uint32 newMapid, float x, float y, float z, float o);
void UpdateForMap(Map const* targetMap, bool newMap);
Expand Down
42 changes: 36 additions & 6 deletions src/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
m_variableManager(this)
{
m_weatherSystem = new WeatherSystem(this);
m_transportGuids.Set(sMapMgr.GetTransportCounter());
}

void Map::Initialize(bool loadInstanceData /*= true*/)
Expand Down Expand Up @@ -1308,11 +1309,40 @@ void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float
AddToGrid(dynObj, newGrid, new_cell);
dynObj->GetViewPoint().Event_GridChanged(&(*newGrid)(new_cell.CellX(), new_cell.CellY()));
}
else

dynObj->Relocate(x, y, z, orientation);
dynObj->UpdateObjectVisibility();
}

void Map::CorpseRelocation(Corpse* corpse, float x, float y, float z, float orientation)
{
Cell new_cell(MaNGOS::ComputeCellPair(x, y));
Cell old_cell = corpse->GetCurrentCell();

if (!getNGrid(new_cell.GridX(), new_cell.GridY()))
return;

if (old_cell.DiffGrid(new_cell))
{
dynObj->Relocate(x, y, z, orientation);
dynObj->UpdateObjectVisibility();
if (!corpse->isActiveObject() && !loaded(new_cell.gridPair()))
{
DEBUG_FILTER_LOG(LOG_FILTER_CREATURE_MOVES, "Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", corpse->GetGUIDLow(), corpse->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
return;
}
EnsureGridLoadedAtEnter(new_cell);
}

// delay corpse move for grid/cell to grid/cell moves
if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
{
NGridType* oldGrid = getNGrid(old_cell.GridX(), old_cell.GridY());
NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
RemoveFromGrid(corpse, oldGrid, old_cell);
AddToGrid(corpse, newGrid, new_cell);
}

corpse->Relocate(x, y, z, orientation);
corpse->UpdateObjectVisibility();
}

bool Map::CreatureCellRelocation(Creature* c, const Cell& new_cell)
Expand Down Expand Up @@ -2608,7 +2638,7 @@ WorldObject* Map::GetWorldObject(ObjectGuid guid)
switch (guid.GetHigh())
{
case HIGHGUID_PLAYER: return GetPlayer(guid);
case HIGHGUID_TRANSPORT:
case HIGHGUID_MO_TRANSPORT:
case HIGHGUID_GAMEOBJECT: return GetGameObject(guid);
case HIGHGUID_UNIT:
case HIGHGUID_VEHICLE: return GetCreature(guid);
Expand All @@ -2620,7 +2650,6 @@ WorldObject* Map::GetWorldObject(ObjectGuid guid)
Corpse* corpse = GetCorpse(guid);
return corpse && corpse->IsInWorld() ? corpse : nullptr;
}
case HIGHGUID_MO_TRANSPORT:
default: break;
}

Expand Down Expand Up @@ -2775,7 +2804,6 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
{
case HIGHGUID_UNIT:
return m_CreatureGuids.Generate();
case HIGHGUID_TRANSPORT:
case HIGHGUID_GAMEOBJECT:
return m_GameObjectGuids.Generate();
case HIGHGUID_DYNAMICOBJECT:
Expand All @@ -2784,6 +2812,8 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
return m_PetGuids.Generate();
case HIGHGUID_VEHICLE:
return m_VehicleGuids.Generate();
case HIGHGUID_MO_TRANSPORT:
return m_transportGuids.Generate();
default:
MANGOS_ASSERT(false);
return 0;
Expand Down
3 changes: 2 additions & 1 deletion src/game/Maps/Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ class Map : public GridRefManager<NGridType>
void CreatureRelocation(Creature* creature, float x, float y, float z, float ang);
void GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail = true);
void DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float z, float orientation);
void CorpseRelocation(Corpse* corpse, float x, float y, float z, float orientation);

template<class T, class CONTAINER> void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER>& visitor);

Expand Down Expand Up @@ -540,10 +541,10 @@ class Map : public GridRefManager<NGridType>
// Map local low guid counters
ObjectGuidGenerator<HIGHGUID_UNIT> m_CreatureGuids;
ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_GameObjectGuids;
ObjectGuidGenerator<HIGHGUID_TRANSPORT> m_transportGuids;
ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT> m_DynObjectGuids;
ObjectGuidGenerator<HIGHGUID_PET> m_PetGuids;
ObjectGuidGenerator<HIGHGUID_VEHICLE> m_VehicleGuids;
ObjectGuidGenerator<HIGHGUID_MO_TRANSPORT> m_transportGuids;

// Type specific code for add/remove to/from grid
template<class T>
Expand Down
2 changes: 1 addition & 1 deletion src/game/Maps/MapManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ INSTANTIATE_SINGLETON_2(MapManager, CLASS_LOCK);
INSTANTIATE_CLASS_MUTEX(MapManager, std::recursive_mutex);

MapManager::MapManager()
: i_gridCleanUpDelay(sWorld.getConfig(CONFIG_UINT32_INTERVAL_GRIDCLEAN))
: i_gridCleanUpDelay(sWorld.getConfig(CONFIG_UINT32_INTERVAL_GRIDCLEAN)), m_transportCounter(0)
{
i_timer.SetInterval(sWorld.getConfig(CONFIG_UINT32_INTERVAL_MAPUPDATE));
}
Expand Down
Loading

0 comments on commit f51a7d0

Please sign in to comment.