if (!GetAir(uid, out var air))
return;
- var ratio = MathF.Min(1f, args.dt * filter.TransferRate);
+ var ratio = MathF.Min(1f, args.dt * filter.TransferRate * _atmosphere.PumpSpeedup());
var removed = air.RemoveRatio(ratio);
// nothing left to remove from the volume
if (MathHelper.CloseToPercent(removed.TotalMoles, 0f))
public bool ExcitedGroupsSpaceIsAllConsuming { get; private set; }
public float AtmosMaxProcessTime { get; private set; }
public float AtmosTickRate { get; private set; }
+ public float Speedup { get; private set; }
/// <summary>
/// Time between each atmos sub-update. If you are writing an atmos device, use AtmosDeviceUpdateEvent.dt
_cfg.OnValueChanged(CCVars.Superconduction, value => Superconduction = value, true);
_cfg.OnValueChanged(CCVars.AtmosMaxProcessTime, value => AtmosMaxProcessTime = value, true);
_cfg.OnValueChanged(CCVars.AtmosTickRate, value => AtmosTickRate = value, true);
+ _cfg.OnValueChanged(CCVars.AtmosSpeedup, value => Speedup = value, true);
_cfg.OnValueChanged(CCVars.ExcitedGroups, value => ExcitedGroups = value, true);
_cfg.OnValueChanged(CCVars.ExcitedGroupsSpaceIsAllConsuming, value => ExcitedGroupsSpaceIsAllConsuming = value, true);
}
Span<float> tmp = stackalloc float[moles.Length];
NumericsHelpers.Multiply(moles, GasSpecificHeats, tmp);
- return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity);
+ // Adjust heat capacity by speedup, because this is primarily what
+ // determines how quickly gases heat up/cool.
+ return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity) / Speedup;
+ }
+
+ /// <summary>
+ /// Return speedup factor for pumped or flow-based devices that depend on MaxTransferRate.
+ /// </summary>
+ public float PumpSpeedup()
+ {
+ return MathF.Sqrt(Speedup);
}
/// <summary>
return 0;
}
float overPressConst = 300; // pressure difference (in atm) to get 200 L/sec transfer rate
- float alpha = Atmospherics.MaxTransferRate / (float)Math.Sqrt(overPressConst*Atmospherics.OneAtmosphere);
+ float alpha = Atmospherics.MaxTransferRate * _atmosphereSystem.PumpSpeedup() / (float)Math.Sqrt(overPressConst*Atmospherics.OneAtmosphere);
return alpha * (float)Math.Sqrt(inlet.Pressure - outlet.Pressure);
}
return;
// We multiply the transfer rate in L/s by the seconds passed since the last process to get the liters.
- var removed = inlet.Air.RemoveVolume(pump.TransferRate * args.dt);
+ var removed = inlet.Air.RemoveVolume(pump.TransferRate * _atmosphereSystem.PumpSpeedup() * args.dt);
// Some of the gas from the mixture leaks when overclocked.
if (pump.Overclocked)
}
// We multiply the transfer rate in L/s by the seconds passed since the last process to get the liters.
- var transferVol = filter.TransferRate * args.dt;
+ var transferVol = filter.TransferRate * _atmosphereSystem.PumpSpeedup() * args.dt;
if (transferVol <= 0)
{
else
{
comp.Enabled = true;
- transferRate = Math.Min(control * comp.Gain, comp.MaxTransferRate);
+ transferRate = Math.Min(control * comp.Gain, comp.MaxTransferRate * _atmosphereSystem.PumpSpeedup());
}
UpdateAppearance(uid, comp);
var timeDelta = args.dt;
// TODO adjust ratio so that environment does not go above MaxPressure?
- var ratio = MathF.Min(1f, timeDelta * injector.TransferRate / inlet.Air.Volume);
+ var ratio = MathF.Min(1f, timeDelta * injector.TransferRate * _atmosphereSystem.PumpSpeedup() / inlet.Air.Volume);
var removed = inlet.Air.RemoveRatio(ratio);
_atmosphereSystem.Merge(environment, removed);
private void Scrub(float timeDelta, GasVentScrubberComponent scrubber, GasMixture? tile, PipeNode outlet)
{
- Scrub(timeDelta, scrubber.TransferRate, scrubber.PumpDirection, scrubber.FilterGases, tile, outlet.Air);
+ Scrub(timeDelta, scrubber.TransferRate*_atmosphereSystem.PumpSpeedup(), scrubber.PumpDirection, scrubber.FilterGases, tile, outlet.Air);
}
/// <summary>
private bool Scrub(float timeDelta, PortableScrubberComponent scrubber, GasMixture? tile)
{
- return _scrubberSystem.Scrub(timeDelta, scrubber.TransferRate, ScrubberPumpDirection.Scrubbing, scrubber.FilterGases, tile, scrubber.Air);
+ return _scrubberSystem.Scrub(timeDelta, scrubber.TransferRate * _atmosphereSystem.PumpSpeedup(), ScrubberPumpDirection.Scrubbing, scrubber.FilterGases, tile, scrubber.Air);
}
private void UpdateAppearance(EntityUid uid, bool isFull, bool isRunning)
energyReleased = burnRate * Atmospherics.FrezonCoolEnergyReleased * energyModifier;
}
+ energyReleased /= atmosphereSystem.Speedup; // adjust energy to make sure speedup doesn't cause mega temperature rise
if (energyReleased >= 0f)
return ReactionResult.NoReaction;
mixture.AdjustMoles(Gas.CarbonDioxide, plasmaBurnRate * (1.0f - supersaturation));
energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate;
+ energyReleased /= atmosphereSystem.Speedup; // adjust energy to make sure speedup doesn't cause mega temperature rise
mixture.ReactionResults[GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate);
}
}
mixture.ReactionResults[GasReaction.Fire] += burnedFuel;
}
+ energyReleased /= atmosphereSystem.Speedup; // adjust energy to make sure speedup doesn't cause mega temperature rise
if (energyReleased > 0)
{
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture);
public static readonly CVarDef<float> AtmosTickRate =
CVarDef.Create("atmos.tickrate", 15f, CVar.SERVERONLY);
+ /// <summary>
+ /// Scale factor for how fast things happen in our atmosphere
+ /// simulation compared to real life. 1x means that a room takes as
+ /// long to heat up in game as real life. Players typically expect
+ /// things to happen faster in-game.
+ /// </summary>
+ public static readonly CVarDef<float> AtmosSpeedup =
+ CVarDef.Create("atmos.speedup", 64f, CVar.SERVERONLY);
+
/*
* MIDI instruments
*/
True: { state: freezerOn }
False: { state: freezerOff }
- type: GasThermoMachine
- coefficientOfPerformance: -64
+ coefficientOfPerformance: -3.9
- type: ApcPowerReceiver
powerDisabled: true #starts off
- type: Machine
True: { state: heaterOn }
False: { state: heaterOff }
- type: GasThermoMachine
- coefficientOfPerformance: 32
+ coefficientOfPerformance: 0.95
- type: ApcPowerReceiver
powerDisabled: true #starts off
- type: Machine
# It fires processing on behalf of its connected circulators.
- type: AtmosDevice
- type: TegGenerator
- powerFactor: 0.025
- type: DeviceNetwork
deviceNetId: AtmosDevices