]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Show battery level for selected devices in Power Monitoring Console (#33854)
authorArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Thu, 19 Dec 2024 00:46:36 +0000 (16:46 -0800)
committerGitHub <noreply@github.com>
Thu, 19 Dec 2024 00:46:36 +0000 (01:46 +0100)
* Use class instead of out variables

* Show battery level in power monitoring console

* Better color contrast for battery level + localized string

* Add visualization to battery percentage

* Reverts random ChatSystem.cs whitespace change

* Address review

* Show BatteryLevel stats in child view when selecting devices

---------

Co-authored-by: Crotalus <crotalus@users.noreply.github.com>
Content.Client/Power/PowerMonitoringWindow.xaml.Widgets.cs
Content.Server/Power/EntitySystems/PowerMonitoringConsoleSystem.cs
Content.Shared/Power/SharedPowerMonitoringConsoleComponent.cs
Resources/Locale/en-US/components/power-monitoring-component.ftl

index 3f7ccfb903b75364ca0b8816ac208f3ad2be1149..87b252e9d509f6755cb36b85e1166e5191c746c4 100644 (file)
@@ -6,6 +6,7 @@ using Robust.Shared.Utility;
 using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Numerics;
+using Vector4 = Robust.Shared.Maths.Vector4;
 
 namespace Content.Client.Power;
 
@@ -104,6 +105,26 @@ public sealed partial class PowerMonitoringWindow
         // Update power value
         // Don't use SI prefixes, just give the number in W, so that it is readily apparent which consumer is using a lot of power.
         button.PowerValue.Text = Loc.GetString("power-monitoring-window-button-value", ("value", Math.Round(entry.PowerValue).ToString("N0")));
+
+        // Update battery level if applicable
+        if (entry.BatteryLevel != null)
+        {
+            button.BatteryLevel.Value = entry.BatteryLevel.Value;
+            button.BatteryLevel.Visible = true;
+
+            button.BatteryPercentage.Text = entry.BatteryLevel.Value.ToString("P0");
+            button.BatteryPercentage.Visible = true;
+
+            // Set progress bar color based on percentage
+            var color = Color.FromHsv(new Vector4(entry.BatteryLevel.Value * 0.33f, 1, 1, 1));
+
+            button.BatteryLevel.ForegroundStyleBoxOverride = new StyleBoxFlat { BackgroundColor = color };
+        }
+        else
+        {
+            button.BatteryLevel.Visible = false;
+            button.BatteryPercentage.Visible = false;
+        }
     }
 
     private void UpdateEntrySourcesOrLoads(BoxContainer masterContainer, BoxContainer currentContainer, PowerMonitoringConsoleEntry[]? entries, SpriteSpecifier.Texture icon)
@@ -443,6 +464,11 @@ public sealed class PowerMonitoringButton : Button
     public BoxContainer MainContainer;
     public TextureRect TextureRect;
     public Label NameLocalized;
+
+    public ProgressBar BatteryLevel;
+    public PanelContainer BackgroundPanel;
+    public Label BatteryPercentage;
+
     public Label PowerValue;
 
     public PowerMonitoringButton()
@@ -478,6 +504,49 @@ public sealed class PowerMonitoringButton : Button
 
         MainContainer.AddChild(NameLocalized);
 
+        BatteryLevel = new ProgressBar()
+        {
+            SetWidth = 47f,
+            SetHeight = 20f,
+            Margin = new Thickness(15, 0, 0, 0),
+            MaxValue = 1,
+            Visible = false,
+            BackgroundStyleBoxOverride = new StyleBoxFlat { BackgroundColor = Color.Black },
+        };
+
+        MainContainer.AddChild(BatteryLevel);
+
+        BackgroundPanel = new PanelContainer
+        {
+            // Draw a half-transparent box over the battery level to make the text more readable.
+            PanelOverride = new StyleBoxFlat
+            {
+                BackgroundColor = new Color(0, 0, 0, 0.9f)
+            },
+            HorizontalAlignment = HAlignment.Center,
+            VerticalAlignment = VAlignment.Center,
+            HorizontalExpand = true,
+            VerticalExpand = true,
+            // Box is undersized perfectly compared to the progress bar, so a little bit of the unaffected progress bar is visible.
+            SetSize = new Vector2(43f, 16f)
+        };
+
+        BatteryLevel.AddChild(BackgroundPanel);
+
+        BatteryPercentage = new Label()
+        {
+            VerticalAlignment = VAlignment.Center,
+            HorizontalAlignment = HAlignment.Center,
+            Align = Label.AlignMode.Center,
+            SetWidth = 45f,
+            MinWidth = 20f,
+            Margin = new Thickness(10, -4, 10, 0),
+            ClipText = true,
+            Visible = false,
+        };
+
+        BackgroundPanel.AddChild(BatteryPercentage);
+
         PowerValue = new Label()
         {
             HorizontalAlignment = HAlignment.Right,
index a07d590461eaaaa36fd57b802c069ad19814b41d..0fc641ed2804bf53e3d445098e889d3d5f5c1fed 100644 (file)
@@ -350,19 +350,20 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
                 continue;
 
             // Get the device power stats
-            var powerValue = GetPrimaryPowerValues(ent, device, out var powerSupplied, out var powerUsage, out var batteryUsage);
+            var powerStats = GetPowerStats(ent, device);
+            //, out var powerSupplied, out var powerUsage, out var batteryUsage);
 
             // Update all running totals
-            totalSources += powerSupplied;
-            totalLoads += powerUsage;
-            totalBatteryUsage += batteryUsage;
+            totalSources += powerStats.PowerSupplied;
+            totalLoads += powerStats.PowerUsage;
+            totalBatteryUsage += powerStats.BatteryUsage;
 
             // Continue on if the device is not in the current focus group
             if (device.Group != component.FocusGroup)
                 continue;
 
             // Generate a new console entry with which to populate the UI
-            var entry = new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), device.Group, powerValue);
+            var entry = new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), device.Group, powerStats.PowerValue, powerStats.BatteryLevel);
             allEntries.Add(entry);
         }
 
