| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- 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;
- using Robust.Client.GameObjects;
- using Robust.Client.Graphics;
- using Robust.Client.UserInterface.Controls;
- using Robust.Client.ResourceManagement;
- using Robust.Client.UserInterface;
- using Robust.Shared.Prototypes;
- using Robust.Shared.Utility;
- namespace Content.Client.HealthAnalyzer.UI
- {
- [GenerateTypedNameReferences]
- public sealed partial class HealthAnalyzerWindow : FancyWindow
- {
- private readonly IEntityManager _entityManager;
- private readonly SpriteSystem _spriteSystem;
- private readonly IPrototypeManager _prototypes;
- private readonly IResourceCache _cache;
- public HealthAnalyzerWindow()
- {
- RobustXamlLoader.Load(this);
- var dependencies = IoCManager.Instance!;
- _entityManager = dependencies.Resolve<IEntityManager>();
- _spriteSystem = _entityManager.System<SpriteSystem>();
- _prototypes = dependencies.Resolve<IPrototypeManager>();
- _cache = dependencies.Resolve<IResourceCache>();
- }
- public void Populate(HealthAnalyzerScannedUserMessage msg)
- {
- var target = _entityManager.GetEntity(msg.TargetEntity);
- if (target == null
- || !_entityManager.TryGetComponent<DamageableComponent>(target, out var damageable))
- {
- NoPatientDataText.Visible = true;
- return;
- }
- NoPatientDataText.Visible = false;
- // Scan Mode
- 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);
- SpriteView.Visible = msg.ScanMode.HasValue && msg.ScanMode.Value;
- NoDataTex.Visible = !SpriteView.Visible;
- 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");
- StatusLabel.Text =
- _entityManager.TryGetComponent<MobStateComponent>(target.Value, out var mobStateComponent)
- ? GetStatus(mobStateComponent.CurrentState)
- : Loc.GetString("health-analyzer-window-entity-unknown-text");
- // Total Damage
- DamageLabel.Text = damageable.TotalDamage.ToString();
- // Alerts
- var showAlerts = msg.Unrevivable == true || msg.Bleeding == true;
- AlertsDivider.Visible = showAlerts;
- AlertsContainer.Visible = showAlerts;
- if (showAlerts)
- AlertsContainer.DisposeAllChildren();
- if (msg.Unrevivable == true)
- AlertsContainer.AddChild(new RichTextLabel
- {
- Text = Loc.GetString("health-analyzer-window-entity-unrevivable-text"),
- Margin = new Thickness(0, 4),
- MaxWidth = 300
- });
- if (msg.Bleeding == true)
- AlertsContainer.AddChild(new RichTextLabel
- {
- Text = Loc.GetString("health-analyzer-window-entity-bleeding-text"),
- Margin = new Thickness(0, 4),
- MaxWidth = 300
- });
- // Damage Groups
- var damageSortedGroups =
- damageable.DamagePerGroup.OrderByDescending(damage => damage.Value)
- .ToDictionary(x => x.Key, x => x.Value);
- IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;
- DrawDiagnosticGroups(damageSortedGroups, damagePerType);
- }
- private static string GetStatus(MobState mobState)
- {
- return mobState switch
- {
- 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)
- {
- GroupsContainer.RemoveAllChildren();
- foreach (var (damageGroupId, damageAmount) in groups)
- {
- if (damageAmount == 0)
- continue;
- var groupTitleText = $"{Loc.GetString(
- "health-analyzer-window-damage-group-text",
- ("damageGroup", _prototypes.Index<DamageGroupPrototype>(damageGroupId).LocalizedName),
- ("amount", damageAmount)
- )}";
- var groupContainer = new BoxContainer
- {
- Align = BoxContainer.AlignMode.Begin,
- Orientation = BoxContainer.LayoutOrientation.Vertical,
- };
- groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId));
- GroupsContainer.AddChild(groupContainer);
- // Show the damage for each type in that group.
- var group = _prototypes.Index<DamageGroupPrototype>(damageGroupId);
- foreach (var type in group.DamageTypes)
- {
- if (!damageDict.TryGetValue(type, out var typeAmount) || typeAmount <= 0)
- continue;
- var damageString = Loc.GetString(
- "health-analyzer-window-damage-type-text",
- ("damageType", _prototypes.Index<DamageTypePrototype>(type).LocalizedName),
- ("amount", typeAmount)
- );
- groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, " · ")));
- }
- }
- }
- private Texture GetTexture(string texture)
- {
- var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
- var rsiSprite = new SpriteSpecifier.Rsi(rsiPath, texture);
- var rsi = _cache.GetResource<RSIResource>(rsiSprite.RsiPath).RSI;
- if (!rsi.TryGetState(rsiSprite.RsiState, out var state))
- {
- rsiSprite = new SpriteSpecifier.Rsi(rsiPath, "unknown");
- }
- return _spriteSystem.Frame0(rsiSprite);
- }
- private static Label CreateDiagnosticItemLabel(string text)
- {
- return new Label
- {
- Text = text,
- };
- }
- 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,
- };
- rootContainer.AddChild(new TextureRect
- {
- SetSize = new Vector2(30, 30),
- Texture = GetTexture(id.ToLower())
- });
- rootContainer.AddChild(CreateDiagnosticItemLabel(text));
- return rootContainer;
- }
- }
- }
|