Adds disposal mailing units (again) (#7630)

This commit is contained in:
Julian Giebel
2022-08-14 07:57:25 +02:00
committed by GitHub
parent 91ddba9927
commit b2436c22a7
36 changed files with 801 additions and 142 deletions

View File

@@ -1,7 +1,10 @@
using Content.Client.Disposal.Components;
using Content.Client.Disposal.Systems;
using Content.Shared.Disposal;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
@@ -9,12 +12,13 @@ using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
namespace Content.Client.Disposal.UI
{
/// <summary>
/// Initializes a <see cref="DisposalUnitWindow"/> and updates it when new server messages are received.
/// Initializes a <see cref="MailingUnitWindow"/> or a <see cref="DisposalUnitWindow"/> and updates it when new server messages are received.
/// </summary>
[UsedImplicitly]
public sealed class DisposalUnitBoundUserInterface : BoundUserInterface
{
public DisposalUnitWindow? Window;
public MailingUnitWindow? MailingUnitWindow;
public DisposalUnitWindow? DisposalUnitWindow;
public DisposalUnitBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
@@ -27,35 +31,66 @@ namespace Content.Client.Disposal.UI
// the pressure lerp up.
}
private void TargetSelected(ItemList.ItemListSelectedEventArgs args)
{
var item = args.ItemList[args.ItemIndex];
SendMessage(new TargetSelectedMessage(item.Text));
}
protected override void Open()
{
base.Open();
Window = new DisposalUnitWindow();
if (UiKey is MailingUnitUiKey)
{
MailingUnitWindow = new MailingUnitWindow();
Window.OpenCentered();
Window.OnClose += Close;
MailingUnitWindow.OpenCenteredRight();
MailingUnitWindow.OnClose += Close;
Window.Eject.OnPressed += _ => ButtonPressed(UiButton.Eject);
Window.Engage.OnPressed += _ => ButtonPressed(UiButton.Engage);
Window.Power.OnPressed += _ => ButtonPressed(UiButton.Power);
MailingUnitWindow.Eject.OnPressed += _ => ButtonPressed(UiButton.Eject);
MailingUnitWindow.Engage.OnPressed += _ => ButtonPressed(UiButton.Engage);
MailingUnitWindow.Power.OnPressed += _ => ButtonPressed(UiButton.Power);
MailingUnitWindow.TargetListContainer.OnItemSelected += TargetSelected;
}
else if(UiKey is DisposalUnitUiKey)
{
DisposalUnitWindow = new DisposalUnitWindow();
DisposalUnitWindow.OpenCenteredRight();
DisposalUnitWindow.OnClose += Close;
DisposalUnitWindow.Eject.OnPressed += _ => ButtonPressed(UiButton.Eject);
DisposalUnitWindow.Engage.OnPressed += _ => ButtonPressed(UiButton.Engage);
DisposalUnitWindow.Power.OnPressed += _ => ButtonPressed(UiButton.Power);
}
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not DisposalUnitBoundUserInterfaceState cast)
if (state is not MailingUnitBoundUserInterfaceState && state is not DisposalUnitBoundUserInterfaceState)
{
return;
}
Window?.UpdateState(cast);
// Kinda icky but we just want client to handle its own lerping and not flood bandwidth for it.
if (!IoCManager.Resolve<IEntityManager>().TryGetComponent(Owner.Owner, out DisposalUnitComponent? component)) return;
component.UiState = cast;
switch (state)
{
case MailingUnitBoundUserInterfaceState mailingUnitState:
MailingUnitWindow?.UpdateState(mailingUnitState);
component.UiState = mailingUnitState.DisposalState;
break;
case DisposalUnitBoundUserInterfaceState disposalUnitState:
DisposalUnitWindow?.UpdateState(disposalUnitState);
component.UiState = disposalUnitState;
break;
}
EntitySystem.Get<DisposalUnitSystem>().UpdateActive(component, true);
}
@@ -63,10 +98,17 @@ namespace Content.Client.Disposal.UI
{
base.Dispose(disposing);
if (disposing)
{
Window?.Dispose();
}
if (!disposing) return;
MailingUnitWindow?.Dispose();
DisposalUnitWindow?.Dispose();
}
public bool? UpdateWindowState(DisposalUnitBoundUserInterfaceState state)
{
return UiKey is DisposalUnitUiKey
? DisposalUnitWindow?.UpdateState(state)
: MailingUnitWindow?.UpdatePressure(state.FullPressureTime);
}
}
}

