diff --git a/Content.Server/Fluids/EntitySystems/FluidSpreaderSystem.cs b/Content.Server/Fluids/EntitySystems/FluidSpreaderSystem.cs
index 84f0fc263d..20f786d6cd 100644
--- a/Content.Server/Fluids/EntitySystems/FluidSpreaderSystem.cs
+++ b/Content.Server/Fluids/EntitySystems/FluidSpreaderSystem.cs
@@ -3,13 +3,13 @@ using System.Linq;
using Content.Server.Fluids.Components;
using Content.Shared;
using Content.Shared.Directions;
+using Content.Shared.Maps;
using Content.Shared.Physics;
using JetBrains.Annotations;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
-using Robust.Shared.Utility;
-using Robust.Shared.Physics.Components;
+using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
namespace Content.Server.Fluids.EntitySystems;
@@ -23,6 +23,8 @@ public sealed class FluidSpreaderSystem : EntitySystem
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly PuddleSystem _puddleSystem = default!;
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
+ [Dependency] private readonly SharedPhysicsSystem _physics = default!;
///
/// Adds an overflow component to the map data component tracking overflowing puddles
@@ -72,20 +74,19 @@ public sealed class FluidSpreaderSystem : EntitySystem
puddles.Clear();
var pos = transform.Coordinates;
- var totalVolume = _puddleSystem.CurrentVolume(puddle.Owner, puddle);
+ var totalVolume = _puddleSystem.CurrentVolume(puddleUid, puddle);
exploreDirections.Shuffle();
foreach (var direction in exploreDirections)
{
var newPos = pos.Offset(direction);
- if (CheckTile(puddle.Owner, puddle, newPos, mapGrid,
- out var puddleComponent))
+ if (CheckTile(puddleUid, puddle, newPos, mapGrid, puddleQuery, out var uid, out var component))
{
- puddles.Add(puddleComponent);
- totalVolume += _puddleSystem.CurrentVolume(puddleComponent.Owner, puddleComponent);
+ puddles.Add(component);
+ totalVolume += _puddleSystem.CurrentVolume(uid.Value, component);
}
}
- _puddleSystem.EqualizePuddles(puddle.Owner, puddles, totalVolume, newIteration, puddle);
+ _puddleSystem.EqualizePuddles(puddleUid, puddles, totalVolume, newIteration, puddle);
}
fluidMapData.Puddles.Clear();
@@ -100,49 +101,57 @@ public sealed class FluidSpreaderSystem : EntitySystem
///
/// Entity Uid of original puddle
/// PuddleComponent attached to srcUid
- /// at which to check tile
+ /// at which to check tile
/// helper param needed to extract entities
- /// either found or newly created PuddleComponent.
+ /// either found or newly created PuddleComponent.
/// true if tile is empty or occupied by a non-overflowing puddle (or a puddle close to being overflowing)
- private bool CheckTile(EntityUid srcUid, PuddleComponent srcPuddle, EntityCoordinates pos, MapGridComponent mapGrid,
- [NotNullWhen(true)] out PuddleComponent? puddle)
+ private bool CheckTile(EntityUid srcUid, PuddleComponent srcPuddle, EntityCoordinates dstPos,
+ MapGridComponent mapGrid, EntityQuery puddleQuery,
+ [NotNullWhen(true)] out EntityUid? newPuddleUid, [NotNullWhen(true)] out PuddleComponent? newPuddleComp)
{
- if (!mapGrid.TryGetTileRef(pos, out var tileRef)
+ if (!mapGrid.TryGetTileRef(dstPos, out var tileRef)
|| tileRef.Tile.IsEmpty)
{
- puddle = null;
+ newPuddleUid = null;
+ newPuddleComp = null;
+ return false;
+ }
+
+ // check if puddle can spread there at all
+ var dstMap = dstPos.ToMap(EntityManager, _transform);
+ var dst = dstMap.Position;
+ var src = Transform(srcUid).MapPosition.Position;
+ var dir = src - dst;
+ var ray = new CollisionRay(dst, dir.Normalized, (int) (CollisionGroup.Impassable | CollisionGroup.HighImpassable));
+ var mapId = dstMap.MapId;
+ var results = _physics.IntersectRay(mapId, ray, dir.Length, returnOnFirstHit: true);
+ if (results.Any())
+ {
+ newPuddleUid = null;
+ newPuddleComp = null;
return false;
}
var puddleCurrentVolume = _puddleSystem.CurrentVolume(srcUid, srcPuddle);
-
- foreach (var entity in mapGrid.GetAnchoredEntities(pos))
+ foreach (var entity in dstPos.GetEntitiesInTile())
{
- // If this is valid puddle check if we spread to it.
- if (TryComp(entity, out PuddleComponent? existingPuddle))
+ if (puddleQuery.TryGetComponent(entity, out var existingPuddle))
{
- // If current puddle has more volume than current we skip that field
- if (_puddleSystem.CurrentVolume(existingPuddle.Owner, existingPuddle) >= puddleCurrentVolume)
+ if (_puddleSystem.CurrentVolume(entity, existingPuddle) >= puddleCurrentVolume)
{
- puddle = null;
+ newPuddleUid = null;
+ newPuddleComp = null;
return false;
}
-
- puddle = existingPuddle;
+ newPuddleUid = entity;
+ newPuddleComp = existingPuddle;
return true;
}
-
- // if not puddle is this tile blocked by an object like wall or door
- if (TryComp(entity, out PhysicsComponent? physComponent)
- && physComponent.CanCollide
- && (physComponent.CollisionLayer & (int) CollisionGroup.MobMask) != 0)
- {
- puddle = null;
- return false;
- }
}
- puddle = _puddleSystem.SpawnPuddle(srcUid, pos, srcPuddle);
+ _puddleSystem.SpawnPuddle(srcUid, dstPos, srcPuddle, out var uid, out var comp);
+ newPuddleUid = uid;
+ newPuddleComp = comp;
return true;
}
}
diff --git a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs
index 7eb16ec0cb..0a9f8a8332 100644
--- a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs
+++ b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs
@@ -266,17 +266,15 @@ namespace Content.Server.Fluids.EntitySystems
return CurrentVolume(uid, puddle) > puddle.OverflowVolume;
}
- public PuddleComponent SpawnPuddle(EntityUid srcUid, EntityCoordinates pos, PuddleComponent? srcPuddleComponent = null)
+ public void SpawnPuddle(EntityUid srcUid, EntityCoordinates pos, PuddleComponent srcPuddleComponent, out EntityUid uid, out PuddleComponent component)
{
MetaDataComponent? metadata = null;
- Resolve(srcUid, ref srcPuddleComponent, ref metadata);
+ Resolve(srcUid, ref metadata);
var prototype = metadata?.EntityPrototype?.ID ?? "PuddleSmear"; // TODO Spawn a entity based on another entity
- var destUid = EntityManager.SpawnEntity(prototype, pos);
- var destPuddle = EntityManager.EnsureComponent(destUid);
-
- return destPuddle;
+ uid = EntityManager.SpawnEntity(prototype, pos);
+ component = EntityManager.EnsureComponent(uid);
}
}
}