diff --git a/Projects/UOContent/Items/Weapons/Abilities/Feint.cs b/Projects/UOContent/Items/Weapons/Abilities/Feint.cs
index dfdf2d2f5..d50532787 100644
--- a/Projects/UOContent/Items/Weapons/Abilities/Feint.cs
+++ b/Projects/UOContent/Items/Weapons/Abilities/Feint.cs
@@ -1,65 +1,78 @@
using System;
using System.Collections.Generic;
-namespace Server.Items
+namespace Server.Items;
+
+///
+/// Gain a defensive advantage over your primary opponent for a short time.
+///
+public class Feint : WeaponAbility
{
- ///
- /// Gain a defensive advantage over your primary opponent for a short time.
- ///
- public class Feint : WeaponAbility
+ public static Dictionary Registry { get; } = new();
+
+ public override int BaseMana => 30;
+ public override bool RequiresSecondarySkill(Mobile from) => true;
+
+ public override void OnHit(Mobile attacker, Mobile defender, int damage, WorldLocation worldLocation)
{
- public static Dictionary Registry { get; } = new();
-
- public override int BaseMana => 30;
- public override bool RequiresSecondarySkill(Mobile from) => true;
-
- public override void OnHit(Mobile attacker, Mobile defender, int damage, WorldLocation worldLocation)
+ if (!Validate(attacker) || !CheckMana(attacker, true))
{
- if (!Validate(attacker) || !CheckMana(attacker, true))
- {
- return;
- }
-
- if (Registry.TryGetValue(defender, out var timer))
- {
- timer.Stop();
- Registry.Remove(defender);
- }
-
- ClearCurrentAbility(attacker);
-
- attacker.SendLocalizedMessage(1063360); // You baffle your target with a feint!
- defender.SendLocalizedMessage(1063361); // You were deceived by an attacker's feint!
-
- attacker.FixedParticles(0x3728, 1, 13, 0x7F3, 0x962, 0, EffectLayer.Waist);
-
- timer = new FeintTimer(
- defender,
- (int)(20.0 + 3.0 *
- (Math.Max(attacker.Skills.Ninjitsu.Value, attacker.Skills.Bushido.Value) - 50.0) / 7.0)
- ); // 20-50 % decrease
-
- timer.Start();
- Registry.Add(defender, timer);
+ return;
}
- public class FeintTimer : Timer
+ if (Registry.Remove(defender, out var timer))
{
- private readonly Mobile m_Defender;
-
- public FeintTimer(Mobile defender, int swingSpeedReduction)
- : base(TimeSpan.FromSeconds(6.0))
- {
- m_Defender = defender;
- SwingSpeedReduction = swingSpeedReduction;
- }
-
- public int SwingSpeedReduction { get; }
-
- protected override void OnTick()
- {
- Registry.Remove(m_Defender);
- }
+ timer.Stop();
}
+
+ ClearCurrentAbility(attacker);
+
+ attacker.SendLocalizedMessage(1063360); // You baffle your target with a feint!
+ defender.SendLocalizedMessage(1063361); // You were deceived by an attacker's feint!
+
+ attacker.FixedParticles(0x3728, 1, 13, 0x7F3, 0x962, 0, EffectLayer.Waist);
+
+ var skill = Math.Max(attacker.Skills.Ninjitsu.Value, attacker.Skills.Bushido.Value);
+
+ // 20-50 % decrease in damage taken for 6 seconds
+ timer = new FeintTimer(
+ attacker,
+ defender,
+ (int)(20.0 + 3.0 * (skill - 50.0) / 7.0)
+ );
+
+ timer.Start();
+ Registry.Add(defender, timer);
+
+ // TODO: Add buff icon (Publish 100)
+ }
+
+ public static bool GetDamageReduction(Mobile attacker, Mobile defender, out int damageReduction)
+ {
+ if (Registry.TryGetValue(attacker, out var timer) && timer.Defender == defender)
+ {
+ damageReduction = timer.DamageReduction;
+ return true;
+ }
+
+ damageReduction = 0;
+ return false;
+ }
+
+ public class FeintTimer : Timer
+ {
+ private readonly Mobile _attacker;
+ public Mobile Defender { get; }
+
+ public FeintTimer(Mobile attacker, Mobile defender, int damageReduction) : base(TimeSpan.FromSeconds(6.0))
+ {
+ _attacker = attacker;
+ Defender = defender;
+ DamageReduction = damageReduction;
+ }
+
+ public int DamageReduction { get; }
+
+ protected override void OnTick() => Registry.Remove(_attacker);
}
}
diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs
index 3c5bc16b7..13232f808 100644
--- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs
+++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs
@@ -1385,11 +1385,6 @@ public abstract partial class BaseWeapon : Item, IWeapon, IFactionItem, ICraftab
bonus += duelWield.BonusSwingSpeed;
}
- if (Feint.Registry.TryGetValue(m, out var feint))
- {
- bonus -= feint.SwingSpeedReduction;
- }
-
var context = TransformationSpellHelper.GetContext(m);
if (context?.Spell is ReaperFormSpell spell)
@@ -1985,6 +1980,12 @@ public abstract partial class BaseWeapon : Item, IWeapon, IFactionItem, ICraftab
move = null;
}
+ if (Feint.GetDamageReduction(attacker, defender, out var feintReduction))
+ {
+ // example: 35 damage * 50 / 100 = 17 damage
+ damage -= damage * feintReduction / 100;
+ }
+
var ignoreArmor = a is ArmorIgnore ||
move?.IgnoreArmor(attacker) == true ||
Bladeweave.BladeWeaving(attacker, out var bladeweavingAbi) &&
diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs
index 16bf662b2..09a6e452e 100644
--- a/Projects/UOContent/Spells/Base/SpellHelper.cs
+++ b/Projects/UOContent/Spells/Base/SpellHelper.cs
@@ -1013,6 +1013,12 @@ namespace Server.Spells
bcTarget?.AlterSpellDamageFrom(from, ref dmg);
+ if (Feint.GetDamageReduction(from, target, out int feintReduction))
+ {
+ // example: 35 damage * 50 / 100 = 17 damage
+ dmg -= dmg * feintReduction / 100;
+ }
+
StaminaSystem.DFA = dfa;
var damageGiven = AOS.Damage(target, from, dmg, phys, fire, cold, pois, nrgy, chaos);