Skip to content

Commit

Permalink
Merge pull request Simple-Station#169 from XavierSomething/HealthAnal…
Browse files Browse the repository at this point in the history
…yzerUIWizden

Updated Health Analyzer UI From Latest Wizden Update
  • Loading branch information
FoxxoTrystan authored Sep 3, 2024
2 parents 1009ac7 + 5bb2164 commit 9977ede
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 116 deletions.
68 changes: 42 additions & 26 deletions Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,48 +1,64 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
SetSize="250 100">
MaxHeight="525"
MinWidth="300">
<ScrollContainer
Margin="5 5 5 5"
ReturnMeasure="True"
VerticalExpand="True">
<BoxContainer
Name="RootContainer"
VerticalExpand="True"
Orientation="Vertical">
<Label
Name="NoPatientDataText"
Text="{Loc health-analyzer-window-no-patient-data-text}" />

<BoxContainer
Name="PatientDataContainer"
Orientation="Vertical"
Margin="0 0 5 10">
<BoxContainer Name="ScanModePanel" HorizontalExpand="True" Visible="False" Margin="0 5 0 0">
<Label
Name="ScanMode"
Align="Left"
Text="{Loc health-analyzer-window-scan-mode-text}"/>
<Label
Name="ScanModeText"
Align="Right"
HorizontalExpand="True"/>
Margin="0 0 0 5"
Orientation="Vertical">
<BoxContainer Orientation="Horizontal" Margin="0 0 0 5">
<SpriteView OverrideDirection="South" Scale="2 2" Name="SpriteView" Access="Public" SetSize="64 64" />
<BoxContainer Margin="5 0 0 0" Orientation="Vertical" VerticalAlignment="Top">
<RichTextLabel Name="NameLabel" SetWidth="150" />
<Label Name="SpeciesLabel" VerticalAlignment="Top" StyleClasses="LabelSubText" />
</BoxContainer>
<Label Margin="0 0 5 0" HorizontalExpand="True" HorizontalAlignment="Right" VerticalExpand="True"
VerticalAlignment="Top" Name="ScanModeLabel"
Text="{Loc 'health-analyzer-window-entity-unknown-text'}" />
</BoxContainer>
<Label
Name="PatientName"/>
<Label
Name="Temperature"
Margin="0 5 0 0"/>
<Label
Name="BloodLevel"
Margin="0 5 0 0"/>
<Label
Name="Bleeding"
Margin="0 5 0 0"/>
<Label
Name="patientDamageAmount"
Margin="0 15 0 0"/>

<PanelContainer StyleClasses="LowDivider" />

<GridContainer Margin="0 5 0 0" Columns="2">
<Label Text="{Loc 'health-analyzer-window-entity-status-text'}" />
<Label Name="StatusLabel" />
<Label Text="{Loc 'health-analyzer-window-entity-temperature-text'}" />
<Label Name="TemperatureLabel" />
<Label Text="{Loc 'health-analyzer-window-entity-blood-level-text'}" />
<Label Name="BloodLabel" />
<Label Text="{Loc 'health-analyzer-window-entity-damage-total-text'}" />
<Label Name="DamageLabel" />
</GridContainer>
</BoxContainer>

<PanelContainer Name="AlertsDivider" Visible="False" StyleClasses="LowDivider" />

<BoxContainer Name="AlertsContainer" Visible="False" Margin="0 5" Orientation="Horizontal"
HorizontalExpand="True" HorizontalAlignment="Center">

</BoxContainer>

<PanelContainer StyleClasses="LowDivider" />

<BoxContainer
Name="GroupsContainer"
Margin="0 5 0 5"
Orientation="Vertical">
</BoxContainer>

</BoxContainer>
</ScrollContainer>
</controls:FancyWindow>
168 changes: 88 additions & 80 deletions Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
using System.Linq;
using System.Numerics;
using Content.Client.Message;
using Content.Shared.Atmos;
using Content.Client.UserInterface.Controls;
using Content.Shared.Alert;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
using Content.Shared.MedicalScanner;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Nutrition.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
Expand All @@ -28,9 +36,6 @@ public sealed partial class HealthAnalyzerWindow : FancyWindow
private readonly IPrototypeManager _prototypes;
private readonly IResourceCache _cache;

private const int AnalyzerHeight = 430;
private const int AnalyzerWidth = 300;

