From 8022cef6a7a1ff0ac3e77be21a23beefd38f60a4 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 20 May 2011 22:42:36 +0400 Subject: [PATCH] [11512] Fixes for channeled spells casting. * Set as expected caster channeling target to created dynamic object at persistent aura area spell casts for channeled spell. * Select correct caster/target for triggered spell in case channeled perioding trigger aura. --- src/game/Spell.cpp | 15 +++++++++------ src/game/SpellAuras.cpp | 39 ++++++++++++++++++++++++++++++++++++++- src/shared/revision_nr.h | 2 +- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 9c209ba8b..12beea562 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -695,7 +695,7 @@ void Spell::prepareDataForTriggerSystem() switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_MAGE: - // Arcane Missles / Blizzard triggers need do it + // Arcane Missiles / Blizzard triggers need do it if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000200080)) m_canTrigger = true; // Clearcasting trigger need do it @@ -3166,16 +3166,16 @@ void Spell::cast(bool skipCheck) void Spell::handle_immediate() { - // start channeling if applicable + // process immediate effects (items, ground, etc.) also initialize some variables + _handle_immediate_phase(); + + // start channeling if applicable (after _handle_immediate_phase for get persistent effect dynamic object for channel target if (IsChanneledSpell(m_spellInfo) && m_duration) { m_spellState = SPELL_STATE_CASTING; SendChannelStart(m_duration); } - // process immediate effects (items, ground, etc.) also initialize some variables - _handle_immediate_phase(); - for(TargetList::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) DoAllEffectOnTarget(&(*ihit)); @@ -4010,8 +4010,11 @@ void Spell::SendChannelStart(uint32 duration) { WorldObject* target = NULL; + // select dynobject created by first effect if any + if (m_spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_PERSISTENT_AREA_AURA) + target = m_caster->GetDynObject(m_spellInfo->Id, EFFECT_INDEX_0); // select first not resisted target from target list for _0_ effect - if (!m_UniqueTargetInfo.empty()) + else if (!m_UniqueTargetInfo.empty()) { for(TargetList::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr) { diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index bf57a786a..981e03080 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1870,9 +1870,46 @@ void Aura::TriggerSpell() } } + Unit* triggerCaster = triggerTarget; + WorldObject* triggerTargetObject = NULL; + + // for channeled spell cast applied from aura owner to channel target (persistent aura affects already applied to true target) + // come periodic casts applied to targets, so need seelct proper caster (ex. 15790) + if (IsChanneledSpell(GetSpellProto()) && GetSpellProto()->Effect[GetEffIndex()] != SPELL_EFFECT_PERSISTENT_AREA_AURA) + { + // interesting 2 cases: periodic aura at caster of channeled spell + if (target->GetObjectGuid() == casterGUID) + { + triggerCaster = target; + + if (WorldObject* channelTarget = target->GetMap()->GetWorldObject(target->GetChannelObjectGuid())) + { + if (channelTarget->isType(TYPEMASK_UNIT)) + triggerTarget = (Unit*)channelTarget; + else + triggerTargetObject = channelTarget; + } + } + // or periodic aura at caster channel target + else if (Unit* caster = GetCaster()) + { + if (target->GetObjectGuid() == caster->GetChannelObjectGuid()) + { + triggerCaster = caster; + triggerTarget = target; + } + } + } + // All ok cast by default case if (triggeredSpellInfo) - triggerTarget->CastSpell(triggerTarget, triggeredSpellInfo, true, NULL, this, casterGUID); + { + if (triggerTargetObject) + triggerCaster->CastSpell(triggerTargetObject->GetPositionX(), triggerTargetObject->GetPositionY(), triggerTargetObject->GetPositionZ(), + triggeredSpellInfo, true, NULL, this, casterGUID); + else + triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, NULL, this, casterGUID); + } else { if (Unit* caster = GetCaster()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7a8fadcde..f12540a6e 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 "11511" + #define REVISION_NR "11512" #endif // __REVISION_NR_H__