AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
PoolMgr Class Reference

#include "PoolMgr.h"

Public Member Functions

void LoadFromDB ()
 
void LoadQuestPools ()
 
void SaveQuestsToDB (bool daily, bool weekly, bool other)
 
void Initialize ()
 
template<typename T >
uint32 IsPartOfAPool (uint32 db_guid_or_pool_id) const
 
template<typename T >
bool IsSpawnedObject (uint32 db_guid_or_pool_id) const
 
bool CheckPool (uint32 pool_id) const
 
void SpawnPool (uint32 pool_id)
 
void DespawnPool (uint32 pool_id)
 
template<typename T >
void UpdatePool (uint32 pool_id, uint32 db_guid_or_pool_id)
 
void ChangeDailyQuests ()
 
void ChangeWeeklyQuests ()
 
void ReSpawnPoolQuests ()
 
PoolTemplateData const * GetPoolTemplate (uint32 poolId) const
 
PoolGroup< Creature > const * GetPoolCreatureGroup (uint32 poolId) const
 
PoolGroup< GameObject > const * GetPoolGameObjectGroup (uint32 poolId) const
 
PoolGroup< Pool > const * GetPoolPoolGroup (uint32 poolId) const
 
ActivePoolData const & GetSpawnedData () const
 
uint32 GetCreaturePoolId (uint32 guid) const
 
uint32 GetGameObjectPoolId (uint32 guid) const
 
template<>
uint32 IsPartOfAPool (uint32 db_guid) const
 
template<>
uint32 IsPartOfAPool (uint32 db_guid) const
 
template<>
uint32 IsPartOfAPool (uint32 questId) const
 
template<>
uint32 IsPartOfAPool (uint32 pool_id) const
 

Static Public Member Functions

static PoolMgrinstance ()
 

Public Attributes

PooledQuestRelation mQuestCreatureRelation
 
PooledQuestRelation mQuestGORelation
 

Private Types

typedef std::unordered_map< uint32, PoolTemplateDataPoolTemplateDataMap
 
typedef std::unordered_map< uint32, PoolGroup< Creature > > PoolGroupCreatureMap
 
typedef std::unordered_map< uint32, PoolGroup< GameObject > > PoolGroupGameObjectMap
 
typedef std::unordered_map< uint32, PoolGroup< Pool > > PoolGroupPoolMap
 
typedef std::unordered_map< uint32, PoolGroup< Quest > > PoolGroupQuestMap
 
typedef std::pair< uint32, uint32SearchPair
 
typedef std::map< uint32, uint32SearchMap
 

Private Member Functions

 PoolMgr ()
 
 ~PoolMgr ()
 
template<typename T >
void SpawnPool (uint32 pool_id, uint32 db_guid_or_pool_id)
 
template<>
void SpawnPool (uint32 pool_id, uint32 db_guid)
 
template<>
void SpawnPool (uint32 pool_id, uint32 db_guid)
 
template<>
void SpawnPool (uint32 pool_id, uint32 sub_pool_id)
 
template<>
void SpawnPool (uint32 pool_id, uint32 quest_id)
 

Private Attributes

PoolTemplateDataMap mPoolTemplate
 
PoolGroupCreatureMap mPoolCreatureGroups
 
PoolGroupGameObjectMap mPoolGameobjectGroups
 
PoolGroupPoolMap mPoolPoolGroups
 
PoolGroupQuestMap mPoolQuestGroups
 
SearchMap mCreatureSearchMap
 
SearchMap mGameobjectSearchMap
 
SearchMap mPoolSearchMap
 
SearchMap mQuestSearchMap
 
ActivePoolData mSpawnedData
 

Friends

class PoolQuestReloadFixTest
 

Detailed Description

Member Typedef Documentation

◆ PoolGroupCreatureMap

typedef std::unordered_map<uint32, PoolGroup<Creature> > PoolMgr::PoolGroupCreatureMap
private

◆ PoolGroupGameObjectMap

typedef std::unordered_map<uint32, PoolGroup<GameObject> > PoolMgr::PoolGroupGameObjectMap
private

◆ PoolGroupPoolMap

typedef std::unordered_map<uint32, PoolGroup<Pool> > PoolMgr::PoolGroupPoolMap
private

◆ PoolGroupQuestMap

typedef std::unordered_map<uint32, PoolGroup<Quest> > PoolMgr::PoolGroupQuestMap
private

◆ PoolTemplateDataMap

typedef std::unordered_map<uint32, PoolTemplateData> PoolMgr::PoolTemplateDataMap
private

◆ SearchMap

typedef std::map<uint32, uint32> PoolMgr::SearchMap
private

◆ SearchPair

typedef std::pair<uint32, uint32> PoolMgr::SearchPair
private

Constructor & Destructor Documentation

◆ PoolMgr()

