]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Show volume on the gas analyzer (#25720)
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Wed, 17 Apr 2024 17:42:24 +0000 (19:42 +0200)
committerGitHub <noreply@github.com>
Wed, 17 Apr 2024 17:42:24 +0000 (09:42 -0800)
The gas analyzer now shows the volume of pipes, tanks, canisters and the environment.

Adjust gas analyzers so that the volume and number of moles shown corresponds to only the scanned element, e.g. a canister or single pipe in a pipenet.

12 files changed:
Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs
Content.Server/Atmos/EntitySystems/GasAnalyzerSystem.cs
Content.Server/Atmos/EntitySystems/GasTankSystem.cs
Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs
Content.Server/Atmos/Piping/Trinary/EntitySystems/GasMixerSystem.cs
Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs
Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs
Content.Server/Atmos/Portable/PortableScrubberSystem.cs
Content.Server/Medical/CryoPodSystem.cs
Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs
Content.Shared/Atmos/Components/GasAnalyzerComponent.cs
Resources/Locale/en-US/atmos/gas-analyzer-component.ftl

index b105e629cfa6e1c81cb829d52f1d4d9634231aff..b54af3a5871f0a1001580b95d7b28fb9a3915762 100644 (file)
@@ -163,6 +163,26 @@ namespace Content.Client.Atmos.UI
             parent.AddChild(panel);
             panel.AddChild(dataContainer);
 
+            // Volume label
+            var volBox = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Horizontal };
+
+            volBox.AddChild(new Label
+            {
+                Text = Loc.GetString("gas-analyzer-window-volume-text")
+            });
+            volBox.AddChild(new Control
+            {
+                MinSize = new Vector2(10, 0),
+                HorizontalExpand = true
+            });
+            volBox.AddChild(new Label
+            {
+                Text = Loc.GetString("gas-analyzer-window-volume-val-text", ("volume", $"{gasMix.Volume:0.##}")),
+                Align = Label.AlignMode.Right,
+                HorizontalExpand = true
+            });
+            dataContainer.AddChild(volBox);
+
             // Pressure label
             var presBox = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Horizontal };
 
index 2eedb1c6a7fb7f0278497131d7a8c16e48a853d1..1f5ca80935285f637e0cac1587d62c5a024d8c78 100644 (file)
@@ -132,7 +132,7 @@ namespace Content.Server.Atmos.EntitySystems
         /// </summary>
         private void OnDisabledMessage(EntityUid uid, GasAnalyzerComponent component, GasAnalyzerDisableMessage message)
         {
-            if (message.Session.AttachedEntity is not {Valid: true})
+            if (message.Session.AttachedEntity is not { Valid: true })
                 return;
             DisableAnalyzer(uid, component);
         }
