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?
This commit is contained in:
metalgearsloth
2023-04-04 04:28:27 +10:00
committed by GitHub
parent fc61b9da62
commit 846274b7b8
4 changed files with 73 additions and 61 deletions

View File

@@ -16,9 +16,9 @@ public sealed partial class DockingSystem
var dockingQuery = GetEntityQuery<DockingComponent>(); var dockingQuery = GetEntityQuery<DockingComponent>();
var xformQuery = GetEntityQuery<TransformComponent>(); var xformQuery = GetEntityQuery<TransformComponent>();
var recentQuery = GetEntityQuery<RecentlyDockedComponent>(); var recentQuery = GetEntityQuery<RecentlyDockedComponent>();
var query = EntityQueryEnumerator<AutoDockComponent, PhysicsComponent>(); var query = EntityQueryEnumerator<AutoDockComponent>();
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)) 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)) if (dock.Docked || recentQuery.HasComponent(dockUid))
continue; 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); TryDock(dockUid, dock, dockable.Owner, dockable);
} }
// Work out recent docks that have gone past their designated threshold. // Work out recent docks that have gone past their designated threshold.
var checkedRecent = new HashSet<EntityUid>(); var checkedRecent = new HashSet<EntityUid>();
var recentQueryEnumerator = EntityQueryEnumerator<RecentlyDockedComponent, TransformComponent>();
foreach (var (comp, xform) in EntityQuery<RecentlyDockedComponent, TransformComponent>()) 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<RecentlyDockedComponent>(comp.Owner); RemCompDeferred<RecentlyDockedComponent>(uid);
continue; continue;
} }
if (!xformQuery.TryGetComponent(comp.LastDocked, out var otherXform)) if (!xformQuery.TryGetComponent(comp.LastDocked, out var otherXform))
{ {
RemComp<RecentlyDockedComponent>(comp.Owner); RemCompDeferred<RecentlyDockedComponent>(uid);
continue; continue;
} }
var worldPos = _transform.GetWorldPosition(xform, xformQuery); var worldPos = _transform.GetWorldPosition(xform, xformQuery);
var otherWorldPos = _transform.GetWorldPosition(otherXform, 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)}"); _sawmill.Debug($"Removed RecentlyDocked from {ToPrettyString(uid)} and {ToPrettyString(comp.LastDocked)}");
RemComp<RecentlyDockedComponent>(comp.Owner); RemComp<RecentlyDockedComponent>(uid);
RemComp<RecentlyDockedComponent>(comp.LastDocked); RemComp<RecentlyDockedComponent>(comp.LastDocked);
} }
} }
@@ -79,7 +83,7 @@ public sealed partial class DockingSystem
return; return;
} }
Undock(dock); Undock(args.DockEntity, dock);
} }
private void OnRequestAutodock(EntityUid uid, ShuttleConsoleComponent component, AutodockRequestMessage args) private void OnRequestAutodock(EntityUid uid, ShuttleConsoleComponent component, AutodockRequestMessage args)

View File

