diff options
| author | ariel- <ariel-@users.noreply.github.com> | 2016-11-16 02:26:18 -0300 |
|---|---|---|
| committer | ariel- <ariel-@users.noreply.github.com> | 2016-11-16 02:26:18 -0300 |
| commit | b6a8045adcbccfba4fa4a48a3dfcc2ccf1972206 (patch) | |
| tree | cc70bbf2c79a4890ce871598939168b7997dfcf4 | |
| parent | f3bdd705c0e3ab28585406ae8e08da44a09b14df (diff) | |
Core/Unit: fix some SPELL_AURA_MOD_DAMAGE_PERCENT_DONE effects being applied more than once
No more overpowered dps for you
Closes #16755
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 124 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 31 |
3 files changed, 81 insertions, 78 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 41d9bf7b2b2..0bd06d3e544 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7798,10 +7798,10 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType att return; // ignore spell mods for not wands - if ((aura->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) == 0 && (getClassMask() & CLASSMASK_WAND_USERS) == 0) + if ((aura->GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) && (!(getClassMask() & CLASSMASK_WAND_USERS))) return; - // generic not weapon specific case processes in aura code + // generic not weapon specific case processed in AuraEffect handler if (aura->GetSpellInfo()->EquippedItemClass == -1) return; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e5ca53c6dea..d551a986adf 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6700,34 +6700,28 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin // 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 += ((Guardian*)this)->GetBonusDamage(); + DoneAdvertisedBenefit += static_cast<Guardian const*>(this)->GetBonusDamage(); // Check for table values - float coeff = 0; + float coeff = 0.f; SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id); if (bonus) { + 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) - { - WeaponAttackType 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); DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus); - } } else { coeff = bonus->direct_damage; if (bonus->ap_bonus > 0) - { - WeaponAttackType 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); DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus); - } } } // Default calculation @@ -6782,19 +6776,21 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank); AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) + for (AuraEffect const* aurEff : mModDamagePercentDone) { - if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1) //prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization) + SpellInfo const* aurSpellInfo = aurEff->GetSpellInfo(); + + if (spellProto->EquippedItemClass == -1 && aurSpellInfo->EquippedItemClass != -1) // prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization) continue; - if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) + if ((aurEff->GetMiscValue() & spellProto->GetSchoolMask()) != 0) { - if ((*i)->GetSpellInfo()->EquippedItemClass == -1) - AddPct(DoneTotalMod, (*i)->GetAmount()); - else if (!(*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) - AddPct(DoneTotalMod, (*i)->GetAmount()); - else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) - AddPct(DoneTotalMod, (*i)->GetAmount()); + if (aurSpellInfo->EquippedItemClass == -1) + AddPct(DoneTotalMod, aurEff->GetAmount()); + else if (!aurSpellInfo->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && (aurSpellInfo->EquippedItemSubClassMask == 0)) + AddPct(DoneTotalMod, aurEff->GetAmount()); + else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements(aurSpellInfo)) + AddPct(DoneTotalMod, aurEff->GetAmount()); } } @@ -7177,13 +7173,15 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const int32 DoneAdvertisedBenefit = 0; AuraEffectList const& mDamageDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); - for (AuraEffectList::const_iterator i = mDamageDone.begin(); i != mDamageDone.end(); ++i) - if (((*i)->GetMiscValue() & schoolMask) != 0 && - (*i)->GetSpellInfo()->EquippedItemClass == -1 && - // -1 == any item class (not wand then) - (*i)->GetSpellInfo()->EquippedItemInventoryTypeMask == 0) - // 0 == any inventory type (not wand then) - DoneAdvertisedBenefit += (*i)->GetAmount(); + for (AuraEffect const* aurEff : mDamageDone) + { + if (!(aurEff->GetMiscValue() & schoolMask)) + continue; + + // only apply generic bonus here, weapon requiring mods are not applicable to non-melee spells + if (aurEff->GetSpellInfo()->EquippedItemClass == -1 && aurEff->GetSpellInfo()->EquippedItemInventoryTypeMask == 0) + DoneAdvertisedBenefit += aurEff->GetAmount(); + } if (GetTypeId() == TYPEID_PLAYER) { @@ -7192,22 +7190,21 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const // Damage bonus from stats AuraEffectList const& mDamageDoneOfStatPercent = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT); - for (AuraEffectList::const_iterator i = mDamageDoneOfStatPercent.begin(); i != mDamageDoneOfStatPercent.end(); ++i) + for (AuraEffect const* aurEff : mDamageDoneOfStatPercent) { - if ((*i)->GetMiscValue() & schoolMask) + if ((aurEff->GetMiscValue() & schoolMask) != 0) { // stat used stored in miscValueB for this aura - Stats usedStat = Stats((*i)->GetMiscValueB()); - DoneAdvertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount())); + Stats const usedStat = static_cast<Stats>(aurEff->GetMiscValueB()); + DoneAdvertisedBenefit += static_cast<int32>(CalculatePct(GetStat(usedStat), aurEff->GetAmount())); } } + // ... and attack power - AuraEffectList const& mDamageDonebyAP = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER); - for (AuraEffectList::const_iterator i =mDamageDonebyAP.begin(); i != mDamageDonebyAP.end(); ++i) - if ((*i)->GetMiscValue() & schoolMask) - DoneAdvertisedBenefit += int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), (*i)->GetAmount())); + DoneAdvertisedBenefit += static_cast<int32>(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER, schoolMask))); } + return DoneAdvertisedBenefit; } @@ -8060,38 +8057,45 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType if (APbonus != 0) // Can be negative { - bool normalized = false; - if (spellProto) - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (spellProto->Effects[i].Effect == SPELL_EFFECT_NORMALIZED_WEAPON_DMG) - { - normalized = true; - break; - } - DoneFlatBenefit += int32(APbonus/14.0f * GetAPMultiplier(attType, normalized)); + bool const normalized = spellProto && spellProto->HasEffect(SPELL_EFFECT_NORMALIZED_WEAPON_DMG); + DoneFlatBenefit += int32(APbonus / 14.0f * GetAPMultiplier(attType, normalized)); } // Done total percent damage auras float DoneTotalMod = 1.0f; // Some spells don't benefit from pct done mods - if (spellProto) - if (!spellProto->HasAttribute(SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)) + if (spellProto && !spellProto->HasAttribute(SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)) + { + AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + for (AuraEffect const* aurEff : mModDamagePercentDone) { - AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) + // Apply mod if schoolmask matches... + if ((aurEff->GetMiscValue() & spellProto->GetSchoolMask()) != 0) { - if ((*i)->GetMiscValue() & spellProto->GetSchoolMask() && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_NORMAL)) - { - if ((*i)->GetSpellInfo()->EquippedItemClass == -1) - AddPct(DoneTotalMod, (*i)->GetAmount()); - else if (!(*i)->GetSpellInfo()->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) - AddPct(DoneTotalMod, (*i)->GetAmount()); - else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) - AddPct(DoneTotalMod, (*i)->GetAmount()); - } + SpellInfo const* aurSpellInfo = aurEff->GetSpellInfo(); + + // ... but not for SCHOOL_MASK_NORMAL, or generic weapon bonus, or creatures (creatures don't have equiped items check) + // for these types the damage was already calculated in AuraEffect handler, and stored into TOTAL_PCT + // if we include them, we'll be multiplying twice (one in Unit::CalculateDamage, the other here) + if ((aurEff->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) && (aurSpellInfo->EquippedItemClass == -1 || GetTypeId() != TYPEID_PLAYER)) + continue; + + // generic weapon bonus (magic) + if (aurSpellInfo->EquippedItemClass == -1) + AddPct(DoneTotalMod, aurEff->GetAmount()); + // skips subclassmask check/has generic subclassmask set + else if (!aurSpellInfo->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && (aurSpellInfo->EquippedItemSubClassMask == 0)) + AddPct(DoneTotalMod, aurEff->GetAmount()); + + // This one is already applied in Player::_ApplyWeaponDependentAuraDamageMod + /* + else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements(aurSpellInfo)) + AddPct(DoneTotalMod, aurEff->GetAmount()); + */ } } + } AuraEffectList const& mDamageDoneVersus = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i) @@ -8168,6 +8172,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType // Custom scripted damage if (spellProto) + { switch (spellProto->SpellFamilyName) { case SPELLFAMILY_DEATHKNIGHT: @@ -8176,8 +8181,9 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType if (AuraEffect* aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 196, 0)) if (victim->GetDiseasesByCaster(owner->GetGUID()) > 0) AddPct(DoneTotalMod, aurEff->GetAmount()); - break; + break; } + } float tmpDamage = float(int32(pdamage) + DoneFlatBenefit) * DoneTotalMod; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 38e7ad0af89..48ca675991f 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -4117,28 +4117,25 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode, // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask // GetMiscValue() comparison with item generated damage types - if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0) + // apply generic physical damage bonuses including wand case + if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) && (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)) { - // apply generic physical damage bonuses including wand case - if (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER) - { - target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetAmount()), apply); - target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetAmount()), apply); - target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetAmount()), apply); + target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetAmount()), apply); + target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetAmount()), apply); + target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetAmount()), apply); - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (GetAmount() > 0) - target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, GetAmount(), apply); - else - target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, GetAmount(), apply); - } - } - else + if (target->GetTypeId() == TYPEID_PLAYER) { - // done in Player::_ApplyWeaponDependentAuraMods + if (GetAmount() > 0) + target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, GetAmount(), apply); + else + target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, GetAmount(), apply); } } + else + { + // done in Player::_ApplyWeaponDependentAuraMods + } // Skip non magic case for speedup if ((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0) |
