diff --git a/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs b/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs index 769d14fd16..e2015f739c 100644 --- a/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/PuddleComponent.cs @@ -6,7 +6,9 @@ using Content.Server.GameObjects.Components.Chemistry; using Content.Server.GameObjects.Components.Movement; using Content.Shared.Chemistry; using Content.Shared.GameObjects.EntitySystems; +using Content.Shared.Maps; using Content.Shared.Physics; +using Content.Shared.Utility; using Robust.Server.GameObjects; using Robust.Server.GameObjects.EntitySystems; using Robust.Server.Interfaces.GameObjects; @@ -338,43 +340,6 @@ namespace Content.Server.GameObjects.Components.Fluids } } - // TODO: Move the below to SnapGrid? - /// - /// Will yield a random direction until none are left - /// - /// - private static IEnumerable RandomDirections() - { - var directions = new[] - { - Direction.East, - Direction.SouthEast, - Direction.South, - Direction.SouthWest, - Direction.West, - Direction.NorthWest, - Direction.North, - Direction.NorthEast, - }; - - var robustRandom = IoCManager.Resolve(); - var n = directions.Length; - - while (n > 1) - { - n--; - var k = robustRandom.Next(n + 1); - var value = directions[k]; - directions[k] = directions[n]; - directions[n] = value; - } - - foreach (var direction in directions) - { - yield return direction; - } - } - /// /// Tries to get an adjacent coordinate to overflow to, unless it is blocked by a wall on the /// same tile or the tile is empty @@ -389,9 +354,13 @@ namespace Content.Server.GameObjects.Components.Fluids var mapGrid = _mapManager.GetGrid(Owner.Transform.GridID); + if (!Owner.Transform.GridPosition.Offset(direction).TryGetTileRef(out var tile)) + { + return false; + } + // If space return early, let that spill go out into the void - var tileRef = mapGrid.GetTileRef(Owner.Transform.GridPosition.Offset(direction.ToVec())); - if (tileRef.Tile.IsEmpty) + if (tile.Value.Tile.IsEmpty) { return false; } @@ -432,7 +401,7 @@ namespace Content.Server.GameObjects.Components.Fluids /// Enumerable of the puddles found or to be created private IEnumerable> GetAllAdjacentOverflow() { - foreach (var direction in RandomDirections()) + foreach (var direction in SharedDirectionExtensions.RandomDirections()) { if (TryGetAdjacentOverflow(direction, out var puddle)) { diff --git a/Content.Shared/Maps/TurfHelpers.cs b/Content.Shared/Maps/TurfHelpers.cs index b02472cfa5..8926c51743 100644 --- a/Content.Shared/Maps/TurfHelpers.cs +++ b/Content.Shared/Maps/TurfHelpers.cs @@ -1,5 +1,6 @@ #nullable enable using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Content.Shared.Physics; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Map; @@ -59,6 +60,11 @@ namespace Content.Shared.Maps return tile; } + public static bool TryGetTileRef(this GridCoordinates coordinates, [NotNullWhen(true)] out TileRef? turf) + { + return (turf = coordinates.GetTileRef()) != null; + } + /// /// Helper that returns all entities in a turf. /// @@ -92,6 +98,11 @@ namespace Content.Shared.Maps return false; } + public static GridCoordinates GridPosition(this TileRef turf) + { + return new GridCoordinates(turf.X, turf.Y, turf.GridIndex); + } + /// /// Creates a box the size of a tile, at the same position in the world as the tile. /// diff --git a/Content.Shared/Utility/SharedDirectionExtensions.cs b/Content.Shared/Utility/SharedDirectionExtensions.cs new file mode 100644 index 0000000000..c33a482b86 --- /dev/null +++ b/Content.Shared/Utility/SharedDirectionExtensions.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using Content.Shared.Maps; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.Interfaces.Random; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; + +namespace Content.Shared.Utility +{ + public static class SharedDirectionExtensions + { + /// + /// Gets random directions until none are left + /// + /// An enumerable of the directions. + public static IEnumerable RandomDirections() + { + var directions = new[] + { + Direction.East, + Direction.SouthEast, + Direction.South, + Direction.SouthWest, + Direction.West, + Direction.NorthWest, + Direction.North, + Direction.NorthEast, + }; + + var robustRandom = IoCManager.Resolve(); + var n = directions.Length; + + while (n > 1) + { + n--; + var k = robustRandom.Next(n + 1); + var value = directions[k]; + directions[k] = directions[n]; + directions[n] = value; + } + + foreach (var direction in directions) + { + yield return direction; + } + } + + /// + /// Gets tiles in random directions from the given one. + /// + /// An enumerable of the adjacent tiles. + public static IEnumerable AdjacentTilesRandom(this TileRef tile, bool ignoreSpace = false) + { + return tile.GridPosition().AdjacentTilesRandom(ignoreSpace); + } + + /// + /// Gets tiles in random directions from the given one. + /// + /// An enumerable of the adjacent tiles. + public static IEnumerable AdjacentTilesRandom(this GridCoordinates coordinates, bool ignoreSpace = false) + { + var mapManager = IoCManager.Resolve(); + + foreach (var direction in RandomDirections()) + { + var adjacent = coordinates.Offset(direction).GetTileRef(); + + if (adjacent == null) + { + continue; + } + + if (ignoreSpace && adjacent.Value.Tile.IsEmpty) + { + continue; + } + + yield return adjacent.Value; + } + } + + public static GridCoordinates Offset(this GridCoordinates coordinates, Direction direction) + { + return coordinates.Offset(direction.ToVec()); + } + } +}