diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index aaf409dc8..108bd404b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7360,67 +7360,24 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE ) return pdamage; - int32 BonusDamage = 0; - if( GetTypeId()==TYPEID_UNIT ) + // For totems get damage bonus from owner (statue isn't totem in fact) + if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE) { - // Pets just add their bonus damage to their spell damage - // note that their spell damage is just gain of their own auras - if (((Creature*)this)->isPet()) - { - BonusDamage = ((Pet*)this)->GetBonusDamage(); - } - // For totems get damage bonus from owner (statue isn't totem in fact) - else if (((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE) - { - if(Unit* owner = GetOwner()) - return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype); - } - } - - // Damage Done - uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); - - // Taken/Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto))+BonusDamage; - int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); - - // Damage over Time spells bonus calculation - float DotFactor = 1.0f; - if(damagetype == DOT) - { - int32 DotDuration = GetSpellDuration(spellProto); - // 200% limit - if(DotDuration > 0) - { - if(DotDuration > 30000) DotDuration = 30000; - if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f; - int x = 0; - for(int j = 0; j < 3; j++) - { - if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && ( - spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE || - spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) ) - { - x = j; - break; - } - } - int DotTicks = 6; - if(spellProto->EffectAmplitude[x] != 0) - DotTicks = DotDuration / spellProto->EffectAmplitude[x]; - if(DotTicks) - { - DoneAdvertisedBenefit /= DotTicks; - TakenAdvertisedBenefit /= DotTicks; - } - } + if(Unit* owner = GetOwner()) + return owner->SpellDamageBonus(pVictim, spellProto, pdamage, damagetype); } // Taken/Done total percent damage auras float DoneTotalMod = 1.0f; float TakenTotalMod = 1.0f; + uint32 DoneTotal = 0; + uint32 TakenTotal = 0; // ..done + // Pet damage + if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() ) + DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank); + AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) { @@ -7435,17 +7392,13 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); + // Add flat bonus from spell damage versus + DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask); AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; - // ..taken - AuraList const& mModDamagePercentTaken = pVictim->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) ) - TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; - // done scripted mod (take it from owner) Unit *owner = GetOwner(); if (!owner) owner = this; @@ -7456,12 +7409,14 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 continue; switch((*i)->GetModifier()->m_miscvalue) { - // Molten Fury - case 4920: + case 4920: // Molten Fury case 4919: + case 6917: // Death's Embrace + case 6926: + case 6928: { if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT)) - TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; + DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; break; } // Soul Siphon @@ -7474,13 +7429,13 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 int32 stepPercent = CalculateSpellDamage((*i)->GetSpellProto(), 0, (*i)->GetSpellProto()->EffectBasePoints[0], this); // count affliction effects and calc additional damage in percentage int32 modPercent = 0; - Unit::AuraMap const& victimAuras = pVictim->GetAuras(); - for (Unit::AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) + AuraMap const& victimAuras = pVictim->GetAuras(); + for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) { SpellEntry const* m_spell = itr->second->GetSpellProto(); if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags & 0x0004071B8044C402LL)) continue; - modPercent += stepPercent; + modPercent += stepPercent * itr->second->GetStackAmount(); if (modPercent >= maxPercent) { modPercent = maxPercent; @@ -7490,8 +7445,13 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 DoneTotalMod *= (modPercent+100.0f)/100.0f; break; } - // Starfire Bonus - case 5481: + case 6916: // Death's Embrace + case 6925: + case 6927: + if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT)) + DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; + break; + case 5481: // Starfire Bonus { AuraList const& auras = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); for(AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) @@ -7510,11 +7470,11 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 case 4554: // Increased Lightning Damage case 4555: // Improved Moonfire case 5142: // Increased Lightning Damage - case 5147: // Improved Consecration + case 5147: // Improved Consecration / Libram of Resurgence case 5148: // Idol of the Shooting Star case 6008: // Increased Lightning Damage / Totem of Hex { - pdamage+=(*i)->GetModifier()->m_amount; + DoneTotal+=(*i)->GetModifier()->m_amount; break; } // Tundra Stalker @@ -7525,7 +7485,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 if ((*i)->GetSpellProto()->SpellIconID == 2656) { if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT)) - TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; + DoneTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; } else // Tundra Stalker { @@ -7543,7 +7503,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } break; } - case 7293: + case 7293: // Rage of Rivendare { AuraList const& auras = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); for(AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) @@ -7597,6 +7557,13 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } } } + + // ..taken + AuraList const& mModDamagePercentTaken = pVictim->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) ) + TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + // .. taken pct: dummy auras AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) @@ -7634,6 +7601,49 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; } + // Damage Done from spell damage bonus + uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto); + + // 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(); + + // Damage over Time spells bonus calculation + float DotFactor = 1.0f; + if(damagetype == DOT) + { + int32 DotDuration = GetSpellDuration(spellProto); + // 200% limit + if(DotDuration > 0) + { + if(DotDuration > 30000) DotDuration = 30000; + if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f; + int x = 0; + for(int j = 0; j < 3; j++) + { + if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && ( + spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE || + spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) ) + { + x = j; + break; + } + } + int DotTicks = 6; + if(spellProto->EffectAmplitude[x] != 0) + DotTicks = DotDuration / spellProto->EffectAmplitude[x]; + if(DotTicks) + { + DoneAdvertisedBenefit /= DotTicks; + TakenAdvertisedBenefit /= DotTicks; + } + } + } // Distribute Damage over multiple effects, reduce by AoE CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); @@ -7853,19 +7863,12 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; float TakenActualBenefit = TakenAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * LvlPenalty; - float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod; - - // Add flat bonus from spell damage versus - tmpDamage += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask); - - // apply spellmod to Done damage + float tmpDamage = (float(pdamage)+DoneActualBenefit + 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+TakenActualBenefit)*TakenTotalMod; - - if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() ) - tmpDamage *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank); + tmpDamage = (tmpDamage + TakenActualBenefit + TakenTotal)*TakenTotalMod; return tmpDamage > 0 ? uint32(tmpDamage) : 0; }