From 61f64e15f20016ddafc9967db993cbd0fea52cb5 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Wed, 2 Sep 2020 01:16:25 +0200 Subject: [PATCH] Add extensions for spilling solutions into puddles (#1991) --- .../Components/Chemistry/VaporComponent.cs | 2 +- .../Components/Fluids/CanSpillComponent.cs | 2 +- .../Components/Fluids/MopComponent.cs | 4 +- .../Components/Fluids/SpillExtensions.cs | 128 ++++++++++++++++++ .../Components/Fluids/SpillHelper.cs | 94 ------------- .../Components/Nutrition/DrinkComponent.cs | 2 +- 6 files changed, 133 insertions(+), 99 deletions(-) create mode 100644 Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs delete mode 100644 Content.Server/GameObjects/Components/Fluids/SpillHelper.cs diff --git a/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs b/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs index ace097cce5..31734a5924 100644 --- a/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/VaporComponent.cs @@ -76,7 +76,7 @@ namespace Content.Server.GameObjects.Components.Chemistry foreach (var tile in tiles) { var pos = tile.GridIndices.ToGridCoordinates(_mapManager, tile.GridIndex); - SpillHelper.SpillAt(pos, contents.SplitSolution(amount), "PuddleSmear", false); //make non PuddleSmear? + contents.SplitSolution(amount).SpillAt(pos, "PuddleSmear", false); // TODO: Make non PuddleSmear? } } diff --git a/Content.Server/GameObjects/Components/Fluids/CanSpillComponent.cs b/Content.Server/GameObjects/Components/Fluids/CanSpillComponent.cs index 1eb779557b..b14063b7a4 100644 --- a/Content.Server/GameObjects/Components/Fluids/CanSpillComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/CanSpillComponent.cs @@ -41,7 +41,7 @@ namespace Content.Server.GameObjects.Components.Fluids // Need this as when we split the component's owner may be deleted var entityLocation = component.Owner.Transform.GridPosition; var solution = solutionComponent.SplitSolution(solutionComponent.CurrentVolume); - SpillHelper.SpillAt(entityLocation, solution, "PuddleSmear"); + solution.SpillAt(entityLocation, "PuddleSmear"); } } } diff --git a/Content.Server/GameObjects/Components/Fluids/MopComponent.cs b/Content.Server/GameObjects/Components/Fluids/MopComponent.cs index 907c1d3a48..857b53399d 100644 --- a/Content.Server/GameObjects/Components/Fluids/MopComponent.cs +++ b/Content.Server/GameObjects/Components/Fluids/MopComponent.cs @@ -80,7 +80,7 @@ namespace Content.Server.GameObjects.Components.Fluids if (eventArgs.Target == null) { // Drop the liquid on the mop on to the ground - SpillHelper.SpillAt(eventArgs.ClickLocation, contents.SplitSolution(CurrentVolume), "PuddleSmear"); + contents.SplitSolution(CurrentVolume).SpillAt(eventArgs.ClickLocation, "PuddleSmear"); return; } @@ -116,7 +116,7 @@ namespace Content.Server.GameObjects.Components.Fluids if (puddleCleaned) //After cleaning the puddle, make a new puddle with solution from the mop as a "wet floor". Then evaporate it slowly. { - SpillHelper.SpillAt(eventArgs.ClickLocation, contents.SplitSolution(transferAmount), "PuddleSmear"); + contents.SplitSolution(transferAmount).SpillAt(eventArgs.ClickLocation, "PuddleSmear"); } else { diff --git a/Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs b/Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs new file mode 100644 index 0000000000..5f9c45580f --- /dev/null +++ b/Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs @@ -0,0 +1,128 @@ +#nullable enable +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Chemistry; +using Robust.Server.Interfaces.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.IoC; +using Robust.Shared.Map; + +namespace Content.Server.GameObjects.Components.Fluids +{ + public static class SpillExtensions + { + /// + /// Spills the specified solution at the entity's location if possible. + /// + /// + /// The entity to use as a location to spill the solution at. + /// + /// Initial solution for the prototype. + /// The prototype to use. + /// Play the spill sound. + /// 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.GridPosition; + return solution.SpillAt(coordinates, prototype, sound); + } + + /// + /// Spills the specified solution at the entity's location if possible. + /// + /// + /// The entity to use as a location to spill the solution at. + /// + /// Initial solution for the prototype. + /// The prototype to use. + /// The puddle if one was created, null otherwise. + /// Play the spill sound. + /// True if a puddle was created, false otherwise. + public static bool TrySpillAt(this Solution solution, IEntity entity, string prototype, [NotNullWhen(true)] out PuddleComponent? puddle, bool sound = true) + { + puddle = solution.SpillAt(entity, prototype, sound); + return puddle != null; + } + + /// + /// Spills solution at the specified grid coordinates. + /// + /// Initial solution for the prototype. + /// The coordinates to spill the solution at. + /// 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, GridCoordinates coordinates, string prototype, bool sound = true) + { + if (solution.TotalVolume == 0) + { + return null; + } + + var mapManager = IoCManager.Resolve(); + var entityManager = IoCManager.Resolve(); + var serverEntityManager = IoCManager.Resolve(); + + var mapGrid = mapManager.GetGrid(coordinates.GridID); + + // 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 spillTileMapGrid = mapManager.GetGrid(coordinates.GridID); + var spillTileRef = spillTileMapGrid.GetTileRef(coordinates).GridIndices; + var spillGridCoords = spillTileMapGrid.GridTileToLocal(spillTileRef); + + var spilt = false; + + foreach (var spillEntity in entityManager.GetEntitiesAt(spillTileMapGrid.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; + } + + /// + /// Spills the specified solution at the entity's location if possible. + /// + /// The coordinates to spill the solution at. + /// Initial solution for the prototype. + /// The prototype to use. + /// The puddle if one was created, null otherwise. + /// Play the spill sound. + /// True if a puddle was created, false otherwise. + public static bool TrySpillAt(this Solution solution, GridCoordinates coordinates, string prototype, [NotNullWhen(true)] out PuddleComponent? puddle, bool sound = true) + { + puddle = solution.SpillAt(coordinates, prototype, sound); + return puddle != null; + } + } +} diff --git a/Content.Server/GameObjects/Components/Fluids/SpillHelper.cs b/Content.Server/GameObjects/Components/Fluids/SpillHelper.cs deleted file mode 100644 index e616a7f5f0..0000000000 --- a/Content.Server/GameObjects/Components/Fluids/SpillHelper.cs +++ /dev/null @@ -1,94 +0,0 @@ -#nullable enable -using Content.Shared.Chemistry; -using Robust.Server.Interfaces.GameObjects; -using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Interfaces.Map; -using Robust.Shared.IoC; -using Robust.Shared.Map; - -namespace Content.Server.GameObjects.Components.Fluids -{ - public static class SpillHelper - { - - /// - /// Spills the specified solution at the entity's location if possible. - /// - /// Entity location to spill at - /// Initial solution for the prototype - /// Prototype to use - /// Play the spill sound - internal static void SpillAt(IEntity entity, Solution solution, string prototype, bool sound = true) - { - var entityLocation = entity.Transform.GridPosition; - SpillAt(entityLocation, solution, prototype, sound); - } - - // Other functions will be calling this one - - /// - /// Spills solution at the specified grid co-ordinates - /// - /// - /// Initial solution for the prototype - /// Prototype to use - /// Play the spill sound - internal static PuddleComponent? SpillAt(GridCoordinates gridCoordinates, Solution solution, string prototype, bool sound = true) - { - if (solution.TotalVolume == 0) - { - return null; - } - - var mapManager = IoCManager.Resolve(); - var entityManager = IoCManager.Resolve(); - var serverEntityManager = IoCManager.Resolve(); - - var mapGrid = mapManager.GetGrid(gridCoordinates.GridID); - - // If space return early, let that spill go out into the void - var tileRef = mapGrid.GetTileRef(gridCoordinates); - 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 spillTileMapGrid = mapManager.GetGrid(gridCoordinates.GridID); - var spillTileRef = spillTileMapGrid.GetTileRef(gridCoordinates).GridIndices; - var spillGridCoords = spillTileMapGrid.GridTileToLocal(spillTileRef); - - var spilt = false; - - foreach (var spillEntity in entityManager.GetEntitiesAt(spillTileMapGrid.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; - } - - } - -} diff --git a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs index 194f671221..3a317ec1d4 100644 --- a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs @@ -172,7 +172,7 @@ namespace Content.Server.GameObjects.Components.Nutrition Opened = true; var solution = component.SplitSolution(component.CurrentVolume); - SpillHelper.SpillAt(Owner, solution, "PuddleSmear"); + solution.SpillAt(Owner, "PuddleSmear"); EntitySystem.Get().PlayFromEntity(_burstSound, Owner, AudioParams.Default.WithVolume(-4));