mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-15 01:59:09 +00:00
feat(Core/Misc): implement ObjectGuid class (port from TC) (#4885)
This commit is contained in:
@@ -43,9 +43,9 @@ u_map_magic MapLiquidMagic = { {'M', 'L', 'I', 'Q'} };
|
||||
|
||||
Map::~Map()
|
||||
{
|
||||
sScriptMgr->OnDestroyMap(this);
|
||||
// UnloadAll must be called before deleting the map
|
||||
|
||||
UnloadAll();
|
||||
sScriptMgr->OnDestroyMap(this);
|
||||
|
||||
while (!i_worldObjects.empty())
|
||||
{
|
||||
@@ -300,6 +300,25 @@ void Map::AddToGrid(DynamicObject* obj, Cell const& cell)
|
||||
obj->SetCurrentCell(cell);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::AddToGrid(Corpse* obj, Cell const& cell)
|
||||
{
|
||||
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
|
||||
// Corpses are a special object type - they can be added to grid via a call to AddToMap
|
||||
// or loaded through ObjectGridLoader.
|
||||
// Both corpses loaded from database and these freshly generated by Player::CreateCoprse are added to _corpsesByCell
|
||||
// ObjectGridLoader loads all corpses from _corpsesByCell even if they were already added to grid before it was loaded
|
||||
// so we need to explicitly check it here (Map::AddToGrid is only called from Player::BuildPlayerRepop, not from ObjectGridLoader)
|
||||
// to avoid failing an assertion in GridObject::AddToGrid
|
||||
if (grid->isGridObjectDataLoaded())
|
||||
{
|
||||
if (obj->IsWorldObject())
|
||||
grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj);
|
||||
else
|
||||
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Map::SwitchGridContainers(T* /*obj*/, bool /*on*/)
|
||||
{
|
||||
@@ -312,7 +331,8 @@ void Map::SwitchGridContainers(Creature* obj, bool on)
|
||||
CellCoord p = acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
|
||||
if (!p.IsCoordValid())
|
||||
{
|
||||
LOG_ERROR("server", "Map::SwitchGridContainers: Object " UI64FMTD " has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
|
||||
LOG_ERROR("server", "Map::SwitchGridContainers: Object %s has invalid coordinates X:%f Y:%f grid cell [%u:%u]",
|
||||
obj->GetGUID().ToString().c_str(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -321,7 +341,7 @@ void Map::SwitchGridContainers(Creature* obj, bool on)
|
||||
return;
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("maps", "Switch object " SZFMTD " from grid[%u, %u] %d", obj->GetGUID(), cell.GridX(), cell.GridY(), on);
|
||||
LOG_DEBUG("maps", "Switch object %s from grid[%u, %u] %d", obj->GetGUID().ToString().c_str(), cell.GridX(), cell.GridY(), on);
|
||||
#endif
|
||||
NGridType* ngrid = getNGrid(cell.GridX(), cell.GridY());
|
||||
ASSERT(ngrid != nullptr);
|
||||
@@ -351,7 +371,8 @@ void Map::SwitchGridContainers(GameObject* obj, bool on)
|
||||
CellCoord p = acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
|
||||
if (!p.IsCoordValid())
|
||||
{
|
||||
LOG_ERROR("server", "Map::SwitchGridContainers: Object " UI64FMTD " has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
|
||||
LOG_ERROR("server", "Map::SwitchGridContainers: Object %s has invalid coordinates X:%f Y:%f grid cell [%u:%u]",
|
||||
obj->GetGUID().ToString().c_str(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -359,7 +380,7 @@ void Map::SwitchGridContainers(GameObject* obj, bool on)
|
||||
if (!IsGridLoaded(GridCoord(cell.data.Part.grid_x, cell.data.Part.grid_y)))
|
||||
return;
|
||||
|
||||
//TC_LOG_DEBUG(LOG_FILTER_MAPS, "Switch object " UI64FMTD " from grid[%u, %u] %u", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y, on);
|
||||
//TC_LOG_DEBUG(LOG_FILTER_MAPS, "Switch object %s from grid[%u, %u] %u", obj->GetGUID().ToString().c_str(), cell.data.Part.grid_x, cell.data.Part.grid_y, on);
|
||||
NGridType* ngrid = getNGrid(cell.GridX(), cell.GridY());
|
||||
ASSERT(ngrid != nullptr);
|
||||
|
||||
@@ -389,14 +410,9 @@ void Map::DeleteFromWorld(T* obj)
|
||||
template<>
|
||||
void Map::DeleteFromWorld(Player* player)
|
||||
{
|
||||
sObjectAccessor->RemoveObject(player);
|
||||
ObjectAccessor::RemoveObject(player);
|
||||
|
||||
// pussywizard: optimization
|
||||
std::string charName = player->GetName();
|
||||
std::transform(charName.begin(), charName.end(), charName.begin(), ::tolower);
|
||||
sObjectAccessor->playerNameToPlayerPointer.erase(charName);
|
||||
|
||||
sObjectAccessor->RemoveUpdateObject(player); //TODO: I do not know why we need this, it should be removed in ~Object anyway
|
||||
RemoveUpdateObject(player); //TODO: I do not know why we need this, it should be removed in ~Object anyway
|
||||
delete player;
|
||||
}
|
||||
|
||||
@@ -454,8 +470,6 @@ bool Map::EnsureGridLoaded(const Cell& cell)
|
||||
ObjectGridLoader loader(*grid, this, cell);
|
||||
loader.LoadN();
|
||||
|
||||
// Add resurrectable corpses to world object list in grid
|
||||
sObjectAccessor->AddCorpsesToGrid(GridCoord(cell.GridX(), cell.GridY()), grid->GetGridType(cell.CellX(), cell.CellY()), this);
|
||||
Balance();
|
||||
return true;
|
||||
//}
|
||||
@@ -481,7 +495,8 @@ bool Map::AddPlayerToMap(Player* player)
|
||||
CellCoord cellCoord = acore::ComputeCellCoord(player->GetPositionX(), player->GetPositionY());
|
||||
if (!cellCoord.IsCoordValid())
|
||||
{
|
||||
LOG_ERROR("server", "Map::Add: Player (GUID: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
|
||||
LOG_ERROR("server", "Map::Add: Player (%s) has invalid coordinates X:%f Y:%f grid cell [%u:%u]",
|
||||
player->GetGUID().ToString().c_str(), player->GetPositionX(), player->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -501,6 +516,9 @@ bool Map::AddPlayerToMap(Player* player)
|
||||
player->m_clientGUIDs.clear();
|
||||
player->UpdateObjectVisibility(false);
|
||||
|
||||
if (player->IsAlive())
|
||||
ConvertCorpseToBones(player->GetGUID());
|
||||
|
||||
sScriptMgr->OnPlayerEnterMap(this, player);
|
||||
return true;
|
||||
}
|
||||
@@ -540,7 +558,8 @@ bool Map::AddToMap(T* obj, bool checkTransport)
|
||||
ASSERT(cellCoord.IsCoordValid());
|
||||
if (!cellCoord.IsCoordValid())
|
||||
{
|
||||
LOG_ERROR("server", "Map::Add: Object " UI64FMTD " has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
|
||||
LOG_ERROR("server", "Map::Add: Object %s has invalid coordinates X:%f Y:%f grid cell [%u:%u]",
|
||||
obj->GetGUID().ToString().c_str(), obj->GetPositionX(), obj->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
|
||||
return false; //Should delete object
|
||||
}
|
||||
|
||||
@@ -588,7 +607,8 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
|
||||
CellCoord cellCoord = acore::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
|
||||
if (!cellCoord.IsCoordValid())
|
||||
{
|
||||
LOG_ERROR("server", "Map::Add: Object " UI64FMTD " has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
|
||||
LOG_ERROR("server", "Map::Add: Object %s has invalid coordinates X:%f Y:%f grid cell [%u:%u]",
|
||||
obj->GetGUID().ToString().c_str(), obj->GetPositionX(), obj->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
|
||||
return false; //Should delete object
|
||||
}
|
||||
|
||||
@@ -830,6 +850,8 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
|
||||
transport->Update(t_diff);
|
||||
}
|
||||
|
||||
SendObjectUpdates();
|
||||
|
||||
///- Process necessary scripts
|
||||
if (!m_scriptSchedule.empty())
|
||||
{
|
||||
@@ -845,8 +867,6 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
|
||||
HandleDelayedVisibility();
|
||||
|
||||
sScriptMgr->OnMapUpdate(this, t_diff);
|
||||
|
||||
BuildAndSendUpdateForObjects(); // pussywizard
|
||||
}
|
||||
|
||||
void Map::HandleDelayedVisibility()
|
||||
@@ -1263,6 +1283,20 @@ void Map::UnloadAll()
|
||||
}
|
||||
|
||||
_transports.clear();
|
||||
|
||||
for (auto& cellCorpsePair : _corpsesByCell)
|
||||
{
|
||||
for (Corpse* corpse : cellCorpsePair.second)
|
||||
{
|
||||
corpse->RemoveFromWorld();
|
||||
corpse->ResetMap();
|
||||
delete corpse;
|
||||
}
|
||||
}
|
||||
|
||||
_corpsesByCell.clear();
|
||||
_corpsesByPlayer.clear();
|
||||
_corpseBones.clear();
|
||||
}
|
||||
|
||||
// *****************************
|
||||
@@ -2333,7 +2367,7 @@ void Map::UpdateObjectsVisibilityFor(Player* player, Cell cell, CellCoord cellpa
|
||||
void Map::SendInitSelf(Player* player)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
LOG_DEBUG("server", "Creating player data for himself %u", player->GetGUIDLow());
|
||||
LOG_DEBUG("server", "Creating player data for himself %s", player->GetGUID().ToString().c_str());
|
||||
#endif
|
||||
|
||||
UpdateData data;
|
||||
@@ -2378,9 +2412,9 @@ void Map::SendRemoveTransports(Player* player)
|
||||
(*itr)->BuildOutOfRangeUpdateBlock(&transData);
|
||||
|
||||
// pussywizard: remove static transports from client
|
||||
for (Player::ClientGUIDs::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); )
|
||||
for (GuidUnorderedSet::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); )
|
||||
{
|
||||
if (IS_TRANSPORT_GUID(*it))
|
||||
if ((*it).IsTransport())
|
||||
{
|
||||
transData.AddOutOfRangeGUID(*it);
|
||||
it = player->m_clientGUIDs.erase(it);
|
||||
@@ -2404,6 +2438,29 @@ inline void Map::setNGrid(NGridType* grid, uint32 x, uint32 y)
|
||||
i_grids[x][y] = grid;
|
||||
}
|
||||
|
||||
void Map::SendObjectUpdates()
|
||||
{
|
||||
UpdateDataMapType update_players;
|
||||
UpdatePlayerSet player_set;
|
||||
|
||||
while (!_updateObjects.empty())
|
||||
{
|
||||
Object* obj = *_updateObjects.begin();
|
||||
ASSERT(obj->IsInWorld());
|
||||
|
||||
_updateObjects.erase(_updateObjects.begin());
|
||||
obj->BuildUpdate(update_players, player_set);
|
||||
}
|
||||
|
||||
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
|
||||
for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
|
||||
{
|
||||
iter->second.BuildPacket(&packet);
|
||||
iter->first->GetSession()->SendPacket(&packet);
|
||||
packet.clear(); // clean the string
|
||||
}
|
||||
}
|
||||
|
||||
void Map::DelayedUpdate(const uint32 t_diff)
|
||||
{
|
||||
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();)
|
||||
@@ -2427,7 +2484,7 @@ void Map::AddObjectToRemoveList(WorldObject* obj)
|
||||
obj->CleanupsBeforeDelete(false); // remove or simplify at least cross referenced links
|
||||
|
||||
i_objectsToRemove.insert(obj);
|
||||
//LOG_DEBUG("maps", "Object (GUID: %u TypeId: %u) added to removing list.", obj->GetGUIDLow(), obj->GetTypeId());
|
||||
//LOG_DEBUG("maps", "Object (%s) added to removing list.", obj->GetGUID().ToString().c_str());
|
||||
}
|
||||
|
||||
void Map::AddObjectToSwitchList(WorldObject* obj, bool on)
|
||||
@@ -2485,7 +2542,7 @@ void Map::RemoveAllObjectsInRemoveList()
|
||||
{
|
||||
Corpse* corpse = ObjectAccessor::GetCorpse(*obj, obj->GetGUID());
|
||||
if (!corpse)
|
||||
LOG_ERROR("server", "Tried to delete corpse/bones %u that is not in map.", obj->GetGUIDLow());
|
||||
LOG_ERROR("server", "Tried to delete corpse/bones %s that is not in map.", obj->GetGUID().ToString().c_str());
|
||||
else
|
||||
RemoveFromMap(corpse, true);
|
||||
break;
|
||||
@@ -2651,7 +2708,8 @@ bool InstanceMap::CanEnter(Player* player, bool loginCheck)
|
||||
{
|
||||
if (!loginCheck && player->GetMapRef().getTarget() == this)
|
||||
{
|
||||
LOG_ERROR("server", "InstanceMap::CanEnter - player %s(%u) already in map %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode());
|
||||
LOG_ERROR("server", "InstanceMap::CanEnter - player %s (%s) already in map %d, %d, %d!",
|
||||
player->GetName().c_str(), player->GetGUID().ToString().c_str(), GetId(), GetInstanceId(), GetSpawnMode());
|
||||
ABORT();
|
||||
return false;
|
||||
}
|
||||
@@ -2736,25 +2794,27 @@ bool InstanceMap::AddPlayerToMap(Player* player)
|
||||
}
|
||||
|
||||
// check for existing instance binds
|
||||
InstancePlayerBind* playerBind = sInstanceSaveMgr->PlayerGetBoundInstance(player->GetGUIDLow(), GetId(), Difficulty(GetSpawnMode()));
|
||||
InstancePlayerBind* playerBind = sInstanceSaveMgr->PlayerGetBoundInstance(player->GetGUID(), GetId(), Difficulty(GetSpawnMode()));
|
||||
if (playerBind && playerBind->perm)
|
||||
{
|
||||
if (playerBind->save != mapSave)
|
||||
{
|
||||
LOG_ERROR("server", "InstanceMap::Add: player %s(%d) is permanently bound to instance %d, %d, %d, %d but he is being put into instance %d, %d, %d, %d", player->GetName().c_str(), player->GetGUIDLow(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->CanReset());
|
||||
LOG_ERROR("server", "InstanceMap::Add: player %s (%s) is permanently bound to instance %d, %d, %d, %d but he is being put into instance %d, %d, %d, %d",
|
||||
player->GetName().c_str(), player->GetGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(),
|
||||
playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->CanReset());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
playerBind = sInstanceSaveMgr->PlayerBindToInstance(player->GetGUIDLow(), mapSave, false, player);
|
||||
playerBind = sInstanceSaveMgr->PlayerBindToInstance(player->GetGUID(), mapSave, false, player);
|
||||
// pussywizard: bind lider also if not yet bound
|
||||
if (Group* g = player->GetGroup())
|
||||
if (g->GetLeaderGUID() != player->GetGUID())
|
||||
if (!sInstanceSaveMgr->PlayerGetBoundInstance(GUID_LOPART(g->GetLeaderGUID()), mapSave->GetMapId(), mapSave->GetDifficulty()))
|
||||
if (!sInstanceSaveMgr->PlayerGetBoundInstance(g->GetLeaderGUID(), mapSave->GetMapId(), mapSave->GetDifficulty()))
|
||||
{
|
||||
sInstanceSaveMgr->PlayerCreateBoundInstancesMaps(GUID_LOPART(g->GetLeaderGUID()));
|
||||
sInstanceSaveMgr->PlayerBindToInstance(GUID_LOPART(g->GetLeaderGUID()), mapSave, false, ObjectAccessor::FindPlayerInOrOutOfWorld(g->GetLeaderGUID()));
|
||||
sInstanceSaveMgr->PlayerCreateBoundInstancesMaps(g->GetLeaderGUID());
|
||||
sInstanceSaveMgr->PlayerBindToInstance(g->GetLeaderGUID(), mapSave, false, ObjectAccessor::FindConnectedPlayer(g->GetLeaderGUID()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2857,7 +2917,7 @@ void InstanceMap::CreateInstanceScript(bool load, std::string data, uint32 compl
|
||||
/*
|
||||
Returns true if there are no players in the instance
|
||||
*/
|
||||
bool InstanceMap::Reset(uint8 method, std::list<uint32>* globalResetSkipList)
|
||||
bool InstanceMap::Reset(uint8 method, GuidList* globalResetSkipList)
|
||||
{
|
||||
if (method == INSTANCE_RESET_GLOBAL)
|
||||
{
|
||||
@@ -2865,7 +2925,7 @@ bool InstanceMap::Reset(uint8 method, std::list<uint32>* globalResetSkipList)
|
||||
for (MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
|
||||
{
|
||||
// teleport players that are no longer bound (can be still bound if extended id)
|
||||
if (!globalResetSkipList || std::find(globalResetSkipList->begin(), globalResetSkipList->end(), itr->GetSource()->GetGUIDLow()) == globalResetSkipList->end())
|
||||
if (!globalResetSkipList || std::find(globalResetSkipList->begin(), globalResetSkipList->end(), itr->GetSource()->GetGUID()) == globalResetSkipList->end())
|
||||
itr->GetSource()->RepopAtGraveyard();
|
||||
}
|
||||
|
||||
@@ -2926,14 +2986,14 @@ void InstanceMap::PermBindAllPlayers()
|
||||
|
||||
// players inside an instance cannot be bound to other instances
|
||||
// some players may already be permanently bound, in this case nothing happens
|
||||
InstancePlayerBind* bind = sInstanceSaveMgr->PlayerGetBoundInstance(player->GetGUIDLow(), save->GetMapId(), save->GetDifficulty());
|
||||
InstancePlayerBind* bind = sInstanceSaveMgr->PlayerGetBoundInstance(player->GetGUID(), save->GetMapId(), save->GetDifficulty());
|
||||
|
||||
if (!bind || !bind->perm)
|
||||
{
|
||||
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
|
||||
data << uint32(0);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
sInstanceSaveMgr->PlayerBindToInstance(player->GetGUIDLow(), save, true, player);
|
||||
sInstanceSaveMgr->PlayerBindToInstance(player->GetGUID(), save, true, player);
|
||||
}
|
||||
|
||||
// Xinef: Difficulty change prevention
|
||||
@@ -2947,7 +3007,10 @@ void InstanceMap::UnloadAll()
|
||||
ASSERT(!HavePlayers());
|
||||
|
||||
if (m_resetAfterUnload == true)
|
||||
{
|
||||
DeleteRespawnTimes();
|
||||
DeleteCorpseData();
|
||||
}
|
||||
|
||||
Map::UnloadAll();
|
||||
}
|
||||
@@ -3010,7 +3073,7 @@ bool BattlegroundMap::CanEnter(Player* player, bool loginCheck)
|
||||
{
|
||||
if (!loginCheck && player->GetMapRef().getTarget() == this)
|
||||
{
|
||||
LOG_ERROR("server", "BGMap::CanEnter - player %u is already in map!", player->GetGUIDLow());
|
||||
LOG_ERROR("server", "BGMap::CanEnter - player %s is already in map!", player->GetGUID().ToString().c_str());
|
||||
ABORT();
|
||||
return false;
|
||||
}
|
||||
@@ -3058,43 +3121,38 @@ void BattlegroundMap::RemoveAllPlayers()
|
||||
player->TeleportTo(player->GetEntryPoint());
|
||||
}
|
||||
|
||||
Player* Map::GetPlayer(uint64 guid)
|
||||
Corpse* Map::GetCorpse(ObjectGuid const guid)
|
||||
{
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (Player*)nullptr);
|
||||
return _objectsStore.Find<Corpse>(guid);
|
||||
}
|
||||
|
||||
Creature* Map::GetCreature(uint64 guid)
|
||||
Creature* Map::GetCreature(ObjectGuid const guid)
|
||||
{
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (Creature*)nullptr);
|
||||
return _objectsStore.Find<Creature>(guid);
|
||||
}
|
||||
|
||||
GameObject* Map::GetGameObject(uint64 guid)
|
||||
GameObject* Map::GetGameObject(ObjectGuid const guid)
|
||||
{
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)nullptr);
|
||||
return _objectsStore.Find<GameObject>(guid);
|
||||
}
|
||||
|
||||
Transport* Map::GetTransport(uint64 guid)
|
||||
Pet* Map::GetPet(ObjectGuid const guid)
|
||||
{
|
||||
if (GUID_HIPART(guid) != HIGHGUID_MO_TRANSPORT && GUID_HIPART(guid) != HIGHGUID_TRANSPORT)
|
||||
return _objectsStore.Find<Pet>(guid);
|
||||
}
|
||||
|
||||
Transport* Map::GetTransport(ObjectGuid guid)
|
||||
{
|
||||
if (guid.GetHigh() != HighGuid::Mo_Transport && guid.GetHigh() != HighGuid::Transport)
|
||||
return nullptr;
|
||||
|
||||
GameObject* go = GetGameObject(guid);
|
||||
return go ? go->ToTransport() : nullptr;
|
||||
}
|
||||
|
||||
DynamicObject* Map::GetDynamicObject(uint64 guid)
|
||||
DynamicObject* Map::GetDynamicObject(ObjectGuid guid)
|
||||
{
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)nullptr);
|
||||
}
|
||||
|
||||
Pet* Map::GetPet(uint64 guid)
|
||||
{
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (Pet*)nullptr);
|
||||
}
|
||||
|
||||
Corpse* Map::GetCorpse(uint64 guid)
|
||||
{
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (Corpse*)nullptr);
|
||||
return _objectsStore.Find<DynamicObject>(guid);
|
||||
}
|
||||
|
||||
void Map::UpdateIteratorBack(Player* player)
|
||||
@@ -3103,12 +3161,12 @@ void Map::UpdateIteratorBack(Player* player)
|
||||
m_mapRefIter = m_mapRefIter->nocheck_prev();
|
||||
}
|
||||
|
||||
void Map::SaveCreatureRespawnTime(uint32 dbGuid, time_t& respawnTime)
|
||||
void Map::SaveCreatureRespawnTime(ObjectGuid::LowType spawnId, time_t& respawnTime)
|
||||
{
|
||||
if (!respawnTime)
|
||||
{
|
||||
// Delete only
|
||||
RemoveCreatureRespawnTime(dbGuid);
|
||||
RemoveCreatureRespawnTime(spawnId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3116,33 +3174,33 @@ void Map::SaveCreatureRespawnTime(uint32 dbGuid, time_t& respawnTime)
|
||||
if (GetInstanceResetPeriod() > 0 && respawnTime - now + 5 >= GetInstanceResetPeriod())
|
||||
respawnTime = now + YEAR;
|
||||
|
||||
_creatureRespawnTimes[dbGuid] = respawnTime;
|
||||
_creatureRespawnTimes[spawnId] = respawnTime;
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN);
|
||||
stmt->setUInt32(0, dbGuid);
|
||||
stmt->setUInt32(0, spawnId);
|
||||
stmt->setUInt32(1, uint32(respawnTime));
|
||||
stmt->setUInt16(2, GetId());
|
||||
stmt->setUInt32(3, GetInstanceId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
void Map::RemoveCreatureRespawnTime(uint32 dbGuid)
|
||||
void Map::RemoveCreatureRespawnTime(ObjectGuid::LowType spawnId)
|
||||
{
|
||||
_creatureRespawnTimes.erase(dbGuid);
|
||||
_creatureRespawnTimes.erase(spawnId);
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
|
||||
stmt->setUInt32(0, dbGuid);
|
||||
stmt->setUInt32(0, spawnId);
|
||||
stmt->setUInt16(1, GetId());
|
||||
stmt->setUInt32(2, GetInstanceId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
void Map::SaveGORespawnTime(uint32 dbGuid, time_t& respawnTime)
|
||||
void Map::SaveGORespawnTime(ObjectGuid::LowType spawnId, time_t& respawnTime)
|
||||
{
|
||||
if (!respawnTime)
|
||||
{
|
||||
// Delete only
|
||||
RemoveGORespawnTime(dbGuid);
|
||||
RemoveGORespawnTime(spawnId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3150,22 +3208,22 @@ void Map::SaveGORespawnTime(uint32 dbGuid, time_t& respawnTime)
|
||||
if (GetInstanceResetPeriod() > 0 && respawnTime - now + 5 >= GetInstanceResetPeriod())
|
||||
respawnTime = now + YEAR;
|
||||
|
||||
_goRespawnTimes[dbGuid] = respawnTime;
|
||||
_goRespawnTimes[spawnId] = respawnTime;
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN);
|
||||
stmt->setUInt32(0, dbGuid);
|
||||
stmt->setUInt32(0, spawnId);
|
||||
stmt->setUInt32(1, uint32(respawnTime));
|
||||
stmt->setUInt16(2, GetId());
|
||||
stmt->setUInt32(3, GetInstanceId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
void Map::RemoveGORespawnTime(uint32 dbGuid)
|
||||
void Map::RemoveGORespawnTime(ObjectGuid::LowType spawnId)
|
||||
{
|
||||
_goRespawnTimes.erase(dbGuid);
|
||||
_goRespawnTimes.erase(spawnId);
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN);
|
||||
stmt->setUInt32(0, dbGuid);
|
||||
stmt->setUInt32(0, spawnId);
|
||||
stmt->setUInt16(1, GetId());
|
||||
stmt->setUInt32(2, GetInstanceId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
@@ -3181,10 +3239,10 @@ void Map::LoadRespawnTimes()
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 loguid = fields[0].GetUInt32();
|
||||
ObjectGuid::LowType lowguid = fields[0].GetUInt32();
|
||||
uint32 respawnTime = fields[1].GetUInt32();
|
||||
|
||||
_creatureRespawnTimes[loguid] = time_t(respawnTime);
|
||||
_creatureRespawnTimes[lowguid] = time_t(respawnTime);
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
@@ -3196,10 +3254,10 @@ void Map::LoadRespawnTimes()
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 loguid = fields[0].GetUInt32();
|
||||
ObjectGuid::LowType lowguid = fields[0].GetUInt32();
|
||||
uint32 respawnTime = fields[1].GetUInt32();
|
||||
|
||||
_goRespawnTimes[loguid] = time_t(respawnTime);
|
||||
_goRespawnTimes[lowguid] = time_t(respawnTime);
|
||||
} while (result->NextRow());
|
||||
}
|
||||
}
|
||||
@@ -3299,7 +3357,8 @@ void Map::LogEncounterFinished(EncounterCreditType type, uint32 creditEntry)
|
||||
auraStr += buffer2;
|
||||
}
|
||||
|
||||
snprintf(buffer, 16384, "%s (guid: %u, acc: %u, ip: %s, guild: %u), xyz: (%.1f, %.1f, %.1f), auras: %s\n", p->GetName().c_str(), p->GetGUIDLow(), p->GetSession()->GetAccountId(), p->GetSession()->GetRemoteAddress().c_str(), p->GetGuildId(), p->GetPositionX(), p->GetPositionY(), p->GetPositionZ(), auraStr.c_str());
|
||||
snprintf(buffer, 16384, "%s (%s, acc: %u, ip: %s, guild: %u), xyz: (%.1f, %.1f, %.1f), auras: %s\n",
|
||||
p->GetName().c_str(), p->GetGUID().ToString().c_str(), p->GetSession()->GetAccountId(), p->GetSession()->GetRemoteAddress().c_str(), p->GetGuildId(), p->GetPositionX(), p->GetPositionY(), p->GetPositionZ(), auraStr.c_str());
|
||||
playersInfo += buffer;
|
||||
}
|
||||
CleanStringForMysqlQuery(playersInfo);
|
||||
@@ -3322,15 +3381,15 @@ void Map::AllTransportsRemovePassengers()
|
||||
(*itr)->RemovePassenger(*((*itr)->GetPassengers().begin()), true);
|
||||
}
|
||||
|
||||
time_t Map::GetLinkedRespawnTime(uint64 guid) const
|
||||
time_t Map::GetLinkedRespawnTime(ObjectGuid guid) const
|
||||
{
|
||||
uint64 linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid);
|
||||
switch (GUID_HIPART(linkedGuid))
|
||||
ObjectGuid linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid);
|
||||
switch (linkedGuid.GetHigh())
|
||||
{
|
||||
case HIGHGUID_UNIT:
|
||||
return GetCreatureRespawnTime(GUID_LOPART(linkedGuid));
|
||||
case HIGHGUID_GAMEOBJECT:
|
||||
return GetGORespawnTime(GUID_LOPART(linkedGuid));
|
||||
case HighGuid::Unit:
|
||||
return GetCreatureRespawnTime(linkedGuid.GetCounter());
|
||||
case HighGuid::GameObject:
|
||||
return GetGORespawnTime(linkedGuid.GetCounter());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3338,6 +3397,114 @@ time_t Map::GetLinkedRespawnTime(uint64 guid) const
|
||||
return time_t(0);
|
||||
}
|
||||
|
||||
void Map::AddCorpse(Corpse* corpse)
|
||||
{
|
||||
corpse->SetMap(this);
|
||||
|
||||
_corpsesByCell[corpse->GetCellCoord().GetId()].insert(corpse);
|
||||
if (corpse->GetType() != CORPSE_BONES)
|
||||
_corpsesByPlayer[corpse->GetOwnerGUID()] = corpse;
|
||||
else
|
||||
_corpseBones.insert(corpse);
|
||||
}
|
||||
|
||||
void Map::RemoveCorpse(Corpse* corpse)
|
||||
{
|
||||
ASSERT(corpse);
|
||||
|
||||
corpse->DestroyForNearbyPlayers();
|
||||
if (corpse->IsInGrid())
|
||||
RemoveFromMap(corpse, false);
|
||||
else
|
||||
{
|
||||
corpse->RemoveFromWorld();
|
||||
corpse->ResetMap();
|
||||
}
|
||||
|
||||
_corpsesByCell[corpse->GetCellCoord().GetId()].erase(corpse);
|
||||
if (corpse->GetType() != CORPSE_BONES)
|
||||
_corpsesByPlayer.erase(corpse->GetOwnerGUID());
|
||||
else
|
||||
_corpseBones.erase(corpse);
|
||||
}
|
||||
|
||||
Corpse* Map::ConvertCorpseToBones(ObjectGuid const ownerGuid, bool insignia /*= false*/)
|
||||
{
|
||||
Corpse* corpse = GetCorpseByPlayer(ownerGuid);
|
||||
if (!corpse)
|
||||
return nullptr;
|
||||
|
||||
RemoveCorpse(corpse);
|
||||
|
||||
// remove corpse from DB
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
corpse->DeleteFromDB(trans);
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
|
||||
Corpse* bones = NULL;
|
||||
|
||||
// create the bones only if the map and the grid is loaded at the corpse's location
|
||||
// ignore bones creating option in case insignia
|
||||
if ((insignia ||
|
||||
(IsBattlegroundOrArena() ? sWorld->getBoolConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld->getBoolConfig(CONFIG_DEATH_BONES_WORLD))) &&
|
||||
!IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
|
||||
{
|
||||
// Create bones, don't change Corpse
|
||||
bones = new Corpse();
|
||||
bones->Create(corpse->GetGUID().GetCounter());
|
||||
|
||||
for (uint8 i = OBJECT_FIELD_TYPE + 1; i < CORPSE_END; ++i) // don't overwrite guid and object type
|
||||
bones->SetUInt32Value(i, corpse->GetUInt32Value(i));
|
||||
|
||||
bones->SetCellCoord(corpse->GetCellCoord());
|
||||
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
|
||||
bones->SetPhaseMask(corpse->GetPhaseMask(), false);
|
||||
|
||||
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
|
||||
bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty);
|
||||
|
||||
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||
if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
|
||||
bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
|
||||
|
||||
AddCorpse(bones);
|
||||
|
||||
// add bones in grid store if grid loaded where corpse placed
|
||||
AddToMap(bones);
|
||||
}
|
||||
|
||||
// all references to the corpse should be removed at this point
|
||||
delete corpse;
|
||||
|
||||
return bones;
|
||||
}
|
||||
|
||||
void Map::RemoveOldCorpses()
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
|
||||
std::vector<ObjectGuid> corpses;
|
||||
corpses.reserve(_corpsesByPlayer.size());
|
||||
|
||||
for (auto const& p : _corpsesByPlayer)
|
||||
if (p.second->IsExpired(now))
|
||||
corpses.push_back(p.first);
|
||||
|
||||
for (ObjectGuid const& ownerGuid : corpses)
|
||||
ConvertCorpseToBones(ownerGuid);
|
||||
|
||||
std::vector<Corpse*> expiredBones;
|
||||
for (Corpse* bones : _corpseBones)
|
||||
if (bones->IsExpired(now))
|
||||
expiredBones.push_back(bones);
|
||||
|
||||
for (Corpse* bones : expiredBones)
|
||||
{
|
||||
RemoveCorpse(bones);
|
||||
delete bones;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::SendZoneDynamicInfo(Player* player)
|
||||
{
|
||||
uint32 zoneId = GetZoneId(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
|
||||
@@ -3630,3 +3797,47 @@ bool Map::CheckCollisionAndGetValidCoords(const WorldObject* source, float start
|
||||
|
||||
return failOnCollision ? !collided : true;
|
||||
}
|
||||
|
||||
void Map::LoadCorpseData()
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES);
|
||||
stmt->setUInt32(0, GetId());
|
||||
stmt->setUInt32(1, GetInstanceId());
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
||||
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, guid FROM corpse WHERE mapId = ? AND instanceId = ?
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
CorpseType type = CorpseType(fields[13].GetUInt8());
|
||||
uint32 guid = fields[16].GetUInt32();
|
||||
if (type >= MAX_CORPSE_TYPE || type == CORPSE_BONES)
|
||||
{
|
||||
LOG_ERROR("server", "Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type);
|
||||
continue;
|
||||
}
|
||||
|
||||
Corpse* corpse = new Corpse(type);
|
||||
|
||||
if (!corpse->LoadCorpseFromDB(GenerateLowGuid<HighGuid::Corpse>(), fields))
|
||||
{
|
||||
delete corpse;
|
||||
continue;
|
||||
}
|
||||
|
||||
AddCorpse(corpse);
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
void Map::DeleteCorpseData()
|
||||
{
|
||||
// DELETE FROM corpse WHERE mapId = ? AND instanceId = ?
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSES_FROM_MAP);
|
||||
stmt->setUInt32(0, GetId());
|
||||
stmt->setUInt32(1, GetInstanceId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user