Files
RobustToolbox/Robust.Shared/GameObjects/Systems/SharedGridTraversalSystem.cs
f2625bf5c5 Removes IMapManager (#6584)
* Move MapManager queries to SharedMapSystem
Moves all variants of FindGridsIntersecting/TryFindGridAt to SharedMapSystem
Hollows out the MapManager methods and converts them into relays to SharedMapSystem

* Move CreateGrid to SharedMapSystem
Moves the functionality for CreateGrid and its variants to SharedMapSystem
Hollows out the MapManager methods and converts them into relays for the SharedMapSystem methods
Obsoletes them too
Also moves over the GetAllMapGrids and GetAllGrids methods

* Move RaiseOnTileChanged to SharedMapSystem
Also moves the SuppressOnTileChanged flag member to SharedMapSystem
Hollows out and obsoletes the MapManager versions

* Move default value constants to SharedMapSystem

* Converts map pausing events into LocalizedEntityCommands

* Move MapManager related delegates/structs to SharedMapSystem
Moves the GridCreationOptions struct to the same namespace as SharedMapSystem and converts it into a record struct
Move the GridCallback delegates to the same namespace as SharedMapSystem

* Move CullDeletionHistory to SharedMapSystem
Well, that was less painful than I thought it would be

* Actually obsolete the NetworkedMapManager method

* Rename file

* Doc comments for new SharedMapSystem methods

* Doc comment

* Doc comments

* Fix access

* Purge all references to IMapManagerInternal

* Cull easy IMapManager references

* The rest

* Purge IMapManager

* Private internal FindGridsIntersecting method

* please die

* 41

* notes

---------

Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
2026-07-01 19:32:17 -07:00

113 lines
3.7 KiB
C#

using System.Numerics;
using Robust.Shared.Audio.Components;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Robust.Shared.GameObjects;
/// <summary>
/// Handles moving entities between grids as they move around.
/// </summary>
public sealed partial class SharedGridTraversalSystem : EntitySystem
{
[Dependency] private SharedMapSystem _mapSystem = default!;
[Dependency] private SharedTransformSystem _transform = default!;
[Dependency] private IGameTiming _timing = default!;
private EntityUid _recursionGuard;
/// <summary>
/// Enables or disables changing grid / map uid upon moving.
/// WARNING: If you do this in a live-game. You need to make sure that the parented entity
/// doesn't move too far away from the grid. As it will cause Entity Lookups to not see it
/// (because the grid its parented to is not close enough and all parented entities are assumed
/// to be on the grid through the broadphase component)
/// </summary>
public bool Enabled = true;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<TransformStartupEvent>(OnStartup);
}
private void OnStartup(ref TransformStartupEvent ev)
{
CheckTraverse(ev.Entity);
}
internal void CheckTraverse(Entity<TransformComponent> entity)
{
if (!Enabled || _timing.ApplyingState)
return;
var uid = entity.Owner;
var xform = entity.Comp;
// Grid-traversal can result in a stack overflow. This is probably because of rounding errors when checking
// grid intersections using the map vs grid coordinates.
if (uid == _recursionGuard)
return;
// Don't run logic if:
// - Current parent is not a grid / map
// - Is anchored
// - Is a grid/map
// - Is in nullspace
if ((xform.GridUid != xform.ParentUid && xform.MapUid != xform.ParentUid)
|| xform.Anchored
|| uid == xform.GridUid
|| uid == xform.MapUid
|| xform.MapUid is not {} map
|| !xform.GridTraversal)
{
return;
}
if (_recursionGuard != EntityUid.Invalid)
{
Log.Error($"Grid traversal attempted to handle movement of {ToPrettyString(uid)} while moving {ToPrettyString(_recursionGuard)}");
return;
}
_recursionGuard = uid;
try
{
CheckTraversal(uid, xform, map);
}
finally
{
_recursionGuard = default;
}
}
public void CheckTraversal(EntityUid entity, TransformComponent xform, EntityUid map)
{
// TODO: This should probably check center of mass.
DebugTools.Assert(!HasComp<MapGridComponent>(entity));
DebugTools.Assert(!HasComp<MapComponent>(entity));
var mapPos = xform.ParentUid == xform.MapUid
? xform.LocalPosition
: Vector2.Transform(xform.LocalPosition, Transform(xform.ParentUid).LocalMatrix);
// Change parent if necessary
if (_mapSystem.TryFindGridAt(map, mapPos, out var gridUid, out _))
{
// Some minor duplication here with AttachParent but only happens when going on/off grid so not a big deal ATM.
if (gridUid != xform.GridUid && !TerminatingOrDeleted(gridUid))
_transform.SetParent(entity, xform, gridUid);
return;
}
// Attach them to map / they are on an invalid grid
if (xform.GridUid != null)
_transform.SetParent(entity, xform, map);
}
}