using System.Collections.Generic; using System.Linq; using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; namespace Robust.Shared.GameObjects { internal class SharedTransformSystem : EntitySystem { [Dependency] private readonly IMapManager _mapManager = default!; private readonly Queue _gridMoves = new(); private readonly Queue _otherMoves = new(); public override void Initialize() { base.Initialize(); _mapManager.TileChanged += MapManagerOnTileChanged; } public override void Shutdown() { _mapManager.TileChanged -= MapManagerOnTileChanged; base.Shutdown(); } private void MapManagerOnTileChanged(object? sender, TileChangedEventArgs e) { if(e.NewTile.Tile != Tile.Empty) return; var grid = _mapManager.GetGrid(e.NewTile.GridIndex); var tileIndices = e.NewTile.GridIndices; UnanchorAllEntsOnTile(grid, tileIndices); } private void UnanchorAllEntsOnTile(IMapGrid grid, Vector2i tileIndices) { var anchoredEnts = grid.GetAnchoredEntities(tileIndices); foreach (var ent in anchoredEnts.ToList()) // changing anchored modifies this set { if (!EntityManager.EntityExists(ent)) continue; ComponentManager.GetComponent(ent).Anchored = false; } } public void DeferMoveEvent(ref MoveEvent moveEvent) { if (moveEvent.Sender.HasComponent()) _gridMoves.Enqueue(moveEvent); else _otherMoves.Enqueue(moveEvent); } public override void Update(float frameTime) { base.Update(frameTime); // Process grid moves first. Process(_gridMoves); Process(_otherMoves); void Process(Queue queue) { while (queue.TryDequeue(out var ev)) { if (ev.Sender.Deleted) continue; // Hopefully we can remove this when PVS gets updated to not use NaNs if (!ev.NewPosition.IsValid(EntityManager)) { continue; } RaiseLocalEvent(ev.Sender.Uid, ref ev); } } } } }