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<int32, 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 auto evalContext = [](ItemContext currentContext, ItemContext newContext)
77 {
78 if (newContext == ItemContext::NONE)
79 newContext = currentContext;
80 else if (newContext == ItemContext::Force_to_NONE)
81 newContext = ItemContext::NONE;
82 return newContext;
83 };
84
86 if (DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(mapDifficulty->DifficultyID))
87 context = evalContext(context, ItemContext(difficulty->ItemContext));
88
89 context = evalContext(context, ItemContext(mapDifficulty->ItemContext));
90
91 if (mapDifficulty->ItemContextPickerID)
92 {
93 uint32 contentTuningId = sDB2Manager.GetRedirectedContentTuningId(mapDifficulty->ContentTuningID, player->m_playerData->CtrOptions->ContentTuningConditionMask);
94
95 ItemContextPickerEntryEntry const* selectedPickerEntry = nullptr;
96 for (ItemContextPickerEntryEntry const* itemContextPickerEntry : sItemContextPickerEntryStore)
97 {
98 if (itemContextPickerEntry->ItemContextPickerID != uint32(mapDifficulty->ItemContextPickerID))
99 continue;
100
101 if (itemContextPickerEntry->PVal <= 0)
102 continue;
103
104 bool meetsPlayerCondition = false;
105 if (player)
106 if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(itemContextPickerEntry->PlayerConditionID))
107 meetsPlayerCondition = ConditionMgr::IsPlayerMeetingCondition(player, playerCondition);
108
109 if (itemContextPickerEntry->Flags & 0x1)
110 meetsPlayerCondition = !meetsPlayerCondition;
111
112 if (!meetsPlayerCondition)
113 continue;
114
115 if (itemContextPickerEntry->LabelID && !sDB2Manager.HasContentTuningLabel(contentTuningId, itemContextPickerEntry->LabelID))
116 continue;
117
118 if (!selectedPickerEntry || selectedPickerEntry->OrderIndex < itemContextPickerEntry->OrderIndex)
119 selectedPickerEntry = itemContextPickerEntry;
120 }
121
122 if (selectedPickerEntry)
123 context = evalContext(context, ItemContext(selectedPickerEntry->ItemCreationContext));
124 }
125
126 return context;
127}
128
129std::span<ItemBonusEntry const*> GetItemBonuses(uint32 bonusListId)
130{
131 if (std::vector<ItemBonusEntry const*>* itemBonusEntries = Trinity::Containers::MapGetValuePtr(_itemBonusLists, bonusListId))
132 return std::span(*itemBonusEntries);
133
134 return {};
135}
136
138{
139 if (uint32 const* itemBonusListId = Trinity::Containers::MapGetValuePtr(_itemLevelDeltaToBonusListContainer, delta))
140 return *itemBonusListId;
141
142 return 0;
143}
144
145bool CanApplyBonusTreeToItem(ItemTemplate const* itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const& params)
146{
147 if (ItemBonusTreeEntry const* bonusTree = sItemBonusTreeStore.LookupEntry(itemBonusTreeId))
148 {
149 if (bonusTree->InventoryTypeSlotMask)
150 if (!(1 << itemTemplate->GetInventoryType() & bonusTree->InventoryTypeSlotMask))
151 return false;
152
153 if (bonusTree->Flags & 0x8 && !itemTemplate->HasFlag(ITEM_FLAG2_CASTER_WEAPON))
154 return false;
155 if (bonusTree->Flags & 0x10 && itemTemplate->HasFlag(ITEM_FLAG2_CASTER_WEAPON))
156 return false;
157 if (bonusTree->Flags & 0x20 && !itemTemplate->HasFlag(ITEM_FLAG4_CC_TRINKET))
158 return false;
159 if (bonusTree->Flags & 0x40 && itemTemplate->HasFlag(ITEM_FLAG4_CC_TRINKET))
160 return false;
161
162 if (bonusTree->Flags & 0x4)
163 return true;
164 }
165
166 if (std::set<ItemBonusTreeNodeEntry const*>* bonusTreeNodes = Trinity::Containers::MapGetValuePtr(_itemBonusTrees, itemBonusTreeId))
167 {
168 bool anyNodeMatched = false;
169 for (ItemBonusTreeNodeEntry const* bonusTreeNode : *bonusTreeNodes)
170 {
171 if (bonusTreeNode->MinMythicPlusLevel > 0)
172 continue;
173
174 ItemContext nodeContext = ItemContext(bonusTreeNode->ItemContext);
175 if (nodeContext == ItemContext::NONE || nodeContext == params.Context)
176 {
177 if (anyNodeMatched)
178 return false;
179
180 anyNodeMatched = true;
181 }
182 }
183 }
184
185 return true;
186}
187
189{
190 // TODO: configure seasons globally
191 if (MythicPlusSeasonEntry const* mythicPlusSeason = sMythicPlusSeasonStore.LookupEntry(0))
192 {
193 int32 selectedLevel = -1;
194 int32 selectedMilestoneSeason = -1;
195 ChallengeModeItemBonusOverrideEntry const* selectedItemBonusOverride = nullptr;
196 for (auto& [_, itemBonusOverride] : Trinity::Containers::MapEqualRange(_challengeModeItemBonusOverrides, itemBonusTreeId))
197 {
198 if (itemBonusOverride->Type != 0)
199 continue;
200
201 if (itemBonusOverride->Value > params.MythicPlusKeystoneLevel.value_or(-1))
202 continue;
203
204 if (itemBonusOverride->MythicPlusSeasonID)
205 {
206 MythicPlusSeasonEntry const* overrideSeason = sMythicPlusSeasonStore.LookupEntry(itemBonusOverride->MythicPlusSeasonID);
207 if (!overrideSeason)
208 continue;
209
210 if (mythicPlusSeason->MilestoneSeason < overrideSeason->MilestoneSeason)
211 continue;
212
213 if (selectedMilestoneSeason > overrideSeason->MilestoneSeason)
214 continue;
215
216 if (selectedMilestoneSeason == overrideSeason->MilestoneSeason)
217 if (selectedLevel > itemBonusOverride->Value)
218 continue;
219
220 selectedMilestoneSeason = overrideSeason->MilestoneSeason;
221 }
222 else if (selectedLevel > itemBonusOverride->Value)
223 continue;
224
225 selectedLevel = itemBonusOverride->Value;
226 selectedItemBonusOverride = itemBonusOverride;
227 }
228
229 if (selectedItemBonusOverride && selectedItemBonusOverride->DstItemBonusTreeID)
230 itemBonusTreeId = selectedItemBonusOverride->DstItemBonusTreeID;
231 }
232
233 // TODO: configure seasons globally
234 if (PvpSeasonEntry const* pvpSeason = sPvpSeasonStore.LookupEntry(0))
235 {
236 int32 selectedLevel = -1;
237 int32 selectedMilestoneSeason = -1;
238 ChallengeModeItemBonusOverrideEntry const* selectedItemBonusOverride = nullptr;
239 for (auto& [_, itemBonusOverride] : Trinity::Containers::MapEqualRange(_challengeModeItemBonusOverrides, itemBonusTreeId))
240 {
241 if (itemBonusOverride->Type != 1)
242 continue;
243
244 if (itemBonusOverride->Value > params.PvpTier.value_or(-1))
245 continue;
246
247 if (itemBonusOverride->PvPSeasonID)
248 {
249 PvpSeasonEntry const* overrideSeason = sPvpSeasonStore.LookupEntry(itemBonusOverride->PvPSeasonID);
250 if (!overrideSeason)
251 continue;
252
253 if (pvpSeason->MilestoneSeason < overrideSeason->MilestoneSeason)
254 continue;
255
256 if (selectedMilestoneSeason > overrideSeason->MilestoneSeason)
257 continue;
258
259 if (selectedMilestoneSeason == overrideSeason->MilestoneSeason)
260 if (selectedLevel > itemBonusOverride->Value)
261 continue;
262
263 selectedMilestoneSeason = overrideSeason->MilestoneSeason;
264 }
265 else if (selectedLevel > itemBonusOverride->Value)
266 continue;
267
268 selectedLevel = itemBonusOverride->Value;
269 selectedItemBonusOverride = itemBonusOverride;
270 }
271
272 if (selectedItemBonusOverride && selectedItemBonusOverride->DstItemBonusTreeID)
273 itemBonusTreeId = selectedItemBonusOverride->DstItemBonusTreeID;
274 }
275
276 return itemBonusTreeId;
277}
278
279void ApplyBonusTreeHelper(ItemTemplate const* itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const& params, int32 sequenceLevel, uint32* itemLevelSelectorId, std::vector<int32>* bonusListIDs)
280{
281 uint32 originalItemBonusTreeId = itemBonusTreeId;
282
283 // override bonus tree with season specific values
284 itemBonusTreeId = GetBonusTreeIdOverride(itemBonusTreeId, params);
285
286 if (!CanApplyBonusTreeToItem(itemTemplate, itemBonusTreeId, params))
287 return;
288
289 auto treeItr = _itemBonusTrees.find(itemBonusTreeId);
290 if (treeItr == _itemBonusTrees.end())
291 return;
292
293 for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second)
294 {
295 ItemContext nodeContext = ItemContext(bonusTreeNode->ItemContext);
296 ItemContext requiredContext = nodeContext != ItemContext::Force_to_NONE ? nodeContext : ItemContext::NONE;
297 if (nodeContext != ItemContext::NONE && params.Context != requiredContext)
298 continue;
299
300 if (params.MythicPlusKeystoneLevel)
301 {
302 if (bonusTreeNode->MinMythicPlusLevel && params.MythicPlusKeystoneLevel < bonusTreeNode->MinMythicPlusLevel)
303 continue;
304
305 if (bonusTreeNode->MaxMythicPlusLevel && params.MythicPlusKeystoneLevel > bonusTreeNode->MaxMythicPlusLevel)
306 continue;
307 }
308
309 if (bonusTreeNode->ChildItemBonusTreeID)
310 ApplyBonusTreeHelper(itemTemplate, bonusTreeNode->ChildItemBonusTreeID, params, sequenceLevel, itemLevelSelectorId, bonusListIDs);
311 else if (bonusTreeNode->ChildItemBonusListID)
312 bonusListIDs->push_back(bonusTreeNode->ChildItemBonusListID);
313 else if (bonusTreeNode->ChildItemLevelSelectorID)
314 *itemLevelSelectorId = bonusTreeNode->ChildItemLevelSelectorID;
315 else if (bonusTreeNode->ChildItemBonusListGroupID)
316 {
317 int32 resolvedSequenceLevel = sequenceLevel;
318 switch (originalItemBonusTreeId)
319 {
320 case 4001:
321 resolvedSequenceLevel = 1;
322 break;
323 case 4079:
324 if (params.MythicPlusKeystoneLevel)
325 {
326 switch (bonusTreeNode->IblGroupPointsModSetID)
327 {
328 case 2909: // MythicPlus_End_of_Run levels 2-8
329 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62951, *params.MythicPlusKeystoneLevel);
330 break;
331 case 2910: // MythicPlus_End_of_Run levels 9-16
332 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62952, *params.MythicPlusKeystoneLevel);
333 break;
334 case 2911: // MythicPlus_End_of_Run levels 17-20
335 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62954, *params.MythicPlusKeystoneLevel);
336 break;
337 case 3007: // MythicPlus_Jackpot (weekly reward) levels 2-7
338 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64388, *params.MythicPlusKeystoneLevel);
339 break;
340 case 3008: // MythicPlus_Jackpot (weekly reward) levels 8-15
341 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64389, *params.MythicPlusKeystoneLevel);
342 break;
343 case 3009: // MythicPlus_Jackpot (weekly reward) levels 16-20
344 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64395, *params.MythicPlusKeystoneLevel);
345 break;
346 default:
347 break;
348 }
349 }
350 break;
351 case 4125:
352 resolvedSequenceLevel = 2;
353 break;
354 case 4126:
355 resolvedSequenceLevel = 3;
356 break;
357 case 4127:
358 resolvedSequenceLevel = 4;
359 break;
360 case 4128:
361 switch (params.Context)
362 {
366 resolvedSequenceLevel = 2;
367 break;
369 resolvedSequenceLevel = 6;
370 break;
371 default:
372 break;
373 }
374 break;
375 case 4140:
376 switch (params.Context)
377 {
379 resolvedSequenceLevel = 2;
380 break;
382 resolvedSequenceLevel = 4;
383 break;
384 default:
385 break;
386 }
387 break;
388 default:
389 break;
390 }
391
392 for (auto const& [_, bonusListGroupEntry] : Trinity::Containers::MapEqualRange(_itemBonusListGroupEntries, bonusTreeNode->ChildItemBonusListGroupID))
393 {
394 if ((resolvedSequenceLevel > 0 || bonusListGroupEntry->SequenceValue <= 0) && resolvedSequenceLevel != bonusListGroupEntry->SequenceValue)
395 continue;
396
397 *itemLevelSelectorId = bonusListGroupEntry->ItemLevelSelectorID;
398 bonusListIDs->push_back(bonusListGroupEntry->ItemBonusListID);
399 break;
400 }
401 }
402 }
403}
404
405int32 GetAzeriteUnlockBonusList(uint16 azeriteUnlockMappingSetId, uint16 minItemLevel, InventoryType inventoryType)
406{
407 AzeriteUnlockMappingEntry const* selectedAzeriteUnlockMapping = nullptr;
408 for (auto [_, azeriteUnlockMapping] : Trinity::Containers::MapEqualRange(_azeriteUnlockMappings, azeriteUnlockMappingSetId))
409 {
410 if (minItemLevel < azeriteUnlockMapping->ItemLevel)
411 continue;
412
413 if (selectedAzeriteUnlockMapping && selectedAzeriteUnlockMapping->ItemLevel > azeriteUnlockMapping->ItemLevel)
414 continue;
415
416 selectedAzeriteUnlockMapping = azeriteUnlockMapping;
417 }
418
419 if (selectedAzeriteUnlockMapping)
420 {
421 switch (inventoryType)
422 {
423 case INVTYPE_HEAD:
424 return selectedAzeriteUnlockMapping->ItemBonusListHead;
426 return selectedAzeriteUnlockMapping->ItemBonusListShoulders;
427 case INVTYPE_CHEST:
428 case INVTYPE_ROBE:
429 return selectedAzeriteUnlockMapping->ItemBonusListChest;
430 default:
431 break;
432 }
433 }
434
435 return 0;
436}
437
439{
440 std::vector<int32> bonusListIDs;
441
442 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
443 if (!itemTemplate)
444 return bonusListIDs;
445
446 uint32 itemLevelSelectorId = 0;
447
448 for (auto [_, itemBonusTreeId] : Trinity::Containers::MapEqualRange(_itemToBonusTree, itemId))
449 ApplyBonusTreeHelper(itemTemplate, itemBonusTreeId, params, 0, &itemLevelSelectorId, &bonusListIDs);
450
451 if (ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(itemLevelSelectorId))
452 {
453 int16 delta = int16(selector->MinItemLevel) - int16(itemTemplate->GetBaseItemLevel());
454
455 if (uint32 bonus = GetItemBonusListForItemLevelDelta(delta))
456 bonusListIDs.push_back(bonus);
457
458 if (ItemLevelSelectorQualitySetEntry const* selectorQualitySet = sItemLevelSelectorQualitySetStore.LookupEntry(selector->ItemLevelSelectorQualitySetID))
459 {
460 auto itemSelectorQualities = _itemLevelQualitySelectorQualities.find(selector->ItemLevelSelectorQualitySetID);
461 if (itemSelectorQualities != _itemLevelQualitySelectorQualities.end())
462 {
464 if (selector->MinItemLevel >= selectorQualitySet->IlvlEpic)
465 quality = ITEM_QUALITY_EPIC;
466 else if (selector->MinItemLevel >= selectorQualitySet->IlvlRare)
467 quality = ITEM_QUALITY_RARE;
468
469 auto itemSelectorQuality = std::lower_bound(itemSelectorQualities->second.begin(), itemSelectorQualities->second.end(),
470 quality, ItemLevelSelectorQualityEntryComparator{});
471
472 if (itemSelectorQuality != itemSelectorQualities->second.end())
473 bonusListIDs.push_back((*itemSelectorQuality)->QualityItemBonusListID);
474 }
475 }
476
477 if (int32 azeriteUnlockBonusListId = GetAzeriteUnlockBonusList(selector->AzeriteUnlockMappingSet, selector->MinItemLevel, itemTemplate->GetInventoryType()))
478 bonusListIDs.push_back(azeriteUnlockBonusListId);
479 }
480
481 return bonusListIDs;
482}
483
484template<typename Visitor>
485void VisitItemBonusTree(uint32 itemBonusTreeId, Visitor visitor)
486{
487 auto treeItr = _itemBonusTrees.find(itemBonusTreeId);
488 if (treeItr == _itemBonusTrees.end())
489 return;
490
491 for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second)
492 {
493 visitor(bonusTreeNode);
494 if (bonusTreeNode->ChildItemBonusTreeID)
495 VisitItemBonusTree(bonusTreeNode->ChildItemBonusTreeID, visitor);
496 }
497}
498
499std::vector<int32> GetAllBonusListsForTree(uint32 itemBonusTreeId)
500{
501 std::vector<int32> bonusListIDs;
502 VisitItemBonusTree(itemBonusTreeId, [&bonusListIDs](ItemBonusTreeNodeEntry const* bonusTreeNode)
503 {
504 if (bonusTreeNode->ChildItemBonusListID)
505 bonusListIDs.push_back(bonusTreeNode->ChildItemBonusListID);
506 });
507 return bonusListIDs;
508}
509}
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< ItemLevelSelectorEntry > sItemLevelSelectorStore("ItemLevelSelector.db2", &ItemLevelSelectorLoadInfo::Instance)
DB2Storage< ItemBonusTreeEntry > sItemBonusTreeStore("ItemBonusTree.db2", &ItemBonusTreeLoadInfo::Instance)
DB2Storage< PvpSeasonEntry > sPvpSeasonStore("PvpSeason.db2", &PvpSeasonLoadInfo::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< MythicPlusSeasonEntry > sMythicPlusSeasonStore("MythicPlusSeason.db2", &MythicPlusSeasonLoadInfo::Instance)
DB2Storage< ItemBonusListLevelDeltaEntry > sItemBonusListLevelDeltaStore("ItemBonusListLevelDelta.db2", &ItemBonusListLevelDeltaLoadInfo::Instance)
DB2Storage< ItemBonusListGroupEntryEntry > sItemBonusListGroupEntryStore("ItemBonusListGroupEntry.db2", &ItemBonusListGroupEntryLoadInfo::Instance)
DB2Storage< PlayerConditionEntry > sPlayerConditionStore("PlayerCondition.db2", &PlayerConditionLoadInfo::Instance)
DB2Storage< ItemLevelSelectorQualitySetEntry > sItemLevelSelectorQualitySetStore("ItemLevelSelectorQualitySet.db2", &ItemLevelSelectorQualitySetLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:538
ItemContext
Definition: DBCEnums.h:1063
int16_t int16
Definition: Define.h:139
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
std::unordered_set< uint32 > params[2]
Definition: DisableMgr.cpp:50
@ ITEM_FLAG2_CASTER_WEAPON
Definition: ItemTemplate.h:221
@ ITEM_FLAG4_CC_TRINKET
Definition: ItemTemplate.h:309
InventoryType
Definition: ItemTemplate.h:378
@ INVTYPE_HEAD
Definition: ItemTemplate.h:380
@ INVTYPE_ROBE
Definition: ItemTemplate.h:399
@ INVTYPE_SHOULDERS
Definition: ItemTemplate.h:382
@ INVTYPE_CHEST
Definition: ItemTemplate.h:384
#define sObjectMgr
Definition: ObjectMgr.h:1946
ItemQualities
@ ITEM_QUALITY_UNCOMMON
@ ITEM_QUALITY_RARE
@ ITEM_QUALITY_EPIC
static bool IsPlayerMeetingCondition(Player const *player, PlayerConditionEntry const *condition)
UF::UpdateField< UF::PlayerData, 0, TYPEID_PLAYER > m_playerData
Definition: Player.h:2863
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:29
uint32 GetBaseItemLevel() const
Definition: ItemTemplate.h:789
InventoryType GetInventoryType() const
Definition: ItemTemplate.h:786
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:871