diff --git a/addons/medical_statemachine/Statemachine.hpp b/addons/medical_statemachine/Statemachine.hpp index eecb6a236c..6508b4c34e 100644 --- a/addons/medical_statemachine/Statemachine.hpp +++ b/addons/medical_statemachine/Statemachine.hpp @@ -43,7 +43,7 @@ class ACE_Medical_StateMachine { }; class Unconscious { onState = QFUNC(handleStateUnconscious); - onStateEntered = QUOTE([ARR_2(_this,true)] call EFUNC(medical_status,setUnconsciousState)); + onStateEntered = QFUNC(enteredStateUnconscious); class DeathAI { targetState = "Dead"; condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this}); diff --git a/addons/medical_statemachine/XEH_PREP.hpp b/addons/medical_statemachine/XEH_PREP.hpp index 38d0cb573a..df481ae634 100644 --- a/addons/medical_statemachine/XEH_PREP.hpp +++ b/addons/medical_statemachine/XEH_PREP.hpp @@ -4,6 +4,7 @@ PREP(conditionSecondChance); PREP(enteredStateCardiacArrest); PREP(enteredStateDeath); PREP(enteredStateFatalInjury); +PREP(enteredStateUnconscious); PREP(handleStateCardiacArrest); PREP(handleStateDefault); PREP(handleStateInjured); diff --git a/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf index b2bcde8071..b0477cd120 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf @@ -17,6 +17,9 @@ */ params ["_unit"]; +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + WARNING_1("enteredStateCardiacArrest: State transition on dead or null unit - %1",_unit); +}; // 10% possible variance in cardiac arrest time private _time = GVAR(cardiacArrestTime); diff --git a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf index 913ffb075e..9d020719eb 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf @@ -16,13 +16,15 @@ */ params ["_unit"]; -if (isNull _unit) exitWith {}; +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + if ((_unit getVariable [QEGVAR(medical,causeOfDeath), ""]) == "#scripted") exitWith {}; + WARNING_1("enteredStateDeath: State transition on dead or null unit - %1",_unit); +}; //IGNORE_PRIVATE_WARNING ["_thisOrigin", "_thisTransition"]; // vars provided by CBA_statemachine -TRACE_3("enteredStateDeath",_this,_thisOrigin,_thisTransition); +TRACE_4("enteredStateDeath",_this,_thisOrigin,_thisTransition,CBA_missionTime); private _causeOfDeath = format ["%1:%2", _thisOrigin, _thisTransition]; private _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; -// could delay a frame here to fix the double killed EH, but we lose it being a "native" kill (scoreboard / rating) [_unit, _causeOfDeath, _instigator] call EFUNC(medical_status,setDead); diff --git a/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf b/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf index 04121b1c95..3a01912ebf 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateFatalInjury.sqf @@ -16,5 +16,8 @@ */ params ["_unit"]; +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + WARNING_1("enteredStateFatalInjury: State transition on dead or null unit - %1",_unit); +}; [QEGVAR(medical,FatalInjuryInstantTransition), _unit] call CBA_fnc_localEvent; diff --git a/addons/medical_statemachine/functions/fnc_enteredStateUnconscious.sqf b/addons/medical_statemachine/functions/fnc_enteredStateUnconscious.sqf new file mode 100644 index 0000000000..c35d3ab797 --- /dev/null +++ b/addons/medical_statemachine/functions/fnc_enteredStateUnconscious.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: GhostIsSpooky + * Handles a unit reaching the point of unconsciousness (calls for a status update). + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_statemachine_fnc_enteredStateUnconscious + * + * Public: No + */ +params ["_unit"]; + +if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith { + WARNING_1("enteredStateUnconscious: State transition on dead or null unit - %1",_unit); +}; + +//IGNORE_PRIVATE_WARNING ["_thisOrigin", "_thisTransition"]; // vars provided by CBA_statemachine +TRACE_4("enteredStateUnconscious",_this,_thisOrigin,_thisTransition,CBA_missionTime); + +[_unit, true] call EFUNC(medical_status,setUnconsciousState); diff --git a/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf index b9e49adfe3..d108148fc7 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf @@ -18,8 +18,7 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; -if (!local _unit) exitWith {}; +if (!alive _unit || {!local _unit}) exitWith {}; [_unit] call EFUNC(medical_vitals,handleUnitVitals); @@ -34,4 +33,3 @@ if (_timeDiff >= 1) then { _timeLeft = _timeLeft - _timeDiff; // negative values are fine _unit setVariable [QGVAR(cardiacArrestTimeLeft), _timeLeft]; }; - diff --git a/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf b/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf index f1fdada8dc..129a17a77f 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf @@ -18,8 +18,7 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; -if (!local _unit) exitWith {}; +if (!alive _unit || {!local _unit}) exitWith {}; if ([_unit] call EFUNC(medical_vitals,handleUnitVitals)) then { // returns true when update ran private _painLevel = GET_PAIN_PERCEIVED(_unit); diff --git a/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf b/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf index 6bdd3e07d3..dc2586803a 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf @@ -18,8 +18,7 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; -if (!local _unit) exitWith {}; +if (!alive _unit || {!local _unit}) exitWith {}; if ([_unit] call EFUNC(medical_vitals,handleUnitVitals)) then { // returns true when update ran private _painLevel = GET_PAIN_PERCEIVED(_unit); diff --git a/addons/medical_status/functions/fnc_setDead.sqf b/addons/medical_status/functions/fnc_setDead.sqf index 8fde3c5594..9568974919 100644 --- a/addons/medical_status/functions/fnc_setDead.sqf +++ b/addons/medical_status/functions/fnc_setDead.sqf @@ -26,6 +26,12 @@ _unit setVariable [QEGVAR(medical,causeOfDeath), _reason, true]; // Send a local event before death [QEGVAR(medical,death), [_unit]] call CBA_fnc_localEvent; +// Update the state machine if necessary (forced respawn, scripted death, etc) +private _unitState = [_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; +if (_unitState isNotEqualTo "Dead") then { + [_unit, EGVAR(medical,STATE_MACHINE), _unitState, "Dead"] call CBA_statemachine_fnc_manualTransition; +}; + // (#8803) Reenable damage if disabled to prevent having live units in dead state // Keep this after death event for compatibility with third party hooks if !(isDamageAllowed _unit) then { diff --git a/addons/medical_status/functions/fnc_setUnconsciousState.sqf b/addons/medical_status/functions/fnc_setUnconsciousState.sqf index 0a10a29a5d..f434356f07 100644 --- a/addons/medical_status/functions/fnc_setUnconsciousState.sqf +++ b/addons/medical_status/functions/fnc_setUnconsciousState.sqf @@ -9,7 +9,7 @@ * 1: Set unconscious * * Return Value: - * Success + * None * * Example: * [player, true] call ace_medical_status_fnc_setUnconsciousState @@ -21,7 +21,7 @@ params ["_unit", "_active"]; TRACE_2("setUnconsciousState",_unit,_active); // No change to make -if (_active isEqualTo IS_UNCONSCIOUS(_unit)) exitWith { TRACE_2("no change",_active,IS_UNCONSCIOUS(_unit)); }; +if (_active isEqualTo IS_UNCONSCIOUS(_unit) || {!alive _unit}) exitWith { TRACE_2("no change",_active,IS_UNCONSCIOUS(_unit)); }; _unit setVariable [VAR_UNCON, _active, true];