Skip to content

Commit

Permalink
Merge pull request #425 from fenndragon/Anchor
Browse files Browse the repository at this point in the history
Station Anchor
  • Loading branch information
Fansana authored Dec 22, 2024
2 parents 4894794 + ff97abf commit 932b132
Show file tree
Hide file tree
Showing 20 changed files with 881 additions and 1 deletion.
39 changes: 39 additions & 0 deletions Content.Client/Power/PowerCharge/PowerChargeBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Content.Shared.Power;
using Robust.Client.UserInterface;

namespace Content.Client.Power.PowerCharge;

public sealed class PowerChargeBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private PowerChargeWindow? _window;

public PowerChargeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}

public void SetPowerSwitch(bool on)
{
SendMessage(new SwitchChargingMachineMessage(on));
}

protected override void Open()
{
base.Open();
if (!EntMan.TryGetComponent(Owner, out PowerChargeComponent? component))
return;

_window = new PowerChargeWindow();
_window.UpdateWindow(this, Loc.GetString(component.WindowTitle));

}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not PowerChargeState chargeState)
return;

_window?.UpdateState(chargeState);
}
}
10 changes: 10 additions & 0 deletions Content.Client/Power/PowerCharge/PowerChargeComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Content.Shared.Power;

namespace Content.Client.Power.PowerCharge;

/// <inheritdoc cref="Content.Shared.Power.SharedPowerChargeComponent" />
[RegisterComponent]
public sealed partial class PowerChargeComponent : SharedPowerChargeComponent
{

}
33 changes: 33 additions & 0 deletions Content.Client/Power/PowerCharge/PowerChargeWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MinSize="270 130"
SetSize="360 180">
<BoxContainer Margin="4 0" Orientation="Horizontal">
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<GridContainer Margin="2 0 0 0" Columns="2">
<!-- Power -->
<Label Text="{Loc 'power-charge-window-power'}" HorizontalExpand="True" StyleClasses="StatusFieldTitle" />
<BoxContainer Orientation="Horizontal" MinWidth="120">
<Button Name="OnButton" Text="{Loc 'power-charge-window-power-on'}" StyleClasses="OpenRight" />
<Button Name="OffButton" Text="{Loc 'power-charge-window-power-off'}" StyleClasses="OpenLeft" />
</BoxContainer>
<Control /> <!-- Empty control to act as a spacer in the grid. -->
<Label Name="PowerLabel" Text="0 / 0 W" />
<!-- Status -->
<Label Text="{Loc 'power-charge-window-status'}" StyleClasses="StatusFieldTitle" />
<Label Name="StatusLabel" Text="{Loc 'power-charge-window-status-fully-charged'}" />
<!-- ETA -->
<Label Text="{Loc 'power-charge-window-eta'}" StyleClasses="StatusFieldTitle" />
<Label Name="EtaLabel" Text="N/A" />
<!-- Charge -->
<Label Text="{Loc 'power-charge-window-charge'}" StyleClasses="StatusFieldTitle" />
<ProgressBar Name="ChargeBar" MaxValue="255">
<Label Name="ChargeText" Margin="4 0" Text="0 %" />
</ProgressBar>
</GridContainer>
</BoxContainer>
<PanelContainer Margin="12 0 0 0" StyleClasses="Inset" VerticalAlignment="Center">
<SpriteView Name="EntityView" SetSize="96 96" OverrideDirection="South" />
</PanelContainer>
</BoxContainer>
</controls:FancyWindow>
72 changes: 72 additions & 0 deletions Content.Client/Power/PowerCharge/PowerChargeWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Power;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client.Power.PowerCharge;

