2023-12-13 22:35:44 -05:00
using Content.Server.Atmos.EntitySystems ;
using Content.Server.Atmos.Piping.Components ;
using Content.Server.Atmos.Piping.Unary.Components ;
using Content.Server.NodeContainer ;
using Content.Server.NodeContainer.EntitySystems ;
using Content.Server.NodeContainer.Nodes ;
using Content.Server.Power.Components ;
2023-12-28 20:45:42 -07:00
using Content.Server.Power.EntitySystems ;
2023-12-29 04:47:43 -08:00
using Content.Shared.Atmos ;
2023-12-28 20:45:42 -07:00
using Content.Shared.Chemistry.EntitySystems ;
2023-12-29 04:47:43 -08:00
using Content.Shared.FixedPoint ;
using JetBrains.Annotations ;
2023-12-13 22:35:44 -05:00
namespace Content.Server.Atmos.Piping.Unary.EntitySystems ;
[UsedImplicitly]
public sealed class GasCondenserSystem : EntitySystem
{
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default ! ;
[Dependency] private readonly PowerReceiverSystem _power = default ! ;
[Dependency] private readonly NodeContainerSystem _nodeContainer = default ! ;
2023-12-29 04:47:43 -08:00
[Dependency] private readonly SharedSolutionContainerSystem _solution = default ! ;
2023-12-13 22:35:44 -05:00
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeLocalEvent < GasCondenserComponent , AtmosDeviceUpdateEvent > ( OnCondenserUpdated ) ;
}
2023-12-29 04:47:43 -08:00
private void OnCondenserUpdated ( Entity < GasCondenserComponent > entity , ref AtmosDeviceUpdateEvent args )
2023-12-13 22:35:44 -05:00
{
2024-03-30 17:17:53 +13:00
if ( ! ( TryComp < ApcPowerReceiverComponent > ( entity , out var receiver ) & & _power . IsPowered ( entity , receiver ) )
| | ! _nodeContainer . TryGetNode ( entity . Owner , entity . Comp . Inlet , out PipeNode ? inlet )
2023-12-29 04:47:43 -08:00
| | ! _solution . ResolveSolution ( entity . Owner , entity . Comp . SolutionId , ref entity . Comp . Solution , out var solution ) )
2023-12-13 22:35:44 -05:00
{
return ;
}
if ( solution . AvailableVolume = = 0 | | inlet . Air . TotalMoles = = 0 )
return ;
var molesToConvert = NumberOfMolesToConvert ( receiver , inlet . Air , args . dt ) ;
var removed = inlet . Air . Remove ( molesToConvert ) ;
for ( var i = 0 ; i < Atmospherics . TotalNumberOfGases ; i + + )
{
2024-03-24 03:34:56 +11:00
var moles = removed [ i ] ;
2023-12-13 22:35:44 -05:00
if ( moles < = 0 )
continue ;
2023-12-29 04:47:43 -08:00
if ( _atmosphereSystem . GetGas ( i ) . Reagent is not { } gasReagent )
2023-12-13 22:35:44 -05:00
continue ;
2023-12-29 04:47:43 -08:00
var moleToReagentMultiplier = entity . Comp . MolesToReagentMultiplier ;
var amount = FixedPoint2 . Min ( FixedPoint2 . New ( moles * moleToReagentMultiplier ) , solution . AvailableVolume ) ;
if ( amount < = 0 )
2023-12-28 20:45:42 -07:00
continue ;
2023-12-28 17:58:14 -08:00
2023-12-29 04:47:43 -08:00
solution . AddReagent ( gasReagent , amount ) ;
2023-12-13 22:35:44 -05:00
// if we have leftover reagent, then convert it back to moles and put it back in the mixture.
2023-12-29 04:47:43 -08:00
inlet . Air . AdjustMoles ( i , moles - ( amount . Float ( ) / moleToReagentMultiplier ) ) ;
2023-12-13 22:35:44 -05:00
}
2023-12-29 04:47:43 -08:00
_solution . UpdateChemicals ( entity . Comp . Solution . Value ) ;
2023-12-13 22:35:44 -05:00
}
public float NumberOfMolesToConvert ( ApcPowerReceiverComponent comp , GasMixture mix , float dt )
{
2023-12-15 17:02:21 -05:00
var hc = _atmosphereSystem . GetHeatCapacity ( mix , true ) ;
2023-12-13 22:35:44 -05:00
var alpha = 0.8f ; // tuned to give us 1-ish u/second of reagent conversion
// ignores the energy needed to cool down the solution to the condensation point, but that probably adds too much difficulty and so let's not simulate that
var energy = comp . Load * dt ;
return energy / ( alpha * hc ) ;
}
}