Core/Items: Fix item spell selection for items that have multiple on-use effects
(cherry picked from commit 06dee8eabfa02879c5c22b4f083272b84d59d93f)
This commit is contained in:
@@ -8774,72 +8774,56 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
|
||||
}
|
||||
}
|
||||
|
||||
void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, ObjectGuid castCount, std::array<int32, 3> const& misc)
|
||||
void Player::CastItemUseSpell(Item* item, uint32 spellId, SpellCastTargets const& targets, ObjectGuid castCount, std::array<int32, 3> const& misc)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
|
||||
if (!spellInfo)
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: {}) has wrong spell id {}, ignoring", item->GetEntry(), spellId);
|
||||
return;
|
||||
}
|
||||
|
||||
ItemTemplate const* proto = item->GetTemplate();
|
||||
bool isValidSpell = false;
|
||||
if (!item->GetTemplate()->HasFlag(ITEM_FLAG_LEGACY))
|
||||
{
|
||||
// item spells cast at use
|
||||
for (ItemEffectEntry const* effectData : item->GetEffects())
|
||||
isValidSpell = std::ranges::any_of(item->GetEffects(), [spellId](ItemEffectEntry const* effectData)
|
||||
{
|
||||
// wrong triggering type
|
||||
if (effectData->TriggerType != ITEM_SPELLTRIGGER_ON_USE)
|
||||
continue;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(effectData->SpellID, DIFFICULTY_NONE);
|
||||
if (!spellInfo)
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: {}) has wrong spell id {}, ignoring", item->GetEntry(), effectData->SpellID);
|
||||
continue;
|
||||
}
|
||||
|
||||
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
|
||||
|
||||
WorldPackets::Spells::SpellPrepare spellPrepare;
|
||||
spellPrepare.ClientCastID = castCount;
|
||||
spellPrepare.ServerCastID = spell->m_castId;
|
||||
SendDirectMessage(spellPrepare.Write());
|
||||
|
||||
spell->m_fromClient = true;
|
||||
spell->m_CastItem = item;
|
||||
std::ranges::copy(misc, std::ranges::begin(spell->m_misc.Raw.Data));
|
||||
spell->prepare(targets);
|
||||
return;
|
||||
}
|
||||
return effectData->SpellID == int32(spellId) && effectData->TriggerType == ITEM_SPELLTRIGGER_ON_USE;
|
||||
});
|
||||
}
|
||||
|
||||
// Item enchantments spells cast at use
|
||||
for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
|
||||
if (!isValidSpell)
|
||||
{
|
||||
uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
|
||||
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
|
||||
if (!pEnchant)
|
||||
continue;
|
||||
for (uint8 s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s)
|
||||
isValidSpell = [&]
|
||||
{
|
||||
if (pEnchant->Effect[s] != ITEM_ENCHANTMENT_TYPE_USE_SPELL)
|
||||
continue;
|
||||
for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
|
||||
if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot))))
|
||||
for (uint8 enchantEffect = 0; enchantEffect < MAX_ITEM_ENCHANTMENT_EFFECTS; ++enchantEffect)
|
||||
if (enchant->Effect[enchantEffect] == ITEM_ENCHANTMENT_TYPE_USE_SPELL && enchant->EffectArg[enchantEffect] == spellId)
|
||||
return true;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pEnchant->EffectArg[s], DIFFICULTY_NONE);
|
||||
if (!spellInfo)
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Enchant {}, cast unknown spell {}", pEnchant->ID, pEnchant->EffectArg[s]);
|
||||
continue;
|
||||
}
|
||||
|
||||
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
|
||||
|
||||
WorldPackets::Spells::SpellPrepare spellPrepare;
|
||||
spellPrepare.ClientCastID = castCount;
|
||||
spellPrepare.ServerCastID = spell->m_castId;
|
||||
SendDirectMessage(spellPrepare.Write());
|
||||
|
||||
spell->m_fromClient = true;
|
||||
spell->m_CastItem = item;
|
||||
std::ranges::copy(misc, std::ranges::begin(spell->m_misc.Raw.Data));
|
||||
spell->prepare(targets);
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
}
|
||||
|
||||
if (!isValidSpell)
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Tried to cast Spell {} not found on Item {}, ignoring", spellId, proto->GetId());
|
||||
return;
|
||||
}
|
||||
|
||||
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
|
||||
|
||||
WorldPackets::Spells::SpellPrepare spellPrepare;
|
||||
spellPrepare.ClientCastID = castCount;
|
||||
spellPrepare.ServerCastID = spell->m_castId;
|
||||
SendDirectMessage(spellPrepare.Write());
|
||||
|
||||
spell->m_fromClient = true;
|
||||
spell->m_CastItem = item;
|
||||
std::ranges::copy(misc, std::ranges::begin(spell->m_misc.Raw.Data));
|
||||
spell->prepare(targets);
|
||||
}
|
||||
|
||||
void Player::ApplyItemLootedSpell(Item* item, bool apply)
|
||||
@@ -31751,7 +31735,7 @@ bool Player::ProcessItemCast(SpellCastRequest& castRequest, SpellCastTargets con
|
||||
if (!sScriptMgr->OnItemUse(this, item, targets, castRequest.CastRequest.CastID))
|
||||
{
|
||||
// no script or script not process request by self
|
||||
CastItemUseSpell(item, targets, castRequest.CastRequest.CastID, castRequest.CastRequest.Misc);
|
||||
CastItemUseSpell(item, castRequest.CastRequest.SpellID, targets, castRequest.CastRequest.CastID, castRequest.CastRequest.Misc);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -2554,7 +2554,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
|
||||
|
||||
void CastItemCombatSpell(DamageInfo const& damageInfo);
|
||||
void CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto);
|
||||
void CastItemUseSpell(Item* item, SpellCastTargets const& targets, ObjectGuid castCount, std::array<int32, 3> const& misc);
|
||||
void CastItemUseSpell(Item* item, uint32 spellId, SpellCastTargets const& targets, ObjectGuid castCount, std::array<int32, 3> const& misc);
|
||||
void ApplyItemLootedSpell(Item* item, bool apply);
|
||||
void ApplyItemLootedSpell(ItemTemplate const* itemTemplate);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user