diff --git a/Content.Server/SubFloor/SubFloorHideSystem.cs b/Content.Server/SubFloor/SubFloorHideSystem.cs index 1caaacb2ab..807607d241 100644 --- a/Content.Server/SubFloor/SubFloorHideSystem.cs +++ b/Content.Server/SubFloor/SubFloorHideSystem.cs @@ -1,7 +1,34 @@ +using Content.Server.Construction.Components; using Content.Shared.SubFloor; namespace Content.Server.SubFloor; public sealed class SubFloorHideSystem : SharedSubFloorHideSystem { + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAnchorAttempt); + SubscribeLocalEvent(OnUnanchorAttempt); + } + + private void OnAnchorAttempt(EntityUid uid, SubFloorHideComponent component, AnchorAttemptEvent args) + { + // No teleporting entities through floor tiles when anchoring them. + var xform = Transform(uid); + + if (MapManager.TryGetGrid(xform.GridID, out var grid) + && HasFloorCover(grid, grid.TileIndicesFor(xform.Coordinates))) + { + args.Cancel(); + } + } + + private void OnUnanchorAttempt(EntityUid uid, SubFloorHideComponent component, UnanchorAttemptEvent args) + { + // No un-anchoring things under the floor. Only required for something like vents, which are still interactable + // despite being partially under the floor. + if (component.IsUnderCover) + args.Cancel(); + } } diff --git a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs index 48ca7fb42e..1d048ee332 100644 --- a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs +++ b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs @@ -13,7 +13,7 @@ namespace Content.Shared.SubFloor [UsedImplicitly] public abstract class SharedSubFloorHideSystem : EntitySystem { - [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] protected readonly IMapManager MapManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly TrayScannerSystem _trayScannerSystem = default!; @@ -21,8 +21,8 @@ namespace Content.Shared.SubFloor { base.Initialize(); - _mapManager.GridChanged += MapManagerOnGridChanged; - _mapManager.TileChanged += MapManagerOnTileChanged; + MapManager.GridChanged += MapManagerOnGridChanged; + MapManager.TileChanged += MapManagerOnTileChanged; SubscribeLocalEvent(OnSubFloorStarted); SubscribeLocalEvent(OnSubFloorTerminating); @@ -34,8 +34,8 @@ namespace Content.Shared.SubFloor { base.Shutdown(); - _mapManager.GridChanged -= MapManagerOnGridChanged; - _mapManager.TileChanged -= MapManagerOnTileChanged; + MapManager.GridChanged -= MapManagerOnGridChanged; + MapManager.TileChanged -= MapManagerOnTileChanged; } private void OnInteractionAttempt(EntityUid uid, SubFloorHideComponent component, GettingInteractedWithAttemptEvent args) @@ -89,7 +89,7 @@ namespace Content.Shared.SubFloor if (e.NewTile.Tile.IsEmpty) return; // Anything that was here will be unanchored anyways. - UpdateTile(_mapManager.GetGrid(e.NewTile.GridIndex), e.NewTile.GridIndices); + UpdateTile(MapManager.GetGrid(e.NewTile.GridIndex), e.NewTile.GridIndices); } private void MapManagerOnGridChanged(object? sender, GridChangedEventArgs e) @@ -108,7 +108,7 @@ namespace Content.Shared.SubFloor if (!Resolve(uid, ref component, ref xform)) return; - if (xform.Anchored && _mapManager.TryGetGrid(xform.GridID, out var grid)) + if (xform.Anchored && MapManager.TryGetGrid(xform.GridID, out var grid)) component.IsUnderCover = HasFloorCover(grid, grid.TileIndicesFor(xform.Coordinates)); else component.IsUnderCover = false; @@ -116,7 +116,7 @@ namespace Content.Shared.SubFloor UpdateAppearance(uid, component); } - private bool HasFloorCover(IMapGrid grid, Vector2i position) + public bool HasFloorCover(IMapGrid grid, Vector2i position) { // TODO Redo this function. Currently wires on an asteroid are always "below the floor" var tileDef = (ContentTileDefinition) _tileDefinitionManager[grid.GetTileRef(position).Tile.TypeId]; diff --git a/Content.Shared/SubFloor/SubFloorHideComponent.cs b/Content.Shared/SubFloor/SubFloorHideComponent.cs index 710c2abf7f..22978276ba 100644 --- a/Content.Shared/SubFloor/SubFloorHideComponent.cs +++ b/Content.Shared/SubFloor/SubFloorHideComponent.cs @@ -24,7 +24,7 @@ namespace Content.Shared.SubFloor /// Whether interactions with this entity should be blocked while it is under floor tiles. /// /// - /// Useful for entities like vents, which are only partially hidden. + /// Useful for entities like vents, which are only partially hidden. Anchor attempts will still be blocked. /// [DataField("blockInteractions")] public bool BlockInteractions { get; set; } = true;