PoolMgr::PoolMgr ( )
private
561{
562}

◆ ~PoolMgr()

PoolMgr::~PoolMgr ( )
inlineprivate
109{};

Member Function Documentation

◆ ChangeDailyQuests()

void PoolMgr::ChangeDailyQuests ( )
1011{
1012 for (PoolGroupQuestMap::iterator itr = mPoolQuestGroups.begin(); itr != mPoolQuestGroups.end(); ++itr)
1013 {
1014 if (Quest const* quest = sObjectMgr->GetQuestTemplate(itr->second.GetFirstEqualChancedObjectId()))
1015 {
1016 if (quest->IsWeekly())
1017 continue;
1018
1019 UpdatePool<Quest>(itr->second.GetPoolId(), 1); // anything non-zero means don't load from db
1020 }
1021 }
1022
1023 SaveQuestsToDB(true, false, false);
1024}
#define sObjectMgr
Definition ObjectMgr.h:1723
void SaveQuestsToDB(bool daily, bool weekly, bool other)
Definition PoolMgr.cpp:972
PoolGroupQuestMap mPoolQuestGroups
Definition PoolMgr.h:167
Definition QuestDef.h:210

References mPoolQuestGroups, SaveQuestsToDB(), and sObjectMgr.

◆ ChangeWeeklyQuests()

void PoolMgr::ChangeWeeklyQuests ( )
1027{
1028 for (PoolGroupQuestMap::iterator itr = mPoolQuestGroups.begin(); itr != mPoolQuestGroups.end(); ++itr)
1029 {
1030 if (Quest const* quest = sObjectMgr->GetQuestTemplate(itr->second.GetFirstEqualChancedObjectId()))
1031 {
1032 if (quest->IsDaily())
1033 continue;
1034
1035 UpdatePool<Quest>(itr->second.GetPoolId(), 1);
1036 }
1037 }
1038
1039 SaveQuestsToDB(false, true, false);
1040}

References mPoolQuestGroups, SaveQuestsToDB(), and sObjectMgr.

◆ CheckPool()

bool PoolMgr::CheckPool ( uint32  pool_id) const
1130{
1131 {
1132 auto it = mPoolGameobjectGroups.find(pool_id);
1133 if (it != mPoolGameobjectGroups.end() && !it->second.CheckPool())
1134 return false;
1135 }
1136 {
1137 auto it = mPoolCreatureGroups.find(pool_id);
1138 if (it != mPoolCreatureGroups.end() && !it->second.CheckPool())
1139 return false;
1140 }
1141 {
1142 auto it = mPoolPoolGroups.find(pool_id);
1143 if (it != mPoolPoolGroups.end() && !it->second.CheckPool())
1144 return false;
1145 }
1146 {
1147 auto it = mPoolQuestGroups.find(pool_id);
1148 if (it != mPoolQuestGroups.end() && !it->second.CheckPool())
1149 return false;
1150 }
1151 return true;
1152}
PoolGroupCreatureMap mPoolCreatureGroups
Definition PoolMgr.h:164
PoolGroupPoolMap mPoolPoolGroups
Definition PoolMgr.h:166
PoolGroupGameObjectMap mPoolGameobjectGroups
Definition PoolMgr.h:165

References mPoolCreatureGroups, mPoolGameobjectGroups, mPoolPoolGroups, and mPoolQuestGroups.

Referenced by LoadFromDB().

◆ DespawnPool()

void PoolMgr::DespawnPool ( uint32  pool_id)
1105{
1106 {
1107 auto it = mPoolCreatureGroups.find(pool_id);
1108 if (it != mPoolCreatureGroups.end() && !it->second.IsEmpty())
1109 it->second.DespawnObject(mSpawnedData);
1110 }
1111 {
1112 auto it = mPoolGameobjectGroups.find(pool_id);
1113 if (it != mPoolGameobjectGroups.end() && !it->second.IsEmpty())
1114 it->second.DespawnObject(mSpawnedData);
1115 }
1116 {
1117 auto it = mPoolPoolGroups.find(pool_id);
1118 if (it != mPoolPoolGroups.end() && !it->second.IsEmpty())
1119 it->second.DespawnObject(mSpawnedData);
1120 }
1121 {
1122 auto it = mPoolQuestGroups.find(pool_id);
1123 if (it != mPoolQuestGroups.end() && !it->second.IsEmpty())
1124 it->second.DespawnObject(mSpawnedData);
1125 }
1126}
ActivePoolData mSpawnedData
Definition PoolMgr.h:174

References mPoolCreatureGroups, mPoolGameobjectGroups, mPoolPoolGroups, mPoolQuestGroups, and mSpawnedData.

◆ GetCreaturePoolId()

