From 98bd7918f47ad76f46cbdc48ecf66ad165b68a25 Mon Sep 17 00:00:00 2001 From: Laise Date: Fri, 29 Jul 2011 09:37:32 +0300 Subject: [PATCH] [11760] change proc related part of [11748] note: PROC_EX_CAST_END shouldn't be used with any on-hit proc exs to avoid double proc --- src/game/Spell.cpp | 8 ++++++-- src/game/SpellAuras.cpp | 16 ++++++---------- src/game/SpellMgr.cpp | 4 ++-- src/game/SpellMgr.h | 17 ++++++++++++++++- src/game/Unit.cpp | 10 ++++++---- src/shared/revision_nr.h | 2 +- 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 26c0bb067..c67cf76a5 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3200,6 +3200,10 @@ void Spell::cast(bool skipCheck) InitializeDamageMultipliers(); + Unit *procTarget = m_targets.getUnitTarget(); + if (!procTarget) + procTarget = m_caster; + // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells if (m_spellInfo->speed > 0.0f) { @@ -3221,11 +3225,11 @@ void Spell::cast(bool skipCheck) // critical hit related part is currently done on hit so proc there, // 0 damage since any damage based procs should be on hit // 0 victim proc since there is no victim proc dependent on successfull cast for caster - m_caster->ProcDamageAndSpell(m_caster, m_procAttacker, 0, PROC_EX_NORMAL_HIT, 0, m_attackType, m_spellInfo); + m_caster->ProcDamageAndSpell(procTarget, m_procAttacker, 0, PROC_EX_CAST_END, 0, m_attackType, m_spellInfo); } else { - m_caster->ProcDamageAndSpell(m_caster, m_procAttacker, 0, PROC_EX_NORMAL_HIT, 0, m_attackType, m_spellInfo); + m_caster->ProcDamageAndSpell(procTarget, m_procAttacker, 0, PROC_EX_CAST_END, 0, m_attackType, m_spellInfo); // Immediate spell, no big deal handle_immediate(); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 431fa857e..c3889aa19 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -865,19 +865,15 @@ bool Aura::CanProcFrom(SpellEntry const *spell, uint32 procFlag, uint32 EventPro { if (!(EventProcEx & PROC_EX_EX_TRIGGER_ALWAYS)) { - // modifier aura procs by default are not active and only allowed with non zero charges - // procEx == PROC_EX_NORMAL_HIT only for real "on cast" cases - if (!active && procEx == PROC_EX_NORMAL_HIT && (procFlag & SPELL_CAST_TRIGGER_MASK)) - { - if (GetHolder()->GetAuraCharges() > 0) - return true; - else - return false; - } - // Check for extra req (if none) and hit/crit if (EventProcEx == PROC_EX_NONE) { + // allow proc for modifier auras with charges + if (procEx == PROC_EX_CAST_END + && IsModifierAura(GetSpellProto(), GetEffIndex()) + && GetHolder()->GetAuraCharges() > 0) + return true; + // No extra req, so can trigger only for active (damage/healing present) and hit/crit if((procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && active) return true; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index feb52d9fe..597046351 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1614,8 +1614,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP if (EventProcFlag & (PROC_FLAG_ON_DO_PERIODIC | PROC_FLAG_ON_TAKE_PERIODIC) && (procExtra & PROC_EX_PERIODIC_POSITIVE)) return false; - // No extra req, so can trigger for (damage/healing present) and hit/crit - if(procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) + // No extra req, so can trigger for (damage/healing present) and cast end/hit/crit + if (procExtra & (PROC_EX_CAST_END|PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) return true; } else // all spells hits here only if resist/reflect/immune/evade diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index f1c477414..576d44ab2 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -164,6 +164,20 @@ inline bool IsPeriodicRegenerateEffect(SpellEntry const *spellInfo, SpellEffectI } } +inline bool IsModifierAura(SpellEntry const *spellInfo, SpellEffectIndex effecIdx) +{ + // modifier auras that can proc on cast end + switch (AuraType(spellInfo->EffectApplyAuraName[effecIdx])) + { + case SPELL_AURA_ADD_FLAT_MODIFIER: + case SPELL_AURA_ADD_PCT_MODIFIER: + case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: + return true; + default: + return false; + } +} + inline bool IsSpellHaveAura(SpellEntry const *spellInfo, AuraType aura) { for(int i = 0; i < MAX_EFFECT_INDEX; ++i) @@ -623,7 +637,8 @@ enum ProcFlagsEx PROC_EX_RESERVED3 = 0x0008000, PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not used) - PROC_EX_PERIODIC_POSITIVE = 0x0040000 // For periodic heal + PROC_EX_PERIODIC_POSITIVE = 0x0040000, // For periodic heal + PROC_EX_CAST_END = 0x0080000 // procs on end of cast }; struct SpellProcEventEntry diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index cb969d12d..1b414da8e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9629,7 +9629,7 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage ) { // For melee/ranged based attack need update skills and set some Aura states - if ((damage != 0 || procExtra != PROC_EX_NORMAL_HIT) && procFlag & MELEE_BASED_TRIGGER_MASK) + if (!(procExtra & PROC_EX_CAST_END) && procFlag & MELEE_BASED_TRIGGER_MASK) { // Update skills here for players if (GetTypeId() == TYPEID_PLAYER) @@ -9750,9 +9750,11 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag if (!procSpell->IsFitToFamilyMask(spellProcEvent->spellFamilyMask[i])) continue; - // modifier aura procs by default are not active and only allowed with non zero charges - // procEx == PROC_EX_NORMAL_HIT only for real "on cast" cases - if (!useCharges && damage == 0 && procExtra == PROC_EX_NORMAL_HIT && (procFlag & SPELL_CAST_TRIGGER_MASK)) + // don't allow proc from cast end for non modifier spells + // unless they have proc ex defined for that + if (spellProcEvent->procEx == PROC_EX_NONE + && procExtra == PROC_EX_CAST_END + && (!IsModifierAura(triggeredByHolder->GetSpellProto(), SpellEffectIndex(i)) || !useCharges)) continue; } // don't check dbc FamilyFlags if schoolMask exists diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 602dddb1a..7c600c6f9 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 "11759" + #define REVISION_NR "11760" #endif // __REVISION_NR_H__