mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
manual merge
This commit is contained in:
commit
9cba0baade
@ -1,80 +1,102 @@
|
||||
class ACE_Medical_StateMachine {
|
||||
list = "allUnits select {local _x}";
|
||||
skipNull = 1;
|
||||
|
||||
class Default {
|
||||
onState = QUOTE(DFUNC(handleStateDefault));
|
||||
class Injury {
|
||||
targetState = "Injured";
|
||||
events[] = {"TakenInjury"};
|
||||
events[] = {QGVAR(TakenInjury)};
|
||||
};
|
||||
class CriticalInjuryOrVitals {
|
||||
targetState = "Unconscious";
|
||||
events[] = {"InjuryCritical", "CriticalVitals"};
|
||||
events[] = {QGVAR(InjuryCritical), QGVAR(CriticalVitals)};
|
||||
};
|
||||
class FatalInjuryOrVitals {
|
||||
targetState = "Dead";
|
||||
events[] = {"FatalVitals", "InjuryFatal"};
|
||||
class FatalInjury {
|
||||
targetState = "FatalInjury";
|
||||
events[] = {QGVAR(InjuryFatal)};
|
||||
};
|
||||
};
|
||||
class Injured {
|
||||
onState = QUOTE(DFUNC(handleStateInjured));
|
||||
class FullHeal {
|
||||
targetState = "Default";
|
||||
events[] = {"FullHeal"};
|
||||
events[] = {QGVAR(FullHeal)};
|
||||
};
|
||||
class LastWoundTreated {
|
||||
targetState = "Default";
|
||||
events[] = {"LastWoundTreated"};
|
||||
events[] = {QGVAR(LastWoundTreated)};
|
||||
};
|
||||
class CriticalInjuryOrVitals {
|
||||
targetState = "Unconscious";
|
||||
events[] = {"InjuryCritical", "CriticalVitals"};
|
||||
events[] = {QGVAR(InjuryCritical), QGVAR(CriticalVitals)};
|
||||
};
|
||||
class FatalInjuryOrVitals {
|
||||
targetState = "Dead";
|
||||
events[] = {"FatalVitals", "InjuryFatal"};
|
||||
class FatalVitals {
|
||||
targetState = "CardiacArrest";
|
||||
events[] = {QGVAR(FatalVitals)};
|
||||
};
|
||||
class FatalInjury {
|
||||
targetState = "FatalInjury";
|
||||
events[] = {QGVAR(InjuryFatal)};
|
||||
};
|
||||
};
|
||||
class Unconscious {
|
||||
onState = QUOTE(DFUNC(handleStateUnconscious));
|
||||
onStateEntered = QUOTE(DFUNC(enteredUnconsciousState));
|
||||
onStateLeaving = "_unit setVariable ['ACE_isUnconscious', false, true];";
|
||||
onStateLeaving = "_this setVariable ['ACE_isUnconscious', false, true];";
|
||||
class WakeUpFromKnockDown {
|
||||
targetState = "Injured";
|
||||
condition = QUOTE(_unit call FUNC(hasStableVitals));
|
||||
events[] = {"MinUnconsciousTimer"};
|
||||
condition = QUOTE(_this call FUNC(hasStableVitals));
|
||||
events[] = {QGVAR(MinUnconsciousTimer)};
|
||||
};
|
||||
class WakeUpStable {
|
||||
targetState = "Injured";
|
||||
condition = "unitUnconsciousTimer >= MinUnconsciousTimer";
|
||||
events[] = {"VitalsWentStable"};
|
||||
events[] = {QGVAR(VitalsWentStable)};
|
||||
};
|
||||
class FatalTransitions {
|
||||
targetState = "CardiacArrest";
|
||||
events[] = {QGVAR(FatalVitals), QGVAR(UnconsciousTimerRanOut)};
|
||||
};
|
||||
class FatalInjury {
|
||||
targetState = "FatalInjury";
|
||||
events[] = {QGVAR(InjuryFatal)};
|
||||
};
|
||||
};
|
||||
class FatalInjury {
|
||||
// Transition state for handling instant death
|
||||
// This state raises the next transition in the same frame
|
||||
onStateEntered = QUOTE(DFUNC(enteredStateFatalInjury));
|
||||
class SecondChance {
|
||||
events[] = {QGVAR(FatalInjuryInstantTransition)};
|
||||
targetState = "CardiacArrest";
|
||||
condition = QUOTE(GVAR(fatalInjuryCondition) > 0);
|
||||
onTransition = QUOTE(DFUNC(transitionSecondChance));
|
||||
};
|
||||
class Death {
|
||||
events[] = {QGVAR(FatalInjuryInstantTransition)};
|
||||
targetState = "Dead";
|
||||
events[] = {"InjuryFatal", "FatalVitals", "UnconsciousTimerRanOut"};
|
||||
condition = "true";
|
||||
};
|
||||
};
|
||||
class CardiacArrest {
|
||||
onStateEntered = QUOTE(DFUNC(enteredStateCardiacArrest));
|
||||
onStateLeaving = '_this setVariable [QGVAR(cardiacArrestStart), nil]';
|
||||
class TimerRanOut {
|
||||
targetState = "Dead";
|
||||
condition = QUOTE(DFUNC(conditionCardiacArrestTimer));
|
||||
};
|
||||
class Reanimated {
|
||||
targetState = "Unconscious";
|
||||
events[] = {QGVAR(CPRSucceeded)};
|
||||
};
|
||||
class Execution {
|
||||
targetState = "Dead";
|
||||
condition = QUOTE(DFUNC(conditionExecutionDeath));
|
||||
events[] = {QGVAR(InjuryFatal)};
|
||||
};
|
||||
};
|
||||
class Dead {
|
||||
onStateEntered = "(_this select 0) setDamage 1"; // killing a unit also exits the state machine for this unit
|
||||
};
|
||||
class Revive {
|
||||
onState = QUOTE(DFUNC(handleStateRevive));
|
||||
onStateEntered = QUOTE(DFUNC(enteredRevive)); // set unconscious animation & state
|
||||
onStateLeaving = QUOTE(DFUNC(leavingRevive)); // leave unconscious animation & state
|
||||
class FullHeal {
|
||||
targetState = "Default";
|
||||
events[] = {"fullyHealed"};
|
||||
};
|
||||
class Revived {
|
||||
targetState = "Injured";
|
||||
events[] = {"Revived"};
|
||||
};
|
||||
class TimerRanOut {
|
||||
targetState = "Dead";
|
||||
events[] = {"ReviveTimer", "NoLives"};
|
||||
};
|
||||
class FatalTransitions {
|
||||
targetState = "Dead";
|
||||
condition = QGVAR(killOnFatalDamageInRevive);
|
||||
events[] = {"FatalInjury"};
|
||||
};
|
||||
onStateEntered = "_this setDamage 1"; // killing a unit also exits the state machine for this unit
|
||||
};
|
||||
};
|
||||
|
@ -1,7 +1,4 @@
|
||||
|
||||
PREP(addStateHandler);
|
||||
PREP(adjustPainLevel);
|
||||
PREP(createStateMachine);
|
||||
PREP(getBloodLoss);
|
||||
PREP(getBloodPressure);
|
||||
PREP(getBloodVolumeChange);
|
||||
@ -14,17 +11,22 @@ PREP(isInMedicalVehicle);
|
||||
PREP(isInStableCondition);
|
||||
PREP(isMedic);
|
||||
PREP(isMedicalVehicle);
|
||||
PREP(stateEvent);
|
||||
PREP(stateMachine);
|
||||
|
||||
// PREP(hasMedicalEnabled);
|
||||
|
||||
PREP(enteredStateCardiacArrest);
|
||||
PREP(leavingStateCardiacArrest);
|
||||
|
||||
PREP(enteredStateFatalInjury);
|
||||
|
||||
PREP(conditionExecutionDeath);
|
||||
PREP(transitionSecondChance);
|
||||
|
||||
PREP(handleStateDefault);
|
||||
PREP(handleStateInjured);
|
||||
PREP(handleStateUnconscious);
|
||||
PREP(handleUnitVitals);
|
||||
PREP(handleMedications);
|
||||
// PREP(handleStateRevive);
|
||||
|
||||
PREP(addPain);
|
||||
PREP(setUnconscious);
|
||||
|
@ -1,12 +1,9 @@
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
GVAR(heartBeatSounds_Fast) = ["ACE_heartbeat_fast_1", "ACE_heartbeat_fast_2", "ACE_heartbeat_fast_3"];
|
||||
GVAR(heartBeatSounds_Normal) = ["ACE_heartbeat_norm_1", "ACE_heartbeat_norm_2"];
|
||||
GVAR(heartBeatSounds_Slow) = ["ACE_heartbeat_slow_1", "ACE_heartbeat_slow_2"];
|
||||
|
||||
call FUNC(stateMachine);
|
||||
|
||||
//Handle Deleting Bodies and creating litter on Server:
|
||||
if (isServer) then {
|
||||
["ace_placedInBodyBag", FUNC(serverRemoveBody)] call CBA_fnc_addEventHandler;
|
||||
@ -35,3 +32,29 @@ if (!hasInterface) exitWith {};
|
||||
|
||||
linearConversion [0, 1, _pain, 1, 5, true];
|
||||
}] call EFUNC(common,arithmeticSetSource);
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
if (hasInterface) then {
|
||||
private _ctrl = findDisplay 46 ctrlCreate ["RscText", -1];
|
||||
_ctrl ctrlSetPosition [
|
||||
safeZoneX,
|
||||
safeZoneY,
|
||||
safeZoneW,
|
||||
40 * pixelH
|
||||
];
|
||||
_ctrl ctrlSetFontHeight (40 * pixelH);
|
||||
_ctrl ctrlSetTextColor [0.6, 0, 0, 1];
|
||||
_ctrl ctrlCommit 0;
|
||||
uiNamespace setVariable [QGVAR(debugControl), _ctrl];
|
||||
|
||||
[{
|
||||
private _playerState = [ACE_player, GVAR(STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState;
|
||||
(uiNamespace getVariable [QGVAR(debugControl), controlNull]) ctrlSetText format ["Player state: %1", _playerState];
|
||||
|
||||
if (!isNull cursorTarget && {cursorTarget isKindOf "CAManBase"}) then {
|
||||
private _targetState = [cursorTarget, GVAR(STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState;
|
||||
drawIcon3D ["", [0.6, 0, 0, 1], cursorTarget modelToWorld (cursorTarget selectionPosition "pelvis"), 0, 0, 0, format ["State: %1", _targetState], 2, 40 * pixelH, "RobotoCondensed"];
|
||||
};
|
||||
}] call CBA_fnc_addPerFrameHandler;
|
||||
};
|
||||
#endif
|
||||
|
@ -9,7 +9,7 @@ PREP_RECOMPILE_END;
|
||||
GVAR(HITPOINTS) = ["HitHead", "HitBody", "HitLeftArm", "HitRightArm", "HitLeftLeg", "HitRightLeg"];
|
||||
GVAR(SELECTIONS) = ["head", "body", "hand_l", "hand_r", "leg_l", "leg_r"];
|
||||
|
||||
GVAR(STATE_MACHINE) = (configFile >> "ACE_Medical_StateMachine") call FUNC(createStateMachine);
|
||||
GVAR(STATE_MACHINE) = (configFile >> "ACE_Medical_StateMachine") call CBA_statemachine_fnc_createFromConfig;
|
||||
|
||||
// @todo, ACE_Settings
|
||||
[
|
||||
@ -39,4 +39,26 @@ GVAR(STATE_MACHINE) = (configFile >> "ACE_Medical_StateMachine") call FUNC(creat
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(fatalInjuryCondition),
|
||||
"LIST",
|
||||
["Allow Fatal Injury", "Governs when a fatal injury can occur."], //@todo
|
||||
"ACE Medical", // @todo
|
||||
[
|
||||
[0, 1, 2],
|
||||
["Always", "In Cardiac Arrest", "Never"],
|
||||
0
|
||||
],
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(cardiacArrestTime),
|
||||
"SLIDER",
|
||||
["Cardiac Arrest Time", "Sets how long cardiac arrest will last for (in minutes)."], //@todo
|
||||
"ACE Medical", // @todo
|
||||
[0, 30, 2, 0],
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
ADDON = true;
|
||||
|
18
addons/medical/functions/fnc_conditionCardiacArrestTimer.sqf
Normal file
18
addons/medical/functions/fnc_conditionCardiacArrestTimer.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Checks if the cardiac arrest timer ran out.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit"];
|
||||
|
||||
private _startTime = _unit getVariable [QGVAR(cardiacArrestStart), CBA_missionTime];
|
||||
|
||||
(CBA_missionTime - _startTime) > (GVAR(cardiacArrestTime) * 60)
|
16
addons/medical/functions/fnc_conditionExecutionDeath.sqf
Normal file
16
addons/medical/functions/fnc_conditionExecutionDeath.sqf
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Condition for an execution caused death.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit"];
|
||||
|
||||
(GVAR(fatalInjuryCondition) < 2) && {!(_unit getVariable [QGVAR(deathBlocked), false])}
|
@ -1,59 +0,0 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_stateMachineConfig"];
|
||||
|
||||
private _getCode = {
|
||||
params ["_config", "_attribute"];
|
||||
private _value = getText (_config >> _attribute);
|
||||
if (isNil {missionNamespace getVariable _value}) exitWith {
|
||||
if (_value == "") then {_value = "true"};
|
||||
systemChat format ["getCode (%1) is returning nil: %3", _attribute, missionnamespace getVariable _value, _value];
|
||||
diag_log format ["getCode (%1) is returning nil: %3", _attribute, missionnamespace getVariable _value, _value];
|
||||
|
||||
compile _value;
|
||||
};
|
||||
missionNamespace getVariable _value;
|
||||
};
|
||||
|
||||
private _stateMachine = call CBA_fnc_createNamespace;
|
||||
|
||||
private _states = [];
|
||||
{
|
||||
private _stateName = configName _x;
|
||||
private _onState = [_x, "onState"] call _getCode;
|
||||
private _onEntry = [_x, "onEntry"] call _getCode;
|
||||
private _onExit = [_x, "onExit"] call _getCode;
|
||||
|
||||
// Collect all the transitions for the state
|
||||
private _transitions = [];
|
||||
{
|
||||
private _transitionName = configName _x;
|
||||
private _targetState = getText (_x >> "targetState");
|
||||
private _events = getArray (_x >> "events") apply { toLower _x};
|
||||
private _condition = [_x, "condition"] call _getCode;
|
||||
private _onTransition = [_x, "onTransition"] call _getCode;
|
||||
|
||||
_transitions pushBack [_transitionName, _condition, _events, _onTransition, _targetState];
|
||||
} forEach ("true" configClasses _x);
|
||||
_states pushBack [_stateName, _onState, _onEntry, _onExit, _transitions];
|
||||
} forEach ("true" configClasses _stateMachineConfig);
|
||||
|
||||
// Helper method for finding the desired state when linking (See below)
|
||||
private _getState = {
|
||||
params ["_stateName"];
|
||||
private _state = ["Invalid", {}, {}, {}, []];
|
||||
{
|
||||
if (_stateName == (_x select 0)) exitWith {_state = _x};
|
||||
} forEach _states;
|
||||
_state;
|
||||
};
|
||||
|
||||
_stateMachine setvariable [QGVAR(allStates), _states];
|
||||
|
||||
// Now we have collected all the states, link them in transitions so we do not have to look them up on state transitions
|
||||
{
|
||||
_x params ["_stateName"];
|
||||
_stateMachine setvariable [_stateName, _x];
|
||||
} forEach _states;
|
||||
|
||||
_stateMachine;
|
@ -1,24 +0,0 @@
|
||||
|
||||
|
||||
#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);
|
||||
};
|
16
addons/medical/functions/fnc_enteredStateCardiacArrest.sqf
Normal file
16
addons/medical/functions/fnc_enteredStateCardiacArrest.sqf
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles a unit entering cardiac arrest.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit"];
|
||||
|
||||
_unit setVariable [QGVAR(cardiacArrestStart), CBA_missionTime];
|
16
addons/medical/functions/fnc_enteredStateFatalInjury.sqf
Normal file
16
addons/medical/functions/fnc_enteredStateFatalInjury.sqf
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Raises the transition to the next state instantly when fatally injured.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit"];
|
||||
|
||||
[QGVAR(FatalInjuryInstantTransition), _unit] call CBA_fnc_localEvent;
|
@ -1,55 +0,0 @@
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
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 (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];
|
||||
};
|
||||
_unit setVariable [QGVAR(bloodVolume), _unit getVariable [QGVAR(bloodVolume), DEFAULT_BLOOD_VOLUME], 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];
|
||||
if (_pain > (_unit getVariable [QGVAR(painSuppress), 0])) then {
|
||||
[_unit, "moan", PAIN_TO_MOAN(_pain)] call EFUNC(medical_engine,playInjuredSound);
|
||||
};
|
@ -52,7 +52,7 @@ TRACE_3("ACE_DEBUG",_bloodLoss,_unit getVariable QGVAR(isBleeding),_unit);
|
||||
if (_bloodLoss > 0) then {
|
||||
_unit setVariable [QGVAR(bloodloss), _bloodLoss, _syncValues];
|
||||
|
||||
[_unit, "TakenInjury"] call FUNC(stateEvent);
|
||||
[QGVAR(TakenInjury), _unit] call CBA_fnc_localEvent;
|
||||
|
||||
if !(_unit getVariable [QGVAR(isBleeding), false]) then {
|
||||
_unit setVariable [QGVAR(isBleeding), true, true];
|
||||
|
16
addons/medical/functions/fnc_leavingStateCardiacArrest.sqf
Normal file
16
addons/medical/functions/fnc_leavingStateCardiacArrest.sqf
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles a unit entering cardiac arrest.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit"];
|
||||
|
||||
_unit setVariable [QGVAR(cardiacArrestStart), nil];
|
@ -81,7 +81,7 @@ if (_isDead) exitWith {};
|
||||
*/
|
||||
|
||||
[_unit, true] call EFUNC(medical_engine,setUnconsciousAnim);
|
||||
[_unit, "Unconscious", []] call FUNC(stateEvent);
|
||||
[QGVAR(Unconscious), _unit] call CBA_fnc_localEvent;
|
||||
["ace_unconscious", [_unit, true]] call CBA_fnc_globalEvent;
|
||||
|
||||
// auto wake up
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Author: Glowbal
|
||||
*
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
* 1: Event name <STRING>
|
||||
* 2: Event Arguments
|
||||
*
|
||||
* ReturnValue:
|
||||
* Name of the state after handling the state event <STRING>
|
||||
*
|
||||
* Example:
|
||||
* [unit, "TakenInjury", []] call ace_medical_stateEvent;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", "_event", "_args"];
|
||||
diag_log format["ace_medical_stateEvent: %1", _this];
|
||||
|
||||
_event = toLower _event;
|
||||
|
||||
private _unitState = _unit getVariable [QGVAR(state), [CBA_missionTime, GVAR(STATE_MACHINE) getVariable "Default"]];
|
||||
_unitState params ["_lastTime", "_state"];
|
||||
_state params ["_name", "_handler", "_onEntry", "_onExit", "_transitions"];
|
||||
|
||||
private _newStateName = _name;
|
||||
{
|
||||
_x params ["_transitionName", "_condition", "_events", "_onTransition", "_targetStateName"];
|
||||
|
||||
if (_event in _events && {[_unit, _event, _args] call _condition}) exitWith {
|
||||
private _targetState = GVAR(STATE_MACHINE) getVariable _targetStateName;
|
||||
|
||||
_targetState params ["_targetStateName", "_targetStateHandler", "_targetStateOnEntry", "_targetStateOnExit", "_targetStateTansitions"];
|
||||
_newStateName = _targetStateName;
|
||||
// Handle state leaving
|
||||
[_unit, _event, _args] call _onExit;
|
||||
[_unit, _event, _args] call _onTransition;
|
||||
|
||||
// Switch the state
|
||||
_unitState set [1, _targetState];
|
||||
_unit setvariable [QGVAR(state), _unitState];
|
||||
|
||||
// Enter the state
|
||||
[_unit, _event, _args] call _targetStateOnEntry;
|
||||
};
|
||||
} forEach _transitions;
|
||||
|
||||
_newStateName;
|
@ -1,45 +0,0 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
// Delay between state runs
|
||||
#define DELAY 1
|
||||
#define DEFAULT_STATE [0, "Default", {}, {}, {}, []]
|
||||
|
||||
GVAR(monitoredUnitsList) = [];
|
||||
GVAR(monitoredUnitsListIsSorted) = false;
|
||||
|
||||
[{
|
||||
params ["_args", "_pfhId"];
|
||||
|
||||
if (!GVAR(monitoredUnitsListIsSorted)) then {
|
||||
GVAR(monitoredUnitsList) sort true;
|
||||
GVAR(monitoredUnitsListIsSorted) = true;
|
||||
};
|
||||
|
||||
private _delete = false;
|
||||
private _exit = false;
|
||||
{
|
||||
_x params ["_unit"];
|
||||
|
||||
if (!isNull _unit && alive _unit) then {
|
||||
private _unitState = _unit getVariable [QGVAR(state), [-1, DEFAULT_STATE]];
|
||||
_unitState params ["_lastTime", "_state"];
|
||||
|
||||
if (CBA_missionTime - _lastTime < DELAY) exitWith { _exit = true; };
|
||||
_state params ["_name", "_handler", "_onEntry", "_onExit", "_transitions"];
|
||||
|
||||
_unitState set [0, CBA_missionTime];
|
||||
|
||||
_unit setvariable [QGVAR(state), _unitState];
|
||||
|
||||
[_unit, _name, _lastTime] call _handler;
|
||||
} else {
|
||||
_delete = true;
|
||||
GVAR(monitoredUnitsList) set [_forEachIndex, objNull];
|
||||
};
|
||||
if (_exit) exitWith {};
|
||||
} forEach GVAR(monitoredUnitsList);
|
||||
|
||||
if (_delete) then {
|
||||
GVAR(monitoredUnitsList) = GVAR(monitoredUnitsList) - [objNull];
|
||||
};
|
||||
}, 0, []] call CBA_fnc_addPerFrameHandler;
|
19
addons/medical/functions/fnc_transitionSecondChance.sqf
Normal file
19
addons/medical/functions/fnc_transitionSecondChance.sqf
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Gives the unit a second chance and prevents death for 1 second.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit"];
|
||||
|
||||
_unit setVariable [QGVAR(deathBlocked), true];
|
||||
[{
|
||||
_this setVariable [QGVAR(deathBlocked), false];
|
||||
}, _unit, 1] call CBA_fnc_waitAndExecute;
|
@ -140,6 +140,6 @@ if ((CBA_missionTime - _startingTime) >= _minWaitingTime) exitWith {
|
||||
TRACE_2("ACE_DEBUG_Unconscious_Temp knock outs",_unit, [_unit] call FUNC(getUnconsciousCondition));
|
||||
if (!([_unit] call FUNC(getUnconsciousCondition))) then {
|
||||
//_unit setVariable ["ACE_isUnconscious", false, true];
|
||||
[_unit, "MinUnconsciousTimer", []] call FUNC(stateEvent);
|
||||
[QGVAR(MinUnconsciousTimer), _unit] call CBA_fnc_localEvent;
|
||||
};
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define COMPONENT_BEAUTIFIED Medical Core
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
#define DEBUG_MODE_FULL
|
||||
#define DISABLE_COMPILE_CACHE
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
|
@ -3,4 +3,5 @@ PREP(handleWoundReceived);
|
||||
PREP(isBleeding);
|
||||
PREP(onBleeding);
|
||||
PREP(createBlood);
|
||||
PREP(serverCleanupBlood);
|
||||
PREP(spurt);
|
||||
|
@ -10,37 +10,33 @@ if (isServer) then {
|
||||
|
||||
[QGVAR(bloodDropCreated), {
|
||||
params ["_bloodDrop"];
|
||||
|
||||
GVAR(bloodDrops) pushBack _bloodDrop;
|
||||
// Add to created queue with format [expireTime, object]
|
||||
private _index = GVAR(bloodDrops) pushBack [(CBA_missionTime + BLOOD_OBJECT_LIFETIME), _bloodDrop];
|
||||
|
||||
if (count GVAR(bloodDrops) >= MAX_BLOOD_OBJECTS) then {
|
||||
private _deletedBloodDrop = GVAR(bloodDrops) deleteAt 0;
|
||||
(GVAR(bloodDrops) deleteAt 0) params ["", "_deletedBloodDrop"];
|
||||
deleteVehicle _deletedBloodDrop;
|
||||
};
|
||||
|
||||
[{deleteVehicle _this}, _bloodDrop, BLOOD_OBJECT_LIFETIME] call CBA_fnc_waitAndExecute;
|
||||
if (_index == 1) then { // Start the waitAndExecute loop
|
||||
[FUNC(serverCleanupBlood), [], BLOOD_OBJECT_LIFETIME] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
};
|
||||
|
||||
["ace_settingsInitialized", {
|
||||
TRACE_1("settingsInitialized", GVAR(enabledFor));
|
||||
if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled
|
||||
if (GVAR(enabledFor) == 1 && {!hasInterface}) exitWith {}; // 1: enabledFor_OnlyPlayers
|
||||
if ((GVAR(enabledFor) == 1) && {!hasInterface}) exitWith {}; // 1: enabledFor_OnlyPlayers
|
||||
|
||||
private _listcode = if (GVAR(enabledFor) == 1) then {
|
||||
{[ACE_player] select {[_x] call FUNC(isBleeding)}} // ace_player is only possible local player
|
||||
} else {
|
||||
{allUnits select {(local _x) && {[_x] call FUNC(isBleeding)}}}; // filter all local bleeding units
|
||||
};
|
||||
|
||||
|
||||
private _stateMachine = [_listcode, true] call CBA_statemachine_fnc_create;
|
||||
[_stateMachine, {call FUNC(onBleeding)}, {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState;
|
||||
|
||||
[QEGVAR(medical_engine,woundReceived), FUNC(handleWoundReceived)] call CBA_fnc_addEventHandler;
|
||||
|
||||
/*["CAManBase", "hit", { @todo, remove?
|
||||
params ["_unit"];
|
||||
if (GVAR(enabledFor) == 1 && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {};
|
||||
_this call FUNC(hit);
|
||||
}] call CBA_fnc_addClassEventHandler;*/
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
params ["_unit", "", "_damage", "_shooter"];
|
||||
|
||||
if (GVAR(enabledFor) == 1 && {!isPlayer _unit || {_unit == ACE_player}}) exitWith {};
|
||||
if (GVAR(enabledFor) == 1 && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {};
|
||||
if (vehicle _unit != _unit && {!((vehicle _unit) isKindOf "StaticWeapon")}) exitWith {}; // Don't bleed on ground if mounted
|
||||
|
||||
_damage = _damage min 1;
|
||||
|
23
addons/medical_blood/functions/fnc_serverCleanupBlood.sqf
Normal file
23
addons/medical_blood/functions/fnc_serverCleanupBlood.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Loop that cleans up blood
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* ReturnValue:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
(GVAR(bloodDrops) deleteAt 0) params ["", "_deletedBloodDrop"];
|
||||
deleteVehicle _deletedBloodDrop;
|
||||
|
||||
// If we cleaned out the array, exit loop
|
||||
if (GVAR(bloodDrops) isEqualTo []) exitWith {};
|
||||
|
||||
// Wait until the next blood drop in the queue will expire
|
||||
(GVAR(bloodDrops) select 0) params ["_expireTime"];
|
||||
[FUNC(serverCleanupBlood), [], (_expireTime - CBA_missionTime)] call CBA_fnc_waitAndExecute;
|
Loading…
Reference in New Issue
Block a user