[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

This commit is contained in:
Laise 2011-07-29 09:37:32 +03:00
parent 0220101f7e
commit 98bd7918f4
6 changed files with 37 additions and 20 deletions

View file

@ -3200,6 +3200,10 @@ void Spell::cast(bool skipCheck)
InitializeDamageMultipliers(); 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 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
if (m_spellInfo->speed > 0.0f) 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, // critical hit related part is currently done on hit so proc there,
// 0 damage since any damage based procs should be on hit // 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 // 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 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 // Immediate spell, no big deal
handle_immediate(); handle_immediate();

View file

@ -865,19 +865,15 @@ bool Aura::CanProcFrom(SpellEntry const *spell, uint32 procFlag, uint32 EventPro
{ {
if (!(EventProcEx & PROC_EX_EX_TRIGGER_ALWAYS)) 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 // Check for extra req (if none) and hit/crit
if (EventProcEx == PROC_EX_NONE) 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 // 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) if((procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && active)
return true; return true;

View file

@ -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)) if (EventProcFlag & (PROC_FLAG_ON_DO_PERIODIC | PROC_FLAG_ON_TAKE_PERIODIC) && (procExtra & PROC_EX_PERIODIC_POSITIVE))
return false; return false;
// No extra req, so can trigger for (damage/healing present) and hit/crit // No extra req, so can trigger for (damage/healing present) and cast end/hit/crit
if(procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) if (procExtra & (PROC_EX_CAST_END|PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT))
return true; return true;
} }
else // all spells hits here only if resist/reflect/immune/evade else // all spells hits here only if resist/reflect/immune/evade

View file

@ -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) inline bool IsSpellHaveAura(SpellEntry const *spellInfo, AuraType aura)
{ {
for(int i = 0; i < MAX_EFFECT_INDEX; ++i) for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
@ -623,7 +637,8 @@ enum ProcFlagsEx
PROC_EX_RESERVED3 = 0x0008000, 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_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_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 struct SpellProcEventEntry

View file

@ -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 ) 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 // 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 // Update skills here for players
if (GetTypeId() == TYPEID_PLAYER) if (GetTypeId() == TYPEID_PLAYER)
@ -9750,9 +9750,11 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (!procSpell->IsFitToFamilyMask(spellProcEvent->spellFamilyMask[i])) if (!procSpell->IsFitToFamilyMask(spellProcEvent->spellFamilyMask[i]))
continue; continue;
// modifier aura procs by default are not active and only allowed with non zero charges // don't allow proc from cast end for non modifier spells
// procEx == PROC_EX_NORMAL_HIT only for real "on cast" cases // unless they have proc ex defined for that
if (!useCharges && damage == 0 && procExtra == PROC_EX_NORMAL_HIT && (procFlag & SPELL_CAST_TRIGGER_MASK)) if (spellProcEvent->procEx == PROC_EX_NONE
&& procExtra == PROC_EX_CAST_END
&& (!IsModifierAura(triggeredByHolder->GetSpellProto(), SpellEffectIndex(i)) || !useCharges))
continue; continue;
} }
// don't check dbc FamilyFlags if schoolMask exists // don't check dbc FamilyFlags if schoolMask exists

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11759" #define REVISION_NR "11760"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__