diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml
index 25385c41ff6..bcb75e159b1 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml
@@ -59,9 +59,12 @@
-
-
-
+
+
+
+
+
+
@@ -73,10 +76,41 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs
index 8f667e0ec34..01bc36e382b 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerControl.xaml.cs
@@ -19,12 +19,25 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
+
+// BEGIN DeltaV
+using Content.Client._DV.Traits.Assorted;
+using Content.Shared._DV.Traits.Assorted;
+using Content.Shared._DV.Medical; // Uncloneable
+using Content.Shared._DV.MedicalRecords; // Medical Records
+
+// Health Analyzer Plus
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.Body.Systems;
+using Content.Client.Body.Systems;
+using Content.Shared.Chemistry.EntitySystems;
+using Content.Client.Chemistry.Containers.EntitySystems;
+using Content.Shared.Body.Components;
+// END DeltaV
namespace Content.Client.HealthAnalyzer.UI;
-using Content.Client._DV.Traits.Assorted; // DeltaV
-using Content.Shared._DV.Traits.Assorted; // DeltaV
-using Content.Shared._DV.Medical; // DeltaV - Uncloneable
-using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
+
// Health analyzer UI is split from its window because it's used by both the
// health analyzer item and the cryo pod UI.
@@ -32,6 +45,8 @@ using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
[GenerateTypedNameReferences]
public sealed partial class HealthAnalyzerControl : BoxContainer
{
+ private const string REAGENT_GROUP_MEDICINE = "Medicine"; // DeltaV - Health Analyzer
+
private readonly IEntityManager _entityManager;
private readonly SpriteSystem _spriteSystem;
private readonly IPrototypeManager _prototypes;
@@ -41,6 +56,8 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
private readonly UnborgableSystem _unborgable; // DeltaV
private readonly RedshirtSystem _redshirt; // DeltaV
private readonly UncloneableSystem _uncloneable; // DeltaV
+ private readonly SharedBloodstreamSystem _bloodstream; // DeltaV
+ private readonly SharedSolutionContainerSystem _solutionContainer; // DeltaV
// Begin DeltaV - Medical Records
private readonly ButtonGroup _triageStatusGroup = new();
@@ -66,6 +83,8 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
_unborgable = _entityManager.System(); // DeltaV
_redshirt = _entityManager.System(); // DeltaV
_uncloneable = _entityManager.System(); // DeltaV
+ _bloodstream = _entityManager.System(); // DeltaV
+ _solutionContainer = _entityManager.System(); // DeltaV
// Begin DeltaV - Medical Records
foreach (var item in Enum.GetValues())
@@ -138,9 +157,13 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
? $"{state.Temperature - Atmospherics.T0C:F1} °C ({state.Temperature:F1} K)"
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
+ // Begin DeltaV - Health Analyzer Plus
+ /*
BloodLabel.Text = !float.IsNaN(state.BloodLevel)
? $"{state.BloodLevel * 100:F1} %"
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
+ */
+ // End DeltaV - Health Analyzer Plus
StatusLabel.Text =
_entityManager.TryGetComponent(target.Value, out var mobStateComponent)
@@ -149,7 +172,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
// Total Damage
- DamageLabel.Text = _damageable.GetTotalDamage(target.Value).ToString();
+ // DamageLabel.Text = _damageable.GetTotalDamage(target.Value).ToString(); // DeltaV - Health Analyzer Plus
// Alerts
// DeltaV traits - This is going to be horrid if we just keep adding things like this.
@@ -216,6 +239,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
var damagePerType = _damageable.GetAllDamage(target.Value).DamageDict;
DrawDiagnosticGroups(damageSortedGroups, damagePerType);
+ DrawBloodstreamInfo(target.Value, state.BloodSolution, state.BloodLevel); // End DeltaV - Health Analyzer Plus
// Begin DeltaV - Medical Records
if (state.MedicalRecord is not { } records)
@@ -254,7 +278,15 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
Dictionary, FixedPoint2> groups,
IReadOnlyDictionary, FixedPoint2> damageDict)
{
- GroupsContainer.RemoveAllChildren();
+ // Begin DeltaV - Health Analyzer Plus
+ // GroupsContainer.RemoveAllChildren();
+ DamageGroupsContainer.RemoveAllChildren();
+
+ // Begin DeltaV - Health Analyzer Plus
+ var totalDamage = damageDict.Sum(x => x.Value.Double());
+ TotalDamageLabel.Text = Loc.GetString("health-analyzer-plus-window-entity-total-damage-text", ("amount", Math.Round(totalDamage, 2)));
+ NoDamageLabel.Visible = totalDamage == 0;
+ // End DeltaV - Health Analyzer Plus
foreach (var (damageGroupId, damageAmount) in groups)
{
@@ -275,7 +307,8 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId));
- GroupsContainer.AddChild(groupContainer);
+ // GroupsContainer.AddChild(groupContainer); // DeltaV - Health Analyzer Plus
+ DamageGroupsContainer.AddChild(groupContainer); // DeltaV - Health Analyzer Plus
// Show the damage for each type in that group.
var group = _prototypes.Index(damageGroupId);
@@ -296,6 +329,116 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
}
}
+ // Begin DeltaV - Health Analyzer Plus
+ private void DrawBloodstreamInfo(EntityUid target, Solution? bloodSolution, float bloodlevel)
+ {
+ BloodstreamReagentListContainer.RemoveAllChildren();
+
+ List bloodstream = new();
+ double totalReagentQuantity = 0;
+ double unknownReagents = 0;
+ // Make sure we can access the bloodtype and reagents before trying to use them
+ if (bloodSolution is not null)
+ {
+ if (!_entityManager.TryGetComponent(target, out var bloodstreamComp) ||
+ !_solutionContainer.ResolveSolution(target, bloodstreamComp.BloodSolutionName, ref bloodstreamComp.BloodSolution, out var bloodReagentSolution))
+ return;
+
+ // Get the blood reagent IDs to ignore in the scan
+ var bloodReagentIds = bloodstreamComp.BloodReferenceSolution.Select(b => b.Reagent);
+
+ // Get all of the medicines in the bloodstream
+ foreach (var reagent in bloodSolution!.Contents)
+ {
+ if (bloodReagentIds.Contains(reagent.Reagent))
+ continue;
+
+ if (_prototypes.Index(reagent.Reagent.Prototype).Group == REAGENT_GROUP_MEDICINE)
+ {
+ bloodstream.Add(reagent);
+ totalReagentQuantity += reagent.Quantity.Double();
+ }
+ else
+ {
+ unknownReagents += reagent.Quantity.Double();
+ }
+ }
+ }
+
+ var bloodQuantityPercent = !float.IsNaN(bloodlevel)
+ ? $"{bloodlevel * 100:F1} %"
+ : Loc.GetString("health-analyzer-window-entity-unknown-value-text");
+
+ // Display the percent and amount of blood in the system
+ // Normal health scanner is percent only, this one adds the actual units too
+ BloodLevelLabel.Text = Loc.GetString(
+ "health-analyzer-plus-window-entity-blood-level-quantity-text",
+ ("percent", bloodQuantityPercent)
+ );
+
+ // Display the total amount of reagents in the bloodstream, 0 is valid
+ TotalReagentQuantityLabel.Text = Loc.GetString(
+ "health-analyzer-plus-window-entity-total-reagents-text",
+ ("amount", Math.Round(totalReagentQuantity, 1).ToString("0.0"))
+ );
+
+ // If the bloodstream was empty, display a message instead to fill the space with something
+ NoReagentsLabel.Visible = bloodstream.Count == 0 && unknownReagents == 0;
+
+ // For each of the reagents in the bloodstream, add them to the list of reagents
+ // If there are none, this loop will simply do nothing
+ foreach (var (reagentID, reagentQuantity) in bloodstream)
+ {
+ var reagentPrototype = _prototypes.Index(reagentID.Prototype);
+
+ // Make a new container for each reagent we add to the list
+ var reagentContainer = new BoxContainer
+ {
+ Align = AlignMode.Begin,
+ Orientation = LayoutOrientation.Vertical
+ };
+
+ // Add the string "[] : u" for the current reagent
+ // The [] is a unicode block character, and is colored with the reagent color
+ // to make it easier to identify
+ reagentContainer.AddChild(
+ new RichTextLabel
+ {
+ Text = Loc.GetString("health-analyzer-plus-window-reagent-text",
+ ("reagentColor", reagentPrototype.SubstanceColor),
+ ("reagentName", reagentPrototype.LocalizedName),
+ ("amount", Math.Round(reagentQuantity.Double(), 1).ToString("0.0"))
+ )
+ }
+ );
+
+ BloodstreamReagentListContainer.AddChild(reagentContainer);
+ }
+
+ // Add unknown reagents (if any)
+ if (unknownReagents > 0)
+ {
+ var unknownReagentContainer = new BoxContainer
+ {
+ Align = AlignMode.Begin,
+ Orientation = LayoutOrientation.Vertical
+ };
+
+ unknownReagentContainer.AddChild(
+ new RichTextLabel
+ {
+ Text = Loc.GetString("health-analyzer-plus-window-unknown-reagents-text",
+ ("amount", Math.Round(unknownReagents, 1).ToString("0.0"))
+ )
+ }
+ );
+ BloodstreamReagentListContainer.AddChild(unknownReagentContainer);
+ }
+
+ return;
+ }
+ // End DeltaV - Health Analyzer Plus
+
private Texture GetTexture(string texture)
{
var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
index 24747e516ca..36f93171319 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
@@ -7,7 +7,9 @@
+ VerticalExpand="True"
+ VScrollBarHidden="True"
+ HScrollBarHidden="True">
(entity, out var bloodstream) &&
_solutionContainerSystem.ResolveSolution(entity, bloodstream.BloodSolutionName,
- ref bloodstream.BloodSolution, out var bloodSolution))
+ ref bloodstream.BloodSolution, out bloodSolution)) // DeltaV - Health Analyzer Plus
{
bloodAmount = _bloodstreamSystem.GetBloodLevel(entity);
bleeding = bloodstream.BleedAmount > 0;
@@ -287,6 +290,7 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made
null,
bleeding,
unrevivable,
+ bloodSolution, // DeltaV - Health Analyzer Plus
_medicalRecords.GetMedicalRecords(entity) // DeltaV - Medical Records
);
}
diff --git a/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs b/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
index 3aa887c93a9..6b1cf0bf2f7 100644
--- a/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
+++ b/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
@@ -1,4 +1,5 @@
using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
+using Content.Shared.Chemistry.Components; // DeltaV - Health Analyzer Plus
using Robust.Shared.Serialization;
namespace Content.Shared.MedicalScanner;
@@ -29,11 +30,12 @@ public struct HealthAnalyzerUiState
public bool? ScanMode;
public bool? Bleeding;
public bool? Unrevivable;
+ public readonly Solution? BloodSolution; // DeltaV - Health Analyzer Plus
public MedicalRecord? MedicalRecord; // DeltaV - Medical Records
public HealthAnalyzerUiState() {}
- public HealthAnalyzerUiState(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, MedicalRecord? medicalRecord = null) // DeltaV - Medical Records
+ public HealthAnalyzerUiState(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, Solution? bloodSolution, MedicalRecord? medicalRecord = null) // DeltaV - Health Analyzer Plus, Medical Records
{
TargetEntity = targetEntity;
Temperature = temperature;
@@ -41,6 +43,7 @@ public struct HealthAnalyzerUiState
ScanMode = scanMode;
Bleeding = bleeding;
Unrevivable = unrevivable;
+ BloodSolution = bloodSolution; // DeltaV - Health Analyzer Plus
MedicalRecord = medicalRecord; // DeltaV - Medical Records
}
}
diff --git a/Resources/Locale/en-US/_DV/medical/components/health-analyzer-plus-component.ftl b/Resources/Locale/en-US/_DV/medical/components/health-analyzer-plus-component.ftl
new file mode 100644
index 00000000000..5c495a21e60
--- /dev/null
+++ b/Resources/Locale/en-US/_DV/medical/components/health-analyzer-plus-component.ftl
@@ -0,0 +1,10 @@
+health-analyzer-plus-window-entity-blood-level-quantity-text = {$percent}
+
+health-analyzer-plus-window-entity-total-damage-text = Total Damage: {$amount}
+health-analyzer-plus-window-entity-total-reagents-text = Bloodstream: {$amount}u
+
+health-analyzer-plus-window-reagent-text = [color={$reagentColor}]█[/color] {$reagentName}: {$amount}u
+health-analyzer-plus-window-unknown-reagents-text = Unknown Reagents: {$amount}u
+
+health-analyzer-plus-window-no-damage-text = No damage detected
+health-analyzer-plus-window-no-reagents-text = No reagents detected