Core/Auras: Implemented SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE

This commit is contained in:
Shauren
2021-02-21 15:32:52 +01:00
parent fea8306aa3
commit 5ed75bb2d3
2 changed files with 55 additions and 34 deletions

View File

@@ -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();

View File

@@ -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());
case SPELL_AURA_PERIODIC_DAMAGE:
{
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()))
{
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())
// 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))
{