Files
tbd-station-14/Content.Server/Atmos/EntitySystems/HeatExchangerSystem.cs
Ilya246 f99741937c Adjust radiator flow rate and fix space detection (#18764)
The previous dT did not accurately represent the actual tick time. This is being investigated separately.

Check environment mixture for zero moles, because space mixtures do not necessarily return null.

While here, make an unrelated style change involving TryComp.
2023-08-06 10:23:43 -07:00

100 lines
3.5 KiB
C#

using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Atmos.Piping.Unary.Components;
using Content.Server.Atmos;
using Content.Server.Atmos.Components;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Server.NodeContainer;
using Content.Shared.Atmos.Piping;
using Content.Shared.Atmos;
using Content.Shared.CCVar;
using Content.Shared.Interaction;
using JetBrains.Annotations;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
namespace Content.Server.Atmos.EntitySystems;
public sealed class HeatExchangerSystem : EntitySystem
{
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
[Dependency] private IGameTiming _gameTiming = default!;
float tileLoss;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<HeatExchangerComponent, AtmosDeviceUpdateEvent>(OnAtmosUpdate);
// Getting CVars is expensive, don't do it every tick
_cfg.OnValueChanged(CCVars.SuperconductionTileLoss, CacheTileLoss, true);
}
public override void Shutdown()
{
base.Shutdown();
_cfg.UnsubValueChanged(CCVars.SuperconductionTileLoss, CacheTileLoss);
}
private void CacheTileLoss(float val)
{
tileLoss = val;
}
private void OnAtmosUpdate(EntityUid uid, HeatExchangerComponent comp, AtmosDeviceUpdateEvent args)
{
if (!TryComp(uid, out NodeContainerComponent? nodeContainer)
|| !TryComp(uid, out AtmosDeviceComponent? device)
|| !_nodeContainer.TryGetNode(nodeContainer, comp.InletName, out PipeNode? inlet)
|| !_nodeContainer.TryGetNode(nodeContainer, comp.OutletName, out PipeNode? outlet))
{
return;
}
// Positive dN flows from inlet to outlet
var dt = (float)(_gameTiming.CurTime - device.LastProcess).TotalSeconds;
var dP = inlet.Air.Pressure - outlet.Air.Pressure;
var dN = comp.G*dP*dt;
GasMixture xfer;
if (dN > 0)
xfer = inlet.Air.Remove(dN);
else
xfer = outlet.Air.Remove(-dN);
var radTemp = Atmospherics.TCMB;
// Convection
var environment = _atmosphereSystem.GetContainingMixture(uid, true, true);
if (environment != null && environment.TotalMoles != 0)
{
radTemp = environment.Temperature;
// Positive dT is from pipe to surroundings
var dT = xfer.Temperature - environment.Temperature;
var dE = comp.K * dT * dt;
var envLim = Math.Abs(_atmosphereSystem.GetHeatCapacity(environment) * dT * dt);
var xferLim = Math.Abs(_atmosphereSystem.GetHeatCapacity(xfer) * dT * dt);
var dEactual = Math.Sign(dE) * Math.Min(Math.Abs(dE), Math.Min(envLim, xferLim));
_atmosphereSystem.AddHeat(xfer, -dEactual);
_atmosphereSystem.AddHeat(environment, dEactual);
}
// Radiation
float dTR = xfer.Temperature - radTemp;
float a0 = tileLoss / MathF.Pow(Atmospherics.T20C, 4);
float dER = comp.alpha * a0 * MathF.Pow(dTR, 4) * dt;
_atmosphereSystem.AddHeat(xfer, -dER);
if (dN > 0)
_atmosphereSystem.Merge(outlet.Air, xfer);
else
_atmosphereSystem.Merge(inlet.Air, xfer);
}
}