]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
SSD sleep take 2 (#34039)
authorlzk <124214523+lzk228@users.noreply.github.com>
Tue, 29 Apr 2025 05:24:33 +0000 (07:24 +0200)
committerGitHub <noreply@github.com>
Tue, 29 Apr 2025 05:24:33 +0000 (01:24 -0400)
* ssd sleep part 2

* forgot this

* apply review

* yeah

* add onmapinit

* cache cvar values

---------

Co-authored-by: EmoGarbage404 <retron404@gmail.com>
Content.Shared/CCVar/CCVars.Ic.cs
Content.Shared/SSDIndicator/SSDIndicatorComponent.cs
Content.Shared/SSDIndicator/SSDIndicatorSystem.cs

index e149e9f3e1edd234fc745a48fa8f1163e242823b..54ab69b3faa7417c581bffc80989f43053925a9b 100644 (file)
@@ -45,4 +45,17 @@ public sealed partial class CCVars
     /// </summary>
     public static readonly CVarDef<bool> ICShowSSDIndicator =
         CVarDef.Create("ic.show_ssd_indicator", true, CVar.CLIENTONLY);
+
+    /// <summary>
+    ///     Forces SSD characters to sleep after ICSSDSleepTime seconds
+    /// </summary>
+    public static readonly CVarDef<bool> ICSSDSleep =
+        CVarDef.Create("ic.ssd_sleep", true, CVar.SERVER);
+
+    /// <summary>
+    ///     Time between character getting SSD status and falling asleep
+    ///     Won't work without ICSSDSleep
+    /// </summary>
+    public static readonly CVarDef<float> ICSSDSleepTime =
+        CVarDef.Create("ic.ssd_sleep_time", 600f, CVar.SERVER);
 }
index 634dfc397b3a13eaf42c15f9ebdc078323fe19fd..47ac8afe720a68a979b8d85eed421e6e41b40df2 100644 (file)
@@ -1,4 +1,4 @@
-using Content.Shared.StatusIcon;
+using Content.Shared.StatusIcon;
 using Robust.Shared.GameStates;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -9,7 +9,7 @@ namespace Content.Shared.SSDIndicator;
 ///     Shows status icon when player in SSD
 /// </summary>
 [RegisterComponent, NetworkedComponent]
-[AutoGenerateComponentState]
+[AutoGenerateComponentState, AutoGenerateComponentPause]
 public sealed partial class SSDIndicatorComponent : Component
 {
     [ViewVariables(VVAccess.ReadWrite)]
@@ -19,4 +19,17 @@ public sealed partial class SSDIndicatorComponent : Component
     [ViewVariables(VVAccess.ReadWrite)]
     [DataField]
     public ProtoId<SsdIconPrototype> Icon = "SSDIcon";
+
+    /// <summary>
+    ///     When the entity should fall asleep
+    /// </summary>
+    [DataField, AutoPausedField, Access(typeof(SSDIndicatorSystem))]
+    public TimeSpan FallAsleepTime = TimeSpan.Zero;
+
+    /// <summary>
+    ///     Required to don't remove forced sleep from other sources
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [AutoNetworkedField]
+    public bool ForcedSleepAdded = false;
 }
index 7fc13d161e9c65e9da496665d2b9e6b3eab3d07e..dfba833bcf71cb25191696cfb8f68440b5027f42 100644 (file)
@@ -1,4 +1,8 @@
-using Robust.Shared.Player;
+using Content.Shared.Bed.Sleep;
+using Content.Shared.CCVar;
+using Robust.Shared.Configuration;
+using Robust.Shared.Player;
+using Robust.Shared.Timing;
 
 namespace Content.Shared.SSDIndicator;
 
@@ -7,21 +11,82 @@ namespace Content.Shared.SSDIndicator;
 /// </summary>
 public sealed class SSDIndicatorSystem : EntitySystem
 {
+    [Dependency] private readonly IConfigurationManager _cfg = default!;
+    [Dependency] private readonly IGameTiming _timing = default!;
+
+    private bool _icSsdSleep;
+    private float _icSsdSleepTime;
+
     public override void Initialize()
     {
         SubscribeLocalEvent<SSDIndicatorComponent, PlayerAttachedEvent>(OnPlayerAttached);
         SubscribeLocalEvent<SSDIndicatorComponent, PlayerDetachedEvent>(OnPlayerDetached);
+        SubscribeLocalEvent<SSDIndicatorComponent, MapInitEvent>(OnMapInit);
+
+        _cfg.OnValueChanged(CCVars.ICSSDSleep, obj => _icSsdSleep = obj, true);
+        _cfg.OnValueChanged(CCVars.ICSSDSleepTime, obj => _icSsdSleepTime = obj, true);
     }
 
     private void OnPlayerAttached(EntityUid uid, SSDIndicatorComponent component, PlayerAttachedEvent args)
     {
         component.IsSSD = false;
+
+        // Removes force sleep and resets the time to zero
+        if (_icSsdSleep)
+        {
+            component.FallAsleepTime = TimeSpan.Zero;
+            if (component.ForcedSleepAdded) // Remove component only if it has been added by this system
+            {
+                EntityManager.RemoveComponent<ForcedSleepingComponent>(uid);
+                component.ForcedSleepAdded = false;
+            }
+        }
         Dirty(uid, component);
     }
 
     private void OnPlayerDetached(EntityUid uid, SSDIndicatorComponent component, PlayerDetachedEvent args)
     {
         component.IsSSD = true;
+
+        // Sets the time when the entity should fall asleep
+        if (_icSsdSleep)
+        {
+            component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime);
+        }
         Dirty(uid, component);
     }
+
+    // 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);
+        }
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        if (!_icSsdSleep)
+            return;
+
+        var query = EntityQueryEnumerator<SSDIndicatorComponent>();
+
+        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) &&
+                !HasComp<ForcedSleepingComponent>(uid)) // Don't add the component if the entity has it from another sources
+            {
+                EnsureComp<ForcedSleepingComponent>(uid);
+                ssd.ForcedSleepAdded = true;
+            }
+        }
+    }
 }