aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-01-13 19:57:20 -0300
committerariel- <ariel-@users.noreply.github.com>2018-01-13 20:49:44 -0300
commitd570e2af3e7bcb625d8941397d55972d49319a8f (patch)
treed1f0e8cfa2651b34b808255b3a03260182ae0ba3
parenta3056617854ec3957ed57126e27c6b3bea066448 (diff)
Core/Unit: simplified and arranged spell bonus calculation
- Remove duplicated SPELLMOD_BONUS_MULTIPLIER handling (both on done and taken) - Handle properly bonus data, don't apply bonus by default, only player spells should take into account spell power - Moved Earthliving Weapon coefficient to DB - Refactored Avenging Wrath handling Closes #13287 Closes #21230
-rw-r--r--sql/updates/world/3.3.5/2018_01_13_01_world_335.sql8
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp159
2 files changed, 73 insertions, 94 deletions
diff --git a/sql/updates/world/3.3.5/2018_01_13_01_world_335.sql b/sql/updates/world/3.3.5/2018_01_13_01_world_335.sql
new file mode 100644
index 00000000000..9672b738d25
--- /dev/null
+++ b/sql/updates/world/3.3.5/2018_01_13_01_world_335.sql
@@ -0,0 +1,8 @@
+DELETE FROM `spell_bonus_data` WHERE `entry` IN (51945, 51990, 51997, 51998, 51999, 52000);
+INSERT INTO `spell_bonus_data` (`entry`, `direct_bonus`, `dot_bonus`, `ap_bonus`, `ap_dot_bonus`, `comments`) VALUES
+(51945, 0, 0.1692, 0, 0, 'Shaman - Earthliving Weapon (Rank 1)'),
+(51990, 0, 0.1692, 0, 0, 'Shaman - Earthliving Weapon (Rank 2)'),
+(51997, 0, 0.1692, 0, 0, 'Shaman - Earthliving Weapon (Rank 3)'),
+(51998, 0, 0.1692, 0, 0, 'Shaman - Earthliving Weapon (Rank 4)'),
+(51999, 0, 0.1692, 0, 0, 'Shaman - Earthliving Weapon (Rank 5)'),
+(52000, 0, 0.1692, 0, 0, 'Shaman - Earthliving Weapon (Rank 6)');
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 620cbc31555..2082b974ef6 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -6771,8 +6771,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
// Check for table values
float coeff = 0.f;
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- if (bonus)
+ if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
{
WeaponAttackType const attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
@@ -6793,19 +6792,16 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
}
// Default calculation
- if (DoneAdvertisedBenefit)
+ if (coeff && DoneAdvertisedBenefit)
{
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
-
float factorMod = CalculateLevelPenalty(spellProto) * stack;
-
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
+
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
@@ -7134,7 +7130,6 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
int32 TakenTotal = 0;
float TakenTotalMod = 1.0f;
- float TakenTotalCasterMod = 0.0f;
// Mod damage from spell mechanic
if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
@@ -7166,67 +7161,64 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
break;
}
}
- // Spells with SPELL_ATTR4_FIXED_DAMAGE should only benefit from mechanic damage mod auras.
+
+ // Spells with SPELL_ATTR4_FIXED_DAMAGE should only benefit from mechanic damage mod auras.
if (!spellProto->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
{
- // get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
- TakenTotalCasterMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_IGNORE_TARGET_RESIST, spellProto->GetSchoolMask());
-
// 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
- TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_DAMAGE_FROM_CASTER, [caster, spellProto](AuraEffect const* aurEff) -> bool
+ if (caster)
{
- if (aurEff->GetCasterGUID() == caster->GetGUID() && aurEff->IsAffectedOnSpell(spellProto))
- return true;
- return false;
- });
+ TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_DAMAGE_FROM_CASTER, [caster, spellProto](AuraEffect const* aurEff) -> bool
+ {
+ if (aurEff->GetCasterGUID() == caster->GetGUID() && aurEff->IsAffectedOnSpell(spellProto))
+ return true;
+ return false;
+ });
+ }
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask());
// Check for table values
- float coeff = 0;
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- if (bonus)
+ float coeff = 0.f;
+ if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
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())
+ if (coeff < 0.f)
{
- coeff *= 100.0f;
- modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
- coeff /= 100.0f;
+ Unit const* calc = caster ? caster : this;
+ coeff = calc->CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
}
+
+ // level penalty still applied on Taken bonus - is it blizzlike?
+ float factorMod = CalculateLevelPenalty(spellProto) * stack;
TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod);
}
}
- float tmpDamage = 0.0f;
-
- if (TakenTotalCasterMod)
+ // Sanctified Wrath (bypass damage reduction)
+ if (caster && TakenTotalMod < 1.0f)
{
- if (TakenTotal < 0)
+ float damageReduction = 1.0f - TakenTotalMod;
+ Unit::AuraEffectList const& casterIgnoreResist = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffect const* aurEff : casterIgnoreResist)
{
- if (TakenTotalMod < 1)
- tmpDamage = ((float(CalculatePct(pdamage, TakenTotalCasterMod) + TakenTotal) * TakenTotalMod) + CalculatePct(pdamage, TakenTotalCasterMod));
- else
- tmpDamage = ((float(CalculatePct(pdamage, TakenTotalCasterMod) + TakenTotal) + CalculatePct(pdamage, TakenTotalCasterMod)) * TakenTotalMod);
+ if (!(aurEff->GetMiscValue() & spellProto->GetSchoolMask()))
+ continue;
+
+ ApplyPct(damageReduction, aurEff->GetAmount());
}
- else if (TakenTotalMod < 1)
- tmpDamage = ((CalculatePct(float(pdamage) + TakenTotal, TakenTotalCasterMod) * TakenTotalMod) + CalculatePct(float(pdamage) + TakenTotal, TakenTotalCasterMod));
+
+ TakenTotalMod = 1.0f - damageReduction;
}
- if (!tmpDamage)
- tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod;
+ float tmpDamage = float(pdamage + TakenTotal) * TakenTotalMod;
return uint32(std::max(tmpDamage, 0.0f));
}
@@ -7641,10 +7633,8 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask());
// Check for table values
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- float coeff = 0;
- float factorMod = 1.0f;
- if (bonus)
+ float coeff = 0.f;
+ if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
{
if (damagetype == DOT)
{
@@ -7669,13 +7659,9 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
}
// Default calculation
- if (DoneAdvertisedBenefit)
+ if (coeff && DoneAdvertisedBenefit)
{
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
-
- factorMod *= CalculateLevelPenalty(spellProto) * stack;
-
+ float factorMod = CalculateLevelPenalty(spellProto) * stack;
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
@@ -7683,10 +7669,6 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
coeff /= 100.0f;
}
- // Earthliving - 0.45% of normal hot coeff
- if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
- factorMod *= 0.45f;
-
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
@@ -7838,10 +7820,8 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
}
// Check for table values
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
float coeff = 0;
- float factorMod = 1.0f;
- if (bonus)
+ if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
else
{
@@ -7856,30 +7836,26 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
// Default calculation
if (TakenAdvertisedBenefit)
{
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
-
- factorMod *= CalculateLevelPenalty(spellProto) * int32(stack);
- if (Player* modOwner = GetSpellModOwner())
+ if (coeff < 0.f)
{
- coeff *= 100.0f;
- modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
- coeff /= 100.0f;
+ Unit const* calc = caster ? caster : this;
+ coeff = calc->CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
}
- // Earthliving - 0.45% of normal hot coeff
- if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
- factorMod *= 0.45f;
-
+ // level penalty still applied on Taken bonus - is it blizzlike?
+ float factorMod = CalculateLevelPenalty(spellProto) * int32(stack);
TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod);
}
- TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_RECEIVED, [caster, spellProto](AuraEffect const* aurEff) -> bool
+ if (caster)
{
- if (caster->GetGUID() == aurEff->GetCasterGUID() && aurEff->IsAffectedOnSpell(spellProto))
- return true;
- return false;
- });
+ TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_RECEIVED, [caster, spellProto](AuraEffect const* aurEff) -> bool
+ {
+ if (caster->GetGUID() == aurEff->GetCasterGUID() && aurEff->IsAffectedOnSpell(spellProto))
+ return true;
+ return false;
+ });
+ }
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
@@ -8299,11 +8275,6 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
return 0;
int32 TakenFlatBenefit = 0;
- float TakenTotalCasterMod = 0.0f;
-
- // get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
- SpellSchoolMask const attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL;
- TakenTotalCasterMod += attacker->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_IGNORE_TARGET_RESIST, attackSchoolMask);
// ..taken
TakenFlatBenefit += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, attacker->GetMeleeDamageSchoolMask());
@@ -8382,24 +8353,25 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
else
TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
- float tmpDamage = 0.0f;
-
- if (TakenTotalCasterMod)
+ // Sanctified Wrath (bypass damage reduction)
+ if (attacker && TakenTotalMod < 1.0f)
{
- if (TakenFlatBenefit < 0)
+ SpellSchoolMask const attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL;
+
+ float damageReduction = 1.0f - TakenTotalMod;
+ Unit::AuraEffectList const& casterIgnoreResist = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffect const* aurEff : casterIgnoreResist)
{
- if (TakenTotalMod < 1)
- tmpDamage = ((float(CalculatePct(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) * TakenTotalMod) + CalculatePct(pdamage, TakenTotalCasterMod));
- else
- tmpDamage = ((float(CalculatePct(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) + CalculatePct(pdamage, TakenTotalCasterMod)) * TakenTotalMod);
+ if (!(aurEff->GetMiscValue() & attackSchoolMask))
+ continue;
+
+ ApplyPct(damageReduction, aurEff->GetAmount());
}
- else if (TakenTotalMod < 1)
- tmpDamage = ((CalculatePct(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod) * TakenTotalMod) + CalculatePct(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod));
+
+ TakenTotalMod = 1.0f - damageReduction;
}
- if (!tmpDamage)
- tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;
- // bonus result can be negative
+ float tmpDamage = float(pdamage + TakenFlatBenefit) * TakenTotalMod;
return uint32(std::max(tmpDamage, 0.0f));
}
@@ -11505,7 +11477,6 @@ float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffect
float DotFactor = 1.0f;
if (damagetype == DOT)
{
-
int32 DotDuration = spellInfo->GetDuration();
if (!spellInfo->IsChanneled() && DotDuration > 0)
DotFactor = DotDuration / 15000.0f;