mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-21 15:27:47 -04:00
Merge pull request #12201 from Unholychick/patch-2
Core/Spells: Implement SPELL_ATTR4_FIXED_DAMAGE
This commit is contained in:
@@ -978,86 +978,90 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask);
|
||||
uint32 crTypeMask = victim->GetCreatureTypeMask();
|
||||
|
||||
if (IsDamageReducedByArmor(damageSchoolMask, spellInfo))
|
||||
damage = CalcArmorReducedDamage(victim, damage, spellInfo, attackType);
|
||||
|
||||
bool blocked = false;
|
||||
// Per-school calc
|
||||
switch (spellInfo->DmgClass)
|
||||
// Spells with SPELL_ATTR4_FIXED_DAMAGE ignore resilience because their damage is based off another spell's damage.
|
||||
if (!(spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
|
||||
{
|
||||
// Melee and Ranged Spells
|
||||
case SPELL_DAMAGE_CLASS_RANGED:
|
||||
case SPELL_DAMAGE_CLASS_MELEE:
|
||||
if (IsDamageReducedByArmor(damageSchoolMask, spellInfo))
|
||||
damage = CalcArmorReducedDamage(victim, damage, spellInfo, attackType);
|
||||
|
||||
bool blocked = false;
|
||||
// Per-school calc
|
||||
switch (spellInfo->DmgClass)
|
||||
{
|
||||
// Physical Damage
|
||||
if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
|
||||
// Melee and Ranged Spells
|
||||
case SPELL_DAMAGE_CLASS_RANGED:
|
||||
case SPELL_DAMAGE_CLASS_MELEE:
|
||||
{
|
||||
// Get blocked status
|
||||
blocked = isSpellBlocked(victim, spellInfo, attackType);
|
||||
}
|
||||
// Physical Damage
|
||||
if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
|
||||
{
|
||||
// Get blocked status
|
||||
blocked = isSpellBlocked(victim, spellInfo, attackType);
|
||||
}
|
||||
|
||||
if (crit)
|
||||
{
|
||||
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
|
||||
if (crit)
|
||||
{
|
||||
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
|
||||
|
||||
// Calculate crit bonus
|
||||
uint32 crit_bonus = damage;
|
||||
// Apply crit_damage bonus for melee spells
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
|
||||
damage += crit_bonus;
|
||||
// Calculate crit bonus
|
||||
uint32 crit_bonus = damage;
|
||||
// Apply crit_damage bonus for melee spells
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
|
||||
damage += crit_bonus;
|
||||
|
||||
// Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
|
||||
float critPctDamageMod = 0.0f;
|
||||
if (attackType == RANGED_ATTACK)
|
||||
critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
|
||||
// Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
|
||||
float critPctDamageMod = 0.0f;
|
||||
if (attackType == RANGED_ATTACK)
|
||||
critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
|
||||
else
|
||||
critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
|
||||
|
||||
// Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
|
||||
critPctDamageMod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellInfo->GetSchoolMask()) - 1.0f) * 100;
|
||||
|
||||
// Increase crit damage from SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
|
||||
critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, crTypeMask);
|
||||
|
||||
if (critPctDamageMod != 0)
|
||||
AddPct(damage, critPctDamageMod);
|
||||
}
|
||||
|
||||
// Spell weapon based damage CAN BE crit & blocked at same time
|
||||
if (blocked)
|
||||
{
|
||||
damageInfo->blocked = victim->GetShieldBlockValue();
|
||||
// double blocked amount if block is critical
|
||||
if (victim->isBlockCritical())
|
||||
damageInfo->blocked += damageInfo->blocked;
|
||||
if (damage < int32(damageInfo->blocked))
|
||||
damageInfo->blocked = uint32(damage);
|
||||
damage -= damageInfo->blocked;
|
||||
}
|
||||
|
||||
if (attackType != RANGED_ATTACK)
|
||||
ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_MELEE);
|
||||
else
|
||||
critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
|
||||
|
||||
// Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
|
||||
critPctDamageMod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellInfo->GetSchoolMask()) - 1.0f) * 100;
|
||||
|
||||
// Increase crit damage from SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
|
||||
critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, crTypeMask);
|
||||
|
||||
if (critPctDamageMod != 0)
|
||||
AddPct(damage, critPctDamageMod);
|
||||
ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_RANGED);
|
||||
break;
|
||||
}
|
||||
|
||||
// Spell weapon based damage CAN BE crit & blocked at same time
|
||||
if (blocked)
|
||||
// Magical Attacks
|
||||
case SPELL_DAMAGE_CLASS_NONE:
|
||||
case SPELL_DAMAGE_CLASS_MAGIC:
|
||||
{
|
||||
damageInfo->blocked = victim->GetShieldBlockValue();
|
||||
// double blocked amount if block is critical
|
||||
if (victim->isBlockCritical())
|
||||
damageInfo->blocked += damageInfo->blocked;
|
||||
if (damage < int32(damageInfo->blocked))
|
||||
damageInfo->blocked = uint32(damage);
|
||||
damage -= damageInfo->blocked;
|
||||
}
|
||||
// If crit add critical bonus
|
||||
if (crit)
|
||||
{
|
||||
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
|
||||
damage = SpellCriticalDamageBonus(spellInfo, damage, victim);
|
||||
}
|
||||
|
||||
if (attackType != RANGED_ATTACK)
|
||||
ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_MELEE);
|
||||
else
|
||||
ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_RANGED);
|
||||
break;
|
||||
}
|
||||
// Magical Attacks
|
||||
case SPELL_DAMAGE_CLASS_NONE:
|
||||
case SPELL_DAMAGE_CLASS_MAGIC:
|
||||
{
|
||||
// If crit add critical bonus
|
||||
if (crit)
|
||||
{
|
||||
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
|
||||
damage = SpellCriticalDamageBonus(spellInfo, damage, victim);
|
||||
ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_SPELL);
|
||||
break;
|
||||
}
|
||||
|
||||
ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_SPELL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations
|
||||
@@ -9844,11 +9848,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
|
||||
if (spellProto->AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS)
|
||||
return pdamage;
|
||||
|
||||
// small exception for Deep Wounds, can't find any general rule
|
||||
// should ignore ALL damage mods, they already calculated in trigger spell
|
||||
if (spellProto->Id == 12721) // Deep Wounds
|
||||
return pdamage;
|
||||
|
||||
// For totems get damage bonus from owner
|
||||
if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem())
|
||||
if (Unit* owner = GetOwner())
|
||||
@@ -9864,7 +9863,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
|
||||
DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank);
|
||||
|
||||
// Some spells don't benefit from pct done mods
|
||||
if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !spellProto->IsRankOf(sSpellMgr->GetSpellInfo(12162)))
|
||||
if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS))
|
||||
{
|
||||
AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
|
||||
for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
|
||||
@@ -10261,19 +10260,16 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
|
||||
int32 TakenTotal = 0;
|
||||
float TakenTotalMod = 1.0f;
|
||||
float TakenTotalCasterMod = 0.0f;
|
||||
|
||||
// get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
|
||||
AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
|
||||
for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i)
|
||||
|
||||
// Mod damage from spell mechanic
|
||||
if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
|
||||
{
|
||||
if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
|
||||
TakenTotalCasterMod += (float((*i)->GetAmount()));
|
||||
AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
|
||||
for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
|
||||
if (mechanicMask & uint32(1 << ((*i)->GetMiscValue())))
|
||||
AddPct(TakenTotalMod, (*i)->GetAmount());
|
||||
}
|
||||
|
||||
// from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
|
||||
// multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085)
|
||||
TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask());
|
||||
|
||||
//.. taken pct: dummy auras
|
||||
AuraEffectList const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
|
||||
for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
|
||||
@@ -10292,45 +10288,51 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// From caster spells
|
||||
AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
|
||||
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
|
||||
if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
|
||||
AddPct(TakenTotalMod, (*i)->GetAmount());
|
||||
|
||||
// Mod damage from spell mechanic
|
||||
if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
|
||||
// Spells with SPELL_ATTR4_FIXED_DAMAGE should only benefit from mechanic damage mod auras.
|
||||
if (!(spellProto->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
|
||||
{
|
||||
AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
|
||||
for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
|
||||
if (mechanicMask & uint32(1<<((*i)->GetMiscValue())))
|
||||
AddPct(TakenTotalMod, (*i)->GetAmount());
|
||||
}
|
||||
|
||||
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask());
|
||||
|
||||
// Check for table values
|
||||
float coeff = 0;
|
||||
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
|
||||
if (bonus)
|
||||
coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
|
||||
|
||||
// Default calculation
|
||||
if (TakenAdvertisedBenefit)
|
||||
{
|
||||
if (!bonus || coeff < 0)
|
||||
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
|
||||
|
||||
float factorMod = CalculateLevelPenalty(spellProto) * stack;
|
||||
// level penalty still applied on Taken bonus - is it blizzlike?
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
// get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
|
||||
AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
|
||||
for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i)
|
||||
{
|
||||
coeff *= 100.0f;
|
||||
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
|
||||
coeff /= 100.0f;
|
||||
if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
|
||||
TakenTotalCasterMod += (float((*i)->GetAmount()));
|
||||
}
|
||||
|
||||
// from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
|
||||
// multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085)
|
||||
TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask());
|
||||
|
||||
// From caster spells
|
||||
AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
|
||||
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
|
||||
if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
|
||||
AddPct(TakenTotalMod, (*i)->GetAmount());
|
||||
|
||||
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask());
|
||||
|
||||
// Check for table values
|
||||
float coeff = 0;
|
||||
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
|
||||
if (bonus)
|
||||
coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
|
||||
|
||||
// Default calculation
|
||||
if (TakenAdvertisedBenefit)
|
||||
{
|
||||
if (!bonus || coeff < 0)
|
||||
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
|
||||
|
||||
float factorMod = CalculateLevelPenalty(spellProto) * stack;
|
||||
// level penalty still applied on Taken bonus - is it blizzlike?
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
{
|
||||
coeff *= 100.0f;
|
||||
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
|
||||
coeff /= 100.0f;
|
||||
}
|
||||
TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod);
|
||||
}
|
||||
TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod);
|
||||
}
|
||||
|
||||
float tmpDamage = 0.0f;
|
||||
|
||||
@@ -427,7 +427,7 @@ enum SpellAttr4
|
||||
SPELL_ATTR4_UNK5 = 0x00000020, // 5
|
||||
SPELL_ATTR4_NOT_STEALABLE = 0x00000040, // 6 although such auras might be dispellable, they cannot be stolen
|
||||
SPELL_ATTR4_TRIGGERED = 0x00000080, // 7 spells forced to be triggered
|
||||
SPELL_ATTR4_FIXED_DAMAGE = 0x00000100, // 8 ignores taken percent damage mods?
|
||||
SPELL_ATTR4_FIXED_DAMAGE = 0x00000100, // 8 Ignores resilience and any (except mechanic related) damage or % damage taken auras on target.
|
||||
SPELL_ATTR4_TRIGGER_ACTIVATE = 0x00000200, // 9 initially disabled / trigger activate from event (Execute, Riposte, Deep Freeze end other)
|
||||
SPELL_ATTR4_SPELL_VS_EXTEND_COST = 0x00000400, // 10 Rogue Shiv have this flag
|
||||
SPELL_ATTR4_UNK11 = 0x00000800, // 11
|
||||
|
||||
@@ -5856,7 +5856,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
|
||||
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
|
||||
|
||||
int32 dmg = damage;
|
||||
caster->ApplyResilience(target, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
|
||||
if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
|
||||
caster->ApplyResilience(target, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
|
||||
damage = dmg;
|
||||
|
||||
caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, GetSpellInfo());
|
||||
@@ -5923,7 +5924,8 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
|
||||
}
|
||||
|
||||
int32 dmg = damage;
|
||||
caster->ApplyResilience(target, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
|
||||
if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
|
||||
caster->ApplyResilience(target, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
|
||||
damage = dmg;
|
||||
|
||||
caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, m_spellInfo);
|
||||
|
||||
@@ -3207,6 +3207,9 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
case 63675: // Improved Devouring Plague
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
|
||||
break;
|
||||
case 12721: // Deep Wounds shouldnt ignore resillience or damage taken auras because its damage is not based off a spell.
|
||||
spellInfo->AttributesEx4 = 0;
|
||||
break;
|
||||
case 8145: // Tremor Totem (instant pulse)
|
||||
case 6474: // Earthbind Totem (instant pulse)
|
||||
spellInfo->AttributesEx5 |= SPELL_ATTR5_START_PERIODIC_AT_APPLY;
|
||||
|
||||
Reference in New Issue
Block a user