Skip to content

Commit

Permalink
DynGuid: Fix spawning and respawning of dynguids using command and on…
Browse files Browse the repository at this point in the history
… map init
  • Loading branch information
killerwife committed Nov 29, 2023
1 parent f322337 commit 253f1e1
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 15 deletions.
2 changes: 0 additions & 2 deletions src/game/Entities/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1655,8 +1655,6 @@ bool Creature::LoadFromDB(uint32 dbGuid, Map* map, uint32 newGuid, uint32 forced
{
if (isUsingNewSpawningSystem && !group) // only at this point we know if marked as dynguid per entry
{
GetMap()->GetPersistentState()->RemoveCreatureFromGrid(GetDbGuid(), data);
GetMap()->GetSpawnManager().AddCreature(GetDbGuid());
return false;
}
m_deathState = DEAD;
Expand Down
54 changes: 51 additions & 3 deletions src/game/Globals/ObjectMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,24 @@ WorldStateName* ObjectMgr::GetWorldStateName(int32 Id)
return &(itr->second);
}

std::vector<uint32>* ObjectMgr::GetCreatureDynGuidForMap(uint32 mapId)
{
auto itr = m_dynguidCreatureDbGuids.find(mapId);
if (itr == m_dynguidCreatureDbGuids.end())
return nullptr;

return &(*itr).second;
}

std::vector<uint32>* ObjectMgr::GetGameObjectDynGuidForMap(uint32 mapId)
{
auto itr = m_dynguidGameobjectDbGuids.find(mapId);
if (itr == m_dynguidGameobjectDbGuids.end())
return nullptr;

return &(*itr).second;
}

void ObjectMgr::LoadCreatureImmunities()
{
uint32 count = 0;
Expand Down Expand Up @@ -1952,7 +1970,9 @@ void ObjectMgr::LoadCreatureSpawnEntry()
}

auto& entries = m_creatureSpawnEntryMap[guid];
entries.push_back(entry);
if (cInfo->ExtraFlags & CREATURE_EXTRA_FLAG_ACTIVE)
entries.first = true; // if at least one entry is dynguided, promote dbGuid to dynguided
entries.second.push_back(entry);

++count;
} while (queryResult->NextRow());
Expand Down Expand Up @@ -2008,13 +2028,17 @@ void ObjectMgr::LoadCreatures()

// validate creature dual spawn template
bool isConditional = false;
bool dynGuid = false;
if (entry == 0)
{
CreatureConditionalSpawn const* cSpawn = GetCreatureConditionalSpawn(guid);
if (!cSpawn)
{
if (uint32 randomEntry = GetRandomCreatureEntry(guid))
{
entry = randomEntry;
dynGuid = IsCreatureDbGuidDynGuided(guid);
}
}
else
{
Expand All @@ -2039,6 +2063,9 @@ void ObjectMgr::LoadCreatures()
sLog.outErrorDb("Table `creature` has a creature (GUID: %u, entry: %u) using TotemAI via AIName, skipped.", guid, entry);
continue;
}

if (cInfo->ExtraFlags & CREATURE_EXTRA_FLAG_DYNGUID)
dynGuid = true;
}

CreatureData& data = mCreatureDataMap[guid];
Expand Down Expand Up @@ -2135,6 +2162,10 @@ void ObjectMgr::LoadCreatures()
else
data.OriginalZoneId = 0;

if (dynGuid)
{
m_dynguidCreatureDbGuids[data.mapid].push_back(guid);
}
if (data.IsNotPartOfPoolOrEvent()) // if not this is to be managed by GameEvent System or Pool system
{
AddCreatureToGrid(guid, &data);
Expand Down Expand Up @@ -2221,9 +2252,15 @@ void ObjectMgr::LoadGameObjects()
uint32 guid = fields[ 0].GetUInt32();
uint32 entry = fields[ 1].GetUInt32();

bool dynGuid = false;
if (entry == 0)
{
if (uint32 randomEntry = GetRandomGameObjectEntry(guid))
{
entry = randomEntry;
dynGuid = IsGameObjectDbGuidDynGuided(guid);
}
}

GameObjectInfo const* gInfo = nullptr;
if (entry)
Expand All @@ -2240,6 +2277,9 @@ void ObjectMgr::LoadGameObjects()
sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId);
continue;
}

if (gInfo->ExtraFlags & GAMEOBJECT_EXTRA_FLAG_DYNGUID)
dynGuid = true;
}

