From 5dbaef4e07ddaf8e5d11f374f4ec02086c4082aa Mon Sep 17 00:00:00 2001 From: mharis001 <34453221+mharis001@users.noreply.github.com> Date: Tue, 10 Sep 2019 00:30:56 -0400 Subject: [PATCH] Improve medical statemachine settings (#7154) * Improve medical statemachine settings * Multi-line condition and update fatal injury description * Check isPlayer in DeathAI transition Co-Authored-By: PabstMirror --- addons/medical_statemachine/Statemachine.hpp | 19 ++++------ addons/medical_statemachine/XEH_PREP.hpp | 1 + .../functions/fnc_conditionExecutionDeath.sqf | 8 ++-- .../functions/fnc_conditionSecondChance.sqf | 20 ++++++++++ addons/medical_statemachine/initSettings.sqf | 22 +++++++---- .../medical_statemachine/script_component.hpp | 4 ++ addons/medical_statemachine/stringtable.xml | 37 +++++-------------- 7 files changed, 61 insertions(+), 50 deletions(-) create mode 100644 addons/medical_statemachine/functions/fnc_conditionSecondChance.sqf diff --git a/addons/medical_statemachine/Statemachine.hpp b/addons/medical_statemachine/Statemachine.hpp index 1516c680e2..efeede18dd 100644 --- a/addons/medical_statemachine/Statemachine.hpp +++ b/addons/medical_statemachine/Statemachine.hpp @@ -3,7 +3,6 @@ class ACE_Medical_StateMachine { list = QUOTE(call EFUNC(common,getLocalUnits)); skipNull = 1; - class Default { onState = QFUNC(handleStateDefault); class Injury { @@ -44,7 +43,7 @@ class ACE_Medical_StateMachine { }; class Unconscious { onState = QFUNC(handleStateUnconscious); - onStateEntered = QUOTE([ARR_2(_this,(true))] call EFUNC(medical_status,setUnconscious)); + onStateEntered = QUOTE([ARR_2(_this,true)] call EFUNC(medical_status,setUnconscious)); class DeathAI { targetState = "Dead"; condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this}); @@ -53,7 +52,7 @@ class ACE_Medical_StateMachine { targetState = "Injured"; condition = QEFUNC(medical_status,hasStableVitals); events[] = {QEGVAR(medical,WakeUp)}; - onTransition = QUOTE([ARR_2(_this,(false))] call EFUNC(medical_status,setUnconscious)); + onTransition = QUOTE([ARR_2(_this,false)] call EFUNC(medical_status,setUnconscious)); }; class FatalTransitions { targetState = "CardiacArrest"; @@ -65,24 +64,18 @@ class ACE_Medical_StateMachine { }; }; class FatalInjury { - // Transition state for handling instant death + // Transition state for handling instant death from fatal injuries // This state raises the next transition in the same frame onStateEntered = QFUNC(enteredStateFatalInjury); - class DeathAI { - events[] = {QEGVAR(medical,FatalInjuryInstantTransition)}; - targetState = "Dead"; - condition = QUOTE(!isPlayer _this && {GVAR(fatalInjuryConditionAI)}); - }; class SecondChance { events[] = {QEGVAR(medical,FatalInjuryInstantTransition)}; targetState = "CardiacArrest"; - condition = QUOTE(GVAR(fatalInjuryCondition) > 0); + condition = QFUNC(conditionSecondChance); onTransition = QFUNC(transitionSecondChance); }; class Death { events[] = {QEGVAR(medical,FatalInjuryInstantTransition)}; targetState = "Dead"; - condition = "true"; }; }; class CardiacArrest { @@ -90,8 +83,10 @@ class ACE_Medical_StateMachine { onStateEntered = QFUNC(enteredStateCardiacArrest); onStateLeaving = QFUNC(leftStateCardiacArrest); class DeathAI { + // If an AI unit reanimates, they will immediately die upon entering unconsciousness if AI Unconsciousness is disabled + // As a result, we immediately kill the AI unit since cardiac arrest is effectively useless for it targetState = "Dead"; - condition = QUOTE(!isPlayer _this && {GVAR(fatalInjuryConditionAI)}); + condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this}); }; class Timeout { targetState = "Dead"; diff --git a/addons/medical_statemachine/XEH_PREP.hpp b/addons/medical_statemachine/XEH_PREP.hpp index 8e2725d3da..d8d0af8283 100644 --- a/addons/medical_statemachine/XEH_PREP.hpp +++ b/addons/medical_statemachine/XEH_PREP.hpp @@ -1,5 +1,6 @@ PREP(conditionCardiacArrestTimer); PREP(conditionExecutionDeath); +PREP(conditionSecondChance); PREP(enteredStateCardiacArrest); PREP(enteredStateDeath); PREP(enteredStateFatalInjury); diff --git a/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf b/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf index a409069fba..fe65aff964 100644 --- a/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: BaerMitUmlaut - * Condition for an execution caused death. + * Condition for an execution caused death (fatal injury received in cardiac arrest). * * Arguments: - * 0: The Unit + * 0: Unit * * Return Value: * None @@ -17,4 +17,6 @@ params ["_unit"]; -(GVAR(fatalInjuryCondition) < 2) && {!(_unit getVariable [QEGVAR(medical,deathBlocked), false])} +(isPlayer _unit && {GVAR(fatalInjuriesPlayer) != FATAL_INJURIES_NEVER} +|| {!isPlayer _unit && {GVAR(fatalInjuriesAI) != FATAL_INJURIES_NEVER}}) +&& {!(_unit getVariable [QEGVAR(medical,deathBlocked), false])} diff --git a/addons/medical_statemachine/functions/fnc_conditionSecondChance.sqf b/addons/medical_statemachine/functions/fnc_conditionSecondChance.sqf new file mode 100644 index 0000000000..247526eaa9 --- /dev/null +++ b/addons/medical_statemachine/functions/fnc_conditionSecondChance.sqf @@ -0,0 +1,20 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Condition for going into cardiac arrest upon receiving a fatal injury. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_statemachine_fnc_conditionSecondChance + * + * Public: No + */ + +params ["_unit"]; + +isPlayer _unit && {GVAR(fatalInjuriesPlayer) != FATAL_INJURIES_ALWAYS} || {!isPlayer _unit && {GVAR(fatalInjuriesAI) != FATAL_INJURIES_ALWAYS}} diff --git a/addons/medical_statemachine/initSettings.sqf b/addons/medical_statemachine/initSettings.sqf index 2dfe27463e..a47fa9c31b 100644 --- a/addons/medical_statemachine/initSettings.sqf +++ b/addons/medical_statemachine/initSettings.sqf @@ -1,18 +1,26 @@ [ - QGVAR(fatalInjuryCondition), + QGVAR(fatalInjuriesPlayer), "LIST", - [LSTRING(FatalInjuryCondition_DisplayName), LSTRING(FatalInjuryCondition_Description)], + [LSTRING(FatalInjuriesPlayer_DisplayName), LSTRING(FatalInjuriesPlayer_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory)], - [[0, 1, 2], [ELSTRING(common,Always), LSTRING(InCardiacArrest), ELSTRING(common,Never)], 0], + [ + [FATAL_INJURIES_ALWAYS, FATAL_INJURIES_CRDC_ARRST, FATAL_INJURIES_NEVER], + [ELSTRING(common,Always), LSTRING(InCardiacArrest), ELSTRING(common,Never)], + 0 + ], true ] call CBA_settings_fnc_init; [ - QGVAR(fatalInjuryConditionAI), - "CHECKBOX", - [LSTRING(FatalInjuryConditionAI_DisplayName), LSTRING(FatalInjuryConditionAI_Description)], + QGVAR(fatalInjuriesAI), + "LIST", + [LSTRING(FatalInjuriesAI_DisplayName), LSTRING(FatalInjuriesAI_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory)], - true, + [ + [FATAL_INJURIES_ALWAYS, FATAL_INJURIES_CRDC_ARRST, FATAL_INJURIES_NEVER], + [ELSTRING(common,Always), LSTRING(InCardiacArrest), ELSTRING(common,Never)], + 0 + ], true ] call CBA_settings_fnc_init; diff --git a/addons/medical_statemachine/script_component.hpp b/addons/medical_statemachine/script_component.hpp index fbde60be72..82ee57e12a 100644 --- a/addons/medical_statemachine/script_component.hpp +++ b/addons/medical_statemachine/script_component.hpp @@ -16,3 +16,7 @@ #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" + +#define FATAL_INJURIES_ALWAYS 0 +#define FATAL_INJURIES_CRDC_ARRST 1 +#define FATAL_INJURIES_NEVER 2 diff --git a/addons/medical_statemachine/stringtable.xml b/addons/medical_statemachine/stringtable.xml index 41b1a25903..8b5241ec0f 100644 --- a/addons/medical_statemachine/stringtable.xml +++ b/addons/medical_statemachine/stringtable.xml @@ -8,33 +8,17 @@ Состояния États - - Fatal Injury Player - Tödliche Spielerverletzungen - 致命傷プレイヤー - Смертельные ранения игрока - Blessure fatale des joueurs + + Player Fatal Injuries - - Controls when a player can receive a fatal injury. - Definiert wann ein Spieler tödliche Verletzungen bekommen kann - プレイヤーが致命傷から蘇生できるかどうか決定します - Определяет, когда игрок может получить смертельное ранение - Définit quand un joueur peut recevoir une blessure fatale. + + Controls when players can receive fatal injuries. A fatal injury is caused by significant damage to the head or body. - - AI Instant Death - Direkter Tod KI - AI の即死 - Мгновенная смерть ИИ - Mort instantanée de l'IA + + AI Fatal Injuries - - Controls if AI units are able to die instantly. - Legt fest, ob eine KI direkt sterben kann - AI が即死できるかどうか決定します - Определяет, сможет ли ИИ мгновенно умереть - Définit si les unités IA peuvent mourir instantanément. + + Controls when AI can receive fatal injuries. A fatal injury is caused by significant damage to the head or body.\nWhen set to "Always", this effectively produces "AI Instant Death" behaviour as AI will immediately die from any fatal injury.\nNOTE: Any mode other than "Always" requires AI Unconsciousness to be enabled. AI Unconsciousness @@ -53,10 +37,7 @@ AI無意識 - Allows AI to go unconscious instead of dying. - AI が即死ではなく気絶へ移行できるかどうか決定します。 - Permet aux unités IA de perdre connaissance au lieu de mourir. - Позволяет ИИ оставаться без сознания вместо смерти. + Controls whether AI can go unconscious instead of immediately dying.\nThis setting works together with the "AI Fatal Injuries" setting since, going into cardiac arrest requires that the unit is able to go unconscious.\nHowever, these settings are separated because units can go unconscious from critical vitals resulting from non-fatal injuries.\nIn essence, this means that in order to enable cardiac arrest for AI units, this setting must be enabled. Cardiac Arrest Time