From 661fc00a1fa574abeb4348c7ee4cae8877de49ac Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Mon, 11 Aug 2025 12:41:13 -0700 Subject: [PATCH] [HOTFIX] Stop players from clipping through Windoors (#39564) * Don't have standing state edit soft fixtures? * Bugfix * Cherry pick acquired --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Standing/StandingStateSystem.cs | 65 +++++++++++++------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/Content.Shared/Standing/StandingStateSystem.cs b/Content.Shared/Standing/StandingStateSystem.cs index f965e0ae7c..7f3b8c9aac 100644 --- a/Content.Shared/Standing/StandingStateSystem.cs +++ b/Content.Shared/Standing/StandingStateSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Climbing.Events; using Content.Shared.Hands.Components; using Content.Shared.Movement.Events; using Content.Shared.Movement.Systems; @@ -25,6 +26,7 @@ public sealed class StandingStateSystem : EntitySystem SubscribeLocalEvent(OnMobTargetCollide); SubscribeLocalEvent(OnRefreshFrictionModifiers); SubscribeLocalEvent(OnTileFriction); + SubscribeLocalEvent(OnEndClimb); } private void OnMobTargetCollide(Entity ent, ref AttemptMobTargetCollideEvent args) @@ -58,6 +60,15 @@ public sealed class StandingStateSystem : EntitySystem args.Modifier *= entity.Comp.DownFrictionMod; } + private void OnEndClimb(Entity entity, ref EndClimbEvent args) + { + if (entity.Comp.Standing) + return; + + // Currently only Climbing also edits fixtures layers like this so this is fine for now. + ChangeLayers(entity); + } + public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null) { if (!Resolve(uid, ref standingState, false)) @@ -111,17 +122,7 @@ public sealed class StandingStateSystem : EntitySystem _appearance.SetData(uid, RotationVisuals.RotationState, RotationState.Horizontal, appearance); // Change collision masks to allow going under certain entities like flaps and tables - if (TryComp(uid, out FixturesComponent? fixtureComponent)) - { - foreach (var (key, fixture) in fixtureComponent.Fixtures) - { - if ((fixture.CollisionMask & StandingCollisionLayer) == 0) - continue; - - standingState.ChangedFixtures.Add(key); - _physics.SetCollisionMask(uid, key, fixture, fixture.CollisionMask & ~StandingCollisionLayer, manager: fixtureComponent); - } - } + ChangeLayers((uid, standingState)); // check if component was just added or streamed to client // if true, no need to play sound - mob was down before player could seen that @@ -166,17 +167,43 @@ public sealed class StandingStateSystem : EntitySystem _appearance.SetData(uid, RotationVisuals.RotationState, RotationState.Vertical, appearance); - if (TryComp(uid, out FixturesComponent? fixtureComponent)) + RevertLayers((uid, standingState)); + + return true; + } + + // TODO: This should be moved to a PhysicsModifierSystem which raises events so multiple systems can modify fixtures at once + private void ChangeLayers(Entity entity) + { + if (!Resolve(entity, ref entity.Comp2, false)) + return; + + foreach (var (key, fixture) in entity.Comp2.Fixtures) { - foreach (var key in standingState.ChangedFixtures) - { - if (fixtureComponent.Fixtures.TryGetValue(key, out var fixture)) - _physics.SetCollisionMask(uid, key, fixture, fixture.CollisionMask | StandingCollisionLayer, fixtureComponent); - } + if ((fixture.CollisionMask & StandingCollisionLayer) == 0 || !fixture.Hard) + continue; + + entity.Comp1.ChangedFixtures.Add(key); + _physics.SetCollisionMask(entity, key, fixture, fixture.CollisionMask & ~StandingCollisionLayer, manager: entity.Comp2); } - standingState.ChangedFixtures.Clear(); + } - return true; + // TODO: This should be moved to a PhysicsModifierSystem which raises events so multiple systems can modify fixtures at once + private void RevertLayers(Entity entity) + { + if (!Resolve(entity, ref entity.Comp2, false)) + { + entity.Comp1.ChangedFixtures.Clear(); + return; + } + + foreach (var key in entity.Comp1.ChangedFixtures) + { + if (entity.Comp2.Fixtures.TryGetValue(key, out var fixture) && fixture.Hard) + _physics.SetCollisionMask(entity, key, fixture, fixture.CollisionMask | StandingCollisionLayer, entity.Comp2); + } + + entity.Comp1.ChangedFixtures.Clear(); } } -- 2.51.2