mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[11168] Use MapPersistentState for access to Pool System dynamic data.
* Direct store pool system dynamic data in sPoolMgr replaced by shared pool system data object (for all non instanceable maps) into WorldPersistentState, and own copies of pool system data object in DungeonPersistentState/BattlegroundPersistentState. This let have pools with object at many non-instanceable maps, and single map pools with unique state for each instance. * Avoid direct global grid data modify from pool system, and use for this also recently added local for MapPersistentState grid spawn data. * Implemented proper API for update pool system data in MapPersistentStates from GameEvent system. * Initialize pool system state at MapPersistendState creating. For shared pool system state for non-instanceable maps initilized at first map state creating. Now pool system propertly work in instance also!
This commit is contained in:
parent
9e14a0529d
commit
8feaf211f1
14 changed files with 299 additions and 185 deletions
|
|
@ -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<Creature>(GetGUIDLow()))
|
||||
sPoolMgr.UpdatePool<Creature>(poolid, GetGUIDLow());
|
||||
sPoolMgr.UpdatePool<Creature>(*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<Creature>(GetGUIDLow()))
|
||||
sPoolMgr.UpdatePool<Creature>(poolid, GetGUIDLow());
|
||||
sPoolMgr.UpdatePool<Creature>(*GetMap()->GetPersistentState(), poolid, GetGUIDLow());
|
||||
|
||||
if (IsInWorld()) // can be despawned by update pool
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Creature>(pool_id, *itr, false);
|
||||
sPoolMgr.UpdatePool<Creature>(pool_id);
|
||||
sPoolMgr.UpdatePoolInMaps<Creature>(pool_id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -733,7 +742,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
|
|||
{
|
||||
// will have chance at next pool update
|
||||
sPoolMgr.SetExcludeObject<GameObject>(pool_id, *itr, false);
|
||||
sPoolMgr.UpdatePool<GameObject>(pool_id);
|
||||
sPoolMgr.UpdatePoolInMaps<GameObject>(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<Creature>(*itr))
|
||||
{
|
||||
sPoolMgr.SetExcludeObject<Creature>(poolid, *itr, true);
|
||||
sPoolMgr.UpdatePool<Creature>(poolid, *itr);
|
||||
sPoolMgr.UpdatePoolInMaps<Creature>(poolid, *itr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -808,7 +817,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
|
|||
if (uint16 poolid = sPoolMgr.IsPartOfAPool<GameObject>(*itr))
|
||||
{
|
||||
sPoolMgr.SetExcludeObject<GameObject>(poolid, *itr, true);
|
||||
sPoolMgr.UpdatePool<GameObject>(poolid, *itr);
|
||||
sPoolMgr.UpdatePoolInMaps<GameObject>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()); }
|
||||
|
|
|
|||
|
|
@ -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<GameObject>(GetGUIDLow()))
|
||||
sPoolMgr.UpdatePool<GameObject>(poolid, GetGUIDLow());
|
||||
sPoolMgr.UpdatePool<GameObject>(*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<GameObject>(GetGUIDLow()))
|
||||
sPoolMgr.UpdatePool<GameObject>(poolid, GetGUIDLow());
|
||||
sPoolMgr.UpdatePool<GameObject>(*GetMap()->GetPersistentState(), poolid, GetGUIDLow());
|
||||
else
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<GameObject>(lowguid);
|
||||
if (!pool_id || sPoolMgr.IsSpawnedObject<GameObject>(lowguid))
|
||||
if (!pool_id || pl->GetMap()->GetPersistentState()->IsSpawnedPoolObject<GameObject>(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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<typename T>
|
||||
bool IsSpawnedPoolObject(uint32 db_guid_or_pool_id) { return GetSpawnedPoolData().IsSpawnedObject<T>(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
|
||||
|
|
|
|||
|
|
@ -8828,7 +8828,7 @@ bool FindCreatureData::operator()( CreatureDataPair const& dataPair )
|
|||
|
||||
// skip not spawned (in any state),
|
||||
uint16 pool_id = sPoolMgr.IsPartOfAPool<Creature>(dataPair.first);
|
||||
if (pool_id && !sPoolMgr.IsSpawnedObject<Creature>(dataPair.first))
|
||||
if (pool_id && !i_player->GetMap()->GetPersistentState()->IsSpawnedPoolObject<Creature>(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<GameObject>(dataPair.first);
|
||||
if (pool_id && !sPoolMgr.IsSpawnedObject<GameObject>(dataPair.first))
|
||||
if (pool_id && !i_player->GetMap()->GetPersistentState()->IsSpawnedPoolObject<GameObject>(dataPair.first))
|
||||
return false;
|
||||
|
||||
if (!i_spawnedData || new_dist < i_spawnedDist)
|
||||
|
|
|
|||
|
|
@ -226,18 +226,18 @@ PoolObject* PoolGroup<T>::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<class T>
|
||||
void PoolGroup<T>::DespawnObject(SpawnedPoolData& spawns, uint32 guid)
|
||||
void PoolGroup<T>::DespawnObject(MapPersistentState& mapState, uint32 guid)
|
||||
{
|
||||
for (size_t i = 0; i < EqualChanced.size(); ++i)
|
||||
{
|
||||
// if spawned
|
||||
if (spawns.IsSpawnedObject<T>(EqualChanced[i].guid))
|
||||
if (mapState.GetSpawnedPoolData().IsSpawnedObject<T>(EqualChanced[i].guid))
|
||||
{
|
||||
// any or specially requested
|
||||
if (!guid || EqualChanced[i].guid == guid)
|
||||
{
|
||||
Despawn1Object(EqualChanced[i].guid);
|
||||
spawns.RemoveSpawn<T>(EqualChanced[i].guid,poolId);
|
||||
Despawn1Object(mapState, EqualChanced[i].guid);
|
||||
mapState.GetSpawnedPoolData().RemoveSpawn<T>(EqualChanced[i].guid,poolId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -245,13 +245,13 @@ void PoolGroup<T>::DespawnObject(SpawnedPoolData& spawns, uint32 guid)
|
|||
for (size_t i = 0; i < ExplicitlyChanced.size(); ++i)
|
||||
{
|
||||
// spawned
|
||||
if (spawns.IsSpawnedObject<T>(ExplicitlyChanced[i].guid))
|
||||
if (mapState.GetSpawnedPoolData().IsSpawnedObject<T>(ExplicitlyChanced[i].guid))
|
||||
{
|
||||
// any or specially requested
|
||||
if (!guid || ExplicitlyChanced[i].guid == guid)
|
||||
{
|
||||
Despawn1Object(ExplicitlyChanced[i].guid);
|
||||
spawns.RemoveSpawn<T>(ExplicitlyChanced[i].guid,poolId);
|
||||
Despawn1Object(mapState, ExplicitlyChanced[i].guid);
|
||||
mapState.GetSpawnedPoolData().RemoveSpawn<T>(ExplicitlyChanced[i].guid,poolId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -259,59 +259,45 @@ void PoolGroup<T>::DespawnObject(SpawnedPoolData& spawns, uint32 guid)
|
|||
|
||||
// Method that is actualy doing the removal job on one creature
|
||||
template<>
|
||||
void PoolGroup<Creature>::Despawn1Object(uint32 guid)
|
||||
void PoolGroup<Creature>::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<Map*>(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<GameObject>::Despawn1Object(uint32 guid)
|
||||
void PoolGroup<GameObject>::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<Map*>(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<Pool>::Despawn1Object(uint32 child_pool_id)
|
||||
void PoolGroup<Pool>::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<Pool>::RemoveOneRelation(uint16 child_pool_id)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void PoolGroup<T>::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom, bool instantly)
|
||||
void PoolGroup<T>::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<T>::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 tri
|
|||
{
|
||||
MANGOS_ASSERT(spawns.IsSpawnedObject<T>(obj->guid));
|
||||
MANGOS_ASSERT(spawns.GetSpawnedObjects(poolId) > 0);
|
||||
ReSpawn1Object(obj);
|
||||
ReSpawn1Object(mapState, obj);
|
||||
triggerFrom = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
spawns.AddSpawn<T>(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<T>::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 tri
|
|||
|
||||
// Method that is actualy doing the spawn job on 1 creature
|
||||
template <>
|
||||
void PoolGroup<Creature>::Spawn1Object(PoolObject* obj, bool instantly)
|
||||
void PoolGroup<Creature>::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<Map*>(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<Creature>::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<Creature>::Spawn1Object(PoolObject* obj, bool instantly)
|
|||
|
||||
// Same for 1 gameobject
|
||||
template <>
|
||||
void PoolGroup<GameObject>::Spawn1Object(PoolObject* obj, bool instantly)
|
||||
void PoolGroup<GameObject>::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<Map*>(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<GameObject>::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<GameObject>::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<GameObject>::Spawn1Object(PoolObject* obj, bool instantly)
|
|||
|
||||
// Same for 1 pool
|
||||
template <>
|
||||
void PoolGroup<Pool>::Spawn1Object(PoolObject* obj, bool instantly)
|
||||
void PoolGroup<Pool>::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<Creature>::ReSpawn1Object(PoolObject* obj)
|
||||
void PoolGroup<Creature>::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<Map*>(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<GameObject>::ReSpawn1Object(PoolObject* obj)
|
||||
void PoolGroup<GameObject>::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<Map*>(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<Pool>::ReSpawn1Object(PoolObject* /*obj*/)
|
||||
void PoolGroup<Pool>::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<uint32,MapEntry const*> 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<Creature>(uint16 pool_id, uint32 db_guid, bool instantly)
|
||||
void PoolManager::SpawnPoolGroup<Creature>(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<GameObject>(uint16 pool_id, uint32 db_guid, bool instantly)
|
||||
void PoolManager::SpawnPoolGroup<GameObject>(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<Pool>(uint16 pool_id, uint32 sub_pool_id, bool instantly)
|
||||
void PoolManager::SpawnPoolGroup<Pool>(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>(pool_id, 0, instantly);
|
||||
SpawnPoolGroup<GameObject>(pool_id, 0, instantly);
|
||||
SpawnPoolGroup<Creature>(pool_id, 0, instantly);
|
||||
SpawnPoolGroup<Pool>(mapState, pool_id, 0, instantly);
|
||||
SpawnPoolGroup<GameObject>(mapState, pool_id, 0, instantly);
|
||||
SpawnPoolGroup<Creature>(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<GameObject>(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<typename T>
|
||||
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>(pool_id))
|
||||
SpawnPoolGroup<Pool>(motherpoolid, pool_id, false);
|
||||
SpawnPoolGroup<Pool>(mapState, motherpoolid, pool_id, false);
|
||||
else
|
||||
SpawnPoolGroup<T>(pool_id, db_guid_or_pool_id, false);
|
||||
SpawnPoolGroup<T>(mapState, pool_id, db_guid_or_pool_id, false);
|
||||
}
|
||||
|
||||
template void PoolManager::UpdatePool<Pool>(uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
template void PoolManager::UpdatePool<GameObject>(uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
template void PoolManager::UpdatePool<Creature>(uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
template void PoolManager::UpdatePool<Pool>(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
template void PoolManager::UpdatePool<GameObject>(MapPersistentState& mapState, uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
template void PoolManager::UpdatePool<Creature>(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<typename T>
|
||||
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<T>(*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<typename T>
|
||||
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<T> worker(*this, pool_id, db_guid_or_pool_id);
|
||||
sMapPersistentStateMgr.DoForAllStatesWithMapId(poolTemplate.mapEntry->MapID, worker);
|
||||
}
|
||||
|
||||
template void PoolManager::UpdatePoolInMaps<Pool>(uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
template void PoolManager::UpdatePoolInMaps<GameObject>(uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
template void PoolManager::UpdatePoolInMaps<Creature>(uint16 pool_id, uint32 db_guid_or_pool_id);
|
||||
|
|
|
|||
|
|
@ -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<uint32,uint32> SpawnedPoolPools;
|
|||
class SpawnedPoolData
|
||||
{
|
||||
public:
|
||||
SpawnedPoolData() : m_isInitialized(false) {}
|
||||
|
||||
template<typename T>
|
||||
bool IsSpawnedObject(uint32 db_guid_or_pool_id) const;
|
||||
|
||||
|
|
@ -63,10 +79,14 @@ class SpawnedPoolData
|
|||
|
||||
template<typename T>
|
||||
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 <class T>
|
||||
|
|
@ -82,13 +102,13 @@ class PoolGroup
|
|||
bool CheckPool() const;
|
||||
void CheckEventLinkAndReport(int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> 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<typename T>
|
||||
uint16 IsPartOfAPool(uint32 db_guid_or_pool_id) const;
|
||||
|
|
@ -123,28 +145,36 @@ class PoolManager
|
|||
return 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool IsSpawnedObject(uint32 db_guid_or_pool_id) const { return mSpawnedData.IsSpawnedObject<T>(db_guid_or_pool_id); }
|
||||
|
||||
template<typename T>
|
||||
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<uint32, int16> const& creature2event, std::map<uint32, int16> 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<typename T>
|
||||
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<typename T>
|
||||
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<PoolTemplateData> PoolTemplateDataMap;
|
||||
protected:
|
||||
template<typename T>
|
||||
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<PoolTemplateData> PoolTemplateDataMap;
|
||||
|
||||
typedef std::vector<PoolGroup<Creature> > PoolGroupCreatureMap;
|
||||
typedef std::vector<PoolGroup<GameObject> > PoolGroupGameObjectMap;
|
||||
|
|
@ -161,9 +191,6 @@ class PoolManager
|
|||
SearchMap mCreatureSearchMap;
|
||||
SearchMap mGameobjectSearchMap;
|
||||
SearchMap mPoolSearchMap;
|
||||
|
||||
// dynamic data
|
||||
SpawnedPoolData mSpawnedData;
|
||||
};
|
||||
|
||||
#define sPoolMgr MaNGOS::Singleton<PoolManager>::Instance()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11167"
|
||||
#define REVISION_NR "11168"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue