aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp232
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp6
-rw-r--r--src/server/game/Spells/SpellMgr.cpp3
4 files changed, 125 insertions, 118 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 8b09df988cf..4efa1374ec7 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -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;
-
- // 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);
- else
- critPctDamageMod += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
+ 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;
+
+ // 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_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);
+ // 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);
- }
+ 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;
- }
+ // 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
- 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);
+ 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;
}
}
+ // Spells with SPELL_ATTR4_FIXED_DAMAGE should only benefit from mechanic damage mod auras.
+ if (!(spellProto->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
+ {
+ // 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)
+ {
+ if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
+ TakenTotalCasterMod += (float((*i)->GetAmount()));
+ }
- // 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());
+ // 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());
- // Mod damage from spell mechanic
- if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
- {
- 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())))
+ // 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());
+ 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;
+ // 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())
+ // Default calculation
+ if (TakenAdvertisedBenefit)
{
- coeff *= 100.0f;
- modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
- coeff /= 100.0f;
+ 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;
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index fdf06a8f7e3..4ec1d5750a4 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -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
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index b87524357d2..2096f21e5a1 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -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);
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 501cb1e77f2..4aced0c92dd 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -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;