@@ -426,28 +427,28 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
                 loadsForFocus.ToArray()));
     }
 
-    private double GetPrimaryPowerValues(EntityUid uid, PowerMonitoringDeviceComponent device, out double powerSupplied, out double powerUsage, out double batteryUsage)
+    private PowerStats GetPowerStats(EntityUid uid, PowerMonitoringDeviceComponent device)
     {
-        var powerValue = 0d;
-        powerSupplied = 0d;
-        powerUsage = 0d;
-        batteryUsage = 0d;
+        var stats = new PowerStats();
 
         if (device.Group == PowerMonitoringConsoleGroup.Generator)
         {
             // This covers most power sources
             if (TryComp<PowerSupplierComponent>(uid, out var supplier))
             {
-                powerValue = supplier.CurrentSupply;
-                powerSupplied += powerValue;
+                stats.PowerValue = supplier.CurrentSupply;
+                stats.PowerSupplied += stats.PowerValue;
             }
 
             // Edge case: radiation collectors
             else if (TryComp<BatteryDischargerComponent>(uid, out var _) &&
                 TryComp<PowerNetworkBatteryComponent>(uid, out var battery))
             {
-                powerValue = battery.NetworkBattery.CurrentSupply;
-                powerSupplied += powerValue;
+                stats.PowerValue = battery.NetworkBattery.CurrentSupply;
+                stats.PowerSupplied += stats.PowerValue;
+
+
+                stats.BatteryLevel = GetBatteryLevel(uid);
             }
         }
 
@@ -458,18 +459,20 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
 
             if (TryComp<PowerNetworkBatteryComponent>(uid, out var battery))
             {
-                powerValue = battery.CurrentSupply;
+                stats.BatteryLevel = GetBatteryLevel(uid);
+
+                stats.PowerValue = battery.CurrentSupply;
 
                 // Load due to network battery recharging
-                powerUsage += Math.Max(battery.CurrentReceiving - battery.CurrentSupply, 0d);
+                stats.PowerUsage += Math.Max(battery.CurrentReceiving - battery.CurrentSupply, 0d);
 
                 // Track battery usage
-                batteryUsage += Math.Max(battery.CurrentSupply - battery.CurrentReceiving, 0d);
+                stats.BatteryUsage += Math.Max(battery.CurrentSupply - battery.CurrentReceiving, 0d);
 
                 // Records loads attached to APCs
                 if (device.Group == PowerMonitoringConsoleGroup.APC && battery.Enabled)
                 {
-                    powerUsage += battery.NetworkBattery.LoadingNetworkDemand;
+                    stats.PowerUsage += battery.NetworkBattery.LoadingNetworkDemand;
                 }
             }
         }
@@ -486,16 +489,28 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
                 if (childDevice.IsCollectionMaster && childDevice.ChildDevices.ContainsKey(uid))
                     continue;
 
-                var childPowerValue = GetPrimaryPowerValues(child, childDevice, out var childPowerSupplied, out var childPowerUsage, out var childBatteryUsage);
+                var childResult = GetPowerStats(child, childDevice);
 
-                powerValue += childPowerValue;
-                powerSupplied += childPowerSupplied;
-                powerUsage += childPowerUsage;
-                batteryUsage += childBatteryUsage;
+                stats.PowerValue += childResult.PowerValue;
+                stats.PowerSupplied += childResult.PowerSupplied;
+                stats.PowerUsage += childResult.PowerUsage;
+                stats.BatteryUsage += childResult.BatteryUsage;
             }
         }
 
