From c521e712d3d3f45bff8239371b7d0303f9536c2f Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 1 Jan 2026 09:47:09 +0100 Subject: [PATCH] fix(Core/Player): Make sure OnEquip spells from items are added after revive (#24238) --- src/server/game/Entities/Item/Item.h | 7 +++++++ src/server/game/Entities/Item/ItemTemplate.h | 8 ++++++++ .../game/Entities/Player/PlayerUpdates.cpp | 17 +++++++++++++++++ src/server/game/Entities/Unit/Unit.cpp | 2 +- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 51289594b..9f467fad7 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -272,6 +272,13 @@ public: [[nodiscard]] uint32 GetCount() const { return GetUInt32Value(ITEM_FIELD_STACK_COUNT); } void SetCount(uint32 value) { SetUInt32Value(ITEM_FIELD_STACK_COUNT, value); } [[nodiscard]] uint32 GetMaxStackCount() const { return GetTemplate()->GetMaxStackSize(); } + void GetOnEquipSpellIDs(std::vector& spellEquipID) const + { + if (ItemTemplate const* proto = GetTemplate()) + proto->GetOnEquipSpellIDs(spellEquipID); + else + spellEquipID.clear(); + }; // Checks if this item has sockets, whether built-in or added by an upgrade. [[nodiscard]] bool HasSocket() const; [[nodiscard]] uint8 GetGemCountWithID(uint32 GemID) const; diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index b41616c11..b073cb107 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -729,6 +729,14 @@ struct ItemTemplate return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF - 1) : uint32(Stackable); } + void GetOnEquipSpellIDs(std::vector& spellEquipID) const + { + spellEquipID.clear(); + for (auto const& spell : Spells) + if (spell.SpellId && spell.SpellTrigger == ITEM_SPELLTRIGGER_ON_EQUIP) + spellEquipID.push_back(spell.SpellId); + } + [[nodiscard]] float getDPS() const { if (Delay == 0) diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index b0c7a8521..469131a65 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -319,6 +319,23 @@ void Player::Update(uint32 p_time) { m_regenTimer += p_time; RegenerateAll(); + + // Apply buffs from items with Apply on Equip trigger if they are not present. + for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i) + { + if (!m_items[i]) + continue; + + std::vector spellIDs; + m_items[i]->GetOnEquipSpellIDs(spellIDs); + bool apply = false; + for (uint32 spellID : spellIDs) + if (!apply && !HasAura(spellID)) + apply = true; + + if (apply) + ApplyItemEquipSpell(m_items[i], true, false); + } } if (m_deathState == DeathState::JustDied) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 5fb2c5925..615732f59 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14711,7 +14711,7 @@ void Unit::setDeathState(DeathState s, bool despawn) } else if (s == DeathState::JustRespawned) { - RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) } }