From 633cad5a56c8c02c3c4dbac20e01156df8c1784e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 15 Jan 2009 03:03:19 +0300 Subject: [PATCH] [7089] Implement ITEM_ENCHANTMENT_TYPE_USE_SPELL support. This allow cast spells at item used from engineering recipes 54999, 54736, 54998, 55002, 55016, 54793. --- src/game/Item.h | 2 +- src/game/Player.cpp | 89 ++++++++++++++++++++++++++++++++++ src/game/Player.h | 2 + src/game/Spell.cpp | 2 +- src/game/Spell.h | 2 +- src/game/SpellHandler.cpp | 54 +-------------------- src/shared/Database/DBCEnums.h | 16 +++--- src/shared/revision_nr.h | 2 +- 8 files changed, 105 insertions(+), 64 deletions(-) diff --git a/src/game/Item.h b/src/game/Item.h index a124d318a..2bd91d55e 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -152,7 +152,7 @@ enum EnchantmentSlot SOCK_ENCHANTMENT_SLOT_2 = 3, SOCK_ENCHANTMENT_SLOT_3 = 4, BONUS_ENCHANTMENT_SLOT = 5, - WOTLK_ENCHANTMENT_SLOT = 6, + PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment MAX_INSPECTED_ENCHANTMENT_SLOT = 7, PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 049ea3817..3c6284cf2 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6947,6 +6947,92 @@ void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attTy } } +void Player::CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex) +{ + ItemPrototype const* proto = item->GetProto(); + // special learning case + if(proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN || proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET) + { + uint32 learn_spell_id = proto->Spells[0].SpellId; + uint32 learning_spell_id = proto->Spells[1].SpellId; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id); + if(!spellInfo) + { + sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id); + SendEquipError(EQUIP_ERR_NONE,item,NULL); + return; + } + + Spell *spell = new Spell(this, spellInfo, false); + spell->m_CastItem = item; + spell->m_cast_count = cast_count; //set count of casts + spell->m_currentBasePoints[0] = learning_spell_id; + spell->prepare(&targets); + return; + } + + // use triggered flag only for items with many spell casts and for not first cast + int count = 0; + + // item spells casted at use + for(int i = 0; i < 5; ++i) + { + _Spell const& spellData = proto->Spells[i]; + + // no spell + if(!spellData.SpellId) + continue; + + // wrong triggering type + if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId); + if(!spellInfo) + { + sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring",proto->ItemId, spellData.SpellId); + continue; + } + + Spell *spell = new Spell(this, spellInfo, (count > 0)); + spell->m_CastItem = item; + spell->m_cast_count = cast_count; // set count of casts + spell->m_glyphIndex = glyphIndex; // glyph index + spell->prepare(&targets); + + ++count; + } + + // Item enchantments spells casted at use + for(int e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) + { + uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot)); + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) continue; + for (int s=0;s<3;s++) + { + if(pEnchant->type[s]!=ITEM_ENCHANTMENT_TYPE_USE_SPELL) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(pEnchant->spellid[s]); + if (!spellInfo) + { + sLog.outError("Player::CastItemUseSpell Enchant %i, cast unknown spell %i", pEnchant->ID, pEnchant->spellid[s]); + continue; + } + + Spell *spell = new Spell(this, spellInfo, (count > 0)); + spell->m_CastItem = item; + spell->m_cast_count = cast_count; // set count of casts + spell->m_glyphIndex = glyphIndex; // glyph index + spell->prepare(&targets); + + ++count; + } + } +} + void Player::_RemoveAllItemMods() { sLog.outDebug("_RemoveAllItemMods start."); @@ -11876,6 +11962,9 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a } break; } + case ITEM_ENCHANTMENT_TYPE_USE_SPELL: + // processed in Player::CastItemUseSpell + break; default: sLog.outError("Unknown item enchantment display type: %d",enchant_display_type); break; diff --git a/src/game/Player.h b/src/game/Player.h index 7f40f3ad0..b3a1bb406 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -46,6 +46,7 @@ class Pet; class PlayerMenu; class Transport; class UpdateMask; +class SpellCastTargets; class PlayerSocial; class AchievementMgr; class Vehicle; @@ -1871,6 +1872,7 @@ class MANGOS_DLL_SPEC Player : public Unit void ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply, bool form_change = false); void UpdateEquipSpellsAtFormChange(); void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType); + void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex); void SendInitWorldStates(); void SendUpdateWorldState(uint32 Field, uint32 Value); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 7bc7f0fba..ceb5c032c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2036,7 +2036,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) } } -void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura) +void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura) { m_targets = *targets; diff --git a/src/game/Spell.h b/src/game/Spell.h index e32e32d1f..24258e23c 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -321,7 +321,7 @@ class Spell Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL ); ~Spell(); - void prepare(SpellCastTargets * targets, Aura* triggeredByAura = NULL); + void prepare(SpellCastTargets const* targets, Aura* triggeredByAura = NULL); void cancel(); void update(uint32 difftime); void cast(bool skipCheck = false); diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 2063fa34b..ab9b75917 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -125,59 +125,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) if(!Script->ItemUse(pUser,pItem,targets)) { // no script or script not process request by self - - // special learning case - if((pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) || (pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET)) - { - uint32 learn_spell_id = pItem->GetProto()->Spells[0].SpellId; - uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId; - - SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id); - if(!spellInfo) - { - sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id); - pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL); - return; - } - - Spell *spell = new Spell(pUser, spellInfo, false); - spell->m_CastItem = pItem; - spell->m_cast_count = cast_count; //set count of casts - spell->m_currentBasePoints[0] = learning_spell_id; - spell->prepare(&targets); - return; - } - - // use triggered flag only for items with many spell casts and for not first cast - int count = 0; - - for(int i = 0; i < 5; ++i) - { - _Spell const& spellData = pItem->GetProto()->Spells[i]; - - // no spell - if(!spellData.SpellId) - continue; - - // wrong triggering type - if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) - continue; - - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId); - if(!spellInfo) - { - sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, spellData.SpellId); - continue; - } - - Spell *spell = new Spell(pUser, spellInfo, (count > 0)); - spell->m_CastItem = pItem; - spell->m_cast_count = cast_count; // set count of casts - spell->m_glyphIndex = glyphIndex; // glyph index - spell->prepare(&targets); - - ++count; - } + pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex); } } diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h index 69784cf22..e546b1f78 100644 --- a/src/shared/Database/DBCEnums.h +++ b/src/shared/Database/DBCEnums.h @@ -251,13 +251,15 @@ enum AbilytyLearnType enum ItemEnchantmentType { - ITEM_ENCHANTMENT_TYPE_NONE = 0, - ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1, - ITEM_ENCHANTMENT_TYPE_DAMAGE = 2, - ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3, - ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4, - ITEM_ENCHANTMENT_TYPE_STAT = 5, - ITEM_ENCHANTMENT_TYPE_TOTEM = 6 + ITEM_ENCHANTMENT_TYPE_NONE = 0, + ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1, + ITEM_ENCHANTMENT_TYPE_DAMAGE = 2, + ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3, + ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4, + ITEM_ENCHANTMENT_TYPE_STAT = 5, + ITEM_ENCHANTMENT_TYPE_TOTEM = 6, + ITEM_ENCHANTMENT_TYPE_USE_SPELL = 7, + ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8 }; enum TotemCategoryType diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6531fbd90..d2de4cc4d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7088" + #define REVISION_NR "7089" #endif // __REVISION_NR_H__