Allow protected grids to be repaired (#36989)
* Allow protected grids to be repaired * Probably implement it --------- Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -395,7 +395,7 @@ public sealed class RCDSystem : EntitySystem
|
|||||||
if (prototype.Mode == RcdMode.ConstructTile)
|
if (prototype.Mode == RcdMode.ConstructTile)
|
||||||
{
|
{
|
||||||
// Check rule: Tile placement is valid
|
// Check rule: Tile placement is valid
|
||||||
if (!_floors.CanPlaceTile(gridUid, mapGrid, out var reason))
|
if (!_floors.CanPlaceTile(gridUid, mapGrid, tile.GridIndices, out var reason))
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(reason, uid, user);
|
_popup.PopupClient(reason, uid, user);
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ namespace Content.Shared.Tiles;
|
|||||||
/// Raised directed on a grid when attempting a floor tile placement.
|
/// Raised directed on a grid when attempting a floor tile placement.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct FloorTileAttemptEvent(bool Cancelled);
|
public record struct FloorTileAttemptEvent(Vector2i GridIndices, bool Cancelled = false);
|
||||||
|
|||||||
@@ -126,14 +126,14 @@ public sealed class FloorTileSystem : EntitySystem
|
|||||||
if (mapGrid != null)
|
if (mapGrid != null)
|
||||||
{
|
{
|
||||||
var gridUid = location.EntityId;
|
var gridUid = location.EntityId;
|
||||||
|
var tile = _map.GetTileRef(gridUid, mapGrid, location);
|
||||||
|
|
||||||
if (!CanPlaceTile(gridUid, mapGrid, out var reason))
|
if (!CanPlaceTile(gridUid, mapGrid, tile.GridIndices, out var reason))
|
||||||
{
|
{
|
||||||
_popup.PopupClient(reason, args.User, args.User);
|
_popup.PopupClient(reason, args.User, args.User);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tile = _map.GetTileRef(gridUid, mapGrid, location);
|
|
||||||
var baseTurf = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
|
var baseTurf = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
|
||||||
|
|
||||||
if (HasBaseTurf(currentTileDefinition, baseTurf.ID))
|
if (HasBaseTurf(currentTileDefinition, baseTurf.ID))
|
||||||
@@ -182,12 +182,12 @@ public sealed class FloorTileSystem : EntitySystem
|
|||||||
_audio.PlayPredicted(placeSound, location, user);
|
_audio.PlayPredicted(placeSound, location, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanPlaceTile(EntityUid gridUid, MapGridComponent component, [NotNullWhen(false)] out string? reason)
|
public bool CanPlaceTile(EntityUid gridUid, MapGridComponent component, Vector2i gridIndices, [NotNullWhen(false)] out string? reason)
|
||||||
{
|
{
|
||||||
var ev = new FloorTileAttemptEvent();
|
var ev = new FloorTileAttemptEvent(gridIndices);
|
||||||
RaiseLocalEvent(gridUid, ref ev);
|
RaiseLocalEvent(gridUid, ref ev);
|
||||||
|
|
||||||
if (HasComp<ProtectedGridComponent>(gridUid) || ev.Cancelled)
|
if (ev.Cancelled)
|
||||||
{
|
{
|
||||||
reason = Loc.GetString("invalid-floor-placement");
|
reason = Loc.GetString("invalid-floor-placement");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -5,8 +5,13 @@ namespace Content.Shared.Tiles;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prevents floor tile updates when attached to a grid.
|
/// Prevents floor tile updates when attached to a grid.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
[Access(typeof(ProtectedGridSystem))]
|
||||||
public sealed partial class ProtectedGridComponent : Component
|
public sealed partial class ProtectedGridComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A bitmask of all the initial tiles on this grid.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public Dictionary<Vector2i, ulong> BaseIndices = new();
|
||||||
}
|
}
|
||||||
|
|||||||
70
Content.Shared/Tiles/ProtectedGridSystem.cs
Normal file
70
Content.Shared/Tiles/ProtectedGridSystem.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Robust.Shared.Map.Components;
|
||||||
|
using Robust.Shared.Map.Enumerators;
|
||||||
|
|
||||||
|
namespace Content.Shared.Tiles;
|
||||||
|
|
||||||
|
public sealed class ProtectedGridSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly SharedMapSystem _map = default!;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<ProtectedGridComponent, MapInitEvent>(OnMapInit);
|
||||||
|
SubscribeLocalEvent<ProtectedGridComponent, FloorTileAttemptEvent>(OnFloorTileAttempt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMapInit(Entity<ProtectedGridComponent> ent, ref MapInitEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<MapGridComponent>(ent, out var grid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Engine default is currently 16x size chunks which means we can't just easily have 64bit flags.
|
||||||
|
var chunkEnumerator = new ChunkIndicesEnumerator(grid.LocalAABB, 8);
|
||||||
|
|
||||||
|
while (chunkEnumerator.MoveNext(out var chunk))
|
||||||
|
{
|
||||||
|
ulong flag = 0;
|
||||||
|
|
||||||
|
for (var x = 0; x < 8; x++)
|
||||||
|
{
|
||||||
|
for (var y = 0; y < 8; y++)
|
||||||
|
{
|
||||||
|
var index = new Vector2i(x + chunk.Value.X * 8, y + chunk.Value.Y * 8);
|
||||||
|
var tile = _map.GetTileRef(ent.Owner, grid, index);
|
||||||
|
|
||||||
|
if (tile.Tile.IsEmpty)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var data = SharedMapSystem.ToBitmask(new Vector2i(x, y));
|
||||||
|
|
||||||
|
flag |= data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ent.Comp.BaseIndices[chunk.Value] = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dirty(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnFloorTileAttempt(Entity<ProtectedGridComponent> ent, ref FloorTileAttemptEvent args)
|
||||||
|
{
|
||||||
|
var chunkOrigin = SharedMapSystem.GetChunkIndices(args.GridIndices, 8);
|
||||||
|
|
||||||
|
if (!ent.Comp.BaseIndices.TryGetValue(chunkOrigin, out var data))
|
||||||
|
{
|
||||||
|
args.Cancelled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SharedMapSystem.FromBitmask(args.GridIndices, data))
|
||||||
|
{
|
||||||
|
args.Cancelled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user