]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Buckling an entity requires a do-after (#29621)
authorPlykiya <58439124+Plykiya@users.noreply.github.com>
Fri, 9 Aug 2024 15:43:02 +0000 (08:43 -0700)
committerGitHub <noreply@github.com>
Fri, 9 Aug 2024 15:43:02 +0000 (01:43 +1000)
* Buckling an entity requires a do-after

* Works but feels like bad code?

* Cleanup

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
Content.Shared/Buckle/BuckleDoafterEvent.cs [new file with mode: 0644]
Content.Shared/Buckle/Components/StrapComponent.cs
Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs
Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs
Content.Shared/Buckle/SharedBuckleSystem.cs

diff --git a/Content.Shared/Buckle/BuckleDoafterEvent.cs b/Content.Shared/Buckle/BuckleDoafterEvent.cs
new file mode 100644 (file)
index 0000000..268ddfe
--- /dev/null
@@ -0,0 +1,11 @@
+using Content.Shared.Cuffs.Components;
+using Content.Shared.DoAfter;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Buckle;
+
+[Serializable, NetSerializable]
+public sealed partial class BuckleDoAfterEvent : SimpleDoAfterEvent
+{
+
+}
index a16d15f8a2c07375cd02b6dc3c86624ef8406d28..b8186e2b79f6b7967b6fc04604c5efe3e06018a8 100644 (file)
@@ -84,6 +84,12 @@ public sealed partial class StrapComponent : Component
     /// </summary>
     [DataField]
     public ProtoId<AlertPrototype> BuckledAlertType = "Buckled";
+
+    /// <summary>
+    /// How long it takes to buckle someone else into a chair
+    /// </summary>
+    [DataField]
+    public float BuckleDoafterTime = 2f;
 }
 
 public enum StrapPosition
index 4f91a29ebea1863cb10ba54f3a967f8eedcd1b07..83c24016ceb16be550b13c62529d7a066c758cb0 100644 (file)
@@ -2,7 +2,9 @@ using System.Diagnostics.CodeAnalysis;
 using System.Numerics;
 using Content.Shared.Alert;
 using Content.Shared.Buckle.Components;
+using Content.Shared.Cuffs.Components;
 using Content.Shared.Database;
+using Content.Shared.DoAfter;
 using Content.Shared.Hands.Components;
 using Content.Shared.IdentityManagement;
 using Content.Shared.Movement.Events;
@@ -51,6 +53,12 @@ public abstract partial class SharedBuckleSystem
         SubscribeLocalEvent<BuckleComponent, ThrowPushbackAttemptEvent>(OnBuckleThrowPushbackAttempt);
         SubscribeLocalEvent<BuckleComponent, UpdateCanMoveEvent>(OnBuckleUpdateCanMove);
 
+        SubscribeLocalEvent<BuckleComponent, BuckleDoAfterEvent>(OnBuckleDoafter);
+        SubscribeLocalEvent<BuckleComponent, DoAfterAttemptEvent<BuckleDoAfterEvent>>((uid, comp, ev) =>
+        {
+            BuckleDoafterEarly((uid, comp), ev.Event, ev);
+        });
+
         SubscribeLocalEvent<BuckleComponent, ComponentGetState>(OnGetState);
     }
 
@@ -516,4 +524,39 @@ public abstract partial class SharedBuckleSystem
         RaiseLocalEvent(strap, ref unstrapAttempt);
         return !unstrapAttempt.Cancelled;
     }
+
+    /// <summary>
+    /// Once the do-after is complete, try to buckle target to chair/bed
+    /// </summary>
+    /// <param name="args.Target"> The person being put in the chair/bed</param>
+    /// <param name="args.User"> The person putting a person in a chair/bed</param>
+    /// <param name="args.Used"> The chair/bed </param>
+
+    private void OnBuckleDoafter(Entity<BuckleComponent> entity, ref BuckleDoAfterEvent args)
+    {
+        if (args.Cancelled || args.Handled || args.Target == null || args.Used == null)
+            return;
+
+        args.Handled = TryBuckle(args.Target.Value, args.User, args.Used.Value, popup: false);
+    }
+
+    /// <summary>
+    /// If the target being buckled to a chair/bed goes crit or is cuffed
+    /// Cancel the do-after time and try to buckle the target immediately
+    /// </summary>
+    /// <param name="args.Target"> The person being put in the chair/bed</param>
+    /// <param name="args.User"> The person putting a person in a chair/bed</param>
+    /// <param name="args.Used"> The chair/bed </param>
+    private void BuckleDoafterEarly(Entity<BuckleComponent> entity, BuckleDoAfterEvent args, CancellableEntityEventArgs ev)
+    {
+        if (args.Target == null || args.Used == null)
+            return;
+
+        if (TryComp<CuffableComponent>(args.Target, out var targetCuffableComp) && targetCuffableComp.CuffedHandCount > 0
+            || _mobState.IsIncapacitated(args.Target.Value))
+        {
+            ev.Cancel();
+            TryBuckle(args.Target.Value, args.User, args.Used.Value, popup: false);
+        }
+    }
 }
index 463e0d5596233ea2950647df28444abfb10c8883..a4cfc9c8c4f288675eaef6e10334400a60def711 100644 (file)
@@ -1,4 +1,6 @@
-using Content.Shared.Buckle.Components;
+using Content.Shared.Buckle.Components;
+using Content.Shared.Cuffs.Components;
+using Content.Shared.DoAfter;
 using Content.Shared.DragDrop;
 using Content.Shared.IdentityManagement;
 using Content.Shared.Interaction;
@@ -32,7 +34,24 @@ public abstract partial class SharedBuckleSystem
         if (!StrapCanDragDropOn(uid, args.User, uid, args.Dragged, component))
             return;
 
-        args.Handled = TryBuckle(args.Dragged, args.User, uid, popup: false);
+        if (args.Dragged == args.User)
+        {
+            if (!TryComp(args.User, out BuckleComponent? buckle))
+                return;
+
+            args.Handled = TryBuckle(args.User, args.User, uid, buckle);
+        }
+        else
+        {
+            var doAfterArgs = new DoAfterArgs(EntityManager, args.User, component.BuckleDoafterTime, new BuckleDoAfterEvent(), args.User, args.Dragged, uid)
+            {
+                BreakOnMove = true,
+                BreakOnDamage = true,
+                AttemptFrequency = AttemptFrequency.EveryTick
+            };
+
+            _doAfter.TryStartDoAfter(doAfterArgs);
+        }
     }
 
     private bool StrapCanDragDropOn(
index 770fababded6c881adad02bc664458544b0e1c64..d190f685ed0e7a8ec9e51742d41bd9edec36be45 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Shared.ActionBlocker;
 using Content.Shared.Administration.Logs;
 using Content.Shared.Alert;
+using Content.Shared.DoAfter;
 using Content.Shared.Interaction;
 using Content.Shared.Mobs.Systems;
 using Content.Shared.Popups;
@@ -36,6 +37,7 @@ public abstract partial class SharedBuckleSystem : EntitySystem
     [Dependency] private readonly StandingStateSystem _standing = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
     [Dependency] private readonly SharedRotationVisualsSystem _rotationVisuals = default!;
+    [Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
 
     /// <inheritdoc/>
     public override void Initialize()