From: alexalexmax <149889301+alexalexmax@users.noreply.github.com> Date: Tue, 16 Dec 2025 18:32:56 +0000 (-0800) Subject: Decouple standing state and drop item behavior (#41566) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=2a596d283c47e9223d58c1af4a1a150f12fd72f0;p=space-station-14.git Decouple standing state and drop item behavior (#41566) * 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> --- diff --git a/Content.IntegrationTests/Tests/Buckle/BuckleTest.cs b/Content.IntegrationTests/Tests/Buckle/BuckleTest.cs index d6dec6fe15..b90e1bd13c 100644 --- a/Content.IntegrationTests/Tests/Buckle/BuckleTest.cs +++ b/Content.IntegrationTests/Tests/Buckle/BuckleTest.cs @@ -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); diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs index 0b2efdce59..f7876501d4 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs @@ -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(bodyEnt, out var standingState) + || !standingState.Standing + || !Standing.Down(bodyEnt, standingState: standingState)) + return; + + var ev = new DropHandItemsEvent(); + RaiseLocalEvent(bodyEnt, ref ev); } private void PartRemoveDamage(Entity bodyEnt, Entity partEnt) diff --git a/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs b/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs index ded30499ee..b0a6eb8c80 100644 --- a/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs +++ b/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs @@ -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 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(target); - _standing.Down(target); + Down(target); _appearance.SetData(target, MobStateVisuals.State, MobState.Dead); break; + } case MobState.Invalid: + { //unused; break; + } default: + { throw new NotImplementedException(); + } } } diff --git a/Content.Shared/Slippery/SlipperySystem.cs b/Content.Shared/Slippery/SlipperySystem.cs index 51bbd2bea0..355d898dbf 100644 --- a/Content.Shared/Slippery/SlipperySystem.cs +++ b/Content.Shared/Slippery/SlipperySystem.cs @@ -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); diff --git a/Content.Shared/Standing/StandingStateSystem.cs b/Content.Shared/Standing/StandingStateSystem.cs index e7bd9e5f58..f6189fa667 100644 --- a/Content.Shared/Standing/StandingStateSystem.cs +++ b/Content.Shared/Standing/StandingStateSystem.cs @@ -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(); diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index 60d42ede62..d064434eac 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -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";