Power Monitoring Console (#7849)
This commit is contained in:
@@ -138,6 +138,7 @@ namespace Content.Client.Entry
|
||||
"Flash",
|
||||
"Docking",
|
||||
"Telecrystal",
|
||||
"PowerMonitoringConsole",
|
||||
"RCD",
|
||||
"RCDAmmo",
|
||||
"CursedEntityStorage",
|
||||
|
||||
20
Content.Client/Power/PowerMonitoringWindow.xaml
Normal file
20
Content.Client/Power/PowerMonitoringWindow.xaml
Normal file
@@ -0,0 +1,20 @@
|
||||
<DefaultWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
Title="{Loc 'power-monitoring-window-title'}">
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||
<GridContainer Columns="2">
|
||||
<!-- Grid is used here to align things. -->
|
||||
<Label Text="{Loc 'power-monitoring-window-total-sources'}"/><Label Name="TotalSourcesNum" Text="?"/>
|
||||
<Label Text="{Loc 'power-monitoring-window-total-loads'}"/><Label Name="TotalLoadsNum" Text="?"/>
|
||||
</GridContainer>
|
||||
<TabContainer Name="MasterTabContainer" VerticalExpand="True">
|
||||
<ItemList Name="SourcesList" VerticalExpand="True">
|
||||
</ItemList>
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||
<CheckBox Margin="8 8" Name="ShowInactiveConsumersCheckBox" Text="{Loc 'power-monitoring-window-show-inactive-consumers'}" />
|
||||
<ItemList Name="LoadsList" VerticalExpand="True">
|
||||
</ItemList>
|
||||
</BoxContainer>
|
||||
</TabContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
85
Content.Client/Power/PowerMonitoringWindow.xaml.cs
Normal file
85
Content.Client/Power/PowerMonitoringWindow.xaml.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Content.Client.Computer;
|
||||
using Content.Client.IoC;
|
||||
using Content.Shared.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Power;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class PowerMonitoringWindow : DefaultWindow, IComputerWindow<PowerMonitoringConsoleBoundInterfaceState>
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public PowerMonitoringWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
SetSize = MinSize = (300, 450);
|
||||
IoCManager.InjectDependencies(this);
|
||||
MasterTabContainer.SetTabTitle(0, Loc.GetString("power-monitoring-window-tab-sources"));
|
||||
MasterTabContainer.SetTabTitle(1, Loc.GetString("power-monitoring-window-tab-loads"));
|
||||
}
|
||||
|
||||
public void UpdateState(PowerMonitoringConsoleBoundInterfaceState scc)
|
||||
{
|
||||
UpdateList(TotalSourcesNum, scc.TotalSources, SourcesList, scc.Sources);
|
||||
var loads = scc.Loads;
|
||||
if (!ShowInactiveConsumersCheckBox.Pressed)
|
||||
{
|
||||
// Not showing inactive consumers, so hiding them.
|
||||
// This means filtering out loads that are not either:
|
||||
// + Batteries (always important)
|
||||
// + Meaningful (size above 0)
|
||||
loads = loads.Where(a => a.IsBattery || (a.Size > 0.0f)).ToArray();
|
||||
}
|
||||
UpdateList(TotalLoadsNum, scc.TotalLoads, LoadsList, loads);
|
||||
}
|
||||
|
||||
public void UpdateList(Label number, double numberVal, ItemList list, PowerMonitoringConsoleEntry[] listVal)
|
||||
{
|
||||
number.Text = Loc.GetString("power-monitoring-window-value", ("value", numberVal));
|
||||
// This magic is important to prevent scrolling issues.
|
||||
while (list.Count > listVal.Length)
|
||||
{
|
||||
list.RemoveAt(list.Count - 1);
|
||||
}
|
||||
while (list.Count < listVal.Length)
|
||||
{
|
||||
list.AddItem("YOU SHOULD NEVER SEE THIS (REALLY!)", null, false);
|
||||
}
|
||||
// Now overwrite the items properly...
|
||||
for (var i = 0; i < listVal.Length; i++)
|
||||
{
|
||||
var ent = listVal[i];
|
||||
_prototypeManager.TryIndex(ent.IconEntityPrototypeId, out EntityPrototype? entityPrototype);
|
||||
IRsiStateLike? iconState = null;
|
||||
if (entityPrototype != null)
|
||||
iconState = SpriteComponent.GetPrototypeIcon(entityPrototype, StaticIoC.ResC);
|
||||
var icon = iconState?.GetFrame(RSI.State.Direction.South, 0);
|
||||
var item = list[i];
|
||||
item.Text = $"{ent.NameLocalized} {Loc.GetString("power-monitoring-window-value", ("value", ent.Size))}";
|
||||
item.Icon = icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class PowerMonitoringConsoleBoundUserInterface : ComputerBoundUserInterface<PowerMonitoringWindow, PowerMonitoringConsoleBoundInterfaceState>
|
||||
{
|
||||
public PowerMonitoringConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Power.NodeGroups;
|
||||
using Content.Server.Utility;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.Power.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class PowerMonitoringConsoleComponent : Component
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Power;
|
||||
using Content.Server.NodeContainer;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.NodeGroups;
|
||||
using Content.Server.UserInterface;
|
||||
using Content.Server.WireHacking;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server.Power.EntitySystems;
|
||||
|
||||
[UsedImplicitly]
|
||||
internal sealed class PowerMonitoringConsoleSystem : EntitySystem
|
||||
{
|
||||
private float _updateTimer = 0.0f;
|
||||
private const float UpdateTime = 1.0f;
|
||||
|
||||
[Dependency]
|
||||
private UserInterfaceSystem _userInterfaceSystem = default!;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
_updateTimer += frameTime;
|
||||
if (_updateTimer >= UpdateTime)
|
||||
{
|
||||
_updateTimer -= UpdateTime;
|
||||
foreach (var component in EntityQuery<PowerMonitoringConsoleComponent>())
|
||||
{
|
||||
UpdateUIState(component.Owner, component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateUIState(EntityUid target, PowerMonitoringConsoleComponent? pmcComp = null, NodeContainerComponent? ncComp = null)
|
||||
{
|
||||
if (!Resolve(target, ref pmcComp))
|
||||
return;
|
||||
if (!Resolve(target, ref ncComp))
|
||||
return;
|
||||
|
||||
var totalSources = 0.0d;
|
||||
var totalLoads = 0.0d;
|
||||
var sources = new List<PowerMonitoringConsoleEntry>();
|
||||
var loads = new List<PowerMonitoringConsoleEntry>();
|
||||
PowerMonitoringConsoleEntry LoadOrSource(Component comp, double rate, bool isBattery)
|
||||
{
|
||||
var md = MetaData(comp.Owner);
|
||||
var prototype = md.EntityPrototype?.ID ?? "";
|
||||
return new PowerMonitoringConsoleEntry(md.EntityName, prototype, rate, isBattery);
|
||||
}
|
||||
// Right, so, here's what needs to be considered here.
|
||||
var netQ = ncComp.GetNode<Node>("hv").NodeGroup as PowerNet;
|
||||
if (netQ != null)
|
||||
{
|
||||
var net = netQ!;
|
||||
foreach (PowerConsumerComponent pcc in net.Consumers)
|
||||
{
|
||||
loads.Add(LoadOrSource(pcc, pcc.DrawRate, false));
|
||||
totalLoads += pcc.DrawRate;
|
||||
}
|
||||
foreach (BatteryChargerComponent pcc in net.Chargers)
|
||||
{
|
||||
if (!TryComp(pcc.Owner, out PowerNetworkBatteryComponent? batteryComp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var rate = batteryComp.NetworkBattery.CurrentReceiving;
|
||||
loads.Add(LoadOrSource(pcc, rate, true));
|
||||
totalLoads += rate;
|
||||
}
|
||||
foreach (PowerSupplierComponent pcc in net.Suppliers)
|
||||
{
|
||||
sources.Add(LoadOrSource(pcc, pcc.MaxSupply, false));
|
||||
totalSources += pcc.MaxSupply;
|
||||
}
|
||||
foreach (BatteryDischargerComponent pcc in net.Dischargers)
|
||||
{
|
||||
if (!TryComp(pcc.Owner, out PowerNetworkBatteryComponent? batteryComp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var rate = batteryComp.NetworkBattery.CurrentSupply;
|
||||
sources.Add(LoadOrSource(pcc, rate, true));
|
||||
totalSources += rate;
|
||||
}
|
||||
}
|
||||
// Sort
|
||||
loads.Sort(CompareLoadOrSources);
|
||||
sources.Sort(CompareLoadOrSources);
|
||||
// Actually set state.
|
||||
var state = new PowerMonitoringConsoleBoundInterfaceState(totalSources, totalLoads, sources.ToArray(), loads.ToArray());
|
||||
_userInterfaceSystem.GetUiOrNull(target, PowerMonitoringConsoleUiKey.Key)?.SetState(state);
|
||||
}
|
||||
|
||||
private int CompareLoadOrSources(PowerMonitoringConsoleEntry x, PowerMonitoringConsoleEntry y)
|
||||
{
|
||||
return -x.Size.CompareTo(y.Size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Power;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class PowerMonitoringConsoleBoundInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public double TotalSources;
|
||||
public double TotalLoads;
|
||||
public PowerMonitoringConsoleEntry[] Sources;
|
||||
public PowerMonitoringConsoleEntry[] Loads;
|
||||
public PowerMonitoringConsoleBoundInterfaceState(double totalSources, double totalLoads, PowerMonitoringConsoleEntry[] sources, PowerMonitoringConsoleEntry[] loads)
|
||||
{
|
||||
TotalSources = totalSources;
|
||||
TotalLoads = totalLoads;
|
||||
Sources = sources;
|
||||
Loads = loads;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class PowerMonitoringConsoleEntry
|
||||
{
|
||||
public string NameLocalized;
|
||||
public string IconEntityPrototypeId;
|
||||
public double Size;
|
||||
public bool IsBattery;
|
||||
public PowerMonitoringConsoleEntry(string nl, string ipi, double size, bool isBattery)
|
||||
{
|
||||
NameLocalized = nl;
|
||||
IconEntityPrototypeId = ipi;
|
||||
Size = size;
|
||||
IsBattery = isBattery;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum PowerMonitoringConsoleUiKey
|
||||
{
|
||||
Key
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
power-monitoring-window-title = Power Monitoring Console
|
||||
power-monitoring-window-tab-sources = Sources
|
||||
power-monitoring-window-tab-loads = Loads
|
||||
power-monitoring-window-total-sources = Total Sources:
|
||||
power-monitoring-window-total-loads = Total Loads:
|
||||
power-monitoring-window-value = { POWERWATTS($value) }
|
||||
power-monitoring-window-show-inactive-consumers = Show Inactive Consumers
|
||||
|
||||
@@ -66,6 +66,14 @@
|
||||
- type: ComputerBoard
|
||||
prototype: ComputerSupplyRequest
|
||||
|
||||
- type: entity
|
||||
parent: BaseComputerCircuitboard
|
||||
id: PowerMonitoringComputerCircuitboard
|
||||
name: power monitoring computer board
|
||||
components:
|
||||
- type: ComputerBoard
|
||||
prototype: ComputerPowerMonitoring
|
||||
|
||||
- type: entity
|
||||
parent: BaseComputerCircuitboard
|
||||
id: ResearchComputerCircuitboard
|
||||
|
||||
@@ -75,6 +75,19 @@
|
||||
color: "#c9c042"
|
||||
- type: Computer
|
||||
board: PowerComputerCircuitboard
|
||||
- type: PowerMonitoringConsole
|
||||
- type: NodeContainer
|
||||
examinable: true
|
||||
nodes:
|
||||
hv:
|
||||
!type:CableDeviceNode
|
||||
nodeGroupID: HVPower
|
||||
- type: ActivatableUI
|
||||
key: enum.PowerMonitoringConsoleUiKey.Key
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
- key: enum.PowerMonitoringConsoleUiKey.Key
|
||||
type: PowerMonitoringConsoleBoundUserInterface
|
||||
|
||||
- type: entity
|
||||
parent: ComputerBase
|
||||
|
||||
Reference in New Issue
Block a user