diff options
Diffstat (limited to 'src/server/game')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 21 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 71 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 12 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 51 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 2 |
8 files changed, 143 insertions, 35 deletions
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index f5bef9577af..c670211c7e0 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -153,7 +153,6 @@ TC_GAME_API extern DB2Storage<ItemDamageTwoHandEntry> sItemDamageT TC_GAME_API extern DB2Storage<ItemDamageTwoHandCasterEntry> sItemDamageTwoHandCasterStore; TC_GAME_API extern DB2Storage<ItemDisenchantLootEntry> sItemDisenchantLootStore; TC_GAME_API extern DB2Storage<ItemEffectEntry> sItemEffectStore; -TC_GAME_API extern DB2Storage<ItemNameDescriptionEntry> sItemNameDescriptionStore; TC_GAME_API extern DB2Storage<ItemEntry> sItemStore; TC_GAME_API extern DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore; TC_GAME_API extern DB2Storage<ItemLevelSelectorEntry> sItemLevelSelectorStore; @@ -162,6 +161,7 @@ TC_GAME_API extern DB2Storage<ItemLevelSelectorQualitySetEntry> sItemLevelSe TC_GAME_API extern DB2Storage<ItemLimitCategoryEntry> sItemLimitCategoryStore; TC_GAME_API extern DB2Storage<ItemModifiedAppearanceEntry> sItemModifiedAppearanceStore; TC_GAME_API extern DB2Storage<ItemModifiedAppearanceExtraEntry> sItemModifiedAppearanceExtraStore; +TC_GAME_API extern DB2Storage<ItemNameDescriptionEntry> sItemNameDescriptionStore; TC_GAME_API extern DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore; TC_GAME_API extern DB2Storage<ItemSearchNameEntry> sItemSearchNameStore; TC_GAME_API extern DB2Storage<ItemSetEntry> sItemSetStore; diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index dc68d9fc594..00ad0d2a5d2 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -1206,18 +1206,29 @@ enum ItemBonusType ITEM_BONUS_RELIC_TYPE = 17, ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL = 18, ITEM_BONUS_AZERITE_TIER_UNLOCK_SET = 19, - ITEM_BONUS_SCRAPPING_LOOT_ID = 20, + ITEM_BONUS_SCRAPPING_LOOT_ID = 20, /*NYI*/ ITEM_BONUS_OVERRIDE_CAN_DISENCHANT = 21, ITEM_BONUS_OVERRIDE_CAN_SCRAP = 22, ITEM_BONUS_ITEM_EFFECT_ID = 23, - ITEM_BONUS_MODIFIED_CRAFTING_STAT = 25, + ITEM_BONUS_MODIFIED_CRAFTING_STAT = 25, /*NYI*/ ITEM_BONUS_REQUIRED_LEVEL_CURVE = 27, + ITEM_BONUS_ICON_FILE_DATA_ID = 28, ITEM_BONUS_DESCRIPTION_TEXT = 30, // Item description ITEM_BONUS_OVERRIDE_NAME = 31, // ItemNameDescription id - ITEM_BONUS_ITEM_BONUS_LIST_GROUP = 34, + ITEM_BONUS_UPGRADE_SEQUENCE_VALUE = 33, /*NYI*/ + ITEM_BONUS_ITEM_BONUS_LIST_GROUP = 34, /*NYI*/ ITEM_BONUS_ITEM_LIMIT_CATEGORY = 35, - ITEM_BONUS_ITEM_CONVERSION = 37, - ITEM_BONUS_ITEM_HISTORY_SLOT = 38, + ITEM_BONUS_PVP_ITEM_LEVEL_INCREMENT = 36, + ITEM_BONUS_ITEM_CONVERSION = 37, /*NYI*/ + ITEM_BONUS_ITEM_HISTORY_SLOT = 38, /*NYI*/ + ITEM_BONUS_OVERRIDE_CAN_SALVAGE = 39, + ITEM_BONUS_OVERRIDE_CAN_RECRAFT = 41, + ITEM_BONUS_ITEM_LEVEL_BASE = 42, + ITEM_BONUS_PVP_ITEM_LEVEL_BASE = 43, + ITEM_BONUS_COSMETIC_STAT = 44, + ITEM_BONUS_OVERRIDE_DESCRIPTION_COLOR = 45, // Overrides color of item description and upgrade track if TimeEvent from value[1] has passed + ITEM_BONUS_OVERRIDE_CANNOT_TRADE_BOP = 46, + ITEM_BONUS_BONDING_WITH_PRIORITY = 47, }; enum class ItemCollectionType : uint8 diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 5401c0c9c45..0dc621bd8ce 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1588,7 +1588,7 @@ void Item::SetGem(uint16 slot, ItemDynamicFieldGems const* gem, uint32 gemScalin for (uint16 bonusListId : gem->BonusListIDs) gemBonus.AddBonusList(bonusListId); - uint32 gemBaseItemLevel = gemTemplate->GetBaseItemLevel(); + uint32 gemBaseItemLevel = gemBonus.ItemLevel; if (gemBonus.PlayerLevelToItemLevelCurveId) if (uint32 scaledIlvl = uint32(sDB2Manager.GetCurveValueAt(gemBonus.PlayerLevelToItemLevelCurveId, gemScalingLevel))) gemBaseItemLevel = scaledIlvl; @@ -1677,7 +1677,13 @@ uint8 Item::GetGemCountWithLimitCategory(uint32 limitCategory) const if (!gemProto) return false; - return gemProto->GetItemLimitCategory() == limitCategory; + BonusData gemBonus; + gemBonus.Initialize(gemProto); + + for (uint16 bonusListID : gemData.BonusListIDs) + gemBonus.AddBonusList(bonusListID); + + return gemBonus.LimitCategory == limitCategory; })); } @@ -2317,7 +2323,7 @@ uint32 Item::GetItemLevel(ItemTemplate const* itemTemplate, BonusData const& bon if (!itemTemplate) return MIN_ITEM_LEVEL; - uint32 itemLevel = itemTemplate->GetBaseItemLevel(); + uint32 itemLevel = bonusData.ItemLevel; if (AzeriteLevelInfoEntry const* azeriteLevelInfo = sAzeriteLevelInfoStore.LookupEntry(azeriteLevel)) itemLevel = azeriteLevelInfo->ItemLevel; @@ -2339,7 +2345,13 @@ uint32 Item::GetItemLevel(ItemTemplate const* itemTemplate, BonusData const& bon uint32 itemLevelBeforeUpgrades = itemLevel; if (pvpBonus) + { + if (bonusData.PvpItemLevel) + itemLevel = bonusData.PvpItemLevel; + + itemLevel += bonusData.PvpItemLevelBonus; itemLevel += sDB2Manager.GetPvpItemLevelBonus(itemTemplate->GetId()); + } if (itemTemplate->GetInventoryType() != INVTYPE_NON_EQUIP) { @@ -2885,6 +2897,7 @@ std::string Item::GetDebugInfo() const void BonusData::Initialize(ItemTemplate const* proto) { Quality = proto->GetQuality(); + ItemLevel = proto->GetBaseItemLevel(); ItemLevelBonus = 0; RequiredLevel = proto->GetBaseRequiredLevel(); for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i) @@ -2919,6 +2932,9 @@ void BonusData::Initialize(ItemTemplate const* proto) Suffix = 0; RequiredLevelCurve = 0; + PvpItemLevel = 0; + PvpItemLevelBonus = 0; + EffectCount = 0; for (ItemEffectEntry const* itemEffect : proto->Effects) Effects[EffectCount++] = itemEffect; @@ -2926,8 +2942,13 @@ void BonusData::Initialize(ItemTemplate const* proto) for (std::size_t i = EffectCount; i < Effects.size(); ++i) Effects[i] = nullptr; + LimitCategory = proto->GetItemLimitCategory(); + CanDisenchant = !proto->HasFlag(ITEM_FLAG_NO_DISENCHANT); CanScrap = proto->HasFlag(ITEM_FLAG4_SCRAPABLE); + CanSalvage = !proto->HasFlag(ITEM_FLAG4_NO_SALVAGE); + CanRecraft = proto->HasFlag(ITEM_FLAG4_RECRAFTABLE); + CannotTradeBindOnPickup = proto->HasFlag(ITEM_FLAG2_NO_TRADE_BIND_ON_ACQUIRE); _state.SuffixPriority = std::numeric_limits<int32>::max(); _state.AppearanceModPriority = std::numeric_limits<int32>::max(); @@ -2935,7 +2956,11 @@ void BonusData::Initialize(ItemTemplate const* proto) _state.ScalingStatDistributionPriority = std::numeric_limits<int32>::max(); _state.AzeriteTierUnlockSetPriority = std::numeric_limits<int32>::max(); _state.RequiredLevelCurvePriority = std::numeric_limits<int32>::max(); + _state.ItemLevelPriority = std::numeric_limits<int32>::max(); + _state.PvpItemLevelPriority = std::numeric_limits<int32>::max(); + _state.BondingPriority = std::numeric_limits<int32>::max(); _state.HasQualityBonus = false; + _state.HasItemLimitCategory = false; } void BonusData::Initialize(WorldPackets::Item::ItemInstance const& itemInstance) @@ -3072,5 +3097,45 @@ void BonusData::AddBonus(uint32 type, std::array<int32, 4> const& values) ContentTuningId = static_cast<uint32>(values[1]); } break; + case ITEM_BONUS_ITEM_LIMIT_CATEGORY: + if (!_state.HasItemLimitCategory) + { + LimitCategory = values[0]; + _state.HasItemLimitCategory = true; + } + break; + case ITEM_BONUS_PVP_ITEM_LEVEL_INCREMENT: + PvpItemLevelBonus += values[0]; + break; + case ITEM_BONUS_OVERRIDE_CAN_SALVAGE: + CanSalvage = values[0] != 0; + break; + case ITEM_BONUS_OVERRIDE_CAN_RECRAFT: + CanRecraft = values[0] != 0; + break; + case ITEM_BONUS_ITEM_LEVEL_BASE: + if (values[1] < _state.ItemLevelPriority) + { + ItemLevel = values[0]; + _state.ItemLevelPriority = values[1]; + } + break; + case ITEM_BONUS_PVP_ITEM_LEVEL_BASE: + if (values[1] < _state.PvpItemLevelPriority) + { + PvpItemLevel = values[0]; + _state.PvpItemLevelPriority = values[1]; + } + break; + case ITEM_BONUS_OVERRIDE_CANNOT_TRADE_BOP: + CannotTradeBindOnPickup = values[0] != 0; + break; + case ITEM_BONUS_BONDING_WITH_PRIORITY: + if (values[1] < _state.BondingPriority) + { + Bonding = static_cast<ItemBondingType>(values[0]); + _state.BondingPriority = values[1]; + } + break; } } diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index d8d03f1e709..f1815c0c337 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -60,6 +60,7 @@ extern int32 const ItemTransmogrificationSlots[MAX_INVTYPE]; struct BonusData { uint32 Quality; + uint32 ItemLevel; int32 ItemLevelBonus; int32 RequiredLevel; int32 ItemStatType[MAX_ITEM_PROTO_STATS]; @@ -80,11 +81,17 @@ struct BonusData int32 AzeriteTierUnlockSetId; uint32 Suffix; int32 RequiredLevelCurve; + uint16 PvpItemLevel; + int16 PvpItemLevelBonus; std::array<ItemEffectEntry const*, 13> Effects; std::size_t EffectCount; + uint32 LimitCategory; bool CanDisenchant; bool CanScrap; + bool CanSalvage; + bool CanRecraft; bool HasFixedLevel; + bool CannotTradeBindOnPickup; void Initialize(ItemTemplate const* proto); void Initialize(WorldPackets::Item::ItemInstance const& itemInstance); @@ -100,7 +107,11 @@ private: int32 ScalingStatDistributionPriority; int32 AzeriteTierUnlockSetPriority; int32 RequiredLevelCurvePriority; + int32 ItemLevelPriority; + int32 PvpItemLevelPriority; + int32 BondingPriority; bool HasQualityBonus; + bool HasItemLimitCategory; } _state; }; @@ -347,6 +358,7 @@ class TC_GAME_API Item : public Object static ItemDisenchantLootEntry const* GetBaseDisenchantLoot(ItemTemplate const* itemTemplate, uint32 quality, uint32 itemLevel); void SetFixedLevel(uint8 level); std::span<ItemEffectEntry const* const> GetEffects() const { return { _bonusData.Effects.data(), _bonusData.EffectCount }; } + uint32 GetItemLimitCategory() const { return _bonusData.LimitCategory; } // Item Refund system void SetNotRefundable(Player* owner, bool changestate = true, CharacterDatabaseTransaction* trans = nullptr, bool addToCollection = true); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0bcdbbd1ec7..fbc391ceff6 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9564,9 +9564,8 @@ uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipIte ForEachItem(ItemSearchLocation::Everywhere, [&count, limitCategory, skipItem](Item* item) { if (item != skipItem) - if (ItemTemplate const* pProto = item->GetTemplate()) - if (pProto->GetItemLimitCategory() == limitCategory) - count += item->GetCount(); + if (item->GetItemLimitCategory() == limitCategory) + count += item->GetCount(); return ItemSearchCallbackResult::Continue; }); @@ -9928,7 +9927,7 @@ bool Player::HasItemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count if (pItem->GetSlot() == except_slot) return ItemSearchCallbackResult::Continue; - if (pItem->GetTemplate()->GetItemLimitCategory() != limitCategory) + if (pItem->GetItemLimitCategory() != limitCategory) return ItemSearchCallbackResult::Continue; tempcount += pItem->GetCount(); @@ -9972,8 +9971,10 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item if (pItem && pItem->m_lootGenerated) return EQUIP_ERR_LOOT_GONE; + uint32 limitCategory = pItem ? pItem->GetItemLimitCategory() : pProto->GetItemLimitCategory(); + // no maximum - if ((pProto->GetMaxCount() <= 0 && pProto->GetItemLimitCategory() == 0) || pProto->GetMaxCount() == 2147483647) + if ((pProto->GetMaxCount() <= 0 && limitCategory == 0) || pProto->GetMaxCount() == 2147483647) return EQUIP_ERR_OK; if (pProto->GetMaxCount() > 0) @@ -9988,9 +9989,9 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item } // check unique-equipped limit - if (pProto->GetItemLimitCategory()) + if (limitCategory) { - ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(pProto->GetItemLimitCategory()); + ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(limitCategory); if (!limitEntry) { if (no_space_count) @@ -10001,7 +10002,7 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item if (limitEntry->Flags == ITEM_LIMIT_CATEGORY_MODE_HAVE) { uint8 limitQuantity = GetItemLimitCategoryQuantity(limitEntry); - uint32 curcount = GetItemCountWithLimitCategory(pProto->GetItemLimitCategory(), pItem); + uint32 curcount = GetItemCountWithLimitCategory(limitCategory, pItem); if (curcount + count > uint32(limitQuantity)) { if (no_space_count) @@ -11373,7 +11374,9 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat UpdateCriteria(CriteriaType::ObtainAnyItem, itemId, count); UpdateCriteria(CriteriaType::AcquireItem, itemId, count); - if (allowedLooters.size() > 1 && item->GetTemplate()->GetMaxStackSize() == 1 && item->IsSoulBound()) + if (allowedLooters.size() > 1 && item->IsSoulBound() + && (item->GetTemplate()->GetMaxStackSize() == 1 || item->GetTemplate()->HasFlag(ITEM_FLAG2_CAN_TRADE_BIND_ON_ACQUIRE)) + && !item->GetBonus()->CannotTradeBindOnPickup) { item->SetSoulboundTradeable(allowedLooters); AddTradeableItem(item); @@ -13027,8 +13030,10 @@ void Player::SendEquipError(InventoryResult msg, Item const* item1 /*= nullptr*/ case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS: case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS: { - ItemTemplate const* proto = item1 ? item1->GetTemplate() : sObjectMgr->GetItemTemplate(itemId); - failure.LimitCategory = proto ? proto->GetItemLimitCategory() : 0; + if (item1) + failure.LimitCategory = item1->GetItemLimitCategory(); + else if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId)) + failure.LimitCategory = proto->GetItemLimitCategory(); break; } default: @@ -27014,7 +27019,7 @@ InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limi ItemTemplate const* pProto = pItem->GetTemplate(); // proto based limitations - if (InventoryResult res = CanEquipUniqueItem(pProto, eslot, limit_count)) + if (InventoryResult res = CanEquipUniqueItem(pProto, *pItem->GetBonus(), eslot, limit_count)) return res; // check unique-equipped on gems @@ -27024,18 +27029,24 @@ InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limi if (!pGem) continue; + BonusData gemBonus; + gemBonus.Initialize(pGem); + + for (uint16 bonusListID : gemData.BonusListIDs) + gemBonus.AddBonusList(bonusListID); + // include for check equip another gems with same limit category for not equipped item (and then not counted) - uint32 gem_limit_count = !pItem->IsEquipped() && pGem->GetItemLimitCategory() - ? pItem->GetGemCountWithLimitCategory(pGem->GetItemLimitCategory()) : 1; + uint32 gem_limit_count = !pItem->IsEquipped() && gemBonus.LimitCategory + ? pItem->GetGemCountWithLimitCategory(gemBonus.LimitCategory) : 1; - if (InventoryResult res = CanEquipUniqueItem(pGem, eslot, gem_limit_count)) + if (InventoryResult res = CanEquipUniqueItem(pGem, gemBonus, eslot, gem_limit_count)) return res; } return EQUIP_ERR_OK; } -InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8 except_slot, uint32 limit_count) const +InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, BonusData const& itemBonus, uint8 except_slot, uint32 limit_count) const { // check unique-equipped on item if (itemProto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE)) @@ -27046,9 +27057,9 @@ InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8 } // check unique-equipped limit - if (itemProto->GetItemLimitCategory()) + if (itemBonus.LimitCategory) { - ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(itemProto->GetItemLimitCategory()); + ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(itemBonus.LimitCategory); if (!limitEntry) return EQUIP_ERR_NOT_EQUIPPABLE; @@ -27059,9 +27070,9 @@ InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8 return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS; // there is an equip limit on this item - if (HasItemWithLimitCategoryEquipped(itemProto->GetItemLimitCategory(), limitQuantity - limit_count + 1, except_slot)) + if (HasItemWithLimitCategoryEquipped(itemBonus.LimitCategory, limitQuantity - limit_count + 1, except_slot)) return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS; - else if (HasGemWithLimitCategoryEquipped(itemProto->GetItemLimitCategory(), limitQuantity - limit_count + 1, except_slot)) + else if (HasGemWithLimitCategoryEquipped(itemBonus.LimitCategory, limitQuantity - limit_count + 1, except_slot)) return EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 2b615518381..d6abd1c4104 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -45,6 +45,7 @@ struct AzeriteItemMilestonePowerEntry; struct AzeritePowerEntry; struct BarberShopStyleEntry; struct BattlegroundTemplate; +struct BonusData; struct CharTitlesEntry; struct ChatChannelsEntry; struct ChrSpecializationEntry; @@ -1490,7 +1491,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> InventoryResult CanEquipChildItem(Item* parentItem) const; InventoryResult CanEquipUniqueItem(Item* pItem, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1) const; - InventoryResult CanEquipUniqueItem(ItemTemplate const* itemProto, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1) const; + InventoryResult CanEquipUniqueItem(ItemTemplate const* itemProto, BonusData const& itemBonus, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1) const; InventoryResult CanUnequipItems(uint32 item, uint32 count) const; InventoryResult CanUnequipItem(uint16 src, bool swap) const; InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap, bool not_loading = true, bool reagentBankOnly = false) const; diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index a8602605c7d..329849c5e34 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1048,9 +1048,9 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems) // unique limit type item int32 limit_newcount = 0; - if (iGemProto->GetItemLimitCategory()) + if (gems[i]->GetItemLimitCategory()) { - if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->GetItemLimitCategory())) + if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(gems[i]->GetItemLimitCategory())) { // NOTE: limitEntry->Flags is not checked because if item has limit then it is applied in equip case for (int j = 0; j < MAX_GEM_SOCKETS; ++j) @@ -1058,15 +1058,23 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems) if (gems[j]) { // new gem - if (iGemProto->GetItemLimitCategory() == gems[j]->GetTemplate()->GetItemLimitCategory()) + if (gems[i]->GetItemLimitCategory() == gems[j]->GetItemLimitCategory()) ++limit_newcount; } else if (oldGemData[j]) { // existing gem if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(oldGemData[j]->ItemID)) - if (iGemProto->GetItemLimitCategory() == jProto->GetItemLimitCategory()) + { + BonusData oldGemBonus; + oldGemBonus.Initialize(jProto); + + for (uint16 bonusListID : oldGemData[j]->BonusListIDs) + oldGemBonus.AddBonusList(bonusListID); + + if (gems[i]->GetItemLimitCategory() == oldGemBonus.LimitCategory) ++limit_newcount; + } } } diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index edd02483b46..0dc27c80927 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4968,7 +4968,7 @@ void SpellMgr::LoadSpellInfoCorrections() }); // Conversation - ApplySpellFix({ 274668, 274669 }, [](SpellInfo* spellInfo) + ApplySpellFix({ 274668, 274669, 274622, 274640, 274641, 274674, 274675 }, [](SpellInfo* spellInfo) { ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo) { |