]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Display current load and maximum capacity (#20181)
authordaerSeebaer <61566539+daerSeebaer@users.noreply.github.com>
Wed, 18 Oct 2023 17:46:32 +0000 (19:46 +0200)
committerGitHub <noreply@github.com>
Wed, 18 Oct 2023 17:46:32 +0000 (09:46 -0800)
Content.Client/Ame/UI/AmeWindow.xaml
Content.Client/Ame/UI/AmeWindow.xaml.cs
Content.Server/Ame/AmeNodeGroup.cs
Content.Server/Ame/Components/AmeControllerComponent.cs
Content.Server/Ame/EntitySystems/AmeControllerSystem.cs
Content.Shared/Ame/SharedAmeControllerComponent.cs
Resources/Locale/en-US/ame/components/ame-controller-component.ftl

index 8769e3124e123574a1aacddc769cba716258730f..14835f85c71a9a7fa59db0c7c50620a1b040fd94 100644 (file)
@@ -1,7 +1,7 @@
-<DefaultWindow xmlns="https://spacestation14.io"
+<DefaultWindow xmlns="https://spacestation14.io"
             Title="{Loc 'ame-window-title'}"
             MinSize="250 250">
-    <BoxContainer Orientation="Vertical">
+    <GridContainer Columns="2">
         <BoxContainer Orientation="Horizontal">
             <Label Text="{Loc 'ame-window-engine-status-label'}" />
             <Label Text=" " />
             <Label Text=" " />
             <Label Name="CoreCount" Text="0" />
         </BoxContainer>
-    </BoxContainer>
+        <BoxContainer></BoxContainer>
+        <BoxContainer Orientation="Horizontal">
+            <Label Text="{Loc 'ame-window-power-currentsupply-label'}" />
+            <Label Text=" " />
+            <Label Name="CurrentPowerSupply" Text="0" />
+            <Label Text=" kW" />
+        </BoxContainer>
+        <BoxContainer></BoxContainer>
+        <BoxContainer Orientation="Horizontal">
+            <Label Text="{Loc 'ame-window-power-targetsupply-label'}" />
+            <Label Text=" " />
+            <Label Name="TargetedPowerSupply" Text="0" />
+            <Label Text=" kW" />
+        </BoxContainer>
+    </GridContainer>
 </DefaultWindow>
index 0ad8880becab82c1b5ee07c9a77dd49a068686ac..8f5103e6cf738260cbcaadd8cee8e853a2d9b7d6 100644 (file)
@@ -64,6 +64,9 @@ namespace Content.Client.Ame.UI
 
             CoreCount.Text = $"{castState.CoreCount}";
             InjectionAmount.Text = $"{castState.InjectionAmount}";
+            // format power statistics to pretty numbers
+            CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply.ToString("N1")}";
+            TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply.ToString("N1")}";
         }
     }
 }
index d0e854469f55be027fa2e00a00e859858c98f03f..d970f43d8be23c41eb42014a95b868bddfc06ddc 100644 (file)
@@ -126,11 +126,7 @@ public sealed class AmeNodeGroup : BaseNodeGroup
 
         var safeFuelLimit = CoreCount * 2;
 
-        // Note the float conversions. The maths will completely fail if not done using floats.
-        // Oh, and don't ever stuff the result of this in an int. Seriously.
-        var floatFuel = (float) fuel;
-        var floatCores = (float) CoreCount;
-        var powerOutput = 20000f * floatFuel * floatFuel / floatCores;
+        var powerOutput = CalculatePower(fuel, CoreCount);
         if (fuel <= safeFuelLimit)
             return powerOutput;
 
@@ -177,6 +173,17 @@ public sealed class AmeNodeGroup : BaseNodeGroup
         return powerOutput;
     }
 
+    /// <summary>
+    /// Calculates the amount of power the AME can produce with the given settings
+    /// </summary>
+    public float CalculatePower(int fuel, int cores)
+    {
+        // Fuel is squared so more fuel vastly increases power and efficiency
+        // We divide by the number of cores so a larger AME is less efficient at the same fuel settings
+        // this results in all AMEs having the same efficiency at the same fuel-per-core setting
+        return 20000f * fuel * fuel / cores;
+    }
+
     public int GetTotalStability()
     {
         if (CoreCount < 1)
index 42bfa5303d7342c556096f7e5cfedde782a3abfa..1bf1ac2c927c389be40e559d7ac67f520134bb12 100644 (file)
@@ -72,10 +72,21 @@ public sealed partial class AmeControllerComponent : SharedAmeControllerComponen
     [DataField("nextUpdate")]
     public TimeSpan NextUpdate = default!;
 
+    /// <summary>
+    /// The next time this will try to update the controller UI.
+    /// </summary>
+    public TimeSpan NextUIUpdate = default!;
+
     /// <summary>
     /// The the amount of time that passes between injection attempts.
     /// </summary>
     [DataField("updatePeriod")]
     [ViewVariables(VVAccess.ReadWrite)]
     public TimeSpan UpdatePeriod = TimeSpan.FromSeconds(10.0);
+
+    /// <summary>
+    /// The maximum amount of time that passes between UI updates.
+    /// </summary>
+    [ViewVariables]
+    public TimeSpan UpdateUIPeriod = TimeSpan.FromSeconds(3.0);
 }
