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 | |
| parent | afcb8ff8e9f621ae85fde8575246832013958fd2 (diff) | |
Core/Items: Fixed generating default bonuses based on context
| -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());          }  | 
