diff --git a/Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs b/Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs
index ee800441c0..5576b9276a 100644
--- a/Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs
+++ b/Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs
@@ -1,7 +1,9 @@
#nullable enable
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using Content.Server.Utility;
using Content.Shared.Chemistry;
+using Content.Shared.GameObjects.Components.Chemistry;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
@@ -23,8 +25,7 @@ namespace Content.Server.GameObjects.Components.Fluids
/// The puddle if one was created, null otherwise.
public static PuddleComponent? SpillAt(this Solution solution, IEntity entity, string prototype, bool sound = true)
{
- var coordinates = entity.Transform.Coordinates;
- return solution.SpillAt(coordinates, prototype, sound);
+ return solution.SpillAt(entity.Transform.Coordinates, prototype, sound);
}
///
@@ -52,61 +53,16 @@ namespace Content.Server.GameObjects.Components.Fluids
/// The prototype to use.
/// Whether or not to play the spill sound.
/// The puddle if one was created, null otherwise.
- public static PuddleComponent? SpillAt(this Solution solution, EntityCoordinates coordinates, string prototype, bool sound = true)
+ public static PuddleComponent? SpillAt(this Solution solution, EntityCoordinates coordinates, string prototype, bool overflow = true, bool sound = true)
{
- if (solution.TotalVolume == 0)
- {
- return null;
- }
+ if (solution.TotalVolume == 0) return null;
var mapManager = IoCManager.Resolve();
var entityManager = IoCManager.Resolve();
- var serverEntityManager = IoCManager.Resolve();
- if (!mapManager.TryGetGrid(coordinates.GetGridId(entityManager), out var mapGrid))
- return null; // Let's not spill to space.
+ if (!mapManager.TryGetGrid(coordinates.GetGridId(entityManager), out var mapGrid)) return null; // Let's not spill to space.
- // If space return early, let that spill go out into the void
- var tileRef = mapGrid.GetTileRef(coordinates);
- if (tileRef.Tile.IsEmpty)
- {
- return null;
- }
-
- // Get normalized co-ordinate for spill location and spill it in the centre
- // TODO: Does SnapGrid or something else already do this?
- var spillGridCoords = mapGrid.GridTileToLocal(tileRef.GridIndices);
-
- var spilt = false;
-
- foreach (var spillEntity in entityManager.GetEntitiesAt(mapGrid.ParentMapId, spillGridCoords.Position))
- {
- if (!spillEntity.TryGetComponent(out PuddleComponent? puddleComponent))
- {
- continue;
- }
-
- if (!puddleComponent.TryAddSolution(solution, sound))
- {
- continue;
- }
-
- spilt = true;
- break;
- }
-
- // Did we add to an existing puddle
- if (spilt)
- {
- return null;
- }
-
- var puddle = serverEntityManager.SpawnEntity(prototype, spillGridCoords);
- var newPuddleComponent = puddle.GetComponent();
-
- newPuddleComponent.TryAddSolution(solution, sound);
-
- return newPuddleComponent;
+ return SpillAt(mapGrid.GetTileRef(coordinates), solution, prototype, overflow, sound);
}
///
@@ -141,44 +97,44 @@ namespace Content.Server.GameObjects.Components.Fluids
public static PuddleComponent? SpillAt(this TileRef tileRef, Solution solution, string prototype, bool overflow = true, bool sound = true)
{
- if (solution.TotalVolume <= 0)
- {
- return null;
- }
+ if (solution.TotalVolume <= 0) return null;
var mapManager = IoCManager.Resolve();
var entityManager = IoCManager.Resolve();
var serverEntityManager = IoCManager.Resolve();
- var gridId = tileRef.GridIndex;
-
// If space return early, let that spill go out into the void
- if (tileRef.Tile.IsEmpty)
- {
- return null;
- }
+ if (tileRef.Tile.IsEmpty) return null;
- PuddleComponent? puddle = null;
+ var gridId = tileRef.GridIndex;
+ if (!mapManager.TryGetGrid(gridId, out var mapGrid)) return null; // Let's not spill to invalid grids.
// Get normalized co-ordinate for spill location and spill it in the centre
// TODO: Does SnapGrid or something else already do this?
- if (!mapManager.TryGetGrid(gridId, out var spillTileMapGrid))
- return null; // Let's not spill to invalid grids.
-
- var spillGridCoords = spillTileMapGrid.GridTileToLocal(tileRef.GridIndices);
+ var spillGridCoords = mapGrid.GridTileToLocal(tileRef.GridIndices);
+ PuddleComponent? puddle = null;
var spilt = false;
- foreach (var spillEntity in entityManager.GetEntitiesAt(spillTileMapGrid.ParentMapId, spillGridCoords.Position))
+ var spillEntities = entityManager.GetEntitiesIntersecting(mapGrid.ParentMapId, spillGridCoords.Position).ToArray();
+ foreach (var spillEntity in spillEntities)
{
- if (!spillEntity.TryGetComponent(out PuddleComponent? puddleComponent))
- continue;
+ if (spillEntity.TryGetComponent(out ISolutionInteractionsComponent? solutionContainerComponent) &&
+ solutionContainerComponent.CanRefill)
+ {
+ solutionContainerComponent.Refill(
+ solution.SplitSolution(ReagentUnit.Min(solutionContainerComponent.RefillSpaceAvailable, solutionContainerComponent.MaxSpillRefill))
+ );
+ }
+ }
- if (!overflow && puddleComponent.WouldOverflow(solution))
- return null;
+ foreach (var spillEntity in spillEntities)
+ {
+ if (!spillEntity.TryGetComponent(out PuddleComponent? puddleComponent)) continue;
- if (!puddleComponent.TryAddSolution(solution, sound))
- continue;
+ if (!overflow && puddleComponent.WouldOverflow(solution)) return null;
+
+ if (!puddleComponent.TryAddSolution(solution, sound)) continue;
puddle = puddleComponent;
spilt = true;
@@ -186,17 +142,14 @@ namespace Content.Server.GameObjects.Components.Fluids
}
// Did we add to an existing puddle
- if (spilt)
- {
- return puddle;
- }
+ if (spilt) return puddle;
var puddleEnt = serverEntityManager.SpawnEntity(prototype, spillGridCoords);
- puddle = puddleEnt.GetComponent();
+ var newPuddleComponent = puddleEnt.GetComponent();
- puddle.TryAddSolution(solution, sound);
+ newPuddleComponent.TryAddSolution(solution, sound);
- return puddle;
+ return newPuddleComponent;
}
}
}
diff --git a/Content.Shared/GameObjects/Components/Chemistry/ISolutionInteractionsComponent.cs b/Content.Shared/GameObjects/Components/Chemistry/ISolutionInteractionsComponent.cs
index d74afbc84f..0b391be562 100644
--- a/Content.Shared/GameObjects/Components/Chemistry/ISolutionInteractionsComponent.cs
+++ b/Content.Shared/GameObjects/Components/Chemistry/ISolutionInteractionsComponent.cs
@@ -64,6 +64,11 @@ namespace Content.Shared.GameObjects.Components.Chemistry
bool CanRefill => false;
ReagentUnit RefillSpaceAvailable => ReagentUnit.Zero;
+ ///
+ /// The amount that will transfer if something is spilled on the container.
+ ///
+ ReagentUnit MaxSpillRefill => ReagentUnit.Zero;
+
void Refill(Solution solution)
{
diff --git a/Content.Shared/GameObjects/Components/Chemistry/SharedSolutionContainerComponent.cs b/Content.Shared/GameObjects/Components/Chemistry/SharedSolutionContainerComponent.cs
index d6e189a834..4cc238cb66 100644
--- a/Content.Shared/GameObjects/Components/Chemistry/SharedSolutionContainerComponent.cs
+++ b/Content.Shared/GameObjects/Components/Chemistry/SharedSolutionContainerComponent.cs
@@ -73,6 +73,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry
serializer.DataField(this, x => x.MaxVolume, "maxVol", ReagentUnit.New(0));
serializer.DataField(this, x => x.Solution, "contents", new Solution());
serializer.DataField(this, x => x.Capabilities, "caps", SolutionContainerCaps.None);
+ serializer.DataField(this, x => x.MaxSpillRefill, "maxSpillRefill", MaxVolume / ReagentUnit.New(4));
}
public void RemoveAllSolution()
@@ -214,6 +215,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry
ReagentUnit ISolutionInteractionsComponent.InjectSpaceAvailable => EmptyVolume;
ReagentUnit ISolutionInteractionsComponent.DrawAvailable => CurrentVolume;
ReagentUnit ISolutionInteractionsComponent.DrainAvailable => CurrentVolume;
+ public ReagentUnit MaxSpillRefill { get; set; }
void ISolutionInteractionsComponent.Refill(Solution solution)
{