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());
193 return lootTemplate->HasQuestDrop();
201 if (lootTemplate->HasQuestDropForPlayer(player))
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) -> std::vector<Player*>
702 std::vector<Player*> lootersForItem;
703 for (
auto&& [looter, loot] : personalLoot)
704 if (predicate(looter))
705 lootersForItem.push_back(looter);
707 return lootersForItem;
711 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
713 if (!(item->lootmode & lootMode))
716 if (!item->Roll(rate))
725 std::vector<Player*> lootersForItem = getLootersForItem([&](
Player const* looter)
730 if (!lootersForItem.empty())
733 personalLoot[chosenLooter]->AddItem(*item);
744 std::vector<Player*> gotLoot;
745 for (
uint32 loop = 0; loop < maxcount; ++loop)
747 std::vector<Player*> lootersForItem = getLootersForItem([&](
Player const* looter)
753 if (lootersForItem.empty())
756 auto newEnd = std::remove_if(lootersForItem.begin(), lootersForItem.end(), [&](
Player const* looter)
758 return advstd::ranges::contains(gotLoot, looter);
761 if (lootersForItem.begin() == newEnd)
768 lootersForItem.erase(newEnd, lootersForItem.end());
771 referenced->
Process(*personalLoot[chosenLooter], rate, lootMode, item->groupid, chosenLooter);
772 gotLoot.push_back(chosenLooter);
782 std::vector<Player*> lootersForItem = getLootersForItem([&](
Player const* looter)
787 for (
Player* looter : lootersForItem)
788 personalLoot[looter]->AddItem(*item);
797 for (std::unique_ptr<LootGroup>
const& group :
Groups)
801 std::vector<Player*> lootersForGroup = getLootersForItem([&](
Player const* looter)
803 return group->HasDropForPlayer(looter,
true);
806 if (!lootersForGroup.empty())
809 group->Process(*personalLoot[chosenLooter], lootMode);
820 if (groupId >
Groups.size())
826 return Groups[groupId - 1]->HasDropForPlayer(player, strictUsabilityCheck);
830 for (std::unique_ptr<LootStoreItem>
const& lootStoreItem :
Entries)
832 switch (lootStoreItem->type)
845 if (referenced->
HasDropForPlayer(player, lootStoreItem->groupid, strictUsabilityCheck))
855 for (std::unique_ptr<LootGroup>
const& group :
Groups)
856 if (group && group->HasDropForPlayer(player, strictUsabilityCheck))
867 if (groupId >
Groups.size())
876 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
882 if (item->needs_quest)
900 for (std::unique_ptr<LootGroup>
const& group :
Groups)
901 if (group && group->HasQuestDrop())
912 if (groupId >
Groups.size())
922 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
949 for (std::unique_ptr<LootGroup>
const& group :
Groups)
950 if (group && group->HasQuestDropForPlayer(player))
969 for (std::unique_ptr<LootStoreItem>
const& item :
Entries)
976 ref_set->erase(item->itemid);
980 for (std::unique_ptr<LootGroup>
const& group :
Groups)
982 group->CheckLootRefs(store, ref_set);
989 for (std::unique_ptr<LootStoreItem>& item :
Entries)
991 if (item->itemid ==
uint32(
id.SourceEntry))
993 item->conditions = std::move(reference);
1001 for (std::unique_ptr<LootGroup>& group :
Groups)
1007 if (!itemList->empty())
1009 for (std::unique_ptr<LootStoreItem>
const& item : *itemList)
1011 if (item->itemid ==
uint32(
id.SourceEntry))
1013 item->conditions = std::move(reference);
1019 itemList = group->GetEqualChancedItemList();
1020 if (!itemList->empty())
1022 for (std::unique_ptr<LootStoreItem>
const& item : *itemList)
1024 if (item->itemid ==
uint32(
id.SourceEntry))
1026 item->conditions = std::move(reference);
1038 std::vector<Player*>
const& tappers)
1040 std::unordered_map<Player*, std::unique_ptr<Loot>> tempLoot;
1042 for (
Player* tapper : tappers)
1044 if (tapper->IsLockedToDungeonEncounter(dungeonEncounterId))
1047 std::unique_ptr<Loot>& loot = tempLoot[tapper];
1050 loot->SetDungeonEncounterId(dungeonEncounterId);
1051 loot->generateMoneyLoot(minMoney, maxMoney);
1055 tab->ProcessPersonalLoot(tempLoot, store.
IsRatesAllowed(), lootMode);
1057 std::unordered_map<ObjectGuid, std::unique_ptr<Loot>> personalLoot;
1058 for (
auto&& [looter, loot] : tempLoot)
1060 loot->FillNotNormalLootFor(looter);
1062 if (loot->isLooted())
1065 personalLoot[looter->GetGUID()] = std::move(loot);
1068 return personalLoot;
1073 TC_LOG_INFO(
"server.loading",
"Loading creature loot templates...");
1082 for (
auto const& [creatureId, creatureTemplate] : ctc)
1084 for (
auto const& [difficulty, creatureDifficulty] : creatureTemplate.difficultyStore)
1086 if (
uint32 lootid = creatureDifficulty.LootID)
1088 if (!lootIdSet.contains(lootid))
1091 lootIdSetUsed.insert(lootid);
1096 for (
uint32 lootId : lootIdSetUsed)
1097 lootIdSet.erase(lootId);
1108 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creature loot templates. DB table `creature_loot_template` is empty");
1113 TC_LOG_INFO(
"server.loading",
"Loading disenchanting loot templates...");
1122 uint32 lootid = disenchant->ID;
1123 if (!lootIdSet.contains(lootid))
1126 lootIdSetUsed.insert(lootid);
1134 uint32 lootid = itemBonus->Value[0];
1135 if (!lootIdSet.contains(lootid))
1138 lootIdSetUsed.insert(lootid);
1141 for (
uint32 lootId : lootIdSetUsed)
1142 lootIdSet.erase(lootId);
1150 TC_LOG_INFO(
"server.loading",
">> Loaded 0 disenchanting loot templates. DB table `disenchant_loot_template` is empty");
1155 TC_LOG_INFO(
"server.loading",
"Loading fishing loot templates...");
1164 lootIdSet.erase(areaTable->ID);
1172 TC_LOG_INFO(
"server.loading",
">> Loaded 0 fishing loot templates. DB table `fishing_loot_template` is empty");
1177 TC_LOG_INFO(
"server.loading",
"Loading gameobject loot templates...");
1184 auto checkLootId = [&](
uint32 lootId,
uint32 gameObjectId)
1186 if (!lootIdSet.contains(lootId))
1189 lootIdSetUsed.insert(lootId);
1194 for (
auto const& [gameObjectId, gameObjectTemplate] : gotc)
1196 if (
uint32 lootid = gameObjectTemplate.GetLootId())
1197 checkLootId(lootid, gameObjectId);
1201 if (gameObjectTemplate.chest.chestPersonalLoot)
1202 checkLootId(gameObjectTemplate.chest.chestPersonalLoot, gameObjectId);
1204 if (gameObjectTemplate.chest.chestPushLoot)
1205 checkLootId(gameObjectTemplate.chest.chestPushLoot, gameObjectId);
1209 for (
uint32 lootId : lootIdSetUsed)
1210 lootIdSet.erase(lootId);
1218 TC_LOG_INFO(
"server.loading",
">> Loaded 0 gameobject loot templates. DB table `gameobject_loot_template` is empty");
1223 TC_LOG_INFO(
"server.loading",
"Loading item loot templates...");
1232 for (
auto const& [itemId, itemTemplate] : its)
1234 if (!lootIdSet.erase(itemId))
1243 TC_LOG_INFO(
"server.loading",
">> Loaded 0 item loot templates. DB table `item_loot_template` is empty");
1248 TC_LOG_INFO(
"server.loading",
"Loading milling loot templates...");
1257 for (
auto const& [itemId, itemTemplate] : its)
1259 if (!lootIdSet.erase(itemId))
1268 TC_LOG_INFO(
"server.loading",
">> Loaded 0 milling loot templates. DB table `milling_loot_template` is empty");
1273 TC_LOG_INFO(
"server.loading",
"Loading pickpocketing loot templates...");
1282 for (
auto const& [creatureId, creatureTemplate] : ctc)
1284 for (
auto const& [difficulty, creatureDifficulty] : creatureTemplate.difficultyStore)
1286 if (
uint32 lootid = creatureDifficulty.PickPocketLootID)
1288 if (!lootIdSet.contains(lootid))
1291 lootIdSetUsed.insert(lootid);
1296 for (
uint32 lootId : lootIdSetUsed)
1297 lootIdSet.erase(lootId);
1305 TC_LOG_INFO(
"server.loading",
">> Loaded 0 pickpocketing loot templates. DB table `pickpocketing_loot_template` is empty");
1310 TC_LOG_INFO(
"server.loading",
"Loading prospecting loot templates...");
1319 for (
auto const& [itemId, itemTemplate] : its)
1321 if (!lootIdSet.erase(itemId))
1330 TC_LOG_INFO(
"server.loading",
">> Loaded 0 prospecting loot templates. DB table `prospecting_loot_template` is empty");
1335 TC_LOG_INFO(
"server.loading",
"Loading mail loot templates...");
1344 lootIdSet.erase(mailTemplate->ID);
1352 TC_LOG_INFO(
"server.loading",
">> Loaded 0 mail loot templates. DB table `mail_loot_template` is empty");
1357 TC_LOG_INFO(
"server.loading",
"Loading skinning loot templates...");
1366 for (
auto const& [creatureId, creatureTemplate] : ctc)
1368 for (
auto const& [difficulty, creatureDifficulty] : creatureTemplate.difficultyStore)
1370 if (
uint32 lootid = creatureDifficulty.SkinLootID)
1372 if (!lootIdSet.contains(lootid))
1375 lootIdSetUsed.insert(lootid);
1380 for (
uint32 lootId : lootIdSetUsed)
1381 lootIdSet.erase(lootId);
1389 TC_LOG_INFO(
"server.loading",
">> Loaded 0 skinning loot templates. DB table `skinning_loot_template` is empty");
1395 TC_LOG_INFO(
"server.loading",
"Loading spell loot templates...");
1409 if (!lootIdSet.contains(spellInfo->
Id))
1417 lootIdSetUsed.insert(spellInfo->
Id);
1420 for (
uint32 lootId : lootIdSetUsed)
1421 lootIdSet.erase(lootId);
1429 TC_LOG_INFO(
"server.loading",
">> Loaded 0 spell loot templates. DB table `spell_loot_template` is empty");
1434 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(float chance, PseudoRandomDistributionState &state)
#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
bool HasQuestDropForPlayer(Player const *player, uint8 groupId=0) const
bool HasQuestDrop(uint8 groupId=0) 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 HasDropForPlayer(Player const *player, uint8 groupId=0, bool strictUsabilityCheck=false) const
LootStoreItemList Entries
void Verify(LootStore const &store, uint32 Id) 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)