From a5f1683f5451299f7b2d0c8972b551ebf258305b Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sun, 22 Oct 2023 16:53:39 +1100 Subject: [PATCH] RCD and tile placement fixes (#21132) --- Content.Shared/RCD/Systems/RCDSystem.cs | 18 +++++++++++++---- Content.Shared/Tiles/FloorTileSystem.cs | 27 ++++++++++++++++++------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Content.Shared/RCD/Systems/RCDSystem.cs b/Content.Shared/RCD/Systems/RCDSystem.cs index f94d155d97..ccc47a2fde 100644 --- a/Content.Shared/RCD/Systems/RCDSystem.cs +++ b/Content.Shared/RCD/Systems/RCDSystem.cs @@ -11,6 +11,7 @@ using Content.Shared.Physics; using Content.Shared.Popups; using Content.Shared.RCD.Components; using Content.Shared.Tag; +using Content.Shared.Tiles; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -22,17 +23,19 @@ namespace Content.Shared.RCD.Systems; public sealed class RCDSystem : EntitySystem { + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IMapManager _mapMan = default!; + [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefMan = default!; + [Dependency] private readonly FloorTileSystem _floors = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedChargesSystem _charges = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; - [Dependency] private readonly IMapManager _mapMan = default!; - [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly TagSystem _tag = default!; - [Dependency] private readonly ITileDefinitionManager _tileDefMan = default!; - [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly TurfSystem _turf = default!; private readonly int RcdModeCount = Enum.GetValues(typeof(RcdMode)).Length; @@ -156,10 +159,17 @@ public sealed class RCDSystem : EntitySystem var tile = mapGrid.GetTileRef(location); var snapPos = mapGrid.TileIndicesFor(location); + // I love that this uses entirely separate code to construction and tile placement!!! + switch (comp.Mode) { //Floor mode just needs the tile to be a space tile (subFloor) case RcdMode.Floors: + if (!_floors.CanPlaceTile(gridId.Value, mapGrid, out var reason)) + { + _popup.PopupClient(reason, user, user); + return; + } mapGrid.SetTile(snapPos, new Tile(_tileDefMan[comp.Floor].TileId)); _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to set grid: {tile.GridUid} {snapPos} to {comp.Floor}"); diff --git a/Content.Shared/Tiles/FloorTileSystem.cs b/Content.Shared/Tiles/FloorTileSystem.cs index bf757eb49e..dcf914ccf8 100644 --- a/Content.Shared/Tiles/FloorTileSystem.cs +++ b/Content.Shared/Tiles/FloorTileSystem.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Numerics; using Content.Shared.Administration.Logs; @@ -123,14 +124,10 @@ public sealed class FloorTileSystem : EntitySystem if (mapGrid != null) { var gridUid = mapGrid.Owner; - var ev = new FloorTileAttemptEvent(); - RaiseLocalEvent(mapGrid); - if (HasComp(gridUid) || ev.Cancelled) + if (!CanPlaceTile(gridUid, mapGrid, out var reason)) { - if (_netManager.IsClient && _timing.IsFirstTimePredicted) - _popup.PopupEntity(Loc.GetString("invalid-floor-placement"), args.User); - + _popup.PopupClient(reason, args.User, args.User); return; } @@ -177,9 +174,25 @@ public sealed class FloorTileSystem : EntitySystem { _adminLogger.Add(LogType.Tile, LogImpact.Low, $"{ToPrettyString(user):actor} placed tile {_tileDefinitionManager[tileId].Name} at {ToPrettyString(gridUid)} {location}"); - var variant = ((ContentTileDefinition) _tileDefinitionManager[tileId]).PickVariant(); + // TODO: Proper predicted RNG. + var variant = (byte) (_timing.CurTick.Value % ((ContentTileDefinition) _tileDefinitionManager[tileId]).Variants); mapGrid.SetTile(location.Offset(new Vector2(offset, offset)), new Tile(tileId, 0, variant)); _audio.PlayPredicted(placeSound, location, user, AudioHelpers.WithVariation(0.125f, _random)); } + + public bool CanPlaceTile(EntityUid gridUid, MapGridComponent component, [NotNullWhen(false)] out string? reason) + { + var ev = new FloorTileAttemptEvent(); + RaiseLocalEvent(gridUid, ref ev); + + if (HasComp(gridUid) || ev.Cancelled) + { + reason = Loc.GetString("invalid-floor-placement"); + return false; + } + + reason = null; + return true; + } } -- 2.51.2