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());
+ }
+ }
+}