From 1745faa28c018a94880471304b2a6d12f36f33a3 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sun, 4 Dec 2022 12:39:30 -0800 Subject: [PATCH] fix: Fixes divine fury (#1290) --- .../Skill Items/Ninjitsu/NinjaWeapons.cs | 10 +- .../UOContent/Items/Weapons/BaseWeapon.cs | 10 +- Projects/UOContent/Misc/BuffIcons.cs | 10 +- .../UOContent/Spells/Chivalry/DivineFury.cs | 172 ++++++++++++------ 4 files changed, 125 insertions(+), 77 deletions(-) diff --git a/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs b/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs index 15bf3da6a..d3ff3f60d 100644 --- a/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs +++ b/Projects/UOContent/Items/Skill Items/Ninjitsu/NinjaWeapons.cs @@ -217,10 +217,7 @@ namespace Server.Items double attackValue = AosAttributes.GetValue(attacker, AosAttribute.AttackChance); - if (DivineFurySpell.UnderEffect(attacker)) - { - attackValue += 10; - } + attackValue += DivineFurySpell.GetAttackBonus(attacker); if (AnimalForm.UnderTransformation(attacker, typeof(GreyWolf)) || AnimalForm.UnderTransformation(attacker, typeof(BakeKitsune))) @@ -242,10 +239,7 @@ namespace Server.Items double defenseValue = AosAttributes.GetValue(defender, AosAttribute.DefendChance); - if (DivineFurySpell.UnderEffect(defender)) - { - defenseValue -= 20; - } + defenseValue -= DivineFurySpell.GetDefendMalus(defender); if (HitLower.IsUnderDefenseEffect(defender)) { diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs index 4faff66f0..af6e134e3 100644 --- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs +++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs @@ -1244,10 +1244,7 @@ namespace Server.Items */ var bonus = AosAttributes.GetValue(m, AosAttribute.WeaponSpeed); - if (DivineFurySpell.UnderEffect(m)) - { - bonus += 10; - } + bonus += DivineFurySpell.GetWeaponSpeed(m); // Bonus granted by successful use of Honorable Execution. bonus += HonorableExecution.GetSwingBonus(m); @@ -2430,10 +2427,7 @@ namespace Server.Items } // Divine Fury gives a +10% bonus to damage. - if (DivineFurySpell.UnderEffect(attacker)) - { - damageBonus += 10; - } + damageBonus += DivineFurySpell.GetDamageBonus(attacker); var defenseMasteryMalus = 0; diff --git a/Projects/UOContent/Misc/BuffIcons.cs b/Projects/UOContent/Misc/BuffIcons.cs index 28813c35e..e639ae3cd 100644 --- a/Projects/UOContent/Misc/BuffIcons.cs +++ b/Projects/UOContent/Misc/BuffIcons.cs @@ -70,23 +70,19 @@ namespace Server public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m, TextDefinition args - ) - : this(iconID, titleCliloc, secondaryCliloc, length, m) => - Args = args; + ) : this(iconID, titleCliloc, secondaryCliloc, length, m) => Args = args; public BuffInfo( BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m, TextDefinition args, bool retainThroughDeath - ) - : this(iconID, titleCliloc, titleCliloc + 1, length, m, args, retainThroughDeath) + ) : this(iconID, titleCliloc, titleCliloc + 1, length, m, args, retainThroughDeath) { } public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m, TextDefinition args, bool retainThroughDeath - ) - : this(iconID, titleCliloc, secondaryCliloc, length, m) + ) : this(iconID, titleCliloc, secondaryCliloc, length, m) { Args = args; RetainThroughDeath = retainThroughDeath; diff --git a/Projects/UOContent/Spells/Chivalry/DivineFury.cs b/Projects/UOContent/Spells/Chivalry/DivineFury.cs index 6716c7d66..1fd76cf14 100644 --- a/Projects/UOContent/Spells/Chivalry/DivineFury.cs +++ b/Projects/UOContent/Spells/Chivalry/DivineFury.cs @@ -1,79 +1,143 @@ using System; using System.Collections.Generic; -namespace Server.Spells.Chivalry +namespace Server.Spells.Chivalry; + +public class DivineFurySpell : PaladinSpell { - public class DivineFurySpell : PaladinSpell + private static readonly SpellInfo _info = new( + "Divine Fury", + "Divinum Furis", + -1, + 9002 + ); + + private static readonly Dictionary _table = new(); + + public DivineFurySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) { - private static readonly SpellInfo _info = new( - "Divine Fury", - "Divinum Furis", - -1, - 9002 - ); + } - private static readonly Dictionary _table = new(); + public override TimeSpan CastDelayBase => TimeSpan.FromSeconds(1.0); - public DivineFurySpell(Mobile caster, Item scroll = null) : base(caster, scroll, _info) + public override double RequiredSkill => 25.0; + public override int RequiredMana => 15; + public override int RequiredTithing => 10; + public override int MantraNumber => 1060722; // Divinum Furis + public override bool BlocksMovement => false; + + public override void OnCast() + { + if (CheckSequence()) { - } + Caster.PlaySound(0x20F); + Caster.PlaySound(Caster.Female ? 0x338 : 0x44A); + Caster.FixedParticles(0x376A, 1, 31, 9961, 1160, 0, EffectLayer.Waist); + Caster.FixedParticles(0x37C4, 1, 31, 9502, 43, 2, EffectLayer.Waist); - public override TimeSpan CastDelayBase => TimeSpan.FromSeconds(1.0); + Caster.Stam = Caster.StamMax; - public override double RequiredSkill => 25.0; - public override int RequiredMana => 15; - public override int RequiredTithing => 10; - public override int MantraNumber => 1060722; // Divinum Furis - public override bool BlocksMovement => false; + RemoveTimer(Caster); - public override void OnCast() - { - if (CheckSequence()) + var delay = TimeSpan.FromSeconds(Math.Clamp(ComputePowerValue(10), 7, 24)); + + var timer = Core.HS && Caster.Skills.Chivalry.Value >= 120 && Caster.Karma >= 10000 + ? new InternalTimer(Caster, delay, 15, 20, 15, 10) + : new InternalTimer(Caster, delay, 10, 10, 10, 20); + timer.Start(); + + _table[Caster] = timer; + + Caster.Delta(MobileDelta.WeaponDamage); + + if (Core.HS) // Publish 71 with boost { - Caster.PlaySound(0x20F); - Caster.PlaySound(Caster.Female ? 0x338 : 0x44A); - Caster.FixedParticles(0x376A, 1, 31, 9961, 1160, 0, EffectLayer.Waist); - Caster.FixedParticles(0x37C4, 1, 31, 9502, 43, 2, EffectLayer.Waist); - - Caster.Stam = Caster.StamMax; - - RemoveTimer(Caster); - - var delay = Math.Clamp(ComputePowerValue(10), 7, 24); - - Timer.StartTimer(TimeSpan.FromSeconds(delay), - () => { StopDivineFury(Caster); }, - out var timerToken - ); - - _table[Caster] = timerToken; - - Caster.Delta(MobileDelta.WeaponDamage); - BuffInfo.AddBuff( Caster, - new BuffInfo(BuffIcon.DivineFury, 1060589, 1075634, TimeSpan.FromSeconds(delay), Caster) + new BuffInfo( + BuffIcon.DivineFury, + 1060589, + 1150218, + delay, + Caster, + $"{timer.AttackBonus}\t{timer.DamageBonus}\t{timer.WeaponSpeed}\t{timer.DefendMalus}" + ) ); } - - FinishSequence(); - } - - private static void RemoveTimer(Mobile m) - { - if (_table.Remove(m, out var timerToken)) + else { - timerToken.Cancel(); + BuffInfo.AddBuff( + Caster, + new BuffInfo(BuffIcon.DivineFury, 1060589, 1075634, delay, Caster) + ); } } - public static void StopDivineFury(Mobile m) + FinishSequence(); + } + + public static int GetAttackBonus(Mobile m) => _table.TryGetValue(m, out var timer) ? timer.AttackBonus : 0; + + public static int GetDamageBonus(Mobile m) => _table.TryGetValue(m, out var timer) ? timer.DamageBonus : 0; + + public static int GetWeaponSpeed(Mobile m) => _table.TryGetValue(m, out var timer) ? timer.WeaponSpeed : 0; + + public static int GetDefendMalus(Mobile m) => _table.TryGetValue(m, out var timer) ? timer.DefendMalus : 0; + + public static void GetBonuses( + Mobile m, out int attackBonus, out int damageBonus, out int weaponSpeed, out int defendMalus + ) + { + if (_table.TryGetValue(m, out var timer)) { - RemoveTimer(m); - m.Delta(MobileDelta.WeaponDamage); - m.PlaySound(0xF8); + damageBonus = timer.DamageBonus; + weaponSpeed = timer.WeaponSpeed; + attackBonus = timer.AttackBonus; + defendMalus = timer.DefendMalus; + return; } - public static bool UnderEffect(Mobile m) => _table.ContainsKey(m); + damageBonus = 0; + weaponSpeed = 0; + attackBonus = 0; + defendMalus = 0; + } + + private static void RemoveTimer(Mobile m) + { + if (_table.Remove(m, out var timer)) + { + timer.Stop(); + } + } + + public static void StopDivineFury(Mobile m) + { + RemoveTimer(m); + m.Delta(MobileDelta.WeaponDamage); + m.PlaySound(0xF8); + } + + public static bool UnderEffect(Mobile m) => _table.ContainsKey(m); + + private class InternalTimer : Timer + { + private Mobile _mobile; + public int DamageBonus { get; } + public int WeaponSpeed { get; } + public int AttackBonus { get; } + public int DefendMalus { get; } + + public InternalTimer(Mobile m, TimeSpan delay, int attackBonus, int damageBonus, int weaponSpeed, int defendMalus) + : base(delay) + { + DamageBonus = damageBonus; + WeaponSpeed = weaponSpeed; + AttackBonus = attackBonus; + DefendMalus = defendMalus; + _mobile = m; + } + + protected override void OnTick() => StopDivineFury(_mobile); } }