diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-06-07 12:38:38 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-06-07 12:38:38 +0200 |
commit | e5a6552abcbf0f179aebb67751527242968522f7 (patch) | |
tree | 1beaca8d2b86670941655398130fff6e72d5f4a0 /src | |
parent | afcb8ff8e9f621ae85fde8575246832013958fd2 (diff) |
Core/Items: Fixed generating default bonuses based on context
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 181 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 1 | ||||
-rw-r--r-- | src/server/game/Loot/Loot.cpp | 2 |
4 files changed, 99 insertions, 87 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 369de7d0b0f..4cdd36fbefa 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -973,14 +973,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) _itemLevelDeltaToBonusListContainer[itemBonusListLevelDelta->ItemLevelDelta] = itemBonusListLevelDelta->ID; for (ItemBonusTreeNodeEntry const* bonusTreeNode : sItemBonusTreeNodeStore) - { - uint32 bonusTreeId = bonusTreeNode->ParentItemBonusTreeID; - while (bonusTreeNode) - { - _itemBonusTrees[bonusTreeId].insert(bonusTreeNode); - bonusTreeNode = sItemBonusTreeNodeStore.LookupEntry(bonusTreeNode->ChildItemBonusTreeID); - } - } + _itemBonusTrees[bonusTreeNode->ParentItemBonusTreeID].insert(bonusTreeNode); for (ItemChildEquipmentEntry const* itemChildEquipment : sItemChildEquipmentStore) { @@ -2035,26 +2028,21 @@ uint32 DB2Manager::GetItemBonusListForItemLevelDelta(int16 delta) const } template<typename Visitor> -void VisitItemBonusTree(uint32 itemId, Visitor visitor) +void VisitItemBonusTree(uint32 itemBonusTreeId, bool visitChildren, Visitor visitor) { - auto itemIdRange = _itemToBonusTree.equal_range(itemId); - if (itemIdRange.first == itemIdRange.second) + auto treeItr = _itemBonusTrees.find(itemBonusTreeId); + if (treeItr == _itemBonusTrees.end()) return; - for (auto itemTreeItr = itemIdRange.first; itemTreeItr != itemIdRange.second; ++itemTreeItr) + for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second) { - auto treeItr = _itemBonusTrees.find(itemTreeItr->second); - if (treeItr == _itemBonusTrees.end()) - continue; - - for (ItemBonusTreeNodeEntry const* bonusTreeNode : treeItr->second) - { - visitor(bonusTreeNode); - } + visitor(bonusTreeNode); + if (visitChildren && bonusTreeNode->ChildItemBonusTreeID) + VisitItemBonusTree(bonusTreeNode->ChildItemBonusTreeID, true, visitor); } } -std::set<uint32> DB2Manager::GetItemBonusTree(uint32 itemId, ItemContext itemContext) const +std::set<uint32> DB2Manager::GetDefaultItemBonusTree(uint32 itemId, ItemContext itemContext) const { std::set<uint32> bonusListIDs; @@ -2062,98 +2050,121 @@ std::set<uint32> DB2Manager::GetItemBonusTree(uint32 itemId, ItemContext itemCon if (!proto) return bonusListIDs; - VisitItemBonusTree(itemId, [this, proto, itemContext, &bonusListIDs](ItemBonusTreeNodeEntry const* bonusTreeNode) - { - if (ItemContext(bonusTreeNode->ItemContext) != itemContext) - return; + auto itemIdRange = _itemToBonusTree.equal_range(itemId); + if (itemIdRange.first == itemIdRange.second) + return bonusListIDs; - if (bonusTreeNode->ChildItemBonusListID) + uint16 itemLevelSelectorId = 0; + for (auto itemTreeItr = itemIdRange.first; itemTreeItr != itemIdRange.second; ++itemTreeItr) + { + uint32 matchingNodes = 0; + VisitItemBonusTree(itemTreeItr->second, false, [itemContext, &matchingNodes](ItemBonusTreeNodeEntry const* bonusTreeNode) { - bonusListIDs.insert(bonusTreeNode->ChildItemBonusListID); - } - else if (bonusTreeNode->ChildItemLevelSelectorID) + if (ItemContext(bonusTreeNode->ItemContext) == ItemContext::NONE || itemContext == ItemContext(bonusTreeNode->ItemContext)) + ++matchingNodes; + }); + + if (matchingNodes != 1) + continue; + + VisitItemBonusTree(itemTreeItr->second, true, [itemContext, &bonusListIDs, &itemLevelSelectorId](ItemBonusTreeNodeEntry const* bonusTreeNode) { - ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(bonusTreeNode->ChildItemLevelSelectorID); - if (!selector) + ItemContext requiredContext = ItemContext(bonusTreeNode->ItemContext) != ItemContext::Force_to_NONE ? ItemContext(bonusTreeNode->ItemContext) : ItemContext::NONE; + if (ItemContext(bonusTreeNode->ItemContext) != ItemContext::NONE && itemContext != requiredContext) return; - int16 delta = int16(selector->MinItemLevel) - proto->ItemLevel; + if (bonusTreeNode->ChildItemBonusListID) + { + bonusListIDs.insert(bonusTreeNode->ChildItemBonusListID); + } + else if (bonusTreeNode->ChildItemLevelSelectorID) + { + itemLevelSelectorId = bonusTreeNode->ChildItemLevelSelectorID; + } + }); + } - if (uint32 bonus = GetItemBonusListForItemLevelDelta(delta)) - bonusListIDs.insert(bonus); + if (ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(itemLevelSelectorId)) + { + int16 delta = int16(selector->MinItemLevel) - proto->ItemLevel; - if (ItemLevelSelectorQualitySetEntry const* selectorQualitySet = sItemLevelSelectorQualitySetStore.LookupEntry(selector->ItemLevelSelectorQualitySetID)) + if (uint32 bonus = GetItemBonusListForItemLevelDelta(delta)) + bonusListIDs.insert(bonus); + + if (ItemLevelSelectorQualitySetEntry const* selectorQualitySet = sItemLevelSelectorQualitySetStore.LookupEntry(selector->ItemLevelSelectorQualitySetID)) + { + auto itemSelectorQualities = _itemLevelQualitySelectorQualities.find(selector->ItemLevelSelectorQualitySetID); + if (itemSelectorQualities != _itemLevelQualitySelectorQualities.end()) { - auto itemSelectorQualities = _itemLevelQualitySelectorQualities.find(selector->ItemLevelSelectorQualitySetID); - if (itemSelectorQualities != _itemLevelQualitySelectorQualities.end()) - { - ItemQualities quality = ITEM_QUALITY_UNCOMMON; - if (selector->MinItemLevel >= selectorQualitySet->IlvlEpic) - quality = ITEM_QUALITY_EPIC; - else if (selector->MinItemLevel >= selectorQualitySet->IlvlRare) - quality = ITEM_QUALITY_RARE; + ItemQualities quality = ITEM_QUALITY_UNCOMMON; + if (selector->MinItemLevel >= selectorQualitySet->IlvlEpic) + quality = ITEM_QUALITY_EPIC; + else if (selector->MinItemLevel >= selectorQualitySet->IlvlRare) + quality = ITEM_QUALITY_RARE; - auto itemSelectorQuality = std::lower_bound(itemSelectorQualities->second.begin(), itemSelectorQualities->second.end(), - quality, ItemLevelSelectorQualityEntryComparator{}); + auto itemSelectorQuality = std::lower_bound(itemSelectorQualities->second.begin(), itemSelectorQualities->second.end(), + quality, ItemLevelSelectorQualityEntryComparator{}); - if (itemSelectorQuality != itemSelectorQualities->second.end()) - bonusListIDs.insert((*itemSelectorQuality)->QualityItemBonusListID); - } + if (itemSelectorQuality != itemSelectorQualities->second.end()) + bonusListIDs.insert((*itemSelectorQuality)->QualityItemBonusListID); } + } - if (AzeriteUnlockMappingEntry const* azeriteUnlockMapping = Trinity::Containers::MapGetValuePtr(_azeriteUnlockMappings, std::make_pair(proto->ID, itemContext))) + if (AzeriteUnlockMappingEntry const* azeriteUnlockMapping = Trinity::Containers::MapGetValuePtr(_azeriteUnlockMappings, std::make_pair(proto->ID, itemContext))) + { + switch (proto->InventoryType) { - switch (proto->InventoryType) - { - case INVTYPE_HEAD: - bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListHead); - break; - case INVTYPE_SHOULDERS: - bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListShoulders); - break; - case INVTYPE_CHEST: - case INVTYPE_ROBE: - bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListChest); - break; - } + case INVTYPE_HEAD: + bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListHead); + break; + case INVTYPE_SHOULDERS: + bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListShoulders); + break; + case INVTYPE_CHEST: + case INVTYPE_ROBE: + bonusListIDs.insert(azeriteUnlockMapping->ItemBonusListChest); + break; } } - }); + } return bonusListIDs; } void LoadAzeriteEmpoweredItemUnlockMappings(std::unordered_map<int32, std::vector<AzeriteUnlockMappingEntry const*>> const& azeriteUnlockMappingsBySet, uint32 itemId) { - ItemSparseEntry const* proto = sItemSparseStore.LookupEntry(itemId); - if (!proto) + auto itemIdRange = _itemToBonusTree.equal_range(itemId); + if (itemIdRange.first == itemIdRange.second) return; - VisitItemBonusTree(itemId, [&azeriteUnlockMappingsBySet, proto](ItemBonusTreeNodeEntry const* bonusTreeNode) + for (auto itemTreeItr = itemIdRange.first; itemTreeItr != itemIdRange.second; ++itemTreeItr) { - if (!bonusTreeNode->ChildItemBonusListID && bonusTreeNode->ChildItemLevelSelectorID) + VisitItemBonusTree(itemTreeItr->second, true, [&azeriteUnlockMappingsBySet, itemId](ItemBonusTreeNodeEntry const* bonusTreeNode) { - ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(bonusTreeNode->ChildItemLevelSelectorID); - if (!selector) - return; - - if (std::vector<AzeriteUnlockMappingEntry const*> const* azeriteUnlockMappings = Trinity::Containers::MapGetValuePtr(azeriteUnlockMappingsBySet, selector->AzeriteUnlockMappingSet)) + if (!bonusTreeNode->ChildItemBonusListID && bonusTreeNode->ChildItemLevelSelectorID) { - AzeriteUnlockMappingEntry const* selectedAzeriteUnlockMapping = nullptr; - for (AzeriteUnlockMappingEntry const* azeriteUnlockMapping : *azeriteUnlockMappings) - { - if (azeriteUnlockMapping->ItemLevel > selector->MinItemLevel || - (selectedAzeriteUnlockMapping != nullptr && selectedAzeriteUnlockMapping->ItemLevel > azeriteUnlockMapping->ItemLevel)) - continue; + ItemLevelSelectorEntry const* selector = sItemLevelSelectorStore.LookupEntry(bonusTreeNode->ChildItemLevelSelectorID); + if (!selector) + return; - selectedAzeriteUnlockMapping = azeriteUnlockMapping; + if (std::vector<AzeriteUnlockMappingEntry const*> const* azeriteUnlockMappings = Trinity::Containers::MapGetValuePtr(azeriteUnlockMappingsBySet, selector->AzeriteUnlockMappingSet)) + { + AzeriteUnlockMappingEntry const* selectedAzeriteUnlockMapping = nullptr; + for (AzeriteUnlockMappingEntry const* azeriteUnlockMapping : *azeriteUnlockMappings) + { + if (azeriteUnlockMapping->ItemLevel > selector->MinItemLevel || + (selectedAzeriteUnlockMapping != nullptr && selectedAzeriteUnlockMapping->ItemLevel > azeriteUnlockMapping->ItemLevel)) + continue; + + selectedAzeriteUnlockMapping = azeriteUnlockMapping; + } + + if (selectedAzeriteUnlockMapping) + _azeriteUnlockMappings[std::make_pair(itemId, ItemContext(bonusTreeNode->ItemContext))] = selectedAzeriteUnlockMapping; } - - if (selectedAzeriteUnlockMapping) - _azeriteUnlockMappings[std::make_pair(proto->ID, ItemContext(bonusTreeNode->ItemContext))] = selectedAzeriteUnlockMapping; } - } - }); + }); + } } ItemChildEquipmentEntry const* DB2Manager::GetItemChildEquipment(uint32 itemId) const @@ -3053,7 +3064,7 @@ bool ChrClassesXPowerTypesEntryComparator::Compare(ChrClassesXPowerTypesEntry co bool ItemLevelSelectorQualityEntryComparator::Compare(ItemLevelSelectorQualityEntry const* left, ItemLevelSelectorQualityEntry const* right) { - return left->Quality > right->Quality; + return left->Quality < right->Quality; } bool DB2Manager::MountTypeXCapabilityEntryComparator::Compare(MountTypeXCapabilityEntry const* left, MountTypeXCapabilityEntry const* right) diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index a8c3b074336..a578fedbffc 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -303,7 +303,7 @@ public: std::vector<uint32> const* GetGlyphRequiredSpecs(uint32 glyphPropertiesId) const; ItemBonusList const* GetItemBonusList(uint32 bonusListId) const; uint32 GetItemBonusListForItemLevelDelta(int16 delta) const; - std::set<uint32> GetItemBonusTree(uint32 itemId, ItemContext itemContext) const; + std::set<uint32> GetDefaultItemBonusTree(uint32 itemId, ItemContext itemContext) const; ItemChildEquipmentEntry const* GetItemChildEquipment(uint32 itemId) const; ItemClassEntry const* GetItemClassByOldEnum(uint32 itemClass) const; bool HasItemCurrencyCost(uint32 itemId) const; diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 0c5e35af70f..92dcaa236bc 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -1081,6 +1081,7 @@ enum class ItemContext : uint8 World_Quest_13 = 55, PVP_Ranked_Jackpot = 56, Tournament_Realm = 57, + Relinquished = 58, }; enum ItemLimitCategoryMode diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp index 9e4dc90cab9..e54a007f962 100644 --- a/src/server/game/Loot/Loot.cpp +++ b/src/server/game/Loot/Loot.cpp @@ -274,7 +274,7 @@ void Loot::AddItem(LootStoreItem const& item) generatedLoot.count = std::min(count, proto->GetMaxStackSize()); if (_itemContext != ItemContext::NONE) { - std::set<uint32> bonusListIDs = sDB2Manager.GetItemBonusTree(generatedLoot.itemid, _itemContext); + std::set<uint32> bonusListIDs = sDB2Manager.GetDefaultItemBonusTree(generatedLoot.itemid, _itemContext); generatedLoot.BonusListIDs.insert(generatedLoot.BonusListIDs.end(), bonusListIDs.begin(), bonusListIDs.end()); } |