From: Doru991 <75124791+Doru991@users.noreply.github.com> Date: Fri, 15 Sep 2023 03:14:47 +0000 (+0300) Subject: Cyborg health alert and damage examining (#20084) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=eaecdb433613e5b308a0495f0c83e5967522553c;p=space-station-14.git Cyborg health alert and damage examining (#20084) * Option for alt health alert and no overlay * Fancy borg health indicator * Borg damage examine localization * EENENGHHHH ENNNGHHH * Requested code changes * Legal sound * Revert "Legal sound" This reverts commit 35715c88898aeb78dfe800319852c230395fdd7e. I misunderstood what Sloth meant * Annoying buzzer is back --- diff --git a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs index 4a5731a528..0836314dbc 100644 --- a/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs +++ b/Content.Client/UserInterface/Systems/DamageOverlays/DamageOverlayUiController.cs @@ -1,4 +1,4 @@ -using Content.Client.Alerts; +using Content.Client.Alerts; using Content.Shared.Damage; using Content.Shared.FixedPoint; using Content.Shared.Mobs; @@ -79,9 +79,15 @@ public sealed class DamageOverlayUiController : UIController damageable == null && !EntityManager.TryGetComponent(entity, out damageable)) return; - if (!_mobThresholdSystem.TryGetIncapThreshold(entity, out var foundThreshold, thresholds)) return; //this entity cannot die or crit!! + + if (!thresholds.ShowOverlays) + { + ClearOverlay(); + return; //this entity intentionally has no overlays + } + var critThreshold = foundThreshold.Value; _overlay.State = mobState.CurrentState; diff --git a/Content.Shared/Alert/AlertType.cs b/Content.Shared/Alert/AlertType.cs index 8ba35ae282..e0a7ac99f8 100644 --- a/Content.Shared/Alert/AlertType.cs +++ b/Content.Shared/Alert/AlertType.cs @@ -48,7 +48,8 @@ namespace Content.Shared.Alert Debug4, Debug5, Debug6, - SuitPower + SuitPower, + BorgHealth } } diff --git a/Content.Shared/Mobs/Components/MobThresholdsComponent.cs b/Content.Shared/Mobs/Components/MobThresholdsComponent.cs index 49481787d4..e97d3672a2 100644 --- a/Content.Shared/Mobs/Components/MobThresholdsComponent.cs +++ b/Content.Shared/Mobs/Components/MobThresholdsComponent.cs @@ -1,4 +1,5 @@ -using Content.Shared.FixedPoint; +using Content.Shared.Alert; +using Content.Shared.FixedPoint; using Content.Shared.Mobs.Systems; using Robust.Shared.GameStates; using Robust.Shared.Serialization; @@ -9,7 +10,7 @@ namespace Content.Shared.Mobs.Components; [Access(typeof(MobThresholdSystem))] public sealed partial class MobThresholdsComponent : Component { - [DataField("thresholds", required:true)] + [DataField("thresholds", required: true)] public SortedDictionary Thresholds = new(); [DataField("triggersAlerts")] @@ -18,6 +19,24 @@ public sealed partial class MobThresholdsComponent : Component [DataField("currentThresholdState")] public MobState CurrentThresholdState; + /// + /// The health alert that should be displayed for player controlled entities. + /// Used for alternate health alerts (silicons, for example) + /// + [DataField("stateAlertDict")] + public Dictionary StateAlertDict = new() + { + {MobState.Alive, AlertType.HumanHealth}, + {MobState.Critical, AlertType.HumanCrit}, + {MobState.Dead, AlertType.HumanDead}, + }; + + /// + /// Whether or not this entity should display damage overlays (robots don't feel pain, black out etc.) + /// + [DataField("showOverlays")] + public bool ShowOverlays = true; + /// /// Whether or not this entity can be revived out of a dead state. /// @@ -34,13 +53,25 @@ public sealed class MobThresholdsComponentState : ComponentState public MobState CurrentThresholdState; + public Dictionary StateAlertDict = new() + { + {MobState.Alive, AlertType.HumanHealth}, + {MobState.Critical, AlertType.HumanCrit}, + {MobState.Dead, AlertType.HumanDead}, + }; + + public bool ShowOverlays; + public bool AllowRevives; - public MobThresholdsComponentState(Dictionary unsortedThresholds, bool triggersAlerts, MobState currentThresholdState, bool allowRevives) + public MobThresholdsComponentState(Dictionary unsortedThresholds, bool triggersAlerts, MobState currentThresholdState, + Dictionary stateAlertDict, bool showOverlays, bool allowRevives) { UnsortedThresholds = unsortedThresholds; TriggersAlerts = triggersAlerts; CurrentThresholdState = currentThresholdState; + StateAlertDict = stateAlertDict; + ShowOverlays = showOverlays; AllowRevives = allowRevives; } } diff --git a/Content.Shared/Mobs/Systems/MobThresholdSystem.cs b/Content.Shared/Mobs/Systems/MobThresholdSystem.cs index 93e89c32b8..1cb32543eb 100644 --- a/Content.Shared/Mobs/Systems/MobThresholdSystem.cs +++ b/Content.Shared/Mobs/Systems/MobThresholdSystem.cs @@ -1,10 +1,11 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.Alert; 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; @@ -34,6 +35,8 @@ public sealed class MobThresholdSystem : EntitySystem args.State = new MobThresholdsComponentState(thresholds, component.TriggersAlerts, component.CurrentThresholdState, + component.StateAlertDict, + component.ShowOverlays, component.AllowRevives); } @@ -341,28 +344,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; + + dict.TryGetValue(MobState.Alive, out healthAlert); + dict.TryGetValue(MobState.Critical, out critAlert); + dict.TryGetValue(MobState.Dead, out deadAlert); + switch (currentMobState) { case MobState.Alive: { - var severity = _alerts.GetMinSeverity(AlertType.HumanHealth); + var severity = _alerts.GetMinSeverity(healthAlert); if (TryGetIncapPercentage(target, damageable.TotalDamage, out var percentage)) { severity = (short) MathF.Floor(percentage.Value.Float() * - _alerts.GetSeverityRange(AlertType.HumanHealth)); - severity += _alerts.GetMinSeverity(AlertType.HumanHealth); + _alerts.GetSeverityRange(healthAlert)); + severity += _alerts.GetMinSeverity(healthAlert); } - _alerts.ShowAlert(target, AlertType.HumanHealth, severity); + _alerts.ShowAlert(target, healthAlert, severity); break; } case MobState.Critical: { - _alerts.ShowAlert(target, AlertType.HumanCrit); + _alerts.ShowAlert(target, critAlert); break; } case MobState.Dead: { - _alerts.ShowAlert(target, AlertType.HumanDead); + _alerts.ShowAlert(target, deadAlert); break; } case MobState.Invalid: diff --git a/Resources/Audio/Machines/attributions.yml b/Resources/Audio/Machines/attributions.yml index 53cbc4748c..bbf4ea9ac0 100644 --- a/Resources/Audio/Machines/attributions.yml +++ b/Resources/Audio/Machines/attributions.yml @@ -41,4 +41,9 @@ - files: ["timer.ogg"] license: "CC-BY-SA-3.0" copyright: "Taken from /tg/station" - source: "https://github.com/tgstation/tgstation/blob/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0/sound/items/timer.ogg" \ No newline at end of file + source: "https://github.com/tgstation/tgstation/blob/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0/sound/items/timer.ogg" + +- files: ["warning_buzzer.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from TG station." + source: "https://github.com/tgstation/tgstation/blob/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0/sound/machines/warning-buzzer.ogg" \ No newline at end of file diff --git a/Resources/Audio/Machines/warning_buzzer.ogg b/Resources/Audio/Machines/warning_buzzer.ogg new file mode 100644 index 0000000000..55bb179f57 Binary files /dev/null and b/Resources/Audio/Machines/warning_buzzer.ogg differ diff --git a/Resources/Locale/en-US/health-examinable/health-examinable-silicon.ftl b/Resources/Locale/en-US/health-examinable/health-examinable-silicon.ftl new file mode 100644 index 0000000000..03eaf07a3b --- /dev/null +++ b/Resources/Locale/en-US/health-examinable/health-examinable-silicon.ftl @@ -0,0 +1,18 @@ +health-examinable-silicon-none = There is no obvious damage to be seen. + +health-examinable-silicon-Blunt-25 = [color=red]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } minor dents on { POSS-ADJ($target) } chassis.[/color] +health-examinable-silicon-Blunt-50 = [color=crimson]{ CAPITALIZE(POSS-ADJ($target)) } chassis is severely dented![/color] +health-examinable-silicon-Blunt-75 = [color=crimson]{ CAPITALIZE(POSS-ADJ($target)) } chassis is almost completely caved in![/color] + +health-examinable-silicon-Slash-10 = [color=red]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } some minor scratches.[/color] +health-examinable-silicon-Slash-25 = [color=red]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } significant scratches on { POSS-ADJ($target) } chassis.[/color] +health-examinable-silicon-Slash-50 = [color=crimson]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } major gashes across { POSS-ADJ($target) } plating![/color] +health-examinable-silicon-Slash-75 = [color=crimson]{ CAPITALIZE(POSS-ADJ($target)) } chassis is torn up![/color] + +health-examinable-silicon-Piercing-50 = [color=crimson]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } large holes all over { POSS-ADJ($target) } chassis![/color] + +health-examinable-silicon-Heat-25 = [color=orange]{ CAPITALIZE(SUBJECT($target)) } { CONJUGATE-HAVE($target) } superficial burns across { POSS-ADJ($target) } chassis.[/color] +health-examinable-silicon-Heat-50 = [color=orange]{ CAPITALIZE(POSS-ADJ($target)) } chassis is significantly charred.[/color] +health-examinable-silicon-Heat-75 = [color=orange]{ CAPITALIZE(POSS-ADJ($target)) } chassis is partially melted![/color] + +health-examinable-silicon-Shock-50 = [color=lightgoldenrodyellow]{ CAPITALIZE(POSS-ADJ($target)) } circuits seem partially fried![/color] diff --git a/Resources/Prototypes/Alerts/alerts.yml b/Resources/Prototypes/Alerts/alerts.yml index ce6b2d0510..e71a8ed381 100644 --- a/Resources/Prototypes/Alerts/alerts.yml +++ b/Resources/Prototypes/Alerts/alerts.yml @@ -178,6 +178,25 @@ minSeverity: 0 maxSeverity: 4 +- type: alert + id: BorgHealth + category: Health + icons: + - sprite: /Textures/Interface/Alerts/borg_alive.rsi + state: health0 + - sprite: /Textures/Interface/Alerts/borg_alive.rsi + state: health1 + - sprite: /Textures/Interface/Alerts/borg_alive.rsi + state: health2 + - sprite: /Textures/Interface/Alerts/borg_alive.rsi + state: health3 + - sprite: /Textures/Interface/Alerts/borg_alive.rsi + state: health4 + name: alerts-health-name + description: alerts-health-desc + minSeverity: 0 + maxSeverity: 4 + - type: alert id: BorgBattery category: Battery diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index fb58b5a644..25e4271b10 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -48,6 +48,18 @@ - type: MobThresholds thresholds: 0: Alive + 100: Dead + stateAlertDict: + Alive: BorgHealth + showOverlays: false + - type: HealthExaminable + examinableTypes: + - Blunt + - Slash + - Piercing + - Heat + - Shock + locPrefix: silicon - type: UserInterface interfaces: - key: enum.SiliconLawsUiKey.Key @@ -124,6 +136,15 @@ damageContainer: Inorganic - type: Destructible thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: + path: /Audio/Machines/warning_buzzer.ogg + params: + volume: 5 - trigger: !type:DamageTrigger damage: 100 diff --git a/Resources/Textures/Interface/Alerts/borg_alive.rsi/health0.png b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health0.png new file mode 100644 index 0000000000..b94d636d0f Binary files /dev/null and b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health0.png differ diff --git a/Resources/Textures/Interface/Alerts/borg_alive.rsi/health1.png b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health1.png new file mode 100644 index 0000000000..c58c73f604 Binary files /dev/null and b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health1.png differ diff --git a/Resources/Textures/Interface/Alerts/borg_alive.rsi/health2.png b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health2.png new file mode 100644 index 0000000000..2447ba0fe3 Binary files /dev/null and b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health2.png differ diff --git a/Resources/Textures/Interface/Alerts/borg_alive.rsi/health3.png b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health3.png new file mode 100644 index 0000000000..fd4e7ccde3 Binary files /dev/null and b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health3.png differ diff --git a/Resources/Textures/Interface/Alerts/borg_alive.rsi/health4.png b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health4.png new file mode 100644 index 0000000000..449d4428b8 Binary files /dev/null and b/Resources/Textures/Interface/Alerts/borg_alive.rsi/health4.png differ diff --git a/Resources/Textures/Interface/Alerts/borg_alive.rsi/meta.json b/Resources/Textures/Interface/Alerts/borg_alive.rsi/meta.json new file mode 100644 index 0000000000..048a7bbda1 --- /dev/null +++ b/Resources/Textures/Interface/Alerts/borg_alive.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Original from https://github.com/tgstation/tgstation/blob/42ebbb4202b472cf94561974a30e00a0b00e11bc/icons/mob/screen1_robot.dmi, edited by @Doru991", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "health0" + }, + { + "name": "health1" + }, + { + "name": "health2" + }, + { + "name": "health3" + }, + { + "name": "health4" + } + ] +}