-        return powerValue;
+        return stats;
+    }
+
+    private float? GetBatteryLevel(EntityUid uid)
+    {
+        if (!TryComp<BatteryComponent>(uid, out var battery))
+            return null;
+
+        var effectiveMax = battery.MaxCharge;
+        if (effectiveMax == 0)
+            effectiveMax = 1;
+
+        return battery.CurrentCharge / effectiveMax;
     }
 
     private void GetSourcesForNode(EntityUid uid, Node node, out List<PowerMonitoringConsoleEntry> sources)
@@ -532,7 +547,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
                     continue;
                 }
 
-                indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerSupplier.CurrentSupply));
+                indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerSupplier.CurrentSupply, GetBatteryLevel(ent)));
             }
         }
 
@@ -562,7 +577,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
                     continue;
                 }
 
-                indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, entBattery.CurrentSupply));
+                indexedSources.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, entBattery.CurrentSupply, GetBatteryLevel(ent)));
             }
         }
 
@@ -609,7 +624,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
         for (int i = 0; i < sources.Count; i++)
         {
             var entry = sources[i];
-            sources[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction);
+            sources[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction, entry.BatteryLevel);
         }
     }
 
@@ -646,7 +661,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
                     continue;
                 }
 
-                indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerConsumer.ReceivedPower));
+                indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, powerConsumer.ReceivedPower, GetBatteryLevel(ent)));
             }
         }
 
@@ -676,7 +691,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
                     continue;
                 }
 
-                indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, battery.CurrentReceiving));
+                indexedLoads.Add(ent, new PowerMonitoringConsoleEntry(EntityManager.GetNetEntity(ent), entDevice.Group, battery.CurrentReceiving, GetBatteryLevel(ent)));
             }
         }
 
@@ -713,7 +728,7 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
         for (int i = 0; i < indexedLoads.Values.Count; i++)
         {
             var entry = loads[i];
-            loads[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction);
+            loads[i] = new PowerMonitoringConsoleEntry(entry.NetEntity, entry.Group, entry.PowerValue * powerFraction, entry.BatteryLevel);
         }
     }
 
@@ -990,4 +1005,13 @@ internal sealed partial class PowerMonitoringConsoleSystem : SharedPowerMonitori
 
         Dirty(uid, component);
     }
+
+    private struct PowerStats
+    {
+        public double PowerValue { get; set; }
+        public double PowerSupplied { get; set; }
+        public double PowerUsage { get; set; }
+        public double BatteryUsage { get; set; }
+        public float? BatteryLevel { get; set; }
+    }
 }
index 4d404f209cd75fa8e6fb49f99eed9f48812d3e1c..d7e060cccd67b51d7a31462c471bf53014d76ade 100644 (file)
@@ -102,14 +102,16 @@ public struct PowerMonitoringConsoleEntry
     public NetEntity NetEntity;
     public PowerMonitoringConsoleGroup Group;
     public double PowerValue;
+    public float? BatteryLevel;
 
     [NonSerialized] public PowerMonitoringDeviceMetaData? MetaData = null;
 
-    public PowerMonitoringConsoleEntry(NetEntity netEntity, PowerMonitoringConsoleGroup group, double powerValue = 0d)
+    public PowerMonitoringConsoleEntry(NetEntity netEntity, PowerMonitoringConsoleGroup group, double powerValue = 0d, float? batteryLevel = null)
     {
         NetEntity = netEntity;
         Group = group;
         PowerValue = powerValue;
+        BatteryLevel = batteryLevel;
     }
 }
 
index 9433c9ea9ef90ad1146e9844179ddba8f543fb05..3b54b400bcd8208ac68347c04ce4387ff12d8c14 100644 (file)
@@ -22,7 +22,7 @@ power-monitoring-window-show-hv-cable = High voltage
 power-monitoring-window-show-mv-cable = Medium voltage
 power-monitoring-window-show-lv-cable = Low voltage
 
-power-monitoring-window-flavor-left = [user@nanotrasen] $run power_net_query  
+power-monitoring-window-flavor-left = [user@nanotrasen] $run power_net_query
 power-monitoring-window-flavor-right = v1.3
 power-monitoring-window-rogue-power-consumer = [color=white][font size=14][bold]! WARNING - ROGUE POWER CONSUMING DEVICE DETECTED ![/bold][/font][/color]
 power-monitoring-window-power-net-abnormalities = [color=white][font size=14][bold]CAUTION - ABNORMAL ACTIVITY IN POWER NET[/bold][/font][/color]