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); } } }