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 ()
 
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
 

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
106{};

Member Function Documentation

◆ ChangeDailyQuests()

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

References mPoolQuestGroups, SaveQuestsToDB(), and sObjectMgr.

◆ ChangeWeeklyQuests()

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

References mPoolQuestGroups, SaveQuestsToDB(), and sObjectMgr.

◆ CheckPool()

bool PoolMgr::CheckPool ( uint32  pool_id) const
1115{
1116 {
1117 auto it = mPoolGameobjectGroups.find(pool_id);
1118 if (it != mPoolGameobjectGroups.end() && !it->second.CheckPool())
1119 return false;
1120 }
1121 {
1122 auto it = mPoolCreatureGroups.find(pool_id);
1123 if (it != mPoolCreatureGroups.end() && !it->second.CheckPool())
1124 return false;
1125 }
1126 {
1127 auto it = mPoolPoolGroups.find(pool_id);
1128 if (it != mPoolPoolGroups.end() && !it->second.CheckPool())
1129 return false;
1130 }
1131 {
1132 auto it = mPoolQuestGroups.find(pool_id);
1133 if (it != mPoolQuestGroups.end() && !it->second.CheckPool())
1134 return false;
1135 }
1136 return true;
1137}
PoolGroupCreatureMap mPoolCreatureGroups
Definition: PoolMgr.h:150
PoolGroupPoolMap mPoolPoolGroups
Definition: PoolMgr.h:152
PoolGroupGameObjectMap mPoolGameobjectGroups
Definition: PoolMgr.h:151

References mPoolCreatureGroups, mPoolGameobjectGroups, mPoolPoolGroups, and mPoolQuestGroups.

Referenced by LoadFromDB().

◆ DespawnPool()

void PoolMgr::DespawnPool ( uint32  pool_id)
1090{
1091 {
1092 auto it = mPoolCreatureGroups.find(pool_id);
1093 if (it != mPoolCreatureGroups.end() && !it->second.IsEmpty())
1094 it->second.DespawnObject(mSpawnedData);
1095 }
1096 {
1097 auto it = mPoolGameobjectGroups.find(pool_id);
1098 if (it != mPoolGameobjectGroups.end() && !it->second.IsEmpty())
1099 it->second.DespawnObject(mSpawnedData);
1100 }
1101 {
1102 auto it = mPoolPoolGroups.find(pool_id);
1103 if (it != mPoolPoolGroups.end() && !it->second.IsEmpty())
1104 it->second.DespawnObject(mSpawnedData);
1105 }
1106 {
1107 auto it = mPoolQuestGroups.find(pool_id);
1108 if (it != mPoolQuestGroups.end() && !it->second.IsEmpty())
1109 it->second.DespawnObject(mSpawnedData);
1110 }
1111}
ActivePoolData mSpawnedData
Definition: PoolMgr.h:160

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

◆ Initialize()

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

References mCreatureSearchMap, mGameobjectSearchMap, and mQuestSearchMap.

◆ instance()

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

References instance().

Referenced by instance().

◆ IsPartOfAPool() [1/5]

template<>
uint32 PoolMgr::IsPartOfAPool ( uint32  db_guid) const
inline
168{
169 SearchMap::const_iterator itr = mCreatureSearchMap.find(db_guid);
170 if (itr != mCreatureSearchMap.end())
171 return itr->second;
172
173 return 0;
174}

References mCreatureSearchMap.

◆ IsPartOfAPool() [2/5]

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

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
201{
202 SearchMap::const_iterator itr = mPoolSearchMap.find(pool_id);
203 if (itr != mPoolSearchMap.end())
204 return itr->second;
205
206 return 0;
207}
SearchMap mPoolSearchMap
Definition: PoolMgr.h:156

References mPoolSearchMap.

◆ IsPartOfAPool() [5/5]

template<>
uint32 PoolMgr::IsPartOfAPool ( uint32  questId) const
inline
190{
191 SearchMap::const_iterator itr = mQuestSearchMap.find(questId);
192 if (itr != mQuestSearchMap.end())
193 return itr->second;
194
195 return 0;
196}

References mQuestSearchMap.

◆ IsSpawnedObject()

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

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 ( )
968{
969}

