From 03d6b0ced71b991e85b35470e506d2991e5a7200 Mon Sep 17 00:00:00 2001
From: 0x6273 <0x40@keemail.me>
Date: Fri, 7 Jul 2023 03:18:56 +0200
Subject: [PATCH] Add chem solution atmos heating and cooling (#17854)
---
.../Atmos/EntitySystems/AtmosphereSystem.cs | 2 +-
.../SolutionGasHeatConductivityComponent.cs | 22 +++++++++++
.../SolutionGasHeatConductivitySystem.cs | 37 +++++++++++++++++++
.../Prototypes/Entities/Effects/puddle.yml | 3 ++
.../Objects/Consumable/Drinks/drinks.yml | 3 ++
.../Objects/Consumable/Drinks/drinks_cans.yml | 3 ++
.../Objects/Consumable/Drinks/drinks_cups.yml | 3 ++
.../Consumable/Drinks/drinks_special.yml | 3 ++
.../Consumable/Drinks/trash_drinks.yml | 3 ++
.../Entities/Objects/Specific/chemistry.yml | 6 +++
10 files changed, 84 insertions(+), 1 deletion(-)
create mode 100644 Content.Server/Chemistry/Components/SolutionManager/SolutionGasHeatConductivityComponent.cs
create mode 100644 Content.Server/Chemistry/EntitySystems/SolutionGasHeatConductivitySystem.cs
diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs
index 5d3e989e41..b964da9c5a 100644
--- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs
+++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs
@@ -31,7 +31,7 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem
[Dependency] private readonly TransformSystem _transformSystem = default!;
[Dependency] private readonly TileSystem _tile = default!;
- private const float ExposedUpdateDelay = 1f;
+ public const float ExposedUpdateDelay = 1f;
private float _exposedTimer = 0f;
public override void Initialize()
diff --git a/Content.Server/Chemistry/Components/SolutionManager/SolutionGasHeatConductivityComponent.cs b/Content.Server/Chemistry/Components/SolutionManager/SolutionGasHeatConductivityComponent.cs
new file mode 100644
index 0000000000..a70bc3a08b
--- /dev/null
+++ b/Content.Server/Chemistry/Components/SolutionManager/SolutionGasHeatConductivityComponent.cs
@@ -0,0 +1,22 @@
+namespace Content.Server.Chemistry.Components.SolutionManager;
+
+///
+/// Lets the solution conduct heat to/from atmos gases.
+///
+[RegisterComponent]
+public sealed class SolutionGasHeatConductivityComponent : Component
+{
+ ///
+ /// Solution that conducts heat.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("solution")]
+ public string Solution { get; set; } = "default";
+
+ ///
+ /// The heat conductivity between the gas and solution.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("wattsPerKelvin")]
+ public float WattsPerKelvin = 1;
+}
diff --git a/Content.Server/Chemistry/EntitySystems/SolutionGasHeatConductivitySystem.cs b/Content.Server/Chemistry/EntitySystems/SolutionGasHeatConductivitySystem.cs
new file mode 100644
index 0000000000..0b81bf9c8a
--- /dev/null
+++ b/Content.Server/Chemistry/EntitySystems/SolutionGasHeatConductivitySystem.cs
@@ -0,0 +1,37 @@
+using Content.Server.Atmos.EntitySystems;
+using Content.Server.Chemistry.Components.SolutionManager;
+using Robust.Shared.Timing;
+
+namespace Content.Server.Chemistry.EntitySystems;
+
+public sealed class SolutionGasHeatConductivitySystem : EntitySystem
+{
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+ [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
+ [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
+
+ ///
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(AtmosUpdate);
+ }
+
+ private void AtmosUpdate(EntityUid uid, SolutionGasHeatConductivityComponent solutionGasHeatConductivity, ref AtmosExposedUpdateEvent args)
+ {
+ if (!_solutionContainerSystem.TryGetSolution(uid, solutionGasHeatConductivity.Solution, out var solution) || solution.Volume == 0)
+ return;
+
+ var heatDifferenceKelvin = args.GasMixture.Temperature - solution.Temperature;
+ if (Math.Abs(heatDifferenceKelvin) < 0.5)
+ return; // close enough
+
+ var thermalEnergyTransferWatts = heatDifferenceKelvin * solutionGasHeatConductivity.WattsPerKelvin;
+ var thermalEnergyTransferJoules = thermalEnergyTransferWatts * AtmosphereSystem.ExposedUpdateDelay;
+
+ _solutionContainerSystem.AddThermalEnergy(uid, solution, thermalEnergyTransferJoules);
+ var gasHeatCapacity = _atmosphereSystem.GetHeatCapacity(args.GasMixture);
+ args.GasMixture.Temperature += gasHeatCapacity == 0 ? 0 : -thermalEnergyTransferJoules / gasHeatCapacity;
+ }
+}
diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml
index bf2b56067e..d627dc20bb 100644
--- a/Resources/Prototypes/Entities/Effects/puddle.yml
+++ b/Resources/Prototypes/Entities/Effects/puddle.yml
@@ -142,6 +142,9 @@
- type: SolutionContainerManager
solutions:
puddle: { maxVol: 1000 }
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: puddle
- type: Puddle
- type: Appearance
- type: EdgeSpreader
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml
index 4baaa3f3bc..7499e6cd38 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml
@@ -30,6 +30,9 @@
solution: drink
- type: DrainableSolution
solution: drink
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: drink
- type: UserInterface
interfaces:
- key: enum.TransferAmountUiKey.Key
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml
index 34f27450c7..8873c72e48 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml
@@ -34,6 +34,9 @@
solution: drink
- type: DrainableSolution
solution: drink
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: drink
- type: Appearance
- type: GenericVisualizer
visuals:
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml
index fa91eb4fd4..dd9800820f 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml
@@ -21,6 +21,9 @@
- type: SolutionTransfer
canChangeTransferAmount: true
maxTransferAmount: 10
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: drink
- type: UserInterface
interfaces:
- key: enum.TransferAmountUiKey.Key
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml
index 684681074e..7f0b081123 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml
@@ -22,6 +22,9 @@
canChangeTransferAmount: true
- type: Spillable
solution: drink
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: drink
- type: Sprite
sprite: Objects/Consumable/Drinks/shaker.rsi
state: icon
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml
index a1a1eef3f3..ac0b95cf66 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/trash_drinks.yml
@@ -33,6 +33,9 @@
solution: drink
- type: DrainableSolution
solution: drink
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: drink
- type: UserInterface
interfaces:
- key: enum.TransferAmountUiKey.Key
diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml
index 83947e6eb5..ba743d7f70 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml
@@ -40,6 +40,9 @@
solution: beaker
- type: SolutionTransfer
canChangeTransferAmount: true
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: beaker
- type: UserInterface
interfaces:
- key: enum.TransferAmountUiKey.Key
@@ -131,6 +134,9 @@
solution: beaker
- type: SolutionTransfer
canChangeTransferAmount: true
+ - type: AtmosExposed
+ - type: SolutionGasHeatConductivity
+ solution: beaker
- type: UserInterface
interfaces:
- key: enum.TransferAmountUiKey.Key