From 86e03cee1b3cfc6febba5dfc4c0939a857c252ef Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sat, 1 Oct 2022 17:10:57 -0400 Subject: [PATCH] Core/Spells: fixed up block mechanics Port From (https://github.com/TrinityCore/TrinityCore/commit/9f084718277b01936435c66696084fc049f8f8cf) --- Source/Game/Entities/Unit/Unit.Spells.cs | 38 ++---------------------- Source/Game/Spells/Spell.cs | 8 ++--- 2 files changed, 7 insertions(+), 39 deletions(-) diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index bff1daba3..95c973c8a 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -766,7 +766,7 @@ namespace Game.Entities bool canDodge = !spellInfo.HasAttribute(SpellAttr7.NoAttackDodge); bool canParry = !spellInfo.HasAttribute(SpellAttr7.NoAttackParry); - bool canBlock = spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked); + bool canBlock = true; // if victim is casting or cc'd it can't avoid attacks if (victim.IsNonMeleeSpellCast(false, false, true) || victim.HasUnitState(UnitState.Controlled)) @@ -776,7 +776,7 @@ namespace Game.Entities canBlock = false; } - // Ranged attacks can only miss, resist and deflect + // Ranged attacks can only miss, resist and deflect and get blocked if (attType == WeaponAttackType.RangedAttack) { canParry = false; @@ -790,7 +790,6 @@ namespace Game.Entities if (roll < tmp) return SpellMissInfo.Deflect; } - return SpellMissInfo.None; } // Check for attack from behind @@ -1800,25 +1799,6 @@ namespace Game.Entities return (uint)crit_bonus; } - bool IsSpellBlocked(Unit victim, SpellInfo spellProto, WeaponAttackType attackType = WeaponAttackType.BaseAttack) - { - // These spells can't be blocked - if (spellProto != null && (spellProto.HasAttribute(SpellAttr0.NoActiveDefense) || spellProto.HasAttribute(SpellAttr3.AlwaysHit))) - return false; - - // Can't block when casting/controlled - if (victim.IsNonMeleeSpellCast(false) || victim.HasUnitState(UnitState.Controlled)) - return false; - - if (victim.HasAuraType(AuraType.IgnoreHitDirection) || victim.HasInArc(MathFunctions.PI, this)) - { - float blockChance = GetUnitBlockChance(attackType, victim); - if (blockChance != 0 && RandomHelper.randChance(blockChance)) - return true; - } - return false; - } - public void _DeleteRemovedAuras() { while (!m_removedAuras.Empty()) @@ -1974,7 +1954,7 @@ namespace Game.Entities } } - public void CalculateSpellDamageTaken(SpellNonMeleeDamage damageInfo, int damage, SpellInfo spellInfo, WeaponAttackType attackType = WeaponAttackType.BaseAttack, bool crit = false, Spell spell = null) + public void CalculateSpellDamageTaken(SpellNonMeleeDamage damageInfo, int damage, SpellInfo spellInfo, WeaponAttackType attackType = WeaponAttackType.BaseAttack, bool crit = false, bool blocked = false, Spell spell = null) { if (damage < 0) return; @@ -1991,7 +1971,6 @@ namespace Game.Entities if (IsDamageReducedByArmor(damageSchoolMask, spellInfo)) damage = (int)CalcArmorReducedDamage(damageInfo.attacker, victim, (uint)damage, spellInfo, attackType); - bool blocked = false; // Per-school calc switch (spellInfo.DmgClass) { @@ -1999,17 +1978,6 @@ namespace Game.Entities case SpellDmgClass.Ranged: case SpellDmgClass.Melee: { - // Physical Damage - if (damageSchoolMask.HasAnyFlag(SpellSchoolMask.Normal)) - { - // Spells with this attribute were already calculated in MeleeSpellHitResult - if (!spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked)) - { - // Get blocked status - blocked = IsSpellBlocked(victim, spellInfo, attackType); - } - } - if (crit) { damageInfo.HitInfo |= HitInfo.CriticalHit; diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index bd280358b..fe4b884f0 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -3920,7 +3920,7 @@ namespace Game.Spells // possibly SPELL_MISS_IMMUNE2 for this?? targetInfo.MissCondition = SpellMissInfo.Immune2; - if (targetInfo.MissCondition == SpellMissInfo.None) // hits + if (targetInfo.MissCondition == SpellMissInfo.None || (targetInfo.MissCondition == SpellMissInfo.Block && !m_spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked))) // Add only hits and partial blocked { data.HitTargets.Add(targetInfo.TargetGUID); data.HitStatus.Add(new SpellHitStatus(SpellMissInfo.None)); @@ -7238,7 +7238,7 @@ namespace Game.Spells { Unit unit = null; // In case spell hit target, do all effect on that target - if (targetInfo.MissCondition == SpellMissInfo.None) + if (targetInfo.MissCondition == SpellMissInfo.None || (targetInfo.MissCondition == SpellMissInfo.Block && !m_spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked))) unit = m_caster.GetGUID() == targetInfo.TargetGUID ? m_caster.ToUnit() : Global.ObjAccessor.GetUnit(m_caster, targetInfo.TargetGUID); // In case spell reflect from target, do all effect on caster (if hit) else if (targetInfo.MissCondition == SpellMissInfo.Reflect && targetInfo.ReflectResult == SpellMissInfo.None) @@ -8280,7 +8280,7 @@ namespace Game.Spells spell.m_healing = Healing; _spellHitTarget = null; - if (MissCondition == SpellMissInfo.None) + if (MissCondition == SpellMissInfo.None || (MissCondition == SpellMissInfo.Block && !spell.GetSpellInfo().HasAttribute(SpellAttr3.CompletelyBlocked))) _spellHitTarget = unit; else if (MissCondition == SpellMissInfo.Reflect && ReflectResult == SpellMissInfo.None) _spellHitTarget = spell.GetCaster().ToUnit(); @@ -8485,7 +8485,7 @@ namespace Game.Spells caster.SetLastDamagedTargetGuid(spell.unitTarget.GetGUID()); // Add bonuses and fill damageInfo struct - caster.CalculateSpellDamageTaken(damageInfo, spell.m_damage, spell.m_spellInfo, spell.m_attackType, IsCrit); + caster.CalculateSpellDamageTaken(damageInfo, spell.m_damage, spell.m_spellInfo, spell.m_attackType, IsCrit, MissCondition == SpellMissInfo.Block, spell); Unit.DealDamageMods(damageInfo.attacker, damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb); hitMask |= Unit.CreateProcHitMask(damageInfo, MissCondition);