From 4f766f199c7db48908a1b7143980c744ef29bab7 Mon Sep 17 00:00:00 2001 From: Tayrtahn Date: Mon, 14 Jul 2025 00:35:47 -0400 Subject: [PATCH] Refactor ExaminableDamage (#38978) * Remove prototype caching in ExaminableDamageComponent * Replace ExaminableDamagePrototype with LocalizedDatasetPrototype * Allow null --- .../Components/ExaminableDamageComponent.cs | 16 ++--- .../Damage/Systems/ExaminableDamageSystem.cs | 58 ++++++------------- .../Prototypes/ExaminableDamagePrototype.cs | 21 ------- .../Prototypes/Damage/examine_messages.yml | 12 ++-- 4 files changed, 32 insertions(+), 75 deletions(-) delete mode 100644 Content.Shared/Damage/Prototypes/ExaminableDamagePrototype.cs diff --git a/Content.Server/Damage/Components/ExaminableDamageComponent.cs b/Content.Server/Damage/Components/ExaminableDamageComponent.cs index 46a86012ad..26e9e40692 100644 --- a/Content.Server/Damage/Components/ExaminableDamageComponent.cs +++ b/Content.Server/Damage/Components/ExaminableDamageComponent.cs @@ -1,16 +1,18 @@ -using Content.Shared.Damage.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Content.Shared.Dataset; +using Robust.Shared.Prototypes; namespace Content.Server.Damage.Components; /// -/// This component shows entity damage severity when it is examined by player. +/// This component shows entity damage severity when it is examined by player. /// [RegisterComponent] public sealed partial class ExaminableDamageComponent : Component { - [DataField("messages", required: true, customTypeSerializer:typeof(PrototypeIdSerializer))] - public string? MessagesProtoId; - - public ExaminableDamagePrototype? MessagesProto; + /// + /// ID of the containing messages to display a different damage levels. + /// The first message will be used at 0 damage with the others equally distributed across the range from undamaged to fully damaged. + /// + [DataField] + public ProtoId? Messages; } diff --git a/Content.Server/Damage/Systems/ExaminableDamageSystem.cs b/Content.Server/Damage/Systems/ExaminableDamageSystem.cs index c80e19a53d..155cf08962 100644 --- a/Content.Server/Damage/Systems/ExaminableDamageSystem.cs +++ b/Content.Server/Damage/Systems/ExaminableDamageSystem.cs @@ -1,9 +1,6 @@ -using System.Linq; -using Content.Server.Damage.Components; +using Content.Server.Damage.Components; using Content.Server.Destructible; -using Content.Server.Destructible.Thresholds.Triggers; using Content.Shared.Damage; -using Content.Shared.Damage.Prototypes; using Content.Shared.Examine; using Content.Shared.Rounding; using Robust.Shared.Prototypes; @@ -12,59 +9,42 @@ namespace Content.Server.Damage.Systems; public sealed class ExaminableDamageSystem : EntitySystem { + [Dependency] private readonly DestructibleSystem _destructible = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnExamine); } - private void OnInit(EntityUid uid, ExaminableDamageComponent component, ComponentInit args) + private void OnExamine(Entity ent, ref ExaminedEvent args) { - if (component.MessagesProtoId == null) - return; - component.MessagesProto = _prototype.Index(component.MessagesProtoId); - } - - private void OnExamine(EntityUid uid, ExaminableDamageComponent component, ExaminedEvent args) - { - if (component.MessagesProto == null) - return; - - var messages = component.MessagesProto.Messages; - if (messages.Length == 0) + if (!_prototype.TryIndex(ent.Comp.Messages, out var proto) || proto.Values.Count == 0) return; - var level = GetDamageLevel(uid, component); - var msg = Loc.GetString(messages[level]); - args.PushMarkup(msg,-99); + var percent = GetDamagePercent(ent); + var level = ContentHelpers.RoundToNearestLevels(percent, 1, proto.Values.Count - 1); + var msg = Loc.GetString(proto.Values[level]); + args.PushMarkup(msg, -99); } - private int GetDamageLevel(EntityUid uid, ExaminableDamageComponent? component = null, - DamageableComponent? damageable = null, DestructibleComponent? destructible = null) + /// + /// Returns a value between 0 and 1 representing how damaged the entity is, + /// where 0 is undamaged and 1 is fully damaged. + /// + /// How damaged the entity is from 0 to 1 + private float GetDamagePercent(Entity ent) { - if (!Resolve(uid, ref component, ref damageable, ref destructible)) + if (!TryComp(ent, out var damageable)) return 0; - if (component.MessagesProto == null) - return 0; - - var maxLevels = component.MessagesProto.Messages.Length - 1; - if (maxLevels <= 0) - return 0; + var damage = damageable.TotalDamage; + var damageThreshold = _destructible.DestroyedAt(ent); - var trigger = (DamageTrigger?) destructible.Thresholds - .LastOrDefault(threshold => threshold.Trigger is DamageTrigger)?.Trigger; - if (trigger == null) + if (damageThreshold == 0) return 0; - var damage = damageable.TotalDamage; - var damageThreshold = trigger.Damage; - var fraction = damageThreshold == 0 ? 0f : (float) damage / damageThreshold; - - var level = ContentHelpers.RoundToNearestLevels(fraction, 1, maxLevels); - return level; + return (damage / damageThreshold).Float(); } } diff --git a/Content.Shared/Damage/Prototypes/ExaminableDamagePrototype.cs b/Content.Shared/Damage/Prototypes/ExaminableDamagePrototype.cs deleted file mode 100644 index 4d28412334..0000000000 --- a/Content.Shared/Damage/Prototypes/ExaminableDamagePrototype.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Robust.Shared.Prototypes; - -namespace Content.Shared.Damage.Prototypes; - -/// -/// Prototype for examinable damage messages. -/// -[Prototype] -public sealed partial class ExaminableDamagePrototype : IPrototype -{ - [IdDataField] - public string ID { get; private set; } = default!; - - /// - /// List of damage messages IDs sorted by severity. - /// First one describes fully intact entity. - /// Last one describes almost destroyed. - /// - [DataField("messages")] - public string[] Messages = {}; -} diff --git a/Resources/Prototypes/Damage/examine_messages.yml b/Resources/Prototypes/Damage/examine_messages.yml index 4523998094..91f838a436 100644 --- a/Resources/Prototypes/Damage/examine_messages.yml +++ b/Resources/Prototypes/Damage/examine_messages.yml @@ -1,9 +1,5 @@ -- type: examinableDamage +- type: localizedDataset id: WindowMessages - messages: - - comp-window-damaged-1 - - comp-window-damaged-2 - - comp-window-damaged-3 - - comp-window-damaged-4 - - comp-window-damaged-5 - - comp-window-damaged-6 + values: + prefix: comp-window-damaged- + count: 6 -- 2.52.0