Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Client.Guidebook.Components;
using Content.Client.UserInterface.Controls;
using Content.Shared.Chemistry;
using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations;
Expand Down Expand Up @@ -31,8 +32,7 @@ protected override void Open()

// Setup window layout/elements
_window = this.CreateWindow<ReagentDispenserWindow>();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
_window.HelpGuidebookIds = EntMan.GetComponent<GuideHelpComponent>(Owner).Guides;
_window.SetInfoFromEntity(EntMan, Owner);

// Setup static button actions.
_window.EjectButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName));
Expand Down
11 changes: 11 additions & 0 deletions Content.Client/Entry/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Content.Client.Screenshot;
using Content.Client.Singularity;
using Content.Client.Stylesheets;
using Content.Client.UserInterface;
using Content.Client.Viewport;
using Content.Client.Voting;
using Content.Shared.Ame.Components;
Expand Down Expand Up @@ -77,6 +78,7 @@ public sealed class EntryPoint : GameClient
[Dependency] private readonly DebugMonitorManager _debugMonitorManager = default!;
[Dependency] private readonly TitleWindowManager _titleWindowManager = default!;
[Dependency] private readonly DiscordAuthManager _discordAuth = default!; // Floofstation
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;

public override void Init()
{
Expand Down Expand Up @@ -237,6 +239,15 @@ public override void Update(ModUpdateLevel level, FrameEventArgs frameEventArgs)
{
_debugMonitorManager.FrameUpdate();
}

if (level == ModUpdateLevel.PreEngine)
{
if (_baseClient.RunLevel is ClientRunLevel.InGame or ClientRunLevel.SinglePlayerGame)
{
var updateSystem = _entitySystemManager.GetEntitySystem<BuiPreTickUpdateSystem>();
updateSystem.RunUpdates();
}
}
}
}
}
85 changes: 85 additions & 0 deletions Content.Client/Power/Battery/BatteryBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Content.Client.UserInterface;
using Content.Shared.Power;
using JetBrains.Annotations;
using Robust.Client.Timing;
using Robust.Client.UserInterface;

namespace Content.Client.Power.Battery;

/// <summary>
/// BUI for <see cref="BatteryUiKey.Key"/>.
/// </summary>
/// <seealso cref="BoundUserInterfaceState"/>
/// <seealso cref="BatteryMenu"/>
[UsedImplicitly]
public sealed class BatteryBoundUserInterface : BoundUserInterface, IBuiPreTickUpdate
{
[Dependency] private readonly IClientGameTiming _gameTiming = null!;

[ViewVariables]
private BatteryMenu? _menu;

private BuiPredictionState? _pred;
private InputCoalescer<float> _chargeRateCoalescer;
private InputCoalescer<float> _dischargeRateCoalescer;

public BatteryBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}

protected override void Open()
{
base.Open();

_pred = new BuiPredictionState(this, _gameTiming);

_menu = this.CreateWindow<BatteryMenu>();
_menu.SetEntity(Owner);

_menu.OnInBreaker += val => _pred!.SendMessage(new BatterySetInputBreakerMessage(val));
_menu.OnOutBreaker += val => _pred!.SendMessage(new BatterySetOutputBreakerMessage(val));

_menu.OnChargeRate += val => _chargeRateCoalescer.Set(val);
_menu.OnDischargeRate += val => _dischargeRateCoalescer.Set(val);
}

void IBuiPreTickUpdate.PreTickUpdate()
{
if (_chargeRateCoalescer.CheckIsModified(out var chargeRateValue))
_pred!.SendMessage(new BatterySetChargeRateMessage(chargeRateValue));

if (_dischargeRateCoalescer.CheckIsModified(out var dischargeRateValue))
_pred!.SendMessage(new BatterySetDischargeRateMessage(dischargeRateValue));
}

protected override void UpdateState(BoundUserInterfaceState state)
{
if (state is not BatteryBuiState batteryState)
return;

foreach (var replayMsg in _pred!.MessagesToReplay())
{
switch (replayMsg)
{
case BatterySetInputBreakerMessage setInputBreaker:
batteryState.CanCharge = setInputBreaker.On;
break;

case BatterySetOutputBreakerMessage setOutputBreaker:
batteryState.CanDischarge = setOutputBreaker.On;
break;

case BatterySetChargeRateMessage setChargeRate:
batteryState.MaxChargeRate = setChargeRate.Rate;
break;

case BatterySetDischargeRateMessage setDischargeRate:
batteryState.MaxSupply = setDischargeRate.Rate;
break;
}
}

_menu?.Update(batteryState);
}
}
146 changes: 146 additions & 0 deletions Content.Client/Power/Battery/BatteryMenu.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
SetSize="650 330"
Resizable="False">
<BoxContainer Orientation="Vertical">
<!-- Top row: main content -->
<BoxContainer Name="MainContent" Orientation="Horizontal" VerticalExpand="True" Margin="4">
<!-- Left pane: I/O, passthrough, sprite view -->
<BoxContainer Name="IOPane" Orientation="Vertical" HorizontalExpand="True">
<!-- Top row: input -->
<BoxContainer Name="InputRow" Orientation="Horizontal">
<!-- Input power line -->
<PanelContainer Name="InPowerLine" SetHeight="2" VerticalAlignment="Top" SetWidth="32"
Margin="2 16" />

<!-- Box with breaker, label, values -->
<PanelContainer HorizontalExpand="True" StyleClasses="Inset">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'battery-menu-in'}" HorizontalExpand="True" VerticalAlignment="Top"
StyleClasses="LabelKeyText" />
<controls:OnOffButton Name="InBreaker" />
</BoxContainer>
<Label Name="InValue" />
</BoxContainer>
</PanelContainer>
</BoxContainer>