@@ -169,7 +169,7 @@ namespace Content.Server.Atmos.EntitySystems
                 // Check if position is out of range => don't update and disable
                 if (!component.LastPosition.Value.InRange(EntityManager, _transform, userPos, SharedInteractionSystem.InteractionRange))
                 {
-                    if(component.User is { } userId && component.Enabled)
+                    if (component.User is { } userId && component.Enabled)
                         _popup.PopupEntity(Loc.GetString("gas-analyzer-shutoff"), userId, userId);
                     DisableAnalyzer(uid, component, component.User);
                     return false;
@@ -182,13 +182,13 @@ namespace Content.Server.Atmos.EntitySystems
             var tileMixture = _atmo.GetContainingMixture(uid, true);
             if (tileMixture != null)
             {
-                gasMixList.Add(new GasMixEntry(Loc.GetString("gas-analyzer-window-environment-tab-label"), tileMixture.Pressure, tileMixture.Temperature,
+                gasMixList.Add(new GasMixEntry(Loc.GetString("gas-analyzer-window-environment-tab-label"), tileMixture.Volume, tileMixture.Pressure, tileMixture.Temperature,
                     GenerateGasEntryArray(tileMixture)));
             }
             else
             {
                 // No gases were found
-                gasMixList.Add(new GasMixEntry(Loc.GetString("gas-analyzer-window-environment-tab-label"), 0f, 0f));
+                gasMixList.Add(new GasMixEntry(Loc.GetString("gas-analyzer-window-environment-tab-label"), 0f, 0f, 0f));
             }
 
             var deviceFlipped = false;
@@ -209,8 +209,8 @@ namespace Content.Server.Atmos.EntitySystems
                 {
                     foreach (var mixes in ev.GasMixtures)
                     {
-                        if(mixes.Value != null)
-                            gasMixList.Add(new GasMixEntry(mixes.Key, mixes.Value.Pressure, mixes.Value.Temperature, GenerateGasEntryArray(mixes.Value)));
+                        if (mixes.Item2 != null)
+                            gasMixList.Add(new GasMixEntry(mixes.Item1, mixes.Item2.Volume, mixes.Item2.Pressure, mixes.Item2.Temperature, GenerateGasEntryArray(mixes.Item2)));
                     }
 
                     deviceFlipped = ev.DeviceFlipped;
@@ -223,7 +223,16 @@ namespace Content.Server.Atmos.EntitySystems
                         foreach (var pair in node.Nodes)
                         {
                             if (pair.Value is PipeNode pipeNode)
-                                gasMixList.Add(new GasMixEntry(pair.Key, pipeNode.Air.Pressure, pipeNode.Air.Temperature, GenerateGasEntryArray(pipeNode.Air)));
+                            {
+                                // check if the volume is zero for some reason so we don't divide by zero
+                                if (pipeNode.Air.Volume == 0f)
+                                    continue;
+                                // only display the gas in the analyzed pipe element, not the whole system
+                                var pipeAir = pipeNode.Air.Clone();
+                                pipeAir.Multiply(pipeNode.Volume / pipeNode.Air.Volume);
+                                pipeAir.Volume = pipeNode.Volume;
+                                gasMixList.Add(new GasMixEntry(pair.Key, pipeAir.Volume, pipeAir.Pressure, pipeAir.Temperature, GenerateGasEntryArray(pipeAir)));
+                            }
                         }
                     }
                 }
@@ -286,9 +295,9 @@ namespace Content.Server.Atmos.EntitySystems
 public sealed class GasAnalyzerScanEvent : EntityEventArgs
 {
     /// <summary>
-    /// Key is the mix name (ex "pipe", "inlet", "filter"), value is the pipe direction and GasMixture. Add all mixes that should be reported when scanned.
+    /// The string is for the name (ex "pipe", "inlet", "filter"), GasMixture for the corresponding gas mix. Add all mixes that should be reported when scanned.
     /// </summary>
-    public Dictionary<string, GasMixture?>? GasMixtures;
+    public List<(string, GasMixture?)>? GasMixtures;
 
     /// <summary>
     /// If the device is flipped. Flipped is defined as when the inline input is 90 degrees CW to the side input
index 80842416e8bd7943d5ff1c6e3aee4f93e0437e32..dd84756e45d035e5ef4f9e1bb068ca8566c87620 100644 (file)
@@ -359,7 +359,8 @@ namespace Content.Server.Atmos.EntitySystems
         /// </summary>
         private void OnAnalyzed(EntityUid uid, GasTankComponent component, GasAnalyzerScanEvent args)
         {
-            args.GasMixtures = new Dictionary<string, GasMixture?> { {Name(uid), component.Air} };
+            args.GasMixtures ??= new List<(string, GasMixture?)>();
+            args.GasMixtures.Add((Name(uid), component.Air));
         }
 
         private void OnGasTankPrice(EntityUid uid, GasTankComponent component, ref PriceCalculationEvent args)
index fbd4260469401fbf71b3fb7cfd4c78bdf39012a1..c0c2b930f6910bcda712865ffce09c687e778715 100644 (file)
@@ -73,7 +73,7 @@ namespace Content.Server.Atmos.Piping.Trinary.EntitySystems
 
             if (filter.FilteredGas.HasValue)
             {
-                var filteredOut = new GasMixture() {Temperature = removed.Temperature};
+                var filteredOut = new GasMixture() { Temperature = removed.Temperature };
 
                 filteredOut.SetMoles(filter.FilteredGas.Value, removed.GetMoles(filter.FilteredGas.Value));
                 removed.SetMoles(filter.FilteredGas.Value, 0f);
@@ -180,17 +180,30 @@ namespace Content.Server.Atmos.Piping.Trinary.EntitySystems
         /// </summary>
         private void OnFilterAnalyzed(EntityUid uid, GasFilterComponent component, GasAnalyzerScanEvent args)
         {
-            if (!EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer))
-                return;
-
-            args.GasMixtures ??= new Dictionary<string, GasMixture?>();
+            args.GasMixtures ??= new List<(string, GasMixture?)>();
 
-            if(_nodeContainer.TryGetNode(nodeContainer, component.InletName, out PipeNode? inlet))
-                args.GasMixtures.Add(Loc.GetString("gas-analyzer-window-text-inlet"), inlet.Air);
-            if(_nodeContainer.TryGetNode(nodeContainer, component.FilterName, out PipeNode? filterNode))
-                args.GasMixtures.Add(Loc.GetString("gas-analyzer-window-text-filter"), filterNode.Air);
-            if(_nodeContainer.TryGetNode(nodeContainer, component.OutletName, out PipeNode? outlet))
-                args.GasMixtures.Add(Loc.GetString("gas-analyzer-window-text-outlet"), outlet.Air);
+            // multiply by volume fraction to make sure to send only the gas inside the analyzed pipe element, not the whole pipe system
+            if (_nodeContainer.TryGetNode(uid, component.InletName, out PipeNode? inlet) && inlet.Air.Volume != 0f)
+            {
+                var inletAirLocal = inlet.Air.Clone();
+                inletAirLocal.Multiply(inlet.Volume / inlet.Air.Volume);
+                inletAirLocal.Volume = inlet.Volume;
+                args.GasMixtures.Add((Loc.GetString("gas-analyzer-window-text-inlet"), inletAirLocal));
+            }
+            if (_nodeContainer.TryGetNode(uid, component.FilterName, out PipeNode? filterNode) && filterNode.Air.Volume != 0f)
+            {
+                var filterNodeAirLocal = filterNode.Air.Clone();
+                filterNodeAirLocal.Multiply(filterNode.Volume / filterNode.Air.Volume);
+                filterNodeAirLocal.Volume = filterNode.Volume;
+                args.GasMixtures.Add((Loc.GetString("gas-analyzer-window-text-filter"), filterNodeAirLocal));
+            }
+            if (_nodeContainer.TryGetNode(uid, component.OutletName, out PipeNode? outlet) && outlet.Air.Volume != 0f)
+            {
+                var outletAirLocal = outlet.Air.Clone();
+                outletAirLocal.Multiply(outlet.Volume / outlet.Air.Volume);
+                outletAirLocal.Volume = outlet.Volume;
+                args.GasMixtures.Add((Loc.GetString("gas-analyzer-window-text-outlet"), outletAirLocal));
+            }
 
             args.DeviceFlipped = inlet != null && filterNode != null && inlet.CurrentPipeDirection.ToDirection() == filterNode.CurrentPipeDirection.ToDirection().GetClockwise90Degrees();
         }
index ba8ebf3c9ae2d95b5c30868361fbdc0d323383f7..4d7fc134c70fa7012d4618d47cd687d7ede0197d 100644 (file)
@@ -205,19 +205,31 @@ namespace Content.Server.Atmos.Piping.Trinary.EntitySystems
         /// </summary>
         private void OnMixerAnalyzed(EntityUid uid, GasMixerComponent component, GasAnalyzerScanEvent args)
         {
-            if (!EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer))
-                return;
-
-            var gasMixDict = new Dictionary<string, GasMixture?>();
+            args.GasMixtures ??= new List<(string, GasMixture?)>();
 
-            if(_nodeContainer.TryGetNode(nodeContainer, component.InletOneName, out PipeNode? inletOne))
-                gasMixDict.Add($"{inletOne.CurrentPipeDirection} {Loc.GetString("gas-analyzer-window-text-inlet")}", inletOne.Air);
-            if(_nodeContainer.TryGetNode(nodeContainer, component.InletTwoName, out PipeNode? inletTwo))
-                gasMixDict.Add($"{inletTwo.CurrentPipeDirection} {Loc.GetString("gas-analyzer-window-text-inlet")}", inletTwo.Air);
-            if(_nodeContainer.TryGetNode(nodeContainer, component.OutletName, out PipeNode? outlet))
-                gasMixDict.Add(Loc.GetString("gas-analyzer-window-text-outlet"), outlet.Air);
+            // multiply by volume fraction to make sure to send only the gas inside the analyzed pipe element, not the whole pipe system
+            if (_nodeContainer.TryGetNode(uid, component.InletOneName, out PipeNode? inletOne) && inletOne.Air.Volume != 0f)
+            {
+                var inletOneAirLocal = inletOne.Air.Clone();
+                inletOneAirLocal.Multiply(inletOne.Volume / inletOne.Air.Volume);
+                inletOneAirLocal.Volume = inletOne.Volume;
+                args.GasMixtures.Add(($"{inletOne.CurrentPipeDirection} {Loc.GetString("gas-analyzer-window-text-inlet")}", inletOneAirLocal));
+            }
+            if (_nodeContainer.TryGetNode(uid, component.InletTwoName, out PipeNode? inletTwo) && inletTwo.Air.Volume != 0f)
+            {
+                var inletTwoAirLocal = inletTwo.Air.Clone();
+                inletTwoAirLocal.Multiply(inletTwo.Volume / inletTwo.Air.Volume);
+                inletTwoAirLocal.Volume = inletTwo.Volume;
+                args.GasMixtures.Add(($"{inletTwo.CurrentPipeDirection} {Loc.GetString("gas-analyzer-window-text-inlet")}", inletTwoAirLocal));
+            }
+            if (_nodeContainer.TryGetNode(uid, component.OutletName, out PipeNode? outlet) && outlet.Air.Volume != 0f)
+            {
+                var outletAirLocal = outlet.Air.Clone();
+                outletAirLocal.Multiply(outlet.Volume / outlet.Air.Volume);
+                outletAirLocal.Volume = outlet.Volume;
+                args.GasMixtures.Add((Loc.GetString("gas-analyzer-window-text-outlet"), outletAirLocal));
+            }
 
-            args.GasMixtures = gasMixDict;
             args.DeviceFlipped = inletOne != null && inletTwo != null && inletOne.CurrentPipeDirection.ToDirection() == inletTwo.CurrentPipeDirection.ToDirection().GetClockwise90Degrees();
         }
     }
index 3e4340bf1db557a9b3453cc4816280706860e7e1..bdc9e76538143423971ae5c0a44a919168541c35 100644 (file)
@@ -294,9 +294,17 @@ public sealed class GasCanisterSystem : EntitySystem
     /// <summary>
     /// Returns the gas mixture for the gas analyzer
     /// </summary>
-    private void OnAnalyzed(EntityUid uid, GasCanisterComponent component, GasAnalyzerScanEvent args)
+    private void OnAnalyzed(EntityUid uid, GasCanisterComponent canisterComponent, GasAnalyzerScanEvent args)
     {
-        args.GasMixtures = new Dictionary<string, GasMixture?> { {Name(uid), component.Air} };
+        args.GasMixtures ??= new List<(string, GasMixture?)>();
+        args.GasMixtures.Add((Name(uid), canisterComponent.Air));
+        // if a tank is inserted show it on the analyzer as well
+        if (canisterComponent.GasTankSlot.Item != null)
+        {
+            var tank = canisterComponent.GasTankSlot.Item.Value;
+            var tankComponent = Comp<GasTankComponent>(tank);
+            args.GasMixtures.Add((Name(tank), tankComponent.Air));
+        }
     }
 
     /// <summary>
index a986385f5e9b1ae4b92e2beb849f4ba2d386c252..7c12cf3f77f65a5aced29afe1617d1c3a966c99e 100644 (file)
@@ -80,7 +80,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
                 return;
             }
 
