97 Player const* personalLooter =
nullptr)
const;
114 : m_name(name), m_entryName(entryName), m_ratesAllowed(ratesAllowed)
125 m_LootTemplates.clear();
133 lootTemplate->
Verify(*
this, lootId);
144 QueryResult result =
WorldDatabase.PQuery(
"SELECT Entry, ItemType, Item, Chance, QuestRequired, LootMode, GroupId, MinCount, MaxCount FROM {}",
GetName());
153 Field* fields = result->Fetch();
158 float chance = fields[3].
GetFloat();
159 bool needsquest = fields[4].
GetBool();
167 if (!storeitem->
IsValid(*
this, entry))
179 tab->second->AddEntry(storeitem);
182 while (result->NextRow());
235 for (
uint32 lootId : lootIdSet)
241 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} does not exist but it is used by {} {}",
GetName(), lootId, ownerType, ownerId);
289 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: wrong MinCount ({}) - skipped",
301 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: item does not exist - skipped",
308 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: equal-chanced grouped entry, but group not defined - skipped",
315 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: low chance ({}) - skipped",
322 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: MaxCount ({}) less that MinCount ({}) - skipped",
330 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: quest required will be ignored",
334 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: zero chance is specified for a reference, skipped",
343 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: currency does not exist - skipped",
350 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: equal-chanced grouped entry, but group not defined - skipped",
357 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: low chance ({}) - skipped",
364 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: MaxCount ({}) less that MinCount ({}) - skipped",
375 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: quest does not exist - skipped",
382 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: quest is not a tracking flag - skipped",
389 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: equal-chanced grouped entry, but group not defined - skipped",
396 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: low chance ({}) - skipped",
403 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} ItemType {} Item {}: tracking quest has count other than 1 (MinCount {} MaxCount {}) - skipped",
411 TC_LOG_ERROR(
"sql.sql",
"Table '{}' Entry {} Item {}: invalid ItemType {}, skipped",
436 std::vector<LootStoreItem const*> possibleLoot;
437 possibleLoot.resize(items.size());
438 std::ranges::transform(items, possibleLoot.begin(), [](std::unique_ptr<LootStoreItem>
const& i) { return i.get(); });
443 std::vector<LootStoreItem const*> possibleLoot = getValidLoot(ExplicitlyChanced, lootMode, personalLooter);
445 if (!possibleLoot.empty())
451 if (item->chance >= 100.0f)
454 roll -= item->chance;
460 possibleLoot = getValidLoot(EqualChanced, lootMode, personalLooter);
461 if (!possibleLoot.empty())
469 for (std::unique_ptr<LootStoreItem>
const& lootStoreItem : ExplicitlyChanced)
473 for (std::unique_ptr<LootStoreItem>
const& lootStoreItem : EqualChanced)
495 auto hasQuestForLootItem = [player](std::unique_ptr<LootStoreItem>
const& item)
509 if (std::ranges::any_of(ExplicitlyChanced, hasQuestForLootItem))
512 if (std::ranges::any_of(EqualChanced, hasQuestForLootItem))
521 if (
LootStoreItem const* item = Roll(lootMode, personalLooter))
530 for (std::unique_ptr<LootStoreItem>
const& item : ExplicitlyChanced)
531 if (!item->needs_quest)
532 result += item->chance;
540 float result = RawTotalChance();
542 if (!EqualChanced.empty() && result < 100.0f)
550 float chance = RawTotalChance();
552 TC_LOG_ERROR(
"sql.sql",
"Table '{}' entry {} group {} has total chance > 100% ({})", lootstore.
GetName(),
id, group_id, chance);
554 if (chance >= 100.0f && !EqualChanced.empty())
555 TC_LOG_ERROR(
"sql.sql",
"Table '{}' entry {} group {} has items with chance=0% but group total chance >= 100% ({})", lootstore.
GetName(),
id, group_id, chance);
560 for (std::unique_ptr<LootStoreItem>
const& item : ExplicitlyChanced)
567 ref_set->erase(item->itemid);
571 for (std::unique_ptr<LootStoreItem>
const& item : EqualChanced)
578 ref_set->erase(item->itemid);
601 group->AddEntry(item);
610 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
632 if (item->itemid != li->
itemid)
645 if (groupId >
Groups.size())
651 Groups[groupId - 1]->Process(loot, lootMode, personalLooter);
656 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
658 if (!(item->lootmode & lootMode))
661 if (!item->Roll(rate))
682 for (
uint32 loop = 0; loop < maxcount; ++loop)
683 Referenced->
Process(loot, rate, lootMode, item->groupid, personalLooter);
693 for (std::unique_ptr<LootGroup>
const& group :
Groups)
695 group->Process(loot, lootMode, personalLooter);
700 auto getLootersForItem = [&personalLoot](
auto&& predicate)
702 std::vector<Player*> lootersForItem;
703 for (
auto&& [looter, loot] : personalLoot)
705 if (predicate(looter))
706 lootersForItem.push_back(looter);
708 return lootersForItem;
712 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
714 if (!(item->lootmode & lootMode))
717 if (!item->Roll(rate))
726 std::vector<Player*> lootersForItem = getLootersForItem([&](
Player const* looter)
731 if (!lootersForItem.empty())
734 personalLoot[chosenLooter]->AddItem(*item);
745 std::vector<Player*> gotLoot;
746 for (
uint32 loop = 0; loop < maxcount; ++loop)
748 std::vector<Player*> lootersForItem = getLootersForItem([&](
Player const* looter)
754 if (lootersForItem.empty())
757 auto newEnd = std::remove_if(lootersForItem.begin(), lootersForItem.end(), [&](
Player const* looter)
759 return advstd::ranges::contains(gotLoot, looter);
762 if (lootersForItem.begin() == newEnd)
769 lootersForItem.erase(newEnd, lootersForItem.end());
772 referenced->
Process(*personalLoot[chosenLooter], rate, lootMode, item->groupid, chosenLooter);
773 gotLoot.push_back(chosenLooter);
783 std::vector<Player*> lootersForItem = getLootersForItem([&](
Player const* looter)
788 for (
Player* looter : lootersForItem)
789 personalLoot[looter]->AddItem(*item);
798 for (std::unique_ptr<LootGroup>
const& group :
Groups)
802 std::vector<Player*> lootersForGroup = getLootersForItem([&](
Player const* looter)
804 return group->HasDropForPlayer(looter,
true);
807 if (!lootersForGroup.empty())
810 group->Process(*personalLoot[chosenLooter], lootMode);
821 if (groupId >
Groups.size())
827 return Groups[groupId - 1]->HasDropForPlayer(player, strictUsabilityCheck);
831 for (std::unique_ptr<LootStoreItem>
const& lootStoreItem :
Entries)
833 switch (lootStoreItem->type)
846 if (referenced->
HasDropForPlayer(player, lootStoreItem->groupid, strictUsabilityCheck))
856 for (std::unique_ptr<LootGroup>
const& group :
Groups)
857 if (group && group->HasDropForPlayer(player, strictUsabilityCheck))
868 if (groupId >
Groups.size())
877 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
883 if (item->needs_quest)
888 LootTemplateMap::const_iterator Referenced = store.find(item->itemid);
889 if (Referenced == store.end())
891 if (Referenced->second->HasQuestDrop(store, item->groupid))
901 for (std::unique_ptr<LootGroup>
const& group :
Groups)
902 if (group && group->HasQuestDrop())
913 if (groupId >
Groups.size())
919 return Groups[groupId - 1]->HasQuestDropForPlayer(player);
923 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
933 LootTemplateMap::const_iterator Referenced = store.find(item->itemid);
934 if (Referenced == store.end())
936 if (Referenced->second->HasQuestDropForPlayer(store, player, item->groupid))
950 for (std::unique_ptr<LootGroup>
const& group :
Groups)
951 if (group && group->HasQuestDropForPlayer(player))
963 Groups[i]->Verify(lootstore,
id, i + 1);
970 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
977 ref_set->erase(item->itemid);
981 for (std::unique_ptr<LootGroup>
const& group :
Groups)
983 group->CheckLootRefs(store, ref_set);
990 for (std::unique_ptr<LootStoreItem>& item :
Entries)
992 if (item->itemid ==
uint32(
id.SourceEntry))
994 item->conditions = std::move(reference);
1002 for (std::unique_ptr<LootGroup>& group :
Groups)
1008 if (!itemList->empty())
1010 for (std::unique_ptr<LootStoreItem>
const& item : *itemList)
1012 if (item->itemid ==
uint32(
id.SourceEntry))
1014 item->conditions = std::move(reference);
1020 itemList = group->GetEqualChancedItemList();
1021 if (!itemList->empty())
1023 for (std::unique_ptr<LootStoreItem>
const& item : *itemList)
1025 if (item->itemid ==
uint32(
id.SourceEntry))
1027 item->conditions = std::move(reference);
1039 std::vector<Player*>
const& tappers)
1041 std::unordered_map<Player*, std::unique_ptr<Loot>> tempLoot;
1043 for (
Player* tapper : tappers)
1045 if (tapper->IsLockedToDungeonEncounter(dungeonEncounterId))
1048 std::unique_ptr<Loot>& loot = tempLoot[tapper];
1051 loot->SetDungeonEncounterId(dungeonEncounterId);
1052 loot->generateMoneyLoot(minMoney, maxMoney);
1056 tab->ProcessPersonalLoot(tempLoot, store.
IsRatesAllowed(), lootMode);
1058 std::unordered_map<ObjectGuid, std::unique_ptr<Loot>> personalLoot;
1059 for (
auto&& [looter, loot] : tempLoot)
1061 loot->FillNotNormalLootFor(looter);
1063 if (loot->isLooted())
1066 personalLoot[looter->GetGUID()] = std::move(loot);
1069 return personalLoot;
1074 TC_LOG_INFO(
"server.loading",
"Loading creature loot templates...");
1083 for (
auto const& [creatureId, creatureTemplate] : ctc)
1085 for (
auto const& [difficulty, creatureDifficulty] : creatureTemplate.difficultyStore)
1087 if (
uint32 lootid = creatureDifficulty.LootID)
1089 if (!lootIdSet.contains(lootid))
1092 lootIdSetUsed.insert(lootid);
1097 for (
uint32 lootId : lootIdSetUsed)
1098 lootIdSet.erase(lootId);
1109 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature loot templates. DB table `creature_loot_template` is empty");
1114 TC_LOG_INFO(
"server.loading",
"Loading disenchanting loot templates...");
1123 uint32 lootid = disenchant->ID;
1124 if (!lootIdSet.contains(lootid))
1127 lootIdSetUsed.insert(lootid);
1135 uint32 lootid = itemBonus->Value[0];
1136 if (!lootIdSet.contains(lootid))
1139 lootIdSetUsed.insert(lootid);
1142 for (
uint32 lootId : lootIdSetUsed)
1143 lootIdSet.erase(lootId);
1151 TC_LOG_INFO(
"server.loading",
">> Loaded 0 disenchanting loot templates. DB table `disenchant_loot_template` is empty");
1156 TC_LOG_INFO(
"server.loading",
"Loading fishing loot templates...");
1165 lootIdSet.erase(areaTable->ID);
1173 TC_LOG_INFO(
"server.loading",
">> Loaded 0 fishing loot templates. DB table `fishing_loot_template` is empty");
1178 TC_LOG_INFO(
"server.loading",
"Loading gameobject loot templates...");
1185 auto checkLootId = [&](
uint32 lootId,
uint32 gameObjectId)
1187 if (!lootIdSet.contains(lootId))
1190 lootIdSetUsed.insert(lootId);
1195 for (
auto const& [gameObjectId, gameObjectTemplate] : gotc)
1197 if (
uint32 lootid = gameObjectTemplate.GetLootId())
1198 checkLootId(lootid, gameObjectId);
1202 if (gameObjectTemplate.chest.chestPersonalLoot)
1203 checkLootId(gameObjectTemplate.chest.chestPersonalLoot, gameObjectId);
1205 if (gameObjectTemplate.chest.chestPushLoot)
1206 checkLootId(gameObjectTemplate.chest.chestPushLoot, gameObjectId);
1210 for (
uint32 lootId : lootIdSetUsed)
1211 lootIdSet.erase(lootId);
1219 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject loot templates. DB table `gameobject_loot_template` is empty");
1224 TC_LOG_INFO(
"server.loading",
"Loading item loot templates...");
1233 for (
auto const& [itemId, itemTemplate] : its)
1235 if (!lootIdSet.erase(itemId))
1244 TC_LOG_INFO(
"server.loading",
">> Loaded 0 item loot templates. DB table `item_loot_template` is empty");
1249 TC_LOG_INFO(
"server.loading",
"Loading milling loot templates...");
1258 for (
auto const& [itemId, itemTemplate] : its)
1260 if (!lootIdSet.erase(itemId))
1269 TC_LOG_INFO(
"server.loading",
">> Loaded 0 milling loot templates. DB table `milling_loot_template` is empty");
1274 TC_LOG_INFO(
"server.loading",
"Loading pickpocketing loot templates...");
1283 for (
auto const& [creatureId, creatureTemplate] : ctc)
1285 for (
auto const& [difficulty, creatureDifficulty] : creatureTemplate.difficultyStore)
1287 if (
uint32 lootid = creatureDifficulty.PickPocketLootID)
1289 if (!lootIdSet.contains(lootid))
1292 lootIdSetUsed.insert(lootid);
1297 for (
uint32 lootId : lootIdSetUsed)
1298 lootIdSet.erase(lootId);
1306 TC_LOG_INFO(
"server.loading",
">> Loaded 0 pickpocketing loot templates. DB table `pickpocketing_loot_template` is empty");
1311 TC_LOG_INFO(
"server.loading",
"Loading prospecting loot templates...");
1320 for (
auto const& [itemId, itemTemplate] : its)
1322 if (!lootIdSet.erase(itemId))
1331 TC_LOG_INFO(
"server.loading",
">> Loaded 0 prospecting loot templates. DB table `prospecting_loot_template` is empty");
1336 TC_LOG_INFO(
"server.loading",
"Loading mail loot templates...");
1345 lootIdSet.erase(mailTemplate->ID);
1353 TC_LOG_INFO(
"server.loading",
">> Loaded 0 mail loot templates. DB table `mail_loot_template` is empty");
1358 TC_LOG_INFO(
"server.loading",
"Loading skinning loot templates...");
1367 for (
auto const& [creatureId, creatureTemplate] : ctc)
1369 for (
auto const& [difficulty, creatureDifficulty] : creatureTemplate.difficultyStore)
1371 if (
uint32 lootid = creatureDifficulty.SkinLootID)
1373 if (!lootIdSet.contains(lootid))
1376 lootIdSetUsed.insert(lootid);
1381 for (
uint32 lootId : lootIdSetUsed)
1382 lootIdSet.erase(lootId);
1390 TC_LOG_INFO(
"server.loading",
">> Loaded 0 skinning loot templates. DB table `skinning_loot_template` is empty");
1396 TC_LOG_INFO(
"server.loading",
"Loading spell loot templates...");
1410 if (!lootIdSet.contains(spellInfo->
Id))
1418 lootIdSetUsed.insert(spellInfo->
Id);
1421 for (
uint32 lootId : lootIdSetUsed)
1422 lootIdSet.erase(lootId);
1430 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spell loot templates. DB table `spell_loot_template` is empty");
1435 TC_LOG_INFO(
"server.loading",
"Loading reference loot templates...");
DB2Storage< ItemBonusEntry > sItemBonusStore("ItemBonus.db2", &ItemBonusLoadInfo::Instance)
DB2Storage< MailTemplateEntry > sMailTemplateStore("MailTemplate.db2", &MailTemplateLoadInfo::Instance)
DB2Storage< ItemDisenchantLootEntry > sItemDisenchantLootStore("ItemDisenchantLoot.db2", &ItemDisenchantLootLoadInfo::Instance)
DB2Storage< CurrencyTypesEntry > sCurrencyTypesStore("CurrencyTypes.db2", &CurrencyTypesLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
@ ITEM_BONUS_DISENCHANT_LOOT_ID
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
@ ITEM_FLAG_IS_PROSPECTABLE
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true)
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
static constexpr Rates QualityToRate[MAX_ITEM_QUALITY]
LootStore LootTemplates_Item("item_loot_template", "item entry", true)
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Reference("reference_loot_template", "reference id", false)
LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
LootStore LootTemplates_Creature("creature_loot_template", "creature entry", true)
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template", "creature pickpocket lootid", true)
LootStore LootTemplates_Mail("mail_loot_template", "mail template id", false)
LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true)
TC_GAME_API void LoadLootTemplates_Skinning()
std::vector< std::unique_ptr< LootStoreItem > > LootStoreItemList
TC_GAME_API LootStore LootTemplates_Reference
TC_GAME_API void LoadLootTemplates_Creature()
TC_GAME_API void LoadLootTemplates_Milling()
TC_GAME_API void LoadLootTemplates_Disenchant()
TC_GAME_API LootStore LootTemplates_Gameobject
TC_GAME_API LootStore LootTemplates_Item
TC_GAME_API LootStore LootTemplates_Prospecting
TC_GAME_API void LoadLootTemplates_Gameobject()
TC_GAME_API LootStore LootTemplates_Skinning
TC_GAME_API void LoadLootTemplates_Pickpocketing()
TC_GAME_API LootStore LootTemplates_Fishing
TC_GAME_API void LoadLootTemplates_Prospecting()
TC_GAME_API LootStore LootTemplates_Disenchant
TC_GAME_API LootStore LootTemplates_Pickpocketing
TC_GAME_API LootStore LootTemplates_Spell
std::unordered_map< uint32, std::unique_ptr< LootTemplate > > LootTemplateMap
TC_GAME_API void LoadLootTemplates_Mail()
TC_GAME_API LootStore LootTemplates_Creature
TC_GAME_API void LoadLootTables()
std::unordered_map< ObjectGuid, std::unique_ptr< Loot > > GenerateDungeonEncounterPersonalLoot(uint32 dungeonEncounterId, uint32 lootId, LootStore const &store, LootType type, WorldObject const *lootOwner, uint32 minMoney, uint32 maxMoney, uint16 lootMode, MapDifficultyEntry const *mapDifficulty, std::vector< Player * > const &tappers)
TC_GAME_API LootStore LootTemplates_Mail
std::set< uint32 > LootIdSet
TC_GAME_API void LoadLootTemplates_Item()
TC_GAME_API void LoadLootTemplates_Fishing()
TC_GAME_API void LoadLootTemplates_Reference()
TC_GAME_API LootStore LootTemplates_Milling
TC_GAME_API void LoadLootTemplates_Spell()
std::unordered_map< uint32, ItemTemplate > ItemTemplateContainer
std::unordered_map< uint32, GameObjectTemplate > GameObjectTemplateContainer
std::unordered_map< uint32, CreatureTemplate > CreatureTemplateContainer
@ QUEST_FLAGS_TRACKING_EVENT
bool roll_chance(T chance)
#define PLAYER_CORPSE_LOOT_ENTRY
@ SPELL_ATTR0_IS_TRADESKILL
@ SPELL_ATTR0_NOT_SHAPESHIFTED
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
ObjectGuid const & GetGUID() const
Class used to access individual fields of database query result.
float GetFloat() const noexcept
bool GetBool() const noexcept
uint32 GetUInt32() const noexcept
uint16 GetUInt16() const noexcept
uint8 GetUInt8() const noexcept
int8 GetInt8() const noexcept
void ReportUnusedIds(LootIdSet const &lootIdSet) const
LootTemplate const * GetLootFor(uint32 loot_id) const
LootTemplateMap m_LootTemplates
void ReportNonExistingId(uint32 lootId, char const *ownerType, uint32 ownerId) const
void CheckLootRefs(LootIdSet *ref_set=nullptr) const
char const * GetEntryName() const
bool HaveQuestLootFor(uint32 loot_id) const
LootTemplate * GetLootForConditionFill(uint32 loot_id)
LootStore(char const *name, char const *entryName, bool ratesAllowed)
bool IsRatesAllowed() const
char const * GetName() const
uint32 LoadAndCollectLootIds(LootIdSet &lootIdSet)
bool HaveQuestLootForPlayer(uint32 loot_id, Player const *player) const
void CheckLootRefs(LootTemplateMap const &store, LootIdSet *ref_set) const
LootStoreItemList ExplicitlyChanced
LootGroup(LootGroup &&)=delete
LootGroup & operator=(LootGroup &&)=delete
LootStoreItemList * GetEqualChancedItemList()
LootStoreItem const * Roll(uint16 lootMode, Player const *personalLooter=nullptr) const
LootGroup & operator=(LootGroup const &)=delete
LootStoreItemList EqualChanced
void Verify(LootStore const &lootstore, uint32 id, uint8 group_id) const
LootStoreItemList * GetExplicitlyChancedItemList()
float RawTotalChance() const
void AddEntry(LootStoreItem *item)
bool HasQuestDropForPlayer(Player const *player) const
void Process(Loot &loot, uint16 lootMode, Player const *personalLooter=nullptr) const
LootGroup(LootGroup const &)=delete
float TotalChance() const
bool HasQuestDrop() const
bool HasDropForPlayer(Player const *player, bool strictUsabilityCheck) const
void ProcessPersonalLoot(std::unordered_map< Player *, std::unique_ptr< Loot > > &personalLoot, bool rate, uint16 lootMode) const
void Process(Loot &loot, bool rate, uint16 lootMode, uint8 groupId, Player const *personalLooter=nullptr) const
void CheckLootRefs(LootTemplateMap const &store, LootIdSet *ref_set) const
void CopyConditions(LootItem *li) const
void AddEntry(LootStoreItem *item)
bool LinkConditions(ConditionId const &id, ConditionsReference reference)
bool HasQuestDropForPlayer(LootTemplateMap const &store, Player const *player, uint8 groupId=0) const
bool HasDropForPlayer(Player const *player, uint8 groupId=0, bool strictUsabilityCheck=false) const
LootStoreItemList Entries
void Verify(LootStore const &store, uint32 Id) const
bool HasQuestDrop(LootTemplateMap const &store, uint8 groupId=0) const
bool HasQuestForItem(uint32 itemId) const
bool HasQuestForCurrency(uint32 currencyId) const
bool HasFlag(QuestFlags flag) const
bool IsLootCrafting() const
bool HasAttribute(SpellAttr0 attribute) const
@ RATE_DROP_ITEM_REFERENCED_AMOUNT
@ RATE_DROP_ITEM_LEGENDARY
@ RATE_DROP_ITEM_UNCOMMON
@ RATE_DROP_ITEM_REFERENCED
@ RATE_DROP_ITEM_ARTIFACT
ItemContext GetContextForPlayer(MapDifficultyEntry const *mapDifficulty, Player const *player)
constexpr void EraseIf(Container &c, Predicate p)
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
constexpr decltype(auto) EnsureWritableVectorIndex(std::vector< T > &vec, typename std::vector< T >::size_type i)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
uint32 GetQuality() const
LootGroupInvalidSelector(uint16 lootMode, Player const *personalLooter)
bool operator()(LootStoreItem const *item) const
Player const * _personalLooter
bool AllowedForPlayer(Player const *player, Loot const *loot) const
ConditionsReference conditions
bool Roll(bool rate) const
bool IsValid(LootStore const &store, uint32 entry) const
void AddItem(LootStoreItem const &item)