mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-19 03:45:43 +00:00
feat(Core/Misc): implement ObjectGuid class (port from TC) (#4885)
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user