diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 863483e21..3d1a336f8 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -497,7 +497,7 @@ void Creature::Update(uint32 update_diff, uint32 diff) { // since pool system can fail to roll unspawned object, this one can remain spawned, so must set respawn nevertheless if (uint16 poolid = sPoolMgr.IsPartOfAPool(GetGUIDLow())) - sPoolMgr.UpdatePool(poolid, GetGUIDLow()); + sPoolMgr.UpdatePool(*GetMap()->GetPersistentState(), poolid, GetGUIDLow()); if (IsInWorld()) // can be despawned by update pool { @@ -527,7 +527,7 @@ void Creature::Update(uint32 update_diff, uint32 diff) { // since pool system can fail to roll unspawned object, this one can remain spawned, so must set respawn nevertheless if (uint16 poolid = sPoolMgr.IsPartOfAPool(GetGUIDLow())) - sPoolMgr.UpdatePool(poolid, GetGUIDLow()); + sPoolMgr.UpdatePool(*GetMap()->GetPersistentState(), poolid, GetGUIDLow()); if (IsInWorld()) // can be despawned by update pool { diff --git a/src/game/Creature.h b/src/game/Creature.h index 509249663..14b6cdb41 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -612,7 +612,6 @@ class MANGOS_DLL_SPEC Creature : public Unit void SetRespawnRadius(float dist) { m_respawnradius = dist; } // Functions spawn/remove creature with DB guid in all loaded map copies (if point grid loaded in map) - // FIXME: it will work for for instanceable maps only after switch to use static guids) static void AddToRemoveListInMaps(uint32 db_guid, CreatureData const* data); static void SpawnInMaps(uint32 db_guid, CreatureData const* data); diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 51f0bd39b..3b25cc630 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -593,6 +593,15 @@ uint32 GameEventMgr::Initialize() // return the next e return delay; } +void GameEventMgr::Initialize( MapPersistentState* state ) +{ + // At map persistent state creating need only apply pool spawn modifications + // other data is global and will be auto-apply + for(GameEventMgr::ActiveEvents::const_iterator event_itr = m_ActiveEvents.begin(); event_itr != m_ActiveEvents.end(); ++event_itr) + for (IdList::iterator pool_itr = mGameEventSpawnPoolIds[*event_itr].begin(); pool_itr != mGameEventSpawnPoolIds[*event_itr].end(); ++pool_itr) + sPoolMgr.InitSpawnPool(*state, *pool_itr); +} + // return the next event delay in ms uint32 GameEventMgr::Update(ActiveEvents const* activeAtShutdown /*= NULL*/) { @@ -703,7 +712,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) { // will have chance at next pool update sPoolMgr.SetExcludeObject(pool_id, *itr, false); - sPoolMgr.UpdatePool(pool_id); + sPoolMgr.UpdatePoolInMaps(pool_id); continue; } } @@ -733,7 +742,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) { // will have chance at next pool update sPoolMgr.SetExcludeObject(pool_id, *itr, false); - sPoolMgr.UpdatePool(pool_id); + sPoolMgr.UpdatePoolInMaps(pool_id); continue; } } @@ -753,7 +762,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) } for (IdList::iterator itr = mGameEventSpawnPoolIds[event_id].begin();itr != mGameEventSpawnPoolIds[event_id].end();++itr) - sPoolMgr.SpawnPool(*itr, true); + sPoolMgr.SpawnPoolInMaps(*itr, true); } } @@ -778,7 +787,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) if (uint16 poolid = sPoolMgr.IsPartOfAPool(*itr)) { sPoolMgr.SetExcludeObject(poolid, *itr, true); - sPoolMgr.UpdatePool(poolid, *itr); + sPoolMgr.UpdatePoolInMaps(poolid, *itr); continue; } } @@ -808,7 +817,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) if (uint16 poolid = sPoolMgr.IsPartOfAPool(*itr)) { sPoolMgr.SetExcludeObject(poolid, *itr, true); - sPoolMgr.UpdatePool(poolid, *itr); + sPoolMgr.UpdatePoolInMaps(poolid, *itr); continue; } } @@ -831,7 +840,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) for (IdList::iterator itr = mGameEventSpawnPoolIds[event_id].begin();itr != mGameEventSpawnPoolIds[event_id].end();++itr) { - sPoolMgr.DespawnPool(*itr); + sPoolMgr.DespawnPoolInMaps(*itr); } } } diff --git a/src/game/GameEventMgr.h b/src/game/GameEventMgr.h index b24382db1..b77346838 100644 --- a/src/game/GameEventMgr.h +++ b/src/game/GameEventMgr.h @@ -77,6 +77,7 @@ class GameEventMgr bool CheckOneGameEvent(uint16 entry, time_t currenttime) const; uint32 NextCheck(uint16 entry) const; void LoadFromDB(); + void Initialize(MapPersistentState* state); // called at new MapPersistentState object create uint32 Update(ActiveEvents const* activeAtShutdown = NULL); bool IsValidEvent(uint16 event_id) const { return event_id < mGameEvent.size() && mGameEvent[event_id].isValid(); } bool IsActiveEvent(uint16 event_id) const { return ( m_ActiveEvents.find(event_id)!=m_ActiveEvents.end()); } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 23904e14d..99f452165 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -424,7 +424,7 @@ void GameObject::Update(uint32 update_diff, uint32 /*p_time*/) // if part of pool, let pool system schedule new spawn instead of just scheduling respawn if (uint16 poolid = sPoolMgr.IsPartOfAPool(GetGUIDLow())) - sPoolMgr.UpdatePool(poolid, GetGUIDLow()); + sPoolMgr.UpdatePool(*GetMap()->GetPersistentState(), poolid, GetGUIDLow()); // can be not in world at pool despawn if (IsInWorld()) @@ -464,7 +464,7 @@ void GameObject::Delete() SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); if (uint16 poolid = sPoolMgr.IsPartOfAPool(GetGUIDLow())) - sPoolMgr.UpdatePool(poolid, GetGUIDLow()); + sPoolMgr.UpdatePool(*GetMap()->GetPersistentState(), poolid, GetGUIDLow()); else AddObjectToRemoveList(); } diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 959da5491..6237e48b4 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -658,7 +658,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject void Delete(); // Functions spawn/remove gameobject with DB guid in all loaded map copies (if point grid loaded in map) - // FIXME: it will work for for instanceable maps only after switch to use static guids) static void AddToRemoveListInMaps(uint32 db_guid, GameObjectData const* data); static void SpawnInMaps(uint32 db_guid, GameObjectData const* data); diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 8bd6e0975..173a53ea5 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -32,7 +32,7 @@ #include "World.h" #include "GameEventMgr.h" #include "SpellMgr.h" -#include "PoolManager.h" +#include "MapPersistentStateMgr.h" #include "AccountMgr.h" #include "GMTicketMgr.h" #include "WaypointManager.h" @@ -842,7 +842,7 @@ bool ChatHandler::HandleGameObjectTargetCommand(char* args) o = fields[5].GetFloat(); mapid = fields[6].GetUInt16(); pool_id = sPoolMgr.IsPartOfAPool(lowguid); - if (!pool_id || sPoolMgr.IsSpawnedObject(lowguid)) + if (!pool_id || pl->GetMap()->GetPersistentState()->IsSpawnedPoolObject(lowguid)) found = true; } while (result->NextRow() && (!found)); @@ -1111,7 +1111,6 @@ bool ChatHandler::HandleGameObjectAddCommand(char* args) map->Add(pGameObj); - // TODO: is it really necessary to add both the real and DB table guid here ? sObjectMgr.AddGameobjectToGrid(db_lowGUID, sObjectMgr.GetGOData(db_lowGUID)); PSendSysMessage(LANG_GAMEOBJECT_ADD,id,gInfo->name,db_lowGUID,x,y,z); diff --git a/src/game/MapPersistentStateMgr.cpp b/src/game/MapPersistentStateMgr.cpp index e9fd163d0..616e1c6dd 100644 --- a/src/game/MapPersistentStateMgr.cpp +++ b/src/game/MapPersistentStateMgr.cpp @@ -30,6 +30,7 @@ #include "GridNotifiersImpl.h" #include "Transports.h" #include "ObjectMgr.h" +#include "GameEventMgr.h" #include "World.h" #include "Group.h" #include "InstanceData.h" @@ -40,7 +41,6 @@ INSTANTIATE_SINGLETON_1( MapPersistentStateManager ); static uint32 resetEventTypeDelay[MAX_RESET_EVENT_TYPE] = { 0, 3600, 900, 300, 60 }; //== MapPersistentState functions ========================== - MapPersistentState::MapPersistentState(uint16 MapId, uint32 InstanceId, Difficulty difficulty) : m_instanceid(InstanceId), m_mapid(MapId), m_difficulty(difficulty), m_usedByMap(NULL) @@ -161,6 +161,7 @@ void MapPersistentState::RemoveGameobjectFromGrid( uint32 guid, GameObjectData c } //== WorldPersistentState functions ======================== +SpawnedPoolData WorldPersistentState::m_sharedSpawnedPoolData; bool WorldPersistentState::CanBeUnload() const { @@ -561,6 +562,14 @@ MapPersistentState* MapPersistentStateManager::AddPersistentState(MapEntry const else m_instanceSaveByMapId[mapEntry->MapID] = state; + // pool system initialized already for persistent state (can be shared by map states) + if (!state->GetSpawnedPoolData().IsInitialized()) + { + sPoolMgr.Initialize(state); // init pool system data for map persistent state + sGameEventMgr.Initialize(state); // init pool system data for map persistent state + state->GetSpawnedPoolData().SetInitialized(); + } + return state; } @@ -819,8 +828,6 @@ void MapPersistentStateManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficu else ((DungeonMap*)map2)->Reset(INSTANCE_RESET_GLOBAL); } - - // TODO: delete creature/gameobject respawn times even if the maps are not loaded } void MapPersistentStateManager::GetStatistics(uint32& numStates, uint32& numBoundPlayers, uint32& numBoundGroups) diff --git a/src/game/MapPersistentStateMgr.h b/src/game/MapPersistentStateMgr.h index b83ef812a..da3fc31ce 100644 --- a/src/game/MapPersistentStateMgr.h +++ b/src/game/MapPersistentStateMgr.h @@ -30,6 +30,7 @@ #include "DBCEnums.h" #include "DBCStores.h" #include "ObjectGuid.h" +#include "PoolManager.h" struct InstanceTemplate; struct MapEntry; @@ -100,6 +101,12 @@ class MapPersistentState } void SaveGORespawnTime(uint32 loguid, time_t t); + // pool system + virtual SpawnedPoolData& GetSpawnedPoolData() =0; + + template + bool IsSpawnedPoolObject(uint32 db_guid_or_pool_id) { return GetSpawnedPoolData().IsSpawnedObject(db_guid_or_pool_id); } + // grid objects (Dynamic map/instance specific added/removed grid spawns from pool system/etc) MapCellObjectGuids const& GetCellObjectGuids(uint32 cell_id) { return m_gridObjectGuids[cell_id]; } void AddCreatureToGrid(uint32 guid, CreatureData const* data); @@ -148,8 +155,12 @@ class WorldPersistentState : public MapPersistentState ~WorldPersistentState() {} + SpawnedPoolData& GetSpawnedPoolData() { return m_sharedSpawnedPoolData; } protected: bool CanBeUnload() const; // overwrite MapPersistentState::CanBeUnload + + private: + static SpawnedPoolData m_sharedSpawnedPoolData; // Pools spawns state for map, shared by all non-instanced maps }; /* @@ -172,6 +183,8 @@ class DungeonPersistentState : public MapPersistentState ~DungeonPersistentState(); + SpawnedPoolData& GetSpawnedPoolData() { return m_spawnedPoolData; } + InstanceTemplate const* GetTemplate() const; uint8 GetPlayerCount() const { return m_playerList.size(); } @@ -220,6 +233,8 @@ class DungeonPersistentState : public MapPersistentState TODO: maybe it's enough to just store the number of players/groups */ PlayerListType m_playerList; // lock MapPersistentState from unload GroupListType m_groupList; // lock MapPersistentState from unload + + SpawnedPoolData m_spawnedPoolData; // Pools spawns state for map copy }; class BattleGroundPersistentState : public MapPersistentState @@ -233,8 +248,12 @@ class BattleGroundPersistentState : public MapPersistentState ~BattleGroundPersistentState() {} + SpawnedPoolData& GetSpawnedPoolData() { return m_spawnedPoolData; } protected: bool CanBeUnload() const; // overwrite MapPersistentState::CanBeUnload + + private: + SpawnedPoolData m_spawnedPoolData; // Pools spawns state for map copy }; enum ResetEventType diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index b71891adc..1efd400a8 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -8828,7 +8828,7 @@ bool FindCreatureData::operator()( CreatureDataPair const& dataPair ) // skip not spawned (in any state), uint16 pool_id = sPoolMgr.IsPartOfAPool(dataPair.first); - if (pool_id && !sPoolMgr.IsSpawnedObject(dataPair.first)) + if (pool_id && !i_player->GetMap()->GetPersistentState()->IsSpawnedPoolObject(dataPair.first)) return false; if (!i_spawnedData || new_dist < i_spawnedDist) @@ -8878,7 +8878,7 @@ bool FindGOData::operator()( GameObjectDataPair const& dataPair ) // skip not spawned (in any state) uint16 pool_id = sPoolMgr.IsPartOfAPool(dataPair.first); - if (pool_id && !sPoolMgr.IsSpawnedObject(dataPair.first)) + if (pool_id && !i_player->GetMap()->GetPersistentState()->IsSpawnedPoolObject(dataPair.first)) return false; if (!i_spawnedData || new_dist < i_spawnedDist) diff --git a/src/game/PoolManager.cpp b/src/game/PoolManager.cpp index 803b82354..de4206b4d 100644 --- a/src/game/PoolManager.cpp +++ b/src/game/PoolManager.cpp @@ -226,18 +226,18 @@ PoolObject* PoolGroup::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom) // If no guid is passed, the pool is just removed (event end case) // If guid is filled, cache will be used and no removal will occur, it just fill the cache template -void PoolGroup::DespawnObject(SpawnedPoolData& spawns, uint32 guid) +void PoolGroup::DespawnObject(MapPersistentState& mapState, uint32 guid) { for (size_t i = 0; i < EqualChanced.size(); ++i) { // if spawned - if (spawns.IsSpawnedObject(EqualChanced[i].guid)) + if (mapState.GetSpawnedPoolData().IsSpawnedObject(EqualChanced[i].guid)) { // any or specially requested if (!guid || EqualChanced[i].guid == guid) { - Despawn1Object(EqualChanced[i].guid); - spawns.RemoveSpawn(EqualChanced[i].guid,poolId); + Despawn1Object(mapState, EqualChanced[i].guid); + mapState.GetSpawnedPoolData().RemoveSpawn(EqualChanced[i].guid,poolId); } } } @@ -245,13 +245,13 @@ void PoolGroup::DespawnObject(SpawnedPoolData& spawns, uint32 guid) for (size_t i = 0; i < ExplicitlyChanced.size(); ++i) { // spawned - if (spawns.IsSpawnedObject(ExplicitlyChanced[i].guid)) + if (mapState.GetSpawnedPoolData().IsSpawnedObject(ExplicitlyChanced[i].guid)) { // any or specially requested if (!guid || ExplicitlyChanced[i].guid == guid) { - Despawn1Object(ExplicitlyChanced[i].guid); - spawns.RemoveSpawn(ExplicitlyChanced[i].guid,poolId); + Despawn1Object(mapState, ExplicitlyChanced[i].guid); + mapState.GetSpawnedPoolData().RemoveSpawn(ExplicitlyChanced[i].guid,poolId); } } } @@ -259,59 +259,45 @@ void PoolGroup::DespawnObject(SpawnedPoolData& spawns, uint32 guid) // Method that is actualy doing the removal job on one creature template<> -void PoolGroup::Despawn1Object(uint32 guid) +void PoolGroup::Despawn1Object(MapPersistentState& mapState, uint32 guid) { if (CreatureData const* data = sObjectMgr.GetCreatureData(guid)) { - sObjectMgr.RemoveCreatureFromGrid(guid, data); - - // FIXME: pool system must have local state for each instanced map copy - // Current code preserve existed single state for all instanced map copies way - // specially because pool system not spawn object in instanceable maps - MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); - - // temporary limit pool system full power work to continents - if (mapEntry && !mapEntry->Instanceable()) + // for non-instanceable maps pool spawn can be at different map from provided mapState + if (MapPersistentState* dataMapState = mapState.GetMapId() == data->mapid ? &mapState : sMapPersistentStateMgr.GetPersistentState(data->mapid, 0)) { - if (Map* map = const_cast(sMapMgr.FindMap(data->mapid))) - { - if (Creature* pCreature = map->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, guid))) + dataMapState->RemoveCreatureFromGrid(guid, data); + + if (Map* dataMap = dataMapState->GetMap()) + if (Creature* pCreature = dataMap->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, guid))) pCreature->AddObjectToRemoveList(); - } } } } // Same on one gameobject template<> -void PoolGroup::Despawn1Object(uint32 guid) +void PoolGroup::Despawn1Object(MapPersistentState& mapState, uint32 guid) { if (GameObjectData const* data = sObjectMgr.GetGOData(guid)) { - sObjectMgr.RemoveGameobjectFromGrid(guid, data); - - // FIXME: pool system must have local state for each instanced map copy - // Current code preserve existed single state for all instanced map copies way - // specially because pool system not spawn object in instanceable maps - MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); - - // temporary limit pool system full power work to continents - if (mapEntry && !mapEntry->Instanceable()) + // for non-instanceable maps pool spawn can be at different map from provided mapState + if (MapPersistentState* dataMapState = mapState.GetMapId() == data->mapid ? &mapState : sMapPersistentStateMgr.GetPersistentState(data->mapid, 0)) { - if (Map* map = const_cast(sMapMgr.FindMap(data->mapid))) - { - if (GameObject* pGameobject = map->GetGameObject(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, guid))) + dataMapState->RemoveGameobjectFromGrid(guid, data); + + if (Map* dataMap = dataMapState->GetMap()) + if (GameObject* pGameobject = dataMap->GetGameObject(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, guid))) pGameobject->AddObjectToRemoveList(); - } } } } // Same on one pool template<> -void PoolGroup::Despawn1Object(uint32 child_pool_id) +void PoolGroup::Despawn1Object(MapPersistentState& mapState, uint32 child_pool_id) { - sPoolMgr.DespawnPool(child_pool_id); + sPoolMgr.DespawnPool(mapState, child_pool_id); } // Method for a pool only to remove any found record causing a circular dependency loop @@ -337,8 +323,10 @@ void PoolGroup::RemoveOneRelation(uint16 child_pool_id) } template -void PoolGroup::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom, bool instantly) +void PoolGroup::SpawnObject(MapPersistentState& mapState, uint32 limit, uint32 triggerFrom, bool instantly) { + SpawnedPoolData& spawns = mapState.GetSpawnedPoolData(); + uint32 lastDespawned = 0; int count = limit - spawns.GetSpawnedObjects(poolId); @@ -366,18 +354,18 @@ void PoolGroup::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 tri { MANGOS_ASSERT(spawns.IsSpawnedObject(obj->guid)); MANGOS_ASSERT(spawns.GetSpawnedObjects(poolId) > 0); - ReSpawn1Object(obj); + ReSpawn1Object(mapState, obj); triggerFrom = 0; continue; } spawns.AddSpawn(obj->guid,poolId); - Spawn1Object(obj, instantly); + Spawn1Object(mapState, obj, instantly); if (triggerFrom) { // One spawn one despawn no count increase - DespawnObject(spawns, triggerFrom); + DespawnObject(mapState, triggerFrom); lastDespawned = triggerFrom; triggerFrom = 0; } @@ -386,27 +374,25 @@ void PoolGroup::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 tri // Method that is actualy doing the spawn job on 1 creature template <> -void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) +void PoolGroup::Spawn1Object(MapPersistentState& mapState, PoolObject* obj, bool instantly) { if (CreatureData const* data = sObjectMgr.GetCreatureData(obj->guid)) { - sObjectMgr.AddCreatureToGrid(obj->guid, data); - MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); - // FIXME: pool system must have local state for each instanced map copy - // Current code preserve existed single state for all instanced map copies way - if (mapEntry && !mapEntry->Instanceable()) + // for non-instanceable maps pool spawn can be at different map from provided mapState + if (MapPersistentState* dataMapState = mapState.GetMapId() == data->mapid ? &mapState : sMapPersistentStateMgr.GetPersistentState(data->mapid, 0)) { - // Spawn if necessary (loaded grids only) - Map* map = const_cast(sMapMgr.FindMap(data->mapid)); + dataMapState->AddCreatureToGrid(obj->guid, data); + + Map* dataMap = dataMapState->GetMap(); // We use spawn coords to spawn - if (map && map->IsLoaded(data->posX, data->posY)) + if (dataMap && dataMap->IsLoaded(data->posX, data->posY)) { Creature* pCreature = new Creature; //DEBUG_LOG("Spawning creature %u",obj->guid); - if (!pCreature->LoadFromDB(obj->guid, map)) + if (!pCreature->LoadFromDB(obj->guid, dataMap)) { delete pCreature; return; @@ -420,13 +406,13 @@ void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) if (sWorld.getConfig(CONFIG_BOOL_SAVE_RESPAWN_TIME_IMMEDIATELY) || pCreature->IsWorldBoss()) pCreature->SaveRespawnTime(); } - map->Add(pCreature); + dataMap->Add(pCreature); } } // for not loaded grid just update respawn time (avoid work for instances until implemented support) else if(!instantly) { - map->GetPersistentState()->SaveCreatureRespawnTime(obj->guid, time(NULL) + data->spawntimesecs); + dataMapState->SaveCreatureRespawnTime(obj->guid, time(NULL) + data->spawntimesecs); } } } @@ -434,27 +420,25 @@ void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) // Same for 1 gameobject template <> -void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) +void PoolGroup::Spawn1Object(MapPersistentState& mapState, PoolObject* obj, bool instantly) { if (GameObjectData const* data = sObjectMgr.GetGOData(obj->guid)) { - sObjectMgr.AddGameobjectToGrid(obj->guid, data); - MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); - // FIXME: pool system must have local state for each instanced map copy - // Current code preserve existed single state for all instanced map copies way - if (mapEntry && !mapEntry->Instanceable()) + // for non-instanceable maps pool spawn can be at different map from provided mapState + if (MapPersistentState* dataMapState = mapState.GetMapId() == data->mapid ? &mapState : sMapPersistentStateMgr.GetPersistentState(data->mapid, 0)) { - // Spawn if necessary (loaded grids only) - Map* map = const_cast(sMapMgr.FindMap(data->mapid)); + dataMapState->AddGameobjectToGrid(obj->guid, data); + + Map* dataMap = dataMapState->GetMap(); // We use spawn coords to spawn - if (map && map->IsLoaded(data->posX, data->posY)) + if (dataMap && dataMap->IsLoaded(data->posX, data->posY)) { GameObject* pGameobject = new GameObject; //DEBUG_LOG("Spawning gameobject %u", obj->guid); - if (!pGameobject->LoadFromDB(obj->guid, map)) + if (!pGameobject->LoadFromDB(obj->guid, dataMap)) { delete pGameobject; return; @@ -470,7 +454,7 @@ void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) if (sWorld.getConfig(CONFIG_BOOL_SAVE_RESPAWN_TIME_IMMEDIATELY)) pGameobject->SaveRespawnTime(); } - map->Add(pGameobject); + dataMap->Add(pGameobject); } } } @@ -479,7 +463,7 @@ void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) { // for spawned by default object only if (data->spawntimesecs >= 0) - map->GetPersistentState()->SaveGORespawnTime(obj->guid, time(NULL) + data->spawntimesecs); + dataMapState->SaveGORespawnTime(obj->guid, time(NULL) + data->spawntimesecs); } } } @@ -487,60 +471,42 @@ void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) // Same for 1 pool template <> -void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) +void PoolGroup::Spawn1Object(MapPersistentState& mapState, PoolObject* obj, bool instantly) { - sPoolMgr.SpawnPool(obj->guid, instantly); + sPoolMgr.SpawnPool(mapState, obj->guid, instantly); } // Method that does the respawn job on the specified creature template <> -void PoolGroup::ReSpawn1Object(PoolObject* obj) +void PoolGroup::ReSpawn1Object(MapPersistentState& mapState, PoolObject* obj) { if (CreatureData const* data = sObjectMgr.GetCreatureData(obj->guid)) { - // FIXME: pool system must have local state for each instanced map copy - // Current code preserve existed single state for all instanced map copies way - // specially because pool system not spawn object in instanceable maps - MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); - - // temporary limit pool system full power work to continents - if (mapEntry && !mapEntry->Instanceable()) - { - if (Map* map = const_cast(sMapMgr.FindMap(data->mapid))) - { - if (Creature* pCreature = map->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, obj->guid))) + // for non-instanceable maps pool spawn can be at different map from provided mapState + if (MapPersistentState* dataMapState = mapState.GetMapId() == data->mapid ? &mapState : sMapPersistentStateMgr.GetPersistentState(data->mapid, 0)) + if (Map* dataMap = dataMapState->GetMap()) + if (Creature* pCreature = dataMap->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, obj->guid))) pCreature->GetMap()->Add(pCreature); - } - } } } // Method that does the respawn job on the specified gameobject template <> -void PoolGroup::ReSpawn1Object(PoolObject* obj) +void PoolGroup::ReSpawn1Object(MapPersistentState& mapState, PoolObject* obj) { if (GameObjectData const* data = sObjectMgr.GetGOData(obj->guid)) { - // FIXME: pool system must have local state for each instanced map copy - // Current code preserve existed single state for all instanced map copies way - // specially because pool system not spawn object in instanceable maps - MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); - - // temporary limit pool system full power work to continents - if (mapEntry && !mapEntry->Instanceable()) - { - if (Map* map = const_cast(sMapMgr.FindMap(data->mapid))) - { - if (GameObject* pGameobject = map->GetGameObject(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, obj->guid))) + // for non-instanceable maps pool spawn can be at different map from provided mapState + if (MapPersistentState* dataMapState = mapState.GetMapId() == data->mapid ? &mapState : sMapPersistentStateMgr.GetPersistentState(data->mapid, 0)) + if (Map* dataMap = dataMapState->GetMap()) + if (GameObject* pGameobject = dataMap->GetGameObject(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, obj->guid))) pGameobject->GetMap()->Add(pGameobject); - } - } } } // Nothing to do for a child Pool template <> -void PoolGroup::ReSpawn1Object(PoolObject* /*obj*/) +void PoolGroup::ReSpawn1Object(MapPersistentState& /*mapState*/, PoolObject* /*obj*/) { } @@ -556,8 +522,9 @@ PoolManager::PoolManager() // This applied to all pools have common mother pool struct PoolMapChecker { - typedef std::map Pool2Maps; - Pool2Maps m_pool2maps; + PoolManager::PoolTemplateDataMap& m_poolTemplates; + + explicit PoolMapChecker(PoolManager::PoolTemplateDataMap& poolTemplates) : m_poolTemplates(poolTemplates) {} bool CheckAndRemember(uint32 mapid, uint32 pool_id, char const* tableName, char const* elementName) { @@ -565,12 +532,12 @@ struct PoolMapChecker if (!mapEntry) return false; - MapEntry const* poolMapEntry = GetPoolMapEntry(pool_id); + MapEntry const* poolMapEntry = m_poolTemplates[pool_id].mapEntry; // if not listed then just remember if (!poolMapEntry) { - m_pool2maps[pool_id] = mapEntry; + m_poolTemplates[pool_id].mapEntry = mapEntry; return true; } @@ -597,12 +564,6 @@ struct PoolMapChecker // pool spawns can be at different non-instanceable maps return true; } - - MapEntry const* GetPoolMapEntry(uint32 pool_id) const - { - Pool2Maps::const_iterator p2m_itr = m_pool2maps.find(pool_id); - return p2m_itr != m_pool2maps.end() ? p2m_itr->second : NULL; - } }; void PoolManager::LoadFromDB() @@ -654,7 +615,7 @@ void PoolManager::LoadFromDB() sLog.outString( ">> Loaded %u objects pools", count ); delete result; - PoolMapChecker mapChecker; + PoolMapChecker mapChecker(mPoolTemplate); // Creatures @@ -707,6 +668,7 @@ void PoolManager::LoadFromDB() continue; PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id]; + ++count; PoolObject plObject = PoolObject(guid, chance); @@ -869,7 +831,7 @@ void PoolManager::LoadFromDB() for(SearchMap::iterator poolItr = mPoolSearchMap.find(i); poolItr != mPoolSearchMap.end(); poolItr = mPoolSearchMap.find(poolItr->second)) { // if child pool not have map data then it empty or have not checked child then will checked and all line later - if (MapEntry const* childMapEntry = mapChecker.GetPoolMapEntry(poolItr->first)) + if (MapEntry const* childMapEntry = mPoolTemplate[poolItr->first].mapEntry) { if (!mapChecker.CheckAndRemember(childMapEntry->MapID, poolItr->second, "pool_pool", "pool with creature/gameobject")) { @@ -902,13 +864,8 @@ void PoolManager::LoadFromDB() sLog.outString( ">> Loaded %u pools in mother pools", count ); delete result; } -} - -// The initialize method will spawn all pools not in an event and not in another pool -void PoolManager::Initialize() -{ - uint32 count = 0; + // check chances integrity for(uint16 pool_entry = 0; pool_entry < mPoolTemplate.size(); ++pool_entry) { if (mPoolTemplate[pool_entry].AutoSpawn) @@ -916,63 +873,68 @@ void PoolManager::Initialize() if (!CheckPool(pool_entry)) { sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry); - continue; + mPoolTemplate[pool_entry].AutoSpawn = false; } - SpawnPool(pool_entry, true); - count++; } } +} - BASIC_LOG("Pool handling system initialized, %u pools spawned.", count); +// The initialize method will spawn all pools not in an event and not in another pool +void PoolManager::Initialize(MapPersistentState* state) +{ + // spawn pools for expected map or for not initialized shared pools state for non-instanceable maps + for(uint16 pool_entry = 0; pool_entry < mPoolTemplate.size(); ++pool_entry) + if (mPoolTemplate[pool_entry].AutoSpawn) + InitSpawnPool(*state, pool_entry); } // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the creature is respawned only (added back to map) template<> -void PoolManager::SpawnPoolGroup(uint16 pool_id, uint32 db_guid, bool instantly) +void PoolManager::SpawnPoolGroup(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid, bool instantly) { if (!mPoolCreatureGroups[pool_id].isEmpty()) - mPoolCreatureGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid, instantly); + mPoolCreatureGroups[pool_id].SpawnObject(mapState, mPoolTemplate[pool_id].MaxLimit, db_guid, instantly); } // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the gameobject is respawned only (added back to map) template<> -void PoolManager::SpawnPoolGroup(uint16 pool_id, uint32 db_guid, bool instantly) +void PoolManager::SpawnPoolGroup(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid, bool instantly) { if (!mPoolGameobjectGroups[pool_id].isEmpty()) - mPoolGameobjectGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid, instantly); + mPoolGameobjectGroups[pool_id].SpawnObject(mapState, mPoolTemplate[pool_id].MaxLimit, db_guid, instantly); } // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the pool is respawned only template<> -void PoolManager::SpawnPoolGroup(uint16 pool_id, uint32 sub_pool_id, bool instantly) +void PoolManager::SpawnPoolGroup(MapPersistentState& mapState, uint16 pool_id, uint32 sub_pool_id, bool instantly) { if (!mPoolPoolGroups[pool_id].isEmpty()) - mPoolPoolGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, sub_pool_id, instantly); + mPoolPoolGroups[pool_id].SpawnObject(mapState, mPoolTemplate[pool_id].MaxLimit, sub_pool_id, instantly); } /*! \param instantly defines if (leaf-)objects are spawned instantly or with fresh respawn timer */ -void PoolManager::SpawnPool(uint16 pool_id, bool instantly) +void PoolManager::SpawnPool(MapPersistentState& mapState, uint16 pool_id, bool instantly) { - SpawnPoolGroup(pool_id, 0, instantly); - SpawnPoolGroup(pool_id, 0, instantly); - SpawnPoolGroup(pool_id, 0, instantly); + SpawnPoolGroup(mapState, pool_id, 0, instantly); + SpawnPoolGroup(mapState, pool_id, 0, instantly); + SpawnPoolGroup(mapState, pool_id, 0, instantly); } // Call to despawn a pool, all gameobjects/creatures in this pool are removed -void PoolManager::DespawnPool(uint16 pool_id) +void PoolManager::DespawnPool(MapPersistentState& mapState, uint16 pool_id) { if (!mPoolCreatureGroups[pool_id].isEmpty()) - mPoolCreatureGroups[pool_id].DespawnObject(mSpawnedData); + mPoolCreatureGroups[pool_id].DespawnObject(mapState); if (!mPoolGameobjectGroups[pool_id].isEmpty()) - mPoolGameobjectGroups[pool_id].DespawnObject(mSpawnedData); + mPoolGameobjectGroups[pool_id].DespawnObject(mapState); if (!mPoolPoolGroups[pool_id].isEmpty()) - mPoolPoolGroups[pool_id].DespawnObject(mSpawnedData); + mPoolPoolGroups[pool_id].DespawnObject(mapState); } // Method that check chance integrity of the creatures and gameobjects in this pool @@ -1009,14 +971,109 @@ void PoolManager::SetExcludeObject(uint16 pool_id, uint32 db_guid_or // Here we cache only the creature/gameobject whose guid is passed as parameter // Then the spawn pool call will use this cache to decide template -void PoolManager::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id) +void PoolManager::UpdatePool(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id) { if (uint16 motherpoolid = IsPartOfAPool(pool_id)) - SpawnPoolGroup(motherpoolid, pool_id, false); + SpawnPoolGroup(mapState, motherpoolid, pool_id, false); else - SpawnPoolGroup(pool_id, db_guid_or_pool_id, false); + SpawnPoolGroup(mapState, pool_id, db_guid_or_pool_id, false); } -template void PoolManager::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id); -template void PoolManager::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id); -template void PoolManager::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id); +template void PoolManager::UpdatePool(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id); +template void PoolManager::UpdatePool(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id); +template void PoolManager::UpdatePool(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id); + +struct SpawnPoolInMapsWorker +{ + explicit SpawnPoolInMapsWorker(PoolManager& mgr, uint32 pool_id, bool instantly) + : i_mgr(mgr), i_pool_id(pool_id), i_instantly(instantly) {} + + void operator() (MapPersistentState* state) + { + i_mgr.SpawnPool(*state, i_pool_id, i_instantly); + } + + PoolManager& i_mgr; + uint32 i_pool_id; + bool i_instantly; +}; + +// used for calling from global systems when need spawn pool in all appropriate map persistent states +void PoolManager::SpawnPoolInMaps(uint16 pool_id, bool instantly) +{ + PoolTemplateData& poolTemplate = mPoolTemplate[pool_id]; + + // pool no have spawns (base at loading algo + if (!poolTemplate.mapEntry) + return; + + SpawnPoolInMapsWorker worker(*this, pool_id, instantly); + sMapPersistentStateMgr.DoForAllStatesWithMapId(poolTemplate.mapEntry->MapID, worker); +} + +struct DespawnPoolInMapsWorker +{ + explicit DespawnPoolInMapsWorker(PoolManager& mgr, uint32 pool_id) + : i_mgr(mgr), i_pool_id(pool_id) {} + + void operator() (MapPersistentState* state) + { + i_mgr.DespawnPool(*state, i_pool_id); + } + + PoolManager& i_mgr; + uint32 i_pool_id; +}; + +// used for calling from global systems when need spawn pool in all appropriate map persistent states +void PoolManager::DespawnPoolInMaps(uint16 pool_id) +{ + PoolTemplateData& poolTemplate = mPoolTemplate[pool_id]; + + // pool no have spawns (base at loading algo + if (!poolTemplate.mapEntry) + return; + + DespawnPoolInMapsWorker worker(*this, pool_id); + sMapPersistentStateMgr.DoForAllStatesWithMapId(poolTemplate.mapEntry->MapID, worker); +} + +void PoolManager::InitSpawnPool(MapPersistentState& mapState, uint16 pool_id) +{ + // spawn pool for expected map or for not initialized shared pools state for non-instanceable maps + if (mPoolTemplate[pool_id].CanBeSpawnedAtMap(mapState.GetMapEntry())) + SpawnPool(mapState, pool_id, true); +} + +template +struct UpdatePoolInMapsWorker +{ + explicit UpdatePoolInMapsWorker(PoolManager& mgr, uint32 pool_id, uint32 db_guid_or_pool_id) + : i_mgr(mgr), i_pool_id(pool_id), i_db_guid_or_pool_id(db_guid_or_pool_id) {} + + void operator() (MapPersistentState* state) + { + i_mgr.UpdatePool(*state, i_pool_id, i_db_guid_or_pool_id); + } + + PoolManager& i_mgr; + uint32 i_pool_id; + uint32 i_db_guid_or_pool_id; +}; + +template +void PoolManager::UpdatePoolInMaps(uint16 pool_id, uint32 db_guid_or_pool_id) +{ + PoolTemplateData& poolTemplate = mPoolTemplate[pool_id]; + + // pool no have spawns (base at loading algo + if (!poolTemplate.mapEntry) + return; + + UpdatePoolInMapsWorker worker(*this, pool_id, db_guid_or_pool_id); + sMapPersistentStateMgr.DoForAllStatesWithMapId(poolTemplate.mapEntry->MapID, worker); +} + +template void PoolManager::UpdatePoolInMaps(uint16 pool_id, uint32 db_guid_or_pool_id); +template void PoolManager::UpdatePoolInMaps(uint16 pool_id, uint32 db_guid_or_pool_id); +template void PoolManager::UpdatePoolInMaps(uint16 pool_id, uint32 db_guid_or_pool_id); diff --git a/src/game/PoolManager.h b/src/game/PoolManager.h index 7bf0c469f..24b34ab5c 100644 --- a/src/game/PoolManager.h +++ b/src/game/PoolManager.h @@ -25,10 +25,24 @@ #include "Creature.h" #include "GameObject.h" +class MapPersistentState; +struct MapEntry; + struct PoolTemplateData { + PoolTemplateData() : mapEntry(NULL), MaxLimit(0), AutoSpawn(false) {} + + MapEntry const* mapEntry; // Map id used for pool creature/gameobject spams. In case non-instanceable map + // it can be not unique but base at sharing same pool system dynamic data in this case this is not important. + // NULL is no spawns by some reason uint32 MaxLimit; bool AutoSpawn; // spawn at pool system start (not part of another pool and not part of event spawn) + + // helpers + bool CanBeSpawnedAtMap(MapEntry const* entry) const + { + return mapEntry && (mapEntry == entry || !entry->Instanceable() && !mapEntry->Instanceable()); + } }; struct PoolObject @@ -53,6 +67,8 @@ typedef std::map SpawnedPoolPools; class SpawnedPoolData { public: + SpawnedPoolData() : m_isInitialized(false) {} + template bool IsSpawnedObject(uint32 db_guid_or_pool_id) const; @@ -63,10 +79,14 @@ class SpawnedPoolData template void RemoveSpawn(uint32 db_guid_or_pool_id, uint32 pool_id); + + bool IsInitialized() const { return m_isInitialized; } + void SetInitialized() { m_isInitialized = true; } private: SpawnedPoolObjects mSpawnedCreatures; SpawnedPoolObjects mSpawnedGameobjects; SpawnedPoolPools mSpawnedPools; + bool m_isInitialized; }; template @@ -82,13 +102,13 @@ class PoolGroup bool CheckPool() const; void CheckEventLinkAndReport(int16 event_id, std::map const& creature2event, std::map const& go2event) const; PoolObject* RollOne(SpawnedPoolData& spawns, uint32 triggerFrom); - void DespawnObject(SpawnedPoolData& spawns, uint32 guid=0); - void Despawn1Object(uint32 guid); - void SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom, bool instantly); + void DespawnObject(MapPersistentState& mapState, uint32 guid=0); + void Despawn1Object(MapPersistentState& mapState, uint32 guid); + void SpawnObject(MapPersistentState& mapState, uint32 limit, uint32 triggerFrom, bool instantly); void SetExcludeObject(uint32 guid, bool state); - void Spawn1Object(PoolObject* obj, bool instantly); - void ReSpawn1Object(PoolObject* obj); + void Spawn1Object(MapPersistentState& mapState, PoolObject* obj, bool instantly); + void ReSpawn1Object(MapPersistentState& mapState, PoolObject* obj); void RemoveOneRelation(uint16 child_pool_id); private: uint32 poolId; @@ -103,7 +123,9 @@ class PoolManager ~PoolManager() {}; void LoadFromDB(); - void Initialize(); + void Initialize(MapPersistentState* state); // called at new MapPersistentState object create + + uint16 GetMaxPoolId() const { return max_pool_id; } template uint16 IsPartOfAPool(uint32 db_guid_or_pool_id) const; @@ -123,28 +145,36 @@ class PoolManager return 0; } - template - bool IsSpawnedObject(uint32 db_guid_or_pool_id) const { return mSpawnedData.IsSpawnedObject(db_guid_or_pool_id); } - template void SetExcludeObject(uint16 pool_id, uint32 db_guid_or_pool_id, bool state); bool CheckPool(uint16 pool_id) const; void CheckEventLinkAndReport(uint16 pool_id, int16 event_id, std::map const& creature2event, std::map const& go2event) const; - void SpawnPool(uint16 pool_id, bool instantly); - void DespawnPool(uint16 pool_id); + void SpawnPool(MapPersistentState& mapState, uint16 pool_id, bool instantly); + void DespawnPool(MapPersistentState& mapState, uint16 pool_id); template - void UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id = 0); + void UpdatePool(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id = 0); + + // used for calling from global systems when need spawn pool in all appropriate map instances + void SpawnPoolInMaps(uint16 pool_id, bool instantly); + void DespawnPoolInMaps(uint16 pool_id); + + // used for calling from global systems when need initialize spawn pool state in appropriate (possible) map persistent state + void InitSpawnPool(MapPersistentState& mapState, uint16 pool_id); + + template + void UpdatePoolInMaps(uint16 pool_id, uint32 db_guid_or_pool_id = 0); void RemoveAutoSpawnForPool(uint16 pool_id) { mPoolTemplate[pool_id].AutoSpawn = false; } + + typedef std::vector PoolTemplateDataMap; protected: template - void SpawnPoolGroup(uint16 pool_id, uint32 db_guid_or_pool_id, bool instantly); + void SpawnPoolGroup(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id, bool instantly); uint16 max_pool_id; - typedef std::vector PoolTemplateDataMap; typedef std::vector > PoolGroupCreatureMap; typedef std::vector > PoolGroupGameObjectMap; @@ -161,9 +191,6 @@ class PoolManager SearchMap mCreatureSearchMap; SearchMap mGameobjectSearchMap; SearchMap mPoolSearchMap; - - // dynamic data - SpawnedPoolData mSpawnedData; }; #define sPoolMgr MaNGOS::Singleton::Instance() diff --git a/src/game/World.cpp b/src/game/World.cpp index 611aea382..a020e0da9 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1041,15 +1041,9 @@ void World::SetInitialWorldSettings() sLog.outString( ">>> Creature Addon Data loaded" ); sLog.outString(); - sLog.outString( "Loading Creature Respawn Data..." ); // must be after PackInstances() - sMapPersistentStateMgr.LoadCreatureRespawnTimes(); - sLog.outString( "Loading Gameobject Data..." ); sObjectMgr.LoadGameobjects(); - sLog.outString( "Loading Gameobject Respawn Data..." ); // must be after PackInstances() - sMapPersistentStateMgr.LoadGameobjectRespawnTimes(); - sLog.outString( "Loading Objects Pooling Data..."); sPoolMgr.LoadFromDB(); @@ -1074,6 +1068,12 @@ void World::SetInitialWorldSettings() sLog.outString( ">>> Game Event Data loaded" ); sLog.outString(); + sLog.outString( "Loading Creature Respawn Data..." ); // must be after PackInstances(), LoadCreatures(), sPoolMgr.LoadFromDB(), sGameEventMgr.LoadFromDB(); + sMapPersistentStateMgr.LoadCreatureRespawnTimes(); + + sLog.outString( "Loading Gameobject Respawn Data..." ); // must be after PackInstances(), LoadGameobjects(), sPoolMgr.LoadFromDB(), sGameEventMgr.LoadFromDB(); + sMapPersistentStateMgr.LoadGameobjectRespawnTimes(); + sLog.outString( "Loading UNIT_NPC_FLAG_SPELLCLICK Data..." ); sObjectMgr.LoadNPCSpellClickSpells(); @@ -1337,9 +1337,6 @@ void World::SetInitialWorldSettings() sLog.outString("Calculate next monthly quest reset time..." ); SetMonthlyQuestResetTime(); - sLog.outString("Starting objects Pooling system..." ); - sPoolMgr.Initialize(); - sLog.outString("Starting Game Event system..." ); uint32 nextGameEvent = sGameEventMgr.Initialize(); m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); //depend on next event diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b5426da50..b45007f95 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11167" + #define REVISION_NR "11168" #endif // __REVISION_NR_H__