uint32 PoolMgr::GetCreaturePoolId ( uint32  guid) const
1196{
1197 SearchMap::const_iterator itr = mCreatureSearchMap.find(guid);
1198 return itr != mCreatureSearchMap.end() ? itr->second : 0;
1199}
SearchMap mCreatureSearchMap
Definition PoolMgr.h:168

References mCreatureSearchMap.

◆ GetGameObjectPoolId()

uint32 PoolMgr::GetGameObjectPoolId ( uint32  guid) const
1202{
1203 SearchMap::const_iterator itr = mGameobjectSearchMap.find(guid);
1204 return itr != mGameobjectSearchMap.end() ? itr->second : 0;
1205}
SearchMap mGameobjectSearchMap
Definition PoolMgr.h:169

References mGameobjectSearchMap.

◆ GetPoolCreatureGroup()

PoolGroup< Creature > const * PoolMgr::GetPoolCreatureGroup ( uint32  poolId) const
1178{
1179 auto itr = mPoolCreatureGroups.find(poolId);
1180 return itr != mPoolCreatureGroups.end() ? &itr->second : nullptr;
1181}

References mPoolCreatureGroups.

◆ GetPoolGameObjectGroup()

PoolGroup< GameObject > const * PoolMgr::GetPoolGameObjectGroup ( uint32  poolId) const
1184{
1185 auto itr = mPoolGameobjectGroups.find(poolId);
1186 return itr != mPoolGameobjectGroups.end() ? &itr->second : nullptr;
1187}

References mPoolGameobjectGroups.

◆ GetPoolPoolGroup()

PoolGroup< Pool > const * PoolMgr::GetPoolPoolGroup ( uint32  poolId) const
1190{
1191 auto itr = mPoolPoolGroups.find(poolId);
1192 return itr != mPoolPoolGroups.end() ? &itr->second : nullptr;
1193}

References mPoolPoolGroups.

◆ GetPoolTemplate()

PoolTemplateData const * PoolMgr::GetPoolTemplate ( uint32  poolId) const
1172{
1173 auto itr = mPoolTemplate.find(poolId);
1174 return itr != mPoolTemplate.end() ? &itr->second : nullptr;
1175}
PoolTemplateDataMap mPoolTemplate
Definition PoolMgr.h:163

References mPoolTemplate.

◆ GetSpawnedData()

ActivePoolData const & PoolMgr::GetSpawnedData ( ) const
inline
146{ return mSpawnedData; }

References mSpawnedData.

◆ Initialize()

void PoolMgr::Initialize ( )
571{
572 mQuestSearchMap.clear();
573 mGameobjectSearchMap.clear();
574 mCreatureSearchMap.clear();
575}
SearchMap mQuestSearchMap
Definition PoolMgr.h:171

References mCreatureSearchMap, mGameobjectSearchMap, and mQuestSearchMap.

◆ instance()

PoolMgr * PoolMgr::instance ( )
static
565{
566 static PoolMgr instance;
567 return &instance;
568}
Definition PoolMgr.h:106
static PoolMgr * instance()
Definition PoolMgr.cpp:564

References instance().

Referenced by instance().

◆ IsPartOfAPool() [1/5]

template<>
uint32 PoolMgr::IsPartOfAPool ( uint32  db_guid) const
inline
182{
183 SearchMap::const_iterator itr = mCreatureSearchMap.find(db_guid);
184 if (itr != mCreatureSearchMap.end())
185 return itr->second;
186
187 return 0;
188}

References mCreatureSearchMap.

◆ IsPartOfAPool() [2/5]

template<>
uint32 PoolMgr::IsPartOfAPool ( uint32  db_guid) const
inline
193{
194 SearchMap::const_iterator itr = mGameobjectSearchMap.find(db_guid);
195 if (itr != mGameobjectSearchMap.end())
196 return itr->second;
197
198 return 0;
199}

References mGameobjectSearchMap.

◆ IsPartOfAPool() [3/5]

template<typename T >
uint32 PoolMgr::IsPartOfAPool ( uint32  db_guid_or_pool_id) const

◆ IsPartOfAPool() [4/5]

template<>
uint32 PoolMgr::IsPartOfAPool ( uint32  pool_id) const
inline
215{
216 SearchMap::const_iterator itr = mPoolSearchMap.find(pool_id);
217 if (itr != mPoolSearchMap.end())
218 return itr->second;
219
220 return 0;
221}
SearchMap mPoolSearchMap
Definition PoolMgr.h:170

References mPoolSearchMap.

◆ IsPartOfAPool() [5/5]

template<>
uint32 PoolMgr::IsPartOfAPool ( uint32  questId) const
inline
204{
205 SearchMap::const_iterator itr = mQuestSearchMap.find(questId);
206 if (itr != mQuestSearchMap.end())
207 return itr->second;
208
209 return 0;
210}

References mQuestSearchMap.

◆ IsSpawnedObject()