View File

@@ -1,5 +1,6 @@
<DefaultWindow xmlns="https://spacestation14.io"
MinSize="300 140"
xmlns:ui="clr-namespace:Content.Client.Disposal.UI"
MinSize="300 140"
SetSize="300 140"
Resizable="False">
<BoxContainer Orientation="Vertical">
@@ -13,7 +14,7 @@
<BoxContainer Orientation="Horizontal"
SeparationOverride="4">
<Label Text="{Loc 'ui-disposal-unit-label-pressure'}" />
<ProgressBar Name="PressureBar"
<ui:PressureBar Name="PressureBar"
MinSize="190 20"
HorizontalAlignment="Right"
MinValue="0"

View File

@@ -1,14 +1,7 @@
using System;
using Content.Shared.Disposal;
using Content.Shared.Disposal.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
namespace Content.Client.Disposal.UI
@@ -25,60 +18,18 @@ namespace Content.Client.Disposal.UI
RobustXamlLoader.Load(this);
}
private void UpdatePressureBar(float pressure)
{
PressureBar.Value = pressure;
var normalized = pressure / PressureBar.MaxValue;
const float leftHue = 0.0f; // Red
const float middleHue = 0.066f; // Orange
const float rightHue = 0.33f; // Green
const float saturation = 1.0f; // Uniform saturation
const float value = 0.8f; // Uniform value / brightness
const float alpha = 1.0f; // Uniform alpha
// These should add up to 1.0 or your transition won't be smooth
const float leftSideSize = 0.5f; // Fraction of _chargeBar lerped from leftHue to middleHue
const float rightSideSize = 0.5f; // Fraction of _chargeBar lerped from middleHue to rightHue
float finalHue;
if (normalized <= leftSideSize)
{
normalized /= leftSideSize; // Adjust range to 0.0 to 1.0
finalHue = MathHelper.Lerp(leftHue, middleHue, normalized);
}
else
{
normalized = (normalized - leftSideSize) / rightSideSize; // Adjust range to 0.0 to 1.0.
finalHue = MathHelper.Lerp(middleHue, rightHue, normalized);
}
// Check if null first to avoid repeatedly creating this.
PressureBar.ForegroundStyleBoxOverride ??= new StyleBoxFlat();
var foregroundStyleBoxOverride = (StyleBoxFlat) PressureBar.ForegroundStyleBoxOverride;
foregroundStyleBoxOverride.BackgroundColor =
Color.FromHsv(new Vector4(finalHue, saturation, value, alpha));
}
/// <summary>
/// Update the interface state for the disposals window.
/// </summary>
/// <returns>true if we should stop updating every frame.</returns>
public bool UpdateState(DisposalUnitBoundUserInterfaceState state)
{
var currentTime = IoCManager.Resolve<IGameTiming>().CurTime;
var fullTime = state.FullPressureTime;
var pressure = (float) Math.Min(1.0f, 1.0f - (fullTime.TotalSeconds - currentTime.TotalSeconds) * SharedDisposalUnitSystem.PressurePerSecond);
Title = state.UnitName;
UnitState.Text = state.UnitState;
UpdatePressureBar(pressure);
Power.Pressed = state.Powered;
Engage.Pressed = state.Engaged;
return !state.Powered || pressure >= 1.0f;
return !state.Powered || PressureBar.UpdatePressure(state.FullPressureTime);
}
}
}

View File

