Files
tbd-station-14/Content.Server/Atmos/EntitySystems/GasMinerSystem.cs
Mervill b8d10a3f5e Add verbose (client predicted!) examine text to Gas Miners (#30480)
* add verbose examine text to gas miners so their behaviour can be understood

* no need for these to be properties

* use an enum instead of two booleans for the miner state

* require the gas miner to be anchored in order to not be disabled

* xmldoc

* pr feedback

* file-scope namespace

* it's to late to hide my transgressions in a rebase

* turns out the normal examine distance is totally fine for this
2024-08-08 12:14:31 +10:00

91 lines
3.1 KiB
C#

using System.Diagnostics.CodeAnalysis;
using Content.Server.Atmos.Piping.Components;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.EntitySystems;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
namespace Content.Server.Atmos.EntitySystems;
[UsedImplicitly]
public sealed class GasMinerSystem : SharedGasMinerSystem
{
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly TransformSystem _transformSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GasMinerComponent, AtmosDeviceUpdateEvent>(OnMinerUpdated);
}
private void OnMinerUpdated(Entity<GasMinerComponent> ent, ref AtmosDeviceUpdateEvent args)
{
var miner = ent.Comp;
var oldState = miner.MinerState;
float toSpawn;
if (!GetValidEnvironment(ent, out var environment) || !Transform(ent).Anchored)
{
miner.MinerState = GasMinerState.Disabled;
}
// SpawnAmount is declared in mol/s so to get the amount of gas we hope to mine, we have to multiply this by
// how long we have been waiting to spawn it and further cap the number according to the miner's state.
else if ((toSpawn = CapSpawnAmount(ent, miner.SpawnAmount * args.dt, environment)) == 0)
{
miner.MinerState = GasMinerState.Idle;
}
else
{
miner.MinerState = GasMinerState.Working;
// Time to mine some gas.
var merger = new GasMixture(1) { Temperature = miner.SpawnTemperature };
merger.SetMoles(miner.SpawnGas, toSpawn);
_atmosphereSystem.Merge(environment, merger);
}
if (miner.MinerState != oldState)
{
Dirty(ent);
}
}
private bool GetValidEnvironment(Entity<GasMinerComponent> ent, [NotNullWhen(true)] out GasMixture? environment)
{
var (uid, miner) = ent;
var transform = Transform(uid);
var position = _transformSystem.GetGridOrMapTilePosition(uid, transform);
// Treat space as an invalid environment
if (_atmosphereSystem.IsTileSpace(transform.GridUid, transform.MapUid, position))
{
environment = null;
return false;
}
environment = _atmosphereSystem.GetContainingMixture((uid, transform), true, true);
return environment != null;
}
private float CapSpawnAmount(Entity<GasMinerComponent> ent, float toSpawnTarget, GasMixture environment)
{
var (uid, miner) = ent;
// How many moles could we theoretically spawn. Cap by pressure and amount.
var allowableMoles = Math.Min(
(miner.MaxExternalPressure - environment.Pressure) * environment.Volume / (miner.SpawnTemperature * Atmospherics.R),
miner.MaxExternalAmount - environment.TotalMoles);
var toSpawnReal = Math.Clamp(allowableMoles, 0f, toSpawnTarget);
if (toSpawnReal < Atmospherics.GasMinMoles) {
return 0f;
}
return toSpawnReal;
}
}