template<typename T >
bool PoolMgr::IsSpawnedObject ( uint32  db_guid_or_pool_id) const
inline
124{ return mSpawnedData.IsActiveObject<T>(db_guid_or_pool_id); }
bool IsActiveObject(uint32 db_guid_or_pool_id) const

References ActivePoolData::IsActiveObject(), and mSpawnedData.

◆ LoadFromDB()

void PoolMgr::LoadFromDB ( )
578{
579 // Pool templates
580 {
581 uint32 oldMSTime = getMSTime();
582
583 QueryResult result = WorldDatabase.Query("SELECT entry, max_limit, description FROM pool_template");
584 if (!result)
585 {
586 mPoolTemplate.clear();
587 LOG_WARN("server.loading", ">> Loaded 0 object pools. DB table `pool_template` is empty.");
588 LOG_INFO("server.loading", " ");
589 return;
590 }
591
592 uint32 count = 0;
593 do
594 {
595 Field* fields = result->Fetch();
596
597 uint32 pool_id = fields[0].Get<uint32>();
598
599 PoolTemplateData& pPoolTemplate = mPoolTemplate[pool_id];
600 pPoolTemplate.MaxLimit = fields[1].Get<uint32>();
601 pPoolTemplate.Description = fields[2].Get<std::string>();
602
603 ++count;
604 } while (result->NextRow());
605
606 LOG_INFO("server.loading", ">> Loaded {} Objects Pools In {} ms", count, GetMSTimeDiffToNow(oldMSTime));
607 LOG_INFO("server.loading", " ");
608 }
609
610 // Creatures
611
612 LOG_INFO("server.loading", "Loading Creatures Pooling Data...");
613 {
614 uint32 oldMSTime = getMSTime();
615
616 // 1 2 3
617 QueryResult result = WorldDatabase.Query("SELECT guid, pool_entry, chance FROM pool_creature");
618
619 if (!result)
620 {
621 LOG_WARN("server.loading", ">> Loaded 0 creatures in pools. DB table `pool_creature` is empty.");
622 LOG_INFO("server.loading", " ");
623 }
624 else
625 {
626 uint32 count = 0;
627 do
628 {
629 Field* fields = result->Fetch();
630
631 ObjectGuid::LowType guid = fields[0].Get<uint32>();
632 uint32 pool_id = fields[1].Get<uint32>();
633 float chance = fields[2].Get<float>();
634
635 CreatureData const* data = sObjectMgr->GetCreatureData(guid);
636 if (!data)
637 {
638 LOG_ERROR("sql.sql", "`pool_creature` has a non existing creature spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
639 continue;
640 }
641 auto it = mPoolTemplate.find(pool_id);
642 if (it == mPoolTemplate.end())
643 {
644 LOG_ERROR("sql.sql", "`pool_creature` pool id ({}) is not in `pool_template`, skipped.", pool_id);
645 continue;
646 }
647 if (chance < 0 || chance > 100)
648 {
649 LOG_ERROR("sql.sql", "`pool_creature` has an invalid chance ({}) for creature guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
650 continue;
651 }
652 PoolTemplateData* pPoolTemplate = &mPoolTemplate[pool_id];
653 PoolObject plObject = PoolObject(guid, chance);
654 PoolGroup<Creature>& cregroup = mPoolCreatureGroups[pool_id];
655 cregroup.SetPoolId(pool_id);
656 cregroup.AddEntry(plObject, pPoolTemplate->MaxLimit);
657 SearchPair p(guid, pool_id);
658 mCreatureSearchMap.insert(p);
659
660 ++count;
661 } while (result->NextRow());
662
663 LOG_INFO("server.loading", ">> Loaded {} Creatures In Pools in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
664 LOG_INFO("server.loading", " ");
665 }
666 }
667
668 // Gameobjects
669
670 LOG_INFO("server.loading", "Loading Gameobjects Pooling Data...");
671 {
672 uint32 oldMSTime = getMSTime();
673
674 // 1 2 3
675 QueryResult result = WorldDatabase.Query("SELECT guid, pool_entry, chance FROM pool_gameobject");
676
677 if (!result)
678 {
679 LOG_WARN("server.loading", ">> Loaded 0 gameobjects in pools. DB table `pool_gameobject` is empty.");
680 LOG_INFO("server.loading", " ");
681 }
682 else
683 {
684 uint32 count = 0;
685 do
686 {
687 Field* fields = result->Fetch();
688
689 ObjectGuid::LowType guid = fields[0].Get<uint32>();
690 uint32 pool_id = fields[1].Get<uint32>();
691 float chance = fields[2].Get<float>();
692
693 GameObjectData const* data = sObjectMgr->GetGameObjectData(guid);
694 if (!data)
695 {
696 LOG_ERROR("sql.sql", "`pool_gameobject` has a non existing gameobject spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
697 continue;
698 }
699
700 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(data->id);
701 if (goinfo->type != GAMEOBJECT_TYPE_CHEST &&
702 goinfo->type != GAMEOBJECT_TYPE_GOOBER &&
704 {
705 LOG_ERROR("sql.sql", "`pool_gameobject` has a not lootable gameobject spawn (GUID: {}, type: {}) defined for pool id ({}), skipped.", guid, goinfo->type, pool_id);
706 continue;
707 }
708
709 auto it = mPoolTemplate.find(pool_id);
710 if (it == mPoolTemplate.end())
711 {
712 LOG_ERROR("sql.sql", "`pool_gameobject` pool id ({}) is not in `pool_template`, skipped.", pool_id);
713 continue;
714 }
715
716 if (chance < 0 || chance > 100)
717 {
718 LOG_ERROR("sql.sql", "`pool_gameobject` has an invalid chance ({}) for gameobject guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
719 continue;
720 }
721
722 PoolTemplateData* pPoolTemplate = &mPoolTemplate[pool_id];
723 PoolObject plObject = PoolObject(guid, chance);
725 gogroup.SetPoolId(pool_id);
726 gogroup.AddEntry(plObject, pPoolTemplate->MaxLimit);
727 SearchPair p(guid, pool_id);
728 mGameobjectSearchMap.insert(p);
729
730 ++count;
731 } while (result->NextRow());
732
733 LOG_INFO("server.loading", ">> Loaded {} Gameobjects In Pools in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
734 LOG_INFO("server.loading", " ");
735 }
736 }
737
738 // Pool of pools
739
740 LOG_INFO("server.loading", "Loading Mother Pooling Data...");
741 {
742 uint32 oldMSTime = getMSTime();
743
744 // 1 2 3
745 QueryResult result = WorldDatabase.Query("SELECT pool_id, mother_pool, chance FROM pool_pool");
746
747 if (!result)
748 {
749 LOG_WARN("server.loading", ">> Loaded 0 pools in pools");
750 LOG_INFO("server.loading", " ");
751 }
752 else
753 {
754 uint32 count = 0;
755 do
756 {
757 Field* fields = result->Fetch();
758
759 uint32 child_pool_id = fields[0].Get<uint32>();
760 uint32 mother_pool_id = fields[1].Get<uint32>();
761 float chance = fields[2].Get<float>();
762
763 {
764 auto it = mPoolTemplate.find(mother_pool_id);
765 if (it == mPoolTemplate.end())
766 {
767 LOG_ERROR("sql.sql", "`pool_pool` mother_pool id ({}) is not in `pool_template`, skipped.", mother_pool_id);
768 continue;
769 }
770 }
771 {
772 auto it = mPoolTemplate.find(child_pool_id);
773 if (it == mPoolTemplate.end())
774 {
775 LOG_ERROR("sql.sql", "`pool_pool` included pool_id ({}) is not in `pool_template`, skipped.", child_pool_id);
776 continue;
777 }
778 }
779 if (mother_pool_id == child_pool_id)
780 {
781 LOG_ERROR("sql.sql", "`pool_pool` pool_id ({}) includes itself, dead-lock detected, skipped.", child_pool_id);
782 continue;
783 }
784 if (chance < 0 || chance > 100)
785 {
786 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);
787 continue;
788 }
789 PoolTemplateData* pPoolTemplateMother = &mPoolTemplate[mother_pool_id];
790 PoolObject plObject = PoolObject(child_pool_id, chance);
791 PoolGroup<Pool>& plgroup = mPoolPoolGroups[mother_pool_id];
792 plgroup.SetPoolId(mother_pool_id);
793 plgroup.AddEntry(plObject, pPoolTemplateMother->MaxLimit);
794 SearchPair p(child_pool_id, mother_pool_id);
795 mPoolSearchMap.insert(p);
796
797 ++count;
798 } while (result->NextRow());
799
800 // Now check for circular reference
801 // All pool_ids are in pool_template
802 for (auto const& it : mPoolTemplate)
803 {
804 std::set<uint32> checkedPools;
805 for (SearchMap::iterator poolItr = mPoolSearchMap.find(it.first); poolItr != mPoolSearchMap.end(); poolItr = mPoolSearchMap.find(poolItr->second))
806 {
807 checkedPools.insert(poolItr->first);
808 if (checkedPools.find(poolItr->second) != checkedPools.end())
809 {
810 std::ostringstream ss;
811 ss << "The pool(s) ";
812 for (std::set<uint32>::const_iterator itr = checkedPools.begin(); itr != checkedPools.end(); ++itr)
813 ss << *itr << ' ';
814 ss << "create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
815 << poolItr->first << " and child pool " << poolItr->second;
816 LOG_ERROR("sql.sql", "{}", ss.str());
817 mPoolPoolGroups[poolItr->second].RemoveOneRelation(poolItr->first);
818 mPoolSearchMap.erase(poolItr);
819 --count;
820 break;
821 }
822 }
823 }
824
825 LOG_INFO("server.loading", ">> Loaded {} Pools In Mother Pools in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
826 LOG_INFO("server.loading", " ");
827 }
828 }
829
830 LOG_INFO("server.loading", "Loading Quest Pooling Data...");
831 {
832 uint32 oldMSTime = getMSTime();
833
835 PreparedQueryResult result = WorldDatabase.Query(stmt);
836
837 if (!result)
838 {
839 LOG_WARN("server.loading", ">> Loaded 0 quests in pools");
840 LOG_INFO("server.loading", " ");
841 }
842 else
843 {
846
847 enum eQuestTypes
848 {
849 QUEST_NONE = 0,
850 QUEST_DAILY = 1,
851 QUEST_WEEKLY = 2
852 };
853
854 std::map<uint32, int32> poolTypeMap;
855 uint32 count = 0;
856 do
857 {
858 Field* fields = result->Fetch();
859
860 uint32 entry = fields[0].Get<uint32>();
861 uint32 pool_id = fields[1].Get<uint32>();
862
863 Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
864 if (!quest)
865 {
866 LOG_ERROR("sql.sql", "`pool_quest` has a non existing quest template (Entry: {}) defined for pool id ({}), skipped.", entry, pool_id);
867 continue;
868 }
869
870 auto it = mPoolTemplate.find(pool_id);
871 if (it == mPoolTemplate.end())
872 {
873 LOG_ERROR("sql.sql", "`pool_quest` pool id ({}) is not in `pool_template`, skipped.", pool_id);
874 continue;
875 }
876
877 if (!quest->IsDailyOrWeekly())
878 {
879 LOG_ERROR("sql.sql", "`pool_quest` has an quest ({}) which is not daily or weekly in pool id ({}), use ExclusiveGroup instead, skipped.", entry, pool_id);
880 continue;
881 }
882
883 if (poolTypeMap[pool_id] == QUEST_NONE)
884 poolTypeMap[pool_id] = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
885
886 int32 currType = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
887
888 if (poolTypeMap[pool_id] != currType)
889 {
890 LOG_ERROR("sql.sql", "`pool_quest` quest {} is {} but pool ({}) is specified for {}, mixing not allowed, skipped.",
891 entry, currType == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY", pool_id, poolTypeMap[pool_id] == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY");
892 continue;
893 }
894
895 creBounds = mQuestCreatureRelation.equal_range(entry);
896 goBounds = mQuestGORelation.equal_range(entry);
897
898 if (creBounds.first == creBounds.second && goBounds.first == goBounds.second)
899 {
900 LOG_ERROR("sql.sql", "`pool_quest` lists entry ({}) as member of pool ({}) but is not started anywhere, skipped.", entry, pool_id);
901 continue;
902 }
903
904 PoolTemplateData* pPoolTemplate = &mPoolTemplate[pool_id];
905 PoolObject plObject = PoolObject(entry, 0.0f);
906 PoolGroup<Quest>& questgroup = mPoolQuestGroups[pool_id];
907 questgroup.SetPoolId(pool_id);
908 questgroup.AddEntry(plObject, pPoolTemplate->MaxLimit);
909 SearchPair p(entry, pool_id);
910 mQuestSearchMap.insert(p);
911
912 ++count;
913 } while (result->NextRow());
914
915 LOG_INFO("server.loading", ">> Loaded {} Quests In Pools in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
916 LOG_INFO("server.loading", " ");
917 }
918 }
919
920 // The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks
921 LOG_INFO("server.loading", "Starting Objects Pooling System...");
922 {
923 uint32 oldMSTime = getMSTime();
924
925 QueryResult result = WorldDatabase.Query("SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template"
926 " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry"
927 " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL");
928
929 if (!result)
930 {
931 LOG_INFO("server.loading", ">> Pool handling system initialized, 0 pools spawned.");
932 LOG_INFO("server.loading", " ");
933 }
934 else
935 {
936 uint32 count = 0;
937 do
938 {
939 Field* fields = result->Fetch();
940 uint32 pool_entry = fields[0].Get<uint32>();
941 uint32 pool_pool_id = fields[1].Get<uint32>();
942
943 if (!CheckPool(pool_entry))
944 {
945 if (pool_pool_id)
946 // The pool is a child pool in pool_pool table. Ideally we should remove it from the pool handler to ensure it never gets spawned,
947 // however that could recursively invalidate entire chain of mother pools. It can be done in the future but for now we'll do nothing.
948 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].Get<uint32>());
949 else
950 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);
951 continue;
952 }
953
954 // Don't spawn child pools, they are spawned recursively by their parent pools
955 if (!pool_pool_id)
956 {
957 SpawnPool(pool_entry);
958 count++;
959 }
960 } while (result->NextRow());
961
962 LOG_INFO("pool", "Pool handling system initialized, {} pools spawned in {} ms", count, GetMSTimeDiffToNow(oldMSTime));
963 LOG_INFO("server.loading", " ");
964 }
965 }
966}
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition DatabaseEnv.cpp:20
std::int32_t int32
Definition Define.h:103
std::uint32_t uint32
Definition Define.h:107
#define LOG_INFO(filterType__,...)
Definition Log.h:153
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
#define LOG_WARN(filterType__,...)
Definition Log.h:149
std::pair< PooledQuestRelation::const_iterator, PooledQuestRelation::const_iterator > PooledQuestRelationBounds
Definition PoolMgr.h:102
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1567
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition SharedDefines.h:1589
@ GAMEOBJECT_TYPE_GOOBER
Definition SharedDefines.h:1574
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:131
uint32 getMSTime()
Definition Timer.h:103
@ WORLD_SEL_QUEST_POOLS
Definition WorldDatabase.h:31
const Position SpawnPool[7]
Definition boss_kelthuzad.cpp:121
Class used to access individual fields of database query result.
Definition Field.h:98
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition Field.h:112
uint32 LowType
Definition ObjectGuid.h:122
Definition PoolMgr.h:70
void SetPoolId(uint32 pool_id)
Definition PoolMgr.h:74
void AddEntry(PoolObject &poolitem, uint32 maxentries)
Definition PoolMgr.cpp:133
std::pair< uint32, uint32 > SearchPair
Definition PoolMgr.h:160
bool CheckPool(uint32 pool_id) const
Definition PoolMgr.cpp:1129
PooledQuestRelation mQuestGORelation
Definition PoolMgr.h:139
PooledQuestRelation mQuestCreatureRelation
Definition PoolMgr.h:138
Definition PreparedStatement.h:157
Definition CreatureData.h:370
Definition GameObjectData.h:715
Definition GameObjectData.h:32
uint32 type
Definition GameObjectData.h:34
Definition PoolMgr.h:33
Definition PoolMgr.h:27
uint32 MaxLimit
Definition PoolMgr.h:28

References PoolGroup< T >::AddEntry(), CheckPool(), GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_GOOBER, Field::Get(), getMSTime(), GetMSTimeDiffToNow(), LOG_ERROR, LOG_INFO, LOG_WARN, PoolTemplateData::MaxLimit, mCreatureSearchMap, mGameobjectSearchMap, mPoolCreatureGroups, mPoolGameobjectGroups, mPoolPoolGroups, mPoolQuestGroups, mPoolSearchMap, mPoolTemplate, mQuestCreatureRelation, mQuestGORelation, mQuestSearchMap, PoolGroup< T >::SetPoolId(), sObjectMgr, SpawnPool, GameObjectTemplate::type, WORLD_SEL_QUEST_POOLS, and WorldDatabase.

◆ LoadQuestPools()

void PoolMgr::LoadQuestPools ( )
969{
970}

◆ ReSpawnPoolQuests()

void PoolMgr::ReSpawnPoolQuests ( )
1043{
1044 for (auto& [questId, poolId] : mQuestSearchMap)
1045 {
1046 if (IsSpawnedObject<Quest>(questId))
1047 {
1048 PoolObject tempObj(questId, 0.0f);
1049 auto it = mPoolQuestGroups.find(poolId);
1050 if (it != mPoolQuestGroups.end())
1051 it->second.Spawn1Object(&tempObj);
1052 }
1053 }
1054}

References mPoolQuestGroups, and mQuestSearchMap.

◆ SaveQuestsToDB()

void PoolMgr::SaveQuestsToDB ( bool  daily,
bool  weekly,
bool  other 
)
973{
974 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
975
976 // pussywizard: mysql thread races, change only what is meant to be changed
977 std::set<uint32> deletedPools;
978 for (PoolGroupQuestMap::iterator itr = mPoolQuestGroups.begin(); itr != mPoolQuestGroups.end(); ++itr)
979 {
980 if (itr->second.IsEmpty())
981 continue;
982 if (Quest const* quest = sObjectMgr->GetQuestTemplate(itr->second.GetFirstEqualChancedObjectId()))
983 {
984 if (!daily && quest->IsDaily())
985 continue;
986 if (!weekly && quest->IsWeekly())
987 continue;
988 if (!other && !quest->IsDaily() && !quest->IsWeekly())
989 continue;
990 }
992 stmt->SetData(0, itr->second.GetPoolId());
993 trans->Append(stmt);
994 deletedPools.insert(itr->second.GetPoolId());
995 }
996
997 for (SearchMap::iterator itr = mQuestSearchMap.begin(); itr != mQuestSearchMap.end(); ++itr)
998 if (deletedPools.find(itr->second) != deletedPools.end())
999 if (IsSpawnedObject<Quest>(itr->first))
1000 {
1002 stmt->SetData(0, itr->second);
1003 stmt->SetData(1, itr->first);
1004 trans->Append(stmt);
1005 }
1006
1007 CharacterDatabase.CommitTransaction(trans);
1008}
@ CHAR_DEL_QUEST_POOL_SAVE
Definition CharacterDatabase.h:31
@ CHAR_INS_QUEST_POOL_SAVE
Definition CharacterDatabase.h:32
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition DatabaseEnvFwd.h:69
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77

References CHAR_DEL_QUEST_POOL_SAVE, CHAR_INS_QUEST_POOL_SAVE, CharacterDatabase, mPoolQuestGroups, mQuestSearchMap, PreparedStatementBase::SetData(), and sObjectMgr.

Referenced by ChangeDailyQuests(), and ChangeWeeklyQuests().

◆ SpawnPool() [1/6]

void PoolMgr::SpawnPool ( uint32  pool_id)
1096{
1097 SpawnPool<Pool>(pool_id, 0);
1098 SpawnPool<GameObject>(pool_id, 0);
1099 SpawnPool<Creature>(pool_id, 0);
1100 SpawnPool<Quest>(pool_id, 0);
1101}

◆ SpawnPool() [2/6]

template<>
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  db_guid 
)
private
1060{
1061 auto it = mPoolCreatureGroups.find(pool_id);
1062 if (it != mPoolCreatureGroups.end() && !it->second.IsEmpty())
1063 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid);
1064}

References mPoolCreatureGroups, mPoolTemplate, and mSpawnedData.

◆ SpawnPool() [3/6]

template<>
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  db_guid 
)
private
1070{
1071 auto it = mPoolGameobjectGroups.find(pool_id);
1072 if (it != mPoolGameobjectGroups.end() && !it->second.IsEmpty())
1073 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid);
1074}

References mPoolGameobjectGroups, mPoolTemplate, and mSpawnedData.

◆ SpawnPool() [4/6]

template<typename T >
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  db_guid_or_pool_id 
)
private

