]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Convert `TimedSpawnerComponent` to use an Update loop (#37785)
authorTayrtahn <tayrtahn@gmail.com>
Sat, 24 May 2025 17:35:17 +0000 (13:35 -0400)
committerGitHub <noreply@github.com>
Sat, 24 May 2025 17:35:17 +0000 (19:35 +0200)
Convert TimedSpawnerComponent to use an Update loop

Content.Server/Spawners/Components/TimedSpawnerComponent.cs
Content.Server/Spawners/EntitySystems/SpawnerSystem.cs

index 828e5417177e69b26eb76d2887ac40bf8fb89602..8494a1a2fbececa2da55f443e57b4ef4e94d3d1a 100644 (file)
@@ -1,6 +1,6 @@
-using System.Threading;
-using Robust.Shared.Prototypes;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
 
 namespace Content.Server.Spawners.Components;
 
@@ -10,6 +10,7 @@ namespace Content.Server.Spawners.Components;
 /// and min/max number of entities to spawn.
 /// </summary>
 [RegisterComponent, EntityCategory("Spawner")]
+[AutoGenerateComponentPause]
 public sealed partial class TimedSpawnerComponent : Component, ISerializationHooks
 {
     /// <summary>
@@ -30,7 +31,7 @@ public sealed partial class TimedSpawnerComponent : Component, ISerializationHoo
     /// Length of the interval between spawn attempts.
     /// </summary>
     [DataField]
-    public int IntervalSeconds = 60;
+    public TimeSpan IntervalSeconds = TimeSpan.FromSeconds(60);
 
     /// <summary>
     /// The minimum number of entities that can be spawned when an interval elapses.
@@ -44,7 +45,11 @@ public sealed partial class TimedSpawnerComponent : Component, ISerializationHoo
     [DataField]
     public int MaximumEntitiesSpawned = 1;
 
-    public CancellationTokenSource? TokenSource;
+    /// <summary>
+    /// The time at which the current interval will have elapsed and entities may be spawned.
+    /// </summary>
+    [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
+    public TimeSpan NextFire = TimeSpan.Zero;
 
     void ISerializationHooks.AfterDeserialization()
     {
index c601fdd2875d90e984e1f978517e1aefc24f2e01..6e0b0f384d0a8093b55147b1b0cdb1984a905487 100644 (file)
@@ -1,25 +1,41 @@
-using System.Threading;
 using Content.Server.Spawners.Components;
 using Robust.Shared.Random;
+using Robust.Shared.Timing;
 
 namespace Content.Server.Spawners.EntitySystems;
 
 public sealed class SpawnerSystem : EntitySystem
 {
+    [Dependency] private readonly IGameTiming _timing = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
 
     public override void Initialize()
     {
         base.Initialize();
-        SubscribeLocalEvent<TimedSpawnerComponent, ComponentInit>(OnSpawnerInit);
-        SubscribeLocalEvent<TimedSpawnerComponent, ComponentShutdown>(OnTimedSpawnerShutdown);
+
+        SubscribeLocalEvent<TimedSpawnerComponent, MapInitEvent>(OnMapInit);
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        var curTime = _timing.CurTime;
+        var query = EntityQueryEnumerator<TimedSpawnerComponent>();
+        while (query.MoveNext(out var uid, out var timedSpawner))
+        {
+            if (timedSpawner.NextFire > curTime)
+                continue;
+
+            OnTimerFired(uid, timedSpawner);
+
+            timedSpawner.NextFire += timedSpawner.IntervalSeconds;
+        }
     }
 
-    private void OnSpawnerInit(EntityUid uid, TimedSpawnerComponent component, ComponentInit args)
+    private void OnMapInit(Entity<TimedSpawnerComponent> ent, ref MapInitEvent args)
     {
-        component.TokenSource?.Cancel();
-        component.TokenSource = new CancellationTokenSource();
-        uid.SpawnRepeatingTimer(TimeSpan.FromSeconds(component.IntervalSeconds), () => OnTimerFired(uid, component), component.TokenSource.Token);
+        ent.Comp.NextFire = _timing.CurTime + ent.Comp.IntervalSeconds;
     }
 
     private void OnTimerFired(EntityUid uid, TimedSpawnerComponent component)
@@ -36,9 +52,4 @@ public sealed class SpawnerSystem : EntitySystem
             SpawnAtPosition(entity, coordinates);
         }
     }
-
-    private void OnTimedSpawnerShutdown(EntityUid uid, TimedSpawnerComponent component, ComponentShutdown args)
-    {
-        component.TokenSource?.Cancel();
-    }
 }