Fix planet docking (#20104)

This commit is contained in:
metalgearsloth
2023-09-13 22:06:15 +10:00
committed by GitHub
parent 427a48d67d
commit 7dc3347181
4 changed files with 85 additions and 5 deletions

View File

@@ -185,6 +185,7 @@ namespace Content.IntegrationTests.Tests
var grids = mapManager.GetAllMapGrids(mapId).ToList(); var grids = mapManager.GetAllMapGrids(mapId).ToList();
var gridUids = grids.Select(o => o.Owner).ToList(); var gridUids = grids.Select(o => o.Owner).ToList();
targetGrid = gridUids.First();
foreach (var grid in grids) foreach (var grid in grids)
{ {

View File

@@ -1,9 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using Content.Server.Shuttles.Systems; using Content.Server.Shuttles.Systems;
using Content.Tests; using Content.Tests;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths; using Robust.Shared.Maths;
namespace Content.IntegrationTests.Tests.Shuttle; namespace Content.IntegrationTests.Tests.Shuttle;
@@ -80,4 +83,47 @@ public sealed class DockTest : ContentUnitTest
await pair.CleanReturnAsync(); await pair.CleanReturnAsync();
} }
[Test]
public async Task TestPlanetDock()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var map = await pair.CreateTestMap();
var otherMap = await pair.CreateTestMap();
var entManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var dockingSystem = entManager.System<DockingSystem>();
var xformSystem = entManager.System<SharedTransformSystem>();
var mapSystem = entManager.System<SharedMapSystem>();
var mapGrid = entManager.AddComponent<MapGridComponent>(map.MapUid);
var shuttle = EntityUid.Invalid;
// Spawn shuttle and affirm no valid docks.
await server.WaitAssertion(() =>
{
entManager.DeleteEntity(map.GridUid);
Assert.That(entManager.System<MapLoaderSystem>().TryLoad(otherMap.MapId, "/Maps/Shuttles/emergency.yml", out var rootUids));
shuttle = rootUids[0];
var dockingConfig = dockingSystem.GetDockingConfig(shuttle, map.MapUid);
Assert.That(dockingConfig, Is.EqualTo(null));
});
// Spawn dock and affirm it docks with no blockers / doesn't dock with blockers
await server.WaitAssertion(() =>
{
mapSystem.SetTile(map.MapUid, mapGrid, Vector2i.Zero, new Tile(1));
var airlockEnt = entManager.SpawnEntity("AirlockShuttle", new EntityCoordinates(map.MapUid, Vector2.One / 2f));
Assert.That(entManager.GetComponent<TransformComponent>(airlockEnt).Anchored);
var dockingConfig = dockingSystem.GetDockingConfig(shuttle, map.MapUid);
Assert.That(dockingConfig, Is.Not.EqualTo(null));
});
await pair.CleanReturnAsync();
}
} }

View File

@@ -46,6 +46,7 @@ public sealed partial class DockingSystem
Angle targetGridRotation, Angle targetGridRotation,
FixturesComponent shuttleFixtures, FixturesComponent shuttleFixtures,
MapGridComponent grid, MapGridComponent grid,
bool isMap,
out Matrix3 matty, out Matrix3 matty,
out Box2 shuttleDockedAABB, out Box2 shuttleDockedAABB,
out Angle gridRotation) out Angle gridRotation)
@@ -75,7 +76,7 @@ public sealed partial class DockingSystem
var gridXformMatrix = Matrix3.CreateTransform(gridDockXform.LocalPosition, gridDockAngle); var gridXformMatrix = Matrix3.CreateTransform(gridDockXform.LocalPosition, gridDockAngle);
Matrix3.Multiply(in stationDockMatrix, in gridXformMatrix, out matty); Matrix3.Multiply(in stationDockMatrix, in gridXformMatrix, out matty);
if (!ValidSpawn(grid, matty, offsetAngle, shuttleFixtures)) if (!ValidSpawn(grid, matty, offsetAngle, shuttleFixtures, isMap))
return false; return false;
shuttleDockedAABB = matty.TransformBox(shuttleAABB); shuttleDockedAABB = matty.TransformBox(shuttleAABB);
@@ -136,6 +137,8 @@ public sealed partial class DockingSystem
var shuttleFixturesComp = Comp<FixturesComponent>(shuttleUid); var shuttleFixturesComp = Comp<FixturesComponent>(shuttleUid);
var shuttleAABB = Comp<MapGridComponent>(shuttleUid).LocalAABB; var shuttleAABB = Comp<MapGridComponent>(shuttleUid).LocalAABB;
var isMap = HasComp<MapComponent>(targetGrid);
var validDockConfigs = new List<DockingConfig>(); var validDockConfigs = new List<DockingConfig>();
if (shuttleDocks.Count > 0) if (shuttleDocks.Count > 0)
{ {
@@ -155,6 +158,7 @@ public sealed partial class DockingSystem
targetGridAngle, targetGridAngle,
shuttleFixturesComp, shuttleFixturesComp,
targetGridGrid, targetGridGrid,
isMap,
out var matty, out var matty,
out var dockedAABB, out var dockedAABB,
out var targetAngle)) out var targetAngle))
@@ -205,6 +209,7 @@ public sealed partial class DockingSystem
shuttleAABB, shuttleAABB,
targetGridAngle, targetGridAngle,
shuttleFixturesComp, targetGridGrid, shuttleFixturesComp, targetGridGrid,
isMap,
out _, out _,
out var otherdockedAABB, out var otherdockedAABB,
out var otherTargetAngle)) out var otherTargetAngle))
@@ -255,9 +260,9 @@ public sealed partial class DockingSystem
} }
/// <summary> /// <summary>
/// Checks whether the emergency shuttle can warp to the specified position. /// Checks whether the shuttle can warp to the specified position.
/// </summary> /// </summary>
private bool ValidSpawn(MapGridComponent grid, Matrix3 matty, Angle angle, FixturesComponent shuttleFixturesComp) private bool ValidSpawn(MapGridComponent grid, Matrix3 matty, Angle angle, FixturesComponent shuttleFixturesComp, bool isMap)
{ {
var transform = new Transform(matty.Transform(Vector2.Zero), angle); var transform = new Transform(matty.Transform(Vector2.Zero), angle);
@@ -268,8 +273,32 @@ public sealed partial class DockingSystem
var aabb = polyShape.ComputeAABB(transform, 0); var aabb = polyShape.ComputeAABB(transform, 0);
aabb = aabb.Enlarged(-0.01f); aabb = aabb.Enlarged(-0.01f);
if (grid.GetLocalTilesIntersecting(aabb).Any()) // If it's a map check no hard collidable anchored entities overlap
return false; if (isMap)
{
foreach (var tile in grid.GetLocalTilesIntersecting(aabb))
{
var anchoredEnumerator = grid.GetAnchoredEntitiesEnumerator(tile.GridIndices);
while (anchoredEnumerator.MoveNext(out var anc))
{
if (!_physicsQuery.TryGetComponent(anc, out var physics) ||
!physics.CanCollide ||
!physics.Hard)
{
continue;
}
return false;
}
}
}
// If it's not a map check it doesn't overlap the grid.
else
{
if (grid.GetLocalTilesIntersecting(aabb).Any())
return false;
}
} }
return true; return true;

View File

@@ -32,9 +32,13 @@ namespace Content.Server.Shuttles.Systems
private const string DockingJoint = "docking"; private const string DockingJoint = "docking";
private const float DockingRadius = 0.20f; private const float DockingRadius = 0.20f;
private EntityQuery<PhysicsComponent> _physicsQuery;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_physicsQuery = GetEntityQuery<PhysicsComponent>();
SubscribeLocalEvent<DockingComponent, ComponentStartup>(OnStartup); SubscribeLocalEvent<DockingComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<DockingComponent, ComponentShutdown>(OnShutdown); SubscribeLocalEvent<DockingComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<DockingComponent, AnchorStateChangedEvent>(OnAnchorChange); SubscribeLocalEvent<DockingComponent, AnchorStateChangedEvent>(OnAnchorChange);