using JetBrains.Annotations;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Robust.Shared.GameObjects
{
[UsedImplicitly]
internal class SnapGridSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
///
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent(HandleComponentStartup);
SubscribeLocalEvent(HandleComponentShutdown);
SubscribeLocalEvent(HandleMoveEvent);
}
private void HandleComponentStartup(EntityUid uid, SnapGridComponent component, ComponentStartup args)
{
var transform = ComponentManager.GetComponent(uid);
UpdatePosition(uid, transform, component);
}
private void HandleComponentShutdown(EntityUid uid, SnapGridComponent component, ComponentShutdown args)
{
if (component.LastGrid == GridId.Invalid)
return;
var transform = ComponentManager.GetComponent(uid);
if (_mapManager.TryGetGrid(component.LastGrid, out var grid))
{
var indices = grid.TileIndicesFor(transform.WorldPosition);
grid.RemoveFromSnapGridCell(indices, uid);
return;
}
component.LastGrid = GridId.Invalid;
}
private void HandleMoveEvent(EntityUid uid, SnapGridComponent component, MoveEvent args)
{
var transform = ComponentManager.GetComponent(uid);
UpdatePosition(uid, transform, component);
}
private void UpdatePosition(EntityUid euid, ITransformComponent transform, SnapGridComponent snapComp)
{
if (snapComp.LastGrid != GridId.Invalid)
{
if (!_mapManager.TryGetGrid(snapComp.LastGrid, out var lastGrid))
{
Logger.WarningS("go.comp.snapgrid", "Entity {0} snapgrid didn't find grid {1}. Race condition?", euid, transform.GridID);
return;
}
lastGrid.RemoveFromSnapGridCell(snapComp.LastTileIndices, euid);
}
if (!_mapManager.TryGetGrid(transform.GridID, out var grid))
{
// Either a race condition, or we're not on any grids.
return;
}
var oldPos = snapComp.LastTileIndices;
var oldGrid = snapComp.LastGrid;
var newPos = grid.TileIndicesFor(transform.MapPosition);
var newGrid = transform.GridID;
grid.AddToSnapGridCell(newPos, euid);
if (oldPos != newPos || oldGrid != newGrid)
{
RaiseLocalEvent(euid, new SnapGridPositionChangedEvent(newPos, oldPos, newGrid, oldGrid));
}
snapComp.LastTileIndices = newPos;
snapComp.LastGrid = newGrid;
}
}
public class SnapGridPositionChangedEvent : EntityEventArgs
{
public GridId OldGrid { get; }
public GridId NewGrid { get; }
public bool SameGrid => OldGrid == NewGrid;
public Vector2i OldPosition { get; }
public Vector2i Position { get; }
public SnapGridPositionChangedEvent(Vector2i position, Vector2i oldPosition, GridId newGrid, GridId oldGrid)
{
Position = position;
OldPosition = oldPosition;
NewGrid = newGrid;
OldGrid = oldGrid;
}
}
}