Un-Hardcode water evaporation & mopping behavior (#33399)

* Un-harcode slipperiness

* Make it actually work

* Prettyfy

* Cleanup GetEvaporatingReagents

* Fix mopping with space lube + wrong solutions in absorbance

* Remove LINQ and rename parameters

* Change evaporation speed to fixedpoint2

* Add evaporating speed functionality

* Remove unused imports

* Swap around reagent evaporation speed and puddle evaporation speed.

---------

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
This commit is contained in:
Jajsha
2025-04-18 20:11:28 -04:00
committed by GitHub
parent 181bb27797
commit a6741e42c1
7 changed files with 76 additions and 24 deletions

View File

@@ -57,14 +57,14 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
var oldProgress = component.Progress.ShallowClone();
component.Progress.Clear();
var water = solution.GetTotalPrototypeQuantity(PuddleSystem.EvaporationReagents);
if (water > FixedPoint2.Zero)
var mopReagent = solution.GetTotalPrototypeQuantity(_puddleSystem.GetAbsorbentReagents(solution));
if (mopReagent > FixedPoint2.Zero)
{
component.Progress[solution.GetColorWithOnly(_prototype, PuddleSystem.EvaporationReagents)] = water.Float();
component.Progress[solution.GetColorWithOnly(_prototype, _puddleSystem.GetAbsorbentReagents(solution))] = mopReagent.Float();
}
var otherColor = solution.GetColorWithout(_prototype, PuddleSystem.EvaporationReagents);
var other = (solution.Volume - water).Float();
var otherColor = solution.GetColorWithout(_prototype, _puddleSystem.GetAbsorbentReagents(solution));
var other = (solution.Volume - mopReagent).Float();
if (other > 0f)
{
@@ -180,7 +180,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
}
// Prioritize transferring non-evaporatives if absorbent has any
var contaminants = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, transferAmount, PuddleSystem.EvaporationReagents);
var contaminants = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, transferAmount, _puddleSystem.GetAbsorbentReagents(absorbentSoln.Comp.Solution));
if (contaminants.Volume > 0)
{
_solutionContainerSystem.TryAddSolution(refillableSoln, contaminants);
@@ -205,7 +205,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
Entity<SolutionComponent> absorbentSoln,
Entity<SolutionComponent> refillableSoln)
{
var contaminantsFromAbsorbent = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, component.PickupAmount, PuddleSystem.EvaporationReagents);
var contaminantsFromAbsorbent = _solutionContainerSystem.SplitSolutionWithout(absorbentSoln, component.PickupAmount, _puddleSystem.GetAbsorbentReagents(absorbentSoln.Comp.Solution));
var absorbentSolution = absorbentSoln.Comp.Solution;
if (contaminantsFromAbsorbent.Volume == FixedPoint2.Zero && absorbentSolution.AvailableVolume == FixedPoint2.Zero)
@@ -222,7 +222,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
absorbentSolution.AvailableVolume;
var refillableSolution = refillableSoln.Comp.Solution;
var waterFromRefillable = refillableSolution.SplitSolutionWithOnly(waterPulled, PuddleSystem.EvaporationReagents);
var waterFromRefillable = refillableSolution.SplitSolutionWithOnly(waterPulled, _puddleSystem.GetAbsorbentReagents(refillableSoln.Comp.Solution));
_solutionContainerSystem.UpdateChemicals(refillableSoln);
if (waterFromRefillable.Volume == FixedPoint2.Zero && contaminantsFromAbsorbent.Volume == FixedPoint2.Zero)
@@ -284,7 +284,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
// Check if we have any evaporative reagents on our absorber to transfer
var absorberSolution = absorberSoln.Comp.Solution;
var available = absorberSolution.GetTotalPrototypeQuantity(PuddleSystem.EvaporationReagents);
var available = absorberSolution.GetTotalPrototypeQuantity(_puddleSystem.GetAbsorbentReagents(absorberSolution));
// No material
if (available == FixedPoint2.Zero)
@@ -296,8 +296,8 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
var transferMax = absorber.PickupAmount;
var transferAmount = available > transferMax ? transferMax : available;
var puddleSplit = puddleSolution.SplitSolutionWithout(transferAmount, PuddleSystem.EvaporationReagents);
var absorberSplit = absorberSolution.SplitSolutionWithOnly(puddleSplit.Volume, PuddleSystem.EvaporationReagents);
var puddleSplit = puddleSolution.SplitSolutionWithout(transferAmount, _puddleSystem.GetAbsorbentReagents(puddleSolution));
var absorberSplit = absorberSolution.SplitSolutionWithOnly(puddleSplit.Volume, _puddleSystem.GetAbsorbentReagents(absorberSolution));
// Do tile reactions first
var transform = Transform(target);

View File

