Repository: DeltaV-Station/Delta-v
Pull request #3149: Add triaging to health analyzers and HUD
Author: login: sowelipililimute
Labels: name: Changes: YML
description: Changes any yml files
name: S: Needs Review
description: Awaiting review from a Maintainer
name: Changes: UI
name: Changes: C#
description: Changes any cs files
name: Changes: Localization
description: Changes any ftl files
name: size/L
description: 256-1023 lines
name: Changes: Sprite
description: Changes any png or json in an rsi
Created: 2025-03-08T01:47:59Z | Merged: 2025-03-18T00:24:12Z

<!-- If you are new to the Delta-V repository, please read the [Contributing Guidelines](https://github.com/DeltaV-Station/Delta-v/blob/master/CONTRIBUTING.md) -->

## About the PR
This adds the ability for anyone with a health analyzer to give a patient a triage status (based on the [USA's START](https://chemm.hhs.gov/startadult.htm), commonly used for mass emergency situations) and once a triage status is given, a doctor can mark themselves as the person to work on a patient. All of this is reflected on the medical HUDs.

## Why / Balance
As it is, medical recordkeeping does not exist at all. This remedies that with a system similar to security recordkeeping, albeit based around the health analyzer rather than a medical computer. I am delaying any work on the medical records computer until https://github.com/DeltaV-Station/Delta-v/pull/2236 gets in. 

## Technical details
- new icons for triage severity states, and triage claimage states
- add the `MedicalRecord` and the `MedicalRecordsSystem` for managing the triage status, basing it off of the station records system used for e.g. security stuff
- augment the health analyzer UI to interface with the medical records, using the patient's ID(s) and the doctor's ID(s) to determine which station records keys are relevant for the records
- `ShowTriageIcons` component and corresponding system to render the information as an overlay, with an icon for the triage sevrity and another icon for "unclaimed", "claimed by someone else", and "claimed by you", using your equipped ID card to determine the icon for the latter two

## Media
![image](https://github.com/user-attachments/assets/d38b5260-93df-4de8-9bf0-29755f1f8830)

## Requirements
<!-- Confirm the following by placing an X in the brackets [X]: -->
- [x] I have tested all added content and changes.
- [x] I have added media to this PR or it does not require an ingame showcase.
<!-- You should understand that not following the above may get your PR closed at maintainer’s discretion -->

## Breaking changes
<!-- List any breaking changes, including namespaces, public class/method/field changes, prototype renames; and provide instructions for fixing them. -->

**Changelog**
<!-- Add a Changelog entry to make players aware of new features or changes that could affect gameplay.
Make sure to read the guidelines and take this Changelog template out of the comment block in order for it to show up.
Changelogs must have a :cl: symbol, so the bot recognizes the changes and adds them to the game's changelog. -->
:cl:
- add: Added the ability to triage patients and to indicate that you're working on them with health analyzers/the MedTek PDA, which is reflected on medical HUDs.
<!--
:cl:
- add: Added fun!
- remove: Removed fun!
- tweak: Changed fun!
- fix: Fixed fun!
-->



Diff:
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs
index 3261a109e734..b054b7a14fce 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerBoundUserInterface.cs
@@ -1,5 +1,6 @@
 ﻿using Content.Shared.MedicalScanner;
 using Content.Shared._Shitmed.Targeting; // Shitmed Change
+using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
 using JetBrains.Annotations;
 using Robust.Client.UserInterface;
 
@@ -21,6 +22,8 @@ protected override void Open()
 
             _window = this.CreateWindow<HealthAnalyzerWindow>();
             _window.OnBodyPartSelected += SendBodyPartMessage; // Shitmed Change
+            _window.OnTriageStatusChanged += SendTriageStatusMessage; // DeltaV - Medical Records
+            _window.OnClaimPatient += SendTriageClaimMessage; // DeltaV - Medical Records
             _window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
         }
 
@@ -51,5 +54,13 @@ protected override void Dispose(bool disposing)
         }
 
         // Shitmed Change End
+
+        // Begin DeltaV - Medical Records
+        private void SendTriageStatusMessage(TriageStatus status)
+            => SendMessage(new HealthAnalyzerTriageStatusMessage(status));
+
+        private void SendTriageClaimMessage()
+            => SendMessage(new HealthAnalyzerTriageClaimMessage());
+        // End DeltaV - Medical Records
     }
 }
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
index 7ebd16942d98..25f21ba94ce7 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
@@ -198,6 +198,22 @@
 
                 <PanelContainer StyleClasses="LowDivider"/>
 
+                <!-- Begin DeltaV - Medical Records -->
+                <BoxContainer Name="TriageControls" Orientation="Vertical">
+                    <BoxContainer Name="StatusBox"
+                                  Orientation="Horizontal"
+                                  HorizontalAlignment="Center"
+                                  Margin="0 8 0 0">
+                    </BoxContainer>
+
+                    <Button Name="ClaimButton"
+                            Text="{Loc 'health-analyzer-window-triage-claim'}"
+                            MinSize="60 0" />
+
+                    <PanelContainer StyleClasses="LowDivider" Margin="0 8 0 0"/>
+                </BoxContainer>
+                <!-- End DeltaV - Medical Records -->
+
                 <GridContainer Margin="0 5 0 0"
                                Columns="2">
                     <Label Text="{Loc 'health-analyzer-window-entity-status-text'}"/>
diff --git a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
index 8ed6fc63e402..62e2b7cdc3ca 100644
--- a/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
+++ b/Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
@@ -4,6 +4,7 @@
 using Content.Shared._DV.Traits.Assorted; // DeltaV
 using Content.Shared.Atmos;
 using Content.Client.UserInterface.Controls;
+using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
 using Content.Shared._Shitmed.Targeting; // Shitmed
 using Content.Shared.Alert;
 using Content.Shared.Damage;
@@ -50,6 +51,14 @@ public sealed partial class HealthAnalyzerWindow : FancyWindow
         private EntityUid? _target;
         // Shitmed Change End
 
