From 8d982dbf555a25c480c4dae7ec2c79c378d4ad3c Mon Sep 17 00:00:00 2001 From: Laise Date: Tue, 27 Apr 2010 13:12:44 +0300 Subject: [PATCH] [9798] Implement basic splitting for caster/target part damage/heal bonus calculations, periodic damage/heal over time auras will now store m_amount with caster side bonuses applied and calculate target part on each tick. Currently critical chance/bonus calculations are not affected by this change --- src/game/SpellAuras.cpp | 209 +++++++++----- src/game/SpellEffects.cpp | 47 ++-- src/game/StatSystem.cpp | 6 +- src/game/Unit.cpp | 573 +++++++++++++++++++++++++------------- src/game/Unit.h | 19 +- src/shared/revision_nr.h | 2 +- 6 files changed, 559 insertions(+), 297 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 9f485231966..39ab05e3d34 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -64,7 +64,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE - &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellBaseDamageBonusForVictim + &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonusTaken and Unit::SpellBaseDamageBonusTaken &Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DealMeleeDamage &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH &Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT implemented in Unit::isVisibleForOrDetect @@ -109,7 +109,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED - &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonusDone and Unit::SpellDamageBonusDone &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE &Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL @@ -137,7 +137,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM - &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonusTaken and Unit::SpellDamageBonusTaken &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT implemented in Player::RegenerateHealth &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT &Aura::HandleUnused, // 90 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_RESIST_CHANCE @@ -152,7 +152,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER &Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete 3.x? all player can see all auras now, but still have 2 spells including GM-spell (1852,2855) &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT - &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonusDone &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL @@ -163,30 +163,30 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT &Aura::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS implemented in diff functions. - &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus - &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus - &Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim + &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonusTaken + &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonusTaken + &Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusTaken &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT imppemented in Player::RegenerateAll and Player::RegenerateHealth &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult - &Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus + &Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonusTaken &Aura::HandleUnused, //119 unused (3.0.8a-3.2.2a) old SPELL_AURA_SHARE_PET_TRACKING &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER - &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus - &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus - &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonusTaken + &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonusTaken + &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonusDone &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET &Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS &Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS - &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonusDone &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT &Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE - &Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus + &Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonusDone &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION @@ -215,22 +215,22 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA &Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS implemented in Unit::CalculateMeleeDamage and Unit::SpellCriticalDamageBonus &Aura::HandleUnused, //164 unused (3.0.8a-3.2.2a), only one test spell 10654 - &Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonusDone &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT - &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus + &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonusDone, Unit::MeleeDamageBonusDone &Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE different spells that ignore transformation effects &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK &Aura::HandleUnused, //173 unused (3.0.8a-3.2.2a) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell - &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus - &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus + &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonusDone + &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonusDone &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM (22 spells) &Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus - &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonusDone &Aura::HandleUnused, //181 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS &Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT &Aura::HandleNoImmediateEffect, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746, implemented in ThreatCalcHelper::calcThreat @@ -279,7 +279,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY &Aura::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE &Aura::HandleNoImmediateEffect, //228 SPELL_AURA_DETECT_STEALTH - &Aura::HandleNoImmediateEffect, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE implemented in Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE implemented in Unit::SpellDamageBonusTaken &Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout &Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE &Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration @@ -287,8 +287,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration &Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult &Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE - &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus - &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus + &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonusDone + &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonusDone &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61 &Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE &Aura::HandleForceMoveForward, //241 Forces the player to move forward @@ -305,7 +305,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleModCombatSpeedPct, //252 SPELL_AURA_SLOW_ALL &Aura::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::CalculateMeleeDamage &Aura::HandleNULL, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield - &Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonusTaken &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select &Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL @@ -321,7 +321,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT &Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL implemented in Unit::CalcNotIgnoreDamageRedunction &Aura::HandleUnused, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST (unused in 3.2.2a) - &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus + &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonusTaken &Aura::HandleNoImmediateEffect, //272 SPELL_AURA_MAELSTROM_WEAPON (unclear use for aura, it used in (3.2.2a...3.3.0) in single spell 53817 that spellmode stacked and charged spell expected to be drop as stack &Aura::HandleNoImmediateEffect, //273 SPELL_AURA_X_RAY (client side implementation) &Aura::HandleNULL, //274 proc free shot? @@ -333,7 +333,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleModTargetArmorPct, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT &Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN implemented in Player::RewardHonor &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT - &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus + &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonusTaken &Aura::HandleNULL, //284 51 spells &Aura::HandleAuraModAttackPowerOfArmor, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage &Aura::HandleNoImmediateEffect, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in Aura::IsCritFromAbilityAura called from Aura::PeriodicTick @@ -2386,8 +2386,13 @@ void Aura::HandleAuraDummy(bool apply, bool Real) { // prevent double apply bonuses if (m_target->GetTypeId() != TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) + { if (Unit* caster = GetCaster()) - m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); + { + m_modifier.m_amount = caster->SpellHealingBonusDone(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); + m_modifier.m_amount = m_target->SpellHealingBonusTaken(caster, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); + } + } return; } break; @@ -2791,9 +2796,14 @@ void Aura::HandleAuraDummy(bool apply, bool Real) if (apply) { if (Unit* caster = GetCaster()) + { // prevent double apply bonuses if (m_target->GetTypeId() != TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) - m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); + { + m_modifier.m_amount = caster->SpellHealingBonusDone(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); + m_modifier.m_amount = m_target->SpellHealingBonusTaken(caster, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); + } + } } else { @@ -4804,11 +4814,13 @@ void Aura::HandlePeriodicHeal(bool apply, bool /*Real*/) if (m_spellProto->SpellIconID == 329 && m_spellProto->SpellVisual[0] == 7625) { int32 ap = int32 (0.22f * caster->GetTotalAttackPowerValue(BASE_ATTACK)); - int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) - + caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target); + int32 holy = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellProto)) + + m_target->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellProto)); holy = int32(holy * 377 / 1000); m_modifier.m_amount += ap > holy ? ap : holy; } + + m_modifier.m_amount = caster->SpellHealingBonusDone(m_target, GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); } } @@ -4971,8 +4983,8 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) { // AP * 0.025 + SPH * 0.013 bonus per tick float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) + - caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), GetTarget()); + int32 holy = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellProto)) + + GetTarget()->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellProto)); m_modifier.m_amount += int32(GetStackAmount()) * (int32(ap * 0.025f) + int32(holy * 13 / 1000)); return; } @@ -4981,6 +4993,19 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) default: break; } + + if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE) + { + // SpellDamageBonusDone for magic spells + if(GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_NONE || GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) + m_modifier.m_amount = caster->SpellDamageBonusDone(m_target, GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); + // MeleeDamagebonusDone for weapon based spells + else + { + WeaponAttackType attackType = GetWeaponAttackType(GetSpellProto()); + m_modifier.m_amount = caster->MeleeDamageBonusDone(m_target, m_modifier.m_amount, attackType, GetSpellProto(), DOT, GetStackAmount()); + } + } } // remove time effects else @@ -4999,6 +5024,22 @@ void Aura::HandlePeriodicDamagePCT(bool apply, bool /*Real*/) void Aura::HandlePeriodicLeech(bool apply, bool /*Real*/) { m_isPeriodic = apply; + + // For prevent double apply bonuses + bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); + + // Custom damage calculation after + if (apply) + { + if(loading) + return; + + Unit *caster = GetCaster(); + if (!caster) + return; + + m_modifier.m_amount = caster->SpellDamageBonusDone(m_target, GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); + } } void Aura::HandlePeriodicManaLeech(bool apply, bool /*Real*/) @@ -5009,6 +5050,22 @@ void Aura::HandlePeriodicManaLeech(bool apply, bool /*Real*/) void Aura::HandlePeriodicHealthFunnel(bool apply, bool /*Real*/) { m_isPeriodic = apply; + + // For prevent double apply bonuses + bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); + + // Custom damage calculation after + if (apply) + { + if(loading) + return; + + Unit *caster = GetCaster(); + if (!caster) + return; + + m_modifier.m_amount = caster->SpellDamageBonusDone(m_target, GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); + } } /*********************************************************/ @@ -5146,7 +5203,7 @@ void Aura::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool /*Real*/) if(m_target->GetTypeId() != TYPEID_PLAYER) return; - // Magic damage modifiers implemented in Unit::SpellDamageBonus + // Magic damage modifiers implemented in Unit::SpellDamageBonusDone // This information for client side use only // Recalculate bonus ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); @@ -5175,7 +5232,7 @@ void Aura::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool /*Rea if(m_target->GetTypeId() != TYPEID_PLAYER) return; - // Magic damage modifiers implemented in Unit::SpellDamageBonus + // Magic damage modifiers implemented in Unit::SpellDamageBonusDone // This information for client side use only // Recalculate bonus ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); @@ -5194,7 +5251,7 @@ void Aura::HandleModHealingDone(bool /*apply*/, bool /*Real*/) { if(m_target->GetTypeId() != TYPEID_PLAYER) return; - // implemented in Unit::SpellHealingBonus + // implemented in Unit::SpellHealingBonusDone // this information is for client side only ((Player*)m_target)->UpdateSpellDamageAndHealingBonus(); } @@ -5734,7 +5791,7 @@ void Aura::HandleModDamageDone(bool apply, bool Real) return; } - // Magic damage modifiers implemented in Unit::SpellDamageBonus + // Magic damage modifiers implemented in Unit::SpellDamageBonusDone // This information for client side use only if(m_target->GetTypeId() == TYPEID_PLAYER) { @@ -5812,7 +5869,7 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real) return; } - // Magic damage percent modifiers implemented in Unit::SpellDamageBonus + // Magic damage percent modifiers implemented in Unit::SpellDamageBonusDone // Send info to client if(m_target->GetTypeId() == TYPEID_PLAYER) for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) @@ -6860,7 +6917,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001)) { //+80.68% from +spell bonus - DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f; + DoneActualBenefit = caster->SpellBaseHealingBonusDone(GetSpellSchoolMask(m_spellProto)) * 0.8068f; //Borrowed Time Unit::AuraList const& borrowedTime = caster->GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::const_iterator itr = borrowedTime.begin(); itr != borrowedTime.end(); ++itr) @@ -6879,17 +6936,17 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) // Frost Ward, Fire Ward if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000108)) //+10% from +spell bonus - DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f; + DoneActualBenefit = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellProto)) * 0.1f; // Ice Barrier else if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000100000000)) //+80.67% from +spell bonus - DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8067f; + DoneActualBenefit = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellProto)) * 0.8067f; break; case SPELLFAMILY_WARLOCK: // Shadow Ward if (m_spellProto->SpellFamilyFlags2 & 0x00000040) //+30% from +spell bonus - DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.30f; + DoneActualBenefit = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellProto)) * 0.30f; break; case SPELLFAMILY_PALADIN: // Sacred Shield @@ -6897,7 +6954,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0008000000000000)) { // +75% from spell power - DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.75f; + DoneActualBenefit = caster->SpellBaseHealingBonusDone(GetSpellSchoolMask(m_spellProto)) * 0.75f; } break; default: @@ -7044,43 +7101,42 @@ void Aura::PeriodicTick() uint32 pdamage; if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE) - { pdamage = amount; + else + pdamage = uint32(m_target->GetMaxHealth()*amount/100); - // SpellDamageBonus for magic spells - if(GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_NONE || GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) - pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount()); - // MeleeDamagebonus for weapon based spells - else - { - WeaponAttackType attackType = GetWeaponAttackType(GetSpellProto()); - pdamage = pCaster->MeleeDamageBonus(m_target, pdamage, attackType, GetSpellProto(), DOT, GetStackAmount()); - } + + // SpellDamageBonus for magic spells + if(GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_NONE || GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) + pdamage = m_target->SpellDamageBonusTaken(pCaster, GetSpellProto(), pdamage, DOT, GetStackAmount()); + // MeleeDamagebonus for weapon based spells + else + { + WeaponAttackType attackType = GetWeaponAttackType(GetSpellProto()); + pdamage = m_target->MeleeDamageBonusTaken(pCaster, pdamage, attackType, GetSpellProto(), DOT, GetStackAmount()); + } - // Calculate armor mitigation if it is a physical spell - // But not for bleed mechanic spells - if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL && - GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED) - { - uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage); - cleanDamage.damage += pdamage - pdamageReductedArmor; - pdamage = pdamageReductedArmor; - } + // Calculate armor mitigation if it is a physical spell + // But not for bleed mechanic spells + if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL && + GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED) + { + uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage); + cleanDamage.damage += pdamage - pdamageReductedArmor; + pdamage = pdamageReductedArmor; + } - // Curse of Agony damage-per-tick calculation - if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && GetSpellProto()->SpellIconID==544) - { - // 1..4 ticks, 1/2 from normal tick damage - if (GetAuraTicks() <= 4) - pdamage = pdamage/2; - // 9..12 ticks, 3/2 from normal tick damage - else if(GetAuraTicks() >= 9) - pdamage += (pdamage + 1) / 2; // +1 prevent 0.5 damage possible lost at 1..4 ticks - // 5..8 ticks have normal tick damage - } + // Curse of Agony damage-per-tick calculation + if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && GetSpellProto()->SpellIconID==544) + { + // 1..4 ticks, 1/2 from normal tick damage + if (GetAuraTicks() <= 4) + pdamage = pdamage/2; + // 9..12 ticks, 3/2 from normal tick damage + else if(GetAuraTicks() >= 9) + pdamage += (pdamage + 1) / 2; // +1 prevent 0.5 damage possible lost at 1..4 ticks + // 5..8 ticks have normal tick damage } - else - pdamage = uint32(m_target->GetMaxHealth()*amount/100); // This method can modify pdamage bool isCrit = IsCritFromAbilityAura(pCaster, pdamage); @@ -7157,7 +7213,8 @@ void Aura::PeriodicTick() pdamage = pdamageReductedArmor; } - pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount()); + pdamage = m_target->SpellDamageBonusTaken(pCaster, GetSpellProto(), pdamage, DOT, GetStackAmount()); + bool isCrit = IsCritFromAbilityAura(pCaster, pdamage); // send critical in hit info for threat calculation @@ -7204,7 +7261,7 @@ void Aura::PeriodicTick() if(Player *modOwner = pCaster->GetSpellModOwner()) modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, multiplier); - int32 heal = pCaster->SpellHealingBonus(pCaster, GetSpellProto(), int32(new_damage * multiplier), DOT, GetStackAmount()); + int32 heal = pCaster->SpellHealingBonusTaken(pCaster, GetSpellProto(), int32(new_damage * multiplier), DOT, GetStackAmount()); int32 gain = pCaster->DealHeal(pCaster, heal, GetSpellProto()); pCaster->getHostileRefManager().threatAssist(pCaster, gain * 0.5f, GetSpellProto()); @@ -7252,7 +7309,7 @@ void Aura::PeriodicTick() } } - pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount()); + pdamage = m_target->SpellHealingBonusTaken(pCaster, GetSpellProto(), pdamage, DOT, GetStackAmount()); // This method can modify pdamage bool isCrit = IsCritFromAbilityAura(pCaster, pdamage); @@ -8043,7 +8100,7 @@ void Aura::HandleManaShield(bool apply, bool Real) { // Mana Shield // +50% from +spd bonus - DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.5f; + DoneActualBenefit = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellProto)) * 0.5f; break; } break; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 9c8a1a89570..ee384843884 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -509,7 +509,8 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) if (aura) { // DoT not have applied spell bonuses in m_amount - int32 damagetick = m_caster->SpellDamageBonus(unitTarget, aura->GetSpellProto(), aura->GetModifier()->m_amount, DOT); + int32 damagetick = m_caster->SpellDamageBonusDone(unitTarget, aura->GetSpellProto(), aura->GetModifier()->m_amount, DOT); + damagetick = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellProto(), damagetick, DOT); damage += damagetick * 4; // Glyph of Conflagrate @@ -697,8 +698,8 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) if (m_spellInfo->Id == 20187) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); + int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)) + + unitTarget->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellInfo)); damage += int32(ap * 0.2f) + int32(holy * 32 / 100); } // Judgement of Vengeance/Corruption ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance/Blood Corruption on the target @@ -713,8 +714,8 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) } float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); + int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)) + + unitTarget->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellInfo)); damage+=int32(ap * 0.14f) + int32(holy * 22 / 100); // Get stack of Holy Vengeance on the target added by caster uint32 stacks = 0; @@ -735,16 +736,16 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); + int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)) + + unitTarget->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellInfo)); damage += int32(ap * 0.07f) + int32(holy * 7 / 100); } // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) - ranged type sdb future fix else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000008000000000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); + int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)) + + unitTarget->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellInfo)); damage += int32(ap * 0.15f) + int32(holy * 15 / 100); } // Hammer of the Righteous @@ -2930,7 +2931,8 @@ void Spell::EffectPowerDrain(SpellEffectIndex eff_idx) uint32 curPower = unitTarget->GetPower(drain_power); //add spell damage bonus - damage=m_caster->SpellDamageBonus(unitTarget,m_spellInfo,uint32(damage),SPELL_DIRECT_DAMAGE); + damage = m_caster->SpellDamageBonusDone(unitTarget,m_spellInfo,uint32(damage),SPELL_DIRECT_DAMAGE); + damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage),SPELL_DIRECT_DAMAGE); // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) uint32 power = damage; @@ -3029,8 +3031,8 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) if (m_spellInfo->Id == 20167) { float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellInfo)) + - caster->SpellBaseHealingBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); + int32 holy = caster->SpellBaseHealingBonusDone(GetSpellSchoolMask(m_spellInfo)) + + unitTarget->SpellBaseHealingBonusTaken(GetSpellSchoolMask(m_spellInfo)); addhealth += int32(ap * 0.15) + int32(holy * 15 / 100); } // Vessel of the Naaru (Vial of the Sunwell trinket) @@ -3080,7 +3082,9 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) idx++; } - int32 tickheal = caster->SpellHealingBonus(unitTarget, targetAura->GetSpellProto(), targetAura->GetModifier()->m_amount, DOT); + int32 tickheal = caster->SpellHealingBonusDone(unitTarget, targetAura->GetSpellProto(), targetAura->GetModifier()->m_amount, DOT); + tickheal = unitTarget->SpellHealingBonusTaken(caster, targetAura->GetSpellProto(), tickheal, DOT); + int32 tickcount = GetSpellDuration(targetAura->GetSpellProto()) / targetAura->GetSpellProto()->EffectAmplitude[idx]; // Glyph of Swiftmend @@ -3090,7 +3094,10 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) addhealth += tickheal * tickcount; } else - addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL); + { + addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL); + addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); + } m_healing += addhealth; @@ -3137,7 +3144,9 @@ void Spell::EffectHealMechanical(SpellEffectIndex /*eff_idx*/) if (!caster) return; - uint32 addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, damage, HEAL); + uint32 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, damage, HEAL); + addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); + caster->DealHeal(unitTarget, addhealth, m_spellInfo); } } @@ -3167,7 +3176,9 @@ void Spell::EffectHealthLeech(SpellEffectIndex eff_idx) int32 heal = int32(damage*multiplier); if (m_caster->isAlive()) { - heal = m_caster->SpellHealingBonus(m_caster, m_spellInfo, heal, HEAL); + heal = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, heal, HEAL); + heal = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, heal, HEAL); + m_caster->DealHeal(m_caster, heal, m_spellInfo); } } @@ -4989,8 +5000,8 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x00020000000000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); + int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)) + + unitTarget->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellInfo)); spell_bonus += int32(ap * 0.08f) + int32(holy * 13 / 100); } break; diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 944021730dd..f6e30e1e513 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -103,13 +103,13 @@ void Player::ApplySpellPowerBonus(int32 amount, bool apply) void Player::UpdateSpellDamageAndHealingBonus() { - // Magic damage modifiers implemented in Unit::SpellDamageBonus + // Magic damage modifiers implemented in Unit::SpellDamageBonusDone // This information for client side use only // Get healing bonus for all schools - SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonus(SPELL_SCHOOL_MASK_ALL)); + SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonusDone(SPELL_SCHOOL_MASK_ALL)); // Get damage bonus for all schools for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonus(SpellSchoolMask(1 << i))); + SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonusDone(SpellSchoolMask(1 << i))); } bool Player::UpdateAllStats() diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3d0d448cf0f..78704053ac5 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1217,7 +1217,8 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S case SPELL_DAMAGE_CLASS_MELEE: { //Calculate damage bonus - damage = MeleeDamageBonus(pVictim, damage, attackType, spellInfo, SPELL_DIRECT_DAMAGE); + damage = MeleeDamageBonusDone(pVictim, damage, attackType, spellInfo, SPELL_DIRECT_DAMAGE); + damage = pVictim->MeleeDamageBonusTaken(this, damage, attackType, spellInfo, SPELL_DIRECT_DAMAGE); // if crit add critical bonus if (crit) @@ -1238,7 +1239,9 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S case SPELL_DAMAGE_CLASS_MAGIC: { // Calculate damage bonus - damage = SpellDamageBonus(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = SpellDamageBonusDone(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = pVictim->SpellDamageBonusTaken(this, spellInfo, damage, SPELL_DIRECT_DAMAGE); + // If crit add critical bonus if (crit) { @@ -1368,7 +1371,8 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da } damage += CalculateDamage (damageInfo->attackType, false); // Add melee damage bonus - damage = MeleeDamageBonus(damageInfo->target, damage, damageInfo->attackType); + damage = MeleeDamageBonusDone(damageInfo->target, damage, damageInfo->attackType); + damage = damageInfo->target->MeleeDamageBonusTaken(this, damage, damageInfo->attackType); // Calculate armor reduction uint32 armor_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask); @@ -4243,7 +4247,9 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, if(Unit* caster = dot->GetCaster()) { int32 bp0 = dot->GetModifier()->m_amount; - bp0 = 8 * caster->SpellDamageBonus(this, spellEntry, bp0, DOT, 1); + uint32 bonusDamage = caster->SpellDamageBonusDone(this, spellEntry, bp0, DOT); + bonusDamage = SpellDamageBonusTaken(caster, spellEntry, bonusDamage, DOT); + bp0 = 8 * bonusDamage; // Remove spell auras from stack RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); @@ -5899,7 +5905,9 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (!healingAura) return false; - int32 healingfromticks = SpellHealingBonus(pVictim, procSpell, (healingAura->GetModifier()->m_amount* GetSpellAuraMaxTicks(procSpell)), DOT); + int32 healingfromticks = healingAura->GetModifier()->m_amount * GetSpellAuraMaxTicks(procSpell); + healingfromticks = pVictim->SpellHealingBonusTaken(this, procSpell, healingfromticks, DOT); + basepoints[0] = healingfromticks * triggerAmount / 100; triggered_spell_id = 63544; break; @@ -5914,7 +5922,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (!leachAura) return false; - int32 damagefromticks = SpellDamageBonus(pVictim, procSpell, (leachAura->GetModifier()->m_amount* GetSpellAuraMaxTicks(procSpell)), DOT); + int32 damagefromticks = leachAura->GetModifier()->m_amount * GetSpellAuraMaxTicks(procSpell); + damagefromticks = pVictim->SpellDamageBonusTaken(this, procSpell, damagefromticks, DOT); basepoints[0] = damagefromticks * triggerAmount / 100; triggered_spell_id = 63675; break; @@ -6295,8 +6304,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { triggered_spell_id = 25742; float ap = GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) + - SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, pVictim); + int32 holy = SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY) + + pVictim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY); basepoints[0] = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000; break; } @@ -7807,7 +7816,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB int32 curBonus = 0; if (Aura* aur = owner->GetAura(48090, EFFECT_INDEX_0)) curBonus = aur->GetModifier()->m_amount; - int32 spellDamage = owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_MAGIC) - curBonus; + int32 spellDamage = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_MAGIC) - curBonus; if(spellDamage <= 0) return false; @@ -8867,7 +8876,11 @@ void Unit::EnergizeBySpell(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers pVictim->ModifyPower(powertype, Damage); } -uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) +/** + * Calculates caster part of spell damage bonuses, + * also includes different bonuses dependent from target auras + */ +uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) { if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE ) return pdamage; @@ -8876,16 +8889,12 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE) { if(Unit* owner = GetOwner()) - return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype); + return owner->SpellDamageBonusDone(pVictim, spellProto, pdamage, damagetype); } - // Taken/Done total percent damage auras float DoneTotalMod = 1.0f; - float TakenTotalMod = 1.0f; int32 DoneTotal = 0; - int32 TakenTotal = 0; - // ..done // Creature damage if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() ) DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank); @@ -8914,6 +8923,13 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); + for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i) + { + if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) + DoneTotalMod += ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + } + // done scripted mod (take it from owner) Unit *owner = GetOwner(); if (!owner) owner = this; @@ -9030,7 +9046,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } } - // Custom scripted damage + // Custom scripted damage switch(spellProto->SpellFamilyName) { case SPELLFAMILY_MAGE: @@ -9074,7 +9090,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { if (pVictim->GetHealth() * 100 / pVictim->GetMaxHealth() <= 25) - DoneTotalMod *= 4; + DoneTotalMod *= 4; } break; } @@ -9147,9 +9163,88 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 break; } + // Done fixed damage bonus auras + int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(GetSpellSchoolMask(spellProto)); + + // Pets just add their bonus damage to their spell damage + // note that their spell damage is just gain of their own auras + if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet()) + DoneAdvertisedBenefit += ((Pet*)this)->GetBonusDamage(); + + float LvlPenalty = CalculateLevelPenalty(spellProto); + // Spellmod SpellDamage + float SpellModSpellDamage = 100.0f; + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage); + SpellModSpellDamage /= 100.0f; + + // Check for table values + if (SpellBonusEntry const* bonus = sSpellMgr.GetSpellBonusData(spellProto->Id)) + { + float coeff; + if (damagetype == DOT) + coeff = bonus->dot_damage * LvlPenalty; + else + coeff = bonus->direct_damage * LvlPenalty; + + if (bonus->ap_bonus) + DoneTotal += int32(bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK)); + + DoneTotal += int32(DoneAdvertisedBenefit * coeff * SpellModSpellDamage); + } + // Default calculation + else if (DoneAdvertisedBenefit) + { + // Damage over Time spells bonus calculation + float DotFactor = 1.0f; + if (damagetype == DOT) + { + if (!IsChanneledSpell(spellProto)) + DotFactor = GetSpellDuration(spellProto) / 15000.0f; + + if (uint16 DotTicks = GetSpellAuraMaxTicks(spellProto)) + DoneAdvertisedBenefit = DoneAdvertisedBenefit / DotTicks; + } + // Distribute Damage over multiple effects, reduce by AoE + uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); + CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); + // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing + for(int j = 0; j < MAX_EFFECT_INDEX; ++j) + { + if (spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH || + (spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && + spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH)) + { + CastingTime /= 2; + break; + } + } + DoneTotal += int32(DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * SpellModSpellDamage); + } + + float tmpDamage = (pdamage + DoneTotal * stack) * DoneTotalMod; + // apply spellmod to Done damage (flat and pct) + if(Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage); + + return tmpDamage > 0 ? uint32(tmpDamage) : 0; +} + +/** + * Calculates target part of spell damage bonuses, + * will be called on each tick for periodic damage over time auras + */ +uint32 Unit::SpellDamageBonusTaken(Unit *pCaster, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) +{ + if(!spellProto || !pCaster || damagetype==DIRECT_DAMAGE ) + return pdamage; + + // Taken total percent damage auras + float TakenTotalMod = 1.0f; + int32 TakenTotal = 0; // ..taken - AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); + AuraList const& mModDamagePercentTaken = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i) { if ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) @@ -9157,12 +9252,12 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } // .. taken pct: dummy auras - if (pVictim->GetTypeId() == TYPEID_PLAYER) + if (GetTypeId() == TYPEID_PLAYER) { //Cheat Death - if (Aura *dummy = pVictim->GetDummyAura(45182)) + if (Aura *dummy = GetDummyAura(45182)) { - float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4; + float mod = -((Player*)this)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4; if (mod < float(dummy->GetModifier()->m_amount)) mod = float(dummy->GetModifier()->m_amount); TakenTotalMod *= (mod+100.0f)/100.0f; @@ -9170,57 +9265,42 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } // From caster spells - AuraList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); + AuraList const& mOwnerTaken = GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); for(AuraList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) { - if ((*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto)) + if ((*i)->GetCasterGUID() == pCaster->GetGUID() && (*i)->isAffectedOnSpell(spellProto)) TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f; } // Mod damage from spell mechanic - TakenTotalMod *= pVictim->GetTotalAuraMultiplierByMiscValueForMask(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT,GetAllSpellMechanicMask(spellProto)); + TakenTotalMod *= GetTotalAuraMultiplierByMiscValueForMask(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT,GetAllSpellMechanicMask(spellProto)); // Mod damage taken from AoE spells if(IsAreaOfEffectSpell(spellProto)) { - AuraList const& avoidAuras = pVictim->GetAurasByType(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE); + AuraList const& avoidAuras = GetAurasByType(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE); for(AuraList::const_iterator itr = avoidAuras.begin(); itr != avoidAuras.end(); ++itr) TakenTotalMod *= ((*itr)->GetModifier()->m_amount + 100.0f) / 100.0f; } - // Taken/Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto)); - int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); - - // Pets just add their bonus damage to their spell damage - // note that their spell damage is just gain of their own auras - if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet()) - DoneAdvertisedBenefit += ((Pet*)this)->GetBonusDamage(); + // Taken fixed damage bonus auras + int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(GetSpellSchoolMask(spellProto)); float LvlPenalty = CalculateLevelPenalty(spellProto); - // Spellmod SpellDamage - float SpellModSpellDamage = 100.0f; - if(Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage); - SpellModSpellDamage /= 100.0f; // Check for table values if (SpellBonusEntry const* bonus = sSpellMgr.GetSpellBonusData(spellProto->Id)) { float coeff; if (damagetype == DOT) - coeff = bonus->dot_damage * LvlPenalty * stack; + coeff = bonus->dot_damage * LvlPenalty; else - coeff = bonus->direct_damage * LvlPenalty * stack; - - if (bonus->ap_bonus) - DoneTotal += int32(bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack); + coeff = bonus->direct_damage * LvlPenalty; - DoneTotal += int32(DoneAdvertisedBenefit * coeff * SpellModSpellDamage); TakenTotal += int32(TakenAdvertisedBenefit * coeff); } // Default calculation - else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit) + else if (TakenAdvertisedBenefit) { // Damage over Time spells bonus calculation float DotFactor = 1.0f; @@ -9230,14 +9310,11 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 DotFactor = GetSpellDuration(spellProto) / 15000.0f; if (uint16 DotTicks = GetSpellAuraMaxTicks(spellProto)) - { - DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks; - TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks; - } + TakenAdvertisedBenefit = TakenAdvertisedBenefit / DotTicks; } // Distribute Damage over multiple effects, reduce by AoE uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); - CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); + CastingTime = pCaster->GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing for(int j = 0; j < MAX_EFFECT_INDEX; ++j) { @@ -9249,21 +9326,15 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 break; } } - DoneTotal += int32(DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * SpellModSpellDamage); TakenTotal+= int32(TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty); } - float tmpDamage = (pdamage + DoneTotal) * DoneTotalMod; - // apply spellmod to Done damage (flat and pct) - if(Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage); - - tmpDamage = (tmpDamage + TakenTotal) * TakenTotalMod; + float tmpDamage = (pdamage + TakenTotal * stack) * TakenTotalMod; return tmpDamage > 0 ? uint32(tmpDamage) : 0; } -int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) +int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) { int32 DoneAdvertisedBenefit = 0; @@ -9305,21 +9376,12 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) return DoneAdvertisedBenefit; } -int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim) +int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) { - uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); - int32 TakenAdvertisedBenefit = 0; - // ..done (for creature type by mask) in taken - AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); - for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i) - { - if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) - TakenAdvertisedBenefit += (*i)->GetModifier()->m_amount; - } // ..taken - AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN); + AuraList const& mDamageTaken = GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN); for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i) { if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0) @@ -9559,36 +9621,25 @@ uint32 Unit::SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 dama return damage; } -int32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack) +/** + * Calculates caster part of healing spell bonuses, + * also includes different bonuses dependent from target auras + */ +uint32 Unit::SpellHealingBonusDone(Unit *pVictim, SpellEntry const *spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack) { - // For totems get healing bonus from owner (statue isn't totem in fact) + // For totems get healing bonus from owner (statue isn't totem in fact) if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE) if(Unit* owner = GetOwner()) - return owner->SpellHealingBonus(pVictim, spellProto, healamount, damagetype, stack); - - float TakenTotalMod = 1.0f; - - // Healing taken percent - float minval = float(pVictim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); - if(minval) - TakenTotalMod *= (100.0f + minval) / 100.0f; - - float maxval = float(pVictim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); - if(maxval) - TakenTotalMod *= (100.0f + maxval) / 100.0f; + return owner->SpellHealingBonusDone(pVictim, spellProto, healamount, damagetype, stack); // No heal amount for this class spells if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) - { - healamount = int32(healamount * TakenTotalMod); return healamount < 0 ? 0 : healamount; - } // Healing Done - // Taken/Done total percent damage auras + // Done total percent damage auras float DoneTotalMod = 1.0f; int32 DoneTotal = 0; - int32 TakenTotal = 0; // Healing done percent AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); @@ -9640,7 +9691,7 @@ int32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, int32 ++ownHotCount; if (ownHotCount) - TakenTotalMod *= (stepPercent * ownHotCount + 100.0f) / 100.0f; + DoneTotalMod *= (stepPercent * ownHotCount + 100.0f) / 100.0f; break; } case 7871: // Glyph of Lesser Healing Wave @@ -9654,9 +9705,27 @@ int32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, int32 } } - // Taken/Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto)); - int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); + // Nourish 20% of heal increase if target is affected by Druids HOTs + if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags & UI64LIT(0x0200000000000000))) + { + int ownHotCount = 0; // counted HoT types amount, not stacks + Unit::AuraList const& RejorRegr = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); + for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && + (*i)->GetCasterGUID() == GetGUID()) + ++ownHotCount; + + if (ownHotCount) + { + DoneTotalMod *= 1.2f; // base bonus at HoTs + + if (Aura* glyph = GetAura(62971, EFFECT_INDEX_0))// Glyph of Nourish + DoneTotalMod *= (glyph->GetModifier()->m_amount * ownHotCount + 100.0f) / 100.0f; + } + } + + // Done fixed damage bonus auras + int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(GetSpellSchoolMask(spellProto)); float LvlPenalty = CalculateLevelPenalty(spellProto); // Spellmod SpellDamage @@ -9671,18 +9740,17 @@ int32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, int32 { float coeff; if (damagetype == DOT) - coeff = bonus->dot_damage * LvlPenalty * stack; + coeff = bonus->dot_damage * LvlPenalty; else - coeff = bonus->direct_damage * LvlPenalty * stack; + coeff = bonus->direct_damage * LvlPenalty; if (bonus->ap_bonus) - DoneTotal += int32(bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack); + DoneTotal += int32(bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK)); DoneTotal += int32(DoneAdvertisedBenefit * coeff * SpellModSpellDamage); - TakenTotal += int32(TakenAdvertisedBenefit * coeff); } // Default calculation - else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit) + else if (DoneAdvertisedBenefit) { // Damage over Time spells bonus calculation float DotFactor = 1.0f; @@ -9692,10 +9760,7 @@ int32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, int32 DotFactor = GetSpellDuration(spellProto) / 15000.0f; uint16 DotTicks = GetSpellAuraMaxTicks(spellProto); if(DotTicks) - { - DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks; - TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks; - } + DoneAdvertisedBenefit = DoneAdvertisedBenefit / DotTicks; } // Distribute Damage over multiple effects, reduce by AoE uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); @@ -9711,56 +9776,103 @@ int32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, int32 } } DoneTotal += int32(DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * SpellModSpellDamage * 1.88f); - TakenTotal += int32(TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * 1.88f); } // use float as more appropriate for negative values and percent applying - float heal = (healamount + DoneTotal)*DoneTotalMod; + float heal = (healamount + DoneTotal * stack)*DoneTotalMod; // apply spellmod to Done amount if(Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal); - // Taken mods - // Healing Wave cast - if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000040))) + return heal < 0 ? 0 : uint32(heal); +} + +/** + * Calculates target part of healing spell bonuses, + * will be called on each tick for periodic damage over time auras + */ +uint32 Unit::SpellHealingBonusTaken(Unit *pCaster, SpellEntry const *spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack) +{ + float TakenTotalMod = 1.0f; + + // Healing taken percent + float minval = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); + if(minval) + TakenTotalMod *= (100.0f + minval) / 100.0f; + + float maxval = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); + if(maxval) + TakenTotalMod *= (100.0f + maxval) / 100.0f; + + // No heal amount for this class spells + if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) { - // Search for Healing Way on Victim - Unit::AuraList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr!=auraDummy.end(); ++itr) - if((*itr)->GetId() == 29203) - TakenTotalMod *= ((*itr)->GetModifier()->m_amount+100.0f) / 100.0f; + healamount = int32(healamount * TakenTotalMod); + return healamount < 0 ? 0 : healamount; } - // Nourish 20% of heal increase if target is affected by Druids HOTs - else if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags & UI64LIT(0x0200000000000000))) + + // Healing Done + // Done total percent damage auras + int32 TakenTotal = 0; + + // Taken fixed damage bonus auras + int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(GetSpellSchoolMask(spellProto)); + + float LvlPenalty = CalculateLevelPenalty(spellProto); + + // Check for table values + SpellBonusEntry const* bonus = sSpellMgr.GetSpellBonusData(spellProto->Id); + if (bonus) { - int ownHotCount = 0; // counted HoT types amount, not stacks - Unit::AuraList const& RejorRegr = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); - for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && - (*i)->GetCasterGUID() == GetGUID()) - ++ownHotCount; + float coeff; + if (damagetype == DOT) + coeff = bonus->dot_damage * LvlPenalty; + else + coeff = bonus->direct_damage * LvlPenalty; - if (ownHotCount) + TakenTotal += int32(TakenAdvertisedBenefit * coeff); + } + // Default calculation + else if (TakenAdvertisedBenefit) + { + // Damage over Time spells bonus calculation + float DotFactor = 1.0f; + if(damagetype == DOT) { - TakenTotalMod *= 1.2f; // base bonus at HoTs - - if (Aura* glyph = GetAura(62971, EFFECT_INDEX_0))// Glyph of Nourish - TakenTotalMod *= (glyph->GetModifier()->m_amount * ownHotCount + 100.0f) / 100.0f; + if(!IsChanneledSpell(spellProto)) + DotFactor = GetSpellDuration(spellProto) / 15000.0f; + uint16 DotTicks = GetSpellAuraMaxTicks(spellProto); + if(DotTicks) + TakenAdvertisedBenefit = TakenAdvertisedBenefit / DotTicks; + } + // Distribute Damage over multiple effects, reduce by AoE + uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); + CastingTime = pCaster->GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); + // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing + for(int j = 0; j < MAX_EFFECT_INDEX; ++j) + { + if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH || + spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH ) + { + CastingTime /= 2; + break; + } } + TakenTotal += int32(TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty * 1.88f); } - - AuraList const& mHealingGet= pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED); + AuraList const& mHealingGet= GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED); for(AuraList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i) if ((*i)->isAffectedOnSpell(spellProto)) TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f; - heal = (heal + TakenTotal) * TakenTotalMod; + // use float as more appropriate for negative values and percent applying + float heal = (healamount + TakenTotal * stack) * TakenTotalMod; return heal < 0 ? 0 : uint32(heal); } -int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) +int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) { int32 AdvertisedBenefit = 0; @@ -9793,10 +9905,10 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) return AdvertisedBenefit; } -int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim) +int32 Unit::SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) { int32 AdvertisedBenefit = 0; - AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING); + AuraList const& mDamageTaken = GetAurasByType(SPELL_AURA_MOD_HEALING); for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i) if ((*i)->GetModifier()->m_miscvalue & schoolMask) AdvertisedBenefit += (*i)->GetModifier()->m_amount; @@ -9917,7 +10029,11 @@ bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const return false; } -uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto, DamageEffectType damagetype, uint32 stack) +/** + * Calculates caster part of melee damage bonuses, + * also includes different bonuses dependent from target auras + */ +uint32 Unit::MeleeDamageBonusDone(Unit *pVictim, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto, DamageEffectType damagetype, uint32 stack) { if (!pVictim) return pdamage; @@ -9940,7 +10056,6 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att // FLAT damage bonus auras // ======================= int32 DoneFlat = 0; - int32 TakenFlat = 0; int32 APbonus = 0; // ..done flat, already included in wepon damage based spells @@ -9971,22 +10086,16 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att { APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS); APbonus += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS, creatureTypeMask); - TakenFlat += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN); } else { APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS); APbonus += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS, creatureTypeMask); - TakenFlat += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN); } - // ..taken flat (by school mask) - TakenFlat += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, schoolMask); - // PERCENT damage auras // ==================== float DonePercent = 1.0f; - float TakenPercent = 1.0f; // ..done pct, already included in weapon damage based spells if(!isWeaponDamageBasedSpell) @@ -10010,23 +10119,6 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att // ..done pct (by creature type mask) DonePercent *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS, creatureTypeMask); - // ..taken pct (by school mask) - TakenPercent *= pVictim->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, schoolMask); - - // ..taken pct (by mechanic mask) - TakenPercent *= pVictim->GetTotalAuraMultiplierByMiscValueForMask(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT,mechanicMask); - - // ..taken pct (melee/ranged) - if(attType == RANGED_ATTACK) - TakenPercent *= pVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT); - else - TakenPercent *= pVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT); - - // ..taken pct (aoe avoidance) - if(spellProto && IsAreaOfEffectSpell(spellProto)) - TakenPercent *= pVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE); - - // special dummys/class sripts and other effects // ============================================= Unit *owner = GetOwner(); @@ -10084,30 +10176,7 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att } } - // .. taken (dummy auras) - AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); - for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) - { - switch((*i)->GetSpellProto()->SpellIconID) - { - //Cheat Death - case 2109: - if((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) - { - if(pVictim->GetTypeId() != TYPEID_PLAYER) - continue; - - float mod = ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*(-8.0f); - if (mod < float((*i)->GetModifier()->m_amount)) - mod = float((*i)->GetModifier()->m_amount); - - TakenPercent *= (mod + 100.0f) / 100.0f; - } - break; - } - } - - // .. taken (class scripts) + // .. done (class scripts) AuraList const& mclassScritAuras = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for(AuraList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i) { @@ -10126,7 +10195,7 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att } // effect 0 have expected value but in negative state - TakenPercent *= (-eff0->GetModifier()->m_amount + 100.0f) / 100.0f; + DonePercent *= (-eff0->GetModifier()->m_amount + 100.0f) / 100.0f; } break; } @@ -10146,18 +10215,17 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att { float coeff; if (damagetype == DOT) - coeff = bonus->dot_damage * LvlPenalty * stack; + coeff = bonus->dot_damage * LvlPenalty; else - coeff = bonus->direct_damage * LvlPenalty * stack; + coeff = bonus->direct_damage * LvlPenalty; if (bonus->ap_bonus) - DoneFlat += bonus->ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + APbonus) * stack; + DoneFlat += bonus->ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + APbonus); DoneFlat *= coeff; - TakenFlat *= coeff; } // Default calculation - else if (DoneFlat || TakenFlat) + else if (DoneFlat) { // Damage over Time spells bonus calculation float DotFactor = 1.0f; @@ -10167,16 +10235,12 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att DotFactor = GetSpellDuration(spellProto) / 15000.0f; uint16 DotTicks = GetSpellAuraMaxTicks(spellProto); if(DotTicks) - { - DoneFlat = DoneFlat * int32(stack) / DotTicks; - TakenFlat = TakenFlat * int32(stack) / DotTicks; - } + DoneFlat = DoneFlat / DotTicks; } // Distribute Damage over multiple effects, reduce by AoE uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); DoneFlat *= (CastingTime / 3500.0f) * DotFactor * LvlPenalty; - TakenFlat*= (CastingTime / 3500.0f) * DotFactor * LvlPenalty; } } // weapon damage based spells @@ -10200,7 +10264,7 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att DoneFlat *= GetModifierValue(unitMod, TOTAL_PCT); } - float tmpDamage = float(int32(pdamage) + DoneFlat) * DonePercent; + float tmpDamage = float(int32(pdamage) + DoneFlat * stack) * DonePercent; // apply spellmod to Done damage if(spellProto) @@ -10209,7 +10273,132 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage); } - tmpDamage = (tmpDamage + TakenFlat) * TakenPercent; + // bonus result can be negative + return tmpDamage > 0 ? uint32(tmpDamage) : 0; +} + +/** + * Calculates target part of melee damage bonuses, + * will be called on each tick for periodic damage over time auras + */ +uint32 Unit::MeleeDamageBonusTaken(Unit *pCaster, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto, DamageEffectType damagetype, uint32 stack) +{ + if (!pCaster) + return pdamage; + + if (pdamage == 0) + return pdamage; + + // differentiate for weapon damage based spells + bool isWeaponDamageBasedSpell = !(spellProto && (damagetype == DOT || IsSpellHaveEffect(spellProto, SPELL_EFFECT_SCHOOL_DAMAGE))); + uint32 schoolMask = spellProto ? spellProto->SchoolMask : GetMeleeDamageSchoolMask(); + uint32 mechanicMask = spellProto ? GetAllSpellMechanicMask(spellProto) : 0; + + // Shred also have bonus as MECHANIC_BLEED damages + if (spellProto && spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags & UI64LIT(0x00008000)) + mechanicMask |= (1 << (MECHANIC_BLEED-1)); + + + // FLAT damage bonus auras + // ======================= + int32 TakenFlat = 0; + + // ..taken flat (base at attack power for marked target and base at attack power for creature type) + if (attType == RANGED_ATTACK) + TakenFlat += GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN); + else + TakenFlat += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN); + + // ..taken flat (by school mask) + TakenFlat += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, schoolMask); + + // PERCENT damage auras + // ==================== + float TakenPercent = 1.0f; + + // ..taken pct (by school mask) + TakenPercent *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, schoolMask); + + // ..taken pct (by mechanic mask) + TakenPercent *= GetTotalAuraMultiplierByMiscValueForMask(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT,mechanicMask); + + // ..taken pct (melee/ranged) + if(attType == RANGED_ATTACK) + TakenPercent *= GetTotalAuraMultiplier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT); + else + TakenPercent *= GetTotalAuraMultiplier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT); + + // ..taken pct (aoe avoidance) + if(spellProto && IsAreaOfEffectSpell(spellProto)) + TakenPercent *= GetTotalAuraMultiplier(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE); + + + // special dummys/class scripts and other effects + // ============================================= + + // .. taken (dummy auras) + AuraList const& mDummyAuras = GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) + { + switch((*i)->GetSpellProto()->SpellIconID) + { + //Cheat Death + case 2109: + if((*i)->GetModifier()->m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) + { + if(GetTypeId() != TYPEID_PLAYER) + continue; + + float mod = ((Player*)this)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*(-8.0f); + if (mod < float((*i)->GetModifier()->m_amount)) + mod = float((*i)->GetModifier()->m_amount); + + TakenPercent *= (mod + 100.0f) / 100.0f; + } + break; + } + } + + // final calculation + // ================= + + // scaling of non weapon based spells + if (!isWeaponDamageBasedSpell) + { + float LvlPenalty = CalculateLevelPenalty(spellProto); + + // Check for table values + if (SpellBonusEntry const* bonus = sSpellMgr.GetSpellBonusData(spellProto->Id)) + { + float coeff; + if (damagetype == DOT) + coeff = bonus->dot_damage * LvlPenalty; + else + coeff = bonus->direct_damage * LvlPenalty; + + TakenFlat *= coeff; + } + // Default calculation + else if (TakenFlat) + { + // Damage over Time spells bonus calculation + float DotFactor = 1.0f; + if(damagetype == DOT) + { + if(!IsChanneledSpell(spellProto)) + DotFactor = GetSpellDuration(spellProto) / 15000.0f; + uint16 DotTicks = GetSpellAuraMaxTicks(spellProto); + if(DotTicks) + TakenFlat = TakenFlat / DotTicks; + } + // Distribute Damage over multiple effects, reduce by AoE + uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); + CastingTime = pCaster->GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); + TakenFlat*= (CastingTime / 3500.0f) * DotFactor * LvlPenalty; + } + } + + float tmpDamage = float(int32(pdamage) + TakenFlat * stack) * TakenPercent; // bonus result can be negative return tmpDamage > 0 ? uint32(tmpDamage) : 0; diff --git a/src/game/Unit.h b/src/game/Unit.h index 06c38a490bc..1a6fd5ef508 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1703,12 +1703,18 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool HasAuraStateForCaster(AuraState flag, uint64 caster) const; void UnsummonAllTotems(); Unit* SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo = NULL); - int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask); - int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask); - int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); - int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim); - uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1); - int32 SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack = 1); + + int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask); + int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask); + uint32 SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellDamageBonusTaken(Unit *pCaster, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); + int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask); + int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask); + uint32 SpellHealingBonusDone(Unit *pVictim, SpellEntry const *spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellHealingBonusTaken(Unit *pCaster, SpellEntry const *spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack = 1); + uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1); + uint32 MeleeDamageBonusTaken(Unit *pCaster, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1); + bool IsSpellBlocked(Unit *pCaster, SpellEntry const *spellProto, WeaponAttackType attackType = BASE_ATTACK); bool IsSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK); uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); @@ -1727,7 +1733,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void SetContestedPvP(Player *attackedPlayer = NULL); - uint32 MeleeDamageBonus(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack =1); uint32 GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime ); void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ed80a2e73cc..b0ad510eb7f 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9797" + #define REVISION_NR "9798" #endif // __REVISION_NR_H__