Fix a crash caused by 0ac431f52d. Close #4418.

This commit is contained in:
megamage
2011-12-23 11:09:09 -05:00
parent 07c294b0c2
commit e6a3dc679f
+168 -163
View File
@@ -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);