APC GUI. (#107)
This commit is contained in:
committed by
GitHub
parent
bb5a278fdb
commit
d414ea55f5
@@ -70,6 +70,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="EntryPoint.cs" />
|
<Compile Include="EntryPoint.cs" />
|
||||||
<Compile Include="GameObjects\Components\Inventory\ClientInventoryComponent.cs" />
|
<Compile Include="GameObjects\Components\Inventory\ClientInventoryComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\ApcBoundUserInterface.cs" />
|
||||||
<Compile Include="GameObjects\Components\Storage\ClientStorageComponent.cs" />
|
<Compile Include="GameObjects\Components\Storage\ClientStorageComponent.cs" />
|
||||||
<Compile Include="Input\ContentContexts.cs" />
|
<Compile Include="Input\ContentContexts.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
|
using SS14.Client.GameObjects.Components.UserInterface;
|
||||||
|
using SS14.Client.UserInterface.Controls;
|
||||||
|
using SS14.Client.UserInterface.CustomControls;
|
||||||
|
using SS14.Shared.GameObjects.Components.UserInterface;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
public class ApcBoundUserInterface : BoundUserInterface
|
||||||
|
{
|
||||||
|
private SS14Window _window;
|
||||||
|
private BaseButton _breakerButton;
|
||||||
|
private Label _externalPowerStateLabel;
|
||||||
|
private ProgressBar _chargeBar;
|
||||||
|
|
||||||
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
|
||||||
|
_window = new ApcWindow();
|
||||||
|
_window.OnClose += Close;
|
||||||
|
_breakerButton = _window.Contents.GetChild<BaseButton>("Rows/Breaker/Breaker");
|
||||||
|
_breakerButton.OnPressed += _ => SendMessage(new ApcToggleMainBreakerMessage());
|
||||||
|
_externalPowerStateLabel = _window.Contents.GetChild<Label>("Rows/ExternalStatus/Status");
|
||||||
|
_chargeBar = _window.Contents.GetChild<ProgressBar>("Rows/Charge/Charge");
|
||||||
|
_window.AddToScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApcBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateState(BoundUserInterfaceState state)
|
||||||
|
{
|
||||||
|
base.UpdateState(state);
|
||||||
|
|
||||||
|
var castState = (ApcBoundInterfaceState) state;
|
||||||
|
|
||||||
|
_breakerButton.Pressed = castState.MainBreaker;
|
||||||
|
switch (castState.ApcExternalPower)
|
||||||
|
{
|
||||||
|
case ApcExternalPowerState.None:
|
||||||
|
_externalPowerStateLabel.Text = "None";
|
||||||
|
break;
|
||||||
|
case ApcExternalPowerState.Low:
|
||||||
|
_externalPowerStateLabel.Text = "Low";
|
||||||
|
break;
|
||||||
|
case ApcExternalPowerState.Good:
|
||||||
|
_externalPowerStateLabel.Text = "Good";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
_chargeBar.Value = castState.Charge;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
_window.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ApcWindow : SS14Window
|
||||||
|
{
|
||||||
|
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Power/Apc.tscn");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,23 +1,42 @@
|
|||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using SS14.Server.GameObjects;
|
using SS14.Server.GameObjects;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Server.GameObjects.Components.UserInterface;
|
||||||
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects.Components.UserInterface;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Power
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
{
|
{
|
||||||
public class ApcComponent : Component
|
public sealed class ApcComponent : SharedApcComponent, IAttackHand
|
||||||
{
|
{
|
||||||
public override string Name => "Apc";
|
|
||||||
|
|
||||||
PowerStorageComponent Storage;
|
PowerStorageComponent Storage;
|
||||||
AppearanceComponent Appearance;
|
AppearanceComponent Appearance;
|
||||||
|
private PowerProviderComponent _provider;
|
||||||
|
|
||||||
ApcChargeState LastChargeState;
|
ApcChargeState LastChargeState;
|
||||||
|
private float _lastCharge = 0f;
|
||||||
|
private ApcExternalPowerState _lastExternalPowerState;
|
||||||
|
private BoundUserInterface _userInterface;
|
||||||
|
private bool _uiDirty = true;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
Storage = Owner.GetComponent<PowerStorageComponent>();
|
Storage = Owner.GetComponent<PowerStorageComponent>();
|
||||||
Appearance = Owner.GetComponent<AppearanceComponent>();
|
Appearance = Owner.GetComponent<AppearanceComponent>();
|
||||||
|
_provider = Owner.GetComponent<PowerProviderComponent>();
|
||||||
|
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>().GetBoundUserInterface(ApcUiKey.Key);
|
||||||
|
_userInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserInterfaceOnOnReceiveMessage(BoundUserInterfaceMessage obj)
|
||||||
|
{
|
||||||
|
if (obj is ApcToggleMainBreakerMessage)
|
||||||
|
{
|
||||||
|
_provider.MainBreaker = !_provider.MainBreaker;
|
||||||
|
_uiDirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnUpdate()
|
public void OnUpdate()
|
||||||
@@ -28,23 +47,68 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
LastChargeState = newState;
|
LastChargeState = newState;
|
||||||
Appearance.SetData(ApcVisuals.ChargeState, newState);
|
Appearance.SetData(ApcVisuals.ChargeState, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var newCharge = Storage.Charge;
|
||||||
|
if (newCharge != _lastCharge)
|
||||||
|
{
|
||||||
|
_lastCharge = newCharge;
|
||||||
|
_uiDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApcChargeState CalcChargeState()
|
var extPowerState = CalcExtPowerState();
|
||||||
|
if (extPowerState != _lastExternalPowerState)
|
||||||
|
{
|
||||||
|
_lastExternalPowerState = extPowerState;
|
||||||
|
_uiDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_uiDirty)
|
||||||
|
{
|
||||||
|
_userInterface.SetState(new ApcBoundInterfaceState(_provider.MainBreaker, extPowerState, newCharge / Storage.Capacity));
|
||||||
|
_uiDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApcChargeState CalcChargeState()
|
||||||
{
|
{
|
||||||
var storageCharge = Storage.GetChargeState();
|
var storageCharge = Storage.GetChargeState();
|
||||||
if (storageCharge == ChargeState.Discharging)
|
switch (storageCharge)
|
||||||
{
|
{
|
||||||
|
case ChargeState.Discharging:
|
||||||
return ApcChargeState.Lack;
|
return ApcChargeState.Lack;
|
||||||
}
|
case ChargeState.Charging:
|
||||||
|
|
||||||
if (storageCharge == ChargeState.Charging)
|
|
||||||
{
|
|
||||||
return ApcChargeState.Charging;
|
return ApcChargeState.Charging;
|
||||||
}
|
default:
|
||||||
|
|
||||||
// Still.
|
// Still.
|
||||||
return Storage.Full ? ApcChargeState.Full : ApcChargeState.Lack;
|
return Storage.Full ? ApcChargeState.Full : ApcChargeState.Lack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ApcExternalPowerState CalcExtPowerState()
|
||||||
|
{
|
||||||
|
if (!Owner.TryGetComponent(out PowerNodeComponent node) || node.Parent == null)
|
||||||
|
{
|
||||||
|
return ApcExternalPowerState.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
var net = node.Parent;
|
||||||
|
if (net.LastTotalAvailable <= 0)
|
||||||
|
{
|
||||||
|
return ApcExternalPowerState.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
return net.Lack > 0 ? ApcExternalPowerState.Low : ApcExternalPowerState.Good;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IAttackHand.Attackhand(IEntity user)
|
||||||
|
{
|
||||||
|
if (!user.TryGetComponent(out IActorComponent actor))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_userInterface.Open(actor.playerSession);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Text;
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
using SS14.Shared.GameObjects;
|
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.Map;
|
using SS14.Shared.Map;
|
||||||
@@ -32,7 +31,22 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builder.AppendFormat(" Powernet: {0}\n", node.Parent.Uid);
|
var net = node.Parent;
|
||||||
|
builder.AppendFormat(@" Powernet: {0}
|
||||||
|
Wires: {1}, Nodes: {2}
|
||||||
|
Generators: {3}, Loaders: {4},
|
||||||
|
StorageS: {5}, StorageC: {6},
|
||||||
|
Load: {7}, Supply: {8},
|
||||||
|
LAvail: {9}, LDraw: {10},
|
||||||
|
LDemand: {11}, LDemandWS: {12},
|
||||||
|
",
|
||||||
|
net.Uid,
|
||||||
|
net.NodeList.Count, net.WireList.Count,
|
||||||
|
net.GeneratorCount, net.DeviceCount,
|
||||||
|
net.PowerStorageSupplierCount, net.PowerStorageConsumerCount,
|
||||||
|
net.Load, net.Supply,
|
||||||
|
net.LastTotalAvailable, net.LastTotalDraw,
|
||||||
|
net.LastTotalDemand, net.LastTotalDemandWithSuppliers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,14 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
get => _range;
|
get => _range;
|
||||||
private set => _range = value;
|
private set => _range = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _range = 0;
|
private int _range = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List storing all the power devices that we are currently providing power to
|
/// List storing all the power devices that we are currently providing power to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SortedSet<PowerDeviceComponent> DeviceLoadList = new SortedSet<PowerDeviceComponent>(new Powernet.DevicePriorityCompare());
|
public SortedSet<PowerDeviceComponent> DeviceLoadList =
|
||||||
|
new SortedSet<PowerDeviceComponent>(new Powernet.DevicePriorityCompare());
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of devices in range that we "advertised" to.
|
/// List of devices in range that we "advertised" to.
|
||||||
@@ -47,6 +49,46 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
|
|
||||||
public override Powernet.Priority Priority { get; protected set; } = Powernet.Priority.Provider;
|
public override Powernet.Priority Priority { get; protected set; } = Powernet.Priority.Provider;
|
||||||
|
|
||||||
|
private bool _mainBreaker = true;
|
||||||
|
|
||||||
|
public bool MainBreaker
|
||||||
|
{
|
||||||
|
get => _mainBreaker;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_mainBreaker == value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mainBreaker = value;
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
DepowerAllDevices();
|
||||||
|
Load = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Load = TheoreticalLoad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float _theoreticalLoad = 0f;
|
||||||
|
|
||||||
|
public float TheoreticalLoad
|
||||||
|
{
|
||||||
|
get => _theoreticalLoad;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_theoreticalLoad = value;
|
||||||
|
if (MainBreaker)
|
||||||
|
{
|
||||||
|
Load = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PowerProviderComponent()
|
public PowerProviderComponent()
|
||||||
{
|
{
|
||||||
Load = 0;
|
Load = 0;
|
||||||
@@ -60,6 +102,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
device.RemoveProvider(this);
|
device.RemoveProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvertisedDevices.Clear();
|
AdvertisedDevices.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,17 +122,21 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!MainBreaker)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ExternalPowered)
|
if (ExternalPowered)
|
||||||
{
|
{
|
||||||
PowerAllDevices();
|
PowerAllDevices();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (storage.CanDeductCharge(TheoreticalLoad * frametime))
|
||||||
if (storage.CanDeductCharge(Load * frametime))
|
|
||||||
{
|
{
|
||||||
PowerAllDevices();
|
PowerAllDevices();
|
||||||
storage.DeductCharge(Load * frametime);
|
storage.DeductCharge(TheoreticalLoad * frametime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +157,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
DepoweredDevices.Remove(device);
|
DepoweredDevices.Remove(device);
|
||||||
device.ExternalPowered = true;
|
device.ExternalPowered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
usedEnergy += deviceLoad;
|
usedEnergy += deviceLoad;
|
||||||
remainingEnergy -= deviceLoad;
|
remainingEnergy -= deviceLoad;
|
||||||
}
|
}
|
||||||
@@ -117,12 +165,14 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
|
|
||||||
storage.DeductCharge(usedEnergy);
|
storage.DeductCharge(usedEnergy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PowerAllDevices()
|
private void PowerAllDevices()
|
||||||
{
|
{
|
||||||
foreach (var device in DepoweredDevices)
|
foreach (var device in DepoweredDevices)
|
||||||
{
|
{
|
||||||
device.ExternalPowered = true;
|
device.ExternalPowered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DepoweredDevices.Clear();
|
DepoweredDevices.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +181,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
foreach (var device in DeviceLoadList)
|
foreach (var device in DeviceLoadList)
|
||||||
{
|
{
|
||||||
device.ExternalPowered = false;
|
device.ExternalPowered = false;
|
||||||
|
DepoweredDevices.Add(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +222,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
device.RemoveProvider(this);
|
device.RemoveProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvertisedDevices.Clear();
|
AdvertisedDevices.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +232,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
public void AddDevice(PowerDeviceComponent device)
|
public void AddDevice(PowerDeviceComponent device)
|
||||||
{
|
{
|
||||||
DeviceLoadList.Add(device);
|
DeviceLoadList.Add(device);
|
||||||
Load += device.Load;
|
TheoreticalLoad += device.Load;
|
||||||
if (!device.Powered)
|
if (!device.Powered)
|
||||||
DepoweredDevices.Add(device);
|
DepoweredDevices.Add(device);
|
||||||
}
|
}
|
||||||
@@ -192,8 +244,8 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
if (DeviceLoadList.Contains(device))
|
if (DeviceLoadList.Contains(device))
|
||||||
{
|
{
|
||||||
Load -= oldLoad;
|
TheoreticalLoad -= oldLoad;
|
||||||
Load += device.Load;
|
TheoreticalLoad += device.Load;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,14 +256,15 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
if (DeviceLoadList.Contains(device))
|
if (DeviceLoadList.Contains(device))
|
||||||
{
|
{
|
||||||
Load -= device.Load;
|
TheoreticalLoad -= device.Load;
|
||||||
DeviceLoadList.Remove(device);
|
DeviceLoadList.Remove(device);
|
||||||
if (DepoweredDevices.Contains(device))
|
if (DepoweredDevices.Contains(device))
|
||||||
DepoweredDevices.Remove(device);
|
DepoweredDevices.Remove(device);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.WarningS("power", "We tried to remove device {0} twice from the same {1}, somehow.", device.Owner, Owner);
|
Logger.WarningS("power", "We tried to remove device {0} twice from the same {1}, somehow.",
|
||||||
|
device.Owner, Owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using System.Collections.Generic;
|
|||||||
namespace Content.Server.GameObjects.Components.Power
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Master class for group of powertransfercomponents, takes in and distributes power via nodes
|
/// Master class for group of <see cref="PowerTransferComponent"/>, takes in and distributes power via nodes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Powernet
|
public class Powernet
|
||||||
{
|
{
|
||||||
@@ -38,12 +38,18 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Subset of nodelist that adds a continuous power supply to the network
|
/// Subset of nodelist that adds a continuous power supply to the network
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<PowerGeneratorComponent, float> GeneratorList = new Dictionary<PowerGeneratorComponent, float>();
|
private readonly Dictionary<PowerGeneratorComponent, float> GeneratorList =
|
||||||
|
new Dictionary<PowerGeneratorComponent, float>();
|
||||||
|
|
||||||
|
public int GeneratorCount => GeneratorList.Count;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Subset of nodelist that draw power, stores information on current continuous powernet load
|
/// Subset of nodelist that draw power, stores information on current continuous powernet load
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly SortedSet<PowerDeviceComponent> DeviceLoadList = new SortedSet<PowerDeviceComponent>(new DevicePriorityCompare());
|
private readonly SortedSet<PowerDeviceComponent> DeviceLoadList =
|
||||||
|
new SortedSet<PowerDeviceComponent>(new DevicePriorityCompare());
|
||||||
|
|
||||||
|
public int DeviceCount => DeviceLoadList.Count;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All the devices that have been depowered by this powernet or depowered prior to being absorted into this powernet
|
/// All the devices that have been depowered by this powernet or depowered prior to being absorted into this powernet
|
||||||
@@ -55,11 +61,15 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<PowerStorageComponent> PowerStorageSupplierList = new List<PowerStorageComponent>();
|
private readonly List<PowerStorageComponent> PowerStorageSupplierList = new List<PowerStorageComponent>();
|
||||||
|
|
||||||
|
public int PowerStorageSupplierCount => PowerStorageSupplierList.Count;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of energy storage components that will never feed the powernet, will try to draw energy to feed themselves if possible
|
/// A list of energy storage components that will never feed the powernet, will try to draw energy to feed themselves if possible
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<PowerStorageComponent> PowerStorageConsumerList = new List<PowerStorageComponent>();
|
private readonly List<PowerStorageComponent> PowerStorageConsumerList = new List<PowerStorageComponent>();
|
||||||
|
|
||||||
|
public int PowerStorageConsumerCount => PowerStorageConsumerList.Count;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static counter of all continuous load placed from devices on this power network.
|
/// Static counter of all continuous load placed from devices on this power network.
|
||||||
/// In Watts.
|
/// In Watts.
|
||||||
@@ -67,7 +77,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
public float Load { get; private set; } = 0;
|
public float Load { get; private set; } = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static counter of all continiuous supply from generators on this power network.
|
/// Static counter of all continuous supply from generators on this power network.
|
||||||
/// In Watts.
|
/// In Watts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Supply { get; private set; } = 0;
|
public float Supply { get; private set; } = 0;
|
||||||
@@ -77,47 +87,108 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Dirty { get; set; } = false;
|
public bool Dirty { get; set; } = false;
|
||||||
|
|
||||||
|
// These are stats for power monitoring equipment such as APCs.
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total supply that was available to us last tick.
|
||||||
|
/// This does not mean it was used.
|
||||||
|
/// </summary>
|
||||||
|
public float LastTotalAvailable { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total power drawn last tick.
|
||||||
|
/// This is how much power was actually, in practice, drawn.
|
||||||
|
/// Not how much SHOULD have been drawn.
|
||||||
|
/// If avail < demand, this will be just <= than the actual avail
|
||||||
|
/// (e.g. if all machines need 100 W but there's 20 W excess, the 20 W will be avail but not drawn.)
|
||||||
|
/// </summary>
|
||||||
|
public float LastTotalDraw { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of power that was demanded last tick.
|
||||||
|
/// This does not mean it was full filled in practice.
|
||||||
|
/// This does not include the demand from storage suppliers until the suppliers are actually capable of drawing power.
|
||||||
|
/// As such, this will quite abruptly shoot up if available rises to cover supplier charge demand too.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="LastTotalDemandWithSuppliers"/>
|
||||||
|
public float LastTotalDemand { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of power that was demanded last tick, ALWAYS including storage supplier draw.
|
||||||
|
/// This does not mean it was full filled in practice.
|
||||||
|
/// See <see cref="LastTotalDemand"/> for the difference.
|
||||||
|
/// </summary>
|
||||||
|
public float LastTotalDemandWithSuppliers { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of power that we are lacking to properly power everything (excluding storage supplier charging).
|
||||||
|
/// </summary>
|
||||||
|
public float Lack => Math.Max(0, LastTotalDemand - LastTotalAvailable);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total amount of power that wasn't used last tick.
|
||||||
|
/// This does not necessarily mean it went to waste, unused supply from storage is also counted.
|
||||||
|
/// It is ALSO not implied that if this is > 0, that we have sufficient power for everything.
|
||||||
|
/// See the doc comment on <see cref="LastTotalDraw"/>.
|
||||||
|
/// </summary>
|
||||||
|
public float Excess => Math.Max(0, LastTotalAvailable - LastTotalDraw);
|
||||||
|
|
||||||
public void Update(float frameTime)
|
public void Update(float frameTime)
|
||||||
{
|
{
|
||||||
float activesupply = Supply * frameTime;
|
// The amount of energy that is supplied from generators that do not care if it's used or not.
|
||||||
float activeload = Load * frameTime;
|
var activeSupply = Supply * frameTime;
|
||||||
|
// The total load we need to fill for machines.
|
||||||
float storageconsumerdemand = 0;
|
var activeLoad = Load * frameTime;
|
||||||
|
|
||||||
|
// The total load from storage consumers (batteries that do not supply like an SMES)
|
||||||
|
float storageConsumerDemand = 0;
|
||||||
foreach (var supply in PowerStorageConsumerList)
|
foreach (var supply in PowerStorageConsumerList)
|
||||||
{
|
{
|
||||||
storageconsumerdemand += supply.RequestCharge(frameTime);
|
storageConsumerDemand += supply.RequestCharge(frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
float storagesupply = 0;
|
// The total supply from storage suppliers.
|
||||||
float storagesupplierdemand = 0;
|
float storageSupply = 0;
|
||||||
|
// The total load from storage suppliers (batteries that DO supply like an SMES)
|
||||||
|
float storageSupplierDemand = 0;
|
||||||
foreach (var supply in PowerStorageSupplierList)
|
foreach (var supply in PowerStorageSupplierList)
|
||||||
{
|
{
|
||||||
storagesupply += supply.AvailableCharge(frameTime);
|
storageSupply += supply.AvailableCharge(frameTime);
|
||||||
storagesupplierdemand += supply.RequestCharge(frameTime);
|
storageSupplierDemand += supply.RequestCharge(frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LastTotalAvailable = (storageSupply + activeSupply) / frameTime;
|
||||||
|
LastTotalDemandWithSuppliers = (activeLoad + storageConsumerDemand + storageSupplierDemand) / frameTime;
|
||||||
|
|
||||||
|
// The happy case.
|
||||||
// If we have enough power to feed all load and storage demand, then feed everything
|
// If we have enough power to feed all load and storage demand, then feed everything
|
||||||
if (activesupply > activeload + storageconsumerdemand + storagesupplierdemand)
|
if (activeSupply > activeLoad + storageConsumerDemand + storageSupplierDemand)
|
||||||
{
|
{
|
||||||
PowerAllDevices();
|
PowerAllDevices();
|
||||||
ChargeStorageConsumers(frameTime);
|
ChargeStorageConsumers(frameTime);
|
||||||
ChargeStorageSuppliers(frameTime);
|
ChargeStorageSuppliers(frameTime);
|
||||||
|
LastTotalDraw = LastTotalDemand = LastTotalDemandWithSuppliers;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LastTotalDemand = (activeLoad + storageConsumerDemand) / frameTime;
|
||||||
|
|
||||||
// We don't have enough power for the storage powernet suppliers, ignore powering them
|
// We don't have enough power for the storage powernet suppliers, ignore powering them
|
||||||
else if (activesupply > activeload + storageconsumerdemand)
|
// TODO: This is technically incorrect, it's totally possible to power *some* suppliers here,
|
||||||
|
// just not all.
|
||||||
|
if (activeSupply > activeLoad + storageConsumerDemand)
|
||||||
{
|
{
|
||||||
PowerAllDevices();
|
PowerAllDevices();
|
||||||
ChargeStorageConsumers(frameTime);
|
ChargeStorageConsumers(frameTime);
|
||||||
|
LastTotalDraw = LastTotalDemand;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The complex case: There is too little power to power everything without using storage suppliers (SMES).
|
||||||
|
// We have to keep track of power draw as to not incorrectly detract too much from storage suppliers.
|
||||||
|
|
||||||
float totalRemaining = activesupply + storagesupply;
|
// Calculate the total potential supply, then go through every normal load and detract.
|
||||||
|
var totalRemaining = activeSupply + storageSupply;
|
||||||
foreach (var device in DeviceLoadList)
|
foreach (var device in DeviceLoadList)
|
||||||
{
|
{
|
||||||
var deviceLoad = device.Load * frameTime;
|
var deviceLoad = device.Load * frameTime;
|
||||||
@@ -137,25 +208,35 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// What we have left goes into storage consumers.
|
if (totalRemaining > 0)
|
||||||
|
{
|
||||||
|
// What we have left (if any) goes into storage consumers.
|
||||||
foreach (var consumer in PowerStorageConsumerList)
|
foreach (var consumer in PowerStorageConsumerList)
|
||||||
{
|
{
|
||||||
if (totalRemaining < 0)
|
if (totalRemaining < 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var demand = consumer.RequestCharge(frameTime);
|
var demand = consumer.RequestCharge(frameTime);
|
||||||
if (demand == 0)
|
if (demand == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var taken = Math.Min(demand, totalRemaining);
|
var taken = Math.Min(demand, totalRemaining);
|
||||||
totalRemaining -= taken;
|
totalRemaining -= taken;
|
||||||
consumer.AddCharge(taken);
|
consumer.AddCharge(taken);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var supplierUsed = storagesupply - totalRemaining;
|
LastTotalDraw = (activeSupply + storageSupply - totalRemaining) / frameTime;
|
||||||
|
|
||||||
|
// activeSupply is free to use, but storageSupply is not.
|
||||||
|
// Calculate how much of storageSupply, and deduct it from the storage suppliers.
|
||||||
|
var supplierUsed = storageSupply - totalRemaining;
|
||||||
|
|
||||||
|
// And deduct!
|
||||||
foreach (var supplier in PowerStorageSupplierList)
|
foreach (var supplier in PowerStorageSupplierList)
|
||||||
{
|
{
|
||||||
var load = supplier.AvailableCharge(frameTime);
|
var load = supplier.AvailableCharge(frameTime);
|
||||||
@@ -163,6 +244,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var added = Math.Min(load, supplierUsed);
|
var added = Math.Min(load, supplierUsed);
|
||||||
supplierUsed -= added;
|
supplierUsed -= added;
|
||||||
supplier.DeductCharge(added);
|
supplier.DeductCharge(added);
|
||||||
@@ -179,6 +261,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
device.ExternalPowered = true;
|
device.ExternalPowered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DepoweredDevices.Clear();
|
DepoweredDevices.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +291,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
NodeList[0].DisconnectFromPowernet();
|
NodeList[0].DisconnectFromPowernet();
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratorList.Clear();
|
GeneratorList.Clear();
|
||||||
DeviceLoadList.Clear();
|
DeviceLoadList.Clear();
|
||||||
DepoweredDevices.Clear();
|
DepoweredDevices.Clear();
|
||||||
@@ -228,6 +312,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
wire.Parent = this;
|
wire.Parent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
WireList.AddRange(toMerge.WireList);
|
WireList.AddRange(toMerge.WireList);
|
||||||
toMerge.WireList.Clear();
|
toMerge.WireList.Clear();
|
||||||
|
|
||||||
@@ -235,6 +320,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
node.Parent = this;
|
node.Parent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList.AddRange(toMerge.NodeList);
|
NodeList.AddRange(toMerge.NodeList);
|
||||||
toMerge.NodeList.Clear();
|
toMerge.NodeList.Clear();
|
||||||
|
|
||||||
@@ -242,6 +328,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
GeneratorList.Add(generator.Key, generator.Value);
|
GeneratorList.Add(generator.Key, generator.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Supply += toMerge.Supply;
|
Supply += toMerge.Supply;
|
||||||
toMerge.Supply = 0;
|
toMerge.Supply = 0;
|
||||||
toMerge.GeneratorList.Clear();
|
toMerge.GeneratorList.Clear();
|
||||||
@@ -250,6 +337,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
DeviceLoadList.Add(device);
|
DeviceLoadList.Add(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
Load += toMerge.Load;
|
Load += toMerge.Load;
|
||||||
toMerge.Load = 0;
|
toMerge.Load = 0;
|
||||||
toMerge.DeviceLoadList.Clear();
|
toMerge.DeviceLoadList.Clear();
|
||||||
@@ -362,7 +450,8 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.WarningS("power", "We tried to remove generator {0} twice from {1}, somehow.", generator.Owner, this);
|
Logger.WarningS("power", "We tried to remove generator {0} twice from {1}, somehow.", generator.Owner,
|
||||||
|
this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,11 +491,13 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
PowerStorageSupplierList.Remove(storage);
|
PowerStorageSupplierList.Remove(storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PowerStorageConsumerList.Contains(storage))
|
if (PowerStorageConsumerList.Contains(storage))
|
||||||
{
|
{
|
||||||
PowerStorageSupplierList.Remove(storage);
|
PowerStorageSupplierList.Remove(storage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Registration
|
#endregion Registration
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@@ -441,6 +532,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
return y.Owner.Uid.CompareTo(x.Owner.Uid);
|
return y.Owner.Uid.CompareTo(x.Owner.Uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return compare;
|
return compare;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects.Components.UserInterface;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.Components.Power
|
namespace Content.Shared.GameObjects.Components.Power
|
||||||
{
|
{
|
||||||
|
public abstract class SharedApcComponent : Component
|
||||||
|
{
|
||||||
|
public sealed override string Name => "Apc";
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public enum ApcVisuals
|
public enum ApcVisuals
|
||||||
{
|
{
|
||||||
@@ -27,4 +34,37 @@ namespace Content.Shared.GameObjects.Components.Power
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Full,
|
Full,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class ApcBoundInterfaceState : BoundUserInterfaceState
|
||||||
|
{
|
||||||
|
public readonly bool MainBreaker;
|
||||||
|
public readonly ApcExternalPowerState ApcExternalPower;
|
||||||
|
public readonly float Charge;
|
||||||
|
|
||||||
|
public ApcBoundInterfaceState(bool mainBreaker, ApcExternalPowerState apcExternalPower, float charge)
|
||||||
|
{
|
||||||
|
MainBreaker = mainBreaker;
|
||||||
|
ApcExternalPower = apcExternalPower;
|
||||||
|
Charge = charge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class ApcToggleMainBreakerMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ApcExternalPowerState
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Low,
|
||||||
|
Good,
|
||||||
|
}
|
||||||
|
|
||||||
|
[NetSerializable, Serializable]
|
||||||
|
public enum ApcUiKey
|
||||||
|
{
|
||||||
|
Key,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,10 @@
|
|||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
- type: ApcVisualizer2D
|
- type: ApcVisualizer2D
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.ApcUiKey.Key
|
||||||
|
type: ApcBoundUserInterface
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: SMES
|
id: SMES
|
||||||
|
|||||||
230
Resources/Scenes/Power/Apc.tscn
Normal file
230
Resources/Scenes/Power/Apc.tscn
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
[gd_scene load_steps=2 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://Scenes/SS14Window/SS14Window.tscn" type="PackedScene" id=1]
|
||||||
|
|
||||||
|
[node name="SS14Window" index="0" instance=ExtResource( 1 )]
|
||||||
|
margin_right = 426.0
|
||||||
|
margin_bottom = 270.0
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="Contents" parent="." index="0"]
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="Rows" type="VBoxContainer" parent="Contents" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
alignment = 0
|
||||||
|
|
||||||
|
[node name="StatusHeader" type="Label" parent="Contents/Rows" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 306.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Power Status:"
|
||||||
|
percent_visible = 1.0
|
||||||
|
lines_skipped = 0
|
||||||
|
max_lines_visible = -1
|
||||||
|
|
||||||
|
[node name="Breaker" type="HBoxContainer" parent="Contents/Rows" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 18.0
|
||||||
|
margin_right = 306.0
|
||||||
|
margin_bottom = 58.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 1
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
alignment = 0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Contents/Rows/Breaker" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 13.0
|
||||||
|
margin_right = 100.0
|
||||||
|
margin_bottom = 27.0
|
||||||
|
rect_min_size = Vector2( 100, 0 )
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Main Breaker:"
|
||||||
|
percent_visible = 1.0
|
||||||
|
lines_skipped = 0
|
||||||
|
max_lines_visible = -1
|
||||||
|
_sections_unfolded = [ "Rect" ]
|
||||||
|
|
||||||
|
[node name="Breaker" type="CheckButton" parent="Contents/Rows/Breaker" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 104.0
|
||||||
|
margin_right = 180.0
|
||||||
|
margin_bottom = 40.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
toggle_mode = true
|
||||||
|
pressed = true
|
||||||
|
enabled_focus_mode = 2
|
||||||
|
shortcut = null
|
||||||
|
group = null
|
||||||
|
flat = false
|
||||||
|
align = 0
|
||||||
|
|
||||||
|
[node name="ExternalStatus" type="HBoxContainer" parent="Contents/Rows" index="2"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 62.0
|
||||||
|
margin_right = 306.0
|
||||||
|
margin_bottom = 76.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 1
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
alignment = 0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Contents/Rows/ExternalStatus" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 100.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_min_size = Vector2( 100, 0 )
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "External Power:"
|
||||||
|
percent_visible = 1.0
|
||||||
|
lines_skipped = 0
|
||||||
|
max_lines_visible = -1
|
||||||
|
_sections_unfolded = [ "Rect" ]
|
||||||
|
|
||||||
|
[node name="Status" type="Label" parent="Contents/Rows/ExternalStatus" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 104.0
|
||||||
|
margin_right = 138.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Good"
|
||||||
|
percent_visible = 1.0
|
||||||
|
lines_skipped = 0
|
||||||
|
max_lines_visible = -1
|
||||||
|
|
||||||
|
[node name="Charge" type="HBoxContainer" parent="Contents/Rows" index="3"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 80.0
|
||||||
|
margin_right = 306.0
|
||||||
|
margin_bottom = 94.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 1
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
alignment = 0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Contents/Rows/Charge" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 100.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_min_size = Vector2( 100, 0 )
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Charge:"
|
||||||
|
percent_visible = 1.0
|
||||||
|
lines_skipped = 0
|
||||||
|
max_lines_visible = -1
|
||||||
|
_sections_unfolded = [ "Rect" ]
|
||||||
|
|
||||||
|
[node name="Charge" type="ProgressBar" parent="Contents/Rows/Charge" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 104.0
|
||||||
|
margin_right = 306.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 0
|
||||||
|
min_value = 0.0
|
||||||
|
max_value = 1.0
|
||||||
|
step = 1.0
|
||||||
|
page = 0.0
|
||||||
|
value = 0.5
|
||||||
|
exp_edit = false
|
||||||
|
rounded = false
|
||||||
|
allow_greater = false
|
||||||
|
allow_lesser = false
|
||||||
|
percent_visible = true
|
||||||
|
_sections_unfolded = [ "Percent" ]
|
||||||
|
|
||||||
|
[node name="Header" parent="." index="1"]
|
||||||
|
editor/display_folded = true
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="Header Text" parent="Header" index="0"]
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="CloseButton" parent="Header" index="1"]
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
2
engine
2
engine
Submodule engine updated: b5bbbd9dde...a1f3c5fdbb
Reference in New Issue
Block a user