mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 07:48:02 +00:00
fix(Core/Transports): Improve static transport visibility (#22660)
This commit is contained in:
@@ -156,8 +156,8 @@ public:
|
|||||||
|
|
||||||
void SaveToDB(bool saveAddon = false);
|
void SaveToDB(bool saveAddon = false);
|
||||||
void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, 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); }
|
virtual bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); }
|
||||||
bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true);
|
virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true);
|
||||||
void DeleteFromDB();
|
void DeleteFromDB();
|
||||||
|
|
||||||
void SetOwnerGUID(ObjectGuid owner)
|
void SetOwnerGUID(ObjectGuid owner)
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ void ObjectVisibilityContainer::LinkWorldObjectVisibility(WorldObject* worldObje
|
|||||||
if (worldObject == _selfObject)
|
if (worldObject == _selfObject)
|
||||||
return;
|
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
|
// Only players can link visibility
|
||||||
if (!_visibleWorldObjectsMap)
|
if (!_visibleWorldObjectsMap)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1645,10 +1645,7 @@ template <>
|
|||||||
inline void UpdateVisibilityOf_helper(Player* player, GameObject* target,
|
inline void UpdateVisibilityOf_helper(Player* player, GameObject* target,
|
||||||
std::vector<Unit*>& /*v*/)
|
std::vector<Unit*>& /*v*/)
|
||||||
{
|
{
|
||||||
// @HACK: This is to prevent objects like deeprun tram from disappearing
|
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
|
||||||
// when player moves far from its spawn point while riding it
|
|
||||||
if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT))
|
|
||||||
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|||||||
@@ -607,12 +607,12 @@ void MotionTransport::DelayedTeleportTransport()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
|
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
|
||||||
GetMap()->RemoveFromMap<MotionTransport>(this, false);
|
GetMap()->RemoveFromMap<Transport>(this, false);
|
||||||
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
|
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
|
||||||
SetMap(newMap);
|
SetMap(newMap);
|
||||||
|
|
||||||
Relocate(x, y, z, o);
|
Relocate(x, y, z, o);
|
||||||
GetMap()->AddToMap<MotionTransport>(this);
|
GetMap()->AddToMap<Transport>(this);
|
||||||
|
|
||||||
LoadStaticPassengers();
|
LoadStaticPassengers();
|
||||||
}
|
}
|
||||||
@@ -690,6 +690,40 @@ StaticTransport::~StaticTransport()
|
|||||||
ASSERT(_passengers.empty());
|
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<HighGuid::Transport>(), entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, go_state, artKit))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (addToMap && !GetMap()->AddToMap<Transport>(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)
|
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);
|
ASSERT(map);
|
||||||
@@ -794,7 +828,6 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m
|
|||||||
LastUsedScriptID = GetGOInfo()->ScriptId;
|
LastUsedScriptID = GetGOInfo()->ScriptId;
|
||||||
AIM_Initialize();
|
AIM_Initialize();
|
||||||
|
|
||||||
this->setActive(true);
|
|
||||||
return 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
|
if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case
|
||||||
GetMap()->LoadGrid(x, y);
|
GetMap()->LoadGrid(x, y);
|
||||||
|
|
||||||
GetMap()->GameObjectRelocation(this, x, y, z, o); // this also relocates the model
|
Relocate(x, y, z, o);
|
||||||
|
UpdateModelPosition();
|
||||||
|
|
||||||
UpdatePassengerPositions();
|
UpdatePassengerPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public:
|
|||||||
virtual void RemovePassenger(WorldObject* passenger, bool withAll = false) = 0;
|
virtual void RemovePassenger(WorldObject* passenger, bool withAll = false) = 0;
|
||||||
PassengerSet const& GetPassengers() const { return _passengers; }
|
PassengerSet const& GetPassengers() const { return _passengers; }
|
||||||
|
|
||||||
|
virtual void DelayedUpdate(uint32 /*diff*/) {}
|
||||||
|
|
||||||
uint32 GetPathProgress() const { return GetGOValue()->Transport.PathProgress; }
|
uint32 GetPathProgress() const { return GetGOValue()->Transport.PathProgress; }
|
||||||
void SetPathProgress(uint32 val) { m_goValue.Transport.PathProgress = val; }
|
void SetPathProgress(uint32 val) { m_goValue.Transport.PathProgress = val; }
|
||||||
|
|
||||||
@@ -57,7 +59,7 @@ public:
|
|||||||
void BuildUpdate(UpdateDataMapType& data_map) override;
|
void BuildUpdate(UpdateDataMapType& data_map) override;
|
||||||
|
|
||||||
void Update(uint32 diff) 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 UpdatePosition(float x, float y, float z, float o);
|
||||||
|
|
||||||
void AddPassenger(WorldObject* passenger, bool withAll = false) override;
|
void AddPassenger(WorldObject* passenger, bool withAll = false) override;
|
||||||
@@ -115,6 +117,8 @@ public:
|
|||||||
StaticTransport();
|
StaticTransport();
|
||||||
~StaticTransport() override;
|
~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;
|
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 CleanupsBeforeDelete(bool finalCleanup = true) override;
|
||||||
void BuildUpdate(UpdateDataMapType& data_map) override;
|
void BuildUpdate(UpdateDataMapType& data_map) override;
|
||||||
|
|||||||
@@ -64,15 +64,28 @@ void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map)
|
|||||||
for (ObjectGuid::LowType const& guid : guid_set)
|
for (ObjectGuid::LowType const& guid : guid_set)
|
||||||
{
|
{
|
||||||
GameObjectData const* data = sObjectMgr->GetGameObjectData(guid);
|
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;
|
StaticTransport* transport = new StaticTransport();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddObjectHelper<GameObject>(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<GameObject>(map, obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ bool Map::AddToMap(T* obj, bool checkTransport)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
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.
|
//TODO: Needs clean up. An object should not be added to map twice.
|
||||||
if (obj->IsInWorld())
|
if (obj->IsInWorld())
|
||||||
@@ -360,26 +360,22 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Cell cell(cellCoord);
|
Cell cell(cellCoord);
|
||||||
if (obj->isActiveObject())
|
EnsureGridLoaded(cell);
|
||||||
EnsureGridLoaded(cell);
|
|
||||||
|
|
||||||
obj->AddToWorld();
|
obj->AddToWorld();
|
||||||
|
|
||||||
_transports.insert(obj);
|
_transports.insert(obj);
|
||||||
|
|
||||||
// Broadcast creation to players
|
// 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());
|
||||||
UpdateData data;
|
WorldPacket packet;
|
||||||
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
|
data.BuildPacket(packet);
|
||||||
WorldPacket packet;
|
itr->GetSource()->SendDirectMessage(&packet);
|
||||||
data.BuildPacket(packet);
|
|
||||||
itr->GetSource()->SendDirectMessage(&packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,7 +663,7 @@ void Map::RemoveFromMap(T* obj, bool remove)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Map::RemoveFromMap(MotionTransport* obj, bool remove)
|
void Map::RemoveFromMap(Transport* obj, bool remove)
|
||||||
{
|
{
|
||||||
obj->RemoveFromWorld();
|
obj->RemoveFromWorld();
|
||||||
|
|
||||||
@@ -697,8 +693,6 @@ void Map::RemoveFromMap(MotionTransport* obj, bool remove)
|
|||||||
|
|
||||||
obj->ResetMap();
|
obj->ResetMap();
|
||||||
|
|
||||||
// Transports are never actually deleted, but it *should* be safe to clear
|
|
||||||
// from update list when removing from world
|
|
||||||
RemoveObjectFromMapUpdateList(obj);
|
RemoveObjectFromMapUpdateList(obj);
|
||||||
|
|
||||||
if (remove)
|
if (remove)
|
||||||
@@ -966,11 +960,10 @@ void Map::UnloadAll()
|
|||||||
|
|
||||||
for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();)
|
for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();)
|
||||||
{
|
{
|
||||||
MotionTransport* transport = *itr;
|
Transport* transport = *itr;
|
||||||
++itr;
|
++itr;
|
||||||
|
|
||||||
transport->RemoveFromWorld();
|
RemoveFromMap<Transport>(transport, true);
|
||||||
delete transport;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_transports.clear();
|
_transports.clear();
|
||||||
@@ -1589,6 +1582,9 @@ void Map::SendInitSelf(Player* player)
|
|||||||
|
|
||||||
void Map::SendInitTransports(Player* player)
|
void Map::SendInitTransports(Player* player)
|
||||||
{
|
{
|
||||||
|
if (_transports.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
// Hack to send out transports
|
// Hack to send out transports
|
||||||
UpdateData transData;
|
UpdateData transData;
|
||||||
for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr)
|
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)
|
void Map::SendRemoveTransports(Player* player)
|
||||||
{
|
{
|
||||||
|
if (_transports.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
// Hack to send out transports
|
// Hack to send out transports
|
||||||
UpdateData transData;
|
UpdateData transData;
|
||||||
for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr)
|
for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr)
|
||||||
if (*itr != player->GetTransport())
|
if (*itr != player->GetTransport())
|
||||||
(*itr)->BuildOutOfRangeUpdateBlock(&transData);
|
(*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())
|
if (!transData.HasData())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1693,7 +1680,7 @@ void Map::DelayedUpdate(const uint32 t_diff)
|
|||||||
{
|
{
|
||||||
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();)
|
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();)
|
||||||
{
|
{
|
||||||
MotionTransport* transport = *_transportsUpdateIter;
|
Transport* transport = *_transportsUpdateIter;
|
||||||
++_transportsUpdateIter;
|
++_transportsUpdateIter;
|
||||||
|
|
||||||
if (!transport->IsInWorld())
|
if (!transport->IsInWorld())
|
||||||
@@ -1738,7 +1725,7 @@ void Map::RemoveAllObjectsInRemoveList()
|
|||||||
RemoveFromMap((DynamicObject*)obj, true);
|
RemoveFromMap((DynamicObject*)obj, true);
|
||||||
break;
|
break;
|
||||||
case TYPEID_GAMEOBJECT:
|
case TYPEID_GAMEOBJECT:
|
||||||
if (MotionTransport* transport = obj->ToGameObject()->ToMotionTransport())
|
if (Transport* transport = obj->ToGameObject()->ToTransport())
|
||||||
RemoveFromMap(transport, true);
|
RemoveFromMap(transport, true);
|
||||||
else
|
else
|
||||||
RemoveFromMap(obj->ToGameObject(), true);
|
RemoveFromMap(obj->ToGameObject(), true);
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ struct ZoneDynamicInfo
|
|||||||
|
|
||||||
typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
|
typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
|
||||||
typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMap;
|
typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMap;
|
||||||
typedef std::set<MotionTransport*> TransportsContainer;
|
typedef std::unordered_set<Transport*> TransportsContainer;
|
||||||
|
|
||||||
enum EncounterCreditType : uint8
|
enum EncounterCreditType : uint8
|
||||||
{
|
{
|
||||||
@@ -535,7 +535,6 @@ protected:
|
|||||||
MapRefMgr m_mapRefMgr;
|
MapRefMgr m_mapRefMgr;
|
||||||
MapRefMgr::iterator m_mapRefIter;
|
MapRefMgr::iterator m_mapRefIter;
|
||||||
|
|
||||||
// Objects that must update even in inactive grids without activating them
|
|
||||||
TransportsContainer _transports;
|
TransportsContainer _transports;
|
||||||
TransportsContainer::iterator _transportsUpdateIter;
|
TransportsContainer::iterator _transportsUpdateIter;
|
||||||
|
|
||||||
|
|||||||
@@ -412,10 +412,8 @@ MotionTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType
|
|||||||
if (map && map->IsDungeon())
|
if (map && map->IsDungeon())
|
||||||
trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript();
|
trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript();
|
||||||
|
|
||||||
// xinef: transports are active so passengers can be relocated (grids must be loaded)
|
|
||||||
trans->setActive(true);
|
|
||||||
HashMapHolder<MotionTransport>::Insert(trans);
|
HashMapHolder<MotionTransport>::Insert(trans);
|
||||||
trans->GetMap()->AddToMap<MotionTransport>(trans);
|
trans->GetMap()->AddToMap<Transport>(trans);
|
||||||
return trans;
|
return trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user