diff --git a/addons/medical/XEH_PREP.hpp b/addons/medical/XEH_PREP.hpp index 8cdc7feecf..dcbb9b016a 100644 --- a/addons/medical/XEH_PREP.hpp +++ b/addons/medical/XEH_PREP.hpp @@ -1,3 +1,5 @@ PREP(addDamageToUnit); PREP(adjustPainLevel); +PREP(deserializeState); +PREP(serializeState); PREP(setUnconscious); diff --git a/addons/medical/functions/fnc_deserializeState.sqf b/addons/medical/functions/fnc_deserializeState.sqf new file mode 100644 index 0000000000..0fbd796073 --- /dev/null +++ b/addons/medical/functions/fnc_deserializeState.sqf @@ -0,0 +1,98 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut + * Deserializes the medical state of a unit and applies it. + * + * Arguments: + * 0: Unit + * 1: State as JSON + * + * Return Value: + * None + * + * Example: + * [player, _json] call ace_medical_fnc_deserializeState + * + * Public: Yes + */ +params [["_unit", objNull, [objNull]], ["_json", "{}", [""]]]; + +if (isNull _unit) exitWith {}; +if (!local _unit) exitWith { ERROR_1("unit [%1] is not local",_unit) }; + +// If unit is not initialized yet, wait until event is raised +if !(_unit getVariable [QGVAR(initialized), false]) exitWith { + [QEGVAR(medical_status,initialized), { + params ["_unit"]; + _thisArgs params ["_target"]; + + if (_unit == _target) then { + _thisArgs call FUNC(deserializeState); + [_thisType, _thisId] call CBA_fnc_removeEventHandler; + }; + }, _this] call CBA_fnc_addEventHandlerArgs; +}; + +private _state = [_json] call CBA_fnc_parseJSON; + +// Set medical variables +{ + _x params ["_var", "_default"]; + private _value = _state getVariable _x; + + // Treat null as nil + if (_value isEqualTo objNull) then { + _value = _default; + }; + + _unit setVariable [_var, _value, true]; +} forEach [ + [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME], + [VAR_HEART_RATE, DEFAULT_HEART_RATE], + [VAR_BLOOD_PRESS, [80, 120]], + [VAR_PERIPH_RES, DEFAULT_PERIPH_RES], + // State transition should handle this + // [VAR_CRDC_ARRST, false], + [VAR_HEMORRHAGE, 0], + [VAR_PAIN, 0], + [VAR_IN_PAIN, false], + [VAR_PAIN_SUPP, 0], + [VAR_OPEN_WOUNDS, []], + [VAR_BANDAGED_WOUNDS, []], + [VAR_STITCHED_WOUNDS, []], + [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES], + // State transition should handle this + // [VAR_UNCON, false], + [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES], + [QEGVAR(medical,occludedMedications), nil], + [QEGVAR(medical,ivBags), nil], + [QEGVAR(medical,triageLevel), 0], + [QEGVAR(medical,triageCard), []], + [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]] + // Offset needs to be converted + // [VAR_MEDICATIONS, []] +]; + +// Reset timers +_unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; + +// Convert medications offset to time +private _medications = _state getVariable [VAR_MEDICATIONS, []]; +{ + _x set [1, _x#1 + CBA_missionTime]; +} forEach _medications; +_unit setVariable [VAR_MEDICATIONS, _medications, true]; + +// Update effects +[_unit] call EFUNC(medical_engine,updateDamageEffects); +[_unit] call EFUNC(medical_status,updateWoundBloodLoss); + +// Transition within statemachine +private _currentState = [_unit, GVAR(STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; +private _targetState = _state getVariable [QGVAR(statemachineState), "Default"]; +[_unit, GVAR(STATE_MACHINE), _currentState, _targetState] call CBA_statemachine_fnc_manualTransition; + +// Manually call wake up tranisition if necessary +if (_currentState in ["Unconscious", "CardiacArrest"] && {_targetState in ["Default", "Injured"]}) then { + [_unit, false] call EFUNC(medical_status,setUnconsciousState); +}; diff --git a/addons/medical/functions/fnc_serializeState.sqf b/addons/medical/functions/fnc_serializeState.sqf new file mode 100644 index 0000000000..0e1a868a37 --- /dev/null +++ b/addons/medical/functions/fnc_serializeState.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut + * Serializes the medical state of a unit into a string. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Serialized state as JSON string + * + * Example: + * [player] call ace_medical_fnc_serializeState + * + * Public: Yes + */ +params [["_unit", objNull, [objNull]]]; + +private _state = [] call CBA_fnc_createNamespace; + +// For variables, see: EFUNC(medical_status,initUnit) +{ + _x params ["_var"]; + _state setVariable [_var, _unit getVariable _x]; +} forEach [ + [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME], + [VAR_HEART_RATE, DEFAULT_HEART_RATE], + [VAR_BLOOD_PRESS, [80, 120]], + [VAR_PERIPH_RES, DEFAULT_PERIPH_RES], + // State transition should handle this + // [VAR_CRDC_ARRST, false], + [VAR_HEMORRHAGE, 0], + [VAR_PAIN, 0], + [VAR_IN_PAIN, false], + [VAR_PAIN_SUPP, 0], + [VAR_OPEN_WOUNDS, []], + [VAR_BANDAGED_WOUNDS, []], + [VAR_STITCHED_WOUNDS, []], + [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES], + // State transition should handle this + // [VAR_UNCON, false], + [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES], + [QEGVAR(medical,occludedMedications), nil], + [QEGVAR(medical,ivBags), nil], + [QEGVAR(medical,triageLevel), 0], + [QEGVAR(medical,triageCard), []], + [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]] + // Time needs to be converted + // [VAR_MEDICATIONS, []] +]; + +// Convert medications time to offset +private _medications = _unit getVariable [VAR_MEDICATIONS, []]; +{ + _x set [1, _x#1 - CBA_missionTime]; +} forEach _medications; +_state setVariable [VAR_MEDICATIONS, _medications]; + +// Medical statemachine state +private _currentState = [_unit, GVAR(STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; +_state setVariable [QGVAR(statemachineState), _currentState]; + +// Serialize & return +[_state] call CBA_fnc_encodeJSON diff --git a/addons/medical_status/functions/fnc_initUnit.sqf b/addons/medical_status/functions/fnc_initUnit.sqf index 4700d78393..73ff2ce8b6 100644 --- a/addons/medical_status/functions/fnc_initUnit.sqf +++ b/addons/medical_status/functions/fnc_initUnit.sqf @@ -80,5 +80,7 @@ if (_isRespawn) then { [{ params ["_unit"]; TRACE_3("Unit Init",_unit,local _unit,typeOf _unit); + + _unit setVariable [QEGVAR(medical,initialized), true, true]; [QGVAR(initialized), [_unit]] call CBA_fnc_localEvent; }, [_unit], 0.5] call CBA_fnc_waitAndExecute;