]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Kills TurfHelpers (#37939)
authorTemporalOroboros <TemporalOroboros@gmail.com>
Sat, 21 Jun 2025 15:23:19 +0000 (08:23 -0700)
committerGitHub <noreply@github.com>
Sat, 21 Jun 2025 15:23:19 +0000 (11:23 -0400)
* Create TurfSystem equivalent for and obsolete TurfHelpers.GetTileRef

* Fix EntitySystem uses of TurfHelpers.GetTileRef

* Fix EntitySystem uses of TurfHelpers.TryGetTileRef

* Fix construction condition uses of TurfHelpers.GetTileRef

* Fix last use of TurfHelpers.IsBlockedTurf

* Create TurfSystem equivalent to and obsolete TurfHelpers.GetContentTileDefinition

* Fix uses of TurfHelpers.GetContentTileDefinition(TileRef)

* Fix uses of TurfHelpers.GetContentTileDefinition(Tile)

* Create TurfSystem equivalent to and obsolete TurfHelpers.IsSpace

* Fix EntitySystem uses of TurfHelpers.IsSpace(Tile)

* Fix EntitySystem uses of TurfHelpers.IsSpace(TileRef)

* Fix remaining uses of TurfHelpers.IsSpace

* Fix uses of TurfHelpers.GetEntitiesInTile

* Delete TurfHelpers.cs

* Add GetEntitiesInTile lookup methods

* Convert some GetEntitiesInTile methods to LookupSystem extension methods

* Use new GetEntitiesInTile methods

* Recycle spiderweb hashset

* Recycle floor tile hashset

37 files changed:
Content.Client/Mapping/MappingState.cs
Content.Server/Abilities/Mime/MimePowersSystem.cs
Content.Server/Administration/Commands/VariantizeCommand.cs
Content.Server/Chemistry/TileReactions/CreateEntityTileReaction.cs
Content.Server/Construction/Conditions/ComponentInTile.cs
Content.Server/Decals/Commands/AddDecalCommand.cs
Content.Server/Decals/DecalSystem.cs
Content.Server/Dragon/DragonSystem.cs
Content.Server/Electrocution/ElectrocutionSystem.cs
Content.Server/EntityEffects/EntityEffectSystem.cs
Content.Server/Explosion/EntitySystems/SmokeOnTriggerSystem.cs
Content.Server/Fluids/EntitySystems/PuddleSystem.cs
Content.Server/Nuke/NukeSystem.cs
Content.Server/Physics/Controllers/ConveyorController.cs
Content.Server/Pinpointer/NavMapSystem.cs
Content.Server/Procedural/DungeonJob/DungeonJob.Exterior.cs
Content.Server/Procedural/DungeonJob/DungeonJob.cs
Content.Server/Procedural/DungeonSystem.cs
Content.Server/Respawn/SpecialRespawnSystem.cs
Content.Server/Revenant/EntitySystems/RevenantSystem.cs
Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs
Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs
Content.Server/Shuttles/Systems/ShuttleSystem.cs
Content.Server/Shuttles/Systems/ThrusterSystem.cs
Content.Server/Spider/SpiderSystem.cs
Content.Server/Spreader/SpreaderSystem.cs
Content.Server/Worldgen/Systems/Debris/SimpleFloorPlanPopulatorSystem.cs
Content.Shared/Abilities/Goliath/GoliathTentacleSystem.cs
Content.Shared/Blocking/BlockingSystem.cs
Content.Shared/Construction/Conditions/TileNotBlocked.cs
Content.Shared/Construction/Conditions/TileType.cs
Content.Shared/Magic/SharedMagicSystem.cs
Content.Shared/Maps/TurfHelpers.cs [deleted file]
Content.Shared/Maps/TurfSystem.cs
Content.Shared/RCD/Systems/RCDSystem.cs
Content.Shared/Sound/SharedEmitSoundSystem.cs
Content.Shared/Tiles/FloorTileSystem.cs

index 6430f1db1e039a60487495a130df682a46dba829..97fbee70bc6ca1e36f8ef4263db92967fbe3781e 100644 (file)
@@ -793,7 +793,7 @@ public sealed class MappingState : GameplayStateBase
 
             if (_mapMan.TryFindGridAt(mapPos, out var gridUid, out var grid) &&
                 _entityManager.System<SharedMapSystem>().TryGetTileRef(gridUid, grid, coords, out var tileRef) &&
-                _allPrototypesDict.TryGetValue(tileRef.GetContentTileDefinition(), out button))
+                _allPrototypesDict.TryGetValue(_entityManager.System<TurfSystem>().GetContentTileDefinition(tileRef), out button))
             {
                 OnSelected(button);
                 return true;
index 3de356f608202c14d56b63d67a08ec16d274dd1b..29c7b1710c2505660f864a2b7f4eefd5fd12e703 100644 (file)
@@ -82,7 +82,7 @@ namespace Content.Server.Abilities.Mime
             // Get the tile in front of the mime
             var offsetValue = xform.LocalRotation.ToWorldVec();
             var coords = xform.Coordinates.Offset(offsetValue).SnapToGrid(EntityManager, _mapMan);
-            var tile = coords.GetTileRef(EntityManager, _mapMan);
+            var tile = _turf.GetTileRef(coords);
             if (tile == null)
                 return;
 
index 3f9b7efd07ed49b999c03b06c2f413f3556a6928..a75f72b1c7da00c2c3919f5184a9bd1cd8e1c6b5 100644 (file)
@@ -10,7 +10,6 @@ namespace Content.Server.Administration.Commands;
 public sealed class VariantizeCommand : IConsoleCommand
 {
     [Dependency] private readonly IEntityManager _entManager = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
 
     public string Command => "variantize";
 
@@ -40,10 +39,11 @@ public sealed class VariantizeCommand : IConsoleCommand
 
         var mapsSystem = _entManager.System<SharedMapSystem>();
         var tileSystem = _entManager.System<TileSystem>();
+        var turfSystem = _entManager.System<TurfSystem>();
 
         foreach (var tile in mapsSystem.GetAllTiles(euid.Value, gridComp))
         {
-            var def = tile.GetContentTileDefinition(_tileDefManager);
+            var def = turfSystem.GetContentTileDefinition(tile);
             var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, tileSystem.PickVariant(def));
             mapsSystem.SetTile(euid.Value, gridComp, tile.GridIndices, newTile);
         }
index 0249b6255a2d98e597727535228c2e237b20f376..1499967a42218325146686f996f2b32edb868511 100644 (file)
@@ -41,33 +41,33 @@ public sealed partial class CreateEntityTileReaction : ITileReaction
         IEntityManager entityManager,
         List<ReagentData>? data)
     {
-        if (reactVolume >= Usage)
+        if (reactVolume < Usage)
+            return FixedPoint2.Zero;
+
+        if (Whitelist != null)
         {
-            if (Whitelist != null)
+            var lookup = entityManager.System<EntityLookupSystem>();
+
+            int acc = 0;
+            foreach (var ent in lookup.GetEntitiesInTile(tile, LookupFlags.Static))
             {
-                int acc = 0;
-                foreach (var ent in tile.GetEntitiesInTile())
-                {
-                    var whitelistSystem = entityManager.System<EntityWhitelistSystem>();
-                    if (whitelistSystem.IsWhitelistPass(Whitelist, ent))
-                        acc += 1;
+                var whitelistSystem = entityManager.System<EntityWhitelistSystem>();
+                if (whitelistSystem.IsWhitelistPass(Whitelist, ent))
+                    acc += 1;
 
-                    if (acc >= MaxOnTile)
-                        return FixedPoint2.Zero;
-                }
+                if (acc >= MaxOnTile)
+                    return FixedPoint2.Zero;
             }
+        }
 
-            var random = IoCManager.Resolve<IRobustRandom>();
-            var xoffs = random.NextFloat(-RandomOffsetMax, RandomOffsetMax);
-            var yoffs = random.NextFloat(-RandomOffsetMax, RandomOffsetMax);
-
-            var center = entityManager.System<TurfSystem>().GetTileCenter(tile);
-            var pos = center.Offset(new Vector2(xoffs, yoffs));
-            entityManager.SpawnEntity(Entity, pos);
+        var random = IoCManager.Resolve<IRobustRandom>();
+        var xoffs = random.NextFloat(-RandomOffsetMax, RandomOffsetMax);
+        var yoffs = random.NextFloat(-RandomOffsetMax, RandomOffsetMax);
 
-            return Usage;
-        }
+        var center = entityManager.System<TurfSystem>().GetTileCenter(tile);
+        var pos = center.Offset(new Vector2(xoffs, yoffs));
+        entityManager.SpawnEntity(Entity, pos);
 
-        return FixedPoint2.Zero;
+        return Usage;
     }
 }
index 429c4fdabfc95b965144ef548366617cb1fe53f2..6af8c36e24194a619dc3bd8c6efe1c7d5f516cd9 100644 (file)
@@ -58,9 +58,7 @@ namespace Content.Server.Construction.Conditions
             if (!entityManager.System<SharedMapSystem>().TryGetTileRef(transform.GridUid.Value, grid, indices, out var tile))
                 return !HasEntity;
 
-            var entities = tile.GetEntitiesInTile(LookupFlags.Approximate | LookupFlags.Static, lookup);
-
-            foreach (var ent in entities)
+            foreach (var ent in lookup.GetEntitiesInTile(tile, flags: LookupFlags.Approximate | LookupFlags.Static))
             {
                 if (entityManager.HasComponent(ent, type))
                     return HasEntity;
index 2d9c5a1b254b0f81bb4b2524a8bae22a0d849248..e7463ff9cbaaf481e64df9e83d51b295d6d621e3 100644 (file)
@@ -54,8 +54,9 @@ namespace Content.Server.Decals.Commands
             }
 
             var mapSystem = _entManager.System<MapSystem>();
+            var turfSystem = _entManager.System<TurfSystem>();
             var coordinates = new EntityCoordinates(gridIdRaw.Value, new Vector2(x, y));
-            if (mapSystem.GetTileRef(gridIdRaw.Value, grid, coordinates).IsSpace())
+            if (turfSystem.IsSpace(mapSystem.GetTileRef(gridIdRaw.Value, grid, coordinates)))
             {
                 shell.WriteError($"Cannot create decal on space tile at {coordinates}.");
                 return;
index 690d24c2e4e8435c56d65ef1c3b7cddac0252a85..bc77900df7734038602d3dc9657f6ecbcecfc04a 100644 (file)
@@ -29,7 +29,6 @@ namespace Content.Server.Decals
     {
         [Dependency] private readonly IPlayerManager _playerManager = default!;
         [Dependency] private readonly IAdminManager _adminManager = default!;
-        [Dependency] private readonly ITileDefinitionManager _tileDefMan = default!;
         [Dependency] private readonly IParallelManager _parMan = default!;
         [Dependency] private readonly ChunkingSystem _chunking = default!;
         [Dependency] private readonly IConfigurationManager _conf = default!;
@@ -37,6 +36,7 @@ namespace Content.Server.Decals
         [Dependency] private readonly IAdminLogManager _adminLogger = default!;
         [Dependency] private readonly SharedMapSystem _mapSystem = default!;
         [Dependency] private readonly SharedTransformSystem _transform = default!;
+        [Dependency] private readonly TurfSystem _turf = default!;
 
         private readonly Dictionary<NetEntity, HashSet<Vector2i>> _dirtyChunks = new();
         private readonly Dictionary<ICommonSession, Dictionary<NetEntity, HashSet<Vector2i>>> _previousSentChunks = new();
@@ -167,7 +167,7 @@ namespace Content.Server.Decals
 
             foreach (var change in args.Changes)
             {
-                if (!change.NewTile.IsSpace(_tileDefMan))
+                if (!_turf.IsSpace(change.NewTile))
                     continue;
 
                 var indices = GetChunkIndices(change.GridIndices);
@@ -308,7 +308,7 @@ namespace Content.Server.Decals
             if (!TryComp(gridId, out MapGridComponent? grid))
                 return false;
 
-            if (_mapSystem.GetTileRef(gridId.Value, grid, coordinates).IsSpace(_tileDefMan))
+            if (_turf.IsSpace(_mapSystem.GetTileRef(gridId.Value, grid, coordinates)))
                 return false;
 
             if (!TryComp(gridId, out DecalGridComponent? comp))
index efac049b354d1ad789c5b8db7d799be9fcd171ce..960365a7ca1cbee293ef81ea66a2af74f38ebfaf 100644 (file)
@@ -21,7 +21,6 @@ namespace Content.Server.Dragon;
 public sealed partial class DragonSystem : EntitySystem
 {
     [Dependency] private readonly CarpRiftsConditionSystem _carpRifts = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDef = default!;
     [Dependency] private readonly MovementSpeedModifierSystem _movement = default!;
     [Dependency] private readonly NpcFactionSystem _faction = default!;
     [Dependency] private readonly PopupSystem _popup = default!;
@@ -30,6 +29,7 @@ public sealed partial class DragonSystem : EntitySystem
     [Dependency] private readonly SharedTransformSystem _transform = default!;
     [Dependency] private readonly SharedMapSystem _map = default!;
     [Dependency] private readonly MobStateSystem _mobState = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     private EntityQuery<CarpRiftsConditionComponent> _objQuery;
 
@@ -159,7 +159,7 @@ public sealed partial class DragonSystem : EntitySystem
         // cant put a rift on solars
         foreach (var tile in _map.GetTilesIntersecting(xform.GridUid.Value, grid, new Circle(_transform.GetWorldPosition(xform), RiftTileRadius), false))
         {
-            if (!tile.IsSpace(_tileDef))
+            if (!_turf.IsSpace(tile))
                 continue;
 
             _popup.PopupEntity(Loc.GetString("carp-rift-space-proximity", ("proximity", RiftTileRadius)), uid, uid);
index 957f881bed4962773a833f6ea69af4f86f3e34e8..8647f087fc68d9ca093ca917a498383a64cd65bc 100644 (file)
@@ -57,6 +57,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
     [Dependency] private readonly SharedStutteringSystem _stuttering = default!;
     [Dependency] private readonly TagSystem _tag = default!;
     [Dependency] private readonly MetaDataSystem _metaData = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     [ValidatePrototypeId<StatusEffectPrototype>]
     private const string StatusEffectKey = "Electrocution";
@@ -137,7 +138,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
             return false;
         if (electrified.NoWindowInTile)
         {
-            var tileRef = transform.Coordinates.GetTileRef(EntityManager, _mapManager);
+            var tileRef = _turf.GetTileRef(transform.Coordinates);
 
             if (tileRef != null)
             {
index 164199c2002b45366587c0208f21658145f0d526..03a0c8bb2b7d89784932d7fdf146ade179007e15 100644 (file)
@@ -74,6 +74,7 @@ public sealed class EntityEffectSystem : EntitySystem
     [Dependency] private readonly TemperatureSystem _temperature = default!;
     [Dependency] private readonly SharedTransformSystem _xform = default!;
     [Dependency] private readonly VomitSystem _vomit = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     public override void Initialize()
     {
@@ -529,7 +530,7 @@ public sealed class EntityEffectSystem : EntitySystem
                 return;
             }
 
-            if (_spreader.RequiresFloorToSpread(args.Effect.PrototypeId) && tileRef.Tile.IsSpace())
+            if (_spreader.RequiresFloorToSpread(args.Effect.PrototypeId) && _turf.IsSpace(tileRef))
                 return;
 
             var coords = _map.MapToGrid(gridUid, mapCoords);
index 31b4746ec21c1f5b11a93b51a9c36b6059f8e20e..19335d3446c4c11fb0b87c18a9539a79789cfbc0 100644 (file)
@@ -20,6 +20,7 @@ public sealed class SmokeOnTriggerSystem : SharedSmokeOnTriggerSystem
     [Dependency] private readonly SmokeSystem _smoke = default!;
     [Dependency] private readonly TransformSystem _transform = default!;
     [Dependency] private readonly SpreaderSystem _spreader = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     public override void Initialize()
     {
@@ -39,7 +40,7 @@ public sealed class SmokeOnTriggerSystem : SharedSmokeOnTriggerSystem
             return;
         }
 
-        if (_spreader.RequiresFloorToSpread(comp.SmokePrototype.ToString()) && tileRef.Tile.IsSpace())
+        if (_spreader.RequiresFloorToSpread(comp.SmokePrototype.ToString()) && _turf.IsSpace(tileRef))
             return;
 
         var coords = _map.MapToGrid(gridUid, mapCoords);
index 94951b01136e53fe283d2713839e2b48b85346b7..bb7b06bd0b7b80e1587a912527d5d1b16f9d53c4 100644 (file)
@@ -47,7 +47,6 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
     [Dependency] private readonly SharedMapSystem _map = default!;
     [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefMan = default!;
     [Dependency] private readonly AudioSystem _audio = default!;
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
     [Dependency] private readonly ReactiveSystem _reactive = default!;
@@ -59,6 +58,7 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
     [Dependency] private readonly SpeedModifierContactsSystem _speedModContacts = default!;
     [Dependency] private readonly TileFrictionController _tile = default!;
     [Dependency] private readonly SharedTransformSystem _transform = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     [ValidatePrototypeId<ReagentPrototype>]
     private const string Blood = "Blood";
@@ -686,7 +686,7 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
         }
 
         // If space return early, let that spill go out into the void
-        if (tileRef.Tile.IsEmpty || tileRef.IsSpace(_tileDefMan))
+        if (tileRef.Tile.IsEmpty || _turf.IsSpace(tileRef))
         {
             puddleUid = EntityUid.Invalid;
             return false;
index 77be71f7bcba5e60337414f31b1f51d163e48022..81fbf074da8886c15131868e8ac3b0a2a29e4c24 100644 (file)
@@ -32,7 +32,6 @@ public sealed class NukeSystem : EntitySystem
     [Dependency] private readonly ChatSystem _chatSystem = default!;
     [Dependency] private readonly ExplosionSystem _explosions = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
     [Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
     [Dependency] private readonly NavMapSystem _navMap = default!;
     [Dependency] private readonly PointLightSystem _pointLight = default!;
@@ -45,6 +44,7 @@ public sealed class NukeSystem : EntitySystem
     [Dependency] private readonly StationSystem _station = default!;
     [Dependency] private readonly UserInterfaceSystem _ui = default!;
     [Dependency] private readonly AppearanceSystem _appearance = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     /// <summary>
     ///     Used to calculate when the nuke song should start playing for maximum kino with the nuke sfx
@@ -210,7 +210,7 @@ public sealed class NukeSystem : EntitySystem
 
             foreach (var tile in _map.GetTilesIntersecting(xform.GridUid.Value, grid, new Circle(worldPos, component.RequiredFloorRadius), false))
             {
-                if (!tile.IsSpace(_tileDefManager))
+                if (!_turf.IsSpace(tile))
                     continue;
 
                 var msg = Loc.GetString("nuke-component-cant-anchor-floor");
index fa278278e27dcd2a472c1988137730ad34d1f087..9ec05be9b79fc2373a996709f8ab078a32bb6fdf 100644 (file)
@@ -19,6 +19,7 @@ public sealed class ConveyorController : SharedConveyorController
     [Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
     [Dependency] private readonly MaterialReclaimerSystem _materialReclaimer = default!;
     [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     public override void Initialize()
     {
@@ -123,7 +124,7 @@ public sealed class ConveyorController : SharedConveyorController
 
         var xform = ent.Comp;
 
-        var beltTileRef = xform.Coordinates.GetTileRef(EntityManager, MapManager);
+        var beltTileRef = _turf.GetTileRef(xform.Coordinates);
 
         if (beltTileRef != null)
         {
index 7511e60cdec860a32e48383d981a47a3f2b0c459..89e2837b3579a8631e26a17af745868db71f1768 100644 (file)
@@ -28,7 +28,7 @@ public sealed partial class NavMapSystem : SharedNavMapSystem
     [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
     [Dependency] private readonly IMapManager _mapManager = default!;
     [Dependency] private readonly IGameTiming _gameTiming = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
+    [Dependency] private readonly TurfSystem _turfSystem = default!;
 
     public const float CloseDistance = 15f;
     public const float FarDistance = 30f;
@@ -118,7 +118,7 @@ public sealed partial class NavMapSystem : SharedNavMapSystem
             var relative = SharedMapSystem.GetChunkRelative(tile, ChunkSize);
             ref var tileData = ref chunk.TileData[GetTileIndex(relative)];
 
-            if (change.NewTile.IsSpace(_tileDefManager))
+            if (_turfSystem.IsSpace(change.NewTile))
             {
                 tileData = 0;
                 if (PruneEmpty((ev.Entity, navMap), chunk))
index 92237dca2a1678bd6264d364f1ffa7da4b8270df..4f2f564dedbaab9d93f574a82da0a0191130f2c3 100644 (file)
@@ -30,7 +30,7 @@ public sealed partial class DungeonJob
         SharedPathfindingSystem.GridCast(startTile, position, tile =>
         {
             if (!_maps.TryGetTileRef(_gridUid, _grid, tile, out var tileRef) ||
-                tileRef.Tile.IsSpace(_tileDefManager))
+                _turf.IsSpace(tileRef.Tile))
             {
                 return true;
             }
index f2bd5a4394cc635fb05d2b1fce355a2efb5094a8..77404fc963c17f6c673ec6477a51bb85f1f93b95 100644 (file)
@@ -42,6 +42,7 @@ public sealed partial class DungeonJob : Job<List<Dungeon>>
     private readonly EntityTableSystem _entTable;
     private readonly TagSystem _tags;
     private readonly TileSystem _tile;
+    private readonly TurfSystem _turf;
     private readonly SharedMapSystem _maps;
     private readonly SharedTransformSystem _transform;
 
@@ -70,6 +71,7 @@ public sealed partial class DungeonJob : Job<List<Dungeon>>
         DungeonSystem dungeon,
         EntityLookupSystem lookup,
         TileSystem tile,
+        TurfSystem turf,
         SharedTransformSystem transform,
         DungeonConfig gen,
         MapGridComponent grid,
@@ -89,6 +91,7 @@ public sealed partial class DungeonJob : Job<List<Dungeon>>
         _dungeon = dungeon;
         _lookup = lookup;
         _tile = tile;
+        _turf = turf;
         _tags = _entManager.System<TagSystem>();
         _maps = _entManager.System<SharedMapSystem>();
         _entTable = _entManager.System<EntityTableSystem>();
index 9cc3fbb1585068b020ae841d7b891edb7c8f3d23..3a0a7ab2cdb90cef141a13434ee3e571d6877046 100644 (file)
@@ -36,6 +36,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
     [Dependency] private readonly DecalSystem _decals = default!;
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
     [Dependency] private readonly TileSystem _tile = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
     [Dependency] private readonly MapLoaderSystem _loader = default!;
     [Dependency] private readonly SharedMapSystem _maps = default!;
     [Dependency] private readonly SharedTransformSystem _transform = default!;
@@ -212,6 +213,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
             this,
             _lookup,
             _tile,
+            _turf,
             _transform,
             gen,
             grid,
@@ -244,6 +246,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
             this,
             _lookup,
             _tile,
+            _turf,
             _transform,
             gen,
             grid,
index cde0fd2aa00aa197c7823bfcc09a3749494e1a62..45229b74185f1cd0a4abfbab87e138aa2c0f4e06 100644 (file)
@@ -17,7 +17,6 @@ namespace Content.Server.Respawn;
 public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
 {
     [Dependency] private readonly IAdminLogManager _adminLog = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
     [Dependency] private readonly AtmosphereSystem _atmosphere = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly SharedTransformSystem _transform = default!;
@@ -108,7 +107,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
 
             foreach (var tile in _map.GetTilesIntersecting(entityGridUid.Value, grid, circle))
             {
-                if (tile.IsSpace(_tileDefinitionManager)
+                if (_turf.IsSpace(tile)
                     || _turf.IsTileBlocked(tile, CollisionGroup.MobMask)
                     || !_atmosphere.IsTileMixtureProbablySafe(entityGridUid, entityMapUid.Value,
                         _map.TileIndicesFor((entityGridUid.Value, grid), mapPos)))
@@ -179,7 +178,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
 
             foreach (var newTileRef in _map.GetTilesIntersecting(targetGrid, grid, circle))
             {
-                if (newTileRef.IsSpace(_tileDefinitionManager) || _turf.IsTileBlocked(newTileRef, CollisionGroup.MobMask) || !_atmosphere.IsTileMixtureProbablySafe(targetGrid, targetMap, mapTarget))
+                if (_turf.IsSpace(newTileRef) || _turf.IsTileBlocked(newTileRef, CollisionGroup.MobMask) || !_atmosphere.IsTileMixtureProbablySafe(targetGrid, targetMap, mapTarget))
                     continue;
 
                 found = true;
index b319db09e0653a0fd30dcc9df599ad40495c4e14..0501f5afc3ee810971d5c37488c24ba581f42f8a 100644 (file)
@@ -45,6 +45,7 @@ public sealed partial class RevenantSystem : EntitySystem
     [Dependency] private readonly StoreSystem _store = default!;
     [Dependency] private readonly TagSystem _tag = default!;
     [Dependency] private readonly VisibilitySystem _visibility = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     [ValidatePrototypeId<EntityPrototype>]
     private const string RevenantShopId = "ActionRevenantShop";
@@ -164,7 +165,7 @@ public sealed partial class RevenantSystem : EntitySystem
             return false;
         }
 
-        var tileref = Transform(uid).Coordinates.GetTileRef();
+        var tileref = _turf.GetTileRef(Transform(uid).Coordinates);
         if (tileref != null)
         {
             if(_physics.GetEntitiesIntersectingBody(uid, (int) CollisionGroup.Impassable).Count > 0)
index 2fc11db4a49d2fe72d67868bca6429ec851e8149..13e13bf8f371fb996d6c6442fd920f9cb77c4982 100644 (file)
@@ -679,7 +679,7 @@ public sealed partial class ShuttleSystem
         // only toss if its on lattice/space
         var tile = _mapSystem.GetTileRef(shuttleEntity, shuttleGrid, childXform.Coordinates);
 
-        if (!tile.IsSpace(_tileDefManager))
+        if (!_turf.IsSpace(tile))
             return;
 
         var throwDirection = childXform.LocalPosition - shuttleBody.LocalCenter;
index f165990f1cacc0b0516d80cf271c8b33d5a6ea4c..29657af295f18f6a0a1a0a6bf8a6fb9cb77eedc4 100644 (file)
@@ -275,7 +275,7 @@ public sealed partial class ShuttleSystem
 
         foreach (var tileRef in _mapSystem.GetLocalTilesIntersecting(uid, grid, new Circle(centerTile, radius)))
         {
-            var def = (ContentTileDefinition)_tileDefManager[tileRef.Tile.TypeId];
+            var def = _turf.GetContentTileDefinition(tileRef);
             mass += def.Mass;
             tileCount++;
 
@@ -402,7 +402,7 @@ public sealed partial class ShuttleSystem
                 continue;
 
             // Mark tiles for breaking/effects
-            var def = (ContentTileDefinition)_tileDefManager[_mapSystem.GetTileRef(uid, grid, tileData.Tile).Tile.TypeId];
+            var def = _turf.GetContentTileDefinition(_mapSystem.GetTileRef(uid, grid, tileData.Tile));
             if (tileData.Energy > def.Mass * _tileBreakEnergyMultiplier)
                 brokenTiles.Add((tileData.Tile, Tile.Empty));
 
index 71d51e3187ba96304c1d1f939d06a8a908632191..f271be108f15d245af79965d6411f1360d9b96a9 100644 (file)
@@ -28,6 +28,7 @@ using Robust.Shared.Physics.Systems;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 using Robust.Shared.Timing;
+using Content.Shared.Maps;
 
 namespace Content.Server.Shuttles.Systems;
 
@@ -40,7 +41,6 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
     [Dependency] private readonly IMapManager _mapManager = default!;
     [Dependency] private readonly IPrototypeManager _protoManager = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
     [Dependency] private readonly BiomeSystem _biomes = default!;
     [Dependency] private readonly BodySystem _bobby = default!;
     [Dependency] private readonly BuckleSystem _buckle = default!;
@@ -62,6 +62,7 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
     [Dependency] private readonly ThrowingSystem _throwing = default!;
     [Dependency] private readonly ThrusterSystem _thruster = default!;
     [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     private EntityQuery<BuckleComponent> _buckleQuery;
     private EntityQuery<MapGridComponent> _gridQuery;
index 42c249c9abaf3f5907a889e5fdbc073a0913ed96..e7f93043cbcebf195d9ee815c24d2e08129aecec 100644 (file)
@@ -26,13 +26,13 @@ namespace Content.Server.Shuttles.Systems;
 public sealed class ThrusterSystem : EntitySystem
 {
     [Dependency] private readonly IGameTiming _timing = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
     [Dependency] private readonly SharedMapSystem _mapSystem = default!;
     [Dependency] private readonly AmbientSoundSystem _ambient = default!;
     [Dependency] private readonly FixtureSystem _fixtureSystem = default!;
     [Dependency] private readonly DamageableSystem _damageable = default!;
     [Dependency] private readonly SharedPointLightSystem _light = default!;
     [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     // Essentially whenever thruster enables we update the shuttle's available impulses which are used for movement.
     // This is done for each direction available.
@@ -97,7 +97,7 @@ public sealed class ThrusterSystem : EntitySystem
         foreach (var change in args.Changes)
         {
             // If the old tile was space but the new one isn't then disable all adjacent thrusters
-            if (change.NewTile.IsSpace(_tileDefManager) || !change.OldTile.IsSpace(_tileDefManager))
+            if (_turf.IsSpace(change.NewTile) || !_turf.IsSpace(change.OldTile))
                 continue;
 
             var tilePos = change.GridIndices;
@@ -457,7 +457,7 @@ public sealed class ThrusterSystem : EntitySystem
         var mapGrid = Comp<MapGridComponent>(xform.GridUid.Value);
         var tile = _mapSystem.GetTileRef(xform.GridUid.Value, mapGrid, new Vector2i((int)Math.Floor(x), (int)Math.Floor(y)));
 
-        return tile.Tile.IsSpace();
+        return _turf.IsSpace(tile);
     }
 
     #region Burning
index 449e43984c3749aae5a1ac7203a0e6e6de844bf0..6e2e2b59a20de38542b85fa2848fb5da5b87e1cf 100644 (file)
@@ -10,6 +10,13 @@ namespace Content.Server.Spider;
 public sealed class SpiderSystem : SharedSpiderSystem
 {
     [Dependency] private readonly PopupSystem _popup = default!;
+    [Dependency] private readonly EntityLookupSystem _lookup = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
+
+    /// <summary>
+    ///     A recycled hashset used to check turfs for spiderwebs.
+    /// </summary>
+    private readonly HashSet<EntityUid> _webs = [];
 
     public override void Initialize()
     {
@@ -66,7 +73,9 @@ public sealed class SpiderSystem : SharedSpiderSystem
 
     private bool IsTileBlockedByWeb(EntityCoordinates coords)
     {
-        foreach (var entity in coords.GetEntitiesInTile())
+        _webs.Clear();
+        _turf.GetEntitiesInTile(coords, _webs);
+        foreach (var entity in _webs)
         {
             if (HasComp<SpiderWebObjectComponent>(entity))
                 return true;
index 50f5d81183b6d327c037477edb724b2fa39831e3..328f4f0504c76ed3626718234cb34d12a8a3c84d 100644 (file)
@@ -23,6 +23,7 @@ public sealed class SpreaderSystem : EntitySystem
     [Dependency] private readonly IRobustRandom _robustRandom = default!;
     [Dependency] private readonly SharedMapSystem _map = default!;
     [Dependency] private readonly TagSystem _tag = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     /// <summary>
     /// Cached maximum number of updates per spreader prototype. This is applied per-grid.
@@ -246,7 +247,7 @@ public sealed class SpreaderSystem : EntitySystem
             if (!_map.TryGetTileRef(neighborEnt, neighborGrid, neighborPos, out var tileRef) || tileRef.Tile.IsEmpty)
                 continue;
 
-            if (spreaderPrototype.PreventSpreadOnSpaced && tileRef.Tile.IsSpace())
+            if (spreaderPrototype.PreventSpreadOnSpaced && _turf.IsSpace(tileRef))
                 continue;
 
             var directionEnumerator = _map.GetAnchoredEntitiesEnumerator(neighborEnt, neighborGrid, neighborPos);
index ed260531142ea65e4c92dcac4e032a3ab3aeb21b..e936d550bbf1dd339d246271ea1f9f211182e3f7 100644 (file)
@@ -14,6 +14,7 @@ public sealed class SimpleFloorPlanPopulatorSystem : BaseWorldSystem
     [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly ITileDefinitionManager _tileDefinition = default!;
     [Dependency] private readonly SharedMapSystem _map = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     /// <inheritdoc />
     public override void Initialize()
@@ -30,7 +31,7 @@ public sealed class SimpleFloorPlanPopulatorSystem : BaseWorldSystem
         while (enumerator.MoveNext(out var tile))
         {
             var coords = _map.GridTileToLocal(uid, grid, tile.Value.GridIndices);
-            var selector = tile.Value.Tile.GetContentTileDefinition(_tileDefinition).ID;
+            var selector = _turf.GetContentTileDefinition(tile.Value).ID;
             if (!component.Caches.TryGetValue(selector, out var cache))
                 continue;
 
index e0a0453285853c72a260d45edec754b8b5bf4394..a220781420abe2f292bdb88a24f03667d5c9e256 100644 (file)
@@ -55,7 +55,7 @@ public sealed class GoliathTentacleSystem : EntitySystem
         foreach (var pos in spawnPos)
         {
             if (!_map.TryGetTileRef(grid, gridComp, pos, out var tileRef) ||
-                tileRef.IsSpace() ||
+                _turf.IsSpace(tileRef) ||
                 _turf.IsTileBlocked(tileRef, CollisionGroup.Impassable))
             {
                 continue;
index c920fde13b0561944e6c35d0f27b530ce3276ad7..619adf7918a3f1f96e6fcb4090a80c733ed485ba 100644 (file)
@@ -31,6 +31,7 @@ public sealed partial class BlockingSystem : EntitySystem
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
     [Dependency] private readonly ExamineSystemShared _examine = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     public override void Initialize()
     {
@@ -165,7 +166,7 @@ public sealed partial class BlockingSystem : EntitySystem
         }
 
         //Don't allow someone to block if someone else is on the same tile
-        var playerTileRef = xform.Coordinates.GetTileRef();
+        var playerTileRef = _turf.GetTileRef(xform.Coordinates);
         if (playerTileRef != null)
         {
             var intersecting = _lookup.GetLocalEntitiesIntersecting(playerTileRef.Value, 0f);
index 02bc84f736225ca04af44fc68090594ea682869a..c56dcb15838cac4e308efc233e0777ead793edef 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Shared.Maps;
+using Content.Shared.Physics;
 using JetBrains.Annotations;
 using Robust.Shared.Map;
 
@@ -14,24 +15,25 @@ public sealed partial class TileNotBlocked : IConstructionCondition
 
     public bool Condition(EntityUid user, EntityCoordinates location, Direction direction)
     {
-        var tileRef = location.GetTileRef();
+        if (!IoCManager.Resolve<IEntityManager>().TrySystem<TurfSystem>(out var turfSystem))
+            return false;
 
-        if (tileRef == null)
+        if (!turfSystem.TryGetTileRef(location, out var tileRef))
         {
             return false;
         }
 
-        if (tileRef.Value.IsSpace() && _failIfSpace)
+        if (turfSystem.IsSpace(tileRef.Value) && _failIfSpace)
         {
             return false;
         }
 
-        if (!tileRef.Value.GetContentTileDefinition().Sturdy && _failIfNotSturdy)
+        if (!turfSystem.GetContentTileDefinition(tileRef.Value).Sturdy && _failIfNotSturdy)
         {
             return false;
         }
 
-        return !tileRef.Value.IsBlockedTurf(_filterMobs);
+        return !turfSystem.IsTileBlocked(tileRef.Value, _filterMobs ? CollisionGroup.MobMask : CollisionGroup.Impassable);
     }
 
     public ConstructionGuideEntry GenerateGuideEntry()
index 3ffdf66050284b5e08b9cdfb1295ce0585583415..e066e6af2e0ff4a7dfbe2c9bcd807765331b76d4 100644 (file)
@@ -20,12 +20,13 @@ namespace Content.Shared.Construction.Conditions
 
         public bool Condition(EntityUid user, EntityCoordinates location, Direction direction)
         {
-            var tileFound = location.GetTileRef();
+            if (!IoCManager.Resolve<IEntityManager>().TrySystem<TurfSystem>(out var turfSystem))
+                return false;
 
-            if (tileFound == null)
+            if (!turfSystem.TryGetTileRef(location, out var tileFound))
                 return false;
 
-            var tile = tileFound.Value.Tile.GetContentTileDefinition();
+            var tile = turfSystem.GetContentTileDefinition(tileFound.Value);
             foreach (var targetTile in TargetTiles)
             {
                 if (tile.ID == targetTile)
index 4bfe2e1fe56a6589782823b67f823b85da144c23..09b289c2be956c42313008756a9644cfe4d3669b 100644 (file)
@@ -62,6 +62,7 @@ public abstract class SharedMagicSystem : EntitySystem
     [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly SharedMindSystem _mind = default!;
     [Dependency] private readonly SharedStunSystem _stun = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     private static readonly ProtoId<TagPrototype> InvalidForGlobalSpawnSpellTag = "InvalidForGlobalSpawnSpell";
 
@@ -158,7 +159,7 @@ public abstract class SharedMagicSystem : EntitySystem
 
                 if (!TryComp<MapGridComponent>(casterXform.GridUid, out var mapGrid))
                     return new List<EntityCoordinates>();
-                if (!directionPos.TryGetTileRef(out var tileReference, EntityManager, _mapManager))
+                if (!_turf.TryGetTileRef(directionPos, out var tileReference))
                     return new List<EntityCoordinates>();
 
                 var tileIndex = tileReference.Value.GridIndices;
@@ -171,7 +172,7 @@ public abstract class SharedMagicSystem : EntitySystem
                 if (!TryComp<MapGridComponent>(casterXform.GridUid, out var mapGrid))
                     return new List<EntityCoordinates>();
 
-                if (!directionPos.TryGetTileRef(out var tileReference, EntityManager, _mapManager))
+                if (!_turf.TryGetTileRef(directionPos, out var tileReference))
                     return new List<EntityCoordinates>();
 
                 var tileIndex = tileReference.Value.GridIndices;
diff --git a/Content.Shared/Maps/TurfHelpers.cs b/Content.Shared/Maps/TurfHelpers.cs
deleted file mode 100644 (file)
index dfa12f3..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using Content.Shared.Physics;
-using Robust.Shared.Map;
-using Robust.Shared.Map.Components;
-using Robust.Shared.Random;
-
-namespace Content.Shared.Maps
-{
-    // TODO move all these methods to LookupSystem or TurfSystem
-    // That, or make the interface arguments non-optional so people stop failing to pass them in.
-    public static class TurfHelpers
-    {
-        /// <summary>
-        ///     Attempts to get the turf at a certain coordinates or null if no such turf is found.
-        /// </summary>
-        public static TileRef? GetTileRef(this EntityCoordinates coordinates, IEntityManager? entityManager = null, IMapManager? mapManager = null)
-        {
-            entityManager ??= IoCManager.Resolve<IEntityManager>();
-
-            if (!coordinates.IsValid(entityManager))
-                return null;
-
-            mapManager ??= IoCManager.Resolve<IMapManager>();
-            var pos = entityManager.System<SharedTransformSystem>().ToMapCoordinates(coordinates);
-            if (!mapManager.TryFindGridAt(pos, out _, out var grid))
-                return null;
-
-            if (!grid.TryGetTileRef(coordinates, out var tile))
-                return null;
-
-            return tile;
-        }
-
-        public static bool TryGetTileRef(this EntityCoordinates coordinates, [NotNullWhen(true)] out TileRef? turf, IEntityManager? entityManager = null, IMapManager? mapManager = null)
-        {
-            return (turf = coordinates.GetTileRef(entityManager, mapManager)) != null;
-        }
-
-        /// <summary>
-        ///     Returns the content tile definition for a tile.
-        /// </summary>
-        public static ContentTileDefinition GetContentTileDefinition(this Tile tile, ITileDefinitionManager? tileDefinitionManager = null)
-        {
-            tileDefinitionManager ??= IoCManager.Resolve<ITileDefinitionManager>();
-            return (ContentTileDefinition)tileDefinitionManager[tile.TypeId];
-        }
-
-        /// <summary>
-        ///     Returns whether a tile is considered space.
-        /// </summary>
-        public static bool IsSpace(this Tile tile, ITileDefinitionManager? tileDefinitionManager = null)
-        {
-            return tile.GetContentTileDefinition(tileDefinitionManager).MapAtmosphere;
-        }
-
-        /// <summary>
-        ///     Returns the content tile definition for a tile ref.
-        /// </summary>
-        public static ContentTileDefinition GetContentTileDefinition(this TileRef tile, ITileDefinitionManager? tileDefinitionManager = null)
-        {
-            return tile.Tile.GetContentTileDefinition(tileDefinitionManager);
-        }
-
-        /// <summary>
-        ///     Returns whether a tile ref is considered space.
-        /// </summary>
-        public static bool IsSpace(this TileRef tile, ITileDefinitionManager? tileDefinitionManager = null)
-        {
-            return tile.Tile.IsSpace(tileDefinitionManager);
-        }
-
-        /// <summary>
-        ///     Helper that returns all entities in a turf.
-        /// </summary>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        [Obsolete("Use the lookup system")]
-        public static IEnumerable<EntityUid> GetEntitiesInTile(this TileRef turf, LookupFlags flags = LookupFlags.Static, EntityLookupSystem? lookupSystem = null)
-        {
-            lookupSystem ??= EntitySystem.Get<EntityLookupSystem>();
-
-            if (!GetWorldTileBox(turf, out var worldBox))
-                return Enumerable.Empty<EntityUid>();
-
-            return lookupSystem.GetEntitiesIntersecting(turf.GridUid, worldBox, flags);
-        }
-
-        /// <summary>
-        ///     Helper that returns all entities in a turf.
-        /// </summary>
-        [Obsolete("Use the lookup system")]
-        public static IEnumerable<EntityUid> GetEntitiesInTile(this EntityCoordinates coordinates, LookupFlags flags = LookupFlags.Static, EntityLookupSystem? lookupSystem = null)
-        {
-            var turf = coordinates.GetTileRef();
-
-            if (turf == null)
-                return Enumerable.Empty<EntityUid>();
-
-            return GetEntitiesInTile(turf.Value, flags, lookupSystem);
-        }
-
-        /// <summary>
-        /// Checks if a turf has something dense on it.
-        /// </summary>
-        [Obsolete("Use turf system")]
-        public static bool IsBlockedTurf(this TileRef turf, bool filterMobs, EntityLookupSystem? physics = null)
-        {
-            CollisionGroup mask = filterMobs
-                ? CollisionGroup.MobMask
-                : CollisionGroup.Impassable;
-
-            return IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<TurfSystem>().IsTileBlocked(turf, mask);
-        }
-
-        /// <summary>
-        /// Creates a box the size of a tile, at the same position in the world as the tile.
-        /// </summary>
-        [Obsolete]
-        private static bool GetWorldTileBox(TileRef turf, out Box2Rotated res)
-        {
-            var entManager = IoCManager.Resolve<IEntityManager>();
-            var xformSystem = entManager.System<SharedTransformSystem>();
-
-            if (entManager.TryGetComponent<MapGridComponent>(turf.GridUid, out var tileGrid))
-            {
-                var gridRot = xformSystem.GetWorldRotation(turf.GridUid);
-
-                // This is scaled to 90 % so it doesn't encompass walls on other tiles.
-                var tileBox = Box2.UnitCentered.Scale(0.9f);
-                tileBox = tileBox.Scale(tileGrid.TileSize);
-                var worldPos = tileGrid.GridTileToWorldPos(turf.GridIndices);
-                tileBox = tileBox.Translated(worldPos);
-                // Now tileBox needs to be rotated to match grid rotation
-                res = new Box2Rotated(tileBox, gridRot, worldPos);
-                return true;
-            }
-
-            // Have to "return something"
-            res = Box2Rotated.UnitCentered;
-            return false;
-        }
-    }
-}
index 8a4bbf68bed326553a1467e4348a4f54f4e746de..f5477441d9296e6d7a4fc4125a7b02cdabddfa7b 100644 (file)
@@ -1,8 +1,11 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
 using System.Numerics;
 using Content.Shared.Physics;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Physics;
+using Robust.Shared.Toolshed.Commands.Values;
 
 namespace Content.Shared.Maps;
 
@@ -11,8 +14,43 @@ namespace Content.Shared.Maps;
 /// </summary>
 public sealed class TurfSystem : EntitySystem
 {
+    [Dependency] private readonly IMapManager _mapManager = default!;
     [Dependency] private readonly EntityLookupSystem _entityLookup = default!;
     [Dependency] private readonly SharedTransformSystem _transform = default!;
+    [Dependency] private readonly SharedMapSystem _mapSystem = default!;
+    [Dependency] private readonly ITileDefinitionManager _tileDefinitions = default!;
+
+
+    /// <summary>
+    /// Attempts to get the turf at or under some given coordinates or null if no such turf exists.
+    /// </summary>
+    /// <param name="coordinates">The coordinates to search for a turf.</param>
+    /// <returns>A <see cref="TileRef"/> for the turf found at the given coordinates or null if no such turf exists.</returns>
+    public TileRef? GetTileRef(EntityCoordinates coordinates)
+    {
+        if (!coordinates.IsValid(EntityManager))
+            return null;
+
+        var pos = _transform.ToMapCoordinates(coordinates);
+        if (!_mapManager.TryFindGridAt(pos, out var gridUid, out var gridComp))
+            return null;
+
+        if (!_mapSystem.TryGetTileRef(gridUid, gridComp, coordinates, out var tile))
+            return null;
+
+        return tile;
+    }
+
+    /// <summary>
+    /// Attempts to get the turf at or under some given coordinates.
+    /// </summary>
+    /// <param name="coordinates">The coordinates to search for a turf.</param>
+    /// <param name="tile">Returns the turf found at the given coordinates if any.</param>
+    /// <returns>True if a turf was found at the given coordinates, false otherwise.</returns>
+    public bool TryGetTileRef(EntityCoordinates coordinates, [NotNullWhen(true)] out TileRef? tile)
+    {
+        return (tile = GetTileRef(coordinates)) is not null;
+    }
 
     /// <summary>
     ///     Returns true if a given tile is blocked by physics-enabled entities.
@@ -63,14 +101,14 @@ public sealed class TurfSystem : EntitySystem
             rot -= gridRot;
             pos = (-gridRot).RotateVec(pos - gridPos);
 
-            var xform = new Transform(pos, (float) rot.Theta);
+            var xform = new Transform(pos, (float)rot.Theta);
 
             foreach (var fixture in fixtures.Fixtures.Values)
             {
                 if (!fixture.Hard)
                     continue;
 
-                if ((fixture.CollisionLayer & (int) mask) == 0)
+                if ((fixture.CollisionLayer & (int)mask) == 0)
                     continue;
 
                 for (var i = 0; i < fixture.Shape.ChildCount; i++)
@@ -86,6 +124,26 @@ public sealed class TurfSystem : EntitySystem
         return false;
     }
 
+    /// <summary>
+    /// Returns whether a tile is considered to be space or directly exposed to space.
+    /// </summary>
+    /// <param name="tile">The tile in question.</param>
+    /// <returns>True if the tile is considered to be space, false otherwise.</returns>
+    public bool IsSpace(Tile tile)
+    {
+        return GetContentTileDefinition(tile).MapAtmosphere;
+    }
+
+    /// <summary>
+    /// Returns whether a tile is considered to be space or directly exposed to space.
+    /// </summary>
+    /// <param name="tile">The tile in question.</param>
+    /// <returns>True if the tile is considered to be space, false otherwise.</returns>
+    public bool IsSpace(TileRef tile)
+    {
+        return IsSpace(tile.Tile);
+    }
+
     /// <summary>
     /// Returns the location of the centre of the tile in grid coordinates.
     /// </summary>
@@ -95,4 +153,78 @@ public sealed class TurfSystem : EntitySystem
         var center = (turf.GridIndices + new Vector2(0.5f, 0.5f)) * grid.TileSize;
         return new EntityCoordinates(turf.GridUid, center);
     }
+
+    /// <summary>
+    ///     Returns the content tile definition for a tile.
+    /// </summary>
+    public ContentTileDefinition GetContentTileDefinition(Tile tile)
+    {
+        return (ContentTileDefinition)_tileDefinitions[tile.TypeId];
+    }
+
+    /// <summary>
+    ///     Returns the content tile definition for a tile ref.
+    /// </summary>
+    public ContentTileDefinition GetContentTileDefinition(TileRef tile)
+    {
+        return GetContentTileDefinition(tile.Tile);
+    }
+
+    /// <summary>
+    ///     Collects all of the entities intersecting with the turf at a given position into a provided <see cref="HashSet{EntityUid}"/>
+    /// </summary>
+    /// <param name="coords">The position of the turf to search for entities.</param>
+    /// <param name="intersecting">The hashset used to collect the relevant entities.</param>
+    /// <param name="flags">A set of lookup categories to search for relevant entities.</param>
+    public void GetEntitiesInTile(EntityCoordinates coords, HashSet<EntityUid> intersecting, LookupFlags flags = LookupFlags.Static)
+    {
+        if (!TryGetTileRef(coords, out var tileRef))
+            return;
+
+        _entityLookup.GetEntitiesInTile(tileRef.Value, intersecting, flags);
+    }
+
+    /// <summary>
+    ///     Returns a collection containing all of the entities overlapping with the turf at a given position.
+    /// </summary>
+    /// <inheritdoc cref="GetEntitiesInTile(EntityCoordinates, HashSet{EntityUid}, LookupFlags)"/>
+    /// <returns>A hashset containing all of the entities overlapping with the turf in question.</returns>
+    public HashSet<EntityUid> GetEntitiesInTile(EntityCoordinates coords, LookupFlags flags = LookupFlags.Static)
+    {
+        if (!TryGetTileRef(coords, out var tileRef))
+            return [];
+
+        return _entityLookup.GetEntitiesInTile(tileRef.Value, flags);
+    }
+}
+
+/// <summary>
+///     Extension methods for looking up entities with respect to given turfs.
+/// </summary>
+public static partial class TurfLookupExtensions
+{
+    /// <summary>
+    ///     Collects all of the entities overlapping with a given turf into a provided <see cref="HashSet{EntityUid}"/>.
+    /// </summary>
+    /// <param name="turf">The turf in question.</param>
+    /// <param name="intersecting">The hashset used to collect the relevant entities.</param>
+    /// <param name="flags">A set of lookup categories to search for relevant entities.</param>
+    public static void GetEntitiesInTile(this EntityLookupSystem lookupSystem, TileRef turf, HashSet<EntityUid> intersecting, LookupFlags flags = LookupFlags.Static)
+    {
+        var bounds = lookupSystem.GetWorldBounds(turf);
+        bounds.Box = bounds.Box.Scale(0.9f); // Otherwise the box can clip into neighboring tiles.
+        lookupSystem.GetEntitiesIntersecting(turf.GridUid, bounds, intersecting, flags);
+    }
+
+    /// <summary>
+    ///     Returns a collection containing all of the entities overlapping with a given turf.
+    /// </summary>
+    /// <inheritdoc cref="GetEntitiesInTile(EntityLookupSystem, TileRef, HashSet{EntityUid}, LookupFlags)"/>
+    /// <returns>A hashset containing all of the entities overlapping with the turf in question.</returns>
+    public static HashSet<EntityUid> GetEntitiesInTile(this EntityLookupSystem lookupSystem, TileRef turf, LookupFlags flags = LookupFlags.Static)
+    {
+        var intersecting = new HashSet<EntityUid>();
+        lookupSystem.GetEntitiesInTile(turf, intersecting, flags);
+        return intersecting;
+    }
 }
index 238daf6bf76c0d97345eb5cafa252643eeef06ed..6d85b171e09d6b780f1c5d72561feae4eb90178b 100644 (file)
@@ -175,7 +175,7 @@ public sealed class RCDSystem : EntitySystem
                 else
                 {
                     var deconstructedTile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
-                    var protoName = !deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto;
+                    var protoName = !_turf.IsSpace(deconstructedTile) ? _deconstructTileProto : _deconstructLatticeProto;
 
                     if (_protoManager.TryIndex(protoName, out var deconProto))
                     {
@@ -383,7 +383,7 @@ public sealed class RCDSystem : EntitySystem
         }
 
         // Check rule: Must place on subfloor
-        if (prototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnSubfloor) && !tile.Tile.GetContentTileDefinition().IsSubFloor)
+        if (prototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnSubfloor) && !_turf.GetContentTileDefinition(tile).IsSubFloor)
         {
             if (popMsgs)
                 _popup.PopupClient(Loc.GetString("rcd-component-must-build-on-subfloor-message"), uid, user);
@@ -404,7 +404,7 @@ public sealed class RCDSystem : EntitySystem
             }
 
             // Check rule: Tiles can't be identical
-            if (tile.Tile.GetContentTileDefinition().ID == prototype.Prototype)
+            if (_turf.GetContentTileDefinition(tile).ID == prototype.Prototype)
             {
                 if (popMsgs)
                     _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-identical-tile"), uid, user);
@@ -487,7 +487,7 @@ public sealed class RCDSystem : EntitySystem
             }
 
             // The tile cannot be destroyed
-            var tileDef = (ContentTileDefinition) _tileDefMan[tile.Tile.TypeId];
+            var tileDef = _turf.GetContentTileDefinition(tile);
 
             if (tileDef.Indestructible)
             {
@@ -559,7 +559,7 @@ public sealed class RCDSystem : EntitySystem
                 if (target == null)
                 {
                     // Deconstruct tile (either converts the tile to lattice, or removes lattice)
-                    var tileDef = (tile.Tile.GetContentTileDefinition().ID != "Lattice") ? new Tile(_tileDefMan["Lattice"].TileId) : Tile.Empty;
+                    var tileDef = (_turf.GetContentTileDefinition(tile).ID != "Lattice") ? new Tile(_tileDefMan["Lattice"].TileId) : Tile.Empty;
                     _mapSystem.SetTile(gridUid, mapGrid, position, tileDef);
                     _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {gridUid} tile: {position} open to space");
                 }
index 58d541e363e47545a3243c9352f1998171813e23..38af0677fafc0d1c84964587d431e4e6cb2c9db3 100644 (file)
@@ -31,13 +31,13 @@ public abstract class SharedEmitSoundSystem : EntitySystem
 {
     [Dependency] protected readonly IGameTiming Timing = default!;
     [Dependency] private readonly INetManager _netMan = default!;
-    [Dependency] private readonly ITileDefinitionManager _tileDefMan = default!;
     [Dependency] protected readonly IRobustRandom Random = default!;
     [Dependency] private   readonly SharedAmbientSoundSystem _ambient = default!;
     [Dependency] private   readonly SharedAudioSystem _audioSystem = default!;
     [Dependency] protected readonly SharedPopupSystem Popup = default!;
     [Dependency] private readonly SharedMapSystem _map = default!;
     [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     public override void Initialize()
     {
@@ -135,7 +135,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem
         var tile = _map.GetTileRef(xform.GridUid.Value, grid, xform.Coordinates);
 
         // Handle maps being grids (we'll still emit the sound).
-        if (xform.GridUid != xform.MapUid && tile.IsSpace(_tileDefMan))
+        if (xform.GridUid != xform.MapUid && _turf.IsSpace(tile))
             return;
 
         // hand throwing not predicted sadly
index d798fa2473d867c146ada6245097f4a3c12e0abc..67283eeea0ecd2204ce388f6bf7e8b57b791de2e 100644 (file)
@@ -37,9 +37,15 @@ public sealed class FloorTileSystem : EntitySystem
     [Dependency] private readonly TileSystem _tile = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
     [Dependency] private readonly SharedMapSystem _map = default!;
+    [Dependency] private readonly TurfSystem _turf = default!;
 
     private static readonly Vector2 CheckRange = new(1f, 1f);
 
+    /// <summary>
+    ///     A recycled hashset used to check for walls when trying to place tiles on turfs.
+    /// </summary>
+    private readonly HashSet<EntityUid> _turfCheck = [];
+
     public override void Initialize()
     {
         base.Initialize();
@@ -104,14 +110,16 @@ public sealed class FloorTileSystem : EntitySystem
 
         // if user can access tile center then they can place floor
         // otherwise check it isn't blocked by a wall
-        if (!canAccessCenter)
+        if (!canAccessCenter && _turf.TryGetTileRef(location, out var tileRef))
         {
-            foreach (var ent in location.GetEntitiesInTile(lookupSystem: _lookup))
+            _turfCheck.Clear();
+            _lookup.GetEntitiesInTile(tileRef.Value, _turfCheck);
+            foreach (var ent in _turfCheck)
             {
                 if (physicQuery.TryGetComponent(ent, out var phys) &&
                     phys.BodyType == BodyType.Static &&
                     phys.Hard &&
-                    (phys.CollisionLayer & (int) CollisionGroup.Impassable) != 0)
+                    (phys.CollisionLayer & (int)CollisionGroup.Impassable) != 0)
                 {
                     return;
                 }