+        // Begin DeltaV - Medical Records
+        private readonly ButtonGroup _triageStatusGroup = new();
+        private readonly Dictionary<TriageStatus, Button> _triageControls = new();
+
+        public event Action<TriageStatus>? OnTriageStatusChanged;
+        public event Action? OnClaimPatient;
+        // End DeltaV - Medical Records
+
         public HealthAnalyzerWindow()
         {
             RobustXamlLoader.Load(this);
@@ -83,6 +92,26 @@ public HealthAnalyzerWindow()
             }
             ReturnButton.OnPressed += _ => ResetBodyPart();
             // Shitmed Change End
+
+            // Begin DeltaV - Medical Records
+            foreach (var item in Enum.GetValues<TriageStatus>())
+            {
+                var btn = new Button();
+                var ftlKey = item.ToString();
+                btn.Group = _triageStatusGroup;
+                btn.Text = Loc.GetString($"health-analyzer-window-triage-status-{ftlKey}");
+                btn.ToolTip = Loc.GetString($"health-analyzer-window-triage-status-{ftlKey}.ToolTip");
+                btn.OnPressed += _ => OnTriageStatusChanged?.Invoke(item);
+                btn.AddStyleClass("ButtonSquare");
+                StatusBox.AddChild(btn);
+                _triageControls[item] = btn;
+            }
+            StatusBox.Children.First().AddStyleClass("OpenRight");
+            StatusBox.Children.First().RemoveStyleClass("ButtonSquare");
+            StatusBox.Children.Last().AddStyleClass("OpenLeft");
+            StatusBox.Children.Last().RemoveStyleClass("ButtonSquare");
+            ClaimButton.OnPressed += _ => OnClaimPatient?.Invoke();
+            // End DeltaV - Medical Records
         }
 
         // Shitmed Change Start
@@ -229,6 +258,16 @@ public void Populate(HealthAnalyzerScannedUserMessage msg)
             IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;
 
             DrawDiagnosticGroups(damageSortedGroups, damagePerType);
+
+            // Begin DeltaV - Medical Records
+            if (msg.MedicalRecord is not {} records)
+            {
+                TriageControls.Visible = false;
+                return;
+            }
+
+            _triageControls[records.Status].Pressed = true;
+            // End DeltaV - Medical Records
         }
         // Shitmed Change End
         private static string GetStatus(MobState mobState)
diff --git a/Content.Client/_DV/Overlays/ShowTriageIconsSystem.cs b/Content.Client/_DV/Overlays/ShowTriageIconsSystem.cs
new file mode 100644
index 000000000000..fecf588a6ae5
--- /dev/null
+++ b/Content.Client/_DV/Overlays/ShowTriageIconsSystem.cs
@@ -0,0 +1,64 @@
+using Content.Client.Overlays;
+using Content.Shared._DV.MedicalRecords;
+using Content.Shared._DV.Overlays;
+using Content.Shared.Access.Systems;
+using Content.Shared.Overlays;
+using Content.Shared.StatusIcon;
+using Content.Shared.StatusIcon.Components;
+using Robust.Client.Player;
+using Robust.Shared.Prototypes;
+
+namespace Content.Client._DV.Overlays;
+
+public sealed class ShowTriageIconsSystem : EquipmentHudSystem<ShowTriageIconsComponent>
+{
+    [Dependency] private readonly SharedIdCardSystem _idCard = default!;
+    [Dependency] private readonly IPrototypeManager _prototype = default!;
+    [Dependency] private readonly IPlayerManager _player = default!;
+
+    private static ProtoId<HealthIconPrototype> Minor = "TriageStatusMinor";
+    private static ProtoId<HealthIconPrototype> Delayed = "TriageStatusDelayed";
+    private static ProtoId<HealthIconPrototype> Immediate = "TriageStatusImmediate";
+    private static ProtoId<HealthIconPrototype> Expectant = "TriageStatusExpectant";
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<MedicalRecordComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
+    }
+
+    private void OnGetStatusIconsEvent(Entity<MedicalRecordComponent> ent, ref GetStatusIconsEvent ev)
+    {
+        if (!IsActive)
+            return;
+
+        var triageStatusIcon = ent.Comp.Record.Status switch {
+            TriageStatus.None => null,
+            TriageStatus.Minor => _prototype.Index(Minor),
+            TriageStatus.Delayed => _prototype.Index(Delayed),
+            TriageStatus.Immediate => _prototype.Index(Immediate),
+            TriageStatus.Expectant => _prototype.Index(Expectant),
+        };
+        if (triageStatusIcon is not {} statusPrototype)
+            return;
+
+        ev.StatusIcons.Add(statusPrototype);
+
+        if (ent.Comp.Record.ClaimedName is {} claimedName)
+        {
+            if (_player.LocalEntity is {} local && _idCard.TryFindIdCard(local, out var idCard) && idCard.Comp.FullName == claimedName)
+            {
+                ev.StatusIcons.Add(_prototype.Index<HealthIconPrototype>("TriageClaimedYours"));
+            }
+            else
+            {
+                ev.StatusIcons.Add(_prototype.Index<HealthIconPrototype>("TriageClaimedOthers"));
+            }
+        }
+        else
+        {
+            ev.StatusIcons.Add(_prototype.Index<HealthIconPrototype>("TriageUnclaimed"));
+        }
+    }
+}
diff --git a/Content.Server/Medical/Components/HealthAnalyzerComponent.cs b/Content.Server/Medical/Components/HealthAnalyzerComponent.cs
index cf397984246e..57ace81fd893 100644
--- a/Content.Server/Medical/Components/HealthAnalyzerComponent.cs
+++ b/Content.Server/Medical/Components/HealthAnalyzerComponent.cs
@@ -1,3 +1,4 @@
+using Content.Shared.StationRecords; // DeltaV - triage
 using Robust.Shared.Audio;
 using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
 
@@ -67,4 +68,12 @@ public sealed partial class HealthAnalyzerComponent : Component
     /// </summary>
     [DataField]
     public bool Silent;
