TrinityCore
ItemBonusMgr.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ItemBonusMgr.h"
19#include "ConditionMgr.h"
20#include "DB2Stores.h"
21#include "MapUtils.h"
22#include "ObjectMgr.h"
23#include "Player.h"
24
25namespace
26{
27struct ItemLevelSelectorQualityEntryComparator
28{
29 bool operator()(ItemLevelSelectorQualityEntry const* left, ItemLevelSelectorQualityEntry const* right) const { return left->Quality < right->Quality; }
30 bool operator()(ItemLevelSelectorQualityEntry const* left, ItemQualities quality) const { return left->Quality < quality; }
31};
32
33using ItemLevelSelectorQualities = std::set<ItemLevelSelectorQualityEntry const*, ItemLevelSelectorQualityEntryComparator>;
34
35std::unordered_multimap<int32 /*azeriteUnlockMappingSetId*/, AzeriteUnlockMappingEntry const*> _azeriteUnlockMappings;
36std::unordered_multimap<uint32 /*itemBonusTreeId*/, ChallengeModeItemBonusOverrideEntry const*> _challengeModeItemBonusOverrides;
37std::unordered_map<uint32 /*itemBonusListId*/, std::vector<ItemBonusEntry const*>> _itemBonusLists;
38std::unordered_multimap<uint32, ItemBonusListGroupEntryEntry const*> _itemBonusListGroupEntries;
39std::unordered_map<int16 /*itemLevelDelta*/, uint32 /*itemBonusListId*/> _itemLevelDeltaToBonusListContainer;
40std::unordered_map<uint32 /*itemLevelSelectorQualitySetId*/, ItemLevelSelectorQualities> _itemLevelQualitySelectorQualities;
41std::unordered_map<uint32 /*itemBonusTreeId*/, std::set<ItemBonusTreeNodeEntry const*>> _itemBonusTrees;
42std::unordered_multimap<uint32 /*itemId*/, uint32 /*itemBonusTreeId*/> _itemToBonusTree;
43}
44
45namespace ItemBonusMgr
46{
47void Load()
48{
49 for (AzeriteUnlockMappingEntry const* azeriteUnlockMapping : sAzeriteUnlockMappingStore)
50 _azeriteUnlockMappings.emplace(azeriteUnlockMapping->AzeriteUnlockMappingSetID, azeriteUnlockMapping);
51
52 for (ChallengeModeItemBonusOverrideEntry const* challengeModeItemBonusOverride : sChallengeModeItemBonusOverrideStore)
53 _challengeModeItemBonusOverrides.emplace(challengeModeItemBonusOverride->SrcItemBonusTreeID, challengeModeItemBonusOverride);
54
55 for (ItemBonusEntry const* bonus : sItemBonusStore)
56 _itemBonusLists[bonus->ParentItemBonusListID].push_back(bonus);
57
58 for (ItemBonusListGroupEntryEntry const* bonusListGroupEntry : sItemBonusListGroupEntryStore)
59 _itemBonusListGroupEntries.emplace(bonusListGroupEntry->ItemBonusListGroupID, bonusListGroupEntry);
60
61 for (ItemBonusListLevelDeltaEntry const* itemBonusListLevelDelta : sItemBonusListLevelDeltaStore)
62 _itemLevelDeltaToBonusListContainer[itemBonusListLevelDelta->ItemLevelDelta] = itemBonusListLevelDelta->ID;
63
64 for (ItemLevelSelectorQualityEntry const* itemLevelSelectorQuality : sItemLevelSelectorQualityStore)
65 _itemLevelQualitySelectorQualities[itemLevelSelectorQuality->ParentILSQualitySetID].insert(itemLevelSelectorQuality);
66
67 for (ItemBonusTreeNodeEntry const* bonusTreeNode : sItemBonusTreeNodeStore)
68 _itemBonusTrees[bonusTreeNode->ParentItemBonusTreeID].insert(bonusTreeNode);
69
70 for (ItemXBonusTreeEntry const* itemBonusTreeAssignment : sItemXBonusTreeStore)
71 _itemToBonusTree.insert({ itemBonusTreeAssignment->ItemID, itemBonusTreeAssignment->ItemBonusTreeID });
72}
73
74ItemContext GetContextForPlayer(MapDifficultyEntry const* mapDifficulty, Player const* player)
75{
76 if (!mapDifficulty)
77 return ItemContext::NONE;
78
79 auto evalContext = [](ItemContext currentContext, ItemContext newContext)
80 {
81 if (newContext == ItemContext::NONE)
82 newContext = currentContext;
83 else if (newContext == ItemContext::Force_to_NONE)
84 newContext = ItemContext::NONE;
85 return newContext;
86 };
87
89 if (DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(mapDifficulty->DifficultyID))
90 context = evalContext(context, ItemContext(difficulty->ItemContext));
91
92 context = evalContext(context, ItemContext(mapDifficulty->ItemContext));
93
94 if (mapDifficulty->ItemContextPickerID)
95 {
96 uint32 contentTuningId = sDB2Manager.GetRedirectedContentTuningId(mapDifficulty->ContentTuningID, player->m_playerData->CtrOptions->ConditionalFlags);
97
98 ItemContextPickerEntryEntry const* selectedPickerEntry = nullptr;
99 for (ItemContextPickerEntryEntry const* itemContextPickerEntry : sItemContextPickerEntryStore)
100 {
101 if (itemContextPickerEntry->ItemContextPickerID != uint32(mapDifficulty->ItemContextPickerID))
102 continue;
103
104 if (itemContextPickerEntry->PVal <= 0)
105 continue;
106
107 bool meetsPlayerCondition = false;
108 if (player)
109 meetsPlayerCondition = ConditionMgr::IsPlayerMeetingCondition(player, itemContextPickerEntry->PlayerConditionID);
110
111 if (itemContextPickerEntry->Flags & 0x1)
112 meetsPlayerCondition = !meetsPlayerCondition;
113
114 if (!meetsPlayerCondition)
115 continue;
116
117 if (itemContextPickerEntry->LabelID && !sDB2Manager.HasContentTuningLabel(contentTuningId, itemContextPickerEntry->LabelID))
118 continue;
119
120 if (!selectedPickerEntry || selectedPickerEntry->OrderIndex < itemContextPickerEntry->OrderIndex)
121 selectedPickerEntry = itemContextPickerEntry;
122 }
123
124 if (selectedPickerEntry)
125 context = evalContext(context, ItemContext(selectedPickerEntry->ItemCreationContext));
126 }
127
128 return context;
129}
130
131std::span<ItemBonusEntry const*> GetItemBonuses(uint32 bonusListId)
132{
133 if (std::vector<ItemBonusEntry const*>* itemBonusEntries = Trinity::Containers::MapGetValuePtr(_itemBonusLists, bonusListId))
134 return std::span(*itemBonusEntries);
135
136 return {};
137}
138
140{
141 if (uint32 const* itemBonusListId = Trinity::Containers::MapGetValuePtr(_itemLevelDeltaToBonusListContainer, delta))
142 return *itemBonusListId;
143
144 return 0;
145}
146
147bool CanApplyBonusTreeToItem(ItemTemplate const* itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const& params)
148{
149 if (ItemBonusTreeEntry const* bonusTree = sItemBonusTreeStore.LookupEntry(itemBonusTreeId))
150 {
151 if (bonusTree->InventoryTypeSlotMask)
152 if (!(1 << itemTemplate->GetInventoryType() & bonusTree->InventoryTypeSlotMask))
153 return false;
154
155 if (bonusTree->Flags & 0x8 && !itemTemplate->HasFlag(ITEM_FLAG2_CASTER_WEAPON))
156 return false;
157 if (bonusTree->Flags & 0x10 && itemTemplate->HasFlag(ITEM_FLAG2_CASTER_WEAPON))
158 return false;
159 if (bonusTree->Flags & 0x20 && !itemTemplate->HasFlag(ITEM_FLAG4_CC_TRINKET))
160 return false;
161 if (bonusTree->Flags & 0x40 && itemTemplate->HasFlag(ITEM_FLAG4_CC_TRINKET))
162 return false;
163
164 if (bonusTree->Flags & 0x4)
165 return true;
166 }
167
168 if (std::set<ItemBonusTreeNodeEntry const*>* bonusTreeNodes = Trinity::Containers::MapGetValuePtr(_itemBonusTrees, itemBonusTreeId))
169 {
170 bool anyNodeMatched = false;
171 for (ItemBonusTreeNodeEntry const* bonusTreeNode : *bonusTreeNodes)
172 {
173 if (bonusTreeNode->MinMythicPlusLevel > 0)
174 continue;
175
176 ItemContext nodeContext = ItemContext(bonusTreeNode->ItemContext);
177 if (nodeContext == ItemContext::NONE || nodeContext == params.Context)
178 {
179 if (anyNodeMatched)
180 return false;
181
182 anyNodeMatched = true;
183 }
184 }
185 }
186
187 return true;
188}
189
191{
192 std::vector<int32> passedTimeEvents; // sorted by date TODO: configure globally
193
194 if (!passedTimeEvents.empty())
195 {
196 int32 selectedLevel = -1;
197 std::ptrdiff_t selectedMilestoneSeason = -1;
198 ChallengeModeItemBonusOverrideEntry const* selectedItemBonusOverride = nullptr;
199 for (auto& [_, itemBonusOverride] : Trinity::Containers::MapEqualRange(_challengeModeItemBonusOverrides, itemBonusTreeId))
200 {
201 if (params.MythicPlusKeystoneLevel && itemBonusOverride->Value > *params.MythicPlusKeystoneLevel)
202 continue;
203
204 if (params.PvpTier && itemBonusOverride->Value > *params.PvpTier)
205 continue;
206
207 if (itemBonusOverride->RequiredTimeEventPassed)
208 {
209 auto itr = std::ranges::find(passedTimeEvents, itemBonusOverride->RequiredTimeEventPassed);
210 if (itr == passedTimeEvents.end())
211 continue; // season not started yet
212
213 std::ptrdiff_t overrideMilestoneSeason = std::ranges::distance(passedTimeEvents.begin(), itr);
214 if (selectedMilestoneSeason > overrideMilestoneSeason)
215 continue; // older season that what was selected
216
217 if (selectedMilestoneSeason == overrideMilestoneSeason)
218 if (selectedLevel > itemBonusOverride->Value)
219 continue; // lower level in current season than what was already found
220
221 selectedMilestoneSeason = overrideMilestoneSeason;
222 }
223 else if (selectedLevel > itemBonusOverride->Value)
224 continue;
225
226 selectedLevel = itemBonusOverride->Value;
227 selectedItemBonusOverride = itemBonusOverride;
228 }
229
230 if (selectedItemBonusOverride && selectedItemBonusOverride->DstItemBonusTreeID)
231 itemBonusTreeId = selectedItemBonusOverride->DstItemBonusTreeID;
232 }
233
234 return itemBonusTreeId;
235}
236
237void ApplyBonusTreeHelper(ItemTemplate const* itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const& params, int32 sequenceLevel, uint32* itemLevelSelectorId, std::vector<int32>* bonusListIDs)
238{
239 uint32 originalItemBonusTreeId = itemBonusTreeId;
240
241 // override bonus tree with season specific values
242 itemBonusTreeId = GetBonusTreeIdOverride(itemBonusTreeId, params);
243
244 if (!CanApplyBonusTreeToItem(itemTemplate, itemBonusTreeId, params))
245 return;
246
247 auto treeItr = _itemBonusTrees.find(itemBonusTreeId);
248 if (treeItr == _itemBonusTrees.end())
249 return;
250
251 for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second)
252 {
253 ItemContext nodeContext = ItemContext(bonusTreeNode->ItemContext);
254 ItemContext requiredContext = nodeContext != ItemContext::Force_to_NONE ? nodeContext : ItemContext::NONE;
255 if (nodeContext != ItemContext::NONE && params.Context != requiredContext)
256 continue;
257
258 if (params.MythicPlusKeystoneLevel)
259 {
260 if (bonusTreeNode->MinMythicPlusLevel && params.MythicPlusKeystoneLevel < bonusTreeNode->MinMythicPlusLevel)
261 continue;
262
263 if (bonusTreeNode->MaxMythicPlusLevel && params.MythicPlusKeystoneLevel > bonusTreeNode->MaxMythicPlusLevel)
264 continue;
265 }
266
267 if (bonusTreeNode->ChildItemBonusTreeID)
268 ApplyBonusTreeHelper(itemTemplate, bonusTreeNode->ChildItemBonusTreeID, params, sequenceLevel, itemLevelSelectorId, bonusListIDs);
269 else if (bonusTreeNode->ChildItemBonusListID)
270 bonusListIDs->push_back(bonusTreeNode->ChildItemBonusListID);
271 else if (bonusTreeNode->ChildItemLevelSelectorID)
272 *itemLevelSelectorId = bonusTreeNode->ChildItemLevelSelectorID;
273 else if (bonusTreeNode->ChildItemBonusListGroupID)
274 {
275 int32 resolvedSequenceLevel = sequenceLevel;
276 switch (originalItemBonusTreeId)
277 {
278 case 4001:
279 resolvedSequenceLevel = 1;
280 break;
281 case 4079:
282 if (params.MythicPlusKeystoneLevel)
283 {
284 switch (bonusTreeNode->IblGroupPointsModSetID)
285 {
286 case 2909: // MythicPlus_End_of_Run levels 2-8
287 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62951, *params.MythicPlusKeystoneLevel);
288 break;
289 case 2910: // MythicPlus_End_of_Run levels 9-16
290 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62952, *params.MythicPlusKeystoneLevel);
291 break;
292 case 2911: // MythicPlus_End_of_Run levels 17-20
293 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62954, *params.MythicPlusKeystoneLevel);
294 break;
295 case 3007: // MythicPlus_Jackpot (weekly reward) levels 2-7
296 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64388, *params.MythicPlusKeystoneLevel);
297 break;
298 case 3008: // MythicPlus_Jackpot (weekly reward) levels 8-15
299 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64389, *params.MythicPlusKeystoneLevel);
300 break;
301 case 3009: // MythicPlus_Jackpot (weekly reward) levels 16-20
302 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64395, *params.MythicPlusKeystoneLevel);
303 break;
304 default:
305 break;
306 }
307 }
308 break;
309 case 4125:
310 resolvedSequenceLevel = 2;
311 break;
312 case 4126:
313 resolvedSequenceLevel = 3;
314 break;
315 case 4127:
316 resolvedSequenceLevel = 4;
317 break;
318 case 4128:
319 switch (params.Context)
320 {
324 resolvedSequenceLevel = 2;
325 break;
327 resolvedSequenceLevel = 6;
328 break;
329 default:
330 break;
331 }
332 break;
333 case 4140:
334 switch (params.Context)
335 {
337 resolvedSequenceLevel = 2;
338 break;
340 resolvedSequenceLevel = 4;
341 break;
342 default:
343 break;
344 }
345 break;
346 default:
347 break;
348 }
349
350 for (auto const& [_, bonusListGroupEntry] : Trinity::Containers::MapEqualRange(_itemBonusListGroupEntries, bonusTreeNode->ChildItemBonusListGroupID))
351 {
352 if ((resolvedSequenceLevel > 0 || bonusListGroupEntry->SequenceValue <= 0) && resolvedSequenceLevel != bonusListGroupEntry->SequenceValue)
353 continue;
354
355 *itemLevelSelectorId = bonusListGroupEntry->ItemLevelSelectorID;
356 bonusListIDs->push_back(bonusListGroupEntry->ItemBonusListID);
357 break;
358 }
359 }
360 }
361}
362
363int32 GetAzeriteUnlockBonusList(uint16 azeriteUnlockMappingSetId, uint16 minItemLevel, InventoryType inventoryType)
364{
365 AzeriteUnlockMappingEntry const* selectedAzeriteUnlockMapping = nullptr;
366 for (auto [_, azeriteUnlockMapping] : Trinity::Containers::MapEqualRange(_azeriteUnlockMappings, azeriteUnlockMappingSetId))
367 {
368 if (minItemLevel < azeriteUnlockMapping->ItemLevel)
369 continue;
370
371 if (selectedAzeriteUnlockMapping && selectedAzeriteUnlockMapping->ItemLevel > azeriteUnlockMapping->ItemLevel)
372 continue;
373
374 selectedAzeriteUnlockMapping = azeriteUnlockMapping;
375 }
376
377 if (selectedAzeriteUnlockMapping)
378 {
379 switch (inventoryType)
380 {
381 case INVTYPE_HEAD:
382 return selectedAzeriteUnlockMapping->ItemBonusListHead;
384 return selectedAzeriteUnlockMapping->ItemBonusListShoulders;
385 case INVTYPE_CHEST:
386 case INVTYPE_ROBE:
387 return selectedAzeriteUnlockMapping->ItemBonusListChest;
388 default:
389 break;
390 }
391 }
392
393 return 0;
394}
395
397{
398 std::vector<int32> bonusListIDs;
399
400 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
401 if (!itemTemplate)
402 return bonusListIDs;
403
404 uint32 itemLevelSelectorId = 0;
405
406 for (auto [_, itemBonusTreeId] : Trinity::Containers::MapEqualRange(_itemToBonusTree, itemId))
407 ApplyBonusTreeHelper(itemTemplate, itemBonusTreeId, params, 0, &itemLevelSelectorId, &bonusListIDs);
408
409 if (ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(itemLevelSelectorId))
410 {
411 int16 delta = int16(selector->MinItemLevel) - int16(itemTemplate->GetBaseItemLevel());
412
413 if (uint32 bonus = GetItemBonusListForItemLevelDelta(delta))
414 bonusListIDs.push_back(bonus);
415
416 if (ItemLevelSelectorQualitySetEntry const* selectorQualitySet = sItemLevelSelectorQualitySetStore.LookupEntry(selector->ItemLevelSelectorQualitySetID))
417 {
418 auto itemSelectorQualities = _itemLevelQualitySelectorQualities.find(selector->ItemLevelSelectorQualitySetID);
419 if (itemSelectorQualities != _itemLevelQualitySelectorQualities.end())
420 {
422 if (selector->MinItemLevel >= selectorQualitySet->IlvlEpic)
423 quality = ITEM_QUALITY_EPIC;
424 else if (selector->MinItemLevel >= selectorQualitySet->IlvlRare)
425 quality = ITEM_QUALITY_RARE;
426
427 auto itemSelectorQuality = std::lower_bound(itemSelectorQualities->second.begin(), itemSelectorQualities->second.end(),
428 quality, ItemLevelSelectorQualityEntryComparator{});
429
430 if (itemSelectorQuality != itemSelectorQualities->second.end())
431 bonusListIDs.push_back((*itemSelectorQuality)->QualityItemBonusListID);
432 }
433 }
434
435 if (int32 azeriteUnlockBonusListId = GetAzeriteUnlockBonusList(selector->AzeriteUnlockMappingSet, selector->MinItemLevel, itemTemplate->GetInventoryType()))
436 bonusListIDs.push_back(azeriteUnlockBonusListId);
437 }
438
439 return bonusListIDs;
440}
441
442template<typename Visitor>
443void VisitItemBonusTree(uint32 itemBonusTreeId, Visitor visitor)
444{
445 auto treeItr = _itemBonusTrees.find(itemBonusTreeId);
446 if (treeItr == _itemBonusTrees.end())
447 return;
448
449 for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second)
450 {
451 visitor(bonusTreeNode);
452 if (bonusTreeNode->ChildItemBonusTreeID)
453 VisitItemBonusTree(bonusTreeNode->ChildItemBonusTreeID, visitor);
454 }
455}
456
457std::vector<int32> GetAllBonusListsForTree(uint32 itemBonusTreeId)
458{
459 std::vector<int32> bonusListIDs;
460 VisitItemBonusTree(itemBonusTreeId, [&bonusListIDs](ItemBonusTreeNodeEntry const* bonusTreeNode)
461 {
462 if (bonusTreeNode->ChildItemBonusListID)
463 bonusListIDs.push_back(bonusTreeNode->ChildItemBonusListID);
464 });
465 return bonusListIDs;
466}
467}
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< ItemLevelSelectorEntry > sItemLevelSelectorStore("ItemLevelSelector.db2", &ItemLevelSelectorLoadInfo::Instance)
DB2Storage< ItemBonusTreeEntry > sItemBonusTreeStore("ItemBonusTree.db2", &ItemBonusTreeLoadInfo::Instance)
DB2Storage< ItemBonusEntry > sItemBonusStore("ItemBonus.db2", &ItemBonusLoadInfo::Instance)
DB2Storage< ItemBonusTreeNodeEntry > sItemBonusTreeNodeStore("ItemBonusTreeNode.db2", &ItemBonusTreeNodeLoadInfo::Instance)
DB2Storage< ChallengeModeItemBonusOverrideEntry > sChallengeModeItemBonusOverrideStore("ChallengeModeItemBonusOverride.db2", &ChallengeModeItemBonusOverrideLoadInfo::Instance)
DB2Storage< ItemLevelSelectorQualityEntry > sItemLevelSelectorQualityStore("ItemLevelSelectorQuality.db2", &ItemLevelSelectorQualityLoadInfo::Instance)
DB2Storage< ItemXBonusTreeEntry > sItemXBonusTreeStore("ItemXBonusTree.db2", &ItemXBonusTreeLoadInfo::Instance)
DB2Storage< AzeriteUnlockMappingEntry > sAzeriteUnlockMappingStore("AzeriteUnlockMapping.db2", &AzeriteUnlockMappingLoadInfo::Instance)
DB2Storage< ItemContextPickerEntryEntry > sItemContextPickerEntryStore("ItemContextPickerEntry.db2", &ItemContextPickerEntryLoadInfo::Instance)
DB2Storage< ItemBonusListLevelDeltaEntry > sItemBonusListLevelDeltaStore("ItemBonusListLevelDelta.db2", &ItemBonusListLevelDeltaLoadInfo::Instance)
DB2Storage< ItemBonusListGroupEntryEntry > sItemBonusListGroupEntryStore("ItemBonusListGroupEntry.db2", &ItemBonusListGroupEntryLoadInfo::Instance)
DB2Storage< ItemLevelSelectorQualitySetEntry > sItemLevelSelectorQualitySetStore("ItemLevelSelectorQualitySet.db2", &ItemLevelSelectorQualitySetLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:557
ItemContext
Definition: DBCEnums.h:1129
int16_t int16
Definition: Define.h:145
int32_t int32
Definition: Define.h:144
uint16_t uint16
Definition: Define.h:149
uint32_t uint32
Definition: Define.h:148
std::unordered_set< uint32 > params[2]
Definition: DisableMgr.cpp:50
@ ITEM_FLAG2_CASTER_WEAPON
Definition: ItemTemplate.h:227
@ ITEM_FLAG4_CC_TRINKET
Definition: ItemTemplate.h:315
InventoryType
Definition: ItemTemplate.h:389
@ INVTYPE_HEAD
Definition: ItemTemplate.h:391
@ INVTYPE_ROBE
Definition: ItemTemplate.h:410
@ INVTYPE_SHOULDERS
Definition: ItemTemplate.h:393
@ INVTYPE_CHEST
Definition: ItemTemplate.h:395
#define sObjectMgr
Definition: ObjectMgr.h:1985
ItemQualities
@ ITEM_QUALITY_UNCOMMON
@ ITEM_QUALITY_RARE
@ ITEM_QUALITY_EPIC
static bool IsPlayerMeetingCondition(Player const *player, uint32 conditionId)
UF::UpdateField< UF::PlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_PLAYER > m_playerData
Definition: Player.h:2968
std::vector< int32 > GetBonusListsForItem(uint32 itemId, ItemBonusGenerationParams const &params)
void VisitItemBonusTree(uint32 itemBonusTreeId, Visitor visitor)
ItemContext GetContextForPlayer(MapDifficultyEntry const *mapDifficulty, Player const *player)
int32 GetAzeriteUnlockBonusList(uint16 azeriteUnlockMappingSetId, uint16 minItemLevel, InventoryType inventoryType)
uint32 GetBonusTreeIdOverride(uint32 itemBonusTreeId, ItemBonusGenerationParams const &params)
void ApplyBonusTreeHelper(ItemTemplate const *itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const &params, int32 sequenceLevel, uint32 *itemLevelSelectorId, std::vector< int32 > *bonusListIDs)
std::span< ItemBonusEntry const * > GetItemBonuses(uint32 bonusListId)
bool CanApplyBonusTreeToItem(ItemTemplate const *itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const &params)
std::vector< int32 > GetAllBonusListsForTree(uint32 itemBonusTreeId)
uint32 GetItemBonusListForItemLevelDelta(int16 delta)
auto MapEqualRange(M &map, typename M::key_type const &key)
Definition: IteratorPair.h:60
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition: MapUtils.h:37
uint32 GetBaseItemLevel() const
Definition: ItemTemplate.h:837
InventoryType GetInventoryType() const
Definition: ItemTemplate.h:834
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:919