diff options
| author | ariel- <ariel-@users.noreply.github.com> | 2018-02-12 16:52:59 -0300 | 
|---|---|---|
| committer | ariel- <ariel-@users.noreply.github.com> | 2018-02-12 16:52:59 -0300 | 
| commit | 4d14f613f3d0dc579e2ca4b8dead65ac6e43965d (patch) | |
| tree | a4d525db74b56688392e0e293d8c2fa45f7e4082 /src | |
| parent | e73bfe8df89e4fb6aecc7cb3a1e266e868510799 (diff) | |
Core/Unit: corrected calculation for SPELL_AURA_MOD_DAMAGE_TAKEN/SPELL_AURA_MOD_HEALING auras
- Spell bonus calculation and penalty was done twice, but it's simply flat +SP, which should be taken into account before other bonuses
- Fixed missing code from SpellDamageBonusDone/SpellHealingBonusDone and killed multiplication by stack amount twice for default coefficient spells (already multiplied on level penalty)
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 123 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_paladin.cpp | 16 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_shaman.cpp | 20 | 
4 files changed, 58 insertions, 103 deletions
| diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 34838bd3f67..ee89eab0cbc 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6883,6 +6883,9 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin      // Done fixed damage bonus auras      int32 DoneAdvertisedBenefit  = SpellBaseDamageBonusDone(spellProto->GetSchoolMask()); +    // modify spell power by victim's SPELL_AURA_MOD_DAMAGE_TAKEN auras (eg Amplify/Dampen Magic) +    DoneAdvertisedBenefit += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, spellProto->GetSchoolMask()); +      // Pets just add their bonus damage to their spell damage      // note that their spell damage is just gain of their own auras      if (HasUnitTypeMask(UNIT_MASK_GUARDIAN)) @@ -6909,10 +6912,19 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin                  DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);          }      } +    else +    { +        // No bonus damage for SPELL_DAMAGE_CLASS_NONE class spells by default +        if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) +            return uint32(std::max(pdamage * DoneTotalMod, 0.0f)); +    }      // Default calculation -    if (coeff && DoneAdvertisedBenefit) +    if (DoneAdvertisedBenefit)      { +        if (coeff < 0.f) +            coeff = CalculateDefaultCoefficient(spellProto, damagetype);  // As wowwiki says: C = (Cast Time / 3.5) +          float factorMod = CalculateSpellpowerCoefficientLevelPenalty(spellProto) * stack;          if (Player* modOwner = GetSpellModOwner())          { @@ -7247,7 +7259,6 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui      if (!spellProto || damagetype == DIRECT_DAMAGE)          return pdamage; -    int32 TakenTotal = 0;      float TakenTotalMod = 1.0f;      // Mod damage from spell mechanic @@ -7298,27 +7309,6 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui                  return false;              });          } - -        int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask()); - -        // Check for table values -        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 (coeff < 0.f) -            { -                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 = CalculateSpellpowerCoefficientLevelPenalty(spellProto) * stack; -            TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod); -        }      }      // Sanctified Wrath (bypass damage reduction) @@ -7337,7 +7327,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui          TakenTotalMod = 1.0f - damageReduction;      } -    float tmpDamage = float(pdamage + TakenTotal) * TakenTotalMod; +    float tmpDamage = pdamage * TakenTotalMod;      return uint32(std::max(tmpDamage, 0.0f));  } @@ -7369,11 +7359,6 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const      return DoneAdvertisedBenefit;  } -int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const -{ -    return GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, schoolMask); -} -  float Unit::SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType /*= BASE_ATTACK*/, bool isPeriodic /*= false*/) const  {      //! Mobs can't crit with spells. (Except player controlled) @@ -7750,36 +7735,48 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui      // Done fixed damage bonus auras      int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask()); +    // modify spell power by victim's SPELL_AURA_MOD_HEALING auras (eg Amplify/Dampen Magic) +    DoneAdvertisedBenefit += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_HEALING, spellProto->GetSchoolMask()); + +    // Pets just add their bonus damage to their spell damage +    // note that their spell damage is just gain of their own auras +    if (HasUnitTypeMask(UNIT_MASK_GUARDIAN)) +        DoneAdvertisedBenefit += static_cast<Guardian const*>(this)->GetBonusDamage();      // Check for table values      float coeff = 0.f;      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)); +        APbonus += GetTotalAttackPowerValue(attType); +          if (damagetype == DOT)          {              coeff = bonus->dot_damage;              if (bonus->ap_dot_bonus > 0) -                DoneTotal += int32(bonus->ap_dot_bonus * ApCoeffMod * stack * GetTotalAttackPowerValue( -                    (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK)); +                DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus);          }          else          {              coeff = bonus->direct_damage;              if (bonus->ap_bonus > 0) -                DoneTotal += int32(bonus->ap_bonus * ApCoeffMod * stack * GetTotalAttackPowerValue( -                    (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK)); +                DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);          }      }      else      {          // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default          if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) -            return healamount; +            return uint32(std::max(healamount * DoneTotalMod, 0.0f));      }      // Default calculation -    if (coeff && DoneAdvertisedBenefit) +    if (DoneAdvertisedBenefit)      { +        if (coeff < 0.f) +            coeff = CalculateDefaultCoefficient(spellProto, damagetype) * 1.88f;  // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells) +          float factorMod = CalculateSpellpowerCoefficientLevelPenalty(spellProto) * stack;          if (Player* modOwner = GetSpellModOwner())          { @@ -7911,12 +7908,6 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u      if (AuraEffect const* Tenacity = GetAuraEffect(58549, 0))          AddPct(TakenTotalMod, Tenacity->GetAmount()); -    // Healing Done -    int32 TakenTotal = 0; - -    // Taken fixed damage bonus auras -    int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(spellProto->GetSchoolMask()); -      // Nourish cast      if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000)      { @@ -7938,34 +7929,6 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u              AddPct(TakenTotalMod, maxval_hot);      } -    // Check for table values -    float coeff = 0; -    if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id)) -        coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage; -    else -    { -        // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default -        if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) -        { -            healamount = uint32(std::max((float(healamount) * TakenTotalMod), 0.0f)); -            return healamount; -        } -    } - -    // Default calculation -    if (TakenAdvertisedBenefit) -    { -        if (coeff < 0.f) -        { -            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) -        } - -        // level penalty still applied on Taken bonus - is it blizzlike? -        float factorMod = CalculateSpellpowerCoefficientLevelPenalty(spellProto) * int32(stack); -        TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod); -    } -      if (caster)      {          TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_RECEIVED, [caster, spellProto](AuraEffect const* aurEff) -> bool @@ -7976,22 +7939,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u          });      } -    for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) -    { -        switch (spellProto->Effects[i].ApplyAuraName) -        { -            // Bonus healing does not apply to these spells -            case SPELL_AURA_PERIODIC_LEECH: -            case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: -                TakenTotal = 0; -                break; -        } -        if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH) -            TakenTotal = 0; -    } - -    float heal = float(int32(healamount) + TakenTotal) * TakenTotalMod; - +    float heal = healamount * TakenTotalMod;      return uint32(std::max(heal, 0.0f));  } @@ -8028,11 +7976,6 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const      return advertisedBenefit;  } -int32 Unit::SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const -{ -    return GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_HEALING, schoolMask); -} -  bool Unit::IsImmunedToDamage(SpellSchoolMask schoolMask) const  {      if (schoolMask == SPELL_SCHOOL_MASK_NONE) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 56883760971..706a2a8cc91 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1514,12 +1514,10 @@ class TC_GAME_API Unit : public WorldObject          Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = nullptr);          int32  SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const; -        int32  SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const;          uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, Optional<float> const& donePctTotal, uint32 stack = 1) const;          float  SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const;          uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1) const;          int32  SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const; -        int32  SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const;          uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, Optional<float> const& donePctTotal, uint32 stack = 1) const;          float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const;          uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const; diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index c76f0325c29..c8eaa11810b 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -2022,13 +2022,21 @@ class spell_pal_seal_of_righteousness : public SpellScriptLoader              {                  PreventDefaultAction(); +                Unit* victim = eventInfo.GetProcTarget(); +                  float ap = GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK); -                int32 holy = GetTarget()->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY); -                holy += eventInfo.GetProcTarget()->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY); -                int32 bp = int32((ap * 0.022f + 0.044f * holy) * GetTarget()->GetAttackTime(BASE_ATTACK) / 1000); +                ap += victim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS); + +                int32 sph = GetTarget()->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY); +                sph += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, SPELL_SCHOOL_MASK_HOLY); + +                float mws = GetTarget()->GetAttackTime(BASE_ATTACK); +                mws /= 1000.0f; + +                int32 bp = int32(mws * (0.022f * ap + 0.044f * sph));                  CastSpellExtraArgs args(aurEff);                  args.AddSpellBP0(bp); -                GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS, args); +                GetTarget()->CastSpell(victim, SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS, args);              }              void Register() override diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index a9101e16c46..1b3d63a7ac2 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -715,7 +715,7 @@ class spell_sha_flametongue_weapon : public SpellScriptLoader                  if (!item || !item->IsEquipped())                      return false; -                WeaponAttackType attType = static_cast<WeaponAttackType>(player->GetAttackBySlot(item->GetSlot())); +                WeaponAttackType attType = Player::GetAttackBySlot(item->GetSlot());                  if (attType != BASE_ATTACK && attType != OFF_ATTACK)                      return false; @@ -738,26 +738,32 @@ class spell_sha_flametongue_weapon : public SpellScriptLoader                  Item* item = ASSERT_NOTNULL(player->GetWeaponForAttack(attType)); -                float const basePoints = GetSpellInfo()->Effects[aurEff->GetEffIndex()].CalcValue(); +                float basePoints = GetSpellInfo()->Effects[aurEff->GetEffIndex()].CalcValue();                  // Flametongue max damage is normalized based on a 4.0 speed weapon                  // Tooltip says max damage = BasePoints / 25, so BasePoints / 25 / 4 to get base damage per 1.0s AS +                float attackSpeed = player->GetAttackTime(attType) / 1000.f;                  float fireDamage = basePoints / 100.0f; -                float const attackSpeed = player->GetAttackTime(attType) / 1000.f;                  fireDamage *= attackSpeed;                  // clip value between (BasePoints / 77) and (BasePoints / 25) as the tooltip indicates                  RoundToInterval(fireDamage, basePoints / 77.0f, basePoints / 25.0f);                  // Calculate Spell Power scaling -                float spellPowerBonus = player->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE) + target->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE); +                float spellPowerBonus = player->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE); +                spellPowerBonus += target->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, SPELL_SCHOOL_MASK_FIRE); + +                // calculate penalty from passive aura as is the one with level +                float const factorMod = player->CalculateSpellpowerCoefficientLevelPenalty(GetSpellInfo()); +                  float const spCoeff = 0.03811f; -                spellPowerBonus *= spCoeff * attackSpeed; +                spellPowerBonus *= spCoeff * attackSpeed * factorMod;                  // All done, now proc damage                  CastSpellExtraArgs args(aurEff); -                args.CastItem = item; -                args.AddSpellBP0(fireDamage + spellPowerBonus); +                args +                    .SetCastItem(item) +                    .AddSpellBP0(fireDamage + spellPowerBonus);                  player->CastSpell(target, SPELL_SHAMAN_FLAMETONGUE_ATTACK, args);              } | 
