Fix a crash caused by 0ac431f52d. Close #4418.
This commit is contained in:
@@ -14313,6 +14313,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
if (procTriggered.empty())
|
||||
return;
|
||||
|
||||
// Note: must SetCantProc(false) before return
|
||||
if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC))
|
||||
SetCantProc(true);
|
||||
|
||||
@@ -14337,6 +14338,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
|
||||
cooldown = i->spellProcEvent->cooldown;
|
||||
|
||||
// Note: must SetCantProc(false) before return
|
||||
if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC)
|
||||
SetCantProc(true);
|
||||
|
||||
@@ -14349,176 +14351,179 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
|
||||
{
|
||||
if (!(i->effMask & (1<<effIndex)))
|
||||
continue;
|
||||
|
||||
AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
|
||||
ASSERT(triggeredByAura);
|
||||
|
||||
switch (triggeredByAura->GetAuraType())
|
||||
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
|
||||
{
|
||||
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
// Don`t drop charge or add cooldown for not started trigger
|
||||
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
|
||||
{
|
||||
// target has to be valid
|
||||
if (!target)
|
||||
return;
|
||||
if (!(i->effMask & (1<<effIndex)))
|
||||
continue;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask);
|
||||
uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
|
||||
CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo);
|
||||
DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
|
||||
SendSpellNonMeleeDamageLog(&damageInfo);
|
||||
DealSpellDamage(&damageInfo, true);
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MANA_SHIELD:
|
||||
case SPELL_AURA_DUMMY:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_OBS_MOD_POWER:
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleObsModEnergyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleModDamagePctTakenAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_MELEE_HASTE:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleHasteAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
|
||||
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
|
||||
ASSERT(triggeredByAura);
|
||||
|
||||
HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_RAID_PROC_FROM_CHARGE:
|
||||
switch (triggeredByAura->GetAuraType())
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
|
||||
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
|
||||
HandleAuraRaidProcFromCharge(triggeredByAura);
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
|
||||
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
|
||||
// Skip melee hits or instant cast spells
|
||||
if (procSpell && procSpell->CalcCastTime() != 0)
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
|
||||
// Skip Melee hits and spells ws wrong school
|
||||
if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
|
||||
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
|
||||
// Skip melee hits and spells ws wrong school or zero cost
|
||||
if (procSpell &&
|
||||
(procSpell->ManaCost != 0 || procSpell->ManaCostPercentage != 0) && // Cost check
|
||||
(triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MECHANIC_IMMUNITY:
|
||||
// Compare mechanic
|
||||
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
|
||||
// Compare mechanic
|
||||
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
|
||||
// Compare casters
|
||||
if (triggeredByAura->GetCasterGUID() == target->GetGUID())
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (procSpell && HandleSpellCritChanceAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
// CC Auras which use their amount amount to drop
|
||||
// Are there any more auras which need this?
|
||||
case SPELL_AURA_MOD_CONFUSE:
|
||||
case SPELL_AURA_MOD_FEAR:
|
||||
case SPELL_AURA_MOD_STUN:
|
||||
case SPELL_AURA_MOD_ROOT:
|
||||
case SPELL_AURA_TRANSFORM:
|
||||
{
|
||||
// chargeable mods are breaking on hit
|
||||
if (useCharges)
|
||||
takeCharges = true;
|
||||
else
|
||||
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
||||
{
|
||||
// Spell own direct damage at apply wont break the CC
|
||||
if (procSpell && (procSpell->Id == triggeredByAura->GetId()))
|
||||
{
|
||||
Aura* aura = triggeredByAura->GetBase();
|
||||
// called from spellcast, should not have ticked yet
|
||||
if (aura->GetDuration() == aura->GetMaxDuration())
|
||||
break;
|
||||
}
|
||||
int32 damageLeft = triggeredByAura->GetAmount();
|
||||
// No damage left
|
||||
if (damageLeft < int32(damage))
|
||||
i->aura->Remove();
|
||||
else
|
||||
triggeredByAura->SetAmount(damageLeft - damage);
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
// Don`t drop charge or add cooldown for not started trigger
|
||||
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//case SPELL_AURA_ADD_FLAT_MODIFIER:
|
||||
//case SPELL_AURA_ADD_PCT_MODIFIER:
|
||||
// HandleSpellModAuraProc
|
||||
//break;
|
||||
default:
|
||||
// nothing do, just charges counter
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
|
||||
{
|
||||
// target has to be valid
|
||||
if (!target)
|
||||
break;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask);
|
||||
uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
|
||||
CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo);
|
||||
DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
|
||||
SendSpellNonMeleeDamageLog(&damageInfo);
|
||||
DealSpellDamage(&damageInfo, true);
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MANA_SHIELD:
|
||||
case SPELL_AURA_DUMMY:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_OBS_MOD_POWER:
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleObsModEnergyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleModDamagePctTakenAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_MELEE_HASTE:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleHasteAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
|
||||
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
|
||||
HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_RAID_PROC_FROM_CHARGE:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
|
||||
(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
|
||||
HandleAuraRaidProcFromCharge(triggeredByAura);
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
|
||||
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
|
||||
// Skip melee hits or instant cast spells
|
||||
if (procSpell && procSpell->CalcCastTime() != 0)
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
|
||||
// Skip Melee hits and spells ws wrong school
|
||||
if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
|
||||
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
|
||||
// Skip melee hits and spells ws wrong school or zero cost
|
||||
if (procSpell &&
|
||||
(procSpell->ManaCost != 0 || procSpell->ManaCostPercentage != 0) && // Cost check
|
||||
(triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MECHANIC_IMMUNITY:
|
||||
// Compare mechanic
|
||||
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
|
||||
// Compare mechanic
|
||||
if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
|
||||
// Compare casters
|
||||
if (triggeredByAura->GetCasterGUID() == target->GetGUID())
|
||||
takeCharges = true;
|
||||
break;
|
||||
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
|
||||
if (procSpell && HandleSpellCritChanceAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
|
||||
takeCharges = true;
|
||||
break;
|
||||
// CC Auras which use their amount amount to drop
|
||||
// Are there any more auras which need this?
|
||||
case SPELL_AURA_MOD_CONFUSE:
|
||||
case SPELL_AURA_MOD_FEAR:
|
||||
case SPELL_AURA_MOD_STUN:
|
||||
case SPELL_AURA_MOD_ROOT:
|
||||
case SPELL_AURA_TRANSFORM:
|
||||
{
|
||||
// chargeable mods are breaking on hit
|
||||
if (useCharges)
|
||||
takeCharges = true;
|
||||
else
|
||||
{
|
||||
// Spell own direct damage at apply wont break the CC
|
||||
if (procSpell && (procSpell->Id == triggeredByAura->GetId()))
|
||||
{
|
||||
Aura* aura = triggeredByAura->GetBase();
|
||||
// called from spellcast, should not have ticked yet
|
||||
if (aura->GetDuration() == aura->GetMaxDuration())
|
||||
break;
|
||||
}
|
||||
int32 damageLeft = triggeredByAura->GetAmount();
|
||||
// No damage left
|
||||
if (damageLeft < int32(damage))
|
||||
i->aura->Remove();
|
||||
else
|
||||
triggeredByAura->SetAmount(damageLeft - damage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//case SPELL_AURA_ADD_FLAT_MODIFIER:
|
||||
//case SPELL_AURA_ADD_PCT_MODIFIER:
|
||||
// HandleSpellModAuraProc
|
||||
//break;
|
||||
default:
|
||||
// nothing do, just charges counter
|
||||
takeCharges = true;
|
||||
break;
|
||||
} // switch (triggeredByAura->GetAuraType())
|
||||
} // for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
|
||||
} // if (!handled)
|
||||
|
||||
// Remove charge (aura can be removed by triggers)
|
||||
if (useCharges && takeCharges)
|
||||
i->aura->DropCharge(AURA_REMOVE_BY_EXPIRE);
|
||||
|
||||
Reference in New Issue
Block a user