+
+    // Begin DeltaV - Medical Records
+    /// <summary>
+    /// The station records key of the scanned individual, if they have one
+    /// </summary>
+    [DataField]
+    public StationRecordKey? StationRecordKey;
+    // End DeltaV - Medical Records
 }
diff --git a/Content.Server/Medical/HealthAnalyzerSystem.cs b/Content.Server/Medical/HealthAnalyzerSystem.cs
index edae7c11976f..0761b32da5dd 100644
--- a/Content.Server/Medical/HealthAnalyzerSystem.cs
+++ b/Content.Server/Medical/HealthAnalyzerSystem.cs
@@ -25,6 +25,10 @@
 using Content.Shared._Shitmed.Targeting;
 using System.Linq;
 
+// DeltaV - Medical Records
+using Content.Server._DV.MedicalRecords;
+using Content.Shared._DV.MedicalRecords;
+
 namespace Content.Server.Medical;
 
 public sealed class HealthAnalyzerSystem : EntitySystem
@@ -39,6 +43,7 @@ public sealed class HealthAnalyzerSystem : EntitySystem
     [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
     [Dependency] private readonly TransformSystem _transformSystem = default!;
     [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+    [Dependency] private readonly MedicalRecordsSystem _medicalRecords = default!;
 
     public override void Initialize()
     {
@@ -51,6 +56,8 @@ public override void Initialize()
         Subs.BuiEvents<HealthAnalyzerComponent>(HealthAnalyzerUiKey.Key, subs =>
         {
             subs.Event<HealthAnalyzerPartMessage>(OnHealthAnalyzerPartSelected);
+            subs.Event<HealthAnalyzerTriageStatusMessage>(OnHealthAnalyzerTriageStatusSelected);
+            subs.Event<HealthAnalyzerTriageClaimMessage>(OnHealthAnalyzerTriageClaimSelected);
         });
         // Shitmed Change End
     }
@@ -132,6 +139,7 @@ private void OnDoAfter(Entity<HealthAnalyzerComponent> uid, ref HealthAnalyzerDo
 
         OpenUserInterface(args.User, uid);
         BeginAnalyzingEntity(uid, args.Target.Value);
+        uid.Comp.StationRecordKey = _medicalRecords.GetMedicalRecordsKey(args.Target.Value); // DeltaV - Medical Records
         args.Handled = true;
     }
 
@@ -226,6 +234,24 @@ private void OnHealthAnalyzerPartSelected(Entity<HealthAnalyzerComponent> health
     }
     // Shitmed Change End
 
+    // Begin DeltaV - Medical Records
+    private void OnHealthAnalyzerTriageStatusSelected(Entity<HealthAnalyzerComponent> healthAnalyzer, ref HealthAnalyzerTriageStatusMessage args)
+    {
+        if (healthAnalyzer.Comp.StationRecordKey is not {} key)
+            return;
+
+        _medicalRecords.SetPatientStatus(key, args.TriageStatus);
+    }
+
+    private void OnHealthAnalyzerTriageClaimSelected(Entity<HealthAnalyzerComponent> healthAnalyzer, ref HealthAnalyzerTriageClaimMessage args)
+    {
+        if (healthAnalyzer.Comp.StationRecordKey is not {} key)
+            return;
+
+        _medicalRecords.ClaimPatient(key, args.Actor);
+    }
+    // End DeltaV - Medical Records
+
     /// <summary>
     /// Send an update for the target to the healthAnalyzer
     /// </summary>
@@ -276,6 +302,7 @@ public void UpdateScannedUser(EntityUid healthAnalyzer, EntityUid target, bool s
             unrevivable,
             // Shitmed Change
             body,
+            _medicalRecords.GetMedicalRecords(target), // DeltaV - Medical Records
             part != null ? GetNetEntity(part) : null
         ));
     }
