]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Decouple standing state and drop item behavior (#41566)
authoralexalexmax <149889301+alexalexmax@users.noreply.github.com>
Tue, 16 Dec 2025 18:32:56 +0000 (10:32 -0800)
committerGitHub <noreply@github.com>
Tue, 16 Dec 2025 18:32:56 +0000 (18:32 +0000)
* removed DropHandsItemEvent from standing state system, added DropHandsItemEvent calls in slippery system and shared stun system

* added DropHandItemsEvent calls in mobstate system subscribers

* Added DropHandItemsEvent call in SharedBodySystem.Parts

* Add a standingState check in RemoveLeg so removing the legs of a downed person won't cause them to drop items

* new method for downing + dropping held items in mobstatesystem

* mild cleanup

* Bugfix

* update BuckleTest to reflect new item dropping behavior when removing legs

* light cleanup

---------

Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Content.IntegrationTests/Tests/Buckle/BuckleTest.cs
Content.Shared/Body/Systems/SharedBodySystem.Parts.cs
Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs
Content.Shared/Slippery/SlipperySystem.cs
Content.Shared/Standing/StandingStateSystem.cs
Content.Shared/Stunnable/SharedStunSystem.cs

index d6dec6fe151d142bf5034cc39ff2d7c7faa7ea49..b90e1bd13c291e7b57a4222d993fa4674c2c8d9c 100644 (file)
@@ -315,10 +315,10 @@ namespace Content.IntegrationTests.Tests.Buckle
                 // Still buckled
                 Assert.That(buckle.Buckled);
 
-                // Now with no item in any hand
+                // Still with items in hand
                 foreach (var hand in hands.Hands.Keys)
                 {
-                    Assert.That(handsSys.GetHeldItem((human, hands), hand), Is.Null);
+                    Assert.That(handsSys.GetHeldItem((human, hands), hand), Is.Not.Null);
                 }
 
                 buckleSystem.Unbuckle(human, human);
index 0b2efdce59f74d204c25fdefd1b3cad5eb6fd9b8..f7876501d417114c72646dbbd59404f7b84745b0 100644 (file)
@@ -7,6 +7,7 @@ using Content.Shared.Body.Part;
 using Content.Shared.Damage;
 using Content.Shared.Damage.Prototypes;
 using Content.Shared.Movement.Components;
+using Content.Shared.Standing;
 using Robust.Shared.Containers;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Utility;
@@ -156,17 +157,23 @@ public partial class SharedBodySystem
         if (!Resolve(bodyEnt, ref bodyEnt.Comp, logMissing: false))
             return;
 
-        if (legEnt.Comp.PartType == BodyPartType.Leg)
-        {
-            bodyEnt.Comp.LegEntities.Remove(legEnt);
-            UpdateMovementSpeed(bodyEnt);
-            Dirty(bodyEnt, bodyEnt.Comp);
+        if (legEnt.Comp.PartType != BodyPartType.Leg)
+            return;
 
-            if (!bodyEnt.Comp.LegEntities.Any())
-            {
-                Standing.Down(bodyEnt);
-            }
-        }
+        bodyEnt.Comp.LegEntities.Remove(legEnt);
+        UpdateMovementSpeed(bodyEnt);
+        Dirty(bodyEnt, bodyEnt.Comp);
+
+        if (bodyEnt.Comp.LegEntities.Count != 0)
+            return;
+
+        if (!TryComp<StandingStateComponent>(bodyEnt, out var standingState)
+            || !standingState.Standing
+            || !Standing.Down(bodyEnt, standingState: standingState))
+            return;
+
+        var ev = new DropHandItemsEvent();
+        RaiseLocalEvent(bodyEnt, ref ev);
     }
 
     private void PartRemoveDamage(Entity<BodyComponent?> bodyEnt, Entity<BodyPartComponent> partEnt)
