diff options
author | Jelle Meeus <sogladev@gmail.com> | 2025-08-27 11:43:39 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-27 15:43:39 -0300 |
commit | a3131d5cdb81f6817bbcef8c43ee535ed4c831cf (patch) | |
tree | 671066c6053b6143f1ef65124455c824f24cdb88 /src | |
parent | 71c22ff6cf8c9d442579ec5905c5eee73408b029 (diff) |
fix(Core/Player): Recast lost by death item obtain spells of any item… (#22736)
Co-authored-by: ariel- <ariel-@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 43 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/PlayerStorage.cpp | 25 |
3 files changed, 56 insertions, 15 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 00cde81a60..f9fb147a81 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4550,6 +4550,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) // update visibility UpdateObjectVisibility(); + // recast lost by death auras of any items held in the inventory + CastAllObtainSpells(); + sScriptMgr->OnPlayerResurrect(this, restore_percent, applySickness); if (!applySickness) @@ -7024,6 +7027,46 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt UpdateDamagePhysical(WeaponAttackType(attType)); } +void Player::CastAllObtainSpells() +{ + for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot) + if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + ApplyItemObtainSpells(item, true); + + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + { + Bag* bag = GetBagByPos(i); + if (!bag) + continue; + + for (uint32 slot = 0; slot < bag->GetBagSize(); ++slot) + if (Item* item = bag->GetItemByPos(slot)) + ApplyItemObtainSpells(item, true); + } +} + +void Player::ApplyItemObtainSpells(Item* item, bool apply) +{ + ItemTemplate const* itemTemplate = item->GetTemplate(); + for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + { + if (itemTemplate->Spells[i].SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) // On obtain trigger + continue; + + int32 const spellId = itemTemplate->Spells[i].SpellId; + if (spellId <= 0) + continue; + + if (apply) + { + if (!HasAura(spellId)) + CastSpell(this, spellId, true, item); + } + else + RemoveAurasDueToSpell(spellId); + } +} + SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/, uint8 damageIndex /*= 0*/) const { if (Item const* weapon = GetWeaponForAttack(attackType, true)) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 17e18c0ef8..a79392e7f5 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2206,6 +2206,9 @@ public: void ResetAllPowers(); + void CastAllObtainSpells(); + void ApplyItemObtainSpells(Item* item, bool apply); + SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const override; void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply); diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 01595faa5a..4836811e26 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -2577,8 +2577,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update) return nullptr; Item* lastItem = pItem; - ItemTemplate const* proto = pItem->GetTemplate(); - for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end();) { uint16 pos = itr->pos; @@ -2595,13 +2593,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update) lastItem = _StoreItem(pos, pItem, count, true, update); } - // cast after item storing - some checks in checkcast requires item to be present!! - if (lastItem) - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger - if (!HasAura(proto->Spells[i].SpellId)) - CastSpell(this, proto->Spells[i].SpellId, true, lastItem); - return lastItem; } @@ -2664,6 +2655,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool AddEnchantmentDurations(pItem); AddItemDurations(pItem); + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + ApplyItemObtainSpells(pItem, true); + return pItem; } else @@ -2700,6 +2694,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool pItem2->SetState(ITEM_CHANGED, this); + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + ApplyItemObtainSpells(pItem2, true); + return pItem2; } } @@ -3046,10 +3043,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) pItem->ClearSoulboundTradeable(this); RemoveTradeableItem(pItem); - ItemTemplate const* proto = pItem->GetTemplate(); - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger - RemoveAurasDueToSpell(proto->Spells[i].SpellId); + ApplyItemObtainSpells(pItem, false); ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount()); @@ -3102,8 +3096,9 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) pBag->RemoveItem(slot, update); // Xinef: item is removed, remove loot from storage if any - if (proto->HasFlag(ITEM_FLAG_HAS_LOOT)) - sLootItemStorage->RemoveStoredLoot(pItem->GetGUID()); + if (ItemTemplate const* proto = pItem->GetTemplate()) + if (proto->HasFlag(ITEM_FLAG_HAS_LOOT)) + sLootItemStorage->RemoveStoredLoot(pItem->GetGUID()); if (IsInWorld() && update) { |