fix bluespace shelter capsules (#3674)

Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
deltanedas 2025-05-07 22:15:58 +01:00 committed by GitHub
parent a39db2e065
commit 895b9ae6ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 41 additions and 8 deletions

View File

@ -9,6 +9,7 @@ using Content.Shared.Maps;
using Content.Shared.Physics;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
using System.Numerics;
@ -22,11 +23,18 @@ public sealed class ShelterCapsuleSystem : SharedShelterCapsuleSystem
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SmokeSystem _smoke = default!;
[Dependency] private readonly TurfSystem _turf = default!;
public EntProtoId SmokePrototype = "Smoke";
public static readonly EntProtoId SmokePrototype = "Smoke";
private HashSet<Entity<TransformComponent>> _entities = new();
private EntityQuery<FixturesComponent> _fixturesQuery;
private HashSet<EntityUid> _entities = new();
public override void Initialize()
{
base.Initialize();
_fixturesQuery = GetEntityQuery<FixturesComponent>();
}
protected override LocId? TrySpawnRoom(Entity<ShelterCapsuleComponent> ent)
{
@ -34,13 +42,16 @@ public sealed class ShelterCapsuleSystem : SharedShelterCapsuleSystem
if (xform.GridUid is not {} gridUid || !TryComp<MapGridComponent>(gridUid, out var grid))
return "shelter-capsule-error-space";
var gridXform = Transform(gridUid);
var center = _map.LocalToTile(gridUid, grid, xform.Coordinates);
var room = _proto.Index(ent.Comp.Room);
var origin = center - room.Size / 2;
// check that every tile it needs isn't blocked
var mask = CollisionGroup.MobMask;
var mask = (int) CollisionGroup.MobMask;
if (IsAreaBlocked(gridUid, center, room.Size, mask))
return "shelter-capsule-error-obstructed";
// check that it isn't on space or SpawnRoom will crash
for (int y = 0; y < room.Size.Y; y++)
{
for (int x = 0; x < room.Size.X; x++)
@ -49,9 +60,6 @@ public sealed class ShelterCapsuleSystem : SharedShelterCapsuleSystem
var tile = _map.GetTileRef((gridUid, grid), pos);
if (tile.Tile.IsEmpty)
return "shelter-capsule-error-space";
if (_turf.IsTileBlocked(gridUid, pos, mask, grid, gridXform))
return "shelter-capsule-error-obstructed";
}
}
@ -73,4 +81,29 @@ public sealed class ShelterCapsuleSystem : SharedShelterCapsuleSystem
QueueDel(ent);
return null;
}
private bool IsAreaBlocked(EntityUid grid, Vector2i center, Vector2i size, int mask)
{
// This is scaled to 95 % so it doesn't encompass walls on other tiles.
var aabb = Box2.CenteredAround(center, size * 0.95f);
_entities.Clear();
_lookup.GetLocalEntitiesIntersecting(grid, aabb, _entities, LookupFlags.Dynamic | LookupFlags.Static);
foreach (var uid in _entities)
{
// don't care about non-physical entities
if (!_fixturesQuery.TryComp(uid, out var fixtures))
continue;
foreach (var fixture in fixtures.Fixtures.Values)
{
if (!fixture.Hard)
continue;
if ((fixture.CollisionLayer & mask) != 0)
return true;
}
}
return false; // no entities colliding with the mask found
}
}