From 09a4e13453894517f424fca2deb9a60753045cff Mon Sep 17 00:00:00 2001 From: hondacrx Date: Thu, 5 May 2022 09:52:50 -0400 Subject: [PATCH] Core/Spells: Implement SPELL_ATTR7_NO_ATTACK_DODGE, SPELL_ATTR7_NO_ATTACK_PARRY and SPELL_ATTR7_NO_ATTACK_MISS Port From (https://github.com/TrinityCore/TrinityCore/commit/d22d4616339a966ce5e5fe959dca622fc21b7988) --- .../Framework/Constants/Spells/SpellConst.cs | 6 +- Source/Game/Entities/Object/WorldObject.cs | 98 ++++++++++--------- Source/Game/Entities/StatSystem.cs | 3 + Source/Game/Entities/Unit/Unit.Spells.cs | 4 +- 4 files changed, 62 insertions(+), 49 deletions(-) diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 077aefa6b..52bc24761 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -1841,9 +1841,9 @@ namespace Framework.Constants Unk20 = 0x100000, // 20 Blink, Divine Shield, Ice Block Unk21 = 0x200000, // 21 Not Set Unk22 = 0x400000, // 22 - Unk23 = 0x800000, // 23 Motivate, Mutilate, Shattering Throw - Unk24 = 0x1000000, // 24 Motivate, Mutilate, Perform Speech, Shattering Throw - Unk25 = 0x2000000, // 25 + NoAttackDodge = 0x800000, // 23 No Attack Dodge + NoAttackParry = 0x1000000, // 24 No Attack Parry + NoAttackMiss = 0x2000000, // No Attack Miss Unk26 = 0x4000000, // 26 BypassNoResurrectAura = 0x8000000, // 27 Bypass No Resurrect Aura ConsolidatedRaidBuff = 0x10000000, // 28 Related To Player Positive Buff diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 5286748aa..ede676d14 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -1920,56 +1920,66 @@ namespace Game.Entities if (!victim.IsAlive() && !victim.IsPlayer()) return SpellMissInfo.None; - SpellSchoolMask schoolMask = spellInfo.GetSchoolMask(); - // PvP - PvE spell misschances per leveldif > 2 - int lchance = victim.IsPlayer() ? 7 : 11; - uint thisLevel = GetLevelForTarget(victim); - if (IsCreature() && ToCreature().IsTrigger()) - thisLevel = Math.Max(thisLevel, spellInfo.SpellLevel); - int leveldif = (int)(victim.GetLevelForTarget(this) - thisLevel); - int levelBasedHitDiff = leveldif; - - // Base hit chance from attacker and victim levels - int modHitChance = 100; - if (levelBasedHitDiff >= 0) + float missChance; + if (spellInfo.HasAttribute(SpellAttr7.NoAttackMiss)) { - if (!victim.IsPlayer()) - { - modHitChance = 94 - 3 * Math.Min(levelBasedHitDiff, 3); - levelBasedHitDiff -= 3; - } - else - { - modHitChance = 96 - Math.Min(levelBasedHitDiff, 2); - levelBasedHitDiff -= 2; - } - if (levelBasedHitDiff > 0) - modHitChance -= lchance * Math.Min(levelBasedHitDiff, 7); + missChance = 0.0f; } else - modHitChance = 97 - levelBasedHitDiff; - - // Spellmod from SpellModOp::HitChance - Player modOwner = GetSpellModOwner(); - if (modOwner != null) - modOwner.ApplySpellMod(spellInfo, SpellModOp.HitChance, ref modHitChance); - - // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects - if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult)) { - // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras - modHitChance += victim.GetTotalAuraModifierByMiscMask(AuraType.ModAttackerSpellHitChance, (int)schoolMask); + SpellSchoolMask schoolMask = spellInfo.GetSchoolMask(); + // PvP - PvE spell misschances per leveldif > 2 + int lchance = victim.IsPlayer() ? 7 : 11; + uint thisLevel = GetLevelForTarget(victim); + if (IsCreature() && ToCreature().IsTrigger()) + thisLevel = Math.Max(thisLevel, spellInfo.SpellLevel); + int leveldif = (int)(victim.GetLevelForTarget(this) - thisLevel); + int levelBasedHitDiff = leveldif; + + // Base hit chance from attacker and victim levels + int modHitChance = 100; + if (levelBasedHitDiff >= 0) + { + if (!victim.IsPlayer()) + { + modHitChance = 94 - 3 * Math.Min(levelBasedHitDiff, 3); + levelBasedHitDiff -= 3; + } + else + { + modHitChance = 96 - Math.Min(levelBasedHitDiff, 2); + levelBasedHitDiff -= 2; + } + if (levelBasedHitDiff > 0) + modHitChance -= lchance * Math.Min(levelBasedHitDiff, 7); + } + else + modHitChance = 97 - levelBasedHitDiff; + + // Spellmod from SpellModOp::HitChance + Player modOwner = GetSpellModOwner(); + if (modOwner != null) + modOwner.ApplySpellMod(spellInfo, SpellModOp.HitChance, ref modHitChance); + + // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects + if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult)) + { + // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras + modHitChance += victim.GetTotalAuraModifierByMiscMask(AuraType.ModAttackerSpellHitChance, (int)schoolMask); + } + + float HitChance = modHitChance; + // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings + Unit unit = ToUnit(); + if (unit != null) + HitChance += unit.ModSpellHitChance; + + MathFunctions.RoundToInterval(ref HitChance, 0.0f, 100.0f); + + missChance = 100.0f - HitChance; } - int HitChance = modHitChance * 100; - // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings - Unit unit = ToUnit(); - if (unit != null) - HitChance += (int)(unit.ModSpellHitChance * 100.0f); - - MathFunctions.RoundToInterval(ref HitChance, 0, 10000); - - int tmp = 10000 - HitChance; + int tmp = (int)(missChance * 100.0f); int rand = RandomHelper.IRand(0, 9999); if (tmp > 0 && rand < tmp) diff --git a/Source/Game/Entities/StatSystem.cs b/Source/Game/Entities/StatSystem.cs index 6708e602e..eea8d24c2 100644 --- a/Source/Game/Entities/StatSystem.cs +++ b/Source/Game/Entities/StatSystem.cs @@ -794,6 +794,9 @@ namespace Game.Entities //Chances public override float MeleeSpellMissChance(Unit victim, WeaponAttackType attType, SpellInfo spellInfo) { + if (spellInfo != null && spellInfo.HasAttribute(SpellAttr7.NoAttackMiss)) + return 0.0f; + //calculate miss chance float missChance = victim.GetUnitMissChance(); diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index cca4047d0..3d96c37bf 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -758,8 +758,8 @@ namespace Game.Entities if (spellInfo.HasAttribute(SpellAttr0.ImpossibleDodgeParryBlock)) return SpellMissInfo.None; - bool canDodge = true; - bool canParry = true; + bool canDodge = !spellInfo.HasAttribute(SpellAttr7.NoAttackDodge); + bool canParry = !spellInfo.HasAttribute(SpellAttr7.NoAttackParry); bool canBlock = spellInfo.HasAttribute(SpellAttr3.BlockableSpell); // if victim is casting or cc'd it can't avoid attacks