diff --git a/Content.Server/_DV/MedicalRecords/MedicalRecordsSystem.cs b/Content.Server/_DV/MedicalRecords/MedicalRecordsSystem.cs
new file mode 100644
index 000000000000..0a8eb940263e
--- /dev/null
+++ b/Content.Server/_DV/MedicalRecords/MedicalRecordsSystem.cs
@@ -0,0 +1,97 @@
+using Content.Shared._DV.MedicalRecords;
+using Content.Shared.Access.Systems;
+using Content.Shared.StationRecords;
+using Content.Server.StationRecords.Systems;
+
+namespace Content.Server._DV.MedicalRecords;
+
+public sealed class MedicalRecordsSystem : SharedMedicalRecordsSystem
+{
+    [Dependency] private readonly StationRecordsSystem _records = default!;
+    [Dependency] private readonly AccessReaderSystem _access = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<AfterGeneralRecordCreatedEvent>(OnGeneralRecordCreated);
+    }
+
+    private void OnGeneralRecordCreated(AfterGeneralRecordCreatedEvent evt)
+    {
+        _records.AddRecordEntry(evt.Key, new MedicalRecord());
+        _records.Synchronize(evt.Key);
+    }
+
+    public void SetStatus(StationRecordKey key, MedicalRecord record)
+    {
+        var name = _records.RecordName(key);
+        if (name != string.Empty)
+            UpdateMedicalRecords(name, record);
+
+        _records.AddRecordEntry(key, record);
+        _records.Synchronize(key);
+    }
+
+    public MedicalRecord? GetMedicalRecords(EntityUid patient)
+    {
+        _access.FindStationRecordKeys(patient, out var keys);
+        foreach (var key in keys)
+        {
+            if (_records.TryGetRecord<MedicalRecord>(key, out var record))
+                return record;
+        }
+        foreach (var key in keys)
+        {
+            var medicalRecord = new MedicalRecord();
+            SetStatus(key, medicalRecord);
+            return medicalRecord;
+        }
+        return null;
+    }
+
+    public StationRecordKey? GetMedicalRecordsKey(EntityUid patient)
+    {
+        _access.FindStationRecordKeys(patient, out var keys);
+        foreach (var key in keys)
+        {
+            if (_records.TryGetRecord<MedicalRecord>(key, out var record))
+                return key;
+        }
+        foreach (var key in keys)
+        {
+            SetStatus(key, new MedicalRecord());
+            return key;
+        }
+        return null;
+    }
+
+    public void SetPatientStatus(StationRecordKey patient, TriageStatus status)
+    {
+        if (_records.TryGetRecord<MedicalRecord>(patient, out var record) && status != TriageStatus.None)
+        {
+            SetStatus(patient, record with { Status = status });
+        }
+        else
+        {
+            SetStatus(patient, new MedicalRecord());
+        }
+    }
+
+    public void ClaimPatient(StationRecordKey patient, EntityUid claimer)
+    {
+        _access.FindStationRecordKeys(claimer, out var keys);
+        foreach (var key in keys)
+        {
+            var name = _records.RecordName(key);
+            if (name == string.Empty)
+                continue;
+
+            if (!_records.TryGetRecord<MedicalRecord>(patient, out var record) || record.ClaimedName == name)
+                continue;
+
+            SetStatus(patient, record with { ClaimedName = name });
+            break;
+        }
+    }
+}
diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs
index 94a32f5ef3b4..802efa415e3b 100644
--- a/Content.Shared/Inventory/InventorySystem.Relay.cs
+++ b/Content.Shared/Inventory/InventorySystem.Relay.cs
@@ -65,6 +65,7 @@ public void InitializeRelay()
         SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowMindShieldIconsComponent>>(RefRelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowSyndicateIconsComponent>>(RefRelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<ShowCriminalRecordIconsComponent>>(RefRelayInventoryEvent);
+        SubscribeLocalEvent<InventoryComponent, RefreshEquipmentHudEvent<Content.Shared._DV.Overlays.ShowTriageIconsComponent>>(RefRelayInventoryEvent); // DeltaV - Medical Records
 
         SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<EquipmentVerb>>(OnGetEquipmentVerbs);
     }
diff --git a/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs b/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
index 54a4a5e832d2..1926cf21dd51 100644
--- a/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
+++ b/Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
@@ -1,3 +1,4 @@
+using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
 using Content.Shared._Shitmed.Targeting; // Shitmed Change
 using Robust.Shared.Serialization;
 
@@ -17,8 +18,9 @@ public sealed class HealthAnalyzerScannedUserMessage : BoundUserInterfaceMessage
     public bool? Unrevivable;
     public Dictionary<TargetBodyPart, TargetIntegrity>? Body; // Shitmed Change
     public NetEntity? Part; // Shitmed Change
+    public MedicalRecord? MedicalRecord; // DeltaV - Medical Records
 
-    public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, Dictionary<TargetBodyPart, TargetIntegrity>? body, NetEntity? part = null) // Shitmed Change
+    public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, Dictionary<TargetBodyPart, TargetIntegrity>? body, MedicalRecord? medicalRecord = null, NetEntity? part = null) // Shitmed Change // DeltaV - Medical Records
     {
         TargetEntity = targetEntity;
         Temperature = temperature;
@@ -28,6 +30,7 @@ public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperatu
         Unrevivable = unrevivable;
         Body = body; // Shitmed Change
         Part = part; // Shitmed Change
+        MedicalRecord = medicalRecord; // DeltaV - Medical Records
     }
 }
 
diff --git a/Content.Shared/_DV/MedicalRecords/MedicalRecord.cs b/Content.Shared/_DV/MedicalRecords/MedicalRecord.cs
new file mode 100644
index 000000000000..2b3b4b334272
--- /dev/null
+++ b/Content.Shared/_DV/MedicalRecords/MedicalRecord.cs
@@ -0,0 +1,38 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._DV.MedicalRecords;
+
+/// <summary>
+/// Status used in Medical Records.
+///
+/// None - the default value
+/// Minor - minor injuries, may be able to assist in own care
+/// Delayed - serious injuries, but not expected to deteroriate within a few minutes
+/// Immediate - can be helped with immediate intervention and transport
+/// Expectant - unlikely to survive or already dead
+/// </summary>
+public enum TriageStatus : byte
+{
+    None,
+    Minor,
+    Delayed,
+    Immediate,
+    Expectant,
+}
+
+/// <summary>
+/// Medical record for a crewmember.
+/// </summary>
+[Serializable, NetSerializable, DataRecord]
+public sealed partial record MedicalRecord
+{
+    /// <summary>
+    /// Status of the person
+    /// </summary>
+    public TriageStatus Status = TriageStatus.None;
+
+    /// <summary>
+    /// The name of the doctor who has claimed care of this patient
+    /// </summary>
+    public string? ClaimedName;
+}
diff --git a/Content.Shared/_DV/MedicalRecords/MedicalRecordComponent.cs b/Content.Shared/_DV/MedicalRecords/MedicalRecordComponent.cs
new file mode 100644
index 000000000000..6fa4f936004b
--- /dev/null
+++ b/Content.Shared/_DV/MedicalRecords/MedicalRecordComponent.cs
@@ -0,0 +1,11 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._DV.MedicalRecords;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class MedicalRecordComponent : Component
+{
+    [DataField, AutoNetworkedField]
+    public MedicalRecord Record;
+}
diff --git a/Content.Shared/_DV/MedicalRecords/SharedMedicalRecordsSystem.cs b/Content.Shared/_DV/MedicalRecords/SharedMedicalRecordsSystem.cs
new file mode 100644
index 000000000000..a5418f2c62ab
--- /dev/null
+++ b/Content.Shared/_DV/MedicalRecords/SharedMedicalRecordsSystem.cs
@@ -0,0 +1,29 @@
+using Content.Shared.IdentityManagement;
+using Content.Shared.IdentityManagement.Components;
+
+namespace Content.Shared._DV.MedicalRecords;
+
+public abstract class SharedMedicalRecordsSystem : EntitySystem
+{
+    public void UpdateMedicalRecords(string name, MedicalRecord status)
+    {
+        var query = EntityQueryEnumerator<IdentityComponent>();
+
+        while (query.MoveNext(out var uid, out var identity))
+        {
+            if (!Identity.Name(uid, EntityManager).Equals(name))
+                continue;
+
+            if (status.Status == TriageStatus.None)
+            {
+                RemComp<MedicalRecordComponent>(uid);
+            }
+            else
+            {
+                EnsureComp<MedicalRecordComponent>(uid, out var record);
+                record.Record = status;
+                Dirty(uid, record);
+            }
+        }
+    }
+}
diff --git a/Content.Shared/_DV/MedicalRecords/TriageMessages.cs b/Content.Shared/_DV/MedicalRecords/TriageMessages.cs
new file mode 100644
index 000000000000..50989f04c5b0
--- /dev/null
+++ b/Content.Shared/_DV/MedicalRecords/TriageMessages.cs
@@ -0,0 +1,12 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._DV.MedicalRecords;
+
+[Serializable, NetSerializable]
+public sealed class HealthAnalyzerTriageStatusMessage(TriageStatus triageStatus) : BoundUserInterfaceMessage
+{
+    public readonly TriageStatus TriageStatus = triageStatus;
+}
+
+[Serializable, NetSerializable]
+public sealed class HealthAnalyzerTriageClaimMessage : BoundUserInterfaceMessage;
diff --git a/Content.Shared/_DV/Overlays/ShowTriageIconsComponent.cs b/Content.Shared/_DV/Overlays/ShowTriageIconsComponent.cs
new file mode 100644
index 000000000000..9bc6e03b07f2
--- /dev/null
+++ b/Content.Shared/_DV/Overlays/ShowTriageIconsComponent.cs
@@ -0,0 +1,9 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared._DV.Overlays;
+
+/// <summary>
+///     This component allows you to see triage icons above mobs.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class ShowTriageIconsComponent : Component;
diff --git a/Resources/Locale/en-US/_DV/medical/components/health-analyzer-component.ftl b/Resources/Locale/en-US/_DV/medical/components/health-analyzer-component.ftl
index 7698576e4e52..7fda8f0c0b98 100644
--- a/Resources/Locale/en-US/_DV/medical/components/health-analyzer-component.ftl
+++ b/Resources/Locale/en-US/_DV/medical/components/health-analyzer-component.ftl
@@ -1 +1,12 @@
 health-analyzer-window-entity-unborgable-text = [color=red]Patient's brain signatures are incompatible with MMI technology![/color]
