From f15cc130fa851a2daa542e5c96fbc30e60225dea Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 22 Feb 2021 15:29:14 -0500 Subject: [PATCH] Core/Auras: Implemented SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE Port From (https://github.com/TrinityCore/TrinityCore/commit/5ed75bb2d3fdc5bd2ee4dddb748db291fe3b1541) --- .../Framework/Constants/Spells/SpellConst.cs | 4 +- Source/Game/Entities/Unit/Unit.Spells.cs | 8 ++ Source/Game/Spells/Auras/AuraEffect.cs | 87 ++++++++++++------- Source/Game/Spells/Spell.cs | 31 ++++++- Source/Game/Spells/SpellEffects.cs | 8 +- Source/Game/Spells/SpellInfo.cs | 4 +- Source/Game/Spells/SpellManager.cs | 4 +- 7 files changed, 100 insertions(+), 46 deletions(-) diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 164056e96..1abb5d330 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -1920,7 +1920,7 @@ namespace Framework.Constants Unk6 = 0x40, // 6 Unk7 = 0x80, // 7 Unk8 = 0x100, // 8 - Unk9 = 0x200, // 9 + IgnoreCastingDisabled = 0x200, // 9 Unk10 = 0x400, // 10 Unk11 = 0x800, // 11 Unk12 = 0x1000, // 12 @@ -2023,7 +2023,7 @@ namespace Framework.Constants IncreseCurrencyCap = 14, RitualActivatePortal = 15, // Unused (4.3.4) QuestComplete = 16, - WeaponDamageNoschool = 17, + WeaponDamageNoSchool = 17, Resurrect = 18, AddExtraAttacks = 19, Dodge = 20, diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 8c04cb53f..3b38108a2 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -1425,6 +1425,14 @@ namespace Game.Entities return true; } + public bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint familyName, FlagArray128 familyFlags) + { + foreach (AuraEffect aura in GetAuraEffectsByType(auraType)) + if (aura.GetSpellInfo().SpellFamilyName == (SpellFamilyNames)familyName && aura.GetSpellInfo().SpellFamilyFlags & familyFlags) + return true; + return false; + } + bool HasBreakableByDamageAuraType(AuraType type, uint excludeAura) { var auras = GetAuraEffectsByType(type); diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs index 9e24874b6..4f1d7a9c6 100644 --- a/Source/Game/Spells/Auras/AuraEffect.cs +++ b/Source/Game/Spells/Auras/AuraEffect.cs @@ -579,6 +579,7 @@ namespace Game.Spells HandlePeriodicTriggerSpellWithValueAuraTick(target, caster); break; case AuraType.PeriodicDamage: + case AuraType.PeriodicWeaponPercentDamage: case AuraType.PeriodicDamagePercent: HandlePeriodicDamageAurasTick(target, caster); break; @@ -5299,43 +5300,63 @@ namespace Game.Spells if (isAreaAura) Global.ScriptMgr.ModifyPeriodicDamageAurasTick(target, caster, ref damage); - if (GetAuraType() == AuraType.PeriodicDamage) + switch (GetAuraType()) { - if (isAreaAura) - damage = (uint)(caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()) * caster.SpellDamagePctDone(target, m_spellInfo, DamageEffectType.DOT)); - damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); - - // Calculate armor mitigation - if (caster.IsDamageReducedByArmor(GetSpellInfo().GetSchoolMask(), GetSpellInfo(), (sbyte)GetEffIndex())) - { - uint 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 == SpellFamilyNames.Warlock && GetSpellInfo().SpellFamilyFlags[0].HasAnyFlag(0x00004000u)) - { - if (caster.IsTypeId(TypeId.Player) && caster.ToPlayer().IsHonorOrXPTarget(target)) - caster.CastSpell(caster, 95810, true, null, this); - } - if (GetSpellInfo().SpellFamilyName == SpellFamilyNames.Generic) - { - switch (GetId()) + case AuraType.PeriodicDamage: { - case 70911: // Unbound Plague - case 72854: // Unbound Plague - case 72855: // Unbound Plague - case 72856: // Unbound Plague - damage *= (uint)Math.Pow(1.25f, m_tickNumber); - break; - default: - break; + if (isAreaAura) + damage = (uint)(caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()) * caster.SpellDamagePctDone(target, m_spellInfo, DamageEffectType.DOT)); + damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), GetBase().GetStackAmount()); + + // Calculate armor mitigation + if (caster.IsDamageReducedByArmor(GetSpellInfo().GetSchoolMask(), GetSpellInfo(), (sbyte)GetEffIndex())) + { + uint 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 == SpellFamilyNames.Warlock && GetSpellInfo().SpellFamilyFlags[0].HasAnyFlag(0x00004000u)) + { + if (caster.IsTypeId(TypeId.Player) && caster.ToPlayer().IsHonorOrXPTarget(target)) + caster.CastSpell(caster, 95810, true, null, this); + } + + if (GetSpellInfo().SpellFamilyName == SpellFamilyNames.Generic) + { + switch (GetId()) + { + case 70911: // Unbound Plague + case 72854: // Unbound Plague + case 72855: // Unbound Plague + case 72856: // Unbound Plague + damage *= (uint)Math.Pow(1.25f, m_tickNumber); + break; + default: + break; + } + } + break; } - } + case AuraType.PeriodicWeaponPercentDamage: + { + WeaponAttackType attackType = GetSpellInfo().GetAttackType(); + + uint weaponDamage = MathFunctions.CalculatePct(caster.CalculateDamage(attackType, false, true), GetAmount()); + + // Add melee damage bonuses (also check for negative) + uint damageBonusDone = caster.MeleeDamageBonusDone(target, Math.Max(weaponDamage, 0), attackType, GetSpellInfo()); + + damage = target.MeleeDamageBonusTaken(caster, damageBonusDone, attackType, DamageEffectType.DOT, GetSpellInfo()); + break; + } + case AuraType.PeriodicDamagePercent: + // ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner + damage = (uint)Math.Ceiling(MathFunctions.CalculatePct((float)target.GetMaxHealth(), (float)damage)); + break; + default: + break; } - else // ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner - damage = (uint)Math.Ceiling((float)MathFunctions.CalculatePct(target.GetMaxHealth(), damage)); if (!m_spellInfo.HasAttribute(SpellAttr4.FixedDamage)) { diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index f7c8ae4b1..0a39bdead 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -4448,8 +4448,33 @@ namespace Game.Spells if (m_caster.IsTypeId(TypeId.Player)) { //can cast triggered (by aura only?) spells while have this flag - if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreCasterAurastate) && m_caster.ToPlayer().HasPlayerFlag(PlayerFlags.AllowOnlyAbility)) - return SpellCastResult.SpellInProgress; + if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreCasterAurastate)) + { + // These two auras check SpellFamilyName defined by db2 class data instead of current spell SpellFamilyName + if (m_caster.HasAuraType(AuraType.DisableCastingExceptAbilities) + && !m_spellInfo.HasAttribute(SpellAttr0.ReqAmmo) + && !m_spellInfo.HasEffect(SpellEffectName.Attack) + && !m_spellInfo.HasAttribute(SpellAttr12.IgnoreCastingDisabled) + && !m_caster.HasAuraTypeWithFamilyFlags(AuraType.DisableCastingExceptAbilities, CliDB.ChrClassesStorage.LookupByKey(m_caster.GetClass()).SpellClassSet, m_spellInfo.SpellFamilyFlags)) + return SpellCastResult.CantDoThatRightNow; + + if (m_caster.HasAuraType(AuraType.DisableAttackingExceptAbilities)) + { + if (!m_caster.HasAuraTypeWithFamilyFlags(AuraType.DisableAttackingExceptAbilities, CliDB.ChrClassesStorage.LookupByKey(m_caster.GetClass()).SpellClassSet, m_spellInfo.SpellFamilyFlags)) + { + if (m_spellInfo.HasAttribute(SpellAttr0.ReqAmmo) + || m_spellInfo.IsNextMeleeSwingSpell() + || m_spellInfo.HasAttribute(SpellAttr1.MeleeCombatStart) + || m_spellInfo.HasAttribute(SpellAttr2.Unk20) + || m_spellInfo.HasEffect(SpellEffectName.Attack) + || m_spellInfo.HasEffect(SpellEffectName.NormalizedWeaponDmg) + || m_spellInfo.HasEffect(SpellEffectName.WeaponDamageNoSchool) + || m_spellInfo.HasEffect(SpellEffectName.WeaponPercentDamage) + || m_spellInfo.HasEffect(SpellEffectName.WeaponDamage)) + return SpellCastResult.CantDoThatRightNow; + } + } + } // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat if (!IsIgnoringCooldowns() && m_caster.ToPlayer().GetLastPotionId() != 0 && m_CastItem && (m_CastItem.IsPotion() || m_spellInfo.IsCooldownStartedOnEvent())) @@ -6306,7 +6331,7 @@ namespace Game.Spells break; } case SpellEffectName.WeaponDamage: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: { if (!m_caster.IsTypeId(TypeId.Player)) return SpellCastResult.TargetNotPlayer; diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index bac4af283..00d96251a 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -2454,7 +2454,7 @@ namespace Game.Spells unitTarget.ToCreature().GetAI().AttackStart(m_caster); } - [SpellEffectHandler(SpellEffectName.WeaponDamageNoschool)] + [SpellEffectHandler(SpellEffectName.WeaponDamageNoSchool)] [SpellEffectHandler(SpellEffectName.WeaponPercentDamage)] [SpellEffectHandler(SpellEffectName.WeaponDamage)] [SpellEffectHandler(SpellEffectName.NormalizedWeaponDmg)] @@ -2478,7 +2478,7 @@ namespace Game.Spells switch (effect.Effect) { case SpellEffectName.WeaponDamage: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.NormalizedWeaponDmg: case SpellEffectName.WeaponPercentDamage: return; // we must calculate only at last weapon effect @@ -2588,7 +2588,7 @@ namespace Game.Spells switch (effect.Effect) { case SpellEffectName.WeaponDamage: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: fixed_bonus += CalculateDamage(effect.EffectIndex, unitTarget); break; case SpellEffectName.NormalizedWeaponDmg: @@ -2643,7 +2643,7 @@ namespace Game.Spells switch (effect.Effect) { case SpellEffectName.WeaponDamage: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.NormalizedWeaponDmg: weaponDamage += (uint)fixed_bonus; break; diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index 9a88cccd0..9b514538e 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -273,7 +273,7 @@ namespace Game.Spells switch (effect.Effect) { case SpellEffectName.WeaponDamage: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.NormalizedWeaponDmg: case SpellEffectName.WeaponPercentDamage: case SpellEffectName.SchoolDamage: @@ -4008,7 +4008,7 @@ namespace Game.Spells case SpellEffectName.SchoolDamage: case SpellEffectName.EnvironmentalDamage: case SpellEffectName.HealthLeech: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.WeaponDamage: return ExpectedStatType.CreatureSpellDamage; case SpellEffectName.Heal: diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index dacb9cce0..3d11b2082 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -2442,7 +2442,7 @@ namespace Game.Entities { case SpellEffectName.SchoolDamage: case SpellEffectName.WeaponDamage: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.NormalizedWeaponDmg: case SpellEffectName.WeaponPercentDamage: case SpellEffectName.Heal: @@ -2519,7 +2519,7 @@ namespace Game.Entities { case SpellEffectName.SchoolDamage: case SpellEffectName.WeaponDamage: - case SpellEffectName.WeaponDamageNoschool: + case SpellEffectName.WeaponDamageNoSchool: case SpellEffectName.NormalizedWeaponDmg: case SpellEffectName.WeaponPercentDamage: case SpellEffectName.TriggerSpell: