Files
Delta-v/Content.Client/_FarHorizons/Power/UI/TurbineWindow.xaml.cs
T
2026-04-26 21:34:23 +00:00

298 lines
11 KiB
C#

using Content.Client.UserInterface.Controls;
using Content.Shared._FarHorizons.Power.Generation.FissionGenerator;
using Content.Shared.IdentityManagement;
using Content.Shared.Lock;
using Content.Shared.Rounding;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis;
namespace Content.Client._FarHorizons.Power.UI;
/// <summary>
/// Client-side UI used to control a turbine.
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class TurbineWindow : FancyWindow
{
// Dependencies
[Dependency] private readonly IEntityManager _entityManager = null!;
private readonly LockSystem _lock;
#region Variables
//Colors for the RPM meter. (lit)
private static readonly Color[] _speedColors = [
Color.FromHex("#BB3232"),
Color.FromHex("#BB3232"),
Color.FromHex("#BB3232"),
Color.FromHex("#C49438"),
Color.FromHex("#C49438"),
Color.FromHex("#C49438"),
Color.FromHex("#B3BF28"),
Color.FromHex("#B3BF28"),
Color.FromHex("#B3BF28"),
Color.FromHex("#6FC938"),
Color.FromHex("#C49438"),
Color.FromHex("#BB3232"),
];
//Colors for the RPM meter. (unlit)
private static readonly Color[] _speedColorsDim =
[
DimGaugeColor(_speedColors[0]),
DimGaugeColor(_speedColors[1]),
DimGaugeColor(_speedColors[2]),
DimGaugeColor(_speedColors[3]),
DimGaugeColor(_speedColors[4]),
DimGaugeColor(_speedColors[5]),
DimGaugeColor(_speedColors[6]),
DimGaugeColor(_speedColors[7]),
DimGaugeColor(_speedColors[8]),
DimGaugeColor(_speedColors[9]),
DimGaugeColor(_speedColors[10]),
DimGaugeColor(_speedColors[11]),
];
// Style boxes for the RPM meter.
private StyleBoxFlat[] _speedMeter;
private int _speedLevel;
private float _flowRate = 0;
private float _statorLevel = 0;
private EntityUid _turbine;
private bool _isMonitor = false;
private EntityUid _monitor;
private bool _suppressSliderEvents;
private bool _suppressStatorUpdate;
private bool _suppressFlowUpdate;
private readonly float _repeatDelay = 0.5f;
private readonly Dictionary<Button, float> _repeatQueue = [];
#endregion
#region Events
public event Action<float>? TurbineFlowRateChanged;
public event Action<float>? TurbineStatorLoadChanged;
#endregion
public TurbineWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_lock = _entityManager.System<LockSystem>();
InitRPMMeter();
// Handle flow rate
TurbineFlowRateLabel.OnFocusEnter += _ => _suppressFlowUpdate = true;
TurbineFlowRateLabel.OnFocusExit += _ => FlowTextChanged();
TurbineFlowRateLabel.OnTextEntered += _ => FlowTextChanged(true);
TurbineFlowRateSlider.OnValueChanged += _ =>
{
if (!_suppressSliderEvents)
TurbineFlowRateChanged?.Invoke(TurbineFlowRateSlider.Value);
};
FlowRateDecrease.OnPressed += _ => TurbineFlowRateChanged?.Invoke(_flowRate - 100);
FlowRateDecrease.OnButtonDown += _ => _repeatQueue.Add(FlowRateDecrease, _repeatDelay);
FlowRateDecrease.OnButtonUp += _ => _repeatQueue.Remove(FlowRateDecrease);
FlowRateIncrease.OnPressed += _ => TurbineFlowRateChanged?.Invoke(_flowRate + 100);
FlowRateIncrease.OnButtonDown += _ => _repeatQueue.Add(FlowRateIncrease, _repeatDelay);
FlowRateIncrease.OnButtonUp += _ => _repeatQueue.Remove(FlowRateIncrease);
// Handle stator load
TurbineStatorLoadLabel.OnFocusEnter += _ => _suppressStatorUpdate = true;
TurbineStatorLoadLabel.OnFocusExit += _ => StatorTextChanged();
TurbineStatorLoadLabel.OnTextEntered += _ => StatorTextChanged(true);
StatorLoadDecreaseLarge.OnPressed += _ => TurbineStatorLoadChanged?.Invoke(_statorLevel - 1000);
StatorLoadDecreaseLarge.OnButtonDown += _ => _repeatQueue.Add(StatorLoadDecreaseLarge, _repeatDelay);
StatorLoadDecreaseLarge.OnButtonUp += _ => _repeatQueue.Remove(StatorLoadDecreaseLarge);
StatorLoadDecrease.OnPressed += _ => TurbineStatorLoadChanged?.Invoke(_statorLevel - 100);
StatorLoadDecrease.OnButtonDown += _ => _repeatQueue.Add(StatorLoadDecrease, _repeatDelay);
StatorLoadDecrease.OnButtonUp += _ => _repeatQueue.Remove(StatorLoadDecrease);
StatorLoadIncrease.OnPressed += _ => TurbineStatorLoadChanged?.Invoke(_statorLevel + 100);
StatorLoadIncrease.OnButtonDown += _ => _repeatQueue.Add(StatorLoadIncrease, _repeatDelay);
StatorLoadIncrease.OnButtonUp += _ => _repeatQueue.Remove(StatorLoadIncrease);
StatorLoadIncreaseLarge.OnPressed += _ => TurbineStatorLoadChanged?.Invoke(_statorLevel + 1000);
StatorLoadIncreaseLarge.OnButtonDown += _ => _repeatQueue.Add(StatorLoadIncreaseLarge, _repeatDelay);
StatorLoadIncreaseLarge.OnButtonUp += _ => _repeatQueue.Remove(StatorLoadIncreaseLarge);
CTabContainer.SetTabTitle(0, Loc.GetString("comp-turbine-ui-tab-main"));
CTabContainer.SetTabTitle(1, Loc.GetString("comp-turbine-ui-tab-parts"));
return;
void FlowTextChanged(bool suppress = false)
{
if (float.TryParse(TurbineFlowRateLabel.Text, out var num) && !float.IsNaN(num))
TurbineFlowRateChanged?.Invoke(num);
_suppressFlowUpdate = suppress;
}
void StatorTextChanged(bool suppress = false)
{
if (float.TryParse(TurbineStatorLoadLabel.Text, out var num) && !float.IsNaN(num))
TurbineStatorLoadChanged?.Invoke(num);
_suppressStatorUpdate = suppress;
}
}
#region Graphics
public void SetEntity(EntityUid turbine, EntityUid? monitor = null)
{
_turbine = turbine;
if (monitor != null)
{
_monitor = monitor.Value;
_isMonitor = true;
}
this.SetInfoFromEntity(_entityManager, _isMonitor ? _monitor : _turbine);
EntityView.SetEntity(turbine);
}
[MemberNotNull(nameof(_speedMeter))]
public void InitRPMMeter()
{
_speedMeter = new StyleBoxFlat[_speedColors.Length];
for (var i = _speedColors.Length - 1; i >= 0; i--)
{
var styleBox = new StyleBoxFlat();
_speedMeter[i] = styleBox;
for (var j = 0; j < RPMMeter.Columns; j++)
{
var control = new PanelContainer
{
Margin = new Thickness(2),
PanelOverride = styleBox,
HorizontalExpand = true,
VerticalExpand = true,
};
RPMMeter.AddChild(control);
}
}
}
private static Color DimGaugeColor(Color color)
{
var hsv = Color.ToHsv(color);
hsv.Z /= 5;
return Color.FromHsv(hsv);
}
public void Update(TurbineBuiState msg)
{
UpdateIndicators(msg);
if(!_suppressFlowUpdate)
TurbineFlowRateLabel.Text = Math.Round(msg.FlowRate).ToString();
if(!_suppressStatorUpdate)
TurbineStatorLoadLabel.Text = Math.Round(msg.StatorLoad).ToString();
var locktarget = _isMonitor ? _monitor : _turbine;
Inputs.Visible = !_lock.IsLocked(locktarget);
LockedMessage.Visible = _lock.IsLocked(locktarget);
_suppressSliderEvents = true;
TurbineFlowRateSlider.MaxValue = msg.FlowRateMax;
TurbineFlowRateSlider.MinValue = msg.FlowRateMin;
TurbineFlowRateSlider.Value = msg.FlowRate;
_flowRate = msg.FlowRate;
_statorLevel = msg.StatorLoad;
_suppressSliderEvents = false;
_speedLevel = ContentHelpers.RoundToNearestLevels(msg.RPM, msg.BestRPM * 1.2, _speedMeter.Length);
var bladeExists = msg.Blade != null;
if(bladeExists)
{
BladeEntityView.SetEntity(msg.Blade!.Value);
BladeInfoName.Text = Identity.Name(_entityManager.GetEntity(msg.Blade!.Value), _entityManager);
}
BladeInfo.Visible = bladeExists;
BladeInfoIntegrity.Text = Math.Round(msg.Health * 100 / msg.HealthMax).ToString() + "%";
BladeInfoStress.Text = Math.Round(msg.RPM * 100 / (msg.BestRPM * 1.2)).ToString() + "%";
var statorExists = msg.Stator != null;
if (statorExists)
{
StatorEntityView.SetEntity(msg.Stator!.Value);
StatorInfoName.Text = Identity.Name(_entityManager.GetEntity(msg.Stator!.Value), _entityManager);
}
StatorInfo.Visible = statorExists;
StatorInfoPotential.Text = Loc.GetString("comp-turbine-ui-power", ("power", msg.PowerGeneration));
StatorInfoSupply.Text = Loc.GetString("comp-turbine-ui-power", ("power", msg.PowerSupply));
}
private void UpdateIndicators(TurbineBuiState msg)
{
var FilePath = "/Textures/_FarHorizons/Structures/Power/Generation/FissionGenerator/indicator_lamps/";
// These are just if/else statements in black magic form
TurbineOverspeed.TexturePath = msg.Overspeed ? FilePath + "redlit.png" : FilePath + "reddim.png";
TurbineOvertemp.TexturePath = msg.Overtemp ? FilePath + "redlit.png" : FilePath + "reddim.png";
TurbineStalling.TexturePath = msg.Stalling ? FilePath + "amberlit.png" : FilePath + "amberdim.png";
TurbineUndertemp.TexturePath = msg.Undertemp ? FilePath + "bluelit.png" : FilePath + "bluedim.png";
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
for (var i = 0; i < _speedMeter.Length; i++)
{
var box = _speedMeter[i];
box.BackgroundColor = _speedLevel > i ? _speedColors[i] : _speedColorsDim[i];
}
foreach (var kvp in _repeatQueue)
{
if(kvp.Value > 0)
{
_repeatQueue[kvp.Key] -= args.DeltaSeconds;
continue;
}
switch (kvp.Key)
{
case var _ when kvp.Key == FlowRateDecrease:
TurbineFlowRateChanged?.Invoke(_flowRate - 100);
break;
case var _ when kvp.Key == FlowRateIncrease:
TurbineFlowRateChanged?.Invoke(_flowRate + 100);
break;
case var _ when kvp.Key == StatorLoadDecreaseLarge:
TurbineStatorLoadChanged?.Invoke(_statorLevel - 1000);
break;
case var _ when kvp.Key == StatorLoadDecrease:
TurbineStatorLoadChanged?.Invoke(_statorLevel - 100);
break;
case var _ when kvp.Key == StatorLoadIncrease:
TurbineStatorLoadChanged?.Invoke(_statorLevel + 100);
break;
case var _ when kvp.Key == StatorLoadIncreaseLarge:
TurbineStatorLoadChanged?.Invoke(_statorLevel + 1000);
break;
}
}
}
#endregion
}