aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2021-12-28 20:13:12 +0100
committerShauren <shauren.trinity@gmail.com>2021-12-28 20:13:12 +0100
commit3c12a189e430b1b6e0a452f272860f58b2dca7bd (patch)
treec59709fb0a5b540d98b0cd98125f12c2f2489bc6 /src
parent3c0baab57616733ff0e3b94ceb215f9bd78239ea (diff)
Core/Items: Fixed heirloom items counting for item set bonuses past their max scaling level and implemented new heirloom upgrade levels
Diffstat (limited to 'src')
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp8
-rw-r--r--src/server/game/DataStores/DB2Stores.h1
-rw-r--r--src/server/game/Entities/Item/Item.cpp34
-rw-r--r--src/server/game/Entities/Item/Item.h2
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.cpp61
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.h11
-rw-r--r--src/server/game/Entities/Player/Player.cpp20
-rw-r--r--src/server/game/Entities/Player/Player.h4
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