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
558{
559}

◆ ~PoolMgr()

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

Member Function Documentation

◆ ChangeDailyQuests()

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

References mPoolQuestGroups, SaveQuestsToDB(), and sObjectMgr.

◆ ChangeWeeklyQuests()

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

References mPoolQuestGroups, SaveQuestsToDB(), and sObjectMgr.

◆ CheckPool()

bool PoolMgr::CheckPool ( uint32  pool_id) const
1112{
1113 {
1114 auto it = mPoolGameobjectGroups.find(pool_id);
1115 if (it != mPoolGameobjectGroups.end() && !it->second.CheckPool())
1116 return false;
1117 }
1118 {
1119 auto it = mPoolCreatureGroups.find(pool_id);
1120 if (it != mPoolCreatureGroups.end() && !it->second.CheckPool())
1121 return false;
1122 }
1123 {
1124 auto it = mPoolPoolGroups.find(pool_id);
1125 if (it != mPoolPoolGroups.end() && !it->second.CheckPool())
1126 return false;
1127 }
1128 {
1129 auto it = mPoolQuestGroups.find(pool_id);
1130 if (it != mPoolQuestGroups.end() && !it->second.CheckPool())
1131 return false;
1132 }
1133 return true;
1134}
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)
1087{
1088 {
1089 auto it = mPoolCreatureGroups.find(pool_id);
1090 if (it != mPoolCreatureGroups.end() && !it->second.IsEmpty())
1091 it->second.DespawnObject(mSpawnedData);
1092 }
1093 {
1094 auto it = mPoolGameobjectGroups.find(pool_id);
1095 if (it != mPoolGameobjectGroups.end() && !it->second.IsEmpty())
1096 it->second.DespawnObject(mSpawnedData);
1097 }
1098 {
1099 auto it = mPoolPoolGroups.find(pool_id);
1100 if (it != mPoolPoolGroups.end() && !it->second.IsEmpty())
1101 it->second.DespawnObject(mSpawnedData);
1102 }
1103 {
1104 auto it = mPoolQuestGroups.find(pool_id);
1105 if (it != mPoolQuestGroups.end() && !it->second.IsEmpty())
1106 it->second.DespawnObject(mSpawnedData);
1107 }
1108}
ActivePoolData mSpawnedData
Definition: PoolMgr.h:160

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

◆ Initialize()

void PoolMgr::Initialize ( )
568{
569 mQuestSearchMap.clear();
570 mGameobjectSearchMap.clear();
571 mCreatureSearchMap.clear();
572}
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
562{
563 static PoolMgr instance;
564 return &instance;
565}
Definition: PoolMgr.h:103
static PoolMgr * instance()
Definition: PoolMgr.cpp:561

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

◆ SaveQuestsToDB()

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

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)
1078{
1079 SpawnPool<Pool>(pool_id, 0);
1080 SpawnPool<GameObject>(pool_id, 0);
1081 SpawnPool<Creature>(pool_id, 0);
1082 SpawnPool<Quest>(pool_id, 0);
1083}

◆ SpawnPool() [2/6]

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

References mPoolCreatureGroups, mPoolTemplate, and mSpawnedData.

◆ SpawnPool() [3/6]

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

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

References mPoolQuestGroups, mPoolTemplate, and mSpawnedData.

◆ SpawnPool() [6/6]

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

References mPoolPoolGroups, mPoolTemplate, and mSpawnedData.

◆ UpdatePool()

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

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