◆ SpawnPool() [5/6]

template<>
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  quest_id 
)
private
1089{
1090 auto it = mPoolQuestGroups.find(pool_id);
1091 if (it != mPoolQuestGroups.end() && !it->second.IsEmpty())
1092 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, quest_id);
1093}

References mPoolQuestGroups, mPoolTemplate, and mSpawnedData.

◆ SpawnPool() [6/6]

template<>
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  sub_pool_id 
)
private
1080{
1081 auto it = mPoolPoolGroups.find(pool_id);
1082 if (it != mPoolPoolGroups.end() && !it->second.IsEmpty())
1083 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, sub_pool_id);
1084}

References mPoolPoolGroups, mPoolTemplate, and mSpawnedData.

◆ UpdatePool()

template<typename T >
template void PoolMgr::UpdatePool< Quest > ( uint32  pool_id,
uint32  db_guid_or_pool_id 
)
1159{
1160 if (uint32 motherpoolid = IsPartOfAPool<Pool>(pool_id))
1161 SpawnPool<Pool>(motherpoolid, pool_id);
1162 else
1163 SpawnPool<T>(pool_id, db_guid_or_pool_id);
1164}

Friends And Related Symbol Documentation

◆ PoolQuestReloadFixTest

friend class PoolQuestReloadFixTest
friend