@@ -1,4 +1,5 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
using Content.Shared.Fluids.Components;
@@ -20,7 +21,7 @@ public sealed partial class PuddleSystem
return;
}
if (solution.GetTotalPrototypeQuantity(EvaporationReagents) > FixedPoint2.Zero)
if (solution.GetTotalPrototypeQuantity(GetEvaporatingReagents(solution)) > FixedPoint2.Zero)
{
var evaporation = AddComp<EvaporationComponent>(uid);
evaporation.NextTick = _timing.CurTime + EvaporationCooldown;
@@ -45,8 +46,11 @@ public sealed partial class PuddleSystem
if (!_solutionContainerSystem.ResolveSolution(uid, puddle.SolutionName, ref puddle.Solution, out var puddleSolution))
continue;
var reagentTick = evaporation.EvaporationAmount * EvaporationCooldown.TotalSeconds;
puddleSolution.SplitSolutionWithOnly(reagentTick, EvaporationReagents);
foreach ((string evaporatingReagent, FixedPoint2 evaporatingSpeed) in GetEvaporationSpeeds(puddleSolution))
{
var reagentTick = evaporation.EvaporationAmount * EvaporationCooldown.TotalSeconds * evaporatingSpeed;
puddleSolution.SplitSolutionWithOnly(reagentTick, evaporatingReagent);
}
// Despawn if we're done
if (puddleSolution.Volume == FixedPoint2.Zero)

View File

@@ -1,5 +1,6 @@
using System.Collections.Frozen;
using System.Linq;
using Content.Shared.FixedPoint;
using System.Text.Json.Serialization;
using Content.Shared.Administration.Logs;
using Content.Shared.Body.Prototypes;
@@ -7,14 +8,12 @@ using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reaction;
using Content.Shared.EntityEffects;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Nutrition;
using Robust.Shared.Audio;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
using Robust.Shared.Utility;
@@ -105,6 +104,18 @@ namespace Content.Shared.Chemistry.Reagent
[DataField]
public bool Slippery;
/// <summary>
/// The speed at which the reagent evaporates over time.
/// </summary>
[DataField]
public FixedPoint2 EvaporationSpeed = FixedPoint2.Zero;
/// <summary>
/// If this reagent can be used to mop up other reagents.
/// </summary>
[DataField]
public bool Absorbent = false;
/// <summary>
/// How easily this reagent becomes fizzy when aggitated.
/// 0 - completely flat, 1 - fizzes up when nudged.

View File

@@ -18,8 +18,8 @@ public sealed partial class EvaporationComponent : Component
public TimeSpan NextTick = TimeSpan.Zero;
/// <summary>
/// How much evaporation per second.
/// Evaporation factor. Multiplied by the evaporating speed of the reagent.
/// </summary>
[DataField("evaporationAmount")]
public FixedPoint2 EvaporationAmount = FixedPoint2.New(0.3);
public FixedPoint2 EvaporationAmount = FixedPoint2.New(1);
}

View File

@@ -1,17 +1,52 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.FixedPoint;
namespace Content.Shared.Fluids;
public abstract partial class SharedPuddleSystem
{
[ValidatePrototypeId<ReagentPrototype>]
private const string Water = "Water";
public string[] GetEvaporatingReagents(Solution solution)
{
var evaporatingReagents = new List<string>();
foreach (ReagentPrototype solProto in solution.GetReagentPrototypes(_prototypeManager).Keys)
{
if (solProto.EvaporationSpeed > FixedPoint2.Zero)
evaporatingReagents.Add(solProto.ID);
}
return evaporatingReagents.ToArray();
}
public static readonly string[] EvaporationReagents = [Water];
public string[] GetAbsorbentReagents(Solution solution)
{
var absorbentReagents = new List<string>();
foreach (ReagentPrototype solProto in solution.GetReagentPrototypes(_prototypeManager).Keys)
{
if (solProto.Absorbent)
absorbentReagents.Add(solProto.ID);
}
return absorbentReagents.ToArray();
}
public bool CanFullyEvaporate(Solution solution)
{
return solution.GetTotalPrototypeQuantity(EvaporationReagents) == solution.Volume;
return solution.GetTotalPrototypeQuantity(GetEvaporatingReagents(solution)) == solution.Volume;
}
/// <summary>
/// Gets the evaporating speed of the reagents within a solution.
/// The speed at which a solution evaporates is the sum of the speed of all evaporating reagents in it.
/// </summary>
public Dictionary<string, FixedPoint2> GetEvaporationSpeeds(Solution solution)
{
var evaporatingSpeeds = new Dictionary<string, FixedPoint2>();
foreach (ReagentPrototype solProto in solution.GetReagentPrototypes(_prototypeManager).Keys)
{
if (solProto.EvaporationSpeed > FixedPoint2.Zero)
{
evaporatingSpeeds.Add(solProto.ID, solProto.EvaporationSpeed);
}
}
return evaporatingSpeeds;
}
}

View File

@@ -100,7 +100,7 @@ public abstract partial class SharedPuddleSystem : EntitySystem
{
if (CanFullyEvaporate(solution))
args.PushMarkup(Loc.GetString("puddle-component-examine-evaporating"));
else if (solution.GetTotalPrototypeQuantity(EvaporationReagents) > FixedPoint2.Zero)
else if (solution.GetTotalPrototypeQuantity(GetEvaporatingReagents(solution)) > FixedPoint2.Zero)
args.PushMarkup(Loc.GetString("puddle-component-examine-evaporating-partial"));
else
args.PushMarkup(Loc.GetString("puddle-component-examine-evaporating-no"));

View File

@@ -436,6 +436,8 @@
parent: BaseDrink
desc: reagent-desc-water
slippery: true
evaporationSpeed: 0.3
absorbent: true
physicalDesc: reagent-physical-desc-translucent
flavor: water
color: "#75b1f0"