From 846274b7b81c79baea91934cac69885a8593cc3b Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Tue, 4 Apr 2023 04:28:27 +1000 Subject: [PATCH] Don't re-close closed doors (#15007) Fixes them re-closing on shuttle departure. If this is bad can just make shuttle code handle it but this seemed more appropriate? --- .../Systems/DockingSystem.AutoDock.cs | 30 +++--- .../Shuttles/Systems/DockingSystem.cs | 96 ++++++++++--------- .../Systems/ShuttleSystem.FasterThanLight.cs | 6 +- .../Doors/Systems/SharedDoorSystem.cs | 2 +- 4 files changed, 73 insertions(+), 61 deletions(-) diff --git a/Content.Server/Shuttles/Systems/DockingSystem.AutoDock.cs b/Content.Server/Shuttles/Systems/DockingSystem.AutoDock.cs index 6091b80a77..7474c5297e 100644 --- a/Content.Server/Shuttles/Systems/DockingSystem.AutoDock.cs +++ b/Content.Server/Shuttles/Systems/DockingSystem.AutoDock.cs @@ -16,9 +16,9 @@ public sealed partial class DockingSystem var dockingQuery = GetEntityQuery(); var xformQuery = GetEntityQuery(); var recentQuery = GetEntityQuery(); - var query = EntityQueryEnumerator(); + var query = EntityQueryEnumerator(); - while (query.MoveNext(out var dockUid, out var comp, out var body)) + while (query.MoveNext(out var dockUid, out var comp)) { if (comp.Requesters.Count == 0 || !dockingQuery.TryGetComponent(dockUid, out var dock)) { @@ -30,39 +30,43 @@ public sealed partial class DockingSystem if (dock.Docked || recentQuery.HasComponent(dockUid)) continue; - var dockable = GetDockable(body, xformQuery.GetComponent(dockUid)); + var dockable = GetDockable(dockUid, xformQuery.GetComponent(dockUid)); - if (dockable == null) continue; + if (dockable == null) + continue; TryDock(dockUid, dock, dockable.Owner, dockable); } // Work out recent docks that have gone past their designated threshold. var checkedRecent = new HashSet(); + var recentQueryEnumerator = EntityQueryEnumerator(); - foreach (var (comp, xform) in EntityQuery()) + while (recentQueryEnumerator.MoveNext(out var uid, out var comp, out var xform)) { - if (!checkedRecent.Add(comp.Owner)) continue; + if (!checkedRecent.Add(uid)) + continue; - if (!dockingQuery.TryGetComponent(comp.Owner, out var dock)) + if (!dockingQuery.HasComponent(uid)) { - RemComp(comp.Owner); + RemCompDeferred(uid); continue; } if (!xformQuery.TryGetComponent(comp.LastDocked, out var otherXform)) { - RemComp(comp.Owner); + RemCompDeferred(uid); continue; } var worldPos = _transform.GetWorldPosition(xform, xformQuery); var otherWorldPos = _transform.GetWorldPosition(otherXform, xformQuery); - if ((worldPos - otherWorldPos).Length < comp.Radius) continue; + if ((worldPos - otherWorldPos).Length < comp.Radius) + continue; - _sawmill.Debug($"Removed RecentlyDocked from {ToPrettyString(comp.Owner)} and {ToPrettyString(comp.LastDocked)}"); - RemComp(comp.Owner); + _sawmill.Debug($"Removed RecentlyDocked from {ToPrettyString(uid)} and {ToPrettyString(comp.LastDocked)}"); + RemComp(uid); RemComp(comp.LastDocked); } } @@ -79,7 +83,7 @@ public sealed partial class DockingSystem return; } - Undock(dock); + Undock(args.DockEntity, dock); } private void OnRequestAutodock(EntityUid uid, ShuttleConsoleComponent component, AutodockRequestMessage args) diff --git a/Content.Server/Shuttles/Systems/DockingSystem.cs b/Content.Server/Shuttles/Systems/DockingSystem.cs index 28fac88f20..edcb5dd8a4 100644 --- a/Content.Server/Shuttles/Systems/DockingSystem.cs +++ b/Content.Server/Shuttles/Systems/DockingSystem.cs @@ -63,20 +63,19 @@ namespace Content.Server.Shuttles.Systems args.Cancel(); } - private DockingComponent? GetDockable(PhysicsComponent body, TransformComponent dockingXform) + private DockingComponent? GetDockable(EntityUid uid, TransformComponent dockingXform) { // Did you know Saltern is the most dockable station? // Assume the docking port itself (and its body) is valid - if (!_mapManager.TryGetGrid(dockingXform.GridUid, out var grid) || - !HasComp(grid.Owner)) + if (!HasComp(dockingXform.GridUid)) { return null; } - var transform = _physics.GetPhysicsTransform(body.Owner, dockingXform); - var dockingFixture = _fixtureSystem.GetFixtureOrNull(body.Owner, DockingFixture); + var transform = _physics.GetPhysicsTransform(uid, dockingXform); + var dockingFixture = _fixtureSystem.GetFixtureOrNull(uid, DockingFixture); if (dockingFixture == null) return null; @@ -88,7 +87,8 @@ namespace Content.Server.Shuttles.Systems aabb = aabb?.Union(dockingFixture.Shape.ComputeAABB(transform, i)) ?? dockingFixture.Shape.ComputeAABB(transform, i); } - if (aabb == null) return null; + if (aabb == null) + return null; var enlargedAABB = aabb.Value.Enlarged(DockingRadius * 1.5f); @@ -121,7 +121,8 @@ namespace Content.Server.Shuttles.Systems { var otherAABB = otherDockingFixture.Shape.ComputeAABB(otherTransform, i); - if (!aabb.Value.Intersects(otherAABB)) continue; + if (!aabb.Value.Intersects(otherAABB)) + continue; // TODO: Need CollisionManager's GJK for accurate bounds // Realistically I want 2 fixtures anyway but I'll deal with that later. @@ -136,12 +137,15 @@ namespace Content.Server.Shuttles.Systems private void OnShutdown(EntityUid uid, DockingComponent component, ComponentShutdown args) { if (component.DockedWith == null || - EntityManager.GetComponent(uid).EntityLifeStage > EntityLifeStage.MapInitialized) return; + EntityManager.GetComponent(uid).EntityLifeStage > EntityLifeStage.MapInitialized) + { + return; + } - Cleanup(component); + Cleanup(uid, component); } - private void Cleanup(DockingComponent dockA) + private void Cleanup(EntityUid dockAUid, DockingComponent dockA) { _pathfinding.RemovePortal(dockA.PathfindHandle); @@ -154,7 +158,7 @@ namespace Content.Server.Shuttles.Systems !TryComp(dockBUid, out DockingComponent? dockB)) { DebugTools.Assert(false); - _sawmill.Error($"Tried to cleanup {dockA.Owner} but not docked?"); + _sawmill.Error($"Tried to cleanup {dockAUid} but not docked?"); dockA.DockedWith = null; if (dockA.DockJoint != null) @@ -175,10 +179,8 @@ namespace Content.Server.Shuttles.Systems dockA.DockJointId = null; // If these grids are ever null then need to look at fixing ordering for unanchored events elsewhere. - var gridAUid = EntityManager.GetComponent(dockA.Owner).GridUid; - var gridBUid = EntityManager.GetComponent(dockB.Owner).GridUid; - DebugTools.Assert(gridAUid != null); - DebugTools.Assert(gridBUid != null); + var gridAUid = EntityManager.GetComponent(dockAUid).GridUid; + var gridBUid = EntityManager.GetComponent(dockBUid.Value).GridUid; var msg = new UndockEvent { @@ -188,8 +190,8 @@ namespace Content.Server.Shuttles.Systems GridBUid = gridBUid!.Value, }; - RaiseLocalEvent(dockA.Owner, msg); - RaiseLocalEvent(dockB.Owner, msg); + RaiseLocalEvent(dockAUid, msg); + RaiseLocalEvent(dockBUid.Value, msg); RaiseLocalEvent(msg); } @@ -204,7 +206,8 @@ namespace Content.Server.Shuttles.Systems if (component.DockedWith != null) { // They're still initialising so we'll just wait for both to be ready. - if (MetaData(component.DockedWith.Value).EntityLifeStage < EntityLifeStage.Initialized) return; + if (MetaData(component.DockedWith.Value).EntityLifeStage < EntityLifeStage.Initialized) + return; var otherDock = EntityManager.GetComponent(component.DockedWith.Value); DebugTools.Assert(otherDock.DockedWith != null); @@ -230,24 +233,26 @@ namespace Content.Server.Shuttles.Systems private void OnDockingReAnchor(EntityUid uid, DockingComponent component, ref ReAnchorEvent args) { - if (!component.Docked) return; + if (!component.Docked) + return; var other = Comp(component.DockedWith!.Value); - Undock(component); + Undock(uid, component); Dock(uid, component, component.DockedWith.Value, other); _console.RefreshShuttleConsoles(); } private void DisableDocking(EntityUid uid, DockingComponent component) { - if (!component.Enabled) return; + if (!component.Enabled) + return; component.Enabled = false; if (component.DockedWith != null) { - Undock(component); + Undock(uid, component); } if (!TryComp(uid, out PhysicsComponent? physicsComponent)) @@ -301,8 +306,8 @@ namespace Content.Server.Shuttles.Systems var gridB = dockBXform.GridUid!.Value; // May not be possible if map or the likes. - if (TryComp(gridA, out var gridPhysicsA) && - TryComp(gridB, out var gridPhysicsB)) + if (HasComp(gridA) && + HasComp(gridB)) { SharedJointSystem.LinearStiffness( 2f, @@ -335,7 +340,7 @@ namespace Content.Server.Shuttles.Systems joint.LocalAnchorA = anchorA; joint.LocalAnchorB = anchorB; - joint.ReferenceAngle = (float) (gridBXform.WorldRotation - gridAXform.WorldRotation); + joint.ReferenceAngle = (float) (_transform.GetWorldRotation(gridBXform) - _transform.GetWorldRotation(gridAXform)); joint.CollideConnected = true; joint.Stiffness = stiffness; joint.Damping = damping; @@ -393,11 +398,9 @@ namespace Content.Server.Shuttles.Systems RaiseLocalEvent(msg); } - private bool CanDock(DockingComponent dockA, DockingComponent dockB) + private bool CanDock(EntityUid dockAUid, EntityUid dockBUid, DockingComponent dockA, DockingComponent dockB) { - if (!TryComp(dockA.Owner, out PhysicsComponent? bodyA) || - !TryComp(dockB.Owner, out PhysicsComponent? bodyB) || - !dockA.Enabled || + if (!dockA.Enabled || !dockB.Enabled || dockA.DockedWith != null || dockB.DockedWith != null) @@ -405,16 +408,16 @@ namespace Content.Server.Shuttles.Systems return false; } - var fixtureA = _fixtureSystem.GetFixtureOrNull(bodyA.Owner, DockingFixture); - var fixtureB = _fixtureSystem.GetFixtureOrNull(bodyB.Owner, DockingFixture); + var fixtureA = _fixtureSystem.GetFixtureOrNull(dockAUid, DockingFixture); + var fixtureB = _fixtureSystem.GetFixtureOrNull(dockBUid, DockingFixture); if (fixtureA == null || fixtureB == null) { return false; } - var transformA = _physics.GetPhysicsTransform(dockA.Owner); - var transformB = _physics.GetPhysicsTransform(dockB.Owner); + var transformA = _physics.GetPhysicsTransform(dockAUid); + var transformB = _physics.GetPhysicsTransform(dockBUid); var intersect = false; for (var i = 0; i < fixtureA.Shape.ChildCount; i++) @@ -424,14 +427,16 @@ namespace Content.Server.Shuttles.Systems for (var j = 0; j < fixtureB.Shape.ChildCount; j++) { var otherAABB = fixtureB.Shape.ComputeAABB(transformB, j); - if (!aabb.Intersects(otherAABB)) continue; + if (!aabb.Intersects(otherAABB)) + continue; // TODO: Need collisionmanager's GJK for accurate checks don't @ me son intersect = true; break; } - if (intersect) break; + if (intersect) + break; } return intersect; @@ -442,19 +447,20 @@ namespace Content.Server.Shuttles.Systems /// private void TryDock(EntityUid dockAUid, DockingComponent dockA, EntityUid dockBUid, DockingComponent dockB) { - if (!CanDock(dockA, dockB)) return; + if (!CanDock(dockAUid, dockBUid, dockA, dockB)) + return; Dock(dockAUid, dockA, dockBUid, dockB); } - public void Undock(DockingComponent dock) + public void Undock(EntityUid dockUid, DockingComponent dock) { if (dock.DockedWith == null) return; - if (TryComp(dock.Owner, out var airlockA)) + if (TryComp(dockUid, out var airlockA)) { - _airlocks.SetBoltsWithAudio(dock.Owner, airlockA, false); + _airlocks.SetBoltsWithAudio(dockUid, airlockA, false); } if (TryComp(dock.DockedWith, out var airlockB)) @@ -462,9 +468,9 @@ namespace Content.Server.Shuttles.Systems _airlocks.SetBoltsWithAudio(dock.DockedWith.Value, airlockB, false); } - if (TryComp(dock.Owner, out DoorComponent? doorA)) + if (TryComp(dockUid, out DoorComponent? doorA)) { - if (_doorSystem.TryClose(doorA.Owner, doorA)) + if (_doorSystem.TryClose(dockUid, doorA)) { doorA.ChangeAirtight = true; } @@ -472,15 +478,15 @@ namespace Content.Server.Shuttles.Systems if (TryComp(dock.DockedWith, out DoorComponent? doorB)) { - if (_doorSystem.TryClose(doorB.Owner, doorB)) + if (_doorSystem.TryClose(dock.DockedWith.Value, doorB)) { doorB.ChangeAirtight = true; } } - if (LifeStage(dock.Owner) < EntityLifeStage.Terminating) + if (LifeStage(dockUid) < EntityLifeStage.Terminating) { - var recentlyDocked = EnsureComp(dock.Owner); + var recentlyDocked = EnsureComp(dockUid); recentlyDocked.LastDocked = dock.DockedWith.Value; } @@ -490,7 +496,7 @@ namespace Content.Server.Shuttles.Systems recentlyDocked.LastDocked = dock.DockedWith.Value; } - Cleanup(dock); + Cleanup(dockUid, dock); } } } diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs index 5342208546..9c6de9106f 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs @@ -361,12 +361,14 @@ public sealed partial class ShuttleSystem private void SetDocks(EntityUid uid, bool enabled) { - foreach (var (dock, xform) in EntityQuery(true)) + var query = AllEntityQuery(); + + while (query.MoveNext(out var dockUid, out var dock, out var xform)) { if (xform.ParentUid != uid || dock.Enabled == enabled) continue; - _dockSystem.Undock(dock); + _dockSystem.Undock(dockUid, dock); dock.Enabled = enabled; } } diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 6bbf943674..b7ad3a799b 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -326,7 +326,7 @@ public abstract class SharedDoorSystem : EntitySystem // since both closing/closed and welded are door states, we need to prevent 'closing' // a welded door or else there will be weird state bugs - if (door.State == DoorState.Welded) + if (door.State is DoorState.Welded or DoorState.Closed) return false; var ev = new BeforeDoorClosedEvent(door.PerformCollisionCheck);