GameObjectData& data = mGameObjectDataMap[guid];
Expand Down Expand Up @@ -2338,7 +2378,11 @@ void ObjectMgr::LoadGameObjects()
else
data.OriginalZoneId = 0;

if (data.IsNotPartOfPoolOrEvent()) // if not this is to be managed by GameEvent System or Pool system
if (dynGuid)
{
m_dynguidGameobjectDbGuids[data.mapid].push_back(guid);
}
else if (data.IsNotPartOfPoolOrEvent()) // if not this is to be managed by GameEvent System or Pool system
{
AddGameobjectToGrid(guid, &data);

Expand Down Expand Up @@ -2405,6 +2449,8 @@ void ObjectMgr::LoadGameObjectSpawnEntry()

uint32 count = 0;

std::set<uint32> dynGuided;

do
{
bar.step();
Expand All @@ -2422,7 +2468,9 @@ void ObjectMgr::LoadGameObjectSpawnEntry()
}

auto& entries = m_gameobjectSpawnEntryMap[guid];
entries.push_back(entry);
if (info->ExtraFlags & GAMEOBJECT_EXTRA_FLAG_DYNGUID)
entries.first = true; // if at least one entry is dynguided, promote dbGuid to dynguided
entries.second.push_back(entry);

++count;
} while (queryResult->NextRow());
Expand Down
28 changes: 22 additions & 6 deletions src/game/Globals/ObjectMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ class ObjectMgr

typedef std::unordered_map<uint32, PetCreateSpellEntry> PetCreateSpellMap;

std::unordered_map<uint32, std::vector<uint32>> const& GetCreatureSpawnEntry() const { return m_creatureSpawnEntryMap; }
std::unordered_map<uint32, std::pair<bool, std::vector<uint32>>> const& GetCreatureSpawnEntry() const { return m_creatureSpawnEntryMap; }

std::vector<uint32> LoadGameobjectInfo();

Expand Down Expand Up @@ -575,15 +575,23 @@ class ObjectMgr
return nullptr;
}

std::vector<uint32> const* GetAllRandomEntries(std::unordered_map<uint32, std::vector<uint32>> const& map, uint32 dbguid) const
std::vector<uint32> const* GetAllRandomEntries(std::unordered_map<uint32, std::pair<bool, std::vector<uint32>>> const& map, uint32 dbguid) const
{
auto itr = map.find(dbguid);
if (itr != map.end())
return &(*itr).second;
return &((*itr).second).second;
return nullptr;
}

uint32 GetRandomEntry(std::unordered_map<uint32, std::vector<uint32>> const& map, uint32 dbguid) const
bool IsRandomDbGuidDynguided(std::unordered_map<uint32, std::pair<bool, std::vector<uint32>>> const& map, uint32 dbguid) const
{
auto itr = map.find(dbguid);
if (itr != map.end())
return &((*itr).second).first;
return false;
}

