]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Health alert tweaks (#20557)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Thu, 28 Sep 2023 14:05:42 +0000 (10:05 -0400)
committerGitHub <noreply@github.com>
Thu, 28 Sep 2023 14:05:42 +0000 (07:05 -0700)
Content.Shared/Mobs/Systems/MobThresholdSystem.cs
Resources/Textures/Interface/Alerts/human_alive.rsi/health0.png
Resources/Textures/Interface/Alerts/human_alive.rsi/health1.png
Resources/Textures/Interface/Alerts/human_alive.rsi/health2.png
Resources/Textures/Interface/Alerts/human_alive.rsi/health3.png
Resources/Textures/Interface/Alerts/human_alive.rsi/health4.png

index 1cb32543ebbd212173f7be694660d6c63931ee7c..f34240d8fe3738fd360083e8c957cc9e4cad31d0 100644 (file)
@@ -5,7 +5,6 @@ using Content.Shared.Damage;
 using Content.Shared.FixedPoint;
 using Content.Shared.Mobs.Components;
 using Robust.Shared.GameStates;
-using Robust.Shared.Utility;
 
 namespace Content.Shared.Mobs.Systems;
 
@@ -52,6 +51,38 @@ public sealed class MobThresholdSystem : EntitySystem
 
     #region Public API
 
+    /// <summary>
+    /// Gets the next available state for a mob.
+    /// </summary>
+    /// <param name="target">Target entity</param>
+    /// <param name="mobState">Supplied MobState</param>
+    /// <param name="nextState">The following MobState. Can be null if there isn't one.</param>
+    /// <param name="thresholdsComponent">Threshold Component Owned by the target</param>
+    /// <returns>True if the next mob state exists</returns>
+    public bool TryGetNextState(
+        EntityUid target,
+        MobState mobState,
+        [NotNullWhen(true)] out MobState? nextState,
+        MobThresholdsComponent? thresholdsComponent = null)
+    {
+        nextState = null;
+        if (!Resolve(target, ref thresholdsComponent))
+            return false;
+
+        MobState? min = null;
+        foreach (var state in thresholdsComponent.Thresholds.Values)
+        {
+            if (state <= mobState)
+                continue;
+
+            if (min == null || state < min)
+                min = state;
+        }
+
+        nextState = min;
+        return nextState != null;
+    }
+
     /// <summary>
     /// Get the Damage Threshold for the appropriate state if it exists
     /// </summary>
@@ -261,7 +292,7 @@ public sealed class MobThresholdSystem : EntitySystem
             threshold.Thresholds.Remove(damageThreshold);
         }
         threshold.Thresholds[damage] = mobState;
-        Dirty(threshold);
+        Dirty(target, threshold);
         VerifyThresholds(target, threshold);
     }
 
@@ -291,7 +322,7 @@ public sealed class MobThresholdSystem : EntitySystem
         if (!Resolve(uid, ref component, false))
             return;
         component.AllowRevives = val;
-        Dirty(component);
+        Dirty(uid, component);
         VerifyThresholds(uid, component);
     }
 
@@ -344,42 +375,37 @@ public sealed class MobThresholdSystem : EntitySystem
         if (!threshold.TriggersAlerts)
             return;
 
-        var dict = threshold.StateAlertDict;
-        var healthAlert = AlertType.HumanHealth;
-        var critAlert = AlertType.HumanCrit;
-        var deadAlert = AlertType.HumanDead;
+        if (!threshold.StateAlertDict.TryGetValue(currentMobState, out var currentAlert))
+        {
+            Log.Error($"No alert alert for mob state {currentMobState} for entity {ToPrettyString(target)}");
+            return;
+        }
 
-        dict.TryGetValue(MobState.Alive, out healthAlert);
-        dict.TryGetValue(MobState.Critical, out critAlert);
-        dict.TryGetValue(MobState.Dead, out deadAlert);
+        if (!_alerts.TryGet(currentAlert, out var alertPrototype))
+        {
+            Log.Error($"Invalid alert type {currentAlert}");
+            return;
+        }
 
-        switch (currentMobState)
+        if (alertPrototype.SupportsSeverity)
         {
-            case MobState.Alive:
+            var severity = _alerts.GetMinSeverity(currentAlert);
+            if (TryGetNextState(target, currentMobState, out var nextState, threshold) &&
+                TryGetPercentageForState(target, nextState.Value, damageable.TotalDamage, out var percentage))
             {
-                var severity = _alerts.GetMinSeverity(healthAlert);
-                if (TryGetIncapPercentage(target, damageable.TotalDamage, out var percentage))
-                {
-                    severity = (short) MathF.Floor(percentage.Value.Float() *
-                                                   _alerts.GetSeverityRange(healthAlert));
-                    severity += _alerts.GetMinSeverity(healthAlert);
-                }
-                _alerts.ShowAlert(target, healthAlert, severity);
-                break;
-            }
-            case MobState.Critical:
-            {
-                _alerts.ShowAlert(target, critAlert);
-                break;
-            }
-            case MobState.Dead:
-            {
-                _alerts.ShowAlert(target, deadAlert);
-                break;
+                percentage = FixedPoint2.Clamp(percentage.Value, 0, 1);
+
+                severity = (short) MathF.Round(
+                    MathHelper.Lerp(
+                        _alerts.GetMinSeverity(currentAlert),
+                        _alerts.GetMaxSeverity(currentAlert),
+                        percentage.Value.Float()));
             }
-            case MobState.Invalid:
-            default:
-                throw new ArgumentOutOfRangeException(nameof(currentMobState), currentMobState, null);
+            _alerts.ShowAlert(target, currentAlert, severity);
+        }
+        else
+        {
+            _alerts.ShowAlert(target, currentAlert);
         }
     }
 
index cce1b027b6101b060904679943dcbe32610f9910..6c9b54e52e29d1909a41d0562da1efb4eba88035 100644 (file)
Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health0.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health0.png differ
index 2ec0eb65515ba5b665988c0d2333bb717e256065..186d07386ec845d1b7f0e5174546f06f38cda0e6 100644 (file)
Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health1.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health1.png differ
index 4fa9ffeccc324cbd18cd79aa7fa5c8a5a9a8ad4f..6463eb386facd0e5a56bcbca291eb2ecfbf5248d 100644 (file)
Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health2.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health2.png differ
index 0daa1136c41a6b3f219cc4aad7e09c7d7a24639d..d7b8d559ef3433d885a1fa0b387f43bb67af0d96 100644 (file)
Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health3.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health3.png differ
index ea55a429b2415d560556620a05de0fe6a5b3b640..9ae49ead79fb7cec528dcbaf4ab1b9b43a2d45e8 100644 (file)
Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health4.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health4.png differ