Member Data Documentation

◆ mCreatureSearchMap

SearchMap PoolMgr::mCreatureSearchMap
private

◆ mGameobjectSearchMap

SearchMap PoolMgr::mGameobjectSearchMap
private

◆ mPoolCreatureGroups

PoolGroupCreatureMap PoolMgr::mPoolCreatureGroups
private

◆ mPoolGameobjectGroups

PoolGroupGameObjectMap PoolMgr::mPoolGameobjectGroups
private

◆ mPoolPoolGroups

PoolGroupPoolMap PoolMgr::mPoolPoolGroups
private

◆ mPoolQuestGroups

◆ mPoolSearchMap

SearchMap PoolMgr::mPoolSearchMap
private

Referenced by IsPartOfAPool(), and LoadFromDB().

◆ mPoolTemplate

PoolTemplateDataMap PoolMgr::mPoolTemplate
private

◆ mQuestCreatureRelation

PooledQuestRelation PoolMgr::mQuestCreatureRelation

Referenced by LoadFromDB().

◆ mQuestGORelation

PooledQuestRelation PoolMgr::mQuestGORelation

Referenced by LoadFromDB().

◆ mQuestSearchMap

SearchMap PoolMgr::mQuestSearchMap
private

◆ mSpawnedData

ActivePoolData PoolMgr::mSpawnedData
private

The documentation for this class was generated from the following files: