TrinityCore
Loading...
Searching...
No Matches
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<uint32 /*itemCreationContextGroupId*/, std::vector<ItemContext>> _itemContextByGroup;
40std::unordered_map<int16 /*itemLevelDelta*/, uint32 /*itemBonusListId*/> _itemLevelDeltaToBonusListContainer;
41std::unordered_map<uint32 /*itemLevelSelectorQualitySetId*/, ItemLevelSelectorQualities> _itemLevelQualitySelectorQualities;
42std::unordered_map<uint32 /*itemBonusTreeId*/, std::set<ItemBonusTreeNodeEntry const*>> _itemBonusTrees;
43std::unordered_multimap<uint32 /*itemId*/, uint32 /*itemBonusTreeId*/> _itemToBonusTree;
44}
45
46namespace ItemBonusMgr
47{
48void Load()
49{
50 for (AzeriteUnlockMappingEntry const* azeriteUnlockMapping : sAzeriteUnlockMappingStore)
51 _azeriteUnlockMappings.emplace(azeriteUnlockMapping->AzeriteUnlockMappingSetID, azeriteUnlockMapping);
52
53 for (ChallengeModeItemBonusOverrideEntry const* challengeModeItemBonusOverride : sChallengeModeItemBonusOverrideStore)
54 _challengeModeItemBonusOverrides.emplace(challengeModeItemBonusOverride->SrcItemBonusTreeID, challengeModeItemBonusOverride);
55
56 for (ItemBonusEntry const* bonus : sItemBonusStore)
57 _itemBonusLists[bonus->ParentItemBonusListID].push_back(bonus);
58
59 for (ItemBonusListGroupEntryEntry const* bonusListGroupEntry : sItemBonusListGroupEntryStore)
60 _itemBonusListGroupEntries.emplace(bonusListGroupEntry->ItemBonusListGroupID, bonusListGroupEntry);
61
62 for (ItemBonusListLevelDeltaEntry const* itemBonusListLevelDelta : sItemBonusListLevelDeltaStore)
63 _itemLevelDeltaToBonusListContainer[itemBonusListLevelDelta->ItemLevelDelta] = itemBonusListLevelDelta->ID;
64
65 for (ItemCreationContextEntry const* itemCreationContext : sItemCreationContextStore)
66 _itemContextByGroup[itemCreationContext->ItemCreationContextGroupID].push_back(ItemContext(itemCreationContext->ItemContext));
67
68 for (ItemLevelSelectorQualityEntry const* itemLevelSelectorQuality : sItemLevelSelectorQualityStore)
69 _itemLevelQualitySelectorQualities[itemLevelSelectorQuality->ParentILSQualitySetID].insert(itemLevelSelectorQuality);
70
71 for (ItemBonusTreeNodeEntry const* bonusTreeNode : sItemBonusTreeNodeStore)
72 _itemBonusTrees[bonusTreeNode->ParentItemBonusTreeID].insert(bonusTreeNode);
73
74 for (ItemXBonusTreeEntry const* itemBonusTreeAssignment : sItemXBonusTreeStore)
75 _itemToBonusTree.insert({ itemBonusTreeAssignment->ItemID, itemBonusTreeAssignment->ItemBonusTreeID });
76}
77
78ItemContext GetContextForPlayer(MapDifficultyEntry const* mapDifficulty, Player const* player)
79{
80 if (!mapDifficulty)
81 return ItemContext::NONE;
82
83 auto evalContext = [](ItemContext currentContext, ItemContext newContext)
84 {
85 if (newContext == ItemContext::NONE)
86 newContext = currentContext;
87 else if (newContext == ItemContext::Force_to_NONE)
88 newContext = ItemContext::NONE;
89 return newContext;
90 };
91
93 if (DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(mapDifficulty->DifficultyID))
94 context = evalContext(context, ItemContext(difficulty->ItemContext));
95
96 context = evalContext(context, ItemContext(mapDifficulty->ItemContext));
97
98 if (mapDifficulty->ItemContextPickerID)
99 {
100 uint32 contentTuningId = sDB2Manager.GetRedirectedContentTuningId(mapDifficulty->ContentTuningID, player->m_playerData->CtrOptions->ConditionalFlags);
101
102 ItemContextPickerEntryEntry const* selectedPickerEntry = nullptr;
103 for (ItemContextPickerEntryEntry const* itemContextPickerEntry : sItemContextPickerEntryStore)
104 {
105 if (itemContextPickerEntry->ItemContextPickerID != uint32(mapDifficulty->ItemContextPickerID))
106 continue;
107
108 if (itemContextPickerEntry->PVal <= 0)
109 continue;
110
111 bool meetsPlayerCondition = false;
112 if (player)
113 meetsPlayerCondition = ConditionMgr::IsPlayerMeetingCondition(player, itemContextPickerEntry->PlayerConditionID);
114
115 if (itemContextPickerEntry->Flags & 0x1)
116 meetsPlayerCondition = !meetsPlayerCondition;
117
118 if (!meetsPlayerCondition)
119 continue;
120
121 if (itemContextPickerEntry->LabelID && !sDB2Manager.HasContentTuningLabel(contentTuningId, itemContextPickerEntry->LabelID))
122 continue;
123
124 if (!selectedPickerEntry || selectedPickerEntry->OrderIndex < itemContextPickerEntry->OrderIndex)
125 selectedPickerEntry = itemContextPickerEntry;
126 }
127
128 if (selectedPickerEntry)
129 context = evalContext(context, ItemContext(selectedPickerEntry->ItemCreationContext));
130 }
131
132 return context;
133}
134
135std::span<ItemBonusEntry const*> GetItemBonuses(uint32 bonusListId)
136{
137 if (std::vector<ItemBonusEntry const*>* itemBonusEntries = Trinity::Containers::MapGetValuePtr(_itemBonusLists, bonusListId))
138 return std::span(*itemBonusEntries);
139
140 return {};
141}
142
144{
145 if (uint32 const* itemBonusListId = Trinity::Containers::MapGetValuePtr(_itemLevelDeltaToBonusListContainer, delta))
146 return *itemBonusListId;
147
148 return 0;
149}
150
151bool CanApplyBonusTreeToItem(ItemTemplate const* itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const& params)
152{
153 if (ItemBonusTreeEntry const* bonusTree = sItemBonusTreeStore.LookupEntry(itemBonusTreeId))
154 {
155 if (bonusTree->InventoryTypeSlotMask)
156 if (!(1 << itemTemplate->GetInventoryType() & bonusTree->InventoryTypeSlotMask))
157 return false;
158
159 if (bonusTree->Flags & 0x8 && !itemTemplate->HasFlag(ITEM_FLAG2_CASTER_WEAPON))
160 return false;
161 if (bonusTree->Flags & 0x10 && itemTemplate->HasFlag(ITEM_FLAG2_CASTER_WEAPON))
162 return false;
163 if (bonusTree->Flags & 0x20 && !itemTemplate->HasFlag(ITEM_FLAG4_CC_TRINKET))
164 return false;
165 if (bonusTree->Flags & 0x40 && itemTemplate->HasFlag(ITEM_FLAG4_CC_TRINKET))
166 return false;
167
168 if (bonusTree->Flags & 0x4)
169 return true;
170 }
171
172 if (std::set<ItemBonusTreeNodeEntry const*>* bonusTreeNodes = Trinity::Containers::MapGetValuePtr(_itemBonusTrees, itemBonusTreeId))
173 {
174 bool anyNodeMatched = false;
175 for (ItemBonusTreeNodeEntry const* bonusTreeNode : *bonusTreeNodes)
176 {
177 if (bonusTreeNode->MinMythicPlusLevel > 0)
178 continue;
179
180 ItemContext nodeContext = ItemContext(bonusTreeNode->ItemContext);
181 if (nodeContext == ItemContext::NONE || nodeContext == params.Context)
182 {
183 if (anyNodeMatched)
184 return false;
185
186 anyNodeMatched = true;
187 }
188 }
189 }
190
191 return true;
192}
193
195{
196 std::vector<int32> passedTimeEvents; // sorted by date TODO: configure globally
197
198 if (!passedTimeEvents.empty())
199 {
200 int32 selectedLevel = -1;
201 std::ptrdiff_t selectedMilestoneSeason = -1;
202 ChallengeModeItemBonusOverrideEntry const* selectedItemBonusOverride = nullptr;
203 for (auto& [_, itemBonusOverride] : Trinity::Containers::MapEqualRange(_challengeModeItemBonusOverrides, itemBonusTreeId))
204 {
205 if (params.MythicPlusKeystoneLevel && itemBonusOverride->Value > *params.MythicPlusKeystoneLevel)
206 continue;
207
208 if (params.PvpTier && itemBonusOverride->Value > *params.PvpTier)
209 continue;
210
211 if (itemBonusOverride->RequiredTimeEventPassed)
212 {
213 auto itr = std::ranges::find(passedTimeEvents, itemBonusOverride->RequiredTimeEventPassed);
214 if (itr == passedTimeEvents.end())
215 continue; // season not started yet
216
217 std::ptrdiff_t overrideMilestoneSeason = std::ranges::distance(passedTimeEvents.begin(), itr);
218 if (selectedMilestoneSeason > overrideMilestoneSeason)
219 continue; // older season that what was selected
220
221 if (selectedMilestoneSeason == overrideMilestoneSeason)
222 if (selectedLevel > itemBonusOverride->Value)
223 continue; // lower level in current season than what was already found
224
225 selectedMilestoneSeason = overrideMilestoneSeason;
226 }
227 else if (selectedLevel > itemBonusOverride->Value)
228 continue;
229
230 selectedLevel = itemBonusOverride->Value;
231 selectedItemBonusOverride = itemBonusOverride;
232 }
233
234 if (selectedItemBonusOverride && selectedItemBonusOverride->DstItemBonusTreeID)
235 itemBonusTreeId = selectedItemBonusOverride->DstItemBonusTreeID;
236 }
237
238 return itemBonusTreeId;
239}
240
241void ApplyBonusTreeHelper(ItemTemplate const* itemTemplate, uint32 itemBonusTreeId, ItemBonusGenerationParams const& params, int32 sequenceLevel, uint32* itemLevelSelectorId, std::vector<int32>* bonusListIDs)
242{
243 uint32 originalItemBonusTreeId = itemBonusTreeId;
244
245 // override bonus tree with season specific values
246 itemBonusTreeId = GetBonusTreeIdOverride(itemBonusTreeId, params);
247
248 if (!CanApplyBonusTreeToItem(itemTemplate, itemBonusTreeId, params))
249 return;
250
251 auto treeItr = _itemBonusTrees.find(itemBonusTreeId);
252 if (treeItr == _itemBonusTrees.end())
253 return;
254
255 for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second)
256 {
257 ItemContext nodeContext = ItemContext(bonusTreeNode->ItemContext);
258 ItemContext requiredContext = nodeContext != ItemContext::Force_to_NONE ? nodeContext : ItemContext::NONE;
259 if (nodeContext != ItemContext::NONE && params.Context != requiredContext)
260 {
261 if (!(bonusTreeNode->Flags & 0x1))
262 continue;
263 }
264 else if (bonusTreeNode->Flags & 0x1 && nodeContext != ItemContext::NONE)
265 continue;
266
267 if (bonusTreeNode->ItemCreationContextGroupID)
268 {
269 bool hasContextFromGroup = false;
270 if (std::vector<ItemContext> const* itemContexts = Trinity::Containers::MapGetValuePtr(_itemContextByGroup, bonusTreeNode->ItemCreationContextGroupID))
271 hasContextFromGroup = advstd::ranges::contains(*itemContexts, params.Context);
272
273 if (!!(bonusTreeNode->Flags & 0x1) == hasContextFromGroup)
274 continue;
275 }
276
277 if (params.MythicPlusKeystoneLevel)
278 {
279 if (bonusTreeNode->MinMythicPlusLevel && params.MythicPlusKeystoneLevel < bonusTreeNode->MinMythicPlusLevel)
280 continue;
281
282 if (bonusTreeNode->MaxMythicPlusLevel && params.MythicPlusKeystoneLevel > bonusTreeNode->MaxMythicPlusLevel)
283 continue;
284 }
285
286 if (bonusTreeNode->ChildItemBonusTreeID)
287 ApplyBonusTreeHelper(itemTemplate, bonusTreeNode->ChildItemBonusTreeID, params, sequenceLevel, itemLevelSelectorId, bonusListIDs);
288 else if (bonusTreeNode->ChildItemBonusListID)
289 bonusListIDs->push_back(bonusTreeNode->ChildItemBonusListID);
290 else if (bonusTreeNode->ChildItemLevelSelectorID)
291 *itemLevelSelectorId = bonusTreeNode->ChildItemLevelSelectorID;
292 else if (bonusTreeNode->ChildItemBonusListGroupID)
293 {
294 int32 resolvedSequenceLevel = sequenceLevel;
295 switch (originalItemBonusTreeId)
296 {
297 case 4001:
298 resolvedSequenceLevel = 1;
299 break;
300 case 4079:
301 if (params.MythicPlusKeystoneLevel)
302 {
303 switch (bonusTreeNode->IblGroupPointsModSetID)
304 {
305 case 2909: // MythicPlus_End_of_Run levels 2-8
306 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62951, *params.MythicPlusKeystoneLevel);
307 break;
308 case 2910: // MythicPlus_End_of_Run levels 9-16
309 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62952, *params.MythicPlusKeystoneLevel);
310 break;
311 case 2911: // MythicPlus_End_of_Run levels 17-20
312 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(62954, *params.MythicPlusKeystoneLevel);
313 break;
314 case 3007: // MythicPlus_Jackpot (weekly reward) levels 2-7
315 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64388, *params.MythicPlusKeystoneLevel);
316 break;
317 case 3008: // MythicPlus_Jackpot (weekly reward) levels 8-15
318 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64389, *params.MythicPlusKeystoneLevel);
319 break;
320 case 3009: // MythicPlus_Jackpot (weekly reward) levels 16-20
321 resolvedSequenceLevel = sDB2Manager.GetCurveValueAt(64395, *params.MythicPlusKeystoneLevel);
322 break;
323 default:
324 break;
325 }
326 }
327 break;
328 case 4125:
329 resolvedSequenceLevel = 2;
330 break;
331 case 4126:
332 resolvedSequenceLevel = 3;
333 break;
334 case 4127:
335 resolvedSequenceLevel = 4;
336 break;
337 case 4128:
338 switch (params.Context)
339 {
343 resolvedSequenceLevel = 2;
344 break;
346 resolvedSequenceLevel = 6;
347 break;
348 default:
349 break;
350 }
351 break;
352 case 4140:
353 switch (params.Context)
354 {
356 resolvedSequenceLevel = 2;
357 break;
359 resolvedSequenceLevel = 4;
360 break;
361 default:
362 break;
363 }
364 break;
365 default:
366 break;
367 }
368
369 for (auto const& [_, bonusListGroupEntry] : Trinity::Containers::MapEqualRange(_itemBonusListGroupEntries, bonusTreeNode->ChildItemBonusListGroupID))
370 {
371 if ((resolvedSequenceLevel > 0 || bonusListGroupEntry->SequenceValue <= 0) && resolvedSequenceLevel != bonusListGroupEntry->SequenceValue)
372 continue;
373
374 *itemLevelSelectorId = bonusListGroupEntry->ItemLevelSelectorID;
375 bonusListIDs->push_back(bonusListGroupEntry->ItemBonusListID);
376 break;
377 }
378 }
379 }
380}
381
382int32 GetAzeriteUnlockBonusList(uint16 azeriteUnlockMappingSetId, uint16 minItemLevel, InventoryType inventoryType)
383{
384 AzeriteUnlockMappingEntry const* selectedAzeriteUnlockMapping = nullptr;
385 for (auto [_, azeriteUnlockMapping] : Trinity::Containers::MapEqualRange(_azeriteUnlockMappings, azeriteUnlockMappingSetId))
386 {
387 if (minItemLevel < azeriteUnlockMapping->ItemLevel)
388 continue;
389
390 if (selectedAzeriteUnlockMapping && selectedAzeriteUnlockMapping->ItemLevel > azeriteUnlockMapping->ItemLevel)
391 continue;
392
393 selectedAzeriteUnlockMapping = azeriteUnlockMapping;
394 }
395
396 if (selectedAzeriteUnlockMapping)
397 {
398 switch (inventoryType)
399 {
400 case INVTYPE_HEAD:
401 return selectedAzeriteUnlockMapping->ItemBonusListHead;
403 return selectedAzeriteUnlockMapping->ItemBonusListShoulders;
404 case INVTYPE_CHEST:
405 case INVTYPE_ROBE:
406 return selectedAzeriteUnlockMapping->ItemBonusListChest;
407 default:
408 break;
409 }
410 }
411
412 return 0;
413}
414
416{
417 std::vector<int32> bonusListIDs;
418
419 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
420 if (!itemTemplate)
421 return bonusListIDs;
422
423 uint32 itemLevelSelectorId = 0;
424
425 for (auto [_, itemBonusTreeId] : Trinity::Containers::MapEqualRange(_itemToBonusTree, itemId))
426 ApplyBonusTreeHelper(itemTemplate, itemBonusTreeId, params, 0, &itemLevelSelectorId, &bonusListIDs);
427
428 if (ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(itemLevelSelectorId))
429 {
430 int16 delta = int16(selector->MinItemLevel) - int16(itemTemplate->GetBaseItemLevel());
431
432 if (uint32 bonus = GetItemBonusListForItemLevelDelta(delta))
433 bonusListIDs.push_back(bonus);
434
435 if (ItemLevelSelectorQualitySetEntry const* selectorQualitySet = sItemLevelSelectorQualitySetStore.LookupEntry(selector->ItemLevelSelectorQualitySetID))
436 {
437 auto itemSelectorQualities = _itemLevelQualitySelectorQualities.find(selector->ItemLevelSelectorQualitySetID);
438 if (itemSelectorQualities != _itemLevelQualitySelectorQualities.end())
439 {
441 if (selector->MinItemLevel >= selectorQualitySet->IlvlEpic)
442 quality = ITEM_QUALITY_EPIC;
443 else if (selector->MinItemLevel >= selectorQualitySet->IlvlRare)
444 quality = ITEM_QUALITY_RARE;
445
446 auto itemSelectorQuality = std::lower_bound(itemSelectorQualities->second.begin(), itemSelectorQualities->second.end(),
447 quality, ItemLevelSelectorQualityEntryComparator{});
448
449 if (itemSelectorQuality != itemSelectorQualities->second.end())
450 bonusListIDs.push_back((*itemSelectorQuality)->QualityItemBonusListID);
451 }
452 }
453
454 if (int32 azeriteUnlockBonusListId = GetAzeriteUnlockBonusList(selector->AzeriteUnlockMappingSet, selector->MinItemLevel, itemTemplate->GetInventoryType()))
455 bonusListIDs.push_back(azeriteUnlockBonusListId);
456 }
457
458 return bonusListIDs;
459}
460
461template<typename Visitor>
462void VisitItemBonusTree(uint32 itemBonusTreeId, Visitor visitor)
463{
464 auto treeItr = _itemBonusTrees.find(itemBonusTreeId);
465 if (treeItr == _itemBonusTrees.end())
466 return;
467
468 for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second)
469 {
470 visitor(bonusTreeNode);
471 if (bonusTreeNode->ChildItemBonusTreeID)
472 VisitItemBonusTree(bonusTreeNode->ChildItemBonusTreeID, visitor);
473 }
474}
475
476std::vector<int32> GetAllBonusListsForTree(uint32 itemBonusTreeId)
477{
478 std::vector<int32> bonusListIDs;
479 VisitItemBonusTree(itemBonusTreeId, [&bonusListIDs](ItemBonusTreeNodeEntry const* bonusTreeNode)
480 {
481 if (bonusTreeNode->ChildItemBonusListID)
482 bonusListIDs.push_back(bonusTreeNode->ChildItemBonusListID);
483 });
484 return bonusListIDs;
485}
486}
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< ItemCreationContextEntry > sItemCreationContextStore("ItemCreationContext.db2", &ItemCreationContextLoadInfo::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:569
ItemContext
Definition DBCEnums.h:1315
int16_t int16
Definition Define.h:151
int32_t int32
Definition Define.h:150
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
std::unordered_set< uint32 > params[2]
@ ITEM_FLAG2_CASTER_WEAPON
@ ITEM_FLAG4_CC_TRINKET
InventoryType
@ INVTYPE_HEAD
@ INVTYPE_ROBE
@ INVTYPE_SHOULDERS
@ INVTYPE_CHEST
#define sObjectMgr
Definition ObjectMgr.h:1885
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:3061
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)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition MapUtils.h:37
struct advstd::ranges::Contains contains
uint32 GetBaseItemLevel() const
InventoryType GetInventoryType() const
bool HasFlag(ItemFlags flag) const