Limit atmos device rates (#6533)

This commit is contained in:
Leon Friedrich
2022-03-01 03:39:30 +13:00
committed by GitHub
parent ffed5eec81
commit ee7d0440f3
20 changed files with 220 additions and 116 deletions

View File

@@ -1,4 +1,3 @@
using System;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Monitor.Components;
using Content.Server.Atmos.Monitor.Systems;
@@ -12,12 +11,10 @@ using Content.Server.NodeContainer.Nodes;
using Content.Server.Power.Components;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Atmos.Visuals;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Timing;
namespace Content.Server.Atmos.Piping.Unary.EntitySystems
{
@@ -26,6 +23,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
{
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
public override void Initialize()
{
@@ -49,7 +47,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
}
if (!vent.Enabled
|| !EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer)
|| !TryComp(uid, out AtmosDeviceComponent? device)
|| !TryComp(uid, out NodeContainerComponent? nodeContainer)
|| !nodeContainer.TryGetNode(vent.InletName, out PipeNode? pipe))
{
appearance?.SetData(VentPumpVisuals.State, VentPumpState.Off);
@@ -65,43 +64,71 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
return;
}
if (vent.PumpDirection == VentPumpDirection.Releasing)
var timeDelta = (_gameTiming.CurTime - device.LastProcess).TotalSeconds;
var pressureDelta = (float) timeDelta * vent.TargetPressureChange;
if (vent.PumpDirection == VentPumpDirection.Releasing && pipe.Air.Pressure > 0)
{
appearance?.SetData(VentPumpVisuals.State, VentPumpState.Out);
var pressureDelta = 10000f;
if (environment.Pressure > vent.MaxPressure)
return;
if ((vent.PressureChecks & VentPressureBound.ExternalBound) != 0)
pressureDelta = MathF.Min(pressureDelta, vent.ExternalPressureBound - environment.Pressure);
if (pressureDelta <= 0)
return;
// how many moles to transfer to change external pressure by pressureDelta
// (ignoring temperature differences because I am lazy)
var transferMoles = pressureDelta * environment.Volume / (pipe.Air.Temperature * Atmospherics.R);
// limit transferMoles so the source doesn't go below its bound.
if ((vent.PressureChecks & VentPressureBound.InternalBound) != 0)
pressureDelta = MathF.Min(pressureDelta, pipe.Air.Pressure - vent.InternalPressureBound);
if (pressureDelta > 0 && pipe.Air.Temperature > 0)
{
var transferMoles = pressureDelta * environment.Volume / (pipe.Air.Temperature * Atmospherics.R);
var internalDelta = pipe.Air.Pressure - vent.InternalPressureBound;
_atmosphereSystem.Merge(environment, pipe.Air.Remove(transferMoles));
if (internalDelta <= 0)
return;
var maxTransfer = internalDelta * pipe.Air.Volume / (pipe.Air.Temperature * Atmospherics.R);
transferMoles = MathF.Min(transferMoles, maxTransfer);
}
_atmosphereSystem.Merge(environment, pipe.Air.Remove(transferMoles));
}
else if (vent.PumpDirection == VentPumpDirection.Siphoning && environment.Pressure > 0)
{
appearance?.SetData(VentPumpVisuals.State, VentPumpState.In);
var ourMultiplier = pipe.Air.Volume / (environment.Temperature * Atmospherics.R);
var molesDelta = 10000f * ourMultiplier;
if ((vent.PressureChecks & VentPressureBound.ExternalBound) != 0)
molesDelta = MathF.Min(molesDelta,
(environment.Pressure - vent.ExternalPressureBound) * environment.Volume /
(environment.Temperature * Atmospherics.R));
if (pipe.Air.Pressure > vent.MaxPressure)
return;
if ((vent.PressureChecks & VentPressureBound.InternalBound) != 0)
molesDelta = MathF.Min(molesDelta, (vent.InternalPressureBound - pipe.Air.Pressure) * ourMultiplier);
pressureDelta = MathF.Min(pressureDelta, vent.InternalPressureBound - pipe.Air.Pressure);
if (molesDelta > 0)
if (pressureDelta <= 0)
return;
// how many moles to transfer to change internal pressure by pressureDelta
// (ignoring temperature differences because I am lazy)
var transferMoles = pressureDelta * pipe.Air.Volume / (environment.Temperature * Atmospherics.R);
// limit transferMoles so the source doesn't go below its bound.
if ((vent.PressureChecks & VentPressureBound.ExternalBound) != 0)
{
var removed = environment.Remove(molesDelta);
_atmosphereSystem.Merge(pipe.Air, removed);
var externalDelta = environment.Pressure - vent.ExternalPressureBound;
if (externalDelta <= 0)
return;
var maxTransfer = externalDelta * environment.Volume / (environment.Temperature * Atmospherics.R);
transferMoles = MathF.Min(transferMoles, maxTransfer);
}
_atmosphereSystem.Merge(pipe.Air, environment.Remove(transferMoles));
}
}