18 ActivePoolPools::const_iterator itr =
mSpawnedPools.find(pool_id);
121 if (poolitem.
chance != 0 && maxentries == 1)
136 if (chance != 100 && chance != 0)
209 sObjectMgr->RemoveCreatureFromGrid(guid, data);
212 creature->AddObjectToRemoveList();
222 sObjectMgr->RemoveGameobjectFromGrid(guid, data);
225 pGameobject->AddObjectToRemoveList();
233 sPoolMgr->DespawnPool(child_pool_id);
243 for (PooledQuestRelation::iterator itr = qr.first; itr != qr.second; ++itr)
245 QuestRelations::iterator qitr = questMap->find(itr->second);
246 if (qitr == questMap->end())
248 QuestRelations::iterator lastElement = questMap->upper_bound(itr->second);
249 for (; qitr != lastElement; ++qitr)
251 if (qitr->first == itr->second && qitr->second == itr->first)
253 questMap->erase(qitr);
260 questMap =
sObjectMgr->GetGOQuestRelationMap();
261 qr =
sPoolMgr->mQuestGORelation.equal_range(quest_id);
262 for (PooledQuestRelation::iterator itr = qr.first; itr != qr.second; ++itr)
264 QuestRelations::iterator qitr = questMap->find(itr->second);
265 if (qitr == questMap->end())
267 QuestRelations::iterator lastElement = questMap->upper_bound(itr->second);
268 for (; qitr != lastElement; ++qitr)
270 if (qitr->first == itr->second && qitr->second == itr->first)
272 questMap->erase(qitr);
285 if (itr->guid == child_pool_id)
293 if (itr->guid == child_pool_id)
314 for (
int i = 0; i < count; ++i)
319 if (obj->
guid == lastDespawned)
322 if (obj->
guid == triggerFrom)
335 lastDespawned = triggerFrom;
350 Map* map =
sMapMgr->CreateBaseMap(data->mapid);
374 Map* map =
sMapMgr->CreateBaseMap(data->mapid);
408 for (PooledQuestRelation::iterator itr = qr.first; itr != qr.second; ++itr)
410 SF_LOG_DEBUG(
"pool",
"PoolGroup<Quest>: Adding quest %u to creature %u", itr->first, itr->second);
411 questMap->insert(QuestRelations::value_type(itr->second, itr->first));
415 questMap =
sObjectMgr->GetGOQuestRelationMap();
417 for (PooledQuestRelation::iterator itr = qr.first; itr != qr.second; ++itr)
419 SF_LOG_DEBUG(
"pool",
"PoolGroup<Quest>: Adding quest %u to GO %u", itr->first, itr->second);
420 questMap->insert(QuestRelations::value_type(itr->second, itr->first));
441 uint32 questId = result->Fetch()[0].GetUInt32();
446 }
while (result->NextRow() && limit);
459 newQuests.insert(itr->guid);
466 if (limit > newQuests.size() && !currentQuests.empty())
471 newQuests.insert(questId);
472 currentQuests.erase(questId);
473 }
while (newQuests.size() < limit && !currentQuests.empty());
476 if (newQuests.empty())
486 newQuests.erase(questId);
488 }
while (limit && !newQuests.empty());
501 creature->GetMap()->AddToMap(creature);
510 pGameobject->GetMap()->AddToMap(pGameobject);
531 Field* fields = result->Fetch();
556 SF_LOG_INFO(
"server.loading",
">> Loaded 0 object pools. DB table `pool_template` is empty.");
563 Field* fields = result->Fetch();
571 }
while (result->NextRow());
578 SF_LOG_INFO(
"server.loading",
"Loading Creatures Pooling Data...");
587 SF_LOG_INFO(
"server.loading",
">> Loaded 0 creatures in pools. DB table `pool_creature` is empty.");
594 Field* fields = result->Fetch();
598 float chance = fields[2].
GetFloat();
603 SF_LOG_ERROR(
"sql.sql",
"`pool_creature` has a non existing creature spawn (GUID: %u) defined for pool id (%u), skipped.", guid, pool_id);
608 SF_LOG_ERROR(
"sql.sql",
"`pool_creature` pool id (%u) is out of range compared to max pool id in `pool_template`, skipped.", pool_id);
611 if (chance < 0 || chance > 100)
613 SF_LOG_ERROR(
"sql.sql",
"`pool_creature` has an invalid chance (%f) for creature guid (%u) in pool id (%u), skipped.", chance, guid, pool_id);
625 }
while (result->NextRow());
633 SF_LOG_INFO(
"server.loading",
"Loading Gameobject Pooling Data...");
642 SF_LOG_INFO(
"server.loading",
">> Loaded 0 gameobjects in pools. DB table `pool_gameobject` is empty.");
649 Field* fields = result->Fetch();
653 float chance = fields[2].
GetFloat();
658 SF_LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a non existing gameobject spawn (GUID: %u) defined for pool id (%u), skipped.", guid, pool_id);
667 SF_LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a not lootable gameobject spawn (GUID: %u, type: %u) defined for pool id (%u), skipped.", guid, goinfo->
type, pool_id);
673 SF_LOG_ERROR(
"sql.sql",
"`pool_gameobject` pool id (%u) is out of range compared to max pool id in `pool_template`, skipped.", pool_id);
677 if (chance < 0 || chance > 100)
679 SF_LOG_ERROR(
"sql.sql",
"`pool_gameobject` has an invalid chance (%f) for gameobject guid (%u) in pool id (%u), skipped.", chance, guid, pool_id);
692 }
while (result->NextRow());
700 SF_LOG_INFO(
"server.loading",
"Loading Mother Pooling Data...");
709 SF_LOG_INFO(
"server.loading",
">> Loaded 0 pools in pools");
716 Field* fields = result->Fetch();
720 float chance = fields[2].
GetFloat();
724 SF_LOG_ERROR(
"sql.sql",
"`pool_pool` mother_pool id (%u) is out of range compared to max pool id in `pool_template`, skipped.", mother_pool_id);
729 SF_LOG_ERROR(
"sql.sql",
"`pool_pool` included pool_id (%u) is out of range compared to max pool id in `pool_template`, skipped.", child_pool_id);
732 if (mother_pool_id == child_pool_id)
734 SF_LOG_ERROR(
"sql.sql",
"`pool_pool` pool_id (%u) includes itself, dead-lock detected, skipped.", child_pool_id);
737 if (chance < 0 || chance > 100)
739 SF_LOG_ERROR(
"sql.sql",
"`pool_pool` has an invalid chance (%f) for pool id (%u) in mother pool id (%u), skipped.", chance, child_pool_id, mother_pool_id);
751 }
while (result->NextRow());
756 std::set<uint32> checkedPools;
759 checkedPools.insert(poolItr->first);
760 if (checkedPools.find(poolItr->second) != checkedPools.end())
762 std::ostringstream ss;
763 ss <<
"The pool(s) ";
764 for (std::set<uint32>::const_iterator itr = checkedPools.begin(); itr != checkedPools.end(); ++itr)
766 ss <<
"create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
767 << poolItr->first <<
" and child pool " << poolItr->second;
781 SF_LOG_INFO(
"server.loading",
"Loading Quest Pooling Data...");
790 SF_LOG_INFO(
"server.loading",
">> Loaded 0 quests in pools");
804 std::map<uint32, int32> poolTypeMap;
808 Field* fields = result->Fetch();
816 SF_LOG_ERROR(
"sql.sql",
"`pool_quest` has a non existing quest template (Entry: %u) defined for pool id (%u), skipped.", entry, pool_id);
822 SF_LOG_ERROR(
"sql.sql",
"`pool_quest` pool id (%u) is out of range compared to max pool id in `pool_template`, skipped.", pool_id);
828 SF_LOG_ERROR(
"sql.sql",
"`pool_quest` has an quest (%u) which is not daily or weekly in pool id (%u), use ExclusiveGroup instead, skipped.", entry, pool_id);
832 if (poolTypeMap[pool_id] == QUEST_NONE)
833 poolTypeMap[pool_id] = quest->
IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
835 int32 currType = quest->
IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
837 if (poolTypeMap[pool_id] != currType)
839 SF_LOG_ERROR(
"sql.sql",
"`pool_quest` quest %u is %s but pool (%u) is specified for %s, mixing not allowed, skipped.",
840 entry, currType == QUEST_DAILY ?
"QUEST_DAILY" :
"QUEST_WEEKLY", pool_id, poolTypeMap[pool_id] == QUEST_DAILY ?
"QUEST_DAILY" :
"QUEST_WEEKLY");
847 if (creBounds.first == creBounds.second && goBounds.first == goBounds.second)
849 SF_LOG_ERROR(
"sql.sql",
"`pool_quest` lists entry (%u) as member of pool (%u) but is not started anywhere, skipped.", entry, pool_id);
862 }
while (result->NextRow());
869 SF_LOG_INFO(
"server.loading",
"Starting objects pooling system...");
873 QueryResult result =
WorldDatabase.Query(
"SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template"
874 " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry"
875 " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL");
879 SF_LOG_INFO(
"server.loading",
">> Pool handling system initialized, 0 pools spawned.");
886 Field* fields = result->Fetch();
895 SF_LOG_ERROR(
"sql.sql",
"Pool Id %u has no equal chance pooled entites defined and explicit chance sum is not 100. This broken pool is a child pool of Id %u and cannot be safely removed.", pool_entry, fields[2].GetUInt32());
897 SF_LOG_ERROR(
"sql.sql",
"Pool Id %u has no equal chance pooled entites defined and explicit chance sum is not 100. The pool will not be spawned.", pool_entry);
907 }
while (result->NextRow());
947 if (
Quest const* quest =
sObjectMgr->GetQuestTemplate(itr->GetFirstEqualChancedObjectId()))
949 if (quest->IsWeekly())
963 if (
Quest const* quest =
sObjectMgr->GetQuestTemplate(itr->GetFirstEqualChancedObjectId()))
965 if (quest->IsDaily())
@ CHAR_DEL_QUEST_POOL_SAVE
@ CHAR_SEL_POOL_QUEST_SAVE
@ CHAR_INS_QUEST_POOL_SAVE
#define SF_LOG_DEBUG(filterType__,...)
#define SF_LOG_ERROR(filterType__,...)
#define SF_LOG_INFO(filterType__,...)
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
std::multimap< uint32, uint32 > QuestRelations
std::pair< PooledQuestRelation::iterator, PooledQuestRelation::iterator > PooledQuestRelationBoundsNC
std::set< uint32 > ActivePoolObjects
std::pair< PooledQuestRelation::const_iterator, PooledQuestRelation::const_iterator > PooledQuestRelationBounds
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Skyfire::AutoPtr< ResultSet, Skyfire::Mutex > QueryResult
@ GAMEOBJECT_TYPE_FISHINGHOLE
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
ActivePoolObjects mActiveQuests
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
ActivePoolObjects GetActiveQuests() const
bool LoadCreatureFromDB(uint32 guid, Map *map, bool addToMap=true)
bool isSpawnedByDefault() const
bool LoadGameObjectFromDB(uint32 guid, Map *map, bool addToMap=true)
bool Instanceable() const
bool IsGridLoaded(float x, float y) const
static T * GetObjectInWorld(uint64 guid, T *)
void SetPoolId(uint32 pool_id)
void SpawnObject(ActivePoolData &spawns, uint32 limit, uint32 triggerFrom)
void ReSpawn1Object(PoolObject *obj)
void Despawn1Object(uint32 guid)
void RemoveOneRelation(uint32 child_pool_id)
PoolObjectList ExplicitlyChanced
void Spawn1Object(PoolObject *obj)
void AddEntry(PoolObject &poolitem, uint32 maxentries)
void DespawnObject(ActivePoolData &spawns, uint32 guid=0)
PoolObjectList EqualChanced
PoolObject * RollOne(ActivePoolData &spawns, uint32 triggerFrom)
std::pair< uint32, uint32 > SearchPair
bool CheckPool(uint32 pool_id) const
void ChangeWeeklyQuests()
PoolGroupCreatureMap mPoolCreatureGroups
PoolGroupPoolMap mPoolPoolGroups
uint32 IsPartOfAPool(uint32 db_guid_or_pool_id) const
SearchMap mGameobjectSearchMap
PoolTemplateDataMap mPoolTemplate
void SpawnPool(uint32 pool_id)
void UpdatePool(uint32 pool_id, uint32 db_guid_or_pool_id)
PoolGroupGameObjectMap mPoolGameobjectGroups
ActivePoolData mSpawnedData
SearchMap mQuestSearchMap
void DespawnPool(uint32 pool_id)
PooledQuestRelation mQuestGORelation
PooledQuestRelation mQuestCreatureRelation
PoolGroupQuestMap mPoolQuestGroups
bool IsSpawnedObject(uint32 db_guid_or_pool_id) const
SearchMap mCreatureSearchMap
void setUInt32(const uint8 index, const uint32 value)
bool IsDailyOrWeekly() const
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
C::value_type const & SelectRandomContainerElement(C const &container)