]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Change suit sensors on other players (#29668)
authorBombasterDS <115770678+BombasterDS@users.noreply.github.com>
Sun, 11 Aug 2024 09:04:42 +0000 (19:04 +1000)
committerGitHub <noreply@github.com>
Sun, 11 Aug 2024 09:04:42 +0000 (19:04 +1000)
* Suit sensors can be turned off on other players

* less doafter time + interaction (nostate) check

* code cleanup

* code cleanup 2

Content.Server/Medical/SuitSensors/SuitSensorComponent.cs
Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs

index 9079655c80c15add2ed9a7dc0a628ccaf1aba5b8..91039712e578343174111a6f1ad1761fac0dff7f 100644 (file)
@@ -14,37 +14,43 @@ public sealed partial class SuitSensorComponent : Component
     /// <summary>
     ///     Choose a random sensor mode when item is spawned.
     /// </summary>
-    [DataField("randomMode")]
+    [DataField]
     public bool RandomMode = true;
 
     /// <summary>
     ///     If true user can't change suit sensor mode
     /// </summary>
-    [DataField("controlsLocked")]
+    [DataField]
     public bool ControlsLocked = false;
 
+    /// <summary>
+    ///  How much time it takes to change another player's sensors
+    /// </summary>
+    [DataField]
+    public float SensorsTime = 1.75f;
+
     /// <summary>
     ///     Current sensor mode. Can be switched by user verbs.
     /// </summary>
-    [DataField("mode")]
+    [DataField]
     public SuitSensorMode Mode = SuitSensorMode.SensorOff;
 
     /// <summary>
     ///     Activate sensor if user wear it in this slot.
     /// </summary>
-    [DataField("activationSlot")]
+    [DataField]
     public string ActivationSlot = "jumpsuit";
 
     /// <summary>
     /// Activate sensor if user has this in a sensor-compatible container.
     /// </summary>
-    [DataField("activationContainer")]
+    [DataField]
     public string? ActivationContainer;
 
     /// <summary>
     ///     How often does sensor update its owners status (in seconds). Limited by the system update rate.
     /// </summary>
-    [DataField("updateRate")]
+    [DataField]
     public TimeSpan UpdateRate = TimeSpan.FromSeconds(2f);
 
     /// <summary>
@@ -56,7 +62,7 @@ public sealed partial class SuitSensorComponent : Component
     /// <summary>
     ///     Next time when sensor updated owners status
     /// </summary>
-    [DataField("nextUpdate", customTypeSerializer:typeof(TimeOffsetSerializer))]
+    [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
     [AutoPausedField]
     public TimeSpan NextUpdate = TimeSpan.Zero;
 
index dc1bb1124de29d6cda4d9fc91e3d254132aa2259..2b412654d57a855dfe40cee0fda59716cffb152d 100644 (file)
@@ -8,10 +8,13 @@ using Content.Server.GameTicking;
 using Content.Server.Medical.CrewMonitoring;
 using Content.Server.Popups;
 using Content.Server.Station.Systems;
+using Content.Shared.ActionBlocker;
 using Content.Shared.Clothing;
 using Content.Shared.Damage;
 using Content.Shared.DeviceNetwork;
+using Content.Shared.DoAfter;
 using Content.Shared.Examine;
+using Content.Shared.Interaction;
 using Content.Shared.Medical.SuitSensor;
 using Content.Shared.Mobs.Components;
 using Content.Shared.Mobs.Systems;
@@ -35,6 +38,9 @@ public sealed class SuitSensorSystem : EntitySystem
     [Dependency] private readonly StationSystem _stationSystem = default!;
     [Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = default!;
     [Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
+    [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+    [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
+    [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
 
     public override void Initialize()
     {
@@ -49,6 +55,7 @@ public sealed class SuitSensorSystem : EntitySystem
         SubscribeLocalEvent<SuitSensorComponent, EntGotRemovedFromContainerMessage>(OnRemove);
         SubscribeLocalEvent<SuitSensorComponent, EmpPulseEvent>(OnEmpPulse);
         SubscribeLocalEvent<SuitSensorComponent, EmpDisabledRemoved>(OnEmpFinished);
+        SubscribeLocalEvent<SuitSensorComponent, SuitSensorChangeDoAfterEvent>(OnSuitSensorDoAfter);
     }
 
     public override void Update(float frameTime)
@@ -205,7 +212,14 @@ public sealed class SuitSensorSystem : EntitySystem
             return;
 
         // standard interaction checks
-        if (!args.CanAccess || !args.CanInteract || args.Hands == null)
+        if (!args.CanInteract || args.Hands == null)
+            return;
+
+        if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target))
+            return;
+
+        // check if target is incapacitated (cuffed, dead, etc)
+        if (component.User != null && args.User != component.User && _actionBlocker.CanInteract(component.User.Value, null))
             return;
 
         args.Verbs.UnionWith(new[]
@@ -239,7 +253,7 @@ public sealed class SuitSensorSystem : EntitySystem
         args.Disabled = true;
 
         component.PreviousMode = component.Mode;
-        SetSensor(uid, SuitSensorMode.SensorOff, null, component);
+        SetSensor((uid, component), SuitSensorMode.SensorOff, null);
 
         component.PreviousControlsLocked = component.ControlsLocked;
         component.ControlsLocked = true;
@@ -247,7 +261,7 @@ public sealed class SuitSensorSystem : EntitySystem
 
     private void OnEmpFinished(EntityUid uid, SuitSensorComponent component, ref EmpDisabledRemoved args)
     {
-        SetSensor(uid, component.PreviousMode, null, component);
+        SetSensor((uid, component), component.PreviousMode, null);
         component.ControlsLocked = component.PreviousControlsLocked;
     }
 
@@ -259,7 +273,7 @@ public sealed class SuitSensorSystem : EntitySystem
             Disabled = component.Mode == mode,
             Priority = -(int) mode, // sort them in descending order
             Category = VerbCategory.SetSensor,
-            Act = () => SetSensor(uid, mode, userUid, component)
+            Act = () => TrySetSensor((uid, component), mode, userUid)
         };
     }
 
@@ -287,18 +301,46 @@ public sealed class SuitSensorSystem : EntitySystem
         return Loc.GetString(name);
     }
 
-    public void SetSensor(EntityUid uid, SuitSensorMode mode, EntityUid? userUid = null,
-        SuitSensorComponent? component = null)
+    public void TrySetSensor(Entity<SuitSensorComponent> sensors, SuitSensorMode mode, EntityUid userUid)
     {
-        if (!Resolve(uid, ref component))
+        var comp = sensors.Comp;
+
+        if (!Resolve(sensors, ref comp))
             return;
 
-        component.Mode = mode;
+        if (comp.User == null || userUid == comp.User)
+            SetSensor(sensors, mode, userUid);
+        else
+        {
+            var doAfterEvent = new SuitSensorChangeDoAfterEvent(mode);
+            var doAfterArgs = new DoAfterArgs(EntityManager, userUid, comp.SensorsTime, doAfterEvent, sensors)
+            {
+                BreakOnMove = true,
+                BreakOnDamage = true
+            };
+
+            _doAfterSystem.TryStartDoAfter(doAfterArgs);
+        }
+    }
+
+    private void OnSuitSensorDoAfter(Entity<SuitSensorComponent> sensors, ref SuitSensorChangeDoAfterEvent args)
+    {
+        if (args.Handled || args.Cancelled)
+            return;
+
+        SetSensor(sensors, args.Mode, args.User);
+    }
+
+    public void SetSensor(Entity<SuitSensorComponent> sensors, SuitSensorMode mode, EntityUid? userUid = null)
+    {
+        var comp = sensors.Comp;
+
+        comp.Mode = mode;
 
         if (userUid != null)
         {
             var msg = Loc.GetString("suit-sensor-mode-state", ("mode", GetModeName(mode)));
-            _popupSystem.PopupEntity(msg, uid, userUid.Value);
+            _popupSystem.PopupEntity(msg, sensors, userUid.Value);
         }
     }
 
index 27539dd22bdcc846685916271ef280b2418c9bd8..f48e31756d2dd91ccdb8ff33fc3d0680881487e1 100644 (file)
@@ -1,3 +1,4 @@
+using Content.Shared.DoAfter;
 using Robust.Shared.Map;
 using Robust.Shared.Serialization;
 
@@ -67,3 +68,16 @@ public static class SuitSensorConstants
     ///Used by the CrewMonitoringServerSystem to send the status of all connected suit sensors to each crew monitor
     public const string NET_STATUS_COLLECTION = "suit-status-collection";
 }
+
+[Serializable, NetSerializable]
+public sealed partial class SuitSensorChangeDoAfterEvent : DoAfterEvent
+{
+    public SuitSensorMode Mode { get; private set; } = SuitSensorMode.SensorOff;
+
+    public SuitSensorChangeDoAfterEvent(SuitSensorMode mode)
+    {
+        Mode = mode;
+    }
+
+    public override DoAfterEvent Clone() => this;
+}