Skip to content

Commit 06dee8e

Browse files
committed
Core/Items: Fix item spell selection for items that have multiple on-use effects
1 parent 9cbff6a commit 06dee8e

File tree

5 files changed

+45
-91
lines changed

5 files changed

+45
-91
lines changed

src/server/game/Entities/Player/Player.cpp

Lines changed: 28 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7834,89 +7834,47 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT
78347834
}
78357835
}
78367836

7837-
void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex)
7837+
void Player::CastItemUseSpell(Item* item, uint32 spellId, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex)
78387838
{
7839-
ItemTemplate const* proto = item->GetTemplate();
7840-
// special learning case
7841-
if (proto->Spells[0].SpellId == 483 || proto->Spells[0].SpellId == 55884)
7839+
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
7840+
if (!spellInfo)
78427841
{
7843-
uint32 learn_spell_id = proto->Spells[0].SpellId;
7844-
uint32 learning_spell_id = proto->Spells[1].SpellId;
7845-
7846-
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(learn_spell_id);
7847-
if (!spellInfo)
7848-
{
7849-
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: {}) has wrong spell id {}, ignoring.", proto->ItemId, learn_spell_id);
7850-
SendEquipError(EQUIP_ERR_NONE, item, nullptr);
7851-
return;
7852-
}
7853-
7854-
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
7855-
spell->m_fromClient = true;
7856-
spell->m_CastItem = item;
7857-
spell->m_cast_count = cast_count; //set count of casts
7858-
spell->SetSpellValue(SPELLVALUE_BASE_POINT0, learning_spell_id);
7859-
spell->prepare(targets);
7842+
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: {}) has wrong spell id {}, ignoring", item->GetEntry(), spellId);
78607843
return;
78617844
}
78627845

7863-
// item spells cast at use
7864-
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
7846+
ItemTemplate const* proto = item->GetTemplate();
7847+
bool isValidSpell = std::ranges::any_of(proto->Spells, [spellId](_Spell const& spellData)
78657848
{
7866-
_Spell const& spellData = proto->Spells[i];
7867-
7868-
// no spell
7869-
if (spellData.SpellId <= 0)
7870-
continue;
7871-
7872-
// wrong triggering type
7873-
if (spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
7874-
continue;
7849+
return spellData.SpellId == int32(spellId) && spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_USE;
7850+
});
78757851

7876-
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellData.SpellId);
7877-
if (!spellInfo)
7852+
if (!isValidSpell)
7853+
{
7854+
isValidSpell = [&]
78787855
{
7879-
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: {}) has wrong spell id {}, ignoring", proto->ItemId, spellData.SpellId);
7880-
continue;
7881-
}
7856+
for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
7857+
if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot))))
7858+
for (uint8 enchantEffect = 0; enchantEffect < MAX_ITEM_ENCHANTMENT_EFFECTS; ++enchantEffect)
7859+
if (enchant->Effect[enchantEffect] == ITEM_ENCHANTMENT_TYPE_USE_SPELL && enchant->EffectArg[enchantEffect] == spellId)
7860+
return true;
78827861

7883-
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
7884-
spell->m_fromClient = true;
7885-
spell->m_CastItem = item;
7886-
spell->m_cast_count = cast_count; // set count of casts
7887-
spell->m_glyphIndex = glyphIndex; // glyph index
7888-
spell->prepare(targets);
7889-
return;
7862+
return false;
7863+
}();
78907864
}
78917865

