Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Medical Statemachine - Improve edge case death handling #8788

Merged
merged 6 commits into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/medical_statemachine/Statemachine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = QUOTE(enteredStateUnconscious);
class DeathAI {
targetState = "Dead";
condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this});
Expand Down
1 change: 1 addition & 0 deletions addons/medical_statemachine/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ PREP(conditionSecondChance);
PREP(enteredStateCardiacArrest);
PREP(enteredStateDeath);
PREP(enteredStateFatalInjury);
PREP(enteredStateUnconscious);
PREP(handleStateCardiacArrest);
PREP(handleStateDefault);
PREP(handleStateInjured);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

params ["_unit"];
if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith {};
veteran29 marked this conversation as resolved.
Show resolved Hide resolved

// 10% possible variance in cardiac arrest time
private _time = GVAR(cardiacArrestTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@
*/

params ["_unit"];
if (isNull _unit) exitWith {};
if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith {};

//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);
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
*/

params ["_unit"];
if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) exitWith {};

[QEGVAR(medical,FatalInjuryInstantTransition), _unit] call CBA_fnc_localEvent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#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 {};

//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);
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -34,4 +33,3 @@ if (_timeDiff >= 1) then {
_timeLeft = _timeLeft - _timeDiff; // negative values are fine
_unit setVariable [QGVAR(cardiacArrestTimeLeft), _timeLeft];
};

Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions addons/medical_status/functions/fnc_setDead.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

// Kill the unit without changing visual apperance
private _prevDamage = _unit getHitPointDamage "HitHead";

Expand Down
4 changes: 2 additions & 2 deletions addons/medical_status/functions/fnc_setUnconsciousState.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* 1: Set unconscious <BOOL>
*
* Return Value:
* Success <BOOL>
* None
*
* Example:
* [player, true] call ace_medical_status_fnc_setUnconsciousState
Expand All @@ -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];

Expand Down