fix(Core/Player): Recast lost by death item obtain spells of any item… (#22736)

Co-authored-by: ariel- <ariel-@users.noreply.github.com>
This commit is contained in:
Jelle Meeus
2025-08-27 11:43:39 -07:00
committed by GitHub
parent 71c22ff6cf
commit a3131d5cdb
3 changed files with 56 additions and 15 deletions

View File

@@ -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))

View File

@@ -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);

View File

@@ -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)
{