HealthExaminableSystem.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using Content.Shared.Damage;
  2. using Content.Shared.Examine;
  3. using Content.Shared.FixedPoint;
  4. using Content.Shared.IdentityManagement;
  5. using Content.Shared.Verbs;
  6. using Robust.Shared.Utility;
  7. namespace Content.Shared.HealthExaminable;
  8. public sealed class HealthExaminableSystem : EntitySystem
  9. {
  10. [Dependency] private readonly ExamineSystemShared _examineSystem = default!;
  11. public override void Initialize()
  12. {
  13. base.Initialize();
  14. SubscribeLocalEvent<HealthExaminableComponent, GetVerbsEvent<ExamineVerb>>(OnGetExamineVerbs);
  15. }
  16. private void OnGetExamineVerbs(EntityUid uid, HealthExaminableComponent component, GetVerbsEvent<ExamineVerb> args)
  17. {
  18. if (!TryComp<DamageableComponent>(uid, out var damage))
  19. return;
  20. var detailsRange = _examineSystem.IsInDetailsRange(args.User, uid);
  21. var verb = new ExamineVerb()
  22. {
  23. Act = () =>
  24. {
  25. var markup = CreateMarkup(uid, component, damage);
  26. _examineSystem.SendExamineTooltip(args.User, uid, markup, false, false);
  27. },
  28. Text = Loc.GetString("health-examinable-verb-text"),
  29. Category = VerbCategory.Examine,
  30. Disabled = !detailsRange,
  31. Message = detailsRange ? null : Loc.GetString("health-examinable-verb-disabled"),
  32. Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/rejuvenate.svg.192dpi.png"))
  33. };
  34. args.Verbs.Add(verb);
  35. }
  36. public FormattedMessage CreateMarkup(EntityUid uid, HealthExaminableComponent component, DamageableComponent damage)
  37. {
  38. var msg = new FormattedMessage();
  39. var first = true;
  40. foreach (var type in component.ExaminableTypes)
  41. {
  42. if (!damage.Damage.DamageDict.TryGetValue(type, out var dmg))
  43. continue;
  44. if (dmg == FixedPoint2.Zero)
  45. continue;
  46. FixedPoint2 closest = FixedPoint2.Zero;
  47. string chosenLocStr = string.Empty;
  48. foreach (var threshold in component.Thresholds)
  49. {
  50. var str = $"health-examinable-{component.LocPrefix}-{type}-{threshold}";
  51. var tempLocStr = Loc.GetString($"health-examinable-{component.LocPrefix}-{type}-{threshold}", ("target", Identity.Entity(uid, EntityManager)));
  52. // i.e., this string doesn't exist, because theres nothing for that threshold
  53. if (tempLocStr == str)
  54. continue;
  55. if (dmg > threshold && threshold > closest)
  56. {
  57. chosenLocStr = tempLocStr;
  58. closest = threshold;
  59. }
  60. }
  61. if (closest == FixedPoint2.Zero)
  62. continue;
  63. if (!first)
  64. {
  65. msg.PushNewline();
  66. }
  67. else
  68. {
  69. first = false;
  70. }
  71. msg.AddMarkupOrThrow(chosenLocStr);
  72. }
  73. if (msg.IsEmpty)
  74. {
  75. msg.AddMarkupOrThrow(Loc.GetString($"health-examinable-{component.LocPrefix}-none"));
  76. }
  77. // Anything else want to add on to this?
  78. RaiseLocalEvent(uid, new HealthBeingExaminedEvent(msg), true);
  79. return msg;
  80. }
  81. }
  82. /// <summary>
  83. /// A class raised on an entity whose health is being examined
  84. /// in order to add special text that is not handled by the
  85. /// damage thresholds.
  86. /// </summary>
  87. public sealed class HealthBeingExaminedEvent
  88. {
  89. public FormattedMessage Message;
  90. public HealthBeingExaminedEvent(FormattedMessage message)
  91. {
  92. Message = message;
  93. }
  94. }