Battery (SMES/substation) interface (#36386)
* Add ENERGYWATTHOURS() loc function Takes in joules (energy), displays as watt-hours. * Add simple OnOffButton control * Re-add Inset style class This was sloppily removed at some point?? Whatever, I need it. * Add helper functions for setting title/guidebook IDs on FancyWindow Reagent dispenser uses these, more in the next commits. * Add BuiPredictionState helper This enables me to implement coarse prediction manually in the battery UI. Basically it's a local buffer of predicted inputs that can easily be replayed against future BUI states from the server. * Add input coalescing infrastructure I ran into the following problem: Robust's Slider control absolutely *spams* input events, to such a degree that it actually causes issues for the networking layer if directly passed through. For something like a slider, we just need to send the most recent value. There is no good way for us to handle this in the control itself, as it *really* needs to happen in PreEngine. For simplicity reasons (for BUIs) I came to the conclusion it's best if it's there, as it's *before* any new states from the server can be applied. We can't just do this in Update() or something on the control as the timing just doesn't line up. I made a content system, BuiPreTickUpdateSystem, that runs in the ModRunLevel.PreEngine phase to achieve this. It runs a method on a new IBuiPreTickUpdate interface on all open BUIs. They can then implement their own coalescing logic. In the simplest case, this coalescing logic can just be "save the last value, and if we have any new value since the last update, send an input event." This is what the new InputCoalescer<T> type is for. Adding new coalescing logic should be possible in the future, of course. It's all just small helpers. * Battery interface This adds a proper interface to batteries (SMES/substation). Players can turn IO on and off, and they can change charge and discharge rate. There's also a ton of numbers and stuff. It looks great. This actually enables charge and discharge rates to be changed for these devices. The settings for both have been set between 5kW and 150kW. * Oops, forgot to remove these style class defs.
This commit is contained in:
committed by
GitHub
parent
791f7af5d4
commit
ffe130b38d
120
Content.Server/Power/EntitySystems/BatteryInterfaceSystem.cs
Normal file
120
Content.Server/Power/EntitySystems/BatteryInterfaceSystem.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.Power;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server.Power.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// Handles logic for the battery interface on SMES/substations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These devices have interfaces that allow user to toggle input and output,
|
||||
/// and configure charge/discharge power limits.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This system is not responsible for any power logic on its own,
|
||||
/// it merely reconfigures parameters on <see cref="PowerNetworkBatteryComponent"/> from the UI.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class BatteryInterfaceSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = null!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
UpdatesAfter.Add(typeof(PowerNetSystem));
|
||||
|
||||
Subs.BuiEvents<BatteryInterfaceComponent>(
|
||||
BatteryUiKey.Key,
|
||||
subs =>
|
||||
{
|
||||
subs.Event<BatterySetInputBreakerMessage>(HandleSetInputBreaker);
|
||||
subs.Event<BatterySetOutputBreakerMessage>(HandleSetOutputBreaker);
|
||||
|
||||
subs.Event<BatterySetChargeRateMessage>(HandleSetChargeRate);
|
||||
subs.Event<BatterySetDischargeRateMessage>(HandleSetDischargeRate);
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleSetInputBreaker(Entity<BatteryInterfaceComponent> ent, ref BatterySetInputBreakerMessage args)
|
||||
{
|
||||
var netBattery = Comp<PowerNetworkBatteryComponent>(ent);
|
||||
netBattery.CanCharge = args.On;
|
||||
}
|
||||
|
||||
private void HandleSetOutputBreaker(Entity<BatteryInterfaceComponent> ent, ref BatterySetOutputBreakerMessage args)
|
||||
{
|
||||
var netBattery = Comp<PowerNetworkBatteryComponent>(ent);
|
||||
netBattery.CanDischarge = args.On;
|
||||
}
|
||||
|
||||
private void HandleSetChargeRate(Entity<BatteryInterfaceComponent> ent, ref BatterySetChargeRateMessage args)
|
||||
{
|
||||
var netBattery = Comp<PowerNetworkBatteryComponent>(ent);
|
||||
netBattery.MaxChargeRate = Math.Clamp(args.Rate, ent.Comp.MinChargeRate, ent.Comp.MaxChargeRate);
|
||||
}
|
||||
|
||||
private void HandleSetDischargeRate(Entity<BatteryInterfaceComponent> ent, ref BatterySetDischargeRateMessage args)
|
||||
{
|
||||
var netBattery = Comp<PowerNetworkBatteryComponent>(ent);
|
||||
netBattery.MaxSupply = Math.Clamp(args.Rate, ent.Comp.MinSupply, ent.Comp.MaxSupply);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
var query = EntityQueryEnumerator<BatteryInterfaceComponent, BatteryComponent, PowerNetworkBatteryComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var batteryInterface, out var battery, out var netBattery))
|
||||
{
|
||||
UpdateUI(uid, batteryInterface, battery, netBattery);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateUI(
|
||||
EntityUid uid,
|
||||
BatteryInterfaceComponent batteryInterface,
|
||||
BatteryComponent battery,
|
||||
PowerNetworkBatteryComponent netBattery)
|
||||
{
|
||||
if (!_uiSystem.IsUiOpen(uid, BatteryUiKey.Key))
|
||||
return;
|
||||
|
||||
_uiSystem.SetUiState(
|
||||
uid,
|
||||
BatteryUiKey.Key,
|
||||
new BatteryBuiState
|
||||
{
|
||||
Capacity = battery.MaxCharge,
|
||||
Charge = battery.CurrentCharge,
|
||||
CanCharge = netBattery.CanCharge,
|
||||
CanDischarge = netBattery.CanDischarge,
|
||||
CurrentReceiving = netBattery.CurrentReceiving,
|
||||
CurrentSupply = netBattery.CurrentSupply,
|
||||
MaxSupply = netBattery.MaxSupply,
|
||||
MaxChargeRate = netBattery.MaxChargeRate,
|
||||
Efficiency = netBattery.Efficiency,
|
||||
MaxMaxSupply = batteryInterface.MaxSupply,
|
||||
MinMaxSupply = batteryInterface.MinSupply,
|
||||
MaxMaxChargeRate = batteryInterface.MaxChargeRate,
|
||||
MinMaxChargeRate = batteryInterface.MinChargeRate,
|
||||
SupplyingNetworkHasPower = CheckHasPower<BatteryChargerComponent>(uid),
|
||||
LoadingNetworkHasPower = CheckHasPower<BatteryDischargerComponent>(uid),
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
bool CheckHasPower<TComp>(EntityUid entity) where TComp : BasePowerNetComponent
|
||||
{
|
||||
if (!TryComp(entity, out TComp? comp))
|
||||
return false;
|
||||
|
||||
if (comp.Net == null)
|
||||
return false;
|
||||
|
||||
return comp.Net.NetworkNode.LastCombinedMaxSupply > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user