index 7b9ea7146ef8d93ddfc3817ea66efa2838023fa9..44140193d2a3f01cdb25134cf6296ed1dc56f45d 100644 (file)
@@ -50,6 +50,8 @@ public sealed class AmeControllerSystem : EntitySystem
         {
             if (controller.NextUpdate <= curTime)
                 UpdateController(uid, curTime, controller, nodes);
+            else if (controller.NextUIUpdate <= curTime)
+                UpdateUi(uid, controller);
         }
     }
 
@@ -60,6 +62,8 @@ public sealed class AmeControllerSystem : EntitySystem
 
         controller.LastUpdate = curTime;
         controller.NextUpdate = curTime + controller.UpdatePeriod;
+        // update the UI regardless of other factors to update the power readings
+        UpdateUi(uid, controller);
 
         if (!controller.Injecting)
             return;
@@ -106,18 +110,35 @@ public sealed class AmeControllerSystem : EntitySystem
 
         var state = GetUiState(uid, controller);
         _userInterfaceSystem.SetUiState(bui, state);
+
+        controller.NextUIUpdate = _gameTiming.CurTime + controller.UpdateUIPeriod;
     }
 
     private AmeControllerBoundUserInterfaceState GetUiState(EntityUid uid, AmeControllerComponent controller)
     {
         var powered = !TryComp<ApcPowerReceiverComponent>(uid, out var powerSource) || powerSource.Powered;
-        var coreCount = TryGetAMENodeGroup(uid, out var group) ? group.CoreCount : 0;
+        var coreCount = 0;
+        // how much power can be produced at the current settings, in kW
+        // we don't use max. here since this is what is set in the Controller, not what the AME is actually producing
+        float targetedPowerSupply = 0;
+        if (TryGetAMENodeGroup(uid, out var group))
+        {
+            coreCount = group.CoreCount;
+            targetedPowerSupply = group.CalculatePower(controller.InjectionAmount, group.CoreCount) / 1000;
+        }
+
+        // set current power statistics in kW
+        float currentPowerSupply = 0;
+        if (TryComp<PowerSupplierComponent>(uid, out var powerOutlet) && coreCount > 0)
+        {
+            currentPowerSupply = powerOutlet.CurrentSupply / 1000;
+        }
 
         var hasJar = Exists(controller.JarSlot.ContainedEntity);
         if (!hasJar || !TryComp<AmeFuelContainerComponent>(controller.JarSlot.ContainedEntity, out var jar))
-            return new AmeControllerBoundUserInterfaceState(powered, IsMasterController(uid), false, hasJar, 0, controller.InjectionAmount, coreCount);
+            return new AmeControllerBoundUserInterfaceState(powered, IsMasterController(uid), false, hasJar, 0, controller.InjectionAmount, coreCount, currentPowerSupply, targetedPowerSupply);
 
-        return new AmeControllerBoundUserInterfaceState(powered, IsMasterController(uid), controller.Injecting, hasJar, jar.FuelAmount, controller.InjectionAmount, coreCount);
+        return new AmeControllerBoundUserInterfaceState(powered, IsMasterController(uid), controller.Injecting, hasJar, jar.FuelAmount, controller.InjectionAmount, coreCount, currentPowerSupply, targetedPowerSupply);
     }
 
     private bool IsMasterController(EntityUid uid)
index 386d577ef38dc57932f10ceb9eda12d225aaf2ae..8dde66724d5b6f9597ce9833d314b708d6f1237f 100644 (file)
@@ -1,4 +1,4 @@
-using Robust.Shared.Serialization;
+using Robust.Shared.Serialization;
 
 namespace Content.Shared.Ame;
 
@@ -17,8 +17,10 @@ public sealed class AmeControllerBoundUserInterfaceState : BoundUserInterfaceSta
     public readonly int FuelAmount;
     public readonly int InjectionAmount;
     public readonly int CoreCount;
+    public readonly float CurrentPowerSupply;
+    public readonly float TargetedPowerSupply;
 
-    public AmeControllerBoundUserInterfaceState(bool hasPower, bool isMaster, bool injecting, bool hasFuelJar, int fuelAmount, int injectionAmount, int coreCount)
+    public AmeControllerBoundUserInterfaceState(bool hasPower, bool isMaster, bool injecting, bool hasFuelJar, int fuelAmount, int injectionAmount, int coreCount, float currentPowerSupply, float targetedPowerSupply)
     {
         HasPower = hasPower;
         IsMaster = isMaster;
@@ -27,6 +29,8 @@ public sealed class AmeControllerBoundUserInterfaceState : BoundUserInterfaceSta
         FuelAmount = fuelAmount;
         InjectionAmount = injectionAmount;
         CoreCount = coreCount;
+        CurrentPowerSupply = currentPowerSupply;
+        TargetedPowerSupply = targetedPowerSupply;
     }
 }
 
index f55fa8755f019f22924dc693a2220843b2c21ad1..cd5e6b4661c12b3aaaa457f130454878cd453be0 100644 (file)
@@ -16,6 +16,8 @@ ame-window-fuel-not-inserted-text = No fuel inserted
 ame-window-injection-amount-label = Injection amount:
 ame-window-refresh-parts-button = Refresh Parts
 ame-window-core-count-label = Core count:
+ame-window-power-currentsupply-label = Current power supply:
+ame-window-power-targetsupply-label = Targeted power supply:
 ame-window-toggle-injection-button = Toggle Injection
 ame-window-eject-button = Eject
 ame-window-increase-fuel-button = Increase