diff --git a/Content.Shared/SSDIndicator/SSDIndicatorComponent.cs b/Content.Shared/SSDIndicator/SSDIndicatorComponent.cs
index 9547b6ce4e..6bfb3fdfd6 100644
--- a/Content.Shared/SSDIndicator/SSDIndicatorComponent.cs
+++ b/Content.Shared/SSDIndicator/SSDIndicatorComponent.cs
@@ -1,29 +1,49 @@
+using Content.Shared.CCVar;
using Content.Shared.StatusIcon;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.SSDIndicator;
///
-/// Shows status icon when player in SSD
+/// Shows status icon when an entity is SSD, based on if a player is attached or not.
///
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState, AutoGenerateComponentPause]
public sealed partial class SSDIndicatorComponent : Component
{
- [DataField, ViewVariables(VVAccess.ReadOnly)]
+ ///
+ /// Whether or not the entity is SSD.
+ ///
[AutoNetworkedField]
+ [DataField, ViewVariables(VVAccess.ReadOnly)]
public bool IsSSD = true;
+ ///
+ /// The icon displayed next to the associated entity when it is SSD.
+ ///
[DataField]
public ProtoId Icon = "SSDIcon";
///
- /// When the entity should fall asleep
+ /// The time at which the entity will fall asleep, if is true.
///
- [DataField]
[AutoNetworkedField, AutoPausedField]
[Access(typeof(SSDIndicatorSystem))]
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan FallAsleepTime = TimeSpan.Zero;
+
+ ///
+ /// The next time this component will be updated.
+ ///
+ [AutoNetworkedField, AutoPausedField]
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
+ public TimeSpan NextUpdate = TimeSpan.Zero;
+
+ ///
+ /// The time between updates checking if the entity should be force slept.
+ ///
+ [DataField]
+ public TimeSpan UpdateInterval = TimeSpan.FromSeconds(1);
}
diff --git a/Content.Shared/SSDIndicator/SSDIndicatorSystem.cs b/Content.Shared/SSDIndicator/SSDIndicatorSystem.cs
index b9c6659c9c..14d71d90d9 100644
--- a/Content.Shared/SSDIndicator/SSDIndicatorSystem.cs
+++ b/Content.Shared/SSDIndicator/SSDIndicatorSystem.cs
@@ -61,12 +61,12 @@ public sealed class SSDIndicatorSystem : EntitySystem
// Prevents mapped mobs to go to sleep immediately
private void OnMapInit(EntityUid uid, SSDIndicatorComponent component, MapInitEvent args)
{
- if (_icSsdSleep &&
- component.IsSSD &&
- component.FallAsleepTime == TimeSpan.Zero)
- {
- component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime);
- }
+ if (!_icSsdSleep || !component.IsSSD)
+ return;
+
+ component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime);
+ component.NextUpdate = _timing.CurTime + component.UpdateInterval;
+ Dirty(uid, component);
}
public override void Update(float frameTime)
@@ -76,17 +76,21 @@ public sealed class SSDIndicatorSystem : EntitySystem
if (!_icSsdSleep)
return;
+ var curTime = _timing.CurTime;
var query = EntityQueryEnumerator();
while (query.MoveNext(out var uid, out var ssd))
{
// Forces the entity to sleep when the time has come
- if (ssd.IsSSD &&
- ssd.FallAsleepTime <= _timing.CurTime &&
- !TerminatingOrDeleted(uid))
- {
- _statusEffects.TrySetStatusEffectDuration(uid, StatusEffectSSDSleeping, null);
- }
+ if (!ssd.IsSSD
+ || ssd.NextUpdate > curTime
+ || ssd.FallAsleepTime > curTime
+ || TerminatingOrDeleted(uid))
+ continue;
+
+ _statusEffects.TryUpdateStatusEffectDuration(uid, StatusEffectSSDSleeping);
+ ssd.NextUpdate += ssd.UpdateInterval;
+ Dirty(uid, ssd);
}
}
}