-            var timeDelta =  args.dt;
+            var timeDelta = args.dt;
             var pressureDelta = timeDelta * vent.TargetPressureChange;
 
             if (vent.PumpDirection == VentPumpDirection.Releasing && pipe.Air.Pressure > 0)
@@ -292,7 +292,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
         /// </summary>
         private void OnAnalyzed(EntityUid uid, GasVentPumpComponent component, GasAnalyzerScanEvent args)
         {
-            var gasMixDict = new Dictionary<string, GasMixture?>();
+            args.GasMixtures ??= new List<(string, GasMixture?)>();
 
             // these are both called pipe, above it switches using this so I duplicated that...?
             var nodeName = component.PumpDirection switch
@@ -301,10 +301,14 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
                 VentPumpDirection.Siphoning => component.Outlet,
                 _ => throw new ArgumentOutOfRangeException()
             };
-            if (_nodeContainer.TryGetNode(uid, nodeName, out PipeNode? pipe))
-                gasMixDict.Add(nodeName, pipe.Air);
-
-            args.GasMixtures = gasMixDict;
+            // multiply by volume fraction to make sure to send only the gas inside the analyzed pipe element, not the whole pipe system
+            if (_nodeContainer.TryGetNode(uid, nodeName, out PipeNode? pipe) && pipe.Air.Volume != 0f)
+            {
+                var pipeAirLocal = pipe.Air.Clone();
+                pipeAirLocal.Multiply(pipe.Volume / pipe.Air.Volume);
+                pipeAirLocal.Volume = pipe.Volume;
+                args.GasMixtures.Add((nodeName, pipeAirLocal));
+            }
         }
 
         private void OnWeldChanged(EntityUid uid, GasVentPumpComponent component, ref WeldableChangedEvent args)