+health-analyzer-window-triage-claim = Claim Patient
+health-analyzer-window-triage-status-None = None
+    .ToolTip = Patient with no injuries
+health-analyzer-window-triage-status-Minor = Minor
+    .ToolTip = Victim with relatively minor injuries
+health-analyzer-window-triage-status-Delayed = Delayed
+    .ToolTip = Victim's transport can be delayed. Potentially life threatening, but not immediately.
+health-analyzer-window-triage-status-Immediate = Immediate
+    .ToolTip = Victim can be helped by immediate intervention and transport. Requires medical attention for survival.
+health-analyzer-window-triage-status-Expectant = Expectant
+    .ToolTip = Victim unlikely to survive, or is already dead.
diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml
index 7d351e420a0e..d114fb30a253 100644
--- a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml
+++ b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml
@@ -14,6 +14,7 @@
   components:
   - type: ShowHealthBars
   - type: ShowHealthIcons
+  - type: ShowTriageIcons # DeltaV - Medical Records
 
 - type: entity
   parent: [ ClothingEyesBase, BaseToggleClothing ] # DeltaV - Added BaseToggleClothing
diff --git a/Resources/Prototypes/_DV/StatusIcon/triage.yml b/Resources/Prototypes/_DV/StatusIcon/triage.yml
new file mode 100644
index 000000000000..4073713a017c
--- /dev/null
+++ b/Resources/Prototypes/_DV/StatusIcon/triage.yml
@@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
+    state: minor
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusDelayed
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
+    state: delayed
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusImmediate
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
+    state: immediate
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusExpectant
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
+    state: expectant
+
+- type: healthIcon
+  parent: TriageClaimIcon
+  id: TriageUnclaimed
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
+    state: unclaimed
+
+- type: healthIcon
+  parent: TriageClaimIcon
+  id: TriageClaimedYours
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
+    state: claimed_yours
+
+- type: healthIcon
+  parent: TriageClaimIcon
+  id: TriageClaimedOthers
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
+    state: claimed_others
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_others.png b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_others.png
new file mode 100644
index 000000000000..722e6e72c1e7
Binary files /dev/null and b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_others.png differ
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_yours.png b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_yours.png
new file mode 100644
index 000000000000..5187d5b01e42
Binary files /dev/null and b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_yours.png differ
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/delayed.png b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/delayed.png
new file mode 100644
index 000000000000..3ae84fd7c0a5
Binary files /dev/null and b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/delayed.png differ
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/expectant.png b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/expectant.png
new file mode 100644
index 000000000000..2ff6a391b7c1
Binary files /dev/null and b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/expectant.png differ
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/immediate.png b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/immediate.png
new file mode 100644
index 000000000000..2e383d8d87b0
Binary files /dev/null and b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/immediate.png differ
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/meta.json b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/meta.json
new file mode 100644
index 000000000000..abc50cd69560
--- /dev/null
+++ b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/meta.json
@@ -0,0 +1,32 @@
+{
+    "version": 1,
+    "license": "CC0-1.0",
+    "copyright": "claimed_others, claimed_yours, delayed, expectant, immediate, minor, unclaimed by Janet Blackquill <uhhadd@gmail.com> 2025",
+    "size": {
+        "x": 8,
+        "y": 8
+    },
+    "states": [
+        {
+            "name": "claimed_others"
+        },
+        {
+            "name": "claimed_yours"
+        },
+        {
+            "name": "unclaimed"
+        },
+        {
+            "name": "minor"
+        },
+        {
+            "name": "delayed"
+        },
+        {
+            "name": "immediate"
+        },
+        {
+            "name": "expectant"
+        }
+    ]
+}
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/minor.png b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/minor.png
new file mode 100644
index 000000000000..765d70d6714a
Binary files /dev/null and b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/minor.png differ
diff --git a/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/unclaimed.png b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/unclaimed.png
new file mode 100644
index 000000000000..31c6edaf225b
Binary files /dev/null and b/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/unclaimed.png differ