uint32 GetRandomEntry(std::unordered_map<uint32, std::pair<bool, std::vector<uint32>>> const& map, uint32 dbguid) const
{
if (auto spawnList = GetAllRandomEntries(map, dbguid))
return (*spawnList)[irand(0, spawnList->size() - 1)];
Expand All @@ -592,9 +600,11 @@ class ObjectMgr

uint32 GetRandomGameObjectEntry(uint32 dbguid) const { return GetRandomEntry(m_gameobjectSpawnEntryMap, dbguid); }
std::vector<uint32> const* GetAllRandomGameObjectEntries(uint32 dbguid) const { return GetAllRandomEntries(m_gameobjectSpawnEntryMap, dbguid); }
bool IsGameObjectDbGuidDynGuided(uint32 dbGuid) const { return IsRandomDbGuidDynguided(m_gameobjectSpawnEntryMap, dbGuid); }

uint32 GetRandomCreatureEntry(uint32 dbguid) const { return GetRandomEntry(m_creatureSpawnEntryMap, dbguid); }
std::vector<uint32> const* GetAllRandomCreatureEntries(uint32 dbguid) const { return GetAllRandomEntries(m_creatureSpawnEntryMap, dbguid); }
bool IsCreatureDbGuidDynGuided(uint32 dbGuid) const { return IsRandomDbGuidDynguided(m_creatureSpawnEntryMap, dbGuid); }

AreaTrigger const* GetGoBackTrigger(uint32 map_id) const;
AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const;
Expand Down Expand Up @@ -1221,6 +1231,9 @@ class ObjectMgr

bool HasWorldStateName(int32 Id) const;
WorldStateName* GetWorldStateName(int32 Id);

std::vector<uint32>* GetCreatureDynGuidForMap(uint32 mapId);
std::vector<uint32>* GetGameObjectDynGuidForMap(uint32 mapId);
protected:

// current locale settings
Expand Down Expand Up @@ -1277,8 +1290,8 @@ class ObjectMgr
GossipMenusMap m_mGossipMenusMap;
GossipMenuItemsMap m_mGossipMenuItemsMap;

std::unordered_map<uint32, std::vector<uint32>> m_creatureSpawnEntryMap;
std::unordered_map<uint32, std::vector<uint32>> m_gameobjectSpawnEntryMap;
std::unordered_map<uint32, std::pair<bool, std::vector<uint32>>> m_creatureSpawnEntryMap;
std::unordered_map<uint32, std::pair<bool, std::vector<uint32>>> m_gameobjectSpawnEntryMap;
std::unordered_map<uint32, GameObjectTemplateAddon> m_gameobjectAddonTemplates;

PointOfInterestMap mPointsOfInterest;
Expand Down Expand Up @@ -1392,6 +1405,9 @@ class ObjectMgr
std::unique_ptr<UnitConditionMgr> m_unitConditionMgr;
std::unique_ptr<WorldStateExpressionMgr> m_worldStateExpressionMgr;
std::unique_ptr<CombatConditionMgr> m_combatConditionMgr;

std::map<uint32, std::vector<uint32>> m_dynguidCreatureDbGuids;
std::map<uint32, std::vector<uint32>> m_dynguidGameobjectDbGuids;
};

#define sObjectMgr MaNGOS::Singleton<ObjectMgr>::Instance()
Expand Down
11 changes: 7 additions & 4 deletions src/game/Grids/GridNotifiers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,13 @@ void MaNGOS::RespawnDo::operator()(Creature* u) const

if (u->IsUsingNewSpawningSystem())
{
if (u->GetMap()->GetMapDataContainer().GetSpawnGroupByGuid(u->GetDbGuid(), TYPEID_UNIT))
u->GetMap()->GetPersistentState()->SaveCreatureRespawnTime(u->GetDbGuid(), time(nullptr));
else
u->GetMap()->GetSpawnManager().RespawnCreature(u->GetDbGuid(), 0);
if (u->IsDead())
{
if (u->GetMap()->GetMapDataContainer().GetSpawnGroupByGuid(u->GetDbGuid(), TYPEID_UNIT))
u->GetMap()->GetPersistentState()->SaveCreatureRespawnTime(u->GetDbGuid(), time(nullptr));
else
u->GetMap()->GetSpawnManager().RespawnCreature(u->GetDbGuid(), 0);
}
}
else
u->Respawn();
Expand Down
30 changes: 30 additions & 0 deletions src/game/Maps/SpawnManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,36 @@ SpawnManager::~SpawnManager()

void SpawnManager::Initialize()
{
time_t now = time(nullptr);
std::vector<uint32>* dynGuidCreatures = sObjectMgr.GetCreatureDynGuidForMap(m_map.GetId());
if (dynGuidCreatures)
{
for (uint32 dbGuid : *dynGuidCreatures)
{
if (m_map.GetPersistentState()->GetCreatureRespawnTime(dbGuid) < now)
{
auto data = sObjectMgr.GetCreatureData(dbGuid);
m_map.GetPersistentState()->AddCreatureToGrid(dbGuid, data);
}
else
AddCreature(dbGuid);
}
}
std::vector<uint32>* dynGuidGameObjects = sObjectMgr.GetGameObjectDynGuidForMap(m_map.GetId());
if (dynGuidGameObjects)
{
for (uint32 dbGuid : *dynGuidGameObjects)
{
if (m_map.GetPersistentState()->GetGORespawnTime(dbGuid) < now)
{
auto data = sObjectMgr.GetGOData(dbGuid);
m_map.GetPersistentState()->AddGameobjectToGrid(dbGuid, data);
}
else
AddGameObject(dbGuid);
}
}

auto spawnGroupData = m_map.GetMapDataContainer().GetSpawnGroups();
for (auto& groupData : spawnGroupData->spawnGroupMap)
{
Expand Down

0 comments on commit 253f1e1

Please sign in to comment.