index f9043c091a8be2a3455b3528aabb8cba8537f0db..91ee588057407cc48021e81a619c1e57976a713a 100644 (file)
@@ -151,10 +151,8 @@ namespace Content.Server.Atmos.Portable
         /// </summary>
         private void OnScrubberAnalyzed(EntityUid uid, PortableScrubberComponent component, GasAnalyzerScanEvent args)
         {
-            args.GasMixtures ??= new Dictionary<string, GasMixture?> { { Name(uid), component.Air } };
-            // If it's connected to a port, include the port side
-            if (_nodeContainer.TryGetNode(uid, component.PortName, out PipeNode? port))
-                args.GasMixtures.Add(component.PortName, port.Air);
+            args.GasMixtures ??= new List<(string, GasMixture?)>();
+            args.GasMixtures.Add((Name(uid), component.Air));
         }
     }
 }
index a949d980bef4f733e6e021b68598111ca1da2560..02e8cebbe064727b1d7f470b9f11970b4210cd81 100644 (file)
@@ -276,10 +276,17 @@ public sealed partial class CryoPodSystem : SharedCryoPodSystem
         if (!TryComp(entity, out CryoPodAirComponent? cryoPodAir))
             return;
 
-        args.GasMixtures ??= new Dictionary<string, GasMixture?> { { Name(entity.Owner), cryoPodAir.Air } };
+        args.GasMixtures ??= new List<(string, GasMixture?)>();
+        args.GasMixtures.Add((Name(entity.Owner), cryoPodAir.Air));
         // If it's connected to a port, include the port side
