*Fix 'crazy procs' issue and shadowstep remove on stealth.
--HG-- branch : trunk
This commit is contained in:
+43
-27
@@ -758,6 +758,7 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura)
|
|||||||
// Create base triggers flags for Attacker and Victim ( m_procAttacker, m_procVictim and m_procEx)
|
// Create base triggers flags for Attacker and Victim ( m_procAttacker, m_procVictim and m_procEx)
|
||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
|
|
||||||
|
m_procVictim = m_procAttacker = 0;
|
||||||
// Get data for type of attack and fill base info for trigger
|
// Get data for type of attack and fill base info for trigger
|
||||||
switch (m_spellInfo->DmgClass)
|
switch (m_spellInfo->DmgClass)
|
||||||
{
|
{
|
||||||
@@ -779,37 +780,15 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell
|
if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON &&
|
||||||
{
|
m_spellInfo->EquippedItemSubClassMask & ITEM_SUBCLASS_WEAPON_WAND
|
||||||
if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE)
|
&& m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG) // Wands auto attack
|
||||||
{
|
|
||||||
m_procAttacker = PROC_FLAG_SUCCESSFUL_HEALING_SPELL;
|
|
||||||
m_procVictim = PROC_FLAG_TAKEN_HEALING_SPELL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_procAttacker = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
|
|
||||||
m_procVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG) // Wands auto attack
|
|
||||||
{
|
{
|
||||||
m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_HIT;
|
m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_HIT;
|
||||||
m_procVictim = PROC_FLAG_TAKEN_RANGED_HIT;
|
m_procVictim = PROC_FLAG_TAKEN_RANGED_HIT;
|
||||||
}
|
}
|
||||||
else // Negative spell
|
// For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
|
||||||
{
|
// Because spell positivity is dependant on target
|
||||||
if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE)
|
|
||||||
{
|
|
||||||
m_procAttacker = PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT;
|
|
||||||
m_procVictim = PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_procAttacker = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
|
|
||||||
m_procVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_procEx= PROC_EX_NONE;
|
m_procEx= PROC_EX_NONE;
|
||||||
|
|
||||||
@@ -1109,6 +1088,12 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||||||
// Do healing and triggers
|
// Do healing and triggers
|
||||||
if (m_healing > 0)
|
if (m_healing > 0)
|
||||||
{
|
{
|
||||||
|
// Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
|
||||||
|
if (canEffectTrigger && !procAttacker && !procVictim)
|
||||||
|
{
|
||||||
|
procAttacker |= PROC_FLAG_SUCCESSFUL_HEALING_SPELL;
|
||||||
|
procVictim |= PROC_FLAG_TAKEN_HEALING_SPELL;
|
||||||
|
}
|
||||||
bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
|
bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
|
||||||
uint32 addhealth = m_healing;
|
uint32 addhealth = m_healing;
|
||||||
if (crit)
|
if (crit)
|
||||||
@@ -1132,6 +1117,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||||||
// Do damage and triggers
|
// Do damage and triggers
|
||||||
else if (m_damage > 0)
|
else if (m_damage > 0)
|
||||||
{
|
{
|
||||||
|
// Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
|
||||||
|
if (canEffectTrigger && !procAttacker && !procVictim)
|
||||||
|
{
|
||||||
|
procAttacker |= PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT;
|
||||||
|
procVictim |= PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT;
|
||||||
|
}
|
||||||
|
|
||||||
// Fill base damage struct (unitTarget - is real spell target)
|
// Fill base damage struct (unitTarget - is real spell target)
|
||||||
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
|
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
|
||||||
|
|
||||||
@@ -1168,6 +1160,30 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||||||
// Passive spell hits/misses or active spells only misses (only triggers)
|
// Passive spell hits/misses or active spells only misses (only triggers)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
|
||||||
|
if (canEffectTrigger && !procAttacker && !procVictim)
|
||||||
|
{
|
||||||
|
// Check spell positivity on target
|
||||||
|
bool positive = true;
|
||||||
|
for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
|
||||||
|
// If at least one effect negative spell is negative hit
|
||||||
|
if (mask & (1<<i) && !IsPositiveEffect(m_spellInfo->Id, i))
|
||||||
|
{
|
||||||
|
positive = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (positive)
|
||||||
|
{
|
||||||
|
procAttacker |= PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
|
||||||
|
procVictim |= PROC_FLAG_TAKEN_POSITIVE_SPELL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
procAttacker |= PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
|
||||||
|
procVictim |= PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fill base damage struct (unitTarget - is real spell target)
|
// Fill base damage struct (unitTarget - is real spell target)
|
||||||
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
|
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
|
||||||
procEx |= createProcExtendMask(&damageInfo, missInfo);
|
procEx |= createProcExtendMask(&damageInfo, missInfo);
|
||||||
|
|||||||
@@ -1268,7 +1268,7 @@ void SpellMgr::LoadSpellBonusess()
|
|||||||
sLog.outString( ">> Loaded %u extra spell bonus data", count);
|
sLog.outString( ">> Loaded %u extra spell bonus data", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra)
|
bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
|
||||||
{
|
{
|
||||||
// No extra req need
|
// No extra req need
|
||||||
uint32 procEvent_procEx = PROC_EX_NONE;
|
uint32 procEvent_procEx = PROC_EX_NONE;
|
||||||
@@ -1356,6 +1356,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
|
|||||||
if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0)
|
if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0)
|
||||||
return false;
|
return false;
|
||||||
hasFamilyMask = true;
|
hasFamilyMask = true;
|
||||||
|
active = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1369,8 +1370,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
|
|||||||
// Check for extra req (if none) and hit/crit
|
// Check for extra req (if none) and hit/crit
|
||||||
if (procEvent_procEx == PROC_EX_NONE)
|
if (procEvent_procEx == PROC_EX_NONE)
|
||||||
{
|
{
|
||||||
// No extra req, so can trigger only for hit/crit
|
// No extra req, so can trigger only for hit/crit - spell has to be active or to have PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT
|
||||||
if((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)))
|
if((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && (active || procFlags & PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else // Passive spells hits here only if resist/reflect/immune/evade
|
else // Passive spells hits here only if resist/reflect/immune/evade
|
||||||
|
|||||||
+5
-5
@@ -393,7 +393,7 @@ enum ProcFlags
|
|||||||
PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor
|
PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor
|
||||||
PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward)
|
PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward)
|
||||||
|
|
||||||
PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee auto attack
|
PROC_FLAG_SUCCESSFUL_MELEE_HIT = 0x00000004, // 02 Successful melee auto attack
|
||||||
PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee auto attack hit
|
PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee auto attack hit
|
||||||
|
|
||||||
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon
|
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon
|
||||||
@@ -429,7 +429,7 @@ enum ProcFlags
|
|||||||
PROC_FLAG_DEATH = 0x01000000 // 24 Died in any way
|
PROC_FLAG_DEATH = 0x01000000 // 24 Died in any way
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MILEE_HIT | \
|
#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MELEE_HIT | \
|
||||||
PROC_FLAG_TAKEN_MELEE_HIT | \
|
PROC_FLAG_TAKEN_MELEE_HIT | \
|
||||||
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT | \
|
PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT | \
|
||||||
PROC_FLAG_TAKEN_MELEE_SPELL_HIT | \
|
PROC_FLAG_TAKEN_MELEE_SPELL_HIT | \
|
||||||
@@ -458,9 +458,9 @@ enum ProcFlagsEx
|
|||||||
PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // aura remove by default and by cancel
|
PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // aura remove by default and by cancel
|
||||||
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_INTERNAL_CANT_PROC = 0x0800000,
|
PROC_EX_INTERNAL_CANT_PROC = 0x0800000, // Only for internal use
|
||||||
PROC_EX_INTERNAL_DOT = 0x1000000, // Only for internal use
|
PROC_EX_INTERNAL_DOT = 0x1000000, // Only for internal use
|
||||||
PROC_EX_INTERNAL_HOT = 0x2000000, // Only for internal use
|
PROC_EX_INTERNAL_HOT = 0x2000000, // Only for internal use
|
||||||
PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use
|
PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use
|
||||||
PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000 // Only for internal use
|
PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000 // Only for internal use
|
||||||
};
|
};
|
||||||
@@ -769,7 +769,7 @@ class SpellMgr
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra);
|
bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
|
||||||
|
|
||||||
SpellEnchantProcEntry const* GetSpellEnchantProcEvent(uint32 enchId) const
|
SpellEnchantProcEntry const* GetSpellEnchantProcEvent(uint32 enchId) const
|
||||||
{
|
{
|
||||||
|
|||||||
+5
-4
@@ -1439,12 +1439,12 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
|
|||||||
switch (attackType)
|
switch (attackType)
|
||||||
{
|
{
|
||||||
case BASE_ATTACK:
|
case BASE_ATTACK:
|
||||||
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MILEE_HIT;
|
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_HIT;
|
||||||
damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT;
|
damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT;
|
||||||
damageInfo->HitInfo = HITINFO_NORMALSWING2;
|
damageInfo->HitInfo = HITINFO_NORMALSWING2;
|
||||||
break;
|
break;
|
||||||
case OFF_ATTACK:
|
case OFF_ATTACK:
|
||||||
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MILEE_HIT | PROC_FLAG_SUCCESSFUL_OFFHAND_HIT;
|
damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_HIT | PROC_FLAG_SUCCESSFUL_OFFHAND_HIT;
|
||||||
damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT;//|PROC_FLAG_TAKEN_OFFHAND_HIT // not used
|
damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT;//|PROC_FLAG_TAKEN_OFFHAND_HIT // not used
|
||||||
damageInfo->HitInfo = HITINFO_LEFTSWING;
|
damageInfo->HitInfo = HITINFO_LEFTSWING;
|
||||||
break;
|
break;
|
||||||
@@ -2982,7 +2982,7 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
|
|||||||
if (reflectchance > 0 && roll_chance_i(reflectchance))
|
if (reflectchance > 0 && roll_chance_i(reflectchance))
|
||||||
{
|
{
|
||||||
// Start triggers for remove charges if need (trigger only for victim, and mark as active spell)
|
// Start triggers for remove charges if need (trigger only for victim, and mark as active spell)
|
||||||
ProcDamageAndSpell(pVictim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT, PROC_EX_REFLECT, 0, BASE_ATTACK, spell);
|
ProcDamageAndSpell(pVictim, PROC_FLAG_NONE, PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT, PROC_EX_REFLECT, 1, BASE_ATTACK, spell);
|
||||||
return SPELL_MISS_REFLECT;
|
return SPELL_MISS_REFLECT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12834,6 +12834,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
|
|||||||
// Remove charge (aura can be removed by triggers)
|
// Remove charge (aura can be removed by triggers)
|
||||||
if(useCharges && takeCharges)
|
if(useCharges && takeCharges)
|
||||||
{
|
{
|
||||||
|
sLog.outError("%d, %d, %d", Id, procSpell? procSpell->Id : 0, procFlag);
|
||||||
i->aura->DropAuraCharge();
|
i->aura->DropAuraCharge();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13480,7 +13481,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check spellProcEvent data requirements
|
// Check spellProcEvent data requirements
|
||||||
if(!spellmgr.IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra))
|
if(!spellmgr.IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
|
||||||
return false;
|
return false;
|
||||||
// In most cases req get honor or XP from kill
|
// In most cases req get honor or XP from kill
|
||||||
if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER)
|
if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER)
|
||||||
|
|||||||
Reference in New Issue
Block a user