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 xformQuery = GetEntityQuery<TransformComponent>();
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))
{
@@ -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<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;
}
if (!xformQuery.TryGetComponent(comp.LastDocked, out var otherXform))
{
RemComp<RecentlyDockedComponent>(comp.Owner);
RemCompDeferred<RecentlyDockedComponent>(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<RecentlyDockedComponent>(comp.Owner);
_sawmill.Debug($"Removed RecentlyDocked from {ToPrettyString(uid)} and {ToPrettyString(comp.LastDocked)}");
RemComp<RecentlyDockedComponent>(uid);
RemComp<RecentlyDockedComponent>(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)

View File

@@ -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<ShuttleComponent>(grid.Owner))
if (!HasComp<ShuttleComponent>(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<MetaDataComponent>(uid).EntityLifeStage > EntityLifeStage.MapInitialized) return;
Cleanup(component);
EntityManager.GetComponent<MetaDataComponent>(uid).EntityLifeStage > EntityLifeStage.MapInitialized)
{
return;
}
private void Cleanup(DockingComponent dockA)
Cleanup(uid, component);
}
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<TransformComponent>(dockA.Owner).GridUid;
var gridBUid = EntityManager.GetComponent<TransformComponent>(dockB.Owner).GridUid;
DebugTools.Assert(gridAUid != null);
DebugTools.Assert(gridBUid != null);
var gridAUid = EntityManager.GetComponent<TransformComponent>(dockAUid).GridUid;
var gridBUid = EntityManager.GetComponent<TransformComponent>(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<DockingComponent>(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<DockingComponent>(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<PhysicsComponent>(gridA, out var gridPhysicsA) &&
TryComp<PhysicsComponent>(gridB, out var gridPhysicsB))
if (HasComp<PhysicsComponent>(gridA) &&
HasComp<PhysicsComponent>(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
/// </summary>
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<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))
@@ -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<RecentlyDockedComponent>(dock.Owner);
var recentlyDocked = EnsureComp<RecentlyDockedComponent>(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);
}
}
}

View File

@@ -361,12 +361,14 @@ public sealed partial class ShuttleSystem
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)
continue;
_dockSystem.Undock(dock);
_dockSystem.Undock(dockUid, dock);
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'
// 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);