mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Items: Fixed heirloom items counting for item set bonuses past their max scaling level and implemented new heirloom upgrade levels
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace WorldPackets
|
||||
struct ItemSetEffect
|
||||
{
|
||||
uint32 ItemSetID;
|
||||
uint32 EquippedItemCount;
|
||||
std::unordered_set<Item const*> EquippedItems;
|
||||
std::unordered_set<ItemSetSpellEntry const*> SetBonuses;
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
for (size_t upgradeLevel = 0; upgradeLevel < std::size(heirloom->UpgradeItemID); ++upgradeLevel)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user