fix: Fixes timer index offset (#1907)

### Summary

- Fixes timer intervals not continuing
- Fixes `Timer.Index` being off by 1. Should start at 0 for the first OnTick
- Simplifies Gift of Renewal end check
- Fixes force of nature not applying at the proper time and simplifies the timer logic.
This commit is contained in:
Kamron Batman 2024-08-06 15:46:40 -07:00 committed by GitHub
parent 2c9b3ef112
commit 28860b7f53
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 47 deletions

View file

@ -134,13 +134,11 @@ public partial class Timer
private static void Execute(Timer timer)
{
var finished = timer.Count != 0 && ++timer.Index >= timer.Count;
var finished = timer.Count != 0 && timer.Index + 1 >= timer.Count;
var prof = timer.GetProfile();
prof?.Start();
var version = timer.Version;
// Stop the timer from running so that way if Start() is called in OnTick, the timer will be started.
if (finished)
{
@ -148,25 +146,30 @@ public partial class Timer
timer.Version++;
}
var version = timer.Version;
timer.OnTick();
prof?.Finish();
// If the timer has been altered (restarted, returned etc) then bail
if (timer.Version != version)
// Starting doesn't change the timer version, so we need to check if it's finished and if it's still running.
if (timer.Version != version || finished && timer.Running)
{
return;
}
if (finished)
if (!finished)
{
timer.Delay = timer.Interval;
timer.Next = DateTime.UtcNow + timer.Interval;
AddTimer(timer, (long)timer.Delay.TotalMilliseconds);
}
else
{
// Already stopped and detached, now run OnDetach
timer.OnDetach();
return;
}
timer.Delay = timer.Interval;
timer.Next = DateTime.UtcNow + timer.Interval;
AddTimer(timer, (long)timer.Delay.TotalMilliseconds);
timer.Index++;
}
private static void AddTimer(Timer timer, long delay)

View file

@ -70,7 +70,6 @@ public partial class Timer
public TimeSpan Interval { get; set; }
public int Index { get; private set; }
public int Count { get; private set; }
public int RemainingCount => Count - Index;
public bool Running { get; private set; }
public TimerProfile GetProfile() => !Core.Profiling ? null : TimerProfile.Acquire(ToString() ?? "null");

View file

@ -16,6 +16,8 @@ public class ForceOfNature : WeaponAbility
ClearCurrentAbility(attacker);
Remove(attacker);
attacker.SendLocalizedMessage(1074374); // You attack your enemy with the force of nature!
defender.SendLocalizedMessage(1074375); // You are assaulted with great force!
@ -23,15 +25,18 @@ public class ForceOfNature : WeaponAbility
defender.FixedParticles(0x36CB, 1, 9, 9911, 67, 5, EffectLayer.Head);
defender.FixedParticles(0x374A, 1, 17, 9502, 1108, 4, (EffectLayer)255);
Remove(attacker);
if (Core.SA)
{
AOS.Damage(defender, attacker, Utility.Random(15, 20), false, 0, 0, 0, 0, 0, 0, 100);
}
ForceOfNatureTimer t = new ForceOfNatureTimer(attacker, defender);
var t = new ForceOfNatureTimer(attacker, defender);
t.Start();
_table[attacker] = t;
}
private static readonly Dictionary<Mobile, ForceOfNatureTimer> _table = new();
private static readonly Dictionary<Mobile, ForceOfNatureTimer> _table = [];
public static void Remove(Mobile m)
{
@ -91,18 +96,18 @@ public class ForceOfNature : WeaponAbility
public static double GetDamageScalar(Mobile from, Mobile target)
{
if (_table.TryGetValue(from, out var t) && t.Target == target)
if (!_table.TryGetValue(from, out var t) || t.Target != target)
{
if (Core.SA)
{
var bonus = Math.Min(100, Math.Max(50, from.Str - 50));
return (100.0 + bonus) / 100.0;
}
return 1.65;
return 1.0;
}
return 1.0;
if (Core.SA)
{
var bonus = Math.Min(100, Math.Max(50, from.Str - 50));
return (100.0 + bonus) / 100.0;
}
return 1.65;
}
private class ForceOfNatureTimer : Timer
@ -113,11 +118,7 @@ public class ForceOfNature : WeaponAbility
public DateTime LastHit { get; set; }
public ForceOfNatureTimer(Mobile from, Mobile target)
: base(
Core.SA ? TimeSpan.FromSeconds(1) : TimeSpan.FromSeconds(10),
Core.SA ? TimeSpan.FromSeconds(1) : TimeSpan.Zero,
Core.SA ? 36 : 1
)
: base(TimeSpan.FromSeconds(Core.SA ? 10 : 360))
{
Target = target;
From = from;
@ -127,26 +128,10 @@ public class ForceOfNature : WeaponAbility
protected override void OnTick()
{
if (!From.Alive || !Target.Alive || Target.Map != From.Map || Target.GetDistanceToSqrt(From.Location) > 10)
if (!Core.SA || !From.Alive || !Target.Alive || Target.Map != From.Map ||
Target.GetDistanceToSqrt(From.Location) > 10 || LastHit + TimeSpan.FromSeconds(20) < Core.Now)
{
Remove(From);
return;
}
if (Core.SA)
{
if (LastHit + TimeSpan.FromSeconds(20) < Core.Now)
{
Remove(From);
return;
}
if (Index == 1)
{
int damage = Utility.Random(15, 20);
AOS.Damage(Target, From, damage, false, 0, 0, 0, 0, 0, 0, 100);
}
}
}
}

View file

@ -102,7 +102,8 @@ namespace Server.Spells.Spellweaving
protected override void OnTick()
{
if (Index + 1 == Count)
// Last tick will change running to false
if (!Running)
{
StopEffect(_mobile);
_mobile.PlaySound(0x455);