diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 8 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 34 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/CollectionMgr.cpp | 61 | ||||
-rw-r--r-- | src/server/game/Entities/Player/CollectionMgr.h | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 4 |
8 files changed, 68 insertions, 73 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 5ab19d417db..d1c7fe437a4 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -2038,6 +2038,14 @@ CurrencyContainerEntry const* DB2Manager::GetCurrencyContainerForCurrencyQuantit return nullptr; } +std::pair<float, float> DB2Manager::GetCurveXAxisRange(uint32 curveId) const +{ + if (std::vector<CurvePointEntry const*> const* points = Trinity::Containers::MapGetValuePtr(_curvePoints, curveId)) + return { points->front()->Pos.X, points->back()->Pos.X }; + + return { 0.0f, 0.0f }; +} + enum class CurveInterpolationMode : uint8 { Linear = 0, diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 25715feb226..75f61df4747 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -390,6 +390,7 @@ public: Optional<ContentTuningLevels> GetContentTuningData(uint32 contentTuningId, uint32 replacementConditionMask, bool forItem = false) const; static char const* GetCreatureFamilyPetName(uint32 petfamily, LocaleConstant locale); CurrencyContainerEntry const* GetCurrencyContainerForCurrencyQuantity(uint32 currencyId, int32 quantity) const; + std::pair<float, float> GetCurveXAxisRange(uint32 curveId) const; float GetCurveValueAt(uint32 curveId, float x) const; EmotesTextSoundEntry const* GetTextSoundEmoteFor(uint32 emote, uint8 race, uint8 gender, uint8 class_) const; float EvaluateExpectedStat(ExpectedStatType stat, uint32 level, int32 expansion, uint32 contentTuningId, Classes unitClass) const; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index ac0770a9e82..744dda953cc 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -60,7 +60,7 @@ Item* NewItemOrBag(ItemTemplate const* proto) return new Item(); } -void AddItemsSetItem(Player* player, Item* item) +void AddItemsSetItem(Player* player, Item const* item) { ItemTemplate const* proto = item->GetTemplate(); uint32 setid = proto->GetItemSet(); @@ -79,6 +79,21 @@ void AddItemsSetItem(Player* player, Item* item) if (set->SetFlags & ITEM_SET_FLAG_LEGACY_INACTIVE) return; + // Check player level for heirlooms + if (sDB2Manager.GetHeirloomByItemId(item->GetEntry())) + { + if (item->GetBonus()->PlayerLevelToItemLevelCurveId) + { + uint32 maxLevel = sDB2Manager.GetCurveXAxisRange(item->GetBonus()->PlayerLevelToItemLevelCurveId).second; + + if (Optional<ContentTuningLevels> contentTuning = sDB2Manager.GetContentTuningData(item->GetBonus()->ContentTuningId, player->m_playerData->CtrOptions->ContentTuningConditionMask, true)) + maxLevel = std::min<uint32>(maxLevel, contentTuning->MaxLevel); + + if (player->GetLevel() > maxLevel) + return; + } + } + ItemSetEffect* eff = nullptr; for (size_t x = 0; x < player->ItemSetEff.size(); ++x) @@ -94,7 +109,6 @@ void AddItemsSetItem(Player* player, Item* item) { eff = new ItemSetEffect(); eff->ItemSetID = setid; - eff->EquippedItemCount = 0; size_t x = 0; for (; x < player->ItemSetEff.size(); ++x) @@ -107,14 +121,14 @@ void AddItemsSetItem(Player* player, Item* item) player->ItemSetEff.push_back(eff); } - ++eff->EquippedItemCount; + eff->EquippedItems.insert(item); if (std::vector<ItemSetSpellEntry const*> const* itemSetSpells = sDB2Manager.GetItemSetSpells(setid)) { for (ItemSetSpellEntry const* itemSetSpell : *itemSetSpells) { //not enough for spell - if (itemSetSpell->Threshold > eff->EquippedItemCount) + if (itemSetSpell->Threshold > eff->EquippedItems.size()) continue; if (eff->SetBonuses.count(itemSetSpell)) @@ -135,15 +149,15 @@ void AddItemsSetItem(Player* player, Item* item) } } -void RemoveItemsSetItem(Player* player, ItemTemplate const* proto) +void RemoveItemsSetItem(Player* player, Item const* item) { - uint32 setid = proto->GetItemSet(); + uint32 setid = item->GetTemplate()->GetItemSet(); ItemSetEntry const* set = sItemSetStore.LookupEntry(setid); if (!set) { - TC_LOG_ERROR("sql.sql", "Item set #%u for item #%u not found, mods not removed.", setid, proto->GetId()); + TC_LOG_ERROR("sql.sql", "Item set #%u for item #%u not found, mods not removed.", setid, item->GetEntry()); return; } @@ -162,14 +176,14 @@ void RemoveItemsSetItem(Player* player, ItemTemplate const* proto) if (!eff) return; - --eff->EquippedItemCount; + eff->EquippedItems.erase(item); if (std::vector<ItemSetSpellEntry const*> const* itemSetSpells = sDB2Manager.GetItemSetSpells(setid)) { for (ItemSetSpellEntry const* itemSetSpell : *itemSetSpells) { // enough for spell - if (itemSetSpell->Threshold <= eff->EquippedItemCount) + if (itemSetSpell->Threshold <= eff->EquippedItems.size()) continue; if (!eff->SetBonuses.count(itemSetSpell)) @@ -180,7 +194,7 @@ void RemoveItemsSetItem(Player* player, ItemTemplate const* proto) } } - if (!eff->EquippedItemCount) //all items of a set were removed + if (eff->EquippedItems.empty()) //all items of a set were removed { ASSERT(eff == player->ItemSetEff[setindex]); delete eff; diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 3ee7515ac03..a53a7c0f8b3 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -41,7 +41,7 @@ namespace WorldPackets struct ItemSetEffect { uint32 ItemSetID; - uint32 EquippedItemCount; + std::unordered_set<Item const*> EquippedItems; std::unordered_set<ItemSetSpellEntry const*> SetBonuses; }; diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp index e8b13bbefdc..40675ea8489 100644 --- a/src/server/game/Entities/Player/CollectionMgr.cpp +++ b/src/server/game/Entities/Player/CollectionMgr.cpp @@ -188,14 +188,14 @@ void CollectionMgr::LoadAccountHeirlooms(PreparedQueryResult result) uint32 bonusId = 0; - if (flags & HEIRLOOM_FLAG_BONUS_LEVEL_120) - bonusId = heirloom->UpgradeItemBonusListID[3]; - else if (flags & HEIRLOOM_FLAG_BONUS_LEVEL_110) - bonusId = heirloom->UpgradeItemBonusListID[2]; - else if (flags & HEIRLOOM_FLAG_BONUS_LEVEL_100) - bonusId = heirloom->UpgradeItemBonusListID[1]; - else if (flags & HEIRLOOM_FLAG_BONUS_LEVEL_90) - bonusId = heirloom->UpgradeItemBonusListID[0]; + for (int32 upgradeLevel = std::size(heirloom->UpgradeItemID) - 1; upgradeLevel >= 0; --upgradeLevel) + { + if (flags & (1 << upgradeLevel)) + { + bonusId = heirloom->UpgradeItemBonusListID[upgradeLevel]; + break; + } + } _heirlooms[itemId] = HeirloomData(flags, bonusId); } while (result->NextRow()); @@ -257,25 +257,13 @@ void CollectionMgr::UpgradeHeirloom(uint32 itemId, int32 castItem) uint32 flags = itr->second.flags; uint32 bonusId = 0; - if (heirloom->UpgradeItemID[0] == castItem) - { - flags |= HEIRLOOM_FLAG_BONUS_LEVEL_90; - bonusId = heirloom->UpgradeItemBonusListID[0]; - } - if (heirloom->UpgradeItemID[1] == castItem) - { - flags |= HEIRLOOM_FLAG_BONUS_LEVEL_100; - bonusId = heirloom->UpgradeItemBonusListID[1]; - } - if (heirloom->UpgradeItemID[2] == castItem) + for (size_t upgradeLevel = 0; upgradeLevel < std::size(heirloom->UpgradeItemID); ++upgradeLevel) { - flags |= HEIRLOOM_FLAG_BONUS_LEVEL_110; - bonusId = heirloom->UpgradeItemBonusListID[2]; - } - if (heirloom->UpgradeItemID[3] == castItem) - { - flags |= HEIRLOOM_FLAG_BONUS_LEVEL_120; - bonusId = heirloom->UpgradeItemBonusListID[3]; + if (heirloom->UpgradeItemID[upgradeLevel] == castItem) + { + flags |= 1 << upgradeLevel; + bonusId = heirloom->UpgradeItemBonusListID[upgradeLevel]; + } } for (Item* item : player->GetItemListByEntry(itemId, true)) @@ -350,27 +338,6 @@ void CollectionMgr::CheckHeirloomUpgrades(Item* item) } } -bool CollectionMgr::CanApplyHeirloomXpBonus(uint32 itemId, uint32 level) -{ - if (!sDB2Manager.GetHeirloomByItemId(itemId)) - return false; - - HeirloomContainer::iterator itr = _heirlooms.find(itemId); - if (itr == _heirlooms.end()) - return false; - - if (itr->second.flags & HEIRLOOM_FLAG_BONUS_LEVEL_120) - return level <= 120; - if (itr->second.flags & HEIRLOOM_FLAG_BONUS_LEVEL_110) - return level <= 110; - if (itr->second.flags & HEIRLOOM_FLAG_BONUS_LEVEL_100) - return level <= 100; - if (itr->second.flags & HEIRLOOM_FLAG_BONUS_LEVEL_90) - return level <= 90; - - return level <= 60; -} - void CollectionMgr::LoadMounts() { for (auto const& m : _mounts) diff --git a/src/server/game/Entities/Player/CollectionMgr.h b/src/server/game/Entities/Player/CollectionMgr.h index bd92481fbe1..fbe60792992 100644 --- a/src/server/game/Entities/Player/CollectionMgr.h +++ b/src/server/game/Entities/Player/CollectionMgr.h @@ -34,10 +34,12 @@ struct ItemModifiedAppearanceEntry; enum HeirloomPlayerFlags { HEIRLOOM_FLAG_NONE = 0x00, - HEIRLOOM_FLAG_BONUS_LEVEL_90 = 0x01, - HEIRLOOM_FLAG_BONUS_LEVEL_100 = 0x02, - HEIRLOOM_FLAG_BONUS_LEVEL_110 = 0x04, - HEIRLOOM_FLAG_BONUS_LEVEL_120 = 0x08 + HEIRLOOM_FLAG_UPGRADE_LEVEL_1 = 0x01, + HEIRLOOM_FLAG_UPGRADE_LEVEL_2 = 0x02, + HEIRLOOM_FLAG_UPGRADE_LEVEL_3 = 0x04, + HEIRLOOM_FLAG_UPGRADE_LEVEL_4 = 0x08, + HEIRLOOM_FLAG_UPGRADE_LEVEL_5 = 0x10, + HEIRLOOM_FLAG_UPGRADE_LEVEL_6 = 0x20, }; enum HeirloomItemFlags @@ -109,7 +111,6 @@ public: void CheckHeirloomUpgrades(Item* item); bool UpdateAccountHeirlooms(uint32 itemId, uint32 flags); - bool CanApplyHeirloomXpBonus(uint32 itemId, uint32 level); uint32 GetHeirloomBonus(uint32 itemId) const; HeirloomContainer const& GetAccountHeirlooms() const { return _heirlooms; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d9467d1f67f..9a5018ef9dc 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -8012,11 +8012,6 @@ void Player::ApplyItemEquipSpell(Item* item, bool apply, bool formChange /*= fal if (!spellproto) continue; - if (spellproto->HasAura(SPELL_AURA_MOD_XP_PCT) - && !GetSession()->GetCollectionMgr()->CanApplyHeirloomXpBonus(item->GetEntry(), GetLevel()) - && sDB2Manager.GetHeirloomByItemId(item->GetEntry())) - continue; - if (effectData->ChrSpecializationID && effectData->ChrSpecializationID != GetPrimarySpecialization()) continue; @@ -8553,7 +8548,7 @@ void Player::_RemoveAllItemMods() // item set bonuses not dependent from item broken state if (proto->GetItemSet()) - RemoveItemsSetItem(this, proto); + RemoveItemsSetItem(this, m_items[i]); if (m_items[i]->IsBroken() || !CanUseAttackType(Player::GetAttackBySlot(i, m_items[i]->GetTemplate()->GetInventoryType()))) continue; @@ -8633,6 +8628,15 @@ void Player::_ApplyAllLevelScaleItemMods(bool apply) continue; _ApplyItemMods(m_items[i], i, apply); + + // Update item sets for heirlooms + if (sDB2Manager.GetHeirloomByItemId(m_items[i]->GetEntry()) && m_items[i]->GetTemplate()->GetItemSet()) + { + if (apply) + AddItemsSetItem(this, m_items[i]); + else + RemoveItemsSetItem(this, m_items[i]); + } } } } @@ -12596,7 +12600,7 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update) // item set bonuses applied only at equip and removed at unequip, and still active for broken items ItemTemplate const* pProto = ASSERT_NOTNULL(pItem->GetTemplate()); if (pProto->GetItemSet()) - RemoveItemsSetItem(this, pProto); + RemoveItemsSetItem(this, pItem); _ApplyItemMods(pItem, slot, false, update); @@ -12736,7 +12740,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) { // item set bonuses applied only at equip and removed at unequip, and still active for broken items if (pProto->GetItemSet()) - RemoveItemsSetItem(this, pProto); + RemoveItemsSetItem(this, pItem); _ApplyItemMods(pItem, slot, false); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 19be32d72a1..5c892d33e73 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -3106,8 +3106,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool _usePvpItemLevels; }; -TC_GAME_API void AddItemsSetItem(Player* player, Item* item); -TC_GAME_API void RemoveItemsSetItem(Player* player, ItemTemplate const* proto); +TC_GAME_API void AddItemsSetItem(Player* player, Item const* item); +TC_GAME_API void RemoveItemsSetItem(Player* player, Item const* item); // Transforms a container of customization choices with continuous storage into iterator pair that does not depend on container // and doesn't force implementations in header files |