]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add verbose (client predicted!) examine text to Gas Miners (#30480)
authorMervill <mervills.email@gmail.com>
Thu, 8 Aug 2024 02:14:31 +0000 (19:14 -0700)
committerGitHub <noreply@github.com>
Thu, 8 Aug 2024 02:14:31 +0000 (12:14 +1000)
* 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

Content.Client/Atmos/EntitySystems/GasMinerSystem.cs [new file with mode: 0644]
Content.Server/Atmos/EntitySystems/GasMinerSystem.cs [new file with mode: 0644]
Content.Server/Atmos/Piping/Other/Components/GasMinerComponent.cs [deleted file]
Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs [deleted file]
Content.Shared/Atmos/Components/GasMinerComponent.cs [new file with mode: 0644]
Content.Shared/Atmos/EntitySystems/SharedGasMinerSystem.cs [new file with mode: 0644]
Resources/Locale/en-US/atmos/gas-miner-component.ftl [new file with mode: 0644]

diff --git a/Content.Client/Atmos/EntitySystems/GasMinerSystem.cs b/Content.Client/Atmos/EntitySystems/GasMinerSystem.cs
new file mode 100644 (file)
index 0000000..aec138e
--- /dev/null
@@ -0,0 +1,10 @@
+using Content.Shared.Atmos.EntitySystems;
+using JetBrains.Annotations;
+
+namespace Content.Client.Atmos.EntitySystems;
+
+[UsedImplicitly]
+public sealed class GasMinerSystem : SharedGasMinerSystem
+{
+
+}
diff --git a/Content.Server/Atmos/EntitySystems/GasMinerSystem.cs b/Content.Server/Atmos/EntitySystems/GasMinerSystem.cs
new file mode 100644 (file)
index 0000000..f7a3b9e
--- /dev/null
@@ -0,0 +1,90 @@
+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;
+    }
+}
diff --git a/Content.Server/Atmos/Piping/Other/Components/GasMinerComponent.cs b/Content.Server/Atmos/Piping/Other/Components/GasMinerComponent.cs
deleted file mode 100644 (file)
index 1775ec5..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-using Content.Shared.Atmos;
-
-namespace Content.Server.Atmos.Piping.Other.Components
-{
-    [RegisterComponent]
-    public sealed partial class GasMinerComponent : Component
-    {
-        [ViewVariables(VVAccess.ReadWrite)]
-        public bool Enabled { get; set; } = true;
-
-        [ViewVariables(VVAccess.ReadOnly)]
-        public bool Idle { get; set; } = false;
-
-        /// <summary>
-        ///      If the number of moles in the external environment exceeds this number, no gas will be mined.
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("maxExternalAmount")]
-        public float MaxExternalAmount { get; set; } = float.PositiveInfinity;
-
-        /// <summary>
-        ///      If the pressure (in kPA) of the external environment exceeds this number, no gas will be mined.
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("maxExternalPressure")]
-        public float MaxExternalPressure { get; set; } = Atmospherics.GasMinerDefaultMaxExternalPressure;
-
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("spawnGas")]
-        public Gas? SpawnGas { get; set; } = null;
-
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("spawnTemperature")]
-        public float SpawnTemperature { get; set; } = Atmospherics.T20C;
-
-        /// <summary>
-        ///     Number of moles created per second when the miner is working.
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("spawnAmount")]
-        public float SpawnAmount { get; set; } = Atmospherics.MolesCellStandard * 20f;
-    }
-}
diff --git a/Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs b/Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs
deleted file mode 100644 (file)
index dd46fb6..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-using Content.Server.Atmos.EntitySystems;
-using Content.Server.Atmos.Piping.Components;
-using Content.Server.Atmos.Piping.Other.Components;
-using Content.Shared.Atmos;
-using JetBrains.Annotations;
-using Robust.Server.GameObjects;
-
-namespace Content.Server.Atmos.Piping.Other.EntitySystems
-{
-    [UsedImplicitly]
-    public sealed class GasMinerSystem : EntitySystem
-    {
-        [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;
-
-            if (!GetValidEnvironment(ent, out var environment))
-            {
-                miner.Idle = true;
-                return;
-            }
-
-            // 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.
-            var toSpawn = CapSpawnAmount(ent, miner.SpawnAmount * args.dt, environment);
-            miner.Idle = toSpawn == 0;
-            if (miner.Idle || !miner.Enabled || !miner.SpawnGas.HasValue)
-                return;
-
-            // Time to mine some gas.
-
-            var merger = new GasMixture(1) { Temperature = miner.SpawnTemperature };
-            merger.SetMoles(miner.SpawnGas.Value, toSpawn);
-
-            _atmosphereSystem.Merge(environment, merger);
-        }
-
-        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;
-        }
-    }
-}
diff --git a/Content.Shared/Atmos/Components/GasMinerComponent.cs b/Content.Shared/Atmos/Components/GasMinerComponent.cs
new file mode 100644 (file)
index 0000000..43f3032
--- /dev/null
@@ -0,0 +1,60 @@
+using Robust.Shared.Serialization;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Atmos.Components;
+
+[NetworkedComponent]
+[AutoGenerateComponentState]
+[RegisterComponent]
+public sealed partial class GasMinerComponent : Component
+{
+    /// <summary>
+    ///     Operational state of the miner.
+    /// </summary>
+    [AutoNetworkedField]
+    [ViewVariables(VVAccess.ReadOnly)]
+    public GasMinerState MinerState = GasMinerState.Disabled;
+
+    /// <summary>
+    ///      If the number of moles in the external environment exceeds this number, no gas will be mined.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField]
+    public float MaxExternalAmount = float.PositiveInfinity;
+
+    /// <summary>
+    ///      If the pressure (in kPA) of the external environment exceeds this number, no gas will be mined.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField]
+    public float MaxExternalPressure = Atmospherics.GasMinerDefaultMaxExternalPressure;
+
+    /// <summary>
+    ///     Gas to spawn.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField(required: true)]
+    public Gas SpawnGas;
+
+    /// <summary>
+    ///     Temperature in Kelvin.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField]
+    public float SpawnTemperature = Atmospherics.T20C;
+
+    /// <summary>
+    ///     Number of moles created per second when the miner is working.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField]
+    public float SpawnAmount = Atmospherics.MolesCellStandard * 20f;
+}
+
+[Serializable, NetSerializable]
+public enum GasMinerState : byte
+{
+    Disabled,
+    Idle,
+    Working,
+}
diff --git a/Content.Shared/Atmos/EntitySystems/SharedGasMinerSystem.cs b/Content.Shared/Atmos/EntitySystems/SharedGasMinerSystem.cs
new file mode 100644 (file)
index 0000000..957ff6f
--- /dev/null
@@ -0,0 +1,55 @@
+using Content.Shared.Atmos.Components;
+using Content.Shared.Examine;
+using Content.Shared.Temperature;
+
+namespace Content.Shared.Atmos.EntitySystems;
+
+public abstract class SharedGasMinerSystem : EntitySystem
+{
+    [Dependency] private readonly SharedAtmosphereSystem _sharedAtmosphereSystem = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<GasMinerComponent, ExaminedEvent>(OnExamine);
+    }
+
+    private void OnExamine(Entity<GasMinerComponent> ent, ref ExaminedEvent args)
+    {
+        var component = ent.Comp;
+
+        using (args.PushGroup(nameof(GasMinerComponent)))
+        {
+            args.PushMarkup(Loc.GetString("gas-miner-mines-text",
+                ("gas", Loc.GetString(_sharedAtmosphereSystem.GetGas(component.SpawnGas).Name))));
+
+            args.PushText(Loc.GetString("gas-miner-amount-text",
+                ("moles", $"{component.SpawnAmount:0.#}")));
+
+            args.PushText(Loc.GetString("gas-miner-temperature-text",
+                ("tempK", $"{component.SpawnTemperature:0.#}"),
+                ("tempC", $"{TemperatureHelpers.KelvinToCelsius(component.SpawnTemperature):0.#}")));
+
+            if (component.MaxExternalAmount < float.PositiveInfinity)
+            {
+                args.PushText(Loc.GetString("gas-miner-moles-cutoff-text",
+                    ("moles", $"{component.MaxExternalAmount:0.#}")));
+            }
+
+            if (component.MaxExternalPressure < float.PositiveInfinity)
+            {
+                args.PushText(Loc.GetString("gas-miner-pressure-cutoff-text",
+                    ("pressure", $"{component.MaxExternalPressure:0.#}")));
+            }
+
+            args.AddMarkup(component.MinerState switch
+            {
+                GasMinerState.Disabled => Loc.GetString("gas-miner-state-disabled-text"),
+                GasMinerState.Idle => Loc.GetString("gas-miner-state-idle-text"),
+                GasMinerState.Working => Loc.GetString("gas-miner-state-working-text"),
+                // C# pattern matching is not exhaustive for enums
+                _ => throw new IndexOutOfRangeException(nameof(component.MinerState)),
+            });
+        }
+    }
+}
diff --git a/Resources/Locale/en-US/atmos/gas-miner-component.ftl b/Resources/Locale/en-US/atmos/gas-miner-component.ftl
new file mode 100644 (file)
index 0000000..87016e4
--- /dev/null
@@ -0,0 +1,11 @@
+gas-miner-mines-text = It mines [color=lightgray]{$gas}[/color] when active.
+
+gas-miner-amount-text = It mines {$moles} moles of gas a second when active.
+gas-miner-temperature-text = Mined gas temp: {$tempK}K ({$tempC}°C).
+
+gas-miner-moles-cutoff-text = Surrounding moles cutoff: {$moles} moles.
+gas-miner-pressure-cutoff-text = Surrounding pressure cutoff: {$pressure} kPA.
+
+gas-miner-state-working-text = The miner is [color=green]active[/color] and mining gas.
+gas-miner-state-idle-text = The miner is [color=yellow]idle[/color] and not mining gas.
+gas-miner-state-disabled-text = The miner is [color=red]disabled[/color] and not mining gas.
\ No newline at end of file