@@ -63,20 +63,19 @@ namespace Content.Server.Shuttles.Systems
args.Cancel(); 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? // Did you know Saltern is the most dockable station?
// Assume the docking port itself (and its body) is valid // Assume the docking port itself (and its body) is valid
if (!_mapManager.TryGetGrid(dockingXform.GridUid, out var grid) || if (!HasComp<ShuttleComponent>(dockingXform.GridUid))
!HasComp<ShuttleComponent>(grid.Owner))
{ {
return null; return null;
} }
var transform = _physics.GetPhysicsTransform(body.Owner, dockingXform); var transform = _physics.GetPhysicsTransform(uid, dockingXform);
var dockingFixture = _fixtureSystem.GetFixtureOrNull(body.Owner, DockingFixture); var dockingFixture = _fixtureSystem.GetFixtureOrNull(uid, DockingFixture);
if (dockingFixture == null) if (dockingFixture == null)
return 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); 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); var enlargedAABB = aabb.Value.Enlarged(DockingRadius * 1.5f);
@@ -121,7 +121,8 @@ namespace Content.Server.Shuttles.Systems
{ {
var otherAABB = otherDockingFixture.Shape.ComputeAABB(otherTransform, i); 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 // TODO: Need CollisionManager's GJK for accurate bounds
// Realistically I want 2 fixtures anyway but I'll deal with that later. // 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) private void OnShutdown(EntityUid uid, DockingComponent component, ComponentShutdown args)
{ {
if (component.DockedWith == null || if (component.DockedWith == null ||
EntityManager.GetComponent<MetaDataComponent>(uid).EntityLifeStage > EntityLifeStage.MapInitialized) return; EntityManager.GetComponent<MetaDataComponent>(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); _pathfinding.RemovePortal(dockA.PathfindHandle);
@@ -154,7 +158,7 @@ namespace Content.Server.Shuttles.Systems
!TryComp(dockBUid, out DockingComponent? dockB)) !TryComp(dockBUid, out DockingComponent? dockB))
{ {
DebugTools.Assert(false); 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; dockA.DockedWith = null;
if (dockA.DockJoint != null) if (dockA.DockJoint != null)
@@ -175,10 +179,8 @@ namespace Content.Server.Shuttles.Systems
dockA.DockJointId = null; dockA.DockJointId = null;
// If these grids are ever null then need to look at fixing ordering for unanchored events elsewhere. // If these grids are ever null then need to look at fixing ordering for unanchored events elsewhere.
var gridAUid = EntityManager.GetComponent<TransformComponent>(dockA.Owner).GridUid; var gridAUid = EntityManager.GetComponent<TransformComponent>(dockAUid).GridUid;
var gridBUid = EntityManager.GetComponent<TransformComponent>(dockB.Owner).GridUid; var gridBUid = EntityManager.GetComponent<TransformComponent>(dockBUid.Value).GridUid;
DebugTools.Assert(gridAUid != null);
DebugTools.Assert(gridBUid != null);
var msg = new UndockEvent var msg = new UndockEvent
{ {
@@ -188,8 +190,8 @@ namespace Content.Server.Shuttles.Systems
GridBUid = gridBUid!.Value, GridBUid = gridBUid!.Value,
}; };
RaiseLocalEvent(dockA.Owner, msg); RaiseLocalEvent(dockAUid, msg);
RaiseLocalEvent(dockB.Owner, msg); RaiseLocalEvent(dockBUid.Value, msg);
RaiseLocalEvent(msg); RaiseLocalEvent(msg);
} }
@@ -204,7 +206,8 @@ namespace Content.Server.Shuttles.Systems
if (component.DockedWith != null) if (component.DockedWith != null)
{ {
// They're still initialising so we'll just wait for both to be ready. // 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<DockingComponent>(component.DockedWith.Value); var otherDock = EntityManager.GetComponent<DockingComponent>(component.DockedWith.Value);
DebugTools.Assert(otherDock.DockedWith != null); DebugTools.Assert(otherDock.DockedWith != null);
@@ -230,24 +233,26 @@ namespace Content.Server.Shuttles.Systems
private void OnDockingReAnchor(EntityUid uid, DockingComponent component, ref ReAnchorEvent args) private void OnDockingReAnchor(EntityUid uid, DockingComponent component, ref ReAnchorEvent args)
{ {
if (!component.Docked) return; if (!component.Docked)
return;
var other = Comp<DockingComponent>(component.DockedWith!.Value); var other = Comp<DockingComponent>(component.DockedWith!.Value);
Undock(component); Undock(uid, component);
Dock(uid, component, component.DockedWith.Value, other); Dock(uid, component, component.DockedWith.Value, other);
_console.RefreshShuttleConsoles(); _console.RefreshShuttleConsoles();
} }
private void DisableDocking(EntityUid uid, DockingComponent component) private void DisableDocking(EntityUid uid, DockingComponent component)
{ {
if (!component.Enabled) return; if (!component.Enabled)
return;
component.Enabled = false; component.Enabled = false;
if (component.DockedWith != null) if (component.DockedWith != null)
{ {
Undock(component); Undock(uid, component);
} }
if (!TryComp(uid, out PhysicsComponent? physicsComponent)) if (!TryComp(uid, out PhysicsComponent? physicsComponent))
@@ -301,8 +306,8 @@ namespace Content.Server.Shuttles.Systems
var gridB = dockBXform.GridUid!.Value; var gridB = dockBXform.GridUid!.Value;
// May not be possible if map or the likes. // May not be possible if map or the likes.
if (TryComp<PhysicsComponent>(gridA, out var gridPhysicsA) && if (HasComp<PhysicsComponent>(gridA) &&
TryComp<PhysicsComponent>(gridB, out var gridPhysicsB)) HasComp<PhysicsComponent>(gridB))
{ {
SharedJointSystem.LinearStiffness( SharedJointSystem.LinearStiffness(
2f, 2f,
@@ -335,7 +340,7 @@ namespace Content.Server.Shuttles.Systems
joint.LocalAnchorA = anchorA; joint.LocalAnchorA = anchorA;
joint.LocalAnchorB = anchorB; joint.LocalAnchorB = anchorB;
joint.ReferenceAngle = (float) (gridBXform.WorldRotation - gridAXform.WorldRotation); joint.ReferenceAngle = (float) (_transform.GetWorldRotation(gridBXform) - _transform.GetWorldRotation(gridAXform));
joint.CollideConnected = true; joint.CollideConnected = true;
joint.Stiffness = stiffness; joint.Stiffness = stiffness;
joint.Damping = damping; joint.Damping = damping;
@@ -393,11 +398,9 @@ namespace Content.Server.Shuttles.Systems
RaiseLocalEvent(msg); 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) || if (!dockA.Enabled ||
!TryComp(dockB.Owner, out PhysicsComponent? bodyB) ||
!dockA.Enabled ||
!dockB.Enabled || !dockB.Enabled ||
dockA.DockedWith != null || dockA.DockedWith != null ||
dockB.DockedWith != null) dockB.DockedWith != null)
@@ -405,16 +408,16 @@ namespace Content.Server.Shuttles.Systems
return false; return false;
} }
var fixtureA = _fixtureSystem.GetFixtureOrNull(bodyA.Owner, DockingFixture); var fixtureA = _fixtureSystem.GetFixtureOrNull(dockAUid, DockingFixture);
var fixtureB = _fixtureSystem.GetFixtureOrNull(bodyB.Owner, DockingFixture); var fixtureB = _fixtureSystem.GetFixtureOrNull(dockBUid, DockingFixture);
if (fixtureA == null || fixtureB == null) if (fixtureA == null || fixtureB == null)
{ {
return false; return false;
} }
var transformA = _physics.GetPhysicsTransform(dockA.Owner); var transformA = _physics.GetPhysicsTransform(dockAUid);
var transformB = _physics.GetPhysicsTransform(dockB.Owner); var transformB = _physics.GetPhysicsTransform(dockBUid);
var intersect = false; var intersect = false;
for (var i = 0; i < fixtureA.Shape.ChildCount; i++) 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++) for (var j = 0; j < fixtureB.Shape.ChildCount; j++)
{ {
var otherAABB = fixtureB.Shape.ComputeAABB(transformB, 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 // TODO: Need collisionmanager's GJK for accurate checks don't @ me son
intersect = true; intersect = true;
break; break;
} }
if (intersect) break; if (intersect)
break;
} }
return intersect; return intersect;
@@ -442,19 +447,20 @@ namespace Content.Server.Shuttles.Systems
/// </summary> /// </summary>
private void TryDock(EntityUid dockAUid, DockingComponent dockA, EntityUid dockBUid, DockingComponent dockB) 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); Dock(dockAUid, dockA, dockBUid, dockB);
} }
public void Undock(DockingComponent dock) public void Undock(EntityUid dockUid, DockingComponent dock)
{ {
if (dock.DockedWith == null) if (dock.DockedWith == null)
return; return;
if (TryComp<AirlockComponent>(dock.Owner, out var airlockA)) if (TryComp<AirlockComponent>(dockUid, out var airlockA))
{ {
_airlocks.SetBoltsWithAudio(dock.Owner, airlockA, false); _airlocks.SetBoltsWithAudio(dockUid, airlockA, false);
} }
if (TryComp<AirlockComponent>(dock.DockedWith, out var airlockB)) if (TryComp<AirlockComponent>(dock.DockedWith, out var airlockB))
@@ -462,9 +468,9 @@ namespace Content.Server.Shuttles.Systems
_airlocks.SetBoltsWithAudio(dock.DockedWith.Value, airlockB, false); _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; doorA.ChangeAirtight = true;
} }
@@ -472,15 +478,15 @@ namespace Content.Server.Shuttles.Systems
if (TryComp(dock.DockedWith, out DoorComponent? doorB)) if (TryComp(dock.DockedWith, out DoorComponent? doorB))
{ {
if (_doorSystem.TryClose(doorB.Owner, doorB)) if (_doorSystem.TryClose(dock.DockedWith.Value, doorB))
{ {
doorB.ChangeAirtight = true; doorB.ChangeAirtight = true;
} }
} }
if (LifeStage(dock.Owner) < EntityLifeStage.Terminating) if (LifeStage(dockUid) < EntityLifeStage.Terminating)
{ {
var recentlyDocked = EnsureComp<RecentlyDockedComponent>(dock.Owner); var recentlyDocked = EnsureComp<RecentlyDockedComponent>(dockUid);
recentlyDocked.LastDocked = dock.DockedWith.Value; recentlyDocked.LastDocked = dock.DockedWith.Value;
} }
@@ -490,7 +496,7 @@ namespace Content.Server.Shuttles.Systems
recentlyDocked.LastDocked = dock.DockedWith.Value; recentlyDocked.LastDocked = dock.DockedWith.Value;
} }
Cleanup(dock); Cleanup(dockUid, dock);
} }
} }
} }

View File

@@ -361,12 +361,14 @@ public sealed partial class ShuttleSystem
private void SetDocks(EntityUid uid, bool enabled) private void SetDocks(EntityUid uid, bool enabled)
{ {
foreach (var (dock, xform) in EntityQuery<DockingComponent, TransformComponent>(true)) var query = AllEntityQuery<DockingComponent, TransformComponent>();
while (query.MoveNext(out var dockUid, out var dock, out var xform))
{ {
if (xform.ParentUid != uid || dock.Enabled == enabled) if (xform.ParentUid != uid || dock.Enabled == enabled)
continue; continue;
_dockSystem.Undock(dock); _dockSystem.Undock(dockUid, dock);
dock.Enabled = enabled; dock.Enabled = enabled;
} }
} }

View File

@@ -326,7 +326,7 @@ public abstract class SharedDoorSystem : EntitySystem
// since both closing/closed and welded are door states, we need to prevent 'closing' // 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 // 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; return false;
var ev = new BeforeDoorClosedEvent(door.PerformCollisionCheck); var ev = new BeforeDoorClosedEvent(door.PerformCollisionCheck);