From 0a161319d2481c7c4e0e02098234d67fdddf7e97 Mon Sep 17 00:00:00 2001 From: Glowbal Date: Sun, 8 Feb 2015 10:25:03 +0100 Subject: [PATCH] Added initial draft of setUnconscious --- addons/medical/CfgEventHandlers.hpp | 6 + addons/medical/XEH_init.sqf | 2 - addons/medical/XEH_postInit.sqf | 22 +++ addons/medical/XEH_preInit.sqf | 9 +- .../medical/functions/fnc_setUnconscious.sqf | 143 ++++++++++++++++++ 5 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 addons/medical/XEH_postInit.sqf create mode 100644 addons/medical/functions/fnc_setUnconscious.sqf diff --git a/addons/medical/CfgEventHandlers.hpp b/addons/medical/CfgEventHandlers.hpp index a51c360577..8033dbe2cb 100644 --- a/addons/medical/CfgEventHandlers.hpp +++ b/addons/medical/CfgEventHandlers.hpp @@ -5,6 +5,12 @@ class Extended_PreInit_EventHandlers { }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; + class Extended_Init_EventHandlers { class CAManBase { class ADDON { diff --git a/addons/medical/XEH_init.sqf b/addons/medical/XEH_init.sqf index fe281f6814..4d92575f9b 100644 --- a/addons/medical/XEH_init.sqf +++ b/addons/medical/XEH_init.sqf @@ -1,12 +1,10 @@ #include "script_component.hpp" private ["_unit"]; - _unit = _this select 0; if !(local _unit) exitWith {}; -diag_log "running init"; _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}]; [_unit] call FUNC(init); diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf new file mode 100644 index 0000000000..8d576f5f0a --- /dev/null +++ b/addons/medical/XEH_postInit.sqf @@ -0,0 +1,22 @@ + +#include "script_component.hpp" + +[{ + { + if (!alive _x || !local _x) then { + GVAR(injuredUnitCollection) set [ _forEachIndex, ObjNull]; + } else { + [_x] call FUNC(handleUnitVitals); + + private "_pain"; + _pain = _X getvariable [QGVAR(pain), 0]; + if (_pain > 45) then { + if (random(1) > 0.6) then { + // [_X] call FUNC(setUnconsciousState); + }; + //[_X] call FUNC(playInjuredSound); + }; + }; + }foreach GVAR(injuredUnitCollection); + GVAR(injuredUnitCollection) = GVAR(injuredUnitCollection) - [ObjNull]; +}, 1, [] ] call CBA_fnc_addPerFrameHandler; diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index b896ddfcda..56cd67e249 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -3,13 +3,13 @@ ADDON = false; PREP(getTypeOfDamage); -PREP(handleAirway); +PREP(handleDamage_airway); PREP(handleDamage); PREP(handleDamage_advanced); PREP(handleDamage_basic); PREP(handleDamage_medium); -PREP(handleFractures); -PREP(handleInternalInjuries); +PREP(handleDamage_fractures); +PREP(handleDamage_internalInjuries); PREP(init); PREP(selectionNameToNumber); PREP(handleDamage_wounds); @@ -19,5 +19,8 @@ PREP(getBloodPressure); PREP(getBloodVolumeChange); PREP(getCardiacOutput); PREP(setCardiacArrest); +PREP(addToInjuredCollection); +PREP(setUnconscious); +GVAR(injuredUnitCollection) = []; ADDON = true; diff --git a/addons/medical/functions/fnc_setUnconscious.sqf b/addons/medical/functions/fnc_setUnconscious.sqf new file mode 100644 index 0000000000..f49e816e63 --- /dev/null +++ b/addons/medical/functions/fnc_setUnconscious.sqf @@ -0,0 +1,143 @@ +/** + * fn_setUnconsciousState.sqf + * @Descr: Sets a unit in the unconscious state + * @Author: Glowbal + * + * @Arguments: [unit OBJECT] + * @Return: void + * @PublicAPI: true + */ + +#include "script_component.hpp" + +private ["_unit", "_animState", "_originalPos", "_captiveSwitch", "_startingTime","_minWaitingTime"]; +_unit = _this select 0; + +if !(!(isNull _unit) && {(_unit isKindOf "CaManBase") && ([_unit] call EFUNC(common,isAwake))}) exitwith{}; + +// We only want this function to work on local machines +if (!local _unit) exitwith { + [[_unit], QUOTE(FUNC(setUnconsciousState)), _unit, false] call EFUNC(common,execRemoteFnc); +}; + +// Get rid of the object we are carrying, before we go unconscious. +[_unit, ObjNull, [0,0,0]] call EFUNC(common,carryObj); + +// Set the unit in the unconscious state. +_unit setvariable ["ACE_isUnconscious",true,true]; +_unit setUnconscious true; + +// If a unit has the launcher out, it will sometimes start selecting the primairy weapon while unconscious, +// therefor we force it to select the primairy weapon before going unconscious +if ((vehicle _unit) isKindOf "StaticWeapon") then { + moveOut _unit; + unassignVehicle _unit; + //_unit action ["eject", vehicle _unit]; +}; +if (animationState _unit in ["ladderriflestatic","laddercivilstatic"]) then { + _unit action ["ladderOff", (nearestBuilding _unit)]; +}; +if (vehicle _unit == _unit) then { + if (primaryWeapon _unit == "") then { + _unit addWeapon "ACE_fakeWeapon"; + }; + _unit selectWeapon (primaryWeapon _unit); + _unit switchMove ""; + _unit playmoveNow ""; +}; + +// We are storing the current animation, so we can use it later on when waking the unit up inside a vehicle +_animState = animationState _unit; +_originalPos = unitPos _unit; + +// Handle the on screen effects +if (isPlayer _unit) then { + //[] call EFUNC(common,closeAllDialogs_f); + //[true] call FUNC(effectBlackOut); + //["unconscious", true] call EFUNC(common,setDisableUserInputStatus); + //[false] call EFUNC(common,setVolume_f); +} else { + //_unit setUnitPos "DOWN"; + //[_unit, true] call EFUNC(common,disableAI_F); +}; + +// So the AI does not get stuck, we are moving the unit to a temp group on its own. +[_unit, true, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide_f); + +_captiveSwitch = false; // [_unit, true] call EFUNC(common,setCaptiveSwitch); +[_unit, [_unit] call EFUNC(common,getDeathAnim), 1, true] call EFUNC(common,doAnimation); + +_startingTime = time; +_minWaitingTime = (round(random(10)+5)); + +[{ + private ["_unit", "_vehicleOfUnit","_lockSwitch","_minWaitingTime", "_oldAnimation", "_captiveSwitch"]; + _args = _this select 0; + _unit = _args select 0; + _oldAnimation = _args select 1; + _captiveSwitch = _args select 2; + _originalPos = _args select 3; + _startingTime = _args select 4; + _minWaitingTime = _args select 5; + + // Since the unit is no longer alive, get rid of this PFH. + if (!alive _unit) exitwith { + // EXIT PFH + [(_this select 1)] call cba_fnc_removePerFrameHandler; + }; + + // In case the unit is no longer in an unconscious state, we are going to check if we can already reset the animation + if !(_unit getvariable ["ACE_isUnconscious",false]) exitwith { + // TODO, handle this with carry instead, so we can remove the PFH here. + // Wait until the unit isn't being carried anymore, so we won't end up with wierd animations + if !([_unit] call EFUNC(common,beingCarried)) then { + if (vehicle _unit == _unit) then { + [_unit,"amovppnemstpsnonwnondnon", 1] call EFUNC(common,doAnimation); + } else { + // Switch to the units original animation, assuming + // TODO: what if the unit switched vehicle? + [_unit, _oldAnimation, 1] call EFUNC(common,doAnimation); + }; + + // EXIT PFH + [(_this select 1)] call cba_fnc_removePerFrameHandler; + }; + }; + + // Ensure we are waiting at least a minimum period before checking if we can wake up the unit again, allows for temp knock outs + if ((time - _startingTime) >= _minWaitingTime) exitwith { + + // Wait until the unit is no longer unconscious + if (!([_unit] call FUNC(getUnconsciousCondition))) then { + // Reset the unit back to the previous captive state. + if (_captiveSwitch) then { + // [_unit, false] call EFUNC(common,setCaptiveSwitch); + }; + + // Swhich the unit back to its original group + [_unit, false, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide_f); + + // Reset any visual and audio effects for players, or enable everything again for AI. + if (isPlayer _unit) then { + //[false] call FUNC(effectBlackOut); + //[true] call EFUNC(common,setVolume_f); + //["unconscious", false] call EFUNC(common,setDisableUserInputStatus); + } else { + //[_unit, false] call EFUNC(common,disableAI_F); + //_unit setUnitPos _originalPos; // This is not position but stance (DOWN, MIDDLE, UP) + }; + + // Move unit out of unconscious state + _unit setvariable ["ACE_isUnconscious", false, true]; + _unit setUnconscious false; + }; + }; + + // A check to ensure that the animation is being played properly. + // TODO: Might no longer be necessary: Have to test this in MP. + if (vehicle _unit == _unit && {animationState _unit != "deadState" && animationState _unit != "unconscious"} && {(isNull ([_unit] call EFUNC(common,getCarriedBy)))} && (time - _startingTime >= 0.5)) then { + [_unit,([_unit] call FUNC(getDeathAnim)), 1, true] call EFUNC(common,doAnimation); // Reset animations if unit starts doing wierd things. + }; + +}, 0.1, [_unit,_animState, _captiveSwitch, _originalPos, _startingTime, _minWaitingTime] ] call CBA_fnc_addPerFrameHandler; +