mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Medical Statemachine - Improve edge case death handling (#8788)
* fix #8772 * add WARNING for dead/null units * fix macro * improve warnings * handle scripted death without warnings Co-authored-by: PabstMirror <pabstmirror@gmail.com> Co-authored-by: PabstMirror <pabstmirror@gmail.com>
This commit is contained in:
parent
90ebe08012
commit
9209fedcf7
@ -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});
|
||||
|
@ -4,6 +4,7 @@ PREP(conditionSecondChance);
|
||||
PREP(enteredStateCardiacArrest);
|
||||
PREP(enteredStateDeath);
|
||||
PREP(enteredStateFatalInjury);
|
||||
PREP(enteredStateUnconscious);
|
||||
PREP(handleStateCardiacArrest);
|
||||
PREP(handleStateDefault);
|
||||
PREP(handleStateInjured);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 <OBJECT>
|
||||
*
|
||||
* 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);
|
@ -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];
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -9,7 +9,7 @@
|
||||
* 1: Set unconscious <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* Success <BOOL>
|
||||
* 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];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user