index ded30499ee88d473dc10815dcbaef8d1cb751829..b0a6eb8c808af4389cc6927f0abddf5a96fe8ed9 100644 (file)
@@ -59,6 +59,13 @@ public partial class MobStateSystem
             args.Cancelled = true;
     }
 
+    private void Down(EntityUid target)
+    {
+        _standing.Down(target);
+        var ev = new DropHandItemsEvent();
+        RaiseLocalEvent(target, ref ev);
+    }
+
     private void CheckConcious(Entity<MobStateComponent> ent, ref ConsciousAttemptEvent args)
     {
         switch (ent.Comp.CurrentState)
@@ -103,23 +110,33 @@ public partial class MobStateSystem
         switch (state)
         {
             case MobState.Alive:
+            {
                 _standing.Stand(target);
                 _appearance.SetData(target, MobStateVisuals.State, MobState.Alive);
                 break;
+            }
             case MobState.Critical:
-                _standing.Down(target);
+            {
+                Down(target);
                 _appearance.SetData(target, MobStateVisuals.State, MobState.Critical);
                 break;
+            }
             case MobState.Dead:
+            {
                 EnsureComp<CollisionWakeComponent>(target);
-                _standing.Down(target);
+                Down(target);
                 _appearance.SetData(target, MobStateVisuals.State, MobState.Dead);
                 break;
+            }
             case MobState.Invalid:
+            {
                 //unused;
                 break;
+            }
             default:
+            {
                 throw new NotImplementedException();
+            }
         }
     }
 
index 51bbd2bea0f39de18110f2544ccd5ae19e6e4095..355d898dbf67ffb553c74c13b4c6abafc1776cf0 100644 (file)
@@ -4,6 +4,7 @@ using Content.Shared.Database;
 using Content.Shared.Inventory;
 using Content.Shared.Movement.Components;
 using Content.Shared.Movement.Systems;
+using Content.Shared.Standing;
 using Content.Shared.StatusEffectNew;
 using Content.Shared.StepTrigger.Systems;
 using Content.Shared.Stunnable;
@@ -131,6 +132,9 @@ public sealed class SlipperySystem : EntitySystem
         // Preventing from playing the slip sound and stunning when you are already knocked down.
         if (!knockedDown)
         {
+            var evDropHands = new DropHandItemsEvent();
+            RaiseLocalEvent(uid, ref evDropHands);
+
             // Status effects should handle a TimeSpan of 0 properly...
             _stun.TryUpdateStunDuration(other, component.SlipData.StunTime);
 
index e7bd9e5f58f9ef0feb0125563c15709390645eb5..f6189fa667d9f8f4dcce58ac4fadbc6343702e48 100644 (file)
@@ -101,16 +101,6 @@ public sealed class StandingStateSystem : EntitySystem
         if (!standingState.Standing)
             return true;
 
-        // This is just to avoid most callers doing this manually saving boilerplate
-        // 99% of the time you'll want to drop items but in some scenarios (e.g. buckling) you don't want to.
-        // We do this BEFORE downing because something like buckle may be blocking downing but we want to drop hand items anyway
-        // and ultimately this is just to avoid boilerplate in Down callers + keep their behavior consistent.
-        if (dropHeldItems && hands != null)
-        {
-            var ev = new DropHandItemsEvent();
-            RaiseLocalEvent(uid, ref ev, false);
-        }
-
         if (!force)
         {
             var msg = new DownAttemptEvent();
index 60d42ede62b87114471f80efbe57d8afcfc26549..d064434eac6a14f73de493bd0167e826832182a0 100644 (file)
@@ -150,6 +150,9 @@ public abstract partial class SharedStunSystem : EntitySystem
         var ev = new StunnedEvent(); // todo: rename event or change how it is raised - this event is raised each time duration of stun was externally changed
         RaiseLocalEvent(uid, ref ev);
 
+        var evDropHands = new DropHandItemsEvent();
+        RaiseLocalEvent(uid, ref evDropHands);
+
         var timeForLogs = duration.HasValue
             ? duration.Value.Seconds.ToString()
             : "Infinite";