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:
parent
2c9b3ef112
commit
28860b7f53
4 changed files with 35 additions and 47 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue