diff options
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 4 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 83 |
2 files changed, 54 insertions, 33 deletions
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index ba8b58e5317..1e76a1ffa2c 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1291,7 +1291,7 @@ class TC_GAME_API Unit : public WorldObject void ClearInPetCombat(); uint32 GetCombatTimer() const { return m_CombatTimer; } - bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const; + bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, flag128 familyFlags) const; bool virtual HasSpell(uint32 /*spellID*/) const { return false; } bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura = 0) const; bool HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel = nullptr) const; @@ -1860,7 +1860,7 @@ class TC_GAME_API Unit : public WorldObject uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack = 1) const; uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr); - uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr); + uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr); bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK); bool isBlockCritical(); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index db2c6865199..c6d680a31ab 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -138,7 +138,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM &AuraEffect::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED &AuraEffect::HandleNoImmediateEffect, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist - &AuraEffect::HandleNULL, // 70 SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE + &AuraEffect::HandleNoImmediateEffect, // 70 SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE implemented in AuraEffect::PeriodicTick &AuraEffect::HandleNULL, // 71 SPELL_AURA_STORE_TELEPORT_RETURN_POINT &AuraEffect::HandleNoImmediateEffect, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT &AuraEffect::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL @@ -1125,6 +1125,7 @@ void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const HandlePeriodicTriggerSpellWithValueAuraTick(target, caster); break; case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE: case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: HandlePeriodicDamageAurasTick(target, caster); break; @@ -5546,43 +5547,63 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const if (isAreaAura) sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage); - if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE) + switch (GetAuraType()) { - if (isAreaAura) - damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT); - damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); - - // Calculate armor mitigation - if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex())) + case SPELL_AURA_PERIODIC_DAMAGE: { - uint32 damageReductedArmor = caster->CalcArmorReducedDamage(caster, target, damage, GetSpellInfo()); - cleanDamage.mitigated_damage += damage - damageReductedArmor; - damage = damageReductedArmor; - } + if (isAreaAura) + damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT); + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()); - // There is a Chance to make a Soul Shard when Drain soul does damage - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000)) - { - if (caster->GetTypeId() == TYPEID_PLAYER && caster->ToPlayer()->isHonorOrXPTarget(target)) - caster->CastSpell(caster, 95810, true, nullptr, this); - } - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_GENERIC) - { - switch (GetId()) + // Calculate armor mitigation + if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex())) { - case 70911: // Unbound Plague - case 72854: // Unbound Plague - case 72855: // Unbound Plague - case 72856: // Unbound Plague - damage *= uint32(pow(1.25f, int32(m_tickNumber))); - break; - default: - break; + uint32 damageReductedArmor = caster->CalcArmorReducedDamage(caster, target, damage, GetSpellInfo()); + cleanDamage.mitigated_damage += damage - damageReductedArmor; + damage = damageReductedArmor; } + + // There is a Chance to make a Soul Shard when Drain soul does damage + if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000)) + { + if (caster->GetTypeId() == TYPEID_PLAYER && caster->ToPlayer()->isHonorOrXPTarget(target)) + caster->CastSpell(caster, 95810, true, nullptr, this); + } + if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_GENERIC) + { + switch (GetId()) + { + case 70911: // Unbound Plague + case 72854: // Unbound Plague + case 72855: // Unbound Plague + case 72856: // Unbound Plague + damage *= uint32(pow(1.25f, int32(m_tickNumber))); + break; + default: + break; + } + } + break; } + case SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE: + { + WeaponAttackType attackType = GetSpellInfo()->GetAttackType(); + + int32 weaponDamage = CalculatePct(caster->CalculateDamage(attackType, false, true), GetAmount()); + + // Add melee damage bonuses (also check for negative) + uint32 damageBonusDone = caster->MeleeDamageBonusDone(target, std::max(weaponDamage, 0), attackType, GetSpellInfo()); + + damage = target->MeleeDamageBonusTaken(caster, damageBonusDone, attackType, DOT, GetSpellInfo()); + break; + } + case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: + // ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner + damage = uint32(ceil(CalculatePct<float, float>(target->GetMaxHealth(), damage))); + break; + default: + break; } - else // ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner - damage = uint32(ceil(CalculatePct<float, float>(target->GetMaxHealth(), damage))); if (!m_spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) { |