feat(Core/Misc): implement ObjectGuid class (port from TC) (#4885)

This commit is contained in:
UltraNix
2021-04-25 22:18:03 +02:00
committed by GitHub
parent 91081f4ad8
commit f4c226423d
568 changed files with 10655 additions and 11019 deletions

View File

@@ -396,7 +396,7 @@ void GameEventMgr::LoadFromDB()
{
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
ObjectGuid::LowType guid = fields[0].GetUInt32();
int16 event_id = fields[1].GetInt8();
int32 internal_event_id = mGameEvent.size() + event_id - 1;
@@ -407,7 +407,7 @@ void GameEventMgr::LoadFromDB()
continue;
}
GuidList& crelist = mGameEventCreatureGuids[internal_event_id];
GuidLowList& crelist = mGameEventCreatureGuids[internal_event_id];
crelist.push_back(guid);
++count;
@@ -438,7 +438,7 @@ void GameEventMgr::LoadFromDB()
{
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
ObjectGuid::LowType guid = fields[0].GetUInt32();
int16 event_id = fields[1].GetInt8();
int32 internal_event_id = mGameEvent.size() + event_id - 1;
@@ -449,7 +449,7 @@ void GameEventMgr::LoadFromDB()
continue;
}
GuidList& golist = mGameEventGameobjectGuids[internal_event_id];
GuidLowList& golist = mGameEventGameobjectGuids[internal_event_id];
golist.push_back(guid);
++count;
@@ -480,8 +480,8 @@ void GameEventMgr::LoadFromDB()
{
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
uint32 entry = fields[1].GetUInt32();
ObjectGuid::LowType guid = fields[0].GetUInt32();
uint32 entry = fields[1].GetUInt32();
uint16 event_id = fields[2].GetUInt8();
if (event_id >= mGameEventModelEquip.size())
@@ -508,7 +508,7 @@ void GameEventMgr::LoadFromDB()
}
}
equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet));
equiplist.push_back(std::pair<ObjectGuid::LowType, ModelEquip>(guid, newModelEquipSet));
++count;
} while (result->NextRow());
@@ -747,9 +747,9 @@ void GameEventMgr::LoadFromDB()
{
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
ObjectGuid::LowType guid = fields[0].GetUInt32();
uint16 event_id = fields[1].GetUInt8();
uint32 npcflag = fields[2].GetUInt32();
uint32 npcflag = fields[2].GetUInt32();
if (event_id >= mGameEvent.size())
{
@@ -841,7 +841,7 @@ void GameEventMgr::LoadFromDB()
NPCVendorList& vendors = mGameEventVendors[event_id];
NPCVendorEntry newEntry;
uint32 guid = fields[1].GetUInt32();
ObjectGuid::LowType guid = fields[1].GetUInt32();
newEntry.item = fields[2].GetUInt32();
newEntry.maxcount = fields[3].GetUInt32();
newEntry.incrtime = fields[4].GetUInt32();
@@ -1015,14 +1015,12 @@ void GameEventMgr::LoadHolidayDates()
uint32 GameEventMgr::GetNPCFlag(Creature* cr)
{
uint32 mask = 0;
uint32 guid = cr->GetDBTableGUIDLow();
ObjectGuid::LowType spawnId = cr->GetSpawnId();
for (ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr)
{
for (NPCFlagList::iterator itr = mGameEventNPCFlags[*e_itr].begin();
itr != mGameEventNPCFlags[*e_itr].end();
++ itr)
if (itr->first == guid)
for (NPCFlagList::iterator itr = mGameEventNPCFlags[*e_itr].begin(); itr != mGameEventNPCFlags[*e_itr].end(); ++ itr)
if (itr->first == spawnId)
mask |= itr->second;
}
@@ -1222,25 +1220,36 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id)
void GameEventMgr::UpdateEventNPCFlags(uint16 event_id)
{
std::unordered_map<uint32, std::unordered_set<ObjectGuid::LowType>> creaturesByMap;
// go through the creatures whose npcflags are changed in the event
for (NPCFlagList::iterator itr = mGameEventNPCFlags[event_id].begin(); itr != mGameEventNPCFlags[event_id].end(); ++itr)
{
// get the creature data from the low guid to get the entry, to be able to find out the whole guid
if (CreatureData const* data = sObjectMgr->GetCreatureData(itr->first))
creaturesByMap[data->mapid].insert(itr->first);
}
for (auto const& p : creaturesByMap)
{
sMapMgr->DoForAllMapsWithMapId(p.first, [this, &p](Map* map)
{
Creature* cr = HashMapHolder<Creature>::Find(MAKE_NEW_GUID(itr->first, data->id, HIGHGUID_UNIT));
// if we found the creature, modify its npcflag
if (cr)
for (auto& spawnId : p.second)
{
uint32 npcflag = GetNPCFlag(cr);
if (const CreatureTemplate* ci = cr->GetCreatureTemplate())
npcflag |= ci->npcflag;
cr->SetUInt32Value(UNIT_NPC_FLAGS, npcflag);
// reset gossip options, since the flag change might have added / removed some
//cr->ResetGossipOptions();
auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(spawnId);
for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr)
{
Creature* creature = itr->second;
uint32 npcflag = GetNPCFlag(creature);
if (CreatureTemplate const* creatureTemplate = creature->GetCreatureTemplate())
npcflag |= creatureTemplate->npcflag;
creature->SetUInt32Value(UNIT_NPC_FLAGS, npcflag);
// reset gossip options, since the flag change might have added / removed some
//cr->ResetGossipOptions();
}
}
// if we didn't find it, then the npcflag will be updated when the creature is loaded
}
});
}
}
@@ -1274,7 +1283,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
return;
}
for (GuidList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin(); itr != mGameEventCreatureGuids[internal_event_id].end(); ++itr)
for (GuidLowList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin(); itr != mGameEventCreatureGuids[internal_event_id].end(); ++itr)
{
// Add to correct cell
if (CreatureData const* data = sObjectMgr->GetCreatureData(*itr))
@@ -1300,7 +1309,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
return;
}
for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin(); itr != mGameEventGameobjectGuids[internal_event_id].end(); ++itr)
for (GuidLowList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin(); itr != mGameEventGameobjectGuids[internal_event_id].end(); ++itr)
{
// Add to correct cell
if (GameObjectData const* data = sObjectMgr->GetGOData(*itr))
@@ -1347,18 +1356,27 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
return;
}
for (GuidList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin(); itr != mGameEventCreatureGuids[internal_event_id].end(); ++itr)
for (GuidLowList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin(); itr != mGameEventCreatureGuids[internal_event_id].end(); ++itr)
{
// check if it's needed by another event, if so, don't remove
if (event_id > 0 && hasCreatureActiveEventExcept(*itr, event_id))
continue;
// Remove the creature from grid
if (CreatureData const* data = sObjectMgr->GetCreatureData(*itr))
{
sObjectMgr->RemoveCreatureFromGrid(*itr, data);
if (Creature* creature = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT), (Creature*)nullptr))
creature->AddObjectToRemoveList();
sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map)
{
auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(*itr);
for (auto itr2 = creatureBounds.first; itr2 != creatureBounds.second;)
{
Creature* creature = itr2->second;
++itr2;
creature->AddObjectToRemoveList();
}
});
}
}
@@ -1369,7 +1387,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
return;
}
for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin(); itr != mGameEventGameobjectGuids[internal_event_id].end(); ++itr)
for (GuidLowList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin(); itr != mGameEventGameobjectGuids[internal_event_id].end(); ++itr)
{
// check if it's needed by another event, if so, don't remove
if (event_id > 0 && hasGameObjectActiveEventExcept(*itr, event_id))
@@ -1379,8 +1397,16 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
{
sObjectMgr->RemoveGameobjectFromGrid(*itr, data);
if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)nullptr))
pGameobject->AddObjectToRemoveList();
sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map)
{
auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(*itr);
for (auto itr2 = gameobjectBounds.first; itr2 != gameobjectBounds.second;)
{
GameObject* go = itr2->second;
++itr2;
go->AddObjectToRemoveList();
}
});
}
}
if (internal_event_id >= int32(mGameEventPoolIds.size()))
@@ -1405,53 +1431,42 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
continue;
// Update if spawned
Creature* creature = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(itr->first, data->id, HIGHGUID_UNIT), (Creature*)nullptr);
if (creature)
sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr, activate](Map* map)
{
if (activate)
auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(itr->first);
for (auto itr2 = creatureBounds.first; itr2 != creatureBounds.second; ++itr2)
{
itr->second.equipement_id_prev = creature->GetCurrentEquipmentId();
itr->second.modelid_prev = creature->GetDisplayId();
creature->LoadEquipment(itr->second.equipment_id, true);
if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid &&
sObjectMgr->GetCreatureModelInfo(itr->second.modelid))
Creature* creature = itr2->second;
if (activate)
{
creature->SetDisplayId(itr->second.modelid);
creature->SetNativeDisplayId(itr->second.modelid);
itr->second.equipement_id_prev = creature->GetCurrentEquipmentId();
itr->second.modelid_prev = creature->GetDisplayId();
creature->LoadEquipment(itr->second.equipment_id, true);
if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid && sObjectMgr->GetCreatureModelInfo(itr->second.modelid))
{
creature->SetDisplayId(itr->second.modelid);
creature->SetNativeDisplayId(itr->second.modelid);
}
}
else
{
creature->LoadEquipment(itr->second.equipement_id_prev, true);
if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid && sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev))
{
creature->SetDisplayId(itr->second.modelid_prev);
creature->SetNativeDisplayId(itr->second.modelid_prev);
}
}
}
else
{
creature->LoadEquipment(itr->second.equipement_id_prev, true);
if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid &&
sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev))
{
creature->SetDisplayId(itr->second.modelid_prev);
creature->SetNativeDisplayId(itr->second.modelid_prev);
}
}
}
else // If not spawned
{
CreatureData const* data2 = sObjectMgr->GetCreatureData(itr->first);
if (data2 && activate)
{
CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(data2->id);
uint32 displayID = ObjectMgr::ChooseDisplayId(cinfo, data2);
sObjectMgr->GetCreatureModelRandomGender(&displayID);
});
if (data2->equipmentId == 0)
itr->second.equipement_id_prev = 0;
else if (data2->equipmentId != -1)
itr->second.equipement_id_prev = data->equipmentId;
itr->second.modelid_prev = displayID;
}
}
// now last step: put in data
// just to have write access to it
CreatureData& data2 = sObjectMgr->NewOrExistCreatureData(itr->first);
if (activate)
{
itr->second.modelid_prev = data2.displayid;
itr->second.equipement_id_prev = data2.equipmentId;
data2.displayid = itr->second.modelid;
data2.equipmentId = itr->second.equipment_id;
}
@@ -1490,33 +1505,29 @@ bool GameEventMgr::hasGameObjectQuestActiveEventExcept(uint32 quest_id, uint16 e
}
return false;
}
bool GameEventMgr::hasCreatureActiveEventExcept(uint32 creature_id, uint16 event_id)
bool GameEventMgr::hasCreatureActiveEventExcept(ObjectGuid::LowType creature_guid, uint16 event_id)
{
for (ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr)
{
if ((*e_itr) != event_id)
{
int32 internal_event_id = mGameEvent.size() + (*e_itr) - 1;
for (GuidList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin();
itr != mGameEventCreatureGuids[internal_event_id].end();
++ itr)
if (*itr == creature_id)
for (GuidLowList::iterator itr = mGameEventCreatureGuids[internal_event_id].begin(); itr != mGameEventCreatureGuids[internal_event_id].end(); ++ itr)
if (*itr == creature_guid)
return true;
}
}
return false;
}
bool GameEventMgr::hasGameObjectActiveEventExcept(uint32 go_id, uint16 event_id)
bool GameEventMgr::hasGameObjectActiveEventExcept(ObjectGuid::LowType go_guid, uint16 event_id)
{
for (ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr)
{
if ((*e_itr) != event_id)
{
int32 internal_event_id = mGameEvent.size() + (*e_itr) - 1;
for (GuidList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin();
itr != mGameEventGameobjectGuids[internal_event_id].end();
++ itr)
if (*itr == go_id)
for (GuidLowList::iterator itr = mGameEventGameobjectGuids[internal_event_id].begin(); itr != mGameEventGameobjectGuids[internal_event_id].end(); ++ itr)
if (*itr == go_guid)
return true;
}
}
@@ -1701,24 +1712,43 @@ void GameEventMgr::SendWorldStateUpdate(Player* player, uint16 event_id)
}
}
class GameEventAIHookWorker
{
public:
GameEventAIHookWorker(uint16 eventId, bool activate) : _eventId(eventId), _activate(activate) { }
void Visit(std::unordered_map<ObjectGuid, Creature*>& creatureMap)
{
for (auto const& p : creatureMap)
if (p.second->IsInWorld() && !p.second->IsDuringRemoveFromWorld() && p.second->FindMap() && p.second->IsAIEnabled && p.second->AI())
p.second->AI()->sOnGameEvent(_activate, _eventId);
}
void Visit(std::unordered_map<ObjectGuid, GameObject*>& gameObjectMap)
{
for (auto const& p : gameObjectMap)
if (p.second->IsInWorld() && p.second->FindMap() && p.second->AI())
p.second->AI()->OnGameEvent(_activate, _eventId);
}
template<class T>
void Visit(std::unordered_map<ObjectGuid, T*>&) { }
private:
uint16 _eventId;
bool _activate;
};
void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate)
{
//! Iterate over every supported source type (creature and gameobject)
//! Not entirely sure how this will affect units in non-loaded grids.
sMapMgr->DoForAllMaps([event_id, activate](Map* map)
{
std::shared_lock<std::shared_mutex> lock(*HashMapHolder<Creature>::GetLock());
HashMapHolder<Creature>::MapType const& m = ObjectAccessor::GetCreatures();
for (HashMapHolder<Creature>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
if (iter->second->IsInWorld() && !iter->second->IsDuringRemoveFromWorld() && iter->second->FindMap() && iter->second->IsAIEnabled && iter->second->AI())
iter->second->AI()->sOnGameEvent(activate, event_id);
}
{
std::shared_lock<std::shared_mutex> lock(*HashMapHolder<GameObject>::GetLock());
HashMapHolder<GameObject>::MapType const& m = ObjectAccessor::GetGameObjects();
for (HashMapHolder<GameObject>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
if (iter->second->IsInWorld() && iter->second->FindMap() && iter->second->AI())
iter->second->AI()->OnGameEvent(activate, event_id);
}
GameEventAIHookWorker worker(event_id, activate);
TypeContainerVisitor<GameEventAIHookWorker, MapStoredObjectTypesContainer> visitor(worker);
visitor.Visit(map->GetObjectsStore());
});
}
void GameEventMgr::SetHolidayEventTime(GameEventData& event)