Reviews:
user: login: deltanedas
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T19:23:12Z
user: login: sowelipililimute
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T19:24:26Z
user: login: deltanedas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T19:32:14Z
user: login: sowelipililimute
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T20:07:32Z
user: login: sowelipililimute
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T20:43:32Z
user: login: sowelipililimute
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T20:45:47Z
user: login: ThataKat
body: Medsec HUD addressed so this is good to go
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T19:14:35Z
user: login: deltanedas
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T23:07:33Z
user: login: sowelipililimute
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T23:28:20Z
user: login: deltanedas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T23:46:36Z
user: login: sowelipililimute
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T00:08:10Z
user: login: deltanedas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T00:23:38Z
user: login: deltanedas
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T00:23:51Z

Review comments:
diff_hunk: @@ -198,6 +198,39 @@
 
                 <PanelContainer StyleClasses="LowDivider"/>
 
+                <BoxContainer Name="TriageControls" Orientation="Vertical">
+                    <BoxContainer Orientation="Horizontal"
+                                  HorizontalAlignment="Center"
+                                  Margin="0 8 0 0">
+                        <Button Name="ExpectantButton"
+                                Text="Expectant"
+                                StyleClasses="OpenRight"
+                                MinSize="60 0" />
+                        <Button Name="ImmediateButton"
+                                Text="Immediate"
+                                StyleClasses="ButtonSquare"
+                                MinSize="60 0" />
+                        <Button Name="DelayedButton"
+                                Text="Delayed"
+                                StyleClasses="ButtonSquare"
+                                MinSize="60 0" />
+                        <Button Name="MinorButton"
+                                Text="Minor"
+                                StyleClasses="ButtonSquare"
+                                MinSize="60 0" />
+                        <Button Name="NoneButton"
+                                Text="None"
+                                StyleClasses="OpenLeft"
+                                MinSize="60 0" />
+                    </BoxContainer>
+
+                    <Button Name="ClaimButton"
+                            Text="Claim Patient"
+                            MinSize="60 0" />
+
+                    <PanelContainer StyleClasses="LowDivider" Margin="0 8 0 0"/>
+                </BoxContainer>
path: Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml
user: login: deltanedas
body: add Begin DeltaV Additions / End DeltaV Additions comments
created_at: 2025-03-08T02:35:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -83,6 +91,22 @@ public HealthAnalyzerWindow()
             }
             ReturnButton.OnPressed += _ => ResetBodyPart();
             // Shitmed Change End
+
+            // Begin DeltaV - Medical Records
+            ExpectantButton.Group = _triageStatusGroup;
+            ImmediateButton.Group = _triageStatusGroup;
+            DelayedButton.Group = _triageStatusGroup;
+            MinorButton.Group = _triageStatusGroup;
+            NoneButton.Group = _triageStatusGroup;
+
+            ExpectantButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Expectant);
+            ImmediateButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Immediate);
+            DelayedButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Delayed);
+            MinorButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Minor);
+            NoneButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.None);
path: Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
user: login: deltanedas
body: create it dynamically from Enum.GetValues instead of hardcoding it
created_at: 2025-03-08T02:36:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,40 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._DV.MedicalRecords;
+
+/// <summary>
+/// Status used in Medical Records.
+///
+/// None - the default value
+/// Minor - minor injuries, may be able to assist in own care
+/// Delayed - serious injuries, but not expected to deteroriate within a few minutes
+/// Immediate - can be helped with immediate intervention and transport
+/// Expectant - unlikely to survive or already dead
+/// </summary>
+public enum TriageStatus : byte
+{
+    None,
+    Minor,
+    Delayed,
+    Immediate,
+    Expectant,
+}
+
+/// <summary>
+/// Medical record for a crewmember.
+/// </summary>
+[Serializable, NetSerializable, DataRecord]
+public sealed partial record MedicalRecord
+{
+    /// <summary>
+    /// Status of the person
+    /// </summary>
+    [DataField]
path: Content.Shared/_DV/MedicalRecords/MedicalRecord.cs
user: login: deltanedas
body: dont need datafields on these as the struct has DataRecord
created_at: 2025-03-08T19:21:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
path: Resources/Prototypes/_DV/StatusIcon/triage.yml
user: login: deltanedas
body: remove /Textures/ prefix from these path its automatically added
created_at: 2025-03-08T19:22:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -83,6 +91,22 @@ public HealthAnalyzerWindow()
             }
             ReturnButton.OnPressed += _ => ResetBodyPart();
             // Shitmed Change End
+
+            // Begin DeltaV - Medical Records
+            ExpectantButton.Group = _triageStatusGroup;
+            ImmediateButton.Group = _triageStatusGroup;
+            DelayedButton.Group = _triageStatusGroup;
+            MinorButton.Group = _triageStatusGroup;
+            NoneButton.Group = _triageStatusGroup;
+
+            ExpectantButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Expectant);
+            ImmediateButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Immediate);
+            DelayedButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Delayed);
+            MinorButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Minor);
+            NoneButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.None);
path: Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
user: login: sowelipililimute
body: do you want to me to like. use reflection to figure out which button goes with which triage status
created_at: 2025-03-08T19:24:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -83,6 +91,22 @@ public HealthAnalyzerWindow()
             }
             ReturnButton.OnPressed += _ => ResetBodyPart();
             // Shitmed Change End