[GenerateTypedNameReferences]
public sealed partial class PowerChargeWindow : FancyWindow
{
private readonly ButtonGroup _buttonGroup = new();

public PowerChargeWindow()
{
RobustXamlLoader.Load(this);

OnButton.Group = _buttonGroup;
OffButton.Group = _buttonGroup;
}

public void UpdateWindow(PowerChargeBoundUserInterface bui, string title)
{
Title = title;

OnButton.OnPressed += _ => bui.SetPowerSwitch(true);
OffButton.OnPressed += _ => bui.SetPowerSwitch(false);

EntityView.SetEntity(bui.Owner);
}

public void UpdateState(PowerChargeState state)
{
if (state.On)
OnButton.Pressed = true;
else
OffButton.Pressed = true;

PowerLabel.Text = Loc.GetString(
"power-charge-window-power-label",
("draw", state.PowerDraw),
("max", state.PowerDrawMax));

PowerLabel.SetOnlyStyleClass(MathHelper.CloseTo(state.PowerDraw, state.PowerDrawMax) ? "Good" : "Caution");

ChargeBar.Value = state.Charge;
ChargeText.Text = (state.Charge / 255f).ToString("P0");
StatusLabel.Text = Loc.GetString(state.PowerStatus switch
{
PowerChargePowerStatus.Off => "power-charge-window-status-off",
PowerChargePowerStatus.Discharging => "power-charge-window-status-discharging",
PowerChargePowerStatus.Charging => "power-charge-window-status-charging",
PowerChargePowerStatus.FullyCharged => "power-charge-window-status-fully-charged",
_ => throw new ArgumentOutOfRangeException()
});

StatusLabel.SetOnlyStyleClass(state.PowerStatus switch
{
PowerChargePowerStatus.Off => "Danger",
PowerChargePowerStatus.Discharging => "Caution",
PowerChargePowerStatus.Charging => "Caution",
PowerChargePowerStatus.FullyCharged => "Good",
_ => throw new ArgumentOutOfRangeException()
});

EtaLabel.Text = state.EtaSeconds >= 0
? Loc.GetString("power-charge-window-eta-value", ("left", TimeSpan.FromSeconds(state.EtaSeconds)))
: Loc.GetString("power-charge-window-eta-none");

EtaLabel.SetOnlyStyleClass(state.EtaSeconds >= 0 ? "Caution" : "Disabled");
}
}
66 changes: 66 additions & 0 deletions Content.Server/Power/Components/PowerChargeComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Content.Server.Power.EntitySystems;
using Content.Shared.Power;

namespace Content.Server.Power.Components;

/// <inheritdoc cref="Content.Shared.Power.SharedPowerChargeComponent" />
[RegisterComponent]
[Access(typeof(PowerChargeSystem))]
public sealed partial class PowerChargeComponent : SharedPowerChargeComponent
{
/// <summary>
/// Change in charge per second.
/// </summary>
[DataField]
public float ChargeRate { get; set; } = 0.01f;

/// <summary>
/// Baseline power that this machine consumes.
/// </summary>
[DataField("idlePower")]
public float IdlePowerUse { get; set; }

/// <summary>
/// Power consumed when <see cref="SwitchedOn"/> is true.
/// </summary>
[DataField("activePower")]
public float ActivePowerUse { get; set; }

/// <summary>
/// Is the gravity generator intact?
/// </summary>
[DataField]
public bool Intact { get; set; } = true;

/// <summary>
/// Is the power switch on?
/// </summary>
[DataField]
public bool SwitchedOn { get; set; } = true;

/// <summary>
/// Whether or not the power is switched on and the entity has charged up.
/// </summary>
[DataField]
public bool Active { get; set; }

[DataField]
public float MaxCharge { get; set; } = 1;

/// <summary>
/// The UI key of the UI that's used with this machine.<br/>
/// This is used to allow machine power charging to be integrated into any ui
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public Enum UiKey { get; set; } = PowerChargeUiKey.Key;

/// <summary>
/// Current charge value.
/// Goes from 0 to 1.
/// </summary>
[DataField]
public float Charge { get; set; } = 1;

[ViewVariables]
public bool NeedUIUpdate { get; set; }
}
Loading

0 comments on commit 932b132

Please sign in to comment.