diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 37605de21..1b8ccd047 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -156,8 +156,8 @@ public: void SaveToDB(bool saveAddon = false); void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, bool saveAddon = false); - bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } - bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); + virtual bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } + virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); void DeleteFromDB(); void SetOwnerGUID(ObjectGuid owner) diff --git a/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp b/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp index 9831adf5a..358626180 100644 --- a/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp +++ b/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp @@ -66,6 +66,10 @@ void ObjectVisibilityContainer::LinkWorldObjectVisibility(WorldObject* worldObje if (worldObject == _selfObject) return; + // Transports are special and should not be added to our visibility map + if (worldObject->IsGameObject() && worldObject->ToGameObject()->IsTransport()) + return; + // Only players can link visibility if (!_visibleWorldObjectsMap) return; diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 074dc4923..8426e4c8c 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1645,10 +1645,7 @@ template <> inline void UpdateVisibilityOf_helper(Player* player, GameObject* target, std::vector& /*v*/) { - // @HACK: This is to prevent objects like deeprun tram from disappearing - // when player moves far from its spawn point while riding it - if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT)) - player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target); + player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target); } template <> diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 251cdb936..ee87af41d 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -607,12 +607,12 @@ void MotionTransport::DelayedTeleportTransport() } Map* newMap = sMapMgr->CreateBaseMap(newMapId); - GetMap()->RemoveFromMap(this, false); + GetMap()->RemoveFromMap(this, false); newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map SetMap(newMap); Relocate(x, y, z, o); - GetMap()->AddToMap(this); + GetMap()->AddToMap(this); LoadStaticPassengers(); } @@ -690,6 +690,40 @@ StaticTransport::~StaticTransport() ASSERT(_passengers.empty()); } +bool StaticTransport::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap) +{ + GameObjectData const* data = sObjectMgr->GetGameObjectData(spawnId); + + if (!data) + { + LOG_ERROR("sql.sql", "Gameobject (GUID: {}) not found in table `gameobject`, can't load. ", spawnId); + return false; + } + + uint32 entry = data->id; + //uint32 map_id = data->mapid; // already used before call + uint32 phaseMask = data->phaseMask; + float x = data->posX; + float y = data->posY; + float z = data->posZ; + float ang = data->orientation; + + uint32 animprogress = data->animprogress; + GOState go_state = data->go_state; + uint32 artKit = data->artKit; + + m_goData = data; + m_spawnId = spawnId; + + if (!Create(map->GenerateLowGuid(), entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, go_state, artKit)) + return false; + + if (addToMap && !GetMap()->AddToMap(this)) + return false; + + return true; +} + bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit) { ASSERT(map); @@ -794,7 +828,6 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m LastUsedScriptID = GetGOInfo()->ScriptId; AIM_Initialize(); - this->setActive(true); return true; } @@ -929,7 +962,9 @@ void StaticTransport::UpdatePosition(float x, float y, float z, float o) if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case GetMap()->LoadGrid(x, y); - GetMap()->GameObjectRelocation(this, x, y, z, o); // this also relocates the model + Relocate(x, y, z, o); + UpdateModelPosition(); + UpdatePassengerPositions(); } diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 005e9d789..9b50775af 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -38,6 +38,8 @@ public: virtual void RemovePassenger(WorldObject* passenger, bool withAll = false) = 0; PassengerSet const& GetPassengers() const { return _passengers; } + virtual void DelayedUpdate(uint32 /*diff*/) {} + uint32 GetPathProgress() const { return GetGOValue()->Transport.PathProgress; } void SetPathProgress(uint32 val) { m_goValue.Transport.PathProgress = val; } @@ -57,7 +59,7 @@ public: void BuildUpdate(UpdateDataMapType& data_map) override; void Update(uint32 diff) override; - void DelayedUpdate(uint32 diff); + void DelayedUpdate(uint32 diff) override; void UpdatePosition(float x, float y, float z, float o); void AddPassenger(WorldObject* passenger, bool withAll = false) override; @@ -115,6 +117,8 @@ public: StaticTransport(); ~StaticTransport() override; + bool LoadFromDB(ObjectGuid::LowType guid, Map* map) override { return LoadGameObjectFromDB(guid, map, false); } + bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true) override; bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0) override; void CleanupsBeforeDelete(bool finalCleanup = true) override; void BuildUpdate(UpdateDataMapType& data_map) override; diff --git a/src/server/game/Grids/GridObjectLoader.cpp b/src/server/game/Grids/GridObjectLoader.cpp index 6a5b4b736..d8b39ebd6 100644 --- a/src/server/game/Grids/GridObjectLoader.cpp +++ b/src/server/game/Grids/GridObjectLoader.cpp @@ -64,15 +64,28 @@ void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map) for (ObjectGuid::LowType const& guid : guid_set) { GameObjectData const* data = sObjectMgr->GetGameObjectData(guid); - GameObject* obj = data && sObjectMgr->IsGameObjectStaticTransport(data->id) ? new StaticTransport() : new GameObject(); - if (!obj->LoadFromDB(guid, map)) + if (data && sObjectMgr->IsGameObjectStaticTransport(data->id)) { - delete obj; - continue; - } + StaticTransport* transport = new StaticTransport(); - AddObjectHelper(map, obj); + // Special case for static transports - we are loaded via grids + // but we do not want to actually be stored in the grid + if (!transport->LoadGameObjectFromDB(guid, map, true)) + delete transport; + } + else + { + GameObject* obj = new GameObject(); + + if (!obj->LoadFromDB(guid, map)) + { + delete obj; + continue; + } + + AddObjectHelper(map, obj); + } } } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index e06a22d64..9ad4cfb4e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -345,7 +345,7 @@ bool Map::AddToMap(T* obj, bool checkTransport) } template<> -bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/) +bool Map::AddToMap(Transport* obj, bool /*checkTransport*/) { //TODO: Needs clean up. An object should not be added to map twice. if (obj->IsInWorld()) @@ -360,26 +360,22 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/) } Cell cell(cellCoord); - if (obj->isActiveObject()) - EnsureGridLoaded(cell); + EnsureGridLoaded(cell); obj->AddToWorld(); _transports.insert(obj); // Broadcast creation to players - if (!GetPlayers().IsEmpty()) + for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) { - for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if (itr->GetSource()->GetTransport() != obj) { - if (itr->GetSource()->GetTransport() != obj) - { - UpdateData data; - obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); - WorldPacket packet; - data.BuildPacket(packet); - itr->GetSource()->SendDirectMessage(&packet); - } + UpdateData data; + obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); + WorldPacket packet; + data.BuildPacket(packet); + itr->GetSource()->SendDirectMessage(&packet); } } @@ -667,7 +663,7 @@ void Map::RemoveFromMap(T* obj, bool remove) } template<> -void Map::RemoveFromMap(MotionTransport* obj, bool remove) +void Map::RemoveFromMap(Transport* obj, bool remove) { obj->RemoveFromWorld(); @@ -697,8 +693,6 @@ void Map::RemoveFromMap(MotionTransport* obj, bool remove) obj->ResetMap(); - // Transports are never actually deleted, but it *should* be safe to clear - // from update list when removing from world RemoveObjectFromMapUpdateList(obj); if (remove) @@ -966,11 +960,10 @@ void Map::UnloadAll() for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();) { - MotionTransport* transport = *itr; + Transport* transport = *itr; ++itr; - transport->RemoveFromWorld(); - delete transport; + RemoveFromMap(transport, true); } _transports.clear(); @@ -1589,6 +1582,9 @@ void Map::SendInitSelf(Player* player) void Map::SendInitTransports(Player* player) { + if (_transports.empty()) + return; + // Hack to send out transports UpdateData transData; for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr) @@ -1605,24 +1601,15 @@ void Map::SendInitTransports(Player* player) void Map::SendRemoveTransports(Player* player) { + if (_transports.empty()) + return; + // Hack to send out transports UpdateData transData; for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr) if (*itr != player->GetTransport()) (*itr)->BuildOutOfRangeUpdateBlock(&transData); - // pussywizard: remove static transports from client - /*for (GuidUnorderedSet::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); ) - { - if ((*it).IsTransport()) - { - transData.AddOutOfRangeGUID(*it); - it = player->m_clientGUIDs.erase(it); - } - else - ++it; - }*/ - if (!transData.HasData()) return; @@ -1693,7 +1680,7 @@ void Map::DelayedUpdate(const uint32 t_diff) { for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) { - MotionTransport* transport = *_transportsUpdateIter; + Transport* transport = *_transportsUpdateIter; ++_transportsUpdateIter; if (!transport->IsInWorld()) @@ -1738,7 +1725,7 @@ void Map::RemoveAllObjectsInRemoveList() RemoveFromMap((DynamicObject*)obj, true); break; case TYPEID_GAMEOBJECT: - if (MotionTransport* transport = obj->ToGameObject()->ToMotionTransport()) + if (Transport* transport = obj->ToGameObject()->ToTransport()) RemoveFromMap(transport, true); else RemoveFromMap(obj->ToGameObject(), true); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index fb24b0924..df1f73cfe 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -146,7 +146,7 @@ struct ZoneDynamicInfo typedef std::map CreatureGroupHolderType; typedef std::unordered_map ZoneDynamicInfoMap; -typedef std::set TransportsContainer; +typedef std::unordered_set TransportsContainer; enum EncounterCreditType : uint8 { @@ -535,7 +535,6 @@ protected: MapRefMgr m_mapRefMgr; MapRefMgr::iterator m_mapRefIter; - // Objects that must update even in inactive grids without activating them TransportsContainer _transports; TransportsContainer::iterator _transportsUpdateIter; diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index ad319e943..f065ccf56 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -412,10 +412,8 @@ MotionTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType if (map && map->IsDungeon()) trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript(); - // xinef: transports are active so passengers can be relocated (grids must be loaded) - trans->setActive(true); HashMapHolder::Insert(trans); - trans->GetMap()->AddToMap(trans); + trans->GetMap()->AddToMap(trans); return trans; }