summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJelle Meeus <sogladev@gmail.com>2025-08-27 11:43:39 -0700
committerGitHub <noreply@github.com>2025-08-27 15:43:39 -0300
commita3131d5cdb81f6817bbcef8c43ee535ed4c831cf (patch)
tree671066c6053b6143f1ef65124455c824f24cdb88 /src
parent71c22ff6cf8c9d442579ec5905c5eee73408b029 (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.cpp43
-rw-r--r--src/server/game/Entities/Player/Player.h3
-rw-r--r--src/server/game/Entities/Player/PlayerStorage.cpp25
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)
{