@@ -0,0 +1,53 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.Disposal.UI"
MinSize="300 400"
SetSize="300 400"
Resizable="False">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal" SeparationOverride="8">
<Label Text="{Loc 'ui-mailing-unit-target-label'}" />
<Label Name="Target"
Text="" />
</BoxContainer>
<ItemList Name="TargetListContainer"
Access="Public"
SelectMode="Single"
VerticalExpand="True"
HorizontalExpand="True"
Margin="0 0 0 16">
</ItemList>
<BoxContainer Orientation="Horizontal" SeparationOverride="4">
<Label Text="{Loc 'ui-disposal-unit-label-state'}" />
<Label Name="UnitState"
Text="{Loc 'ui-disposal-unit-label-status'}" />
</BoxContainer>
<Control MinSize="0 5" />
<BoxContainer Orientation="Horizontal"
SeparationOverride="4">
<Label Text="{Loc 'ui-disposal-unit-label-pressure'}" />
<ui:PressureBar Name="PressureBar"
MinSize="190 20"
HorizontalAlignment="Right"
MinValue="0"
MaxValue="1"
Page="0"
Value="0.5" />
</BoxContainer>
<Control MinSize="0 10" />
<BoxContainer Orientation="Horizontal">
<Button Name="Engage"
Access="Public"
Text="{Loc 'ui-mailing-unit-button-flush'}"
StyleClasses="OpenRight"
ToggleMode="True" />
<Button Name="Eject"
Access="Public"
Text="{Loc 'ui-disposal-unit-button-eject'}"
StyleClasses="OpenBoth" />
<CheckButton Name="Power"
Access="Public"
Text="{Loc 'ui-disposal-unit-button-power'}"
StyleClasses="OpenLeft" />
</BoxContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,50 @@
using Content.Shared.Disposal;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.Disposal.UI
{
/// <summary>
/// Client-side UI used to control a <see cref="MailingUnitComponent"/>
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class MailingUnitWindow : DefaultWindow
{
public MailingUnitWindow()
{
RobustXamlLoader.Load(this);
}
/// <summary>
/// Update the interface state for the disposals window.
/// </summary>
/// <returns>true if we should stop updating every frame.</returns>
public bool UpdateState(MailingUnitBoundUserInterfaceState state)
{
var disposalState = state.DisposalState;
Title = Loc.GetString("ui-mailing-unit-window-title", ("tag", state.Tag ?? " "));
UnitState.Text = disposalState.UnitState;
var pressureReached = PressureBar.UpdatePressure(disposalState.FullPressureTime);
Power.Pressed = disposalState.Powered;
Engage.Pressed = disposalState.Engaged;
//UnitTag.Text = state.Tag;
Target.Text = state.Target;
TargetListContainer.Clear();
foreach (var target in state.TargetList)
{
TargetListContainer.AddItem(target);
}
return !disposalState.Powered || pressureReached;
}
public bool UpdatePressure(TimeSpan stateFullPressureTime)
{
return PressureBar.UpdatePressure(stateFullPressureTime);
}
}
}

View File

@@ -0,0 +1,54 @@
using Content.Shared.Disposal;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Timing;
namespace Content.Client.Disposal.UI;
public sealed class PressureBar : ProgressBar
{
public bool UpdatePressure(TimeSpan fullTime)
{
var currentTime = IoCManager.Resolve<IGameTiming>().CurTime;
var pressure = (float) Math.Min(1.0f, 1.0f - (fullTime.TotalSeconds - currentTime.TotalSeconds) * SharedDisposalUnitSystem.PressurePerSecond);
UpdatePressureBar(pressure);
return pressure >= 1.0f;
}
private void UpdatePressureBar(float pressure)
{
Value = pressure;
var normalized = pressure / MaxValue;
const float leftHue = 0.0f; // Red
const float middleHue = 0.066f; // Orange
const float rightHue = 0.33f; // Green
const float saturation = 1.0f; // Uniform saturation
const float value = 0.8f; // Uniform value / brightness
const float alpha = 1.0f; // Uniform alpha
// These should add up to 1.0 or your transition won't be smooth
const float leftSideSize = 0.5f; // Fraction of _chargeBar lerped from leftHue to middleHue
const float rightSideSize = 0.5f; // Fraction of _chargeBar lerped from middleHue to rightHue
float finalHue;
if (normalized <= leftSideSize)
{
normalized /= leftSideSize; // Adjust range to 0.0 to 1.0
finalHue = MathHelper.Lerp(leftHue, middleHue, normalized);
}
else
{
normalized = (normalized - leftSideSize) / rightSideSize; // Adjust range to 0.0 to 1.0.
finalHue = MathHelper.Lerp(middleHue, rightHue, normalized);
}
// Check if null first to avoid repeatedly creating this.
ForegroundStyleBoxOverride ??= new StyleBoxFlat();
var foregroundStyleBoxOverride = (StyleBoxFlat) ForegroundStyleBoxOverride;
foregroundStyleBoxOverride.BackgroundColor =
Color.FromHsv(new Vector4(finalHue, saturation, value, alpha));
}
}