From 43f4f075144ed1b49792e46c0bb4a461c055dd9f Mon Sep 17 00:00:00 2001 From: Milon Date: Sat, 23 Nov 2024 00:37:37 +0100 Subject: [PATCH 1/3] slightly less terrible shit --- .../_EE/FootPrint/FootPrintsSystem.cs | 140 +++++++++++++++++- 1 file changed, 138 insertions(+), 2 deletions(-) diff --git a/Content.Server/_EE/FootPrint/FootPrintsSystem.cs b/Content.Server/_EE/FootPrint/FootPrintsSystem.cs index b30a721b93b..f751698ac08 100644 --- a/Content.Server/_EE/FootPrint/FootPrintsSystem.cs +++ b/Content.Server/_EE/FootPrint/FootPrintsSystem.cs @@ -1,4 +1,6 @@ -using Content.Server.Atmos.Components; +using System.Linq; +using System.Numerics; // DeltaV +using Content.Server.Atmos.Components; using Content.Shared._EE.FootPrint; using Content.Shared.Inventory; using Content.Shared.Mobs; @@ -7,7 +9,9 @@ // using Content.Shared.Standing; using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.GameTicking; // DeltaV using Robust.Shared.Map; +using Robust.Shared.Map.Components; // DeltaV using Robust.Shared.Random; namespace Content.Server._EE.FootPrint; @@ -21,6 +25,16 @@ public sealed class FootPrintsSystem : EntitySystem [Dependency] private readonly SharedSolutionContainerSystem _solution = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; // DeltaV + + // DeltaV - Max amount of footprints per tile + // Not stored on the component because its convenient here + private const int MaxFootprintsPerTile = 2; + + /// + /// DeltaV: Dictionary tracking footprints per tile using tile coordinates as key + /// + private readonly Dictionary> _footprintsPerTile = new(); private EntityQuery _transformQuery; private EntityQuery _mobThresholdQuery; @@ -38,6 +52,10 @@ public override void Initialize() SubscribeLocalEvent(OnStartupComponent); SubscribeLocalEvent(OnMove); + SubscribeLocalEvent(OnFootPrintInit); // DeltaV + SubscribeLocalEvent(OnFootPrintRemove); // DeltaV + SubscribeLocalEvent(OnGridTerminating); // DeltaV + SubscribeLocalEvent(OnRoundEnd); // DeltaV } private void OnStartupComponent(EntityUid uid, FootPrintsComponent component, ComponentStartup args) @@ -62,7 +80,12 @@ private void OnMove(EntityUid uid, FootPrintsComponent component, ref MoveEvent component.RightStep = !component.RightStep; - var entity = Spawn(component.StepProtoId, CalcCoords(gridUid, component, transform, dragging)); + // DeltaV - Check if we've hit the footprint limit for this tile before spawning + var coords = CalcCoords(gridUid, component, transform, dragging); + if (!ShouldCreateNewFootprint(coords)) + return; + + var entity = Spawn(component.StepProtoId, coords); var footPrintComponent = EnsureComp(entity); footPrintComponent.PrintOwner = uid; @@ -92,6 +115,119 @@ private void OnMove(EntityUid uid, FootPrintsComponent component, ref MoveEvent _solution.TryAddReagent(footPrintComponent.Solution.Value, component.ReagentToTransfer, 1, out _); } + /// + /// DeltaV: Checks if a new footprint can be created at the specified coordinates based on the per-tile limit. + /// + /// True if a new footprint can be created, false if the tile is full or invalid + private bool ShouldCreateNewFootprint(EntityCoordinates coords) + { + if (!coords.IsValid(EntityManager)) + return false; + + var mapCoords = _transform.ToMapCoordinates(coords); + + if (!_map.TryFindGridAt(mapCoords, out var gridUid, out var grid)) + return false; + + var tilePos = _mapSystem.CoordinatesToTile(gridUid, grid, coords); + return !_footprintsPerTile.TryGetValue(tilePos, out var footprints) || footprints.Count < MaxFootprintsPerTile; + } + + /// + /// DeltaV: Handles the initialization of a footprint component. + /// + private void OnFootPrintInit(Entity ent, ref ComponentInit args) + { + if (!TryGetTilePos(ent.Owner, out var tilePos)) + return; + + if (!_footprintsPerTile.TryGetValue(tilePos, out var footprints)) + { + footprints = new Queue(); + _footprintsPerTile[tilePos] = footprints; + } + + footprints.Enqueue(ent); + + // If we've exceeded the limit, remove the oldest footprint + if (footprints.Count > MaxFootprintsPerTile) + { + var oldestFootprint = footprints.Dequeue(); + if (Exists(oldestFootprint)) + QueueDel(oldestFootprint); + } + } + + /// + /// DeltaV: Handles cleanup when a footprint component is removed. + /// + private void OnFootPrintRemove(Entity ent, ref ComponentRemove args) + { + if (!TryGetTilePos(ent.Owner, out var tilePos)) + return; + + if (_footprintsPerTile.TryGetValue(tilePos, out var footprints)) + { + // Create a new queue without the removed footprint + var newQueue = new Queue(footprints.Where(x => x != ent.Owner)); + if (newQueue.Count > 0) + _footprintsPerTile[tilePos] = newQueue; + else + _footprintsPerTile.Remove(tilePos); + } + } + + /// + /// DeltaV: Handles cleanup when a grid is being terminated, removing all footprint tracking data from that grid. + /// + private void OnGridTerminating(Entity ent, ref EntityTerminatingEvent args) + { + // Find and remove all footprints that belong to this grid's tiles + var toRemove = new List(); + + foreach (var (pos, footprints) in _footprintsPerTile) + { + // Convert position to map coordinates to check if it belongs to this grid + var mapCoords = _transform.ToMapCoordinates(new EntityCoordinates(ent, + new Vector2(pos.X * ent.Comp.TileSize, pos.Y * ent.Comp.TileSize))); + + if (_map.TryFindGridAt(mapCoords, out var gridUid, out _) && gridUid == ent.Owner) + { + toRemove.Add(pos); + } + } + + foreach (var pos in toRemove) + { + _footprintsPerTile.Remove(pos); + } + } + + /// + /// DeltaV: Attempts to get the tile position for a given entity. + /// + private bool TryGetTilePos(EntityUid uid, out Vector2i tilePos) + { + tilePos = default; + + var coords = new EntityCoordinates(Transform(uid).ParentUid, Transform(uid).LocalPosition); + var mapCoords = _transform.ToMapCoordinates(coords); + + if (!_map.TryFindGridAt(mapCoords, out var gridUid, out var grid)) + return false; + + tilePos = _mapSystem.CoordinatesToTile(gridUid, grid, coords); + return true; + } + + /// + /// DeltaV: Clean up the dict on round end + /// + private void OnRoundEnd(RoundRestartCleanupEvent ev) + { + _footprintsPerTile.Clear(); + } + private EntityCoordinates CalcCoords(EntityUid uid, FootPrintsComponent component, TransformComponent transform, bool state) { if (state) From a273f31a6b78be87d424844ec33601e0e688d963 Mon Sep 17 00:00:00 2001 From: Milon Date: Sat, 23 Nov 2024 00:56:31 +0100 Subject: [PATCH 2/3] comment ops --- Content.Server/_EE/FootPrint/FootPrintsSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/_EE/FootPrint/FootPrintsSystem.cs b/Content.Server/_EE/FootPrint/FootPrintsSystem.cs index f751698ac08..4024316ac3b 100644 --- a/Content.Server/_EE/FootPrint/FootPrintsSystem.cs +++ b/Content.Server/_EE/FootPrint/FootPrintsSystem.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; // DeltaV using System.Numerics; // DeltaV using Content.Server.Atmos.Components; using Content.Shared._EE.FootPrint; From 0b94f7ccbfaec0fb87e9f67ec7e198a0ce52bfb7 Mon Sep 17 00:00:00 2001 From: Milon Date: Sat, 23 Nov 2024 01:34:02 +0100 Subject: [PATCH 3/3] FUCKING ENTITYTEST --- .../_EE/FootPrint/FootPrintsSystem.cs | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/Content.Server/_EE/FootPrint/FootPrintsSystem.cs b/Content.Server/_EE/FootPrint/FootPrintsSystem.cs index 4024316ac3b..65bfdc765ba 100644 --- a/Content.Server/_EE/FootPrint/FootPrintsSystem.cs +++ b/Content.Server/_EE/FootPrint/FootPrintsSystem.cs @@ -163,17 +163,35 @@ private void OnFootPrintInit(Entity ent, ref ComponentInit a /// private void OnFootPrintRemove(Entity ent, ref ComponentRemove args) { - if (!TryGetTilePos(ent.Owner, out var tilePos)) - return; + // Try to get tile pos if entity is still valid + Vector2i? tilePos = null; + if (!Deleted(ent) && !EntityManager.IsQueuedForDeletion(ent) && Transform(ent).ParentUid.IsValid()) + { + TryGetTilePos(ent.Owner, out var pos); + tilePos = pos; + } + + // If we couldn't get tile pos, search all tiles to find and remove this footprint + if (tilePos == null) + { + foreach (var (pos, prints) in _footprintsPerTile) + { + if (!prints.Contains(ent.Owner)) + continue; + + tilePos = pos; + break; + } + } - if (_footprintsPerTile.TryGetValue(tilePos, out var footprints)) + // Clean up the footprint tracking if we found it + if (tilePos.HasValue && _footprintsPerTile.TryGetValue(tilePos.Value, out var footprints)) { - // Create a new queue without the removed footprint var newQueue = new Queue(footprints.Where(x => x != ent.Owner)); if (newQueue.Count > 0) - _footprintsPerTile[tilePos] = newQueue; + _footprintsPerTile[tilePos.Value] = newQueue; else - _footprintsPerTile.Remove(tilePos); + _footprintsPerTile.Remove(tilePos.Value); } }