7892-
// Item enchantments spells cast at use
7893-
for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
7866+
if (!isValidSpell)
78947867
{
7895-
uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
7896-
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7897-
if (!pEnchant)
7898-
continue;
7899-
for (uint8 s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s)
7900-
{
7901-
if (pEnchant->Effect[s] != ITEM_ENCHANTMENT_TYPE_USE_SPELL)
7902-
continue;
7903-
7904-
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pEnchant->EffectArg[s]);
7905-
if (!spellInfo)
7906-
{
7907-
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Enchant {}, cast unknown spell {}", pEnchant->ID, pEnchant->EffectArg[s]);
7908-
continue;
7909-
}
7910-
7911-
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
7912-
spell->m_fromClient = true;
7913-
spell->m_CastItem = item;
7914-
spell->m_cast_count = cast_count; // set count of casts
7915-
spell->m_glyphIndex = glyphIndex; // glyph index
7916-
spell->prepare(targets);
7917-
return;
7918-
}
7868+
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Tried to cast Spell {} not found on Item {}, ignoring", spellId, proto->ItemId);
7869+
return;
79197870
}
7871+
7872+
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
7873+
spell->m_fromClient = true;
7874+
spell->m_CastItem = item;
7875+
spell->m_cast_count = cast_count; // set count of casts
7876+
spell->m_glyphIndex = glyphIndex; // glyph index
7877+
spell->prepare(targets);
79207878
}
79217879

79227880
void Player::_RemoveAllItemMods()

src/server/game/Entities/Player/Player.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1957,7 +1957,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
19571957
void UpdateEquipSpellsAtFormChange();
19581958
void CastItemCombatSpell(DamageInfo const& damageInfo);
19591959
void CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto);
1960-
void CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex);
1960+
void CastItemUseSpell(Item* item, uint32 spellId, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex);
19611961

19621962
void SendEquipmentSetList();
19631963
void SetEquipmentSet(EquipmentSetInfo::EquipmentSetData const& eqset);

src/server/game/Globals/ObjectMgr.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,22 +3333,6 @@ void ObjectMgr::LoadItemTemplates()
33333333
itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
33343334
}
33353335
}
3336-
3337-
// spell_3*, spell_4*, spell_5* is empty
3338-
for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
3339-
{
3340-
if (itemTemplate.Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
3341-
{
3342-
TC_LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong item spell trigger value in spelltrigger_{} ({})", entry, j+1, itemTemplate.Spells[j].SpellTrigger);
3343-
itemTemplate.Spells[j].SpellId = 0;
3344-
itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
3345-
}
3346-
else if (itemTemplate.Spells[j].SpellId != 0)
3347-
{
3348-
TC_LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong spell in spellid_{} ({}) for learning special format", entry, j+1, itemTemplate.Spells[j].SpellId);
3349-
itemTemplate.Spells[j].SpellId = 0;
3350-
}
3351-
}
33523336
}
33533337
// normal spell list
33543338
else

src/server/game/Handlers/SpellHandler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
164164
if (!sScriptMgr->OnItemUse(pUser, pItem, targets))
165165
{
166166
// no script or script not process request by self
167-
pUser->CastItemUseSpell(pItem, targets, castCount, glyphIndex);
167+
pUser->CastItemUseSpell(pItem, spellId, targets, castCount, glyphIndex);
168168
}
169169
}
170170

src/server/game/Spells/SpellEffects.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,10 +2248,22 @@ void Spell::EffectLearnSpell()
22482248

22492249
Player* player = unitTarget->ToPlayer();
22502250

2251-
uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : effectInfo->TriggerSpell;
2252-
player->LearnSpell(spellToLearn, false);
2251+
if (m_CastItem && !effectInfo->TriggerSpell)
2252+
{
2253+
for (_Spell const& itemEffect : m_CastItem->GetTemplate()->Spells)
2254+
{
2255+
if (itemEffect.SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
2256+
continue;
2257+
2258+
player->LearnSpell(itemEffect.SpellId, false);
2259+
}
2260+
}
22532261

2254-
TC_LOG_DEBUG("spells", "Spell: Player {} has learned spell {} from Npc {}", player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2262+
if (effectInfo->TriggerSpell)
2263+
{
2264+
player->LearnSpell(effectInfo->TriggerSpell, false);
2265+
TC_LOG_DEBUG("spells", "Spell: Player {} has learned spell {} from Npc {}", player->GetGUID().ToString(), effectInfo->TriggerSpell, m_caster->GetGUID().ToString());
2266+
}
22552267
}
22562268

22572269
void Spell::EffectDispel()

0 commit comments

Comments
 (0)