173 lines
8.9 KiB
C#
173 lines
8.9 KiB
C#
using Content.Client.UserInterface.Controls;
|
|
using Content.Shared.Chemistry.Reagent;
|
|
using Content.Shared.FixedPoint;
|
|
using Content.Shared._White.Medical.BodyScanner;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Client._White.Medical.BodyScanner
|
|
{
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class BodyScannerConsoleWindow : FancyWindow
|
|
{
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
|
|
public event Action? OnScanButtonPressed;
|
|
public event Action? OnPrintButtonPressed;
|
|
|
|
public BodyScannerConsoleWindow()
|
|
{
|
|
IoCManager.InjectDependencies(this);
|
|
RobustXamlLoader.Load(this);
|
|
|
|
ScanButton.OnPressed += _ => OnScanButtonPressed?.Invoke();
|
|
NoDataScanButton.OnPressed += _ => OnScanButtonPressed?.Invoke();
|
|
PrintButton.OnPressed += _ => OnPrintButtonPressed?.Invoke();
|
|
}
|
|
|
|
public void UpdateUserInterface(BodyScannerConsoleBoundUserInterfaceState state)
|
|
{
|
|
MainContainer.Visible = state.TargetEntityUid != null && !state.Scanning;
|
|
NoDataContainer.Visible = !MainContainer.Visible;
|
|
NoDataStatusLabel.Text = state.Scanning ? Loc.GetString("body-scanner-console-window-status-scanning") : " ";
|
|
|
|
ScanButton.Disabled = !state.CanScan;
|
|
PrintButton.Disabled = !state.CanPrint;
|
|
NoDataScanButton.Disabled = !state.CanScan;
|
|
|
|
NoDataScanProgressBar.Value = 1 - (float) (state.ScanTimeRemaining / state.ScanTotalTime);
|
|
|
|
if (state.Scanning)
|
|
return;
|
|
|
|
EntityNameLabel.Text = state.EntityName;
|
|
|
|
// First column
|
|
TemperatureLabel.Text = $"{state.CurrentTemperature - 273f:F1} \u00B0C";
|
|
BloodLevelLabel.Text = $"{state.BloodSolution.FillFraction * 100:F1} %";
|
|
TotalDamageLabel.Text = state.TotalDamage.ToString();
|
|
|
|
AliveStatusLabel.Text = state.CurrentState switch
|
|
{
|
|
Shared.Mobs.MobState.Alive => Loc.GetString("body-scanner-console-window-current-alive-status-alive-text"),
|
|
Shared.Mobs.MobState.Critical => Loc.GetString("body-scanner-console-window-current-alive-status-critical-text"),
|
|
Shared.Mobs.MobState.Dead => Loc.GetString("body-scanner-console-window-current-alive-status-dead-text"),
|
|
_ => Loc.GetString("body-scanner-console-window-no-data")
|
|
};
|
|
|
|
HashSet<string> shownTypes = new();
|
|
|
|
var protos = IoCManager.Resolve<IPrototypeManager>();
|
|
|
|
IReadOnlyDictionary<string, FixedPoint2> damagePerGroup = state.DamagePerGroup;
|
|
IReadOnlyDictionary<string, FixedPoint2> damagePerType = state.DamageDict;
|
|
|
|
DamageGroupsContainer.RemoveAllChildren();
|
|
|
|
// Show the total damage and type breakdown for each damage group.
|
|
foreach (var (damageGroupId, damageAmount) in damagePerGroup)
|
|
{
|
|
var damageGroupTitle = Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId, ("amount", damageAmount));
|
|
|
|
DamageGroupsContainer.AddChild(new GroupDamageCardComponent(damageGroupTitle, damageGroupId, damagePerType));
|
|
}
|
|
|
|
// Second column.
|
|
CurrentTemperature.Text = Loc.GetString("body-scanner-console-window-temperature-current-temperature-text",
|
|
("amount", $"{state.CurrentTemperature - 273:f1}"));
|
|
HeatDamageThreshold.Text = Loc.GetString("body-scanner-console-window-temperature-heat-damage-threshold-temperature-text",
|
|
("amount", $"{state.HeatDamageThreshold - 273:f1}"));
|
|
ColdDamageThreshold.Text = Loc.GetString("body-scanner-console-window-temperature-cold-damage-threshold-temperature-text",
|
|
("amount", $"{state.ColdDamageThreshold - 273:f1}"));
|
|
|
|
CurrentSaturation.Text = Loc.GetString("body-scanner-console-window-saturation-current-saturation-text",
|
|
("amount", $"{state.Saturation:f1}"));
|
|
MinimumSaturation.Text = Loc.GetString("body-scanner-console-window-saturation-maximum-saturation-text",
|
|
("amount", $"{state.MinSaturation:f1}"));
|
|
MaximumSaturation.Text = Loc.GetString("body-scanner-console-window-saturation-minimum-saturation-text",
|
|
("amount", $"{state.MaxSaturation:f1}"));
|
|
|
|
CurrentThirst.Text = Loc.GetString("body-scanner-console-window-thirst-current-thirst-text",
|
|
("amount", $"{state.CurrentThirst:f1}"));
|
|
CurrentThirstStatus.Text = Loc.GetString("body-scanner-console-window-thirst-current-thirst-status-text",
|
|
("status", Loc.GetString("body-scanner-console-window-thirst-current-thirst-status-" + state.CurrentThirstThreshold)));
|
|
|
|
CurrentHunger.Text = Loc.GetString("body-scanner-console-window-hunger-current-hunger-text",
|
|
("amount", $"{state.CurrentHunger:f1}"));
|
|
CurrentHungerStatus.Text = Loc.GetString("body-scanner-console-window-hunger-current-hunger-status-text",
|
|
("status", Loc.GetString("body-scanner-console-window-hunger-current-hunger-status-" + state.CurrentHungerThreshold)));
|
|
|
|
BloodSolutionVolume.Text = Loc.GetString("body-scanner-console-window-blood-solutions-volume-group-text",
|
|
("amount", $"{state.BloodSolution.Volume.Float():f1}"),
|
|
("maxAmount", $"{state.BloodSolution.MaxVolume.Float():f1}"),
|
|
("temperature", $"{state.BloodSolution.Temperature - 271:f1}"));
|
|
|
|
BloodSolutionElements.RemoveAllChildren();
|
|
state.BloodSolution.Contents.ForEach(x =>
|
|
{
|
|
_prototypeManager.TryIndex(x.Reagent.Prototype, out ReagentPrototype? proto);
|
|
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
|
|
BloodSolutionElements.AddChild(new Label() { Text = $"{name}: {x.Quantity}", FontColorOverride = Color.LightGray });
|
|
});
|
|
|
|
ChemicalSolutionVolume.Text = Loc.GetString("body-scanner-console-window-chemical-solutions-volume-group-text",
|
|
("amount", $"{state.ChemicalSolution.Volume.Float():f1}"),
|
|
("maxAmount", $"{state.ChemicalSolution.MaxVolume.Float():f1}"),
|
|
("temperature", $"{state.ChemicalSolution.Temperature - 271:f1}"));
|
|
|
|
ChemicalSolutionElements.RemoveAllChildren();
|
|
state.ChemicalSolution.Contents.ForEach(x =>
|
|
{
|
|
_prototypeManager.TryIndex(x.Reagent.Prototype, out ReagentPrototype? proto);
|
|
var name = proto?.LocalizedName ?? Loc.GetString("chem-master-window-unknown-reagent-text");
|
|
ChemicalSolutionElements.AddChild(new Label() { Text = $"{name}: {x.Quantity}", FontColorOverride = Color.LightGray });
|
|
});
|
|
|
|
// Third column.
|
|
if (state.DeadThreshold == FixedPoint2.Zero)
|
|
state.DeadThreshold = 0.01;
|
|
|
|
HealthBar.Value = 1 - (state.TotalDamage / state.DeadThreshold).Float();
|
|
|
|
HealthBar.ForegroundStyleBoxOverride = new StyleBoxFlat()
|
|
{
|
|
BackgroundColor = HealthBar.Value >= 0.5f ?
|
|
GetColorLerp(Color.Yellow, Color.Green, (HealthBar.Value - 0.5f) * 2) :
|
|
GetColorLerp(Color.Red, Color.Yellow, HealthBar.Value * 2)
|
|
};
|
|
|
|
if (state.TargetEntityUid != null)
|
|
EntityView.SetEntity(state.TargetEntityUid.Value);
|
|
|
|
// Bottom row.
|
|
Mind.Text = Loc.GetString("body-scanner-console-window-mind-text",
|
|
("value", state.HasMind ? Loc.GetString("body-scanner-console-window-mind-present-text") :
|
|
Loc.GetString("body-scanner-console-window-mind-absent-text")));
|
|
DNA.Text = Loc.GetString("body-scanner-console-window-dna-text",
|
|
("value", $"{state.DNA}"));
|
|
Fingerprint.Text = Loc.GetString("body-scanner-console-window-fingerprint-text",
|
|
("value", $"{state.Fingerprint}"));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Smooth transition from one color to another depending on the percentage.
|
|
/// </summary>
|
|
/// <param name="startColor"></param>
|
|
/// <param name="endColor"></param>
|
|
/// <param name="percentage"></param>
|
|
/// <returns></returns>
|
|
private Color GetColorLerp(Color startColor, Color endColor, float percentage)
|
|
{
|
|
var r = MathHelper.Lerp(startColor.R, endColor.R, percentage);
|
|
var g = MathHelper.Lerp(startColor.G, endColor.G, percentage);
|
|
var b = MathHelper.Lerp(startColor.B, endColor.B, percentage);
|
|
var a = MathHelper.Lerp(startColor.A, endColor.A, percentage);
|
|
|
|
return new Color(r, g, b, a);
|
|
}
|
|
}
|
|
}
|