From 4e25c74cdf327272514b7298d15f3d65a659b866 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Tue, 22 Apr 2025 17:52:09 -0700 Subject: [PATCH] fix: Fixes magical barrier NPE and an edge case (#2162) --- .../Mobiles/Abilities/MagicalBarrier.cs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Projects/UOContent/Mobiles/Abilities/MagicalBarrier.cs b/Projects/UOContent/Mobiles/Abilities/MagicalBarrier.cs index 585a7695b..2069448be 100644 --- a/Projects/UOContent/Mobiles/Abilities/MagicalBarrier.cs +++ b/Projects/UOContent/Mobiles/Abilities/MagicalBarrier.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace Server.Mobiles; @@ -7,7 +8,7 @@ public class MagicalBarrier : MonsterAbility { private HashSet _inactiveField; - public bool HasField(Mobile source) => !_inactiveField.Contains(source); + public bool HasField(Mobile source) => _inactiveField?.Contains(source) != true; public override MonsterAbilityType AbilityType => MonsterAbilityType.MagicalBarrier; @@ -17,17 +18,20 @@ public class MagicalBarrier : MonsterAbility public override TimeSpan MinTriggerCooldown => TimeSpan.FromSeconds(10.0); public override TimeSpan MaxTriggerCooldown => TimeSpan.FromSeconds(10.0); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool CanUseField(BaseCreature source) => source.Hits >= source.HitsMax * 9 / 10; + // Regeneration is subject to the cooldown, the rest are not. public override bool CanTrigger(BaseCreature source, MonsterAbilityTrigger trigger) => trigger != MonsterAbilityTrigger.Think || base.CanTrigger(source, trigger); public override void Trigger(MonsterAbilityTrigger trigger, BaseCreature source, Mobile target) { - if (trigger == MonsterAbilityTrigger.Think && !source.IsHurt()) + if (trigger == MonsterAbilityTrigger.Think) { - var fieldUp = _inactiveField?.Remove(source) == true; - if (fieldUp) + if (CanUseField(source) && _inactiveField?.Remove(source) == true) { + // Field going up! source.FixedParticles(0, 10, 0, 0x2530, EffectLayer.Waist); if (_inactiveField?.Count == 0) @@ -36,6 +40,15 @@ public class MagicalBarrier : MonsterAbility } } } + else if (trigger is MonsterAbilityTrigger.TakeSpellDamage && !CanUseField(source)) + { + _inactiveField ??= []; + if (_inactiveField.Add(source)) + { + // TODO: message and effect when field turns down; cannot be verified on OSI due to a bug + source.FixedParticles(0x3735, 1, 30, 0x251F, EffectLayer.Waist); + } + } base.Trigger(trigger, source, target); } @@ -53,22 +66,13 @@ public class MagicalBarrier : MonsterAbility public override void AlterSpellDamageFrom(BaseCreature source, Mobile target, ref int damage) { - var canUseField = source.Hits >= source.HitsMax * 9 / 10; - // If we cannot use the field, deactivate it. - var fieldActive = canUseField ? HasField(source) : _inactiveField.Add(source); - - if (!fieldActive) + if (!HasField(source)) { damage = 0; // no spell damage when the field is down // should there be an effect when spells nullifying is on? source.FixedParticles(0, 10, 0, 0x2522, EffectLayer.Waist); target.SendLocalizedMessage(1114359); // Your attack has no effect on the creature's armor. } - else if (!canUseField) - { - // TODO: message and effect when field turns down; cannot be verified on OSI due to a bug - source.FixedParticles(0x3735, 1, 30, 0x251F, EffectLayer.Waist); - } } public override void Move(BaseCreature source, Direction d)