◆ SaveQuestsToDB()

void PoolMgr::SaveQuestsToDB ( bool  daily,
bool  weekly,
bool  other 
)
972{
973 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
974
975 // pussywizard: mysql thread races, change only what is meant to be changed
976 std::set<uint32> deletedPools;
977 for (PoolGroupQuestMap::iterator itr = mPoolQuestGroups.begin(); itr != mPoolQuestGroups.end(); ++itr)
978 {
979 if (itr->second.IsEmpty())
980 continue;
981 if (Quest const* quest = sObjectMgr->GetQuestTemplate(itr->second.GetFirstEqualChancedObjectId()))
982 {
983 if (!daily && quest->IsDaily())
984 continue;
985 if (!weekly && quest->IsWeekly())
986 continue;
987 if (!other && !quest->IsDaily() && !quest->IsWeekly())
988 continue;
989 }
991 stmt->SetData(0, itr->second.GetPoolId());
992 trans->Append(stmt);
993 deletedPools.insert(itr->second.GetPoolId());
994 }
995
996 for (SearchMap::iterator itr = mQuestSearchMap.begin(); itr != mQuestSearchMap.end(); ++itr)
997 if (deletedPools.find(itr->second) != deletedPools.end())
998 if (IsSpawnedObject<Quest>(itr->first))
999 {
1001 stmt->SetData(0, itr->second);
1002 stmt->SetData(1, itr->first);
1003 trans->Append(stmt);
1004 }
1005
1006 CharacterDatabase.CommitTransaction(trans);
1007}
@ 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)
1081{
1082 SpawnPool<Pool>(pool_id, 0);
1083 SpawnPool<GameObject>(pool_id, 0);
1084 SpawnPool<Creature>(pool_id, 0);
1085 SpawnPool<Quest>(pool_id, 0);
1086}

◆ SpawnPool() [2/6]

template<>
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  db_guid 
)
private
1045{
1046 auto it = mPoolCreatureGroups.find(pool_id);
1047 if (it != mPoolCreatureGroups.end() && !it->second.IsEmpty())
1048 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid);
1049}

References mPoolCreatureGroups, mPoolTemplate, and mSpawnedData.

◆ SpawnPool() [3/6]

template<>
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  db_guid 
)
private
1055{
1056 auto it = mPoolGameobjectGroups.find(pool_id);
1057 if (it != mPoolGameobjectGroups.end() && !it->second.IsEmpty())
1058 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid);
1059}

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
1074{
1075 auto it = mPoolQuestGroups.find(pool_id);
1076 if (it != mPoolQuestGroups.end() && !it->second.IsEmpty())
1077 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, quest_id);
1078}

References mPoolQuestGroups, mPoolTemplate, and mSpawnedData.

◆ SpawnPool() [6/6]

template<>
void PoolMgr::SpawnPool ( uint32  pool_id,
uint32  sub_pool_id 
)
private
1065{
1066 auto it = mPoolPoolGroups.find(pool_id);
1067 if (it != mPoolPoolGroups.end() && !it->second.IsEmpty())
1068 it->second.SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, sub_pool_id);
1069}

References mPoolPoolGroups, mPoolTemplate, and mSpawnedData.

◆ UpdatePool()

template<typename T >
template void PoolMgr::UpdatePool< Quest > ( uint32  pool_id,
uint32  db_guid_or_pool_id 
)
1144{
1145 if (uint32 motherpoolid = IsPartOfAPool<Pool>(pool_id))
1146 SpawnPool<Pool>(motherpoolid, pool_id);
1147 else
1148 SpawnPool<T>(pool_id, db_guid_or_pool_id);
1149}

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

Referenced by LoadFromDB(), and SpawnPool().

◆ mQuestCreatureRelation

PooledQuestRelation PoolMgr::mQuestCreatureRelation

Referenced by LoadFromDB().

◆ mQuestGORelation

PooledQuestRelation PoolMgr::mQuestGORelation

Referenced by LoadFromDB().

◆ mQuestSearchMap

SearchMap PoolMgr::mQuestSearchMap
private

◆ mSpawnedData

ActivePoolData PoolMgr::mSpawnedData
private