31 ActivePoolPools::const_iterator itr =
mSpawnedPools.find(pool_id);
57void ActivePoolData::ActivateObject<Creature>(
uint32 db_guid,
uint32 pool_id)
64void ActivePoolData::ActivateObject<GameObject>(
uint32 db_guid,
uint32 pool_id)
71void ActivePoolData::ActivateObject<Pool>(
uint32 sub_pool_id,
uint32 pool_id)
78void ActivePoolData::RemoveObject<Creature>(
uint32 db_guid,
uint32 pool_id)
87void ActivePoolData::RemoveObject<GameObject>(
uint32 db_guid,
uint32 pool_id)
96void ActivePoolData::RemoveObject<Pool>(
uint32 sub_pool_id,
uint32 pool_id)
111 if (poolitem.
chance != 0 && maxentries == 1)
112 ExplicitlyChanced.push_back(poolitem);
114 EqualChanced.push_back(poolitem);
121 if (EqualChanced.empty())
124 for (
uint32 i = 0; i < ExplicitlyChanced.size(); ++i)
125 chance += ExplicitlyChanced[i].chance;
126 if (chance != 100 && chance != 0)
139 Despawn1Object(guid, alwaysDeleteRespawnTime);
142 else if (alwaysDeleteRespawnTime)
143 RemoveRespawnTimeFromDB(guid);
150 DespawnObject(spawns, pooledObject.guid, alwaysDeleteRespawnTime);
152 for (
PoolObject& pooledObject : ExplicitlyChanced)
153 DespawnObject(spawns, pooledObject.guid, alwaysDeleteRespawnTime);
162 sObjectMgr->RemoveCreatureFromGrid(guid, data);
164 Map* map =
sMapMgr->CreateBaseMap(data->mapId);
168 for (
auto itr = creatureBounds.first; itr != creatureBounds.second;)
178 if (alwaysDeleteRespawnTime)
190 sObjectMgr->RemoveGameobjectFromGrid(guid, data);
192 Map* map =
sMapMgr->CreateBaseMap(data->mapId);
196 for (
auto itr = gameobjectBounds.first; itr != gameobjectBounds.second;)
207 if (alwaysDeleteRespawnTime)
217 sPoolMgr->DespawnPool(child_pool_id, alwaysDeleteRespawnTime);
224 for (PoolObjectList::iterator itr = ExplicitlyChanced.begin(); itr != ExplicitlyChanced.end(); ++itr)
226 if (itr->guid == child_pool_id)
228 ExplicitlyChanced.erase(itr);
232 for (PoolObjectList::iterator itr = EqualChanced.begin(); itr != EqualChanced.end(); ++itr)
234 if (itr->guid == child_pool_id)
236 EqualChanced.erase(itr);
248 DespawnObject(spawns, triggerFrom);
255 candidates.reserve(EqualChanced.size() + ExplicitlyChanced.size());
260 candidates.push_back(obj);
264 candidates.push_back(obj);
266 if (candidates.empty())
270 rolledObjects.reserve(count);
273 if (!ExplicitlyChanced.empty())
278 if (candidate.chance > 0)
280 roll -= candidate.chance;
283 rolledObjects.push_back(candidate);
284 std::swap(candidate, candidates.back());
285 candidates.pop_back();
293 uint32 remainingCount = count - rolledObjects.size();
294 if (remainingCount > 0 && !candidates.empty())
296 if (candidates.size() > remainingCount)
299 rolledObjects.insert(rolledObjects.end(), candidates.begin(), candidates.end());
306 Spawn1Object(&objToSpawn);
319 Map* map =
sMapMgr->CreateBaseMap(data->mapId);
343 Map* map =
sMapMgr->CreateBaseMap(data->mapId);
375 Map* map =
sMapMgr->CreateBaseMap(data->mapId);
388 Map* map =
sMapMgr->CreateBaseMap(data->mapId);
426 TC_LOG_INFO(
"server.loading",
">> Loaded 0 object pools. DB table `pool_template` is empty.");
433 Field* fields = result->Fetch();
442 while (result->NextRow());
449 TC_LOG_INFO(
"server.loading",
"Loading Creatures Pooling Data...");
458 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creatures in pools. DB table `pool_creature` is empty.");
465 Field* fields = result->Fetch();
469 float chance = fields[2].
GetFloat();
474 TC_LOG_ERROR(
"sql.sql",
"`pool_creature` has a non existing creature spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
480 TC_LOG_ERROR(
"sql.sql",
"`pool_creature` pool id ({}) is not in `pool_template`, skipped.", pool_id);
483 if (chance < 0 || chance > 100)
485 TC_LOG_ERROR(
"sql.sql",
"`pool_creature` has an invalid chance ({}) for creature guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
498 while (result->NextRow());
506 TC_LOG_INFO(
"server.loading",
"Loading Gameobject Pooling Data...");
515 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobjects in pools. DB table `pool_gameobject` is empty.");
522 Field* fields = result->Fetch();
526 float chance = fields[2].
GetFloat();
531 TC_LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a non existing gameobject spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
541 TC_LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a not lootable gameobject spawn (GUID: {}, type: {}) defined for pool id ({}), skipped.", guid, goinfo->
type, pool_id);
548 TC_LOG_ERROR(
"sql.sql",
"`pool_gameobject` pool id ({}) is not in `pool_template`, skipped.", pool_id);
552 if (chance < 0 || chance > 100)
554 TC_LOG_ERROR(
"sql.sql",
"`pool_gameobject` has an invalid chance ({}) for gameobject guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
568 while (result->NextRow());
576 TC_LOG_INFO(
"server.loading",
"Loading Mother Pooling Data...");
585 TC_LOG_INFO(
"server.loading",
">> Loaded 0 pools in pools");
592 Field* fields = result->Fetch();
596 float chance = fields[2].
GetFloat();
602 TC_LOG_ERROR(
"sql.sql",
"`pool_pool` mother_pool id ({}) is not in `pool_template`, skipped.", mother_pool_id);
610 TC_LOG_ERROR(
"sql.sql",
"`pool_pool` included pool_id ({}) is not in `pool_template`, skipped.", child_pool_id);
614 if (mother_pool_id == child_pool_id)
616 TC_LOG_ERROR(
"sql.sql",
"`pool_pool` pool_id ({}) includes itself, dead-lock detected, skipped.", child_pool_id);
619 if (chance < 0 || chance > 100)
621 TC_LOG_ERROR(
"sql.sql",
"`pool_pool` has an invalid chance ({}) for pool id ({}) in mother pool id ({}), skipped.", chance, child_pool_id, mother_pool_id);
634 while (result->NextRow());
640 std::set<uint32> checkedPools;
643 checkedPools.insert(poolItr->first);
644 if (checkedPools.find(poolItr->second) != checkedPools.end())
646 std::ostringstream ss;
647 ss <<
"The pool(s) ";
648 for (std::set<uint32>::const_iterator itr = checkedPools.begin(); itr != checkedPools.end(); ++itr)
650 ss <<
"create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
651 << poolItr->first <<
" and child pool " << poolItr->second;
666 TC_LOG_INFO(
"server.loading",
"Starting objects pooling system...");
670 QueryResult result =
WorldDatabase.Query(
"SELECT DISTINCT pool_template.entry, pool_members.spawnId, pool_members.poolSpawnId FROM pool_template"
671 " LEFT JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry"
672 " LEFT JOIN pool_members ON pool_members.type = 2 AND pool_template.entry = pool_members.spawnId WHERE game_event_pool.pool_entry IS NULL");
676 TC_LOG_INFO(
"server.loading",
">> Pool handling system initialized, 0 pools spawned.");
683 Field* fields = result->Fetch();
692 TC_LOG_ERROR(
"sql.sql",
"Pool Id {} has no equal chance pooled entites defined and explicit chance sum is not 100. This broken pool is a child pool of Id {} and cannot be safely removed.", pool_entry, fields[2].GetUInt32());
694 TC_LOG_ERROR(
"sql.sql",
"Pool Id {} has no equal chance pooled entites defined and explicit chance sum is not 100. The pool will not be spawned.", pool_entry);
705 while (result->NextRow());
745 SpawnPool<Pool>(pool_id, 0);
746 SpawnPool<GameObject>(pool_id, 0);
747 SpawnPool<Creature>(pool_id, 0);
756 it->second.DespawnAllObjects(
mSpawnedData, alwaysDeleteRespawnTime);
761 it->second.DespawnAllObjects(
mSpawnedData, alwaysDeleteRespawnTime);
766 it->second.DespawnAllObjects(
mSpawnedData, alwaysDeleteRespawnTime);
776 return IsPartOfAPool<Creature>(spawnId);
778 return IsPartOfAPool<GameObject>(spawnId);
780 ABORT_MSG(
"Invalid spawn type %u passed to PoolMgr::IsPartOfPool (with spawnId %u)",
uint32(type), spawnId);
812 if (
uint32 motherpoolid = IsPartOfAPool<Pool>(pool_id))
813 SpawnPool<Pool>(motherpoolid, pool_id);
815 SpawnPool<T>(pool_id, db_guid_or_pool_id);
818template void PoolMgr::UpdatePool<Pool>(
uint32 pool_id,
uint32 db_guid_or_pool_id);
819template void PoolMgr::UpdatePool<GameObject>(
uint32 pool_id,
uint32 db_guid_or_pool_id);
820template void PoolMgr::UpdatePool<Creature>(
uint32 pool_id,
uint32 db_guid_or_pool_id);
827 UpdatePool<Creature>(pool_id, spawnId);
830 UpdatePool<GameObject>(pool_id, spawnId);
833 ABORT_MSG(
"Invalid spawn type %u passed to PoolMgr::IsPartOfPool (with spawnId %u)",
uint32(type), spawnId);
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
@ GAMEOBJECT_TYPE_FISHINGHOLE
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
bool IsActiveObject(uint32 db_guid_or_pool_id) const
void RemoveObject(uint32 db_guid_or_pool_id, uint32 pool_id)
uint32 GetActiveObjectCount(uint32 pool_id) const
ActivePoolObjects mSpawnedCreatures
ActivePoolPools mSpawnedPools
void ActivateObject(uint32 db_guid_or_pool_id, uint32 pool_id)
ActivePoolObjects mSpawnedGameobjects
bool LoadFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap, bool allowDuplicate)
bool GetRespawnCompatibilityMode()
void SaveRespawnTime(uint32 forceDelay=0)
Class used to access individual fields of database query result.
bool LoadFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap, bool=true)
bool isSpawnedByDefault() const
void SaveRespawnTime(uint32 forceDelay=0)
bool GetRespawnCompatibilityMode()
void RemoveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, CharacterDatabaseTransaction dbTrans=nullptr, bool alwaysDeleteFromDB=false)
GameObjectBySpawnIdContainer & GetGameObjectBySpawnIdStore()
bool Instanceable() const
bool IsGridLoaded(uint32 gridId) const
CreatureBySpawnIdContainer & GetCreatureBySpawnIdStore()
void SetPoolId(uint32 pool_id)
void SpawnObject(ActivePoolData &spawns, uint32 limit, uint32 triggerFrom)
void DespawnAllObjects(ActivePoolData &spawns, bool alwaysDeleteRespawnTime=false)
void RemoveOneRelation(uint32 child_pool_id)
void Spawn1Object(PoolObject *obj)
void AddEntry(PoolObject &poolitem, uint32 maxentries)
void DespawnObject(ActivePoolData &spawns, ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime=false)
void Despawn1Object(ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime=false, bool saveRespawnTime=true)
std::vector< PoolObject > PoolObjectList
void RemoveRespawnTimeFromDB(ObjectGuid::LowType guid)
std::pair< uint32, uint32 > SearchPair
bool CheckPool(uint32 pool_id) const
static PoolMgr * instance()
PoolGroupCreatureMap mPoolCreatureGroups
PoolGroupPoolMap mPoolPoolGroups
uint32 IsPartOfAPool(uint32 db_guid_or_pool_id) const
SearchMap mGameobjectSearchMap
PoolTemplateDataMap mPoolTemplate
void DespawnPool(uint32 pool_id, bool alwaysDeleteRespawnTime=false)
void SpawnPool(uint32 pool_id)
void UpdatePool(uint32 pool_id, uint32 db_guid_or_pool_id)
PoolGroupGameObjectMap mPoolGameobjectGroups
ActivePoolData mSpawnedData
SearchMap mCreatureSearchMap
void AddObjectToRemoveList()
void RandomResize(C &container, std::size_t requestedSize)