public HealthAnalyzerWindow()
{
RobustXamlLoader.Load(this);
Expand All @@ -44,8 +49,6 @@ public HealthAnalyzerWindow()

public void Populate(HealthAnalyzerScannedUserMessage msg)
{
GroupsContainer.RemoveAllChildren();

var target = _entityManager.GetEntity(msg.TargetEntity);

if (target == null
Expand All @@ -57,82 +60,96 @@ public void Populate(HealthAnalyzerScannedUserMessage msg)

NoPatientDataText.Visible = false;

string entityName = Loc.GetString("health-analyzer-window-entity-unknown-text");
if (_entityManager.HasComponent<MetaDataComponent>(target.Value))
{
entityName = Identity.Name(target.Value, _entityManager);
}
// Scan Mode

if (msg.ScanMode.HasValue)
{
ScanModePanel.Visible = true;
ScanModeText.Text = Loc.GetString(msg.ScanMode.Value ? "health-analyzer-window-scan-mode-active" : "health-analyzer-window-scan-mode-inactive");
ScanModeText.FontColorOverride = msg.ScanMode.Value ? Color.Green : Color.Red;
}
else
{
ScanModePanel.Visible = false;
}
ScanModeLabel.Text = msg.ScanMode.HasValue
? msg.ScanMode.Value
? Loc.GetString("health-analyzer-window-scan-mode-active")
: Loc.GetString("health-analyzer-window-scan-mode-inactive")
: Loc.GetString("health-analyzer-window-entity-unknown-text");

ScanModeLabel.FontColorOverride = msg.ScanMode.HasValue && msg.ScanMode.Value ? Color.Green : Color.Red;

// Patient Information

SpriteView.SetEntity(target.Value);

var name = new FormattedMessage();
name.PushColor(Color.White);
name.AddText(_entityManager.HasComponent<MetaDataComponent>(target.Value)
? Identity.Name(target.Value, _entityManager)
: Loc.GetString("health-analyzer-window-entity-unknown-text"));
NameLabel.SetMessage(name);

SpeciesLabel.Text =
_entityManager.TryGetComponent<HumanoidAppearanceComponent>(target.Value,
out var humanoidAppearanceComponent)
? Loc.GetString(_prototypes.Index<SpeciesPrototype>(humanoidAppearanceComponent.Species).Name)
: Loc.GetString("health-analyzer-window-entity-unknown-species-text");

// Basic Diagnostic

TemperatureLabel.Text = !float.IsNaN(msg.Temperature)
? $"{msg.Temperature - Atmospherics.T0C:F1} °C ({msg.Temperature:F1} K)"
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");

BloodLabel.Text = !float.IsNaN(msg.BloodLevel)
? $"{msg.BloodLevel * 100:F1} %"
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");

PatientName.Text = Loc.GetString(
"health-analyzer-window-entity-health-text",
("entityName", entityName)
);
StatusLabel.Text =
_entityManager.TryGetComponent<MobStateComponent>(target.Value, out var mobStateComponent)
? GetStatus(mobStateComponent.CurrentState)
: Loc.GetString("health-analyzer-window-entity-unknown-text");

Temperature.Text = Loc.GetString("health-analyzer-window-entity-temperature-text",
("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - Atmospherics.T0C:F1} °C ({msg.Temperature:F1} K)")
);
// Total Damage

BloodLevel.Text = Loc.GetString("health-analyzer-window-entity-blood-level-text",
("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %")
);
DamageLabel.Text = damageable.TotalDamage.ToString();

// Alerts

AlertsDivider.Visible = msg.Bleeding == true;
AlertsContainer.Visible = msg.Bleeding == true;

if (msg.Bleeding == true)
{
Bleeding.Text = Loc.GetString("health-analyzer-window-entity-bleeding-text");
Bleeding.FontColorOverride = Color.Red;
}
else
{
Bleeding.Text = string.Empty; // Clear the text
AlertsContainer.DisposeAllChildren();
AlertsContainer.AddChild(new Label
{
Text = Loc.GetString("health-analyzer-window-entity-bleeding-text"),
FontColorOverride = Color.Red,
});
}

patientDamageAmount.Text = Loc.GetString(
"health-analyzer-window-entity-damage-total-text",
("amount", damageable.TotalDamage)
);
// Damage Groups

var damageSortedGroups =
damageable.DamagePerGroup.OrderBy(damage => damage.Value)
damageable.DamagePerGroup.OrderByDescending(damage => damage.Value)
.ToDictionary(x => x.Key, x => x.Value);

IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;

DrawDiagnosticGroups(damageSortedGroups, damagePerType);
}

if (_entityManager.TryGetComponent(target, out HungerComponent? hunger)
&& hunger.StarvationDamage != null
&& hunger.CurrentThreshold <= HungerThreshold.Starving)
private static string GetStatus(MobState mobState)
{
return mobState switch
{
var box = new Control { Margin = new Thickness(0, 0, 0, 15) };

box.AddChild(CreateDiagnosticGroupTitle(
Loc.GetString("health-analyzer-window-malnutrition"),
"malnutrition"));

GroupsContainer.AddChild(box);
}

SetHeight = AnalyzerHeight;
SetWidth = AnalyzerWidth;
MobState.Alive => Loc.GetString("health-analyzer-window-entity-alive-text"),
MobState.Critical => Loc.GetString("health-analyzer-window-entity-critical-text"),
MobState.Dead => Loc.GetString("health-analyzer-window-entity-dead-text"),
_ => Loc.GetString("health-analyzer-window-entity-unknown-text"),
};
}

private void DrawDiagnosticGroups(
Dictionary<string, FixedPoint2> groups, IReadOnlyDictionary<string, FixedPoint2> damageDict)
Dictionary<string, FixedPoint2> groups,
IReadOnlyDictionary<string, FixedPoint2> damageDict)
{
HashSet<string> shownTypes = new();
GroupsContainer.RemoveAllChildren();

// Show the total damage and type breakdown for each damage group.
foreach (var (damageGroupId, damageAmount) in groups.Reverse())
foreach (var (damageGroupId, damageAmount) in groups)
{
if (damageAmount == 0)
continue;
Expand All @@ -145,7 +162,6 @@ private void DrawDiagnosticGroups(

var groupContainer = new BoxContainer
{
Margin = new Thickness(0, 0, 0, 15),
Align = BoxContainer.AlignMode.Begin,
Orientation = BoxContainer.LayoutOrientation.Vertical,
};
Expand All @@ -159,23 +175,16 @@ private void DrawDiagnosticGroups(

foreach (var type in group.DamageTypes)
{
if (damageDict.TryGetValue(type, out var typeAmount) && typeAmount > 0)
{
// If damage types are allowed to belong to more than one damage group,
// they may appear twice here. Mark them as duplicate.
if (shownTypes.Contains(type))
continue;

shownTypes.Add(type);

var damageString = Loc.GetString(
"health-analyzer-window-damage-type-text",
("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)),
("amount", typeAmount)
);

groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, "- ")));
}
if (!damageDict.TryGetValue(type, out var typeAmount) || typeAmount <= 0)
continue;

var damageString = Loc.GetString(
"health-analyzer-window-damage-type-text",
("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)),
("amount", typeAmount)
);

groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, " · ")));
}
}
}
Expand All @@ -198,7 +207,6 @@ private static Label CreateDiagnosticItemLabel(string text)
{
return new Label
{
Margin = new Thickness(2, 2),
Text = text,
};
}
Expand All @@ -207,13 +215,13 @@ private BoxContainer CreateDiagnosticGroupTitle(string text, string id)
{
var rootContainer = new BoxContainer
{
Margin = new Thickness(0, 6, 0, 0),
VerticalAlignment = VAlignment.Bottom,
Orientation = BoxContainer.LayoutOrientation.Horizontal
Orientation = BoxContainer.LayoutOrientation.Horizontal,
};

rootContainer.AddChild(new TextureRect
{
Margin = new Thickness(0, 3),
SetSize = new Vector2(30, 30),
Texture = GetTexture(id.ToLower())
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
health-analyzer-window-no-patient-data-text = No patient data.
health-analyzer-window-entity-unknown-text = unknown
health-analyzer-window-entity-health-text = {$entityName}'s health:
health-analyzer-window-entity-temperature-text = Temperature: {$temperature}
health-analyzer-window-entity-blood-level-text = Blood Level: {$bloodLevel}
health-analyzer-window-entity-bleeding-text = Patient is bleeding!
health-analyzer-window-entity-damage-total-text = Total Damage: {$amount}
health-analyzer-window-entity-unknown-text = Unknown
health-analyzer-window-entity-unknown-species-text = Non-Humanoid
health-analyzer-window-entity-unknown-value-text = N/A
health-analyzer-window-entity-alive-text = Alive
health-analyzer-window-entity-dead-text = Dead
health-analyzer-window-entity-critical-text = Critical
health-analyzer-window-entity-temperature-text = Temperature:
health-analyzer-window-entity-blood-level-text = Blood Level:
health-analyzer-window-entity-status-text = Status:
health-analyzer-window-entity-damage-total-text = Total Damage:
health-analyzer-window-damage-group-text = {$damageGroup}: {$amount}
health-analyzer-window-damage-type-text = {$damageType}: {$amount}
health-analyzer-window-damage-type-duplicate-text = {$damageType}: {$amount} (duplicate)
health-analyzer-window-scan-mode-text = Scan Mode:
health-analyzer-window-scan-mode-active = ACTIVE
health-analyzer-window-scan-mode-inactive = INACTIVE
health-analyzer-window-damage-group-Brute = Brute
health-analyzer-window-damage-type-Blunt = Blunt
health-analyzer-window-damage-type-Slash = Slash
Expand All @@ -36,3 +39,11 @@ health-analyzer-window-damage-group-Genetic = Genetic
health-analyzer-window-damage-type-Cellular = Cellular
health-analyzer-window-malnutrition = Severely malnourished
health-analyzer-window-entity-bleeding-text = Patient is bleeding!
health-analyzer-window-scan-mode-text = Scan Mode:
health-analyzer-window-scan-mode-active = Active
health-analyzer-window-scan-mode-inactive = Inactive
health-analyzer-popup-scan-target = {CAPITALIZE(THE($user))} is trying to scan you!

0 comments on commit 9977ede

Please sign in to comment.