+
+            // Begin DeltaV - Medical Records
+            ExpectantButton.Group = _triageStatusGroup;
+            ImmediateButton.Group = _triageStatusGroup;
+            DelayedButton.Group = _triageStatusGroup;
+            MinorButton.Group = _triageStatusGroup;
+            NoneButton.Group = _triageStatusGroup;
+
+            ExpectantButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Expectant);
+            ImmediateButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Immediate);
+            DelayedButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Delayed);
+            MinorButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Minor);
+            NoneButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.None);
path: Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
user: login: deltanedas
body: no just store it as metadata, im 90% sure criminal records does this for its drop downs
created_at: 2025-03-08T19:32:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -83,6 +91,22 @@ public HealthAnalyzerWindow()
             }
             ReturnButton.OnPressed += _ => ResetBodyPart();
             // Shitmed Change End
+
+            // Begin DeltaV - Medical Records
+            ExpectantButton.Group = _triageStatusGroup;
+            ImmediateButton.Group = _triageStatusGroup;
+            DelayedButton.Group = _triageStatusGroup;
+            MinorButton.Group = _triageStatusGroup;
+            NoneButton.Group = _triageStatusGroup;
+
+            ExpectantButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Expectant);
+            ImmediateButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Immediate);
+            DelayedButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Delayed);
+            MinorButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Minor);
+            NoneButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.None);
path: Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
user: login: sowelipililimute
body: hm i see
created_at: 2025-03-08T20:07:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
path: Resources/Prototypes/_DV/StatusIcon/triage.yml
user: login: sowelipililimute
body: misinformation ops real
created_at: 2025-03-08T20:43:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -83,6 +91,22 @@ public HealthAnalyzerWindow()
             }
             ReturnButton.OnPressed += _ => ResetBodyPart();
             // Shitmed Change End
+
+            // Begin DeltaV - Medical Records
+            ExpectantButton.Group = _triageStatusGroup;
+            ImmediateButton.Group = _triageStatusGroup;
+            DelayedButton.Group = _triageStatusGroup;
+            MinorButton.Group = _triageStatusGroup;
+            NoneButton.Group = _triageStatusGroup;
+
+            ExpectantButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Expectant);
+            ImmediateButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Immediate);
+            DelayedButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Delayed);
+            MinorButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.Minor);
+            NoneButton.OnPressed += _ => OnTriageStatusChanged?.Invoke(TriageStatus.None);
path: Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
user: login: sowelipililimute
body: enum loops and localization ops real
created_at: 2025-03-08T20:45:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
path: Resources/Prototypes/_DV/StatusIcon/triage.yml
user: login: deltanedas
body: not misinformation if the path isnt rooted to textures it gets added automatically
from ResPathSerializer,
```cs
if (!path.CanonPath.Split('/').First().Equals("Textures", StringComparison.InvariantCultureIgnoreCase))
{
    path = SpriteSpecifierSerializer.TextureRoot / path;
}
```
created_at: 2025-03-17T23:03:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -83,6 +92,25 @@ public HealthAnalyzerWindow()
             }
             ReturnButton.OnPressed += _ => ResetBodyPart();
             // Shitmed Change End