<!-- Middle row: Entity view & passthrough -->
<BoxContainer Name="MiddleRow" Orientation="Horizontal" VerticalExpand="True">
<SpriteView Name="EntityView" SetSize="64 64" Scale="2 2" OverrideDirection="South" Margin="15" />

<BoxContainer Orientation="Vertical" VerticalAlignment="Center" HorizontalExpand="True"
HorizontalAlignment="Right">
<Label HorizontalAlignment="Right" Text="{Loc 'battery-menu-passthrough'}" StyleClasses="StatusFieldTitle" />
<Label HorizontalAlignment="Right" Name="PassthroughValue" />
</BoxContainer>
</BoxContainer>

<!-- Bottom row: output -->
<BoxContainer Name="OutputRow" Orientation="Horizontal">
<!-- Output power line -->
<PanelContainer Name="OutPowerLine" SetHeight="2" VerticalAlignment="Bottom" SetWidth="32"
Margin="2 16" />

<!-- Box with breaker, label, values -->
<PanelContainer HorizontalExpand="True" StyleClasses="Inset">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'battery-menu-out'}" HorizontalExpand="True" VerticalAlignment="Top"
StyleClasses="LabelKeyText" />
<controls:OnOffButton Name="OutBreaker" />
</BoxContainer>
<Label Name="OutValue" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
</BoxContainer>

<!-- Separator connecting panes with some wires -->
<BoxContainer Orientation="Vertical" SetWidth="22" Margin="2 16">
<PanelContainer Name="InSecondPowerLine" SetHeight="2" />
<PanelContainer Name="PassthroughPowerLine" SetWidth="2" HorizontalAlignment="Center" VerticalExpand="True" />
<PanelContainer Name="OutSecondPowerLine" SetHeight="2" />
</BoxContainer>

<!-- Middle pane: charge/discharge -->
<BoxContainer Name="ChargeDischarge" Orientation="Vertical" HorizontalExpand="True">
<!-- Charge -->
<PanelContainer VerticalExpand="True" StyleClasses="Inset" Margin="0 0 0 8">
<BoxContainer Orientation="Vertical">
<Label Text="{Loc 'battery-menu-charge-header'}" StyleClasses="LabelKeyText" />
<BoxContainer Orientation="Vertical" VerticalExpand="True" VerticalAlignment="Center">
<Slider Name="ChargeRateSlider" />
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'battery-menu-max'}" StyleClasses="StatusFieldTitle" HorizontalExpand="True" />
<Label Name="ChargeMaxValue" />
</BoxContainer>
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'battery-menu-current'}" StyleClasses="StatusFieldTitle" HorizontalExpand="True" />
<Label Name="ChargeCurrentValue" />
</BoxContainer>
</BoxContainer>
</PanelContainer>
<!-- Discharge -->
<PanelContainer VerticalExpand="True" StyleClasses="Inset">
<BoxContainer Orientation="Vertical">
<Label Text="{Loc 'battery-menu-discharge-header'}" StyleClasses="LabelKeyText" />
<BoxContainer Orientation="Vertical" VerticalExpand="True" VerticalAlignment="Center">
<Slider Name="DischargeRateSlider" />
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'battery-menu-max'}" StyleClasses="StatusFieldTitle" HorizontalExpand="True" />
<Label Name="DischargeMaxValue" />
</BoxContainer>
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'battery-menu-current'}" StyleClasses="StatusFieldTitle" HorizontalExpand="True" />
<Label Name="DischargeCurrentValue" />
</BoxContainer>
</BoxContainer>
</PanelContainer>
</BoxContainer>

<!-- Separator connecting panes with some wires -->
<BoxContainer Orientation="Vertical" SetWidth="22" Margin="2 16">
<PanelContainer Name="ChargePowerLine" SetHeight="2" VerticalAlignment="Top" VerticalExpand="True" />
<PanelContainer Name="DischargePowerLine" SetHeight="2" VerticalAlignment="Bottom" VerticalExpand="True" />
</BoxContainer>

<!-- Right pane: storage -->
<PanelContainer Name="Storage" StyleClasses="Inset" HorizontalExpand="True">
<BoxContainer Orientation="Vertical">
<Label Text="{Loc 'battery-menu-storage-header'}" StyleClasses="LabelKeyText" />
<GridContainer Columns="2">
<Label Text="{Loc 'battery-menu-stored'}" StyleClasses="StatusFieldTitle" />
<Label Name="StoredPercentageValue" HorizontalAlignment="Right" HorizontalExpand="True" />
<Label Text="{Loc 'battery-menu-energy'}" StyleClasses="StatusFieldTitle" />
<Label Name="StoredEnergyValue" HorizontalAlignment="Right" />
<Label Name="EtaLabel" StyleClasses="StatusFieldTitle" />
<Label Name="EtaValue" HorizontalAlignment="Right" />
</GridContainer>

<!-- Charge meter -->
<GridContainer Name="ChargeMeter" Columns="3" VerticalExpand="True" Margin="0 24 0 0">

</GridContainer>
</BoxContainer>
</PanelContainer>
</BoxContainer>

<!-- Footer -->
<BoxContainer Name="Footer" Orientation="Vertical">
<PanelContainer StyleClasses="LowDivider" />
<BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
<Label Text="{Loc 'battery-menu-footer-left'}" StyleClasses="WindowFooterText" />
<Label Text="{Loc 'battery-menu-footer-right'}" StyleClasses="WindowFooterText"
HorizontalAlignment="Right" HorizontalExpand="True" Margin="0 0 5 0" />
<TextureRect StyleClasses="NTLogoDark" Stretch="KeepAspectCentered"
VerticalAlignment="Center" HorizontalAlignment="Right" SetSize="19 19" />
</BoxContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
Loading
Loading