Re-organize all projects (#4166)
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.DragDrop;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.Disposal.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedDisposalMailingUnitComponent))]
|
||||
public class DisposalMailingUnitComponent : SharedDisposalMailingUnitComponent
|
||||
{
|
||||
public override bool DragDropOn(DragDropEvent eventArgs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Content.Client/Disposal/Components/DisposalUnitComponent.cs
Normal file
16
Content.Client/Disposal/Components/DisposalUnitComponent.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.DragDrop;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.Disposal.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedDisposalUnitComponent))]
|
||||
public class DisposalUnitComponent : SharedDisposalUnitComponent
|
||||
{
|
||||
public override bool DragDropOn(DragDropEvent eventArgs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.GameObjects;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalMailingUnitComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="DisposalMailingUnitWindow"/> and updates it when new server messages are received.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class DisposalMailingUnitBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private DisposalMailingUnitWindow? _window;
|
||||
|
||||
public DisposalMailingUnitBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private void ButtonPressed(UiButton button)
|
||||
{
|
||||
SendMessage(new UiButtonPressedMessage(button));
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new DisposalMailingUnitWindow();
|
||||
|
||||
_window.OpenCentered();
|
||||
_window.OnClose += Close;
|
||||
|
||||
_window.Eject.OnPressed += _ => ButtonPressed(UiButton.Eject);
|
||||
_window.Engage.OnPressed += _ => ButtonPressed(UiButton.Engage);
|
||||
_window.Power.OnPressed += _ => ButtonPressed(UiButton.Power);
|
||||
_window.TargetListContainer.OnItemSelected += TargetSelected;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not DisposalMailingUnitBoundUserInterfaceState cast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_window?.UpdateState(cast);
|
||||
}
|
||||
|
||||
private void TargetSelected(ItemList.ItemListSelectedEventArgs item)
|
||||
{
|
||||
SendMessage(new UiTargetUpdateMessage(_window?.TargetList[item.ItemIndex]));
|
||||
//(ノ°Д°)ノ︵ ┻━┻
|
||||
if (_window != null) _window.Engage.Disabled = false;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
263
Content.Client/Disposal/UI/DisposalMailingUnitWindow.cs
Normal file
263
Content.Client/Disposal/UI/DisposalMailingUnitWindow.cs
Normal file
@@ -0,0 +1,263 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalMailingUnitComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="SharedDisposalMailingUnitComponent"/>
|
||||
/// </summary>
|
||||
public class DisposalMailingUnitWindow : SS14Window
|
||||
{
|
||||
private readonly Label _unitState;
|
||||
private readonly ProgressBar _pressureBar;
|
||||
private readonly Label _pressurePercentage;
|
||||
public readonly Button Engage;
|
||||
public readonly Button Eject;
|
||||
public readonly Button Power;
|
||||
|
||||
public readonly ItemList TargetListContainer;
|
||||
public List<string> TargetList;
|
||||
private readonly Label _tagLabel;
|
||||
|
||||
public DisposalMailingUnitWindow()
|
||||
{
|
||||
MinSize = SetSize = (460, 230);
|
||||
TargetList = new List<string>();
|
||||
Contents.AddChild(new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new VBoxContainer
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
Margin = new Thickness(8, 0),
|
||||
Children =
|
||||
{
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("State: ")},
|
||||
new Control {MinSize = (4, 0)},
|
||||
(_unitState = new Label {Text = Loc.GetString("Ready")})
|
||||
}
|
||||
},
|
||||
new Control {MinSize = (0, 10)},
|
||||
new HBoxContainer
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Pressure:")},
|
||||
new Control {MinSize = (4, 0)},
|
||||
(_pressureBar = new ProgressBar
|
||||
{
|
||||
MinSize = (100, 20),
|
||||
HorizontalExpand = true,
|
||||
MinValue = 0,
|
||||
MaxValue = 1,
|
||||
Page = 0,
|
||||
Value = 0.5f,
|
||||
Children =
|
||||
{
|
||||
(_pressurePercentage = new Label())
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
new Control {MinSize = (0, 10)},
|
||||
new HBoxContainer
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Handle:")},
|
||||
new Control
|
||||
{
|
||||
MinSize = (4, 0),
|
||||
HorizontalExpand = true
|
||||
},
|
||||
(Engage = new Button
|
||||
{
|
||||
MinSize = (16, 0),
|
||||
Text = Loc.GetString("Engage"),
|
||||
ToggleMode = true,
|
||||
Disabled = true
|
||||
})
|
||||
}
|
||||
},
|
||||
new Control {MinSize = (0, 10)},
|
||||
new HBoxContainer
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Eject:")},
|
||||
new Control
|
||||
{
|
||||
MinSize = (4, 0),
|
||||
HorizontalExpand = true
|
||||
},
|
||||
(Eject = new Button
|
||||
{
|
||||
MinSize = (16, 0),
|
||||
Text = Loc.GetString("Eject Contents"),
|
||||
//HorizontalAlignment = HAlignment.Right
|
||||
})
|
||||
}
|
||||
},
|
||||
new Control {MinSize = (0, 10)},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(Power = new CheckButton {Text = Loc.GetString("Power")}),
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new VBoxContainer
|
||||
{
|
||||
Margin = new Thickness(12, 0, 8, 0),
|
||||
Children =
|
||||
{
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label
|
||||
{
|
||||
Text = Loc.GetString("Select a destination:")
|
||||
}
|
||||
}
|
||||
},
|
||||
new Control {MinSize = new Vector2(0, 8)},
|
||||
new HBoxContainer
|
||||
{
|
||||
VerticalExpand = true,
|
||||
Children =
|
||||
{
|
||||
(TargetListContainer = new ItemList
|
||||
{
|
||||
SelectMode = ItemList.ItemListSelectMode.Single,
|
||||
HorizontalExpand = true,
|
||||
VerticalExpand = true
|
||||
})
|
||||
}
|
||||
},
|
||||
new PanelContainer
|
||||
{
|
||||
PanelOverride = new StyleBoxFlat
|
||||
{
|
||||
BackgroundColor = Color.FromHex("#ACBDBA")
|
||||
},
|
||||
HorizontalExpand = true,
|
||||
MinSize = new Vector2(0, 1),
|
||||
},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new HBoxContainer
|
||||
{
|
||||
Margin = new Thickness(4, 0, 0, 0),
|
||||
Children =
|
||||
{
|
||||
new Label
|
||||
{
|
||||
Text = Loc.GetString("This unit:")
|
||||
},
|
||||
new Control
|
||||
{
|
||||
MinSize = new Vector2(4, 0)
|
||||
},
|
||||
(_tagLabel = new Label
|
||||
{
|
||||
Text = "-",
|
||||
VerticalAlignment = VAlignment.Bottom
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
var percentage = pressure / _pressureBar.MaxValue * 100;
|
||||
_pressurePercentage.Text = $" {percentage:0}%";
|
||||
}
|
||||
|
||||
public void UpdateState(DisposalMailingUnitBoundUserInterfaceState state)
|
||||
{
|
||||
Title = state.UnitName;
|
||||
_unitState.Text = state.UnitState;
|
||||
UpdatePressureBar(state.Pressure);
|
||||
Power.Pressed = state.Powered;
|
||||
Engage.Pressed = state.Engaged;
|
||||
PopulateTargetList(state.Tags);
|
||||
_tagLabel.Text = state.Tag;
|
||||
TargetList = state.Tags;
|
||||
}
|
||||
|
||||
private void PopulateTargetList(List<string> tags)
|
||||
{
|
||||
TargetListContainer.Clear();
|
||||
foreach (var target in tags)
|
||||
{
|
||||
TargetListContainer.AddItem(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="DisposalRouterWindow"/> and updates it when new server messages are received.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class DisposalRouterBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private DisposalRouterWindow? _window;
|
||||
|
||||
public DisposalRouterBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new DisposalRouterWindow();
|
||||
|
||||
_window.OpenCentered();
|
||||
_window.OnClose += Close;
|
||||
|
||||
_window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text);
|
||||
_window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text);
|
||||
|
||||
}
|
||||
|
||||
private void ButtonPressed(UiAction action, string tag)
|
||||
{
|
||||
SendMessage(new UiActionMessage(action, tag));
|
||||
_window?.Close();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not DisposalRouterUserInterfaceState cast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_window?.UpdateState(cast);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
54
Content.Client/Disposal/UI/DisposalRouterWindow.cs
Normal file
54
Content.Client/Disposal/UI/DisposalRouterWindow.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="SharedDisposalRouterComponent"/>
|
||||
/// </summary>
|
||||
public class DisposalRouterWindow : SS14Window
|
||||
{
|
||||
public readonly LineEdit TagInput;
|
||||
public readonly Button Confirm;
|
||||
|
||||
public DisposalRouterWindow()
|
||||
{
|
||||
MinSize = SetSize = (500, 110);
|
||||
Title = Loc.GetString("Disposal Router");
|
||||
|
||||
Contents.AddChild(new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Tags:")},
|
||||
new Control {MinSize = (0, 10)},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(TagInput = new LineEdit
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
MinSize = (320, 0),
|
||||
ToolTip = Loc.GetString("A comma separated list of tags"),
|
||||
IsValid = tags => TagRegex.IsMatch(tags)
|
||||
}),
|
||||
new Control {MinSize = (10, 0)},
|
||||
(Confirm = new Button {Text = Loc.GetString("Confirm")})
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void UpdateState(DisposalRouterUserInterfaceState state)
|
||||
{
|
||||
TagInput.Text = state.Tags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="DisposalTaggerWindow"/> and updates it when new server messages are received.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class DisposalTaggerBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private DisposalTaggerWindow? _window;
|
||||
|
||||
public DisposalTaggerBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new DisposalTaggerWindow();
|
||||
|
||||
_window.OpenCentered();
|
||||
_window.OnClose += Close;
|
||||
|
||||
_window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text);
|
||||
_window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text);
|
||||
|
||||
}
|
||||
|
||||
private void ButtonPressed(UiAction action, string tag)
|
||||
{
|
||||
SendMessage(new UiActionMessage(action, tag));
|
||||
_window?.Close();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not DisposalTaggerUserInterfaceState cast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_window?.UpdateState(cast);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
53
Content.Client/Disposal/UI/DisposalTaggerWindow.cs
Normal file
53
Content.Client/Disposal/UI/DisposalTaggerWindow.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="SharedDisposalTaggerComponent"/>
|
||||
/// </summary>
|
||||
public class DisposalTaggerWindow : SS14Window
|
||||
{
|
||||
public readonly LineEdit TagInput;
|
||||
public readonly Button Confirm;
|
||||
|
||||
public DisposalTaggerWindow()
|
||||
{
|
||||
MinSize = SetSize = (500, 110);
|
||||
Title = Loc.GetString("Disposal Tagger");
|
||||
|
||||
Contents.AddChild(new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("Tag:")},
|
||||
new Control {MinSize = (0, 10)},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(TagInput = new LineEdit
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
MinSize = (320, 0),
|
||||
IsValid = tag => TagRegex.IsMatch(tag)
|
||||
}),
|
||||
new Control {MinSize = (10, 0)},
|
||||
(Confirm = new Button {Text = Loc.GetString("Confirm")})
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void UpdateState(DisposalTaggerUserInterfaceState state)
|
||||
{
|
||||
TagInput.Text = state.Tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Content.Client/Disposal/UI/DisposalUnitBoundUserInterface.cs
Normal file
61
Content.Client/Disposal/UI/DisposalUnitBoundUserInterface.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
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.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public class DisposalUnitBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private DisposalUnitWindow? _window;
|
||||
|
||||
public DisposalUnitBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private void ButtonPressed(UiButton button)
|
||||
{
|
||||
SendMessage(new UiButtonPressedMessage(button));
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new DisposalUnitWindow();
|
||||
|
||||
_window.OpenCentered();
|
||||
_window.OnClose += Close;
|
||||
|
||||
_window.Eject.OnPressed += _ => ButtonPressed(UiButton.Eject);
|
||||
_window.Engage.OnPressed += _ => ButtonPressed(UiButton.Engage);
|
||||
_window.Power.OnPressed += _ => ButtonPressed(UiButton.Power);
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not DisposalUnitBoundUserInterfaceState cast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_window?.UpdateState(cast);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
Content.Client/Disposal/UI/DisposalUnitWindow.cs
Normal file
137
Content.Client/Disposal/UI/DisposalUnitWindow.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-side UI used to control a <see cref="SharedDisposalUnitComponent"/>
|
||||
/// </summary>
|
||||
public class DisposalUnitWindow : SS14Window
|
||||
{
|
||||
private readonly Label _unitState;
|
||||
private readonly ProgressBar _pressureBar;
|
||||
public readonly Button Engage;
|
||||
public readonly Button Eject;
|
||||
public readonly Button Power;
|
||||
|
||||
public DisposalUnitWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
MinSize = SetSize = (300, 140);
|
||||
Resizable = false;
|
||||
Contents.AddChild(new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new HBoxContainer
|
||||
{
|
||||
SeparationOverride = 4,
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("ui-disposal-unit-label-state")},
|
||||
(_unitState = new Label {Text = Loc.GetString("ui-disposal-unit-label-status")})
|
||||
}
|
||||
},
|
||||
new Control {MinSize = (0, 5)},
|
||||
new HBoxContainer
|
||||
{
|
||||
SeparationOverride = 4,
|
||||
Children =
|
||||
{
|
||||
new Label {Text = Loc.GetString("ui-disposal-unit-label-pressure")},
|
||||
(_pressureBar = new ProgressBar
|
||||
{
|
||||
MinSize = (190, 20),
|
||||
HorizontalAlignment = HAlignment.Right,
|
||||
MinValue = 0,
|
||||
MaxValue = 1,
|
||||
Page = 0,
|
||||
Value = 0.5f
|
||||
})
|
||||
}
|
||||
},
|
||||
new Control {MinSize = (0, 10)},
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(Engage = new Button
|
||||
{
|
||||
Text = Loc.GetString("ui-disposal-unit-button-flush"),
|
||||
StyleClasses = {StyleBase.ButtonOpenRight},
|
||||
ToggleMode = true
|
||||
}),
|
||||
|
||||
(Eject = new Button
|
||||
{
|
||||
Text = Loc.GetString("ui-disposal-unit-button-eject"),
|
||||
StyleClasses = {StyleBase.ButtonOpenBoth}
|
||||
}),
|
||||
|
||||
(Power = new CheckButton
|
||||
{
|
||||
Text = Loc.GetString("ui-disposal-unit-button-power"),
|
||||
StyleClasses = {StyleBase.ButtonOpenLeft}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
public void UpdateState(DisposalUnitBoundUserInterfaceState state)
|
||||
{
|
||||
Title = state.UnitName;
|
||||
_unitState.Text = state.UnitState;
|
||||
UpdatePressureBar(state.Pressure);
|
||||
Power.Pressed = state.Powered;
|
||||
Engage.Pressed = state.Engaged;
|
||||
}
|
||||
}
|
||||
}
|
||||
171
Content.Client/Disposal/Visualizers/DisposalUnitVisualizer.cs
Normal file
171
Content.Client/Disposal/Visualizers/DisposalUnitVisualizer.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
|
||||
|
||||
namespace Content.Client.Disposal.Visualizers
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class DisposalUnitVisualizer : AppearanceVisualizer, ISerializationHooks
|
||||
{
|
||||
private const string AnimationKey = "disposal_unit_animation";
|
||||
|
||||
[DataField("state_anchored", required: true)]
|
||||
private string? _stateAnchored;
|
||||
|
||||
[DataField("state_unanchored", required: true)]
|
||||
private string? _stateUnAnchored;
|
||||
|
||||
[DataField("state_charging", required: true)]
|
||||
private string? _stateCharging;
|
||||
|
||||
[DataField("overlay_charging", required: true)]
|
||||
private string? _overlayCharging;
|
||||
|
||||
[DataField("overlay_ready", required: true)]
|
||||
private string? _overlayReady;
|
||||
|
||||
[DataField("overlay_full", required: true)]
|
||||
private string? _overlayFull;
|
||||
|
||||
[DataField("overlay_engaged", required: true)]
|
||||
private string? _overlayEngaged;
|
||||
|
||||
[DataField("state_flush", required: true)]
|
||||
private string? _stateFlush;
|
||||
|
||||
[DataField("flush_sound", required: true)]
|
||||
private string? _flushSound;
|
||||
|
||||
[DataField("flush_time", required: true)]
|
||||
private float _flushTime;
|
||||
|
||||
private Animation _flushAnimation = default!;
|
||||
|
||||
void ISerializationHooks.AfterDeserialization()
|
||||
{
|
||||
_flushAnimation = new Animation {Length = TimeSpan.FromSeconds(_flushTime)};
|
||||
|
||||
var flick = new AnimationTrackSpriteFlick();
|
||||
_flushAnimation.AnimationTracks.Add(flick);
|
||||
flick.LayerKey = DisposalUnitVisualLayers.Base;
|
||||
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(_stateFlush, 0));
|
||||
|
||||
var sound = new AnimationTrackPlaySound();
|
||||
_flushAnimation.AnimationTracks.Add(sound);
|
||||
|
||||
if (_flushSound != null)
|
||||
{
|
||||
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_flushSound, 0));
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeState(AppearanceComponent appearance)
|
||||
{
|
||||
if (!appearance.TryGetData(Visuals.VisualState, out VisualState state))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!appearance.Owner.TryGetComponent(out ISpriteComponent? sprite))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case VisualState.UnAnchored:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Base, _stateUnAnchored);
|
||||
break;
|
||||
case VisualState.Anchored:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Base, _stateAnchored);
|
||||
break;
|
||||
case VisualState.Charging:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Base, _stateCharging);
|
||||
break;
|
||||
case VisualState.Flushing:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Base, _stateAnchored);
|
||||
|
||||
var animPlayer = appearance.Owner.GetComponent<AnimationPlayerComponent>();
|
||||
|
||||
if (!animPlayer.HasRunningAnimation(AnimationKey))
|
||||
{
|
||||
animPlayer.Play(_flushAnimation, AnimationKey);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
if (!appearance.TryGetData(Visuals.Handle, out HandleState handleState))
|
||||
{
|
||||
handleState = HandleState.Normal;
|
||||
}
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Handle, handleState != HandleState.Normal);
|
||||
|
||||
switch (handleState)
|
||||
{
|
||||
case HandleState.Normal:
|
||||
break;
|
||||
case HandleState.Engaged:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Handle, _overlayEngaged);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
if (!appearance.TryGetData(Visuals.Light, out LightState lightState))
|
||||
{
|
||||
lightState = LightState.Off;
|
||||
}
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Light, lightState != LightState.Off);
|
||||
|
||||
switch (lightState)
|
||||
{
|
||||
case LightState.Off:
|
||||
break;
|
||||
case LightState.Charging:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Light, _overlayCharging);
|
||||
break;
|
||||
case LightState.Full:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Light, _overlayFull);
|
||||
break;
|
||||
case LightState.Ready:
|
||||
sprite.LayerSetState(DisposalUnitVisualLayers.Light, _overlayReady);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
|
||||
entity.EnsureComponent<AnimationPlayerComponent>();
|
||||
var appearance = entity.EnsureComponent<AppearanceComponent>();
|
||||
|
||||
ChangeState(appearance);
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
ChangeState(component);
|
||||
}
|
||||
}
|
||||
|
||||
public enum DisposalUnitVisualLayers : byte
|
||||
{
|
||||
Base,
|
||||
Handle,
|
||||
Light
|
||||
}
|
||||
}
|
||||
69
Content.Client/Disposal/Visualizers/DisposalVisualizer.cs
Normal file
69
Content.Client/Disposal/Visualizers/DisposalVisualizer.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using Content.Shared.Disposal.Components;
|
||||
using Content.Shared.SubFloor;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Client.Disposal.Visualizers
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class DisposalVisualizer : AppearanceVisualizer
|
||||
{
|
||||
[DataField("state_free")]
|
||||
private string? _stateFree;
|
||||
|
||||
[DataField("state_anchored")]
|
||||
private string? _stateAnchored;
|
||||
|
||||
[DataField("state_broken")]
|
||||
private string? _stateBroken;
|
||||
|
||||
private void ChangeState(AppearanceComponent appearance)
|
||||
{
|
||||
if (!appearance.Owner.TryGetComponent(out ISpriteComponent? sprite))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!appearance.TryGetData(DisposalTubeVisuals.VisualState, out DisposalTubeVisualState state))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var texture = state switch
|
||||
{
|
||||
DisposalTubeVisualState.Free => _stateFree,
|
||||
DisposalTubeVisualState.Anchored => _stateAnchored,
|
||||
DisposalTubeVisualState.Broken => _stateBroken,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
sprite.LayerSetState(0, texture);
|
||||
|
||||
if (state == DisposalTubeVisualState.Anchored)
|
||||
{
|
||||
appearance.Owner.EnsureComponent<SubFloorHideComponent>();
|
||||
}
|
||||
else if (appearance.Owner.HasComponent<SubFloorHideComponent>())
|
||||
{
|
||||
appearance.Owner.RemoveComponent<SubFloorHideComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitializeEntity(IEntity entity)
|
||||
{
|
||||
base.InitializeEntity(entity);
|
||||
|
||||
var appearance = entity.EnsureComponent<AppearanceComponent>();
|
||||
ChangeState(appearance);
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
ChangeState(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user