+
+            // Begin DeltaV - Medical Records
+            foreach (var item in Enum.GetValues<TriageStatus>())
+            {
+                var btn = new Button();
+                btn.Group = _triageStatusGroup;
+                btn.Text = Loc.GetString($"health-analyzer-window-triage-status-{item.ToString()}");
+                btn.ToolTip = Loc.GetString($"health-analyzer-window-triage-status-{item.ToString()}.ToolTip");
path: Content.Client/HealthAnalyzer/UI/HealthAnalyzerWindow.xaml.cs
user: login: deltanedas
body: reuse the item.ToString() result
created_at: 2025-03-17T23:04:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,59 @@
+using Content.Client.Overlays;
+using Content.Shared._DV.MedicalRecords;
+using Content.Shared._DV.Overlays;
+using Content.Shared.Access.Systems;
+using Content.Shared.Overlays;
+using Content.Shared.StatusIcon;
+using Content.Shared.StatusIcon.Components;
+using Robust.Client.Player;
+using Robust.Shared.Prototypes;
+
+namespace Content.Client._DV.Overlays;
+
+public sealed class ShowTriageIconsSystem : EquipmentHudSystem<ShowTriageIconsComponent>
+{
+    [Dependency] private readonly SharedIdCardSystem _idCard = default!;
+    [Dependency] private readonly IPrototypeManager _prototype = default!;
+    [Dependency] private readonly IPlayerManager _player = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<MedicalRecordComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
+    }
+
+    private void OnGetStatusIconsEvent(Entity<MedicalRecordComponent> ent, ref GetStatusIconsEvent ev)
+    {
+        if (!IsActive)
+            return;
+
+        var triageStatusIcon = ent.Comp.Record.Status switch {
+            TriageStatus.None => null,
+            TriageStatus.Minor => _prototype.Index<HealthIconPrototype>("TriageStatusMinor"),
+            TriageStatus.Delayed => _prototype.Index<HealthIconPrototype>("TriageStatusDelayed"),
+            TriageStatus.Immediate => _prototype.Index<HealthIconPrototype>("TriageStatusImmediate"),
+            TriageStatus.Expectant => _prototype.Index<HealthIconPrototype>("TriageStatusExpectant"),
path: Content.Client/_DV/Overlays/ShowTriageIconsSystem.cs
user: login: deltanedas
body: make these static ProtoIds on the system so they get verified
created_at: 2025-03-17T23:05:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,3 +1,4 @@
+using Content.Shared.StationRecords;
path: Content.Server/Medical/Components/HealthAnalyzerComponent.cs
user: login: deltanedas
body: comment
created_at: 2025-03-17T23:05:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -17,8 +18,9 @@ public sealed class HealthAnalyzerScannedUserMessage : BoundUserInterfaceMessage
     public bool? Unrevivable;
     public Dictionary<TargetBodyPart, TargetIntegrity>? Body; // Shitmed Change
     public NetEntity? Part; // Shitmed Change
+    public MedicalRecord? MedicalRecord; // DeltaV - Medical Records
 
-    public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, Dictionary<TargetBodyPart, TargetIntegrity>? body, NetEntity? part = null) // Shitmed Change
+    public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable, Dictionary<TargetBodyPart, TargetIntegrity>? body, MedicalRecord? medicalRecord, NetEntity? part = null) // Shitmed Change // DeltaV - Medical Records
path: Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
user: login: deltanedas
body: make it default to null and undo change to cryo pod system
created_at: 2025-03-17T23:06:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,3 +43,14 @@ public sealed class HealthAnalyzerPartMessage(NetEntity? owner, TargetBodyPart?
 
 }
 // Shitmed Change End
+
+// Begin DeltaV - Medical Records
+[Serializable, NetSerializable]
+public sealed class HealthAnalyzerTriageStatusMessage(TriageStatus triageStatus) : BoundUserInterfaceMessage
+{
+    public readonly TriageStatus TriageStatus = triageStatus;
+}
+
+[Serializable, NetSerializable]
+public sealed class HealthAnalyzerTriageClaimMessage : BoundUserInterfaceMessage;
path: Content.Shared/MedicalScanner/HealthAnalyzerScannedUserMessage.cs
user: login: deltanedas
body: move these to _DV
created_at: 2025-03-17T23:07:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
path: Resources/Prototypes/_DV/StatusIcon/triage.yml
user: login: sowelipililimute
body: i uh, tried multiple variants:
```
- _DV/Interface/Misc/triage_icons.rsi
- /_DV/Interface/Misc/triage_icons.rsi
```
and they failed to load the RSI
created_at: 2025-03-17T23:28:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
path: Resources/Prototypes/_DV/StatusIcon/triage.yml
user: login: deltanedas
body: you dont root it with / you do `sprite: _DV/...` which works for everything else (see: `grep Resources/Prototypes/_DV -Rne 'sprite: _DV/'`) show logs if otherwise
created_at: 2025-03-17T23:46:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
path: Resources/Prototypes/_DV/StatusIcon/triage.yml
user: login: sowelipililimute
body: ```
[ERRO] res: Exception while loading resource Robust.Client.ResourceManagement.RSIResource at '_DV/Interface/Misc/triage_icons.rsi', resorting to fallback.
   at System.Environment.get_StackTrace()
   at Robust.Client.ResourceManagement.ResourceCache.GetResource[T](ResPath path, Boolean useFallback) in /home/jblackquill/GitHub/Delta-v/RobustToolbox/Robust.Client/ResourceManagement/ResourceCache.cs:line 40
   at Robust.Client.GameObjects.SpriteSystem.GetFrame(SpriteSpecifier spriteSpec, TimeSpan curTime, Boolean loop) in /home/jblackquill/GitHub/Delta-v/RobustToolbox/Robust.Client/GameObjects/EntitySystems/SpriteSystem.cs:line 202
   at Content.Client.StatusIcon.StatusIconOverlay.Draw(OverlayDrawArgs& args) in /home/jblackquill/GitHub/Delta-v/Content.Client/StatusIcon/StatusIconOverlay.cs:line 79
```
created_at: 2025-03-18T00:08:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+- type: healthIcon
+  id: TriageStatusIcon
+  abstract: true
+  priority: 4
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  id: TriageClaimIcon
+  abstract: true
+  priority: 5
+  offset: 1
+  locationPreference: Left
+  isShaded: true
+
+- type: healthIcon
+  parent: TriageStatusIcon
+  id: TriageStatusMinor
+  icon:
+    sprite: /Textures/_DV/Interface/Misc/triage_icons.rsi
path: Resources/Prototypes/_DV/StatusIcon/triage.yml
user: login: deltanedas
body: ok other icons do this too, guess status icons specifically dont use the serializer
created_at: 2025-03-18T00:23:38Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-08T01:48:38Z
body: RSI Diff Bot; head commit 664a2e857689841e16e65287e292c663ea707543 merging into 2e9d2c1766baa43b42d8c4baacedf2e7248cb233
This PR makes changes to 1 or more RSIs. Here is a summary of all changes:

<details><summary>Resources/Textures/_DV/Interface/Misc/triage_icons.rsi</summary>
<p>

| State | Old | New | Status
| --- | --- | --- | --- |
| claimed_others | ![]() | ![](https://raw.githubusercontent.com/sowelipililimute/Delta-v/664a2e857689841e16e65287e292c663ea707543/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_others.png) | Added
| claimed_yours | ![]() | ![](https://raw.githubusercontent.com/sowelipililimute/Delta-v/664a2e857689841e16e65287e292c663ea707543/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/claimed_yours.png) | Added
| delayed | ![]() | ![](https://raw.githubusercontent.com/sowelipililimute/Delta-v/664a2e857689841e16e65287e292c663ea707543/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/delayed.png) | Added
| expectant | ![]() | ![](https://raw.githubusercontent.com/sowelipililimute/Delta-v/664a2e857689841e16e65287e292c663ea707543/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/expectant.png) | Added
| immediate | ![]() | ![](https://raw.githubusercontent.com/sowelipililimute/Delta-v/664a2e857689841e16e65287e292c663ea707543/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/immediate.png) | Added
| minor | ![]() | ![](https://raw.githubusercontent.com/sowelipililimute/Delta-v/664a2e857689841e16e65287e292c663ea707543/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/minor.png) | Added
| unclaimed | ![]() | ![](https://raw.githubusercontent.com/sowelipililimute/Delta-v/664a2e857689841e16e65287e292c663ea707543/Resources/Textures/_DV/Interface/Misc/triage_icons.rsi/unclaimed.png) | Added


</p>
</details>
Edit: diff updated after 664a2e857689841e16e65287e292c663ea707543
author_association: CONTRIBUTOR
user: login: ThataKat
created_at: 2025-03-08T19:00:49Z
body: Very neat, under review. 2 days or less.
author_association: CONTRIBUTOR
user: login: ThataKat
created_at: 2025-03-09T19:03:44Z
body: Conceptually approved, but we're wondering what this looks like with the corpsman glasses. Have any conflicts with those been resolved?
author_association: CONTRIBUTOR