-        if (_nodeContainer.TryGetNode(entity.Owner, entity.Comp.PortName, out PipeNode? port))
-            args.GasMixtures.Add(entity.Comp.PortName, port.Air);
+        // multiply by volume fraction to make sure to send only the gas inside the analyzed pipe element, not the whole pipe system
+        if (_nodeContainer.TryGetNode(entity.Owner, entity.Comp.PortName, out PipeNode? port) && port.Air.Volume != 0f)
+        {
+            var portAirLocal = port.Air.Clone();
+            portAirLocal.Multiply(port.Volume / port.Air.Volume);
+            portAirLocal.Volume = port.Volume;
+            args.GasMixtures.Add((entity.Comp.PortName, portAirLocal));
+        }
     }
 
     private void OnEjected(Entity<CryoPodComponent> cryoPod, ref EntRemovedFromContainerMessage args)
index b26ab301c64e7bb2eb32f3f237dbdc9c7f6c3b3a..9107ff2e32e98ba8e5111146807c712328a5873e 100644 (file)
@@ -151,7 +151,8 @@ public sealed class RadiationCollectorSystem : EntitySystem
         if (!TryGetLoadedGasTank(uid, out var gasTankComponent))
             return;
 
-        args.GasMixtures = new Dictionary<string, GasMixture?> { { Name(uid), gasTankComponent.Air } };
+        args.GasMixtures ??= new List<(string, GasMixture?)>();
+        args.GasMixtures.Add((Name(uid), gasTankComponent.Air));
     }
 
     public void ToggleCollector(EntityUid uid, EntityUid? user = null, RadiationCollectorComponent? component = null)
index 51ae8cc7406e1320c94136c6c13dfb749f7661ab..dec9516c0136f5052dc2642ede42bff0152cc14d 100644 (file)
@@ -56,13 +56,15 @@ public sealed partial class GasAnalyzerComponent : Component
         /// Name of the tab in the UI
         /// </summary>
         public readonly string Name;
+        public readonly float Volume;
         public readonly float Pressure;
         public readonly float Temperature;
         public readonly GasEntry[]? Gases;
 
-        public GasMixEntry(string name, float pressure, float temperature, GasEntry[]? gases = null)
+        public GasMixEntry(string name, float volume, float pressure, float temperature, GasEntry[]? gases = null)
         {
             Name = name;
+            Volume = volume;
             Pressure = pressure;
             Temperature = temperature;
             Gases = gases;
index 03a920cb64748062d66e84829816e2dadba962be..652bb19cb5b078c081d84aa9cf9aed7bd31e6dac 100644 (file)
@@ -12,6 +12,8 @@ gas-analyzer-window-refresh-button = Refresh
 gas-analyzer-window-no-data = No Data
 gas-analyzer-window-no-gas-text = No Gases
 gas-analyzer-window-error-text = Error: {$errorText}
+gas-analyzer-window-volume-text = Volume:
+gas-analyzer-window-volume-val-text = {$volume} L
 gas-analyzer-window-pressure-text = Pressure:
 gas-analyzer-window-pressure-val-text = {$pressure} kPa
 gas-analyzer-window-temperature-text = Temperature: