var grids = mapManager.GetAllMapGrids(mapId).ToList();
var gridUids = grids.Select(o => o.Owner).ToList();
+ targetGrid = gridUids.First();
foreach (var grid in grids)
{
using System.Collections.Generic;
+using System.Linq;
using System.Numerics;
using Content.Server.Shuttles.Systems;
using Content.Tests;
+using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
+using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
namespace Content.IntegrationTests.Tests.Shuttle;
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();
+ }
}
Angle targetGridRotation,
FixturesComponent shuttleFixtures,
MapGridComponent grid,
+ bool isMap,
out Matrix3 matty,
out Box2 shuttleDockedAABB,
out Angle gridRotation)
var gridXformMatrix = Matrix3.CreateTransform(gridDockXform.LocalPosition, gridDockAngle);
Matrix3.Multiply(in stationDockMatrix, in gridXformMatrix, out matty);
- if (!ValidSpawn(grid, matty, offsetAngle, shuttleFixtures))
+ if (!ValidSpawn(grid, matty, offsetAngle, shuttleFixtures, isMap))
return false;
shuttleDockedAABB = matty.TransformBox(shuttleAABB);
var shuttleFixturesComp = Comp<FixturesComponent>(shuttleUid);
var shuttleAABB = Comp<MapGridComponent>(shuttleUid).LocalAABB;
+ var isMap = HasComp<MapComponent>(targetGrid);
+
var validDockConfigs = new List<DockingConfig>();
if (shuttleDocks.Count > 0)
{
targetGridAngle,
shuttleFixturesComp,
targetGridGrid,
+ isMap,
out var matty,
out var dockedAABB,
out var targetAngle))
shuttleAABB,
targetGridAngle,
shuttleFixturesComp, targetGridGrid,
+ isMap,
out _,
out var otherdockedAABB,
out var otherTargetAngle))
}
/// <summary>
- /// Checks whether the emergency shuttle can warp to the specified position.
+ /// Checks whether the shuttle can warp to the specified position.
/// </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 aabb = polyShape.ComputeAABB(transform, 0);
aabb = aabb.Enlarged(-0.01f);
- if (grid.GetLocalTilesIntersecting(aabb).Any())
- return false;
+ // If it's a map check no hard collidable anchored entities overlap
+ 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;
private const string DockingJoint = "docking";
private const float DockingRadius = 0.20f;
+ private EntityQuery<PhysicsComponent> _physicsQuery;
+
public override void Initialize()
{
base.Initialize();
+ _physicsQuery = GetEntityQuery<PhysicsComponent>();
+
SubscribeLocalEvent<DockingComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<DockingComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<DockingComponent, AnchorStateChangedEvent>(OnAnchorChange);