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 { /// /// Attempts to get the turf at a certain coordinates or null if no such turf is found. /// public static TileRef? GetTileRef(this EntityCoordinates coordinates, IEntityManager? entityManager = null, IMapManager? mapManager = null) { entityManager ??= IoCManager.Resolve(); if (!coordinates.IsValid(entityManager)) return null; mapManager ??= IoCManager.Resolve(); var pos = entityManager.System().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; } /// /// Returns the content tile definition for a tile. /// public static ContentTileDefinition GetContentTileDefinition(this Tile tile, ITileDefinitionManager? tileDefinitionManager = null) { tileDefinitionManager ??= IoCManager.Resolve(); return (ContentTileDefinition)tileDefinitionManager[tile.TypeId]; } /// /// Returns whether a tile is considered space. /// public static bool IsSpace(this Tile tile, ITileDefinitionManager? tileDefinitionManager = null) { return tile.GetContentTileDefinition(tileDefinitionManager).MapAtmosphere; } /// /// Returns the content tile definition for a tile ref. /// public static ContentTileDefinition GetContentTileDefinition(this TileRef tile, ITileDefinitionManager? tileDefinitionManager = null) { return tile.Tile.GetContentTileDefinition(tileDefinitionManager); } /// /// Returns whether a tile ref is considered space. /// public static bool IsSpace(this TileRef tile, ITileDefinitionManager? tileDefinitionManager = null) { return tile.Tile.IsSpace(tileDefinitionManager); } /// /// Helper that returns all entities in a turf. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [Obsolete("Use the lookup system")] public static IEnumerable GetEntitiesInTile(this TileRef turf, LookupFlags flags = LookupFlags.Static, EntityLookupSystem? lookupSystem = null) { lookupSystem ??= EntitySystem.Get(); if (!GetWorldTileBox(turf, out var worldBox)) return Enumerable.Empty(); return lookupSystem.GetEntitiesIntersecting(turf.GridUid, worldBox, flags); } /// /// Helper that returns all entities in a turf. /// [Obsolete("Use the lookup system")] public static IEnumerable GetEntitiesInTile(this EntityCoordinates coordinates, LookupFlags flags = LookupFlags.Static, EntityLookupSystem? lookupSystem = null) { var turf = coordinates.GetTileRef(); if (turf == null) return Enumerable.Empty(); return GetEntitiesInTile(turf.Value, flags, lookupSystem); } /// /// Checks if a turf has something dense on it. /// [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().GetEntitySystem().IsTileBlocked(turf, mask); } /// /// Creates a box the size of a tile, at the same position in the world as the tile. /// [Obsolete] private static bool GetWorldTileBox(TileRef turf, out Box2Rotated res) { var entManager = IoCManager.Resolve(); var xformSystem = entManager.System(); if (entManager.TryGetComponent(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; } } }