mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Add handle revive and Unconscious states
This commit is contained in:
parent
d0236a007a
commit
2daee60d0c
@ -76,13 +76,13 @@ class ACE_Medical_StateMachine {
|
||||
};
|
||||
class TimerRanOut {
|
||||
targetState = "Dead";
|
||||
condition = "timerValue >= maxReviveTime";
|
||||
condition = "";
|
||||
events[] = {"ReviveTimer"};
|
||||
onTransition = "";
|
||||
};
|
||||
class FatalTransitions {
|
||||
targetState = "Dead";
|
||||
condition = "killOnFatalDamageInRevive && inReviveState >= 10";
|
||||
condition = QGVAR(killOnFatalDamageInRevive);
|
||||
events[] = {"FatalInjury"};
|
||||
};
|
||||
};
|
||||
|
24
addons/medical/functions/fnc_enteredReviveState.sqf
Normal file
24
addons/medical/functions/fnc_enteredReviveState.sqf
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
private _reviveVal = _unit getVariable [QGVAR(enableRevive), GVAR(enableRevive)];
|
||||
if (_reviveVal == 1 && {[_unit] call EFUNC(common,isPlayer)} || _reviveVal == 2) then {
|
||||
if (_unit getVariable [QGVAR(inReviveState), false]) exitWith {
|
||||
// Error, already in revive state
|
||||
false;
|
||||
};
|
||||
|
||||
private _lifesLeft = _unit getVariable[QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives)];
|
||||
if (GVAR(amountOfReviveLives) > 0 && _lifesLeft == 0) exitWith {
|
||||
[_unit, "NoLives", []] call FUNC(stateEvent);
|
||||
};
|
||||
|
||||
_unit setVariable [QGVAR(inReviveState), true, true];
|
||||
_unit setVariable [QGVAR(reviveStartTime), CBA_missionTime];
|
||||
[_unit, true] call FUNC(setUnconscious);
|
||||
} else {
|
||||
[_unit, "NoLives", []] call FUNC(stateEvent);
|
||||
};
|
@ -20,95 +20,4 @@
|
||||
|
||||
params ["_unit", "_event", "_args"];
|
||||
|
||||
private ["_animState", "_originalPos", "_startingTime", "_isDead"];
|
||||
//params ["_unit", ["_set", true], ["_minWaitingTime", DEFAULT_DELAY], ["_force", false]];
|
||||
|
||||
if !(!(isNull _unit) && {(_unit isKindOf "CAManBase") && ([_unit] call EFUNC(common,isAwake))}) exitWith{
|
||||
// TODO log error, already in an unconsicous state or dead?
|
||||
};
|
||||
|
||||
_unit setVariable ["ACE_isUnconscious", true, true];
|
||||
// Disabled to not run with the 1.62 vanilla medical changes.
|
||||
// _unit setUnconscious true;
|
||||
|
||||
// Ensure the map is closed when entering the unconscious state
|
||||
if (_unit == ACE_player) then {
|
||||
if (visibleMap) then {openMap false};
|
||||
while {dialog} do {
|
||||
closeDialog 0;
|
||||
};
|
||||
};
|
||||
|
||||
// if we have unconsciousness for AI disabled, we will kill the unit instead
|
||||
_isDead = false;
|
||||
if (!([_unit, GVAR(remoteControlledAI)] call EFUNC(common,isPlayer)) && !_force) then {
|
||||
_enableUncon = _unit getVariable [QGVAR(enableUnconsciousnessAI), GVAR(enableUnconsciousnessAI)];
|
||||
if (_enableUncon == 0 or {_enableUncon == 1 and (random 1) < 0.5}) then {
|
||||
//[_unit, true] call FUNC(setDead);
|
||||
// TODO raise fatal event
|
||||
_isDead = true;
|
||||
};
|
||||
};
|
||||
if (_isDead) exitWith {};
|
||||
|
||||
// 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 {
|
||||
[_unit] call EFUNC(common,unloadPerson);
|
||||
};
|
||||
if (animationState _unit in ["ladderriflestatic","laddercivilstatic"]) then {
|
||||
_unit action ["ladderOff", (nearestBuilding _unit)];
|
||||
};
|
||||
if (vehicle _unit == _unit) then {
|
||||
if (primaryWeapon _unit == "") then {
|
||||
_unit addWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
_unit selectWeapon (primaryWeapon _unit);
|
||||
};
|
||||
|
||||
// We are storing the current animation, so we can use it later on when waking the unit up inside a vehicle
|
||||
if (vehicle _unit != _unit) then {
|
||||
_unit setVariable [QGVAR(vehicleAwakeAnim), [(vehicle _unit), (animationState _unit)]];
|
||||
};
|
||||
|
||||
//Save current stance:
|
||||
_originalPos = unitPos _unit;
|
||||
|
||||
_unit setUnitPos "DOWN";
|
||||
[_unit, true] call EFUNC(common,disableAI);
|
||||
|
||||
// So the AI does not get stuck, we are moving the unit to a temp group on its own.
|
||||
//Unconscious units shouldn't be put in another group #527:
|
||||
if (GVAR(moveUnitsFromGroupOnUnconscious)) then {
|
||||
[_unit, true, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide);
|
||||
};
|
||||
// Delay Unconscious so the AI dont instant stop shooting on the unit #3121
|
||||
if (GVAR(delayUnconCaptive) == 0) then {
|
||||
[_unit, "setCaptive", "ace_unconscious", true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
[{
|
||||
params ["_unit"];
|
||||
if (_unit getVariable ["ACE_isUnconscious", false]) then {
|
||||
[_unit, "setCaptive", "ace_unconscious", true] call EFUNC(common,statusEffect_set);
|
||||
};
|
||||
},[_unit], GVAR(delayUnconCaptive)] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
|
||||
_anim = [_unit] call EFUNC(common,getDeathAnim);
|
||||
[_unit, _anim, 1, true] call EFUNC(common,doAnimation);
|
||||
[{
|
||||
params ["_unit", "_anim"];
|
||||
if ((_unit getVariable "ACE_isUnconscious") and (animationState _unit != _anim)) then {
|
||||
[_unit, _anim, 2, true] call EFUNC(common,doAnimation);
|
||||
};
|
||||
}, [_unit, _anim], 0.5, 0] call CBA_fnc_waitAndExecute;
|
||||
|
||||
_startingTime = CBA_missionTime;
|
||||
|
||||
// gets started in the handle unconscious state
|
||||
// [DFUNC(unconsciousPFH), 0.1, [_unit, _originalPos, _startingTime, _minWaitingTime, false, vehicle _unit isKindOf "ParachuteBase"] ] call CBA_fnc_addPerFrameHandler;
|
||||
|
||||
// unconscious can't talk
|
||||
[_unit, "isUnconscious"] call EFUNC(common,muteUnit);
|
||||
|
||||
["ace_unconscious", [_unit, true]] call CBA_fnc_globalEvent;
|
||||
[_unit, true] call FUNC(setUnconscious);
|
||||
|
@ -3,12 +3,11 @@
|
||||
|
||||
params ["_unit", "_stateName", "_lastTime"];
|
||||
|
||||
|
||||
// If the unit died the loop is finished
|
||||
if (!alive _unit) exitWith {};
|
||||
|
||||
// If locality changed, broadcast the last medical state and finish the local loop
|
||||
if (!local _unit) exitWith {
|
||||
if (!local _unit) eexitWith{
|
||||
if (GVAR(level) >= 2) then {
|
||||
_unit setVariable [QGVAR(heartRate), _unit getVariable [QGVAR(heartRate), 80], true];
|
||||
_unit setVariable [QGVAR(bloodPressure), _unit getVariable [QGVAR(bloodPressure), [80, 120]], true];
|
||||
@ -16,6 +15,38 @@ if (!local _unit) exitWith {
|
||||
_unit setVariable [QGVAR(bloodVolume), _unit getVariable [QGVAR(bloodVolume), 100], true];
|
||||
};
|
||||
|
||||
private _startTime = _unit getVariable [QGVAR(reviveStartTime), 0];
|
||||
|
||||
// If we are in revive state in a blown up vehicle, try to unload so that people can access the body
|
||||
if ((alive _unit) && {(vehicle _unit) != _unit} && {!alive (vehicle _unit)}) then {
|
||||
TRACE_2("Unloading", _unit, vehicle _unit);
|
||||
[_unit] call EFUNC(common,unloadPerson);
|
||||
};
|
||||
|
||||
// Revive timer ran out
|
||||
if (GVAR(maxReviveTime) > 0 && {CBA_missionTime - _startTime > GVAR(maxReviveTime)}) exitWith
|
||||
[_unit, "ReviveTimer", []] call FUNC(stateEvent);
|
||||
_unit setVariable [QGVAR(inReviveState), nil, true];
|
||||
_unit setVariable [QGVAR(reviveStartTime), nil];
|
||||
};
|
||||
|
||||
// If the unit was taken out from revive state, exit the loop
|
||||
if !(_unit getVariable [QGVAR(inReviveState), false]) exitWith {
|
||||
// Revived without dieing, so in case we have lifes, remove one.
|
||||
if (GVAR(amountOfReviveLives) > 0) then {
|
||||
_lifesLeft = _unit getVariable[QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives)];
|
||||
_unit setVariable [QGVAR(amountOfReviveLives), _lifesLeft - 1, true];
|
||||
};
|
||||
_unit setVariable [QGVAR(reviveStartTime), nil];
|
||||
};
|
||||
|
||||
// Remove heartbeat
|
||||
if (GVAR(level) >= 2) then {
|
||||
if (_unit getVariable [QGVAR(heartRate), 60] > 0) then {
|
||||
_unit setVariable [QGVAR(heartRate), 0];
|
||||
};
|
||||
};
|
||||
|
||||
[_unit, CBA_missionTime - _lastTime] call FUNC(handleUnitVitals);
|
||||
|
||||
private _pain = _unit getVariable [QGVAR(pain), 0];
|
||||
|
127
addons/medical/functions/fnc_setUnconscious.sqf
Normal file
127
addons/medical/functions/fnc_setUnconscious.sqf
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Author: Glowbal
|
||||
* Sets a unit in the unconscious state.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The unit that will be put in an unconscious state <OBJECT>
|
||||
* 1: Set unconsciouns <BOOL> (default: true)
|
||||
* 2: Minimum unconscious time <NUMBER> (default: (round(random(10)+5)))
|
||||
* 3: Force AI Unconscious (skip random death chance) <BOOL> (default: false)
|
||||
*
|
||||
* ReturnValue:
|
||||
* nil
|
||||
*
|
||||
* Example:
|
||||
* [bob, true] call ace_medical_fnc_setUnconscious;
|
||||
*
|
||||
* Public: yes
|
||||
*/
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
#define DEFAULT_DELAY (round(random(10)+5))
|
||||
|
||||
// only run this after the settings are initialized
|
||||
if !(EGVAR(common,settingsInitFinished)) exitWith {
|
||||
EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setUnconscious), _this];
|
||||
};
|
||||
|
||||
private ["_animState", "_originalPos", "_startingTime", "_isDead"];
|
||||
params ["_unit", ["_set", true], ["_minWaitingTime", DEFAULT_DELAY], ["_force", false]];
|
||||
|
||||
// No change, fuck off. (why is there no xor?)
|
||||
if (_set isEqualTo (_unit getVariable ["ACE_isUnconscious", false])) exitWith {};
|
||||
|
||||
if !(_set) exitWith {
|
||||
_unit setVariable ["ACE_isUnconscious", false, true];
|
||||
};
|
||||
|
||||
if !(!(isNull _unit) && {(_unit isKindOf "CAManBase") && ([_unit] call EFUNC(common,isAwake))}) exitWith{};
|
||||
|
||||
if (!local _unit) exitWith {
|
||||
[QGVAR(setUnconscious), [_unit, _set, _minWaitingTime, _force], _unit] call CBA_fnc_targetEvent;
|
||||
};
|
||||
|
||||
_unit setVariable ["ACE_isUnconscious", true, true];
|
||||
_unit setUnconscious true;
|
||||
|
||||
if (_unit == ACE_player) then {
|
||||
if (visibleMap) then {openMap false};
|
||||
while {dialog} do {
|
||||
closeDialog 0;
|
||||
};
|
||||
};
|
||||
|
||||
// if we have unconsciousness for AI disabled, we will kill the unit instead
|
||||
_isDead = false;
|
||||
if (!([_unit, GVAR(remoteControlledAI)] call EFUNC(common,isPlayer)) && !_force) then {
|
||||
_enableUncon = _unit getVariable [QGVAR(enableUnconsciousnessAI), GVAR(enableUnconsciousnessAI)];
|
||||
if (_enableUncon == 0 or {_enableUncon == 1 and (random 1) < 0.5}) then {
|
||||
[_unit, true] call FUNC(setDead);
|
||||
_isDead = true;
|
||||
};
|
||||
};
|
||||
if (_isDead) exitWith {};
|
||||
|
||||
// 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 {
|
||||
[_unit] call EFUNC(common,unloadPerson);
|
||||
};
|
||||
if (animationState _unit in ["ladderriflestatic","laddercivilstatic"]) then {
|
||||
_unit action ["ladderOff", (nearestBuilding _unit)];
|
||||
};
|
||||
if (vehicle _unit == _unit) then {
|
||||
if (primaryWeapon _unit == "") then {
|
||||
_unit addWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
_unit selectWeapon (primaryWeapon _unit);
|
||||
};
|
||||
|
||||
// We are storing the current animation, so we can use it later on when waking the unit up inside a vehicle
|
||||
if (vehicle _unit != _unit) then {
|
||||
_unit setVariable [QGVAR(vehicleAwakeAnim), [(vehicle _unit), (animationState _unit)]];
|
||||
};
|
||||
|
||||
//Save current stance:
|
||||
_originalPos = unitPos _unit;
|
||||
|
||||
_unit setUnitPos "DOWN";
|
||||
[_unit, true] call EFUNC(common,disableAI);
|
||||
|
||||
// So the AI does not get stuck, we are moving the unit to a temp group on its own.
|
||||
//Unconscious units shouldn't be put in another group #527:
|
||||
if (GVAR(moveUnitsFromGroupOnUnconscious)) then {
|
||||
[_unit, true, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide);
|
||||
};
|
||||
// Delay Unconscious so the AI dont instant stop shooting on the unit #3121
|
||||
if (GVAR(delayUnconCaptive) == 0) then {
|
||||
[_unit, "setCaptive", "ace_unconscious", true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
[{
|
||||
params ["_unit"];
|
||||
if (_unit getVariable ["ACE_isUnconscious", false]) then {
|
||||
[_unit, "setCaptive", "ace_unconscious", true] call EFUNC(common,statusEffect_set);
|
||||
};
|
||||
},[_unit], GVAR(delayUnconCaptive)] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
|
||||
_anim = [_unit] call EFUNC(common,getDeathAnim);
|
||||
[_unit, _anim, 1, true] call EFUNC(common,doAnimation);
|
||||
[{
|
||||
params ["_unit", "_anim"];
|
||||
if ((_unit getVariable "ACE_isUnconscious") and (animationState _unit != _anim)) then {
|
||||
[_unit, _anim, 2, true] call EFUNC(common,doAnimation);
|
||||
};
|
||||
}, [_unit, _anim], 0.5, 0] call CBA_fnc_waitAndExecute;
|
||||
|
||||
_startingTime = CBA_missionTime;
|
||||
|
||||
[_unit, "Unconscious", []] call FUNC(stateEvent);
|
||||
|
||||
[DFUNC(unconsciousPFH), 0.1, [_unit, _originalPos, _startingTime, _minWaitingTime, false, vehicle _unit isKindOf "ParachuteBase"] ] call CBA_fnc_addPerFrameHandler;
|
||||
|
||||
// unconscious can't talk
|
||||
[_unit, "isUnconscious"] call EFUNC(common,muteUnit);
|
||||
|
||||
["ace_unconscious", [_unit, true]] call CBA_fnc_globalEvent;
|
@ -35,7 +35,7 @@ GVAR(monitoredUnitsListIsSorted) = false;
|
||||
_delete = true;
|
||||
GVAR(monitoredUnitsList) set [_forEachIndex, objNull];
|
||||
};
|
||||
if (_exit) exitwith {};
|
||||
if (_exit) exitWith {};
|
||||
} forEach GVAR(monitoredUnitsList);
|
||||
|
||||
if (_delete) then {
|
||||
|
@ -1,12 +1,31 @@
|
||||
|
||||
/*
|
||||
* Author: Glowbal
|
||||
* PFH logic for unconscious state
|
||||
*
|
||||
* Arguments:
|
||||
* 0: PFEH - Args
|
||||
* 0: The unit that will be put in an unconscious state <OBJECT>
|
||||
* 1: unitPos (stance) <STRING>
|
||||
* 2: Starting Time <NUMBER>
|
||||
* 3: Minimum Waiting Time <NUMBER>
|
||||
* 4: Has Moved Out <BOOL>
|
||||
* 5: Parachute Check <BOOL>
|
||||
* 1: PFEH ID <NUMBER>
|
||||
*
|
||||
* ReturnValue:
|
||||
* None
|
||||
*
|
||||
* Public: yes
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", "_args"];
|
||||
_args params ["_originalPos", "_startingTime", "_minWaitingTime", "_hasMovedOut", "_parachuteCheck"];
|
||||
private ["_unit", "_minWaitingTime", "_slotInfo", "_hasMovedOut", "_parachuteCheck", "_args", "_originalPos", "_startingTime", "_awakeInVehicleAnimation", "_oldVehicleAnimation", "_vehicle"];
|
||||
params ["_args", "_idPFH"];
|
||||
_args params ["_unit", "_originalPos", "_startingTime", "_minWaitingTime", "_hasMovedOut", "_parachuteCheck"];
|
||||
|
||||
TRACE_6("ACE_DEBUG_Unconscious_handling",_unit, _originalPos, _startingTime, _minWaitingTime, _hasMovedOut, _parachuteCheck);
|
||||
TRACE_6("ACE_DEBUG_Unconscious_PFH",_unit, _originalPos, _startingTime, _minWaitingTime, _hasMovedOut, _parachuteCheck);
|
||||
|
||||
if (!alive _unit) exitWith { // TODO on exit unconscious
|
||||
if (!alive _unit) exitWith {
|
||||
if ("ACE_FakePrimaryWeapon" in (weapons _unit)) then {
|
||||
TRACE_1("Removing fake weapon [on death]",_unit);
|
||||
_unit removeWeapon "ACE_FakePrimaryWeapon";
|
||||
@ -17,12 +36,13 @@ if (!alive _unit) exitWith { // TODO on exit unconscious
|
||||
[_unit, "setCaptive", "ace_unconscious", false] call EFUNC(common,statusEffect_set);
|
||||
[_unit, false] call EFUNC(common,disableAI);
|
||||
//_unit setUnitPos _originalPos;
|
||||
//_unit setUnconscious false;
|
||||
_unit setUnconscious false;
|
||||
|
||||
[_unit, "isUnconscious"] call EFUNC(common,unmuteUnit);
|
||||
["ace_unconscious", [_unit, false]] call CBA_fnc_globalEvent;
|
||||
|
||||
TRACE_3("ACE_DEBUG_Unconscious_Exit",_unit, (!alive _unit) , "ace_unconscious");
|
||||
|
||||
[_idPFH] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
@ -76,12 +96,10 @@ if !(_unit getVariable ["ACE_isUnconscious",false]) exitWith {
|
||||
};
|
||||
_unit setVariable [QGVAR(vehicleAwakeAnim), nil];
|
||||
|
||||
// Now we can leave our unconsicous state
|
||||
["ace_unconscious", [_unit, false]] call CBA_fnc_globalEvent;
|
||||
// EXIT PFH
|
||||
[_idPFH] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
if (!_hasMovedOut) then {
|
||||
// Reset the unit back to the previous captive state.
|
||||
[_unit, "setCaptive", "ace_unconscious", false] call EFUNC(common,statusEffect_set);
|
Loading…
Reference in New Issue
Block a user