Merge branch 'master' into cbaDisposable

This commit is contained in:
PabstMirror 2019-05-06 10:05:35 -05:00
commit 5eead2fc6e
67 changed files with 508 additions and 398 deletions

View File

@ -9,9 +9,3 @@ class Extended_PreInit_EventHandlers {
init = QUOTE(call COMPILE_FILE(XEH_preInit));
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient));
};
};

View File

@ -1,29 +0,0 @@
#include "script_component.hpp"
if (!hasInterface) exitWith {};
private _cfgAction = configFile >> "CfgActions" >> "Eject";
GVAR(ejectActionParams) = [
[
"", // will be set with setUserActionText
{
params ["_vehicle", "_unit"];
private _preserveEngineOn = (_unit == driver _vehicle) && {isEngineOn _vehicle};
moveOut _unit;
if (_preserveEngineOn) then {
// vehicle is local to last driver, no need to care
_vehicle engineOn true;
};
},
nil,
getNumber (_cfgAction >> "priority"),
false,
true,
getText (_cfgAction >> "shortcut"),
'[_this, _target] call DFUNC(canShowEject)'
],
getText (_cfgAction >> "text"),
getText (_cfgAction >> "textDefault")
];
["Helicopter", "initPost", LINKFUNC(initEjectAction)] call CBA_fnc_addClassEventHandler;

View File

@ -6,4 +6,41 @@ PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;
if (hasInterface) then {
["CBA_settingsInitialized", {
private _ejectAction = configFile >> "CfgActions" >> "Eject";
private _hideEjectAction = missionNamespace getVariable [QEGVAR(vehicles,hideEjectAction), false];
private _text = getText (_ejectAction >> "text");
if (_hideEjectAction) then {
_text = format ["<t color='#808080'>%1</t>", _text];
};
GVAR(ejectActionParams) = [
[
"", // will be set with setUserActionText
{
params ["_vehicle", "_unit"];
private _preserveEngineOn = (_unit == driver _vehicle) && {isEngineOn _vehicle};
moveOut _unit;
if (_preserveEngineOn) then {
// vehicle is local to last driver, no need to care
_vehicle engineOn true;
};
},
nil,
[getNumber (_ejectAction >> "priority"), -999] select _hideEjectAction,
false,
true,
getText (_ejectAction >> "shortcut"),
'[_this, _target] call DFUNC(canShowEject)'
],
_text,
getText (_ejectAction >> "textDefault")
];
["Helicopter", "InitPost", LINKFUNC(initEjectAction), nil, nil, true] call CBA_fnc_addClassEventHandler;
}] call CBA_fnc_addEventHandler;
};
ADDON = true;

View File

@ -28,8 +28,6 @@ class CfgWeapons {
// MX
class arifle_MX_Base_F: Rifle_Base_F {
magazineWell[] = {"CBA_65x39_MX", "CBA_65x39_MX_XL"};
class Single: Mode_SemiAuto {
dispersion = MOA_TO_RAD(0.90);
};

View File

@ -21,7 +21,7 @@
*/
params ["_unit", "_animation", ["_priority", 0]];
TRACE_4("params",_unit,_animation,_priority);
TRACE_3("params",_unit,_animation,_priority);
// switchMove "" no longer works in dev 1.37
if (_animation == "") then {

View File

@ -1,7 +1,7 @@
#include "script_component.hpp"
/*
* Author: dedmen
* Adds the local unit event handlers.
* Adds the local unit event handlers.
* Access with function `ace_common_fnc_getLocalUnits` or array `ace_common_localUnits`
*
* Arguments:
@ -15,6 +15,8 @@
*
* Public: No
*/
// Ignore UAV/Drone AI
#define IGNORE_BASE_UAVPILOTS "B_UAV_AI", "O_UAV_AI", "UAV_AI_base_F"
GVAR(localUnits) = [];
@ -27,7 +29,7 @@ GVAR(localUnits) = [];
if (!alive _unit) exitWith {};
GVAR(localUnits) pushBack _unit;
};
}] call CBA_fnc_addClassEventHandler;
}, true, [IGNORE_BASE_UAVPILOTS]] call CBA_fnc_addClassEventHandler;
["CAManBase", "respawn", {
params ["_unit"];
@ -37,7 +39,7 @@ GVAR(localUnits) = [];
if (!alive _unit) exitWith {};
GVAR(localUnits) pushBack _unit;
};
}] call CBA_fnc_addClassEventHandler;
}, true, [IGNORE_BASE_UAVPILOTS]] call CBA_fnc_addClassEventHandler;
["CAManBase", "local", {
params ["_unit", "_local"];
@ -49,7 +51,7 @@ GVAR(localUnits) = [];
} else {
GVAR(localUnits) deleteAt (GVAR(localUnits) find _unit);
};
}] call CBA_fnc_addClassEventHandler;
}, true, [IGNORE_BASE_UAVPILOTS]] call CBA_fnc_addClassEventHandler;
["CAManBase", "deleted", {
params ["_unit"];
@ -64,7 +66,7 @@ GVAR(localUnits) = [];
};
}, [_unit]] call CBA_fnc_execNextFrame;
};
}] call CBA_fnc_addClassEventHandler;
}, true, [IGNORE_BASE_UAVPILOTS]] call CBA_fnc_addClassEventHandler;
["CAManBase", "killed", {
params ["_unit"];
@ -73,4 +75,4 @@ GVAR(localUnits) = [];
if (local _unit) then {
GVAR(localUnits) deleteAt (GVAR(localUnits) find _unit);
};
}] call CBA_fnc_addClassEventHandler;
}, true, [IGNORE_BASE_UAVPILOTS]] call CBA_fnc_addClassEventHandler;

View File

@ -207,7 +207,7 @@ class CfgVehicles {
GVAR(enabled) = 2;
GVAR(ropeOrigins)[] = {"ropeOriginRight", "ropeOriginLeft"};
GVAR(friesType) = "ACE_friesAnchorBar";
GVAR(friesAttachmentPoint)[] = {0.065, 2.2, -0.15};
GVAR(friesAttachmentPoint)[] = {0.035, 2.2, -0.15};
GVAR(onPrepare) = QFUNC(onPrepareCommon);
GVAR(onCut) = QFUNC(onCutCommon);
EQUIP_FRIES_ATTRIBUTE;

View File

@ -4,7 +4,6 @@ PREP(canDeployRopes);
PREP(canFastRope);
PREP(canPrepareFRIES);
PREP(canStowFRIES);
PREP(checkVehicleThread);
PREP(cutRopes);
PREP(deployAI);
PREP(deployRopes);
@ -18,3 +17,4 @@ PREP(onPrepareCommon);
PREP(onRopeBreak);
PREP(prepareFRIES);
PREP(stowFRIES);
PREP(unequipFRIES);

View File

@ -1,24 +0,0 @@
#include "script_component.hpp"
/*
* Author: BaerMitUmlaut
* Checks if the given helicopter still exits, and if not, destroys the FRIES.
*
* Arguments:
* 0: The helicopter <OBJECT>
* 1: The helicopter's FRIES <OBJECT>
*
* Return Value:
* None
*
* Example:
* [_vehicle, _fries] call ace_fastroping_fnc_checkVehicleThread
*
* Public: No
*/
params ["_vehicle", "_fries"];
if (isNull _vehicle) then {
deleteVehicle _fries;
} else {
[FUNC(checkVehicleThread), _this, 5] call CBA_fnc_waitAndExecute;
};

View File

@ -12,7 +12,7 @@
* Example:
* [_vehicle] call ace_fastroping_fnc_equipFRIES
*
* Public: No
* Public: Yes
*/
params ["_vehicle"];
@ -24,15 +24,8 @@ if !(isNumber (_config >> QGVAR(enabled))) then {
private _fries = (getText (_config >> QGVAR(friesType))) createVehicle [0, 0, 0];
_fries attachTo [_vehicle, (getArray (_config >> QGVAR(friesAttachmentPoint)))];
_vehicle setVariable [QGVAR(FRIES), _fries, true];
_vehicle addEventHandler ["Killed", {
params ["_vehicle"];
deleteVehicle (_vehicle getVariable [QGVAR(FRIES), objNull]);
_vehicle setVariable [QGVAR(FRIES), nil, true];
if !((_vehicle getVariable [QGVAR(deployedRopes), []] isEqualTo [])) then {
[_vehicle] call FUNC(cutRopes);
};
}];
[FUNC(checkVehicleThread), [_vehicle, _fries], 5] call CBA_fnc_waitAndExecute;
_vehicle addEventHandler ["Killed", FUNC(unequipFRIES)];
_vehicle addEventHandler ["Deleted", FUNC(unequipFRIES)];
};
};

View File

@ -0,0 +1,24 @@
#include "script_component.hpp"
/*
* Author: BaerMitUmlaut
* Removes FRIES from helicopter.
*
* Arguments:
* 0: The helicopter <OBJECT>
*
* Return Value:
* None
*
* Example:
* [_vehicle] call ace_fastroping_fnc_unequipFRIES
*
* Public: Yes
*/
params ["_vehicle"];
deleteVehicle (_vehicle getVariable [QGVAR(FRIES), objNull]);
_vehicle setVariable [QGVAR(FRIES), nil, true];
if !((_vehicle getVariable [QGVAR(deployedRopes), []] isEqualTo [])) then {
[_vehicle] call FUNC(cutRopes);
};

View File

@ -15,13 +15,9 @@ if (!hasInterface) exitWith {};
};
}] call CBA_fnc_addEventHandler;
// Register fire event handler
["ace_firedPlayerVehicle", DFUNC(firedEH)] call CBA_fnc_addEventHandler;
["ace_firedPlayerVehicleNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler;
// Register event for global updates
[QGVAR(forceUpdate), {[ACE_player] call FUNC(onForceUpdate)}] call CBA_fnc_addEventHandler;
#ifdef DEBUG_MODE_FULL
call compile preprocessFileLineNumbers QPATHTOF(functions\dev_debugConfigs.sqf);
call compile preprocessFileLineNumbers QPATHTOF(dev\test_debugConfigs.sqf);
#endif

View File

@ -21,6 +21,13 @@ params ["_vehicle"];
private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _x] call EFUNC(common,getTurretConfigPath);
if (getNumber (_turretConfig >> QGVAR(Enabled)) == 1) then {
if (missionNamespace getVariable [QGVAR(needToAddFiredEH), true]) then {
["ace_firedPlayerVehicle", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler;
["ace_firedPlayerVehicleNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler;
GVAR(needToAddFiredEH) = false;
TRACE_1("Registered fired event handlers for all vehicles",GVAR(needToAddFiredEH));
};
_vehicle setVariable [format ["%1_%2", QGVAR(Distance), _x], 0, true];
_vehicle setVariable [format ["%1_%2", QGVAR(Magazines), _x], [], true];
_vehicle setVariable [format ["%1_%2", QGVAR(Elevation), _x], [], true];

View File

@ -6,7 +6,7 @@ class CfgWeapons {
EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code)
EGVAR(laser,showHud) = 1; // show attack profile / lock on hud
magazines[] = {"6Rnd_ACE_Hellfire_AGM114K", "PylonMissile_1Rnd_ACE_Hellfire_AGM114K", "PylonRack_1Rnd_ACE_Hellfire_AGM114K", "PylonRack_3Rnd_ACE_Hellfire_AGM114K", "PylonRack_4Rnd_ACE_Hellfire_AGM114K"};
magazineWell[] = {QGVAR(K)};
magazineWell[] += {QGVAR(K)};
autoFire = 0;
canLock = 0;
weaponLockSystem = 0;
@ -27,6 +27,6 @@ class CfgWeapons {
class GVAR(launcher_N): GVAR(launcher) {
displayName = "AGM-114N Hellfire II";
magazines[] = {"6Rnd_ACE_Hellfire_AGM114N", "PylonMissile_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_3Rnd_ACE_Hellfire_AGM114N", "PylonRack_4Rnd_ACE_Hellfire_AGM114N"};
magazineWell[] = {QGVAR(N)};
magazineWell[] += {QGVAR(N)};
};
};

View File

@ -56,7 +56,19 @@
"dd_pletivo.p3d",\
"plot_green_draty.p3d",\
"plot_rust_draty.p3d",\
"wall_fen1_5_2.p3d"\
"wall_fen1_5_2.p3d",\
"gm_fence_border_gssz_70_600.p3d",\
"gm_fence_border_gssz_70_gate_350_r.p3d",\
"gm_fence_border_gssz_70_gate_350_w.p3d",\
"gm_fence_border_gz1_600.p3d",\
"gm_fence_border_gz1_gate_350_r.p3d",\
"gm_fence_border_gz1_gate_350_w.p3d",\
"gm_fence_wirefence_01_01.p3d",\
"gm_fence_wirefence_01_02.p3d",\
"gm_fence_wirefence_01_03.p3d",\
"gm_gc_g501_sm70_01.p3d",\
"gm_gc_g501_sm70_02.p3d",\
"gm_gc_g501_sm70_03.p3d"\
]
#define SOUND_CLIP_TIME_SPACING 1.5

View File

@ -114,6 +114,7 @@ GVAR(vehicleLightColor) = [1,1,1,0];
switch (true) do {
case (_vehicle isKindOf "Tank");
case (_vehicle isKindOf "Wheeled_APC"): { {true} };
case (_vehicle isKindOf "ParachuteBase"): { {false} };
case (_vehicle isKindOf "Helicopter");
case (_vehicle isKindOf "Plane"): { {(driver _vehicle == _unit) || {gunner _vehicle == _unit}} };
default { {false} };

View File

@ -6,7 +6,7 @@ class CfgPatches {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_common"};
requiredAddons[] = {"ace_medical_engine"};
author = ECSTRING(common,ACETeam);
authors[] = {"Glowbal", "KoffeinFlummi","Arcanum417"};
url = ECSTRING(main,URL);

View File

@ -27,10 +27,13 @@
// Blood:
private _bloodVolume = GET_BLOOD_VOLUME(_unit);
private _woundBleeding = GET_WOUND_BLEEDING(_unit);
private _bloodLoss = GET_BLOOD_LOSS(_unit);
private _secondsToHeartstop = if (_bloodLoss != 0) then {format ["[<t color ='#FF9999'>Time Left:</t> %1 sec]", (((_bloodVolume - BLOOD_VOLUME_CLASS_4_HEMORRHAGE) max 0) / _bloodLoss) toFixed 1]} else {""};
_return pushBack format ["Blood: %1", _bloodVolume toFixed 3];
_return pushBack format [" - [Loss: %1] %2", _bloodLoss toFixed 5, _secondsToHeartstop];
private _hemorrhage = GET_HEMORRHAGE(_unit);
private _isBleeding = if (IS_BLEEDING(_unit)) then {"<t color ='#FF9999'>Bleeding</t>"} else {""};
private _secondsToHeartstop = if (_bloodLoss != 0) then {format ["[<t color ='#FF9999'>Time Left:</t> %1 sec]", (((_bloodVolume - BLOOD_VOLUME_CLASS_4_HEMORRHAGE) max 0) / _bloodLoss) toFixed 0]} else {""};
_return pushBack format ["Blood: %1 [Hemorrhage: %2] %3", _bloodVolume toFixed 3, _hemorrhage, _isBleeding];
_return pushBack format [" - [W: %1 T: %2] %3", _woundBleeding toFixed 4, _bloodLoss toFixed 4, _secondsToHeartstop];
// Heart:
private _cardiacOutput = [_unit] call EFUNC(medical_status,getCardiacOutput);
@ -43,15 +46,19 @@
private _pain = GET_PAIN(_unit);
private _painSuppress = GET_PAIN_SUPPRESS(_unit);
private _painLevel = GET_PAIN_PERCEIVED(_unit);
_return pushBack format ["Effective Pain: %1", _painLevel toFixed 3];
private _isInPain = IS_IN_PAIN(_unit);
_return pushBack format ["Effective Pain: %1 [%2]", _painLevel toFixed 3, _isInPain];
_return pushBack format [" - [Pain: %1] [Suppress: %2]", _pain toFixed 3, _painSuppress toFixed 3];
// Damage:
private _damage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _limping = if (_unit getVariable [QEGVAR(medical,isLimping), false]) then {"[<t color ='#FFCC22'> Limping </t>]"} else {""};
_return pushBack format ["Damage: [H: %1] [B: %2] %3", (_damage select 0) toFixed 2, (_damage select 1) toFixed 2, _limping];
_return pushBack format ["Damage: [H: %1] [B: %2] %3", (_damage select 0) toFixed 2, (_damage select 1) toFixed 2];
_return pushBack format ["[LA:%1] [RA: %2] [LL:%3] [RL: %4]", (_damage select 2) toFixed 2, (_damage select 3) toFixed 2, (_damage select 4) toFixed 2, (_damage select 5) toFixed 2];
_return pushBack format ["Hitpoints: [HHed:%1] [HBod: %2]", (_unit getHitPointDamage "HitHead") toFixed 2, (_unit getHitPointDamage "HitBody") toFixed 2];
_return pushBack format ["[HHnd:%1] [HLeg: %2] %3", (_unit getHitPointDamage "HitHands") toFixed 2, (_unit getHitPointDamage "HitLegs") toFixed 2, _limping];
// Tourniquets:
_return pushBack "------- Tourniquets: -------";
@ -79,6 +86,21 @@
_return pushBack format ["%1: [%2-%3] [x%4] [Bld: %5] [Dmg: %6]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xCategory, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2];
} forEach _wounds;
// Bandaged Wounds:
_return pushBack "------- Bandaged Wounds: -------";
private _wounds = _unit getVariable [QEGVAR(medical,bandagedWounds), []];
{
_x params ["", "_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage", "_xCategory"];
_return pushBack format ["%1: [%2-%3] [x%4] [Bld: %5] [Dmg: %6]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xCategory, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2];
} forEach _wounds;
// Stitched Wounds:
_return pushBack "------- Stitched Wounds: -------";
private _wounds = _unit getVariable [QEGVAR(medical,stitchedWounds), []];
{
_x params ["", "_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage", "_xCategory"];
_return pushBack format ["%1: [%2-%3] [x%4] [Bld: %5] [Dmg: %6]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xCategory, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2];
} forEach _wounds;
// IVs:
_return pushBack "------- IVs: -------";
@ -88,10 +110,39 @@
_return pushBack format ["%1: %2 [%3 ml]", ALL_SELECTIONS select _xBodyPartN, _xType, _xVolumeAdded];
} forEach _ivBags;
// Medications:
_return pushBack "------- Medications: -------";
private _hrTargetAdjustment = 0;
private _painSupressAdjustment = 0;
private _peripheralResistanceAdjustment = 0;
private _medicationCounts = [];
private _rawMedications = (_unit getVariable [VAR_MEDICATIONS, []]) apply {
_x params ["_medication", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust"];
private _timeInSystem = CBA_missionTime - _timeAdded;
private _index = _medicationCounts find _medication;
if (_index < 0) then {
_index = _medicationCounts pushBack _medication;
_medicationCounts pushBack 0
};
_medicationCounts set [(_index + 1), (_medicationCounts select (_index + 1)) + linearConversion [_timeTillMaxEffect, _maxTimeInSystem, _timeInSystem, 1, 0, true]];
private _effectRatio = (((_timeInSystem / _timeTillMaxEffect) ^ 2) min 1) * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem;
_hrTargetAdjustment = _hrTargetAdjustment + _hrAdjust * _effectRatio;
_painSupressAdjustment = _painSupressAdjustment + _painAdjust * _effectRatio;
_peripheralResistanceAdjustment = _peripheralResistanceAdjustment + _flowAdjust * _effectRatio;
format ["%1 [%2 / %3][%4][%5,%6,%7]",_medication,_timeInSystem toFixed 0,_maxTimeInSystem toFixed 0, _effectRatio toFixed 2, _hrAdjust toFixed 1, _painAdjust toFixed 2, _flowAdjust toFixed 1];
};
_return pushBack format ["Adjusts: [HR %1][PS %2][PR %3]", _hrTargetAdjustment toFixed 2, _painSupressAdjustment toFixed 2, _peripheralResistanceAdjustment toFixed 2];
for "_i" from 0 to (count _medicationCounts) - 1 step 2 do {
_return pushBack format ["-%1: %2", _medicationCounts select _i, _medicationCounts select _i + 1];
};
_return pushBack "------- Medications Raw: -------";
_return append _rawMedications;
// Footer:
_return pushBack "</t>";
// Return:
_return joinString "<br/>"
}, [30]] call EFUNC(common,watchVariable);
}, [40]] call EFUNC(common,watchVariable);

View File

@ -23,7 +23,7 @@
// #define DEBUG_TESTRESULTS
params [["_unit", objNull, [objNull]], ["_damageToAdd", -1, [0]], ["_bodyPart", "", [""]], ["_typeOfDamage", "", [""]], ["_instigator", objNull, [objNull]]];
TRACE_5("params",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator);
TRACE_5("addDamageToUnit",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator);
private _bodyPartIndex = ALL_BODY_PARTS find (toLower _bodyPart);
if (isNull _unit || {!local _unit} || {!alive _unit}) exitWith {ERROR_1("addDamageToUnit - badUnit %1", _this); false};
@ -34,8 +34,8 @@ if (_bodyPartIndex < 0) exitWith {ERROR_1("addDamageToUnit - bad selection %1",
_bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] select _bodyPartIndex;
if (!isNull _instigator) then {
_unit setVariable [QEGVAR(medical_engine,lastShooter), _instigator];
_unit setVariable [QEGVAR(medical_engine,lastInstigator), _instigator];
_unit setVariable [QEGVAR(medical,lastDamageSource), _instigator];
_unit setVariable [QEGVAR(medical,lastInstigator), _instigator];
};
#ifdef DEBUG_TESTRESULTS

View File

@ -14,5 +14,5 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -14,5 +14,5 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_AI
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -14,8 +14,8 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_BLOOD
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"
#define MAX_BLOOD_OBJECTS 500
#define BLOOD_OBJECT_LIFETIME 900

View File

@ -19,7 +19,7 @@
*/
params ["_unit", "_bodyPart", "_damage", "_typeOfDamage"];
TRACE_5("start",_unit,_bodyPart,_damage,_typeOfDamage);
TRACE_4("start",_unit,_bodyPart,_damage,_typeOfDamage);
if (_typeOfDamage isEqualTo "") then {
_typeOfDamage = "unknown";
@ -129,6 +129,8 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra
_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true];
_unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
[_unit] call EFUNC(medical_status,updateWoundBloodLoss);
_bodyPartVisParams call EFUNC(medical_engine,updateBodyPartVisuals);
[QEGVAR(medical,injured), [_unit, _painLevel]] call CBA_fnc_localEvent;

View File

@ -180,6 +180,8 @@ private _woundsCreated = [];
_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true];
_unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
[_unit] call EFUNC(medical_status,updateWoundBloodLoss);
_bodyPartVisParams call EFUNC(medical_engine,updateBodyPartVisuals);
[QEGVAR(medical,injured), [_unit, _painLevel]] call CBA_fnc_localEvent;

View File

@ -14,5 +14,5 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_DAMAGE
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -20,7 +20,7 @@
_unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}]
];
};
}, nil, nil, true] call CBA_fnc_addClassEventHandler;
}, nil, [IGNORE_BASE_UAVPILOTS], true] call CBA_fnc_addClassEventHandler;
#ifdef DEBUG_MODE_FULL
[QEGVAR(medical,woundReceived), {
@ -30,24 +30,6 @@
}] call CBA_fnc_addEventHandler;
#endif
// Kill vanilla bleeding feedback effects.
#ifdef DISABLE_VANILLA_DAMAGE_EFFECTS
[{
{isNil _x} count [
"BIS_fnc_feedback_damageCC",
"BIS_fnc_feedback_damageRadialBlur",
"BIS_fnc_feedback_damageBlur"
] == 0
}, {
{
ppEffectDestroy _x;
} forEach [
BIS_fnc_feedback_damageCC,
BIS_fnc_feedback_damageRadialBlur,
BIS_fnc_feedback_damageBlur
];
}] call CBA_fnc_waitUntilAndExecute;
#endif
// this handles moving units into vehicles via load functions or zeus
// needed, because the vanilla INCAPACITATED state does not handle vehicles

View File

@ -45,8 +45,8 @@ if (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) exitWith {_oldDa
// This hitpoint is set to trigger last, evaluate all the stored damage values
// to determine where wounds are applied
if (_hitPoint isEqualTo "ace_hdbracket") exitWith {
_unit setVariable [QGVAR(lastShooter), _shooter];
_unit setVariable [QGVAR(lastInstigator), _instigator];
_unit setVariable [QEGVAR(medical,lastDamageSource), _shooter];
_unit setVariable [QEGVAR(medical,lastInstigator), _instigator];
private _damageStructural = _unit getVariable [HIT_STRUCTURAL, 0];

View File

@ -14,8 +14,8 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_ENGINE
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_config.hpp"
#define PRELOAD_CLASS(class) \

View File

@ -1,3 +1,7 @@
// #define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS
#define ALL_BODY_PARTS ["head", "body", "leftarm", "rightarm", "leftleg", "rightleg"]
#define ALL_SELECTIONS ["head", "body", "hand_l", "hand_r", "leg_l", "leg_r"]
@ -108,6 +112,7 @@
// Defined here for easy consistency with GETVAR/SETVAR (also a list for reference)
#define VAR_BLOOD_PRESS QEGVAR(medical,bloodPressure)
#define VAR_BLOOD_VOL QEGVAR(medical,bloodVolume)
#define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding)
#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest)
#define VAR_HEART_RATE QEGVAR(medical,heartRate)
#define VAR_PAIN QEGVAR(medical,pain)
@ -115,13 +120,10 @@
#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance)
#define VAR_UNCON "ACE_isUnconscious"
// These variables track gradual adjustments (from medication, etc.)
#define VAR_HEART_RATE_ADJ QEGVAR(medical,heartRateAdjustments)
#define VAR_PAIN_SUPP_ADJ QEGVAR(medical,painSuppressAdjustments)
#define VAR_PERIPH_RES_ADJ QEGVAR(medical,peripheralResistanceAdjustments)
#define VAR_MEDICATIONS QEGVAR(medical,medications)
// These variables track the current state of status values above
#define VAR_HEMORRHAGE QEGVAR(medical,hemorrhage)
#define VAR_IN_PAIN QEGVAR(medical,inPain)
#define VAR_IS_BLEEDING QEGVAR(medical,isBleeding)
#define VAR_TOURNIQUET QEGVAR(medical,tourniquets)
@ -129,13 +131,14 @@
// Retrieval macros for common unit values
// Defined for easy consistency and speed
#define GET_BLOOD_VOLUME(unit) (unit getVariable [VAR_BLOOD_VOL,DEFAULT_BLOOD_VOLUME])
#define GET_WOUND_BLEEDING(unit) (unit getVariable [VAR_WOUND_BLEEDING,0])
#define GET_HEART_RATE(unit) (unit getVariable [VAR_HEART_RATE,DEFAULT_HEART_RATE])
#define GET_HEMORRHAGE(unit) (unit getVariable [VAR_HEMORRHAGE,0])
#define GET_PAIN(unit) (unit getVariable [VAR_PAIN,0])
#define GET_PAIN_SUPPRESS(unit) (unit getVariable [VAR_PAIN_SUPP,0])
#define GET_TOURNIQUETS(unit) (unit getVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES])
#define IN_CRDC_ARRST(unit) (unit getVariable [VAR_CRDC_ARRST,false])
#define IS_BLEEDING(unit) (unit getVariable [VAR_IS_BLEEDING,false])
#define IS_BLEEDING(unit) (GET_WOUND_BLEEDING(unit) > 0)
#define IS_IN_PAIN(unit) (unit getVariable [VAR_IN_PAIN,false])
#define IS_UNCONSCIOUS(unit) (unit getVariable [VAR_UNCON,false])
@ -151,3 +154,6 @@
// Cache expiry values, in seconds
#define IN_MEDICAL_FACILITY_CACHE_EXPIRY 1
#define CAN_TREAT_CONDITION_CACHE_EXPIRY 2
// Ignore UAV/Drone AI Base Classes
#define IGNORE_BASE_UAVPILOTS "B_UAV_AI", "O_UAV_AI", "UAV_AI_base_F"

View File

@ -70,3 +70,24 @@ GVAR(heartBeatEffectRunning) = false;
[_status, 0] call FUNC(effectUnconscious);
["unconscious", _status] call EFUNC(common,setDisableUserInputStatus);
}] call CBA_fnc_addPlayerEventHandler;
// Kill vanilla bleeding feedback effects.
#ifdef DISABLE_VANILLA_DAMAGE_EFFECTS
TRACE_1("disabling vanilla bleeding feedback effects",_this);
[{
{isNil _x} count [
"BIS_fnc_feedback_damageCC",
"BIS_fnc_feedback_damageRadialBlur",
"BIS_fnc_feedback_damageBlur"
] == 0
}, {
{
ppEffectDestroy _x;
} forEach [
BIS_fnc_feedback_damageCC,
BIS_fnc_feedback_damageRadialBlur,
BIS_fnc_feedback_damageBlur
];
}] call CBA_fnc_waitUntilAndExecute;
#endif

View File

@ -14,8 +14,8 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_FEEDBACK
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"
#define EMPTY_SOUND {"A3\Sounds_F\dummysound.wss",1,1}
#define NAMESPACE_NULL locationNull

View File

@ -14,8 +14,8 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_GUI
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"
#include "\a3\ui_f\hpp\defineResincl.inc"
#include "\a3\ui_f\hpp\defineDIKCodes.inc"

View File

@ -14,5 +14,5 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_STATEMACHINE
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -1,4 +1,4 @@
PREP(addHeartRateAdjustment);
PREP(addMedicationAdjustment);
PREP(adjustPainLevel);
PREP(getBloodLoss);
PREP(getBloodPressure);
@ -12,3 +12,4 @@ PREP(isInStableCondition);
PREP(setCardiacArrest);
PREP(setDead);
PREP(setUnconscious);
PREP(updateWoundBloodLoss);

View File

@ -1,21 +0,0 @@
#include "script_component.hpp"
/*
* Author: BaerMitUmlaut
* Adds a heart rate adjustment that will take effect over time.
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Heart rate change <NUMBER>
* 2: Time in system for the adjustment to reach its peak <NUMBER>
* 3: Duration the adjustment will have an effect <NUMVER>
*
* Return Value:
* None
*/
params ["_unit", "_change", "_timeToMaxEffect", "_maxTimeInSystem"];
private _adjustments = _unit getVariable [VAR_HEART_RATE_ADJ,[]];
// The last number indicates the time the adjustment is already in the system
_adjustments pushBack [_change, _timeToMaxEffect, _maxTimeInSystem, 0];
_unit setVariable [VAR_HEART_RATE_ADJ, _adjustments];

View File

@ -0,0 +1,32 @@
#include "script_component.hpp"
/*
* Author: BaerMitUmlaut, PabstMirror
* Adds a medication and it's effects
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Medication <STRING>
* 2: Time in system for the adjustment to reach its peak <NUMBER>
* 3: Duration the adjustment will have an effect <NUMVER>
* 4: Heart Rate Adjust <NUMVER>
* 5: Pain Suppress Adjust <NUMVER>
* 6: Flow Adjust <NUMVER>
*
* Return Value:
* None
*
* Example:
* [player, "Morphine", 120, 60, -10, 0.8, -10] call ace_medical_status_fnc_addMedicationAdjustment
*/
params ["_unit", "_medication", "_timeToMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust"];
TRACE_7("addMedicationAdjustment",_unit,_medication,_timeToMaxEffect,_maxTimeInSystem,_hrAdjust,_painAdjust,_flowAdjust);
if (_maxTimeInSystem <= 0) exitWith { WARNING_1("bad value for _maxTimeInSystem - %1",_this); };
_timeToMaxEffect = _timeToMaxEffect max 1;
private _adjustments = _unit getVariable [VAR_MEDICATIONS, []];
_adjustments pushBack [_medication, CBA_missionTime, _timeToMaxEffect, _maxTimeInSystem, _hrAdjust, _painAdjust, _flowAdjust];
_unit setVariable [VAR_MEDICATIONS, _adjustments, true];

View File

@ -10,31 +10,16 @@
* Total blood loss of unit <NUMBER>
*
* Example:
* [bob] call ace_medical_status_fnc_getBloodLoss
* [player] call ace_medical_status_fnc_getBloodLoss
*
* Public: No
*/
params ["_unit"];
private _tourniquets = GET_TOURNIQUETS(_unit);
private _bodyPartBleeding = [0,0,0,0,0,0];
{
_x params ["", "", "_bodyPart", "_amountOf", "_bleeeding"];
if (_tourniquets select _bodyPart == 0) then {
_bodyPartBleeding set [_bodyPart, (_bodyPartBleeding select _bodyPart) + (_amountOf * _bleeeding)];
};
} forEach (_unit getVariable [QEGVAR(medical,openWounds), []]);
if (_bodyPartBleeding isEqualTo [0,0,0,0,0,0]) exitWith { 0 };
_bodyPartBleeding params ["_headBleeding", "_bodyBleeding", "_leftArmBleeding", "_rightArmBleeding", "_leftLegBleeding", "_rightLegBleeding"];
private _bodyBleedingRate = ((_headBleeding min 0.9) + (_bodyBleeding min 1.0)) min 1.0;
private _limbBleedingRate = ((_leftArmBleeding min 0.3) + (_rightArmBleeding min 0.3) + (_leftLegBleeding min 0.5) + (_rightLegBleeding min 0.5)) min 1.0;
// limb bleeding is scaled down based on the amount of body bleeding
_limbBleedingRate = _limbBleedingRate * (1 - _bodyBleedingRate);
private _woundBleeding = GET_WOUND_BLEEDING(_unit);
if (_woundBleeding == 0) exitWith {0};
private _cardiacOutput = [_unit] call FUNC(getCardiacOutput);
((_bodyBleedingRate + _limbBleedingRate) * _cardiacOutput * EGVAR(medical,bleedingCoefficient))
(_woundBleeding * _cardiacOutput * EGVAR(medical,bleedingCoefficient))

View File

@ -19,7 +19,6 @@
params ["_unit", "_deltaT", "_syncValues"];
private _bloodVolume = GET_BLOOD_VOLUME(_unit);
private _bloodVolumeChange = -_deltaT * GET_BLOOD_LOSS(_unit);
if (!isNil {_unit getVariable QEGVAR(medical,ivBags)}) then {

View File

@ -21,12 +21,12 @@
*/
// to limit the amount of complex calculations necessary, we take a set modifier to calculate Stroke Volume.
#define MODIFIER_CARDIAC_OUTPUT 19.04761
#define MODIFIER_CARDIAC_OUTPUT 0.1904761
params ["_unit"];
private _bloodVolume = (GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME) * 100;
private _bloodVolumeRatio = (GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME);
private _heartRate = GET_HEART_RATE(_unit);
private _cardiacOutput = ((_bloodVolume / MODIFIER_CARDIAC_OUTPUT) + ((_heartRate / DEFAULT_HEART_RATE) - 1)) / 60;
private _cardiacOutput = ((_bloodVolumeRatio / MODIFIER_CARDIAC_OUTPUT) + ((_heartRate / DEFAULT_HEART_RATE) - 1)) / 60;
(0 max _cardiacOutput)

View File

@ -26,19 +26,15 @@ if (damage _unit > 0) then {
// - Blood and heart ----------------------------------------------------------
_unit setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true];
_unit setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true];
_unit setVariable [VAR_HEART_RATE_ADJ, [], true];
_unit setVariable [VAR_BLOOD_PRESS, [80, 120], true];
_unit setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true];
_unit setVariable [VAR_PERIPH_RES_ADJ, [], true];
_unit setVariable [VAR_CRDC_ARRST, false, true];
_unit setVariable [VAR_HEMORRHAGE, 0, true];
_unit setVariable [VAR_IS_BLEEDING, false, true];
// - Pain ---------------------------------------------------------------------
_unit setVariable [VAR_PAIN, 0, true];
_unit setVariable [VAR_IN_PAIN, false, true];
_unit setVariable [VAR_PAIN_SUPP, 0, true];
_unit setVariable [VAR_PAIN_SUPP_ADJ, [], true];
// - Wounds -------------------------------------------------------------------
_unit setVariable [QEGVAR(medical,openWounds), [], true];
@ -54,6 +50,9 @@ _unit setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true];
_unit setVariable [QEGVAR(medical,occludedMedications), nil, true]; //Delayed Medications (from tourniquets)
_unit setVariable [QEGVAR(medical,ivBags), nil, true];
// - Update wound bleeding
[_unit] call EFUNC(medical_status,updateWoundBloodLoss);
// triage card and logs
_unit setVariable [QEGVAR(medical,triageLevel), 0, true];
_unit setVariable [QEGVAR(medical,triageCard), [], true];
@ -65,11 +64,7 @@ _unit setVariable [QEGVAR(medical,bodyPartStatus), [0,0,0,0,0,0], true];
#endif
// medication
private _allUsedMedication = _unit getVariable [QEGVAR(medical,allUsedMedication), []];
{
_unit setVariable [_x select 0, nil];
} forEach _allUsedMedication;
_unit setVariable [QEGVAR(medical,allUsedMedication), [], true];
_unit setVariable [VAR_MEDICATIONS, [], true];
// TODO move to treatment
private _logs = _unit getVariable [QEGVAR(medical,allLogs), []];

View File

@ -19,5 +19,5 @@ params ["_unit"];
(alive _unit
&& {!IS_UNCONSCIOUS(_unit)}
&& {GET_BLOOD_LOSS(_unit) == 0}
&& {GET_WOUND_BLEEDING(_unit) == 0}
&& {_unit call FUNC(hasStableVitals)})

View File

@ -22,7 +22,7 @@ _unit setVariable [VAR_BLOOD_PRESS, [0, 0], true];
// Kill the unit without changing visual apperance
[_unit, 1] call EFUNC(medical_engine,setStructuralDamage);
private _lastShooter = _unit getVariable [QEGVAR(medical_engine,lastShooter), objNull];
private _lastInstigator = _unit getVariable [QEGVAR(medical_engine,lastInstigator), objNull];
private _lastShooter = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull];
private _lastInstigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull];
["ace_killed", [_unit, _reason, _lastShooter, _lastInstigator]] call CBA_fnc_globalEvent;

View File

@ -0,0 +1,42 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Update total wound bleeding based on open wounds and tourniquets
*
* Arguments:
* 0: The Unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call ace_medical_status_fnc_updateWoundBloodLoss
*
* Public: No
*/
params ["_unit"];
private _tourniquets = GET_TOURNIQUETS(_unit);
private _bodyPartBleeding = [0,0,0,0,0,0];
{
_x params ["", "", "_bodyPart", "_amountOf", "_bleeeding"];
if (_tourniquets select _bodyPart == 0) then {
_bodyPartBleeding set [_bodyPart, (_bodyPartBleeding select _bodyPart) + (_amountOf * _bleeeding)];
};
} forEach (_unit getVariable [QEGVAR(medical,openWounds), []]);
if (_bodyPartBleeding isEqualTo [0,0,0,0,0,0]) then {
TRACE_1("updateWoundBloodLoss-none",_unit);
_unit setVariable [VAR_WOUND_BLEEDING, 0, true];
} else {
_bodyPartBleeding params ["_headBleeding", "_bodyBleeding", "_leftArmBleeding", "_rightArmBleeding", "_leftLegBleeding", "_rightLegBleeding"];
private _bodyBleedingRate = ((_headBleeding min 0.9) + (_bodyBleeding min 1.0)) min 1.0;
private _limbBleedingRate = ((_leftArmBleeding min 0.3) + (_rightArmBleeding min 0.3) + (_leftLegBleeding min 0.5) + (_rightLegBleeding min 0.5)) min 1.0;
// limb bleeding is scaled down based on the amount of body bleeding
_limbBleedingRate = _limbBleedingRate * (1 - _bodyBleedingRate);
TRACE_3("updateWoundBloodLoss-bleeding",_unit,_bodyBleedingRate,_limbBleedingRate);
_unit setVariable [VAR_WOUND_BLEEDING, _bodyBleedingRate + _limbBleedingRate, true];
};

View File

@ -14,5 +14,5 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_STATUS
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -18,13 +18,14 @@
*/
params ["_target", "_impact", "_part", "_injuryIndex", "_injury", "_bandage"];
TRACE_6("handleBandageOpening",_target,_impact,_part,_injuryIndex,_injury,_bandage);
private _classID = _injury select 1;
private _bodyPartN = _injury select 2;
private _category = _injury select 6;
private _postfix = ["Minor", "Medium", "Large"] select _category;
private _className = format ["%1%2", EGVAR(medical_damage,woundClassNames) select _classID, _postfix];
private _reopeningChance = DEFAULT_BANDAGE_REOPENING_CHANCE;
private _reopeningMinDelay = DEFAULT_BANDAGE_REOPENING_MIN_DELAY;
private _reopeningMaxDelay = DEFAULT_BANDAGE_REOPENING_MAX_DELAY;
@ -63,7 +64,7 @@ TRACE_5("configs",_bandage,_className,_reopeningChance,_reopeningMinDelay,_reope
private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []];
private _exist = false;
{
_x params ["", "_id", "_partN", "_amountOf", "_bleeding", "_damage", "_oldCategory"];
_x params ["", "_id", "_partN", "_amountOf", "", "", "_oldCategory"];
if (_id == _classID && {_partN == _bodyPartN && {_oldCategory == _category}}) exitWith {
_x set [3, _amountOf + _impact];
_bandagedWounds set [_forEachIndex, _x];
@ -79,6 +80,10 @@ if (!_exist) then {
_target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true];
// _reopeningChance = 1;
// _reopeningMinDelay = 5;
// _reopeningMaxDelay = 6;
TRACE_1("",_reopeningChance);
// Check if we are ever going to reopen this
if (random 1 <= _reopeningChance) then {
@ -86,19 +91,19 @@ if (random 1 <= _reopeningChance) then {
TRACE_1("Will open",_delay);
[{
params ["_target", "_impact", "_part", "_injuryIndex", "_injury"];
TRACE_5("params",_target,_impact,_part,_injuryIndex,_injury);
TRACE_5("reopen delay finished",_target,_impact,_part,_injuryIndex,_injury);
private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []];
if (count _openWounds - 1 < _injuryIndex) exitWith {};
if (count _openWounds - 1 < _injuryIndex) exitWith { TRACE_2("index bounds",_injuryIndex,count _openWounds); };
_injury params ["", "_classID", "_bodyPartN", "", "", "", "_category"];
_injury params ["", "_classID", "_bodyPartN"];
private _selectedInjury = _openWounds select _injuryIndex;
if (_selectedInjury select 1 == _classID && {_selectedInjury select 2 == _bodyPartN}) then { // matching the IDs
private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []];
private _exist = false;
{
_x params ["", "_id", "_partN", "_amountOf", "_bleeding", "_damage", "_oldCategory"];
_x params ["", "_id", "_partN", "_amountOf", "", "", "_oldCategory"];
if (_id == _classID && {_partN == _bodyPartN && {_oldCategory == _category}}) exitWith {
_x set [3, 0 max (_amountOf - _impact)];
_bandagedWounds set [_forEachIndex, _x];
@ -112,7 +117,11 @@ if (random 1 <= _reopeningChance) then {
_openWounds set [_injuryIndex, _selectedInjury];
_target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true];
_target setVariable [QEGVAR(medical,openWounds), _openWounds, true];
[_target] call EFUNC(medical_status,updateWoundBloodLoss);
};
} else {
TRACE_3("no match",_selectedInjury,_classID,_bodyPartN);
};
}, [_target, _impact, _part, _injuryIndex, +_injury], _delay] call CBA_fnc_waitAndExecute;
};

View File

@ -65,7 +65,7 @@ private _createLitter = {
{
if (count _x < MIN_ENTRIES_LITTER_CONFIG) then {
WARNING_2("Wrong litter array: %1",_x);
WARNING_1("Wrong litter array: %1",_x);
} else {
_x params [
["_selection", "", [""]],

View File

@ -6,69 +6,69 @@
* Arguments:
* 0: The patient <OBJECT>
* 1: Medication Treatment classname <STRING>
* 2: The medication treatment variablename <STRING>
* 3: Max dosage <NUMBER>
* 4: Incompatable medication <ARRAY<STRING>>
* 2: Max dosage <NUMBER>
* 3: Incompatable medication <ARRAY<STRING>>
*
* Return Value:
* None
*
* Example:
* [bob, "classname", "varname", 5, 6, ["stuff"]] call ace_medical_treatment_fnc_onMedicationUsage
* [player, "morphine", 4, [["x", 1]]] call ace_medical_treatment_fnc_onMedicationUsage
*
* Public: No
*/
params ["_target", "_className", "_variable", "_maxDosage", "_incompatabileMeds"];
TRACE_5("params",_target,_className,_variable,_maxDosage,_incompatabileMeds);
params ["_target", "_className", "_maxDosage", "_incompatabileMeds"];
TRACE_4("onMedicationUsage",_target,_className,_maxDosage,_incompatabileMeds);
private _foundEntry = false;
private _allUsedMedication = _target getVariable [QEGVAR(medical,allUsedMedication), []];
{
_x params ["_variableX", "_allMedsFromClassname"];
if (_variableX == _variable) exitWith {
if !(_className in _allMedsFromClassname) then {
_allMedsFromClassname pushBack _className;
_x set [1, _allMedsFromClassname];
_allUsedMedication set [_forEachIndex, _x];
_target setVariable [QEGVAR(medical,allUsedMedication), _allUsedMedication];
};
_foundEntry = true;
};
} forEach _allUsedMedication;
if (!_foundEntry) then {
_allUsedMedication pushBack [_variable, [_className]];
_target setVariable [QEGVAR(medical,allUsedMedication), _allUsedMedication];
};
private _usedMeds = _target getVariable [_variable, 0];
if (_usedMeds >= floor (_maxDosage + round(random(2))) && {_maxDosage >= 1}) then {
[QEGVAR(medical,CriticalVitals), _target] call CBA_fnc_localEvent;
};
private _hasOverDosed = 0;
{
_x params ["_med", "_limit"];
private _fnc_getMedicationCount = {
params ["_target", "_medication"];
private _return = 0;
{
_x params ["", "_classNamesUsed"];
if ({_x == _med} count _classNamesUsed > _limit) then {
_hasOverDosed = _hasOverDosed + 1;
_x params ["_xMed", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem"];
if (_xMed == _medication) then {
private _timeInSystem = CBA_missionTime - _timeAdded;
_return = _return + linearConversion [_timeTillMaxEffect, _maxTimeInSystem, _timeInSystem, 1, 0, true];
};
} forEach _allUsedMedication;
} forEach (_target getVariable [VAR_MEDICATIONS, []]);
TRACE_2("getMedicationCount",_medication,_return);
_return
};
private _overdosedMedications = [];
// Check for overdose from current medication
private _currentDose = [_target, _className] call _fnc_getMedicationCount;
if (_currentDose >= floor (_maxDosage + round(random(2))) && {_maxDosage >= 1}) then {
TRACE_1("exceeded max dose",_currentDose);
_overdosedMedications pushBackUnique _className;
};
// Check incompatible medication (format [med,limit])
{
_x params ["_xMed", "_xLimit"];
private _inSystem = [_target, _xMed] call _fnc_getMedicationCount;
if (_inSystem> _xLimit) then {
_overdosedMedications pushBackUnique _xMed;
};
} forEach _incompatabileMeds;
if (_hasOverDosed > 0) then {
if !(_overdosedMedications isEqualTo []) then {
private _medicationConfig = (configFile >> "ace_medical_treatment" >> "Medication");
private _onOverDose = getText (_medicationConfig >> "onOverDose");
if (isClass (_medicationConfig >> _className)) then {
_medicationConfig = (_medicationConfig >> _className);
if (isText (_medicationConfig >> "onOverDose")) then { _onOverDose = getText (_medicationConfig >> "onOverDose"); };
if (isText (_medicationConfig >> "onOverDose")) then { _onOverDose = getText (_medicationConfig >> "onOverDose"); };
};
TRACE_2("overdose",_overdosedMedications,_onOverDose);
if (_onOverDose == "") exitWith {
TRACE_1("CriticalVitals Event",_target); // make unconscious
[QEGVAR(medical,CriticalVitals), _target] call CBA_fnc_localEvent;
};
if (isNil _onOverDose) then {
_onOverDose = compile _onOverDose;
} else {
_onOverDose = missionNamespace getVariable _onOverDose;
};
[_target, _className] call _onOverDose;
[_target, _className, _overdosedMedications] call _onOverDose;
};

View File

@ -38,6 +38,8 @@ _openWounds set [_woundIndex, _wound];
_target setVariable [QEGVAR(medical,openWounds), _openWounds, true];
[_target] call EFUNC(medical_status,updateWoundBloodLoss);
// Handle the reopening of bandaged wounds
if (_impact > 0 && {GVAR(advancedBandages) && {GVAR(woundReopening)}}) then {
[_target, _impact, _partIndex, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening);

View File

@ -40,12 +40,13 @@ _target setVariable [QEGVAR(medical,bandagedWounds), [], true];
_target setVariable [QEGVAR(medical,stitchedWounds), [], true];
_target setVariable [QEGVAR(medical,isLimping), false, true];
// - Update wound bleeding
[_target] call EFUNC(medical_status,updateWoundBloodLoss);
// vitals
_target setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true];
_target setVariable [VAR_HEART_RATE_ADJ, [], true];
_target setVariable [VAR_BLOOD_PRESS, [80, 120], true];
_target setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true];
_target setVariable [VAR_PERIPH_RES_ADJ, [], true];
// IVs
_target setVariable [QEGVAR(medical,ivBags), nil, true];
@ -60,17 +61,11 @@ _target setVariable [QEGVAR(medical,bodyPartStatus), [0,0,0,0,0,0], true];
_target setVariable [VAR_CRDC_ARRST, false, true];
_target setVariable [VAR_UNCON, false, true];
_target setVariable [VAR_HEMORRHAGE, 0, true];
_target setVariable [VAR_IS_BLEEDING, false, true];
_target setVariable [VAR_IN_PAIN, false, true];
_target setVariable [VAR_PAIN_SUPP, 0, true];
_target setVariable [VAR_PAIN_SUPP_ADJ, [], true];
// medication
private _allUsedMedication = _target getVariable [QEGVAR(medical,allUsedMedication), []];
{
_target setVariable [_x select 0, nil];
} forEach _allUsedMedication;
_target setVariable [VAR_MEDICATIONS, [], true];
// Reset triage card since medication is all reset
_target setVariable [QEGVAR(medical,triageCard), [], true];

View File

@ -11,12 +11,17 @@
* Return Value:
* Succesful treatment started <BOOL>
*
* Example:
* [player, "Morphine", 2] call ace_medical_treatment_fnc_treatmentMedicationLocal
*
* Public: No
*/
#define MORPHINE_PAIN_SUPPRESSION 0.6
params ["_target", "_className", "_partIndex"];
TRACE_3("params",_target,_className,_partIndex);
TRACE_3("treatmentMedicationLocal",_target,_className,_partIndex);
if (!alive _target) exitWith {false};
if (!GVAR(advancedMedication)) exitWith {
TRACE_1("MedicalSettingAdvancedMedication is:", GVAR(advancedMedication));
@ -42,11 +47,6 @@ if (_tourniquets select _partIndex > 0) exitWith {
true
};
// We have added a new dose of this medication to our system, so let's increase it
private _varName = format [QGVAR(%1_inSystem), _className];
private _currentInSystem = _target getVariable [_varName, 0];
_target setVariable [_varName, _currentInSystem + 1];
// Find the proper attributes for the used medication
private _medicationConfig = configFile >> QUOTE(ADDON) >> "Medication";
private _painReduce = getNumber (_medicationConfig >> "painReduce");
@ -57,7 +57,6 @@ private _timeInSystem = getNumber (_medicationConfig >> "timeInSystem");
private _timeTillMaxEffect = getNumber (_medicationConfig >> "timeTillMaxEffect");
private _maxDose = getNumber (_medicationConfig >> "maxDose");
private _viscosityChange = getNumber (_medicationConfig >> "viscosityChange");
private _inCompatableMedication = [];
if (isClass (_medicationConfig >> _className)) then {
@ -73,35 +72,16 @@ if (isClass (_medicationConfig >> _className)) then {
if (isNumber (_medicationConfig >> "viscosityChange")) then { _viscosityChange = getNumber (_medicationConfig >> "viscosityChange"); };
};
if (alive _target) then {
private _heartRate = GET_HEART_RATE(_target);
private _hrIncrease = [_hrIncreaseLow, _hrIncreaseNorm, _hrIncreaseHigh] select (floor ((0 max _heartRate min 110) / 55));
_hrIncrease params ["_minIncrease", "_maxIncrease"];
private _heartRateChange = _minIncrease + random (_maxIncrease - _minIncrease);
private _heartRate = GET_HEART_RATE(_target);
private _hrIncrease = [_hrIncreaseLow, _hrIncreaseNorm, _hrIncreaseHigh] select (floor ((0 max _heartRate min 110) / 55));
_hrIncrease params ["_minIncrease", "_maxIncrease"];
private _heartRateChange = _minIncrease + random (_maxIncrease - _minIncrease);
// Adjust the heart rate based upon config entry
if (_heartRateChange != 0) then {
TRACE_1("heartRateChange", _heartRateChange);
private _adjustments = _target getVariable [VAR_HEART_RATE_ADJ,[]];
_adjustments pushBack [_heartRateChange, _timeTillMaxEffect, _timeInSystem, 0];
_target setVariable [VAR_HEART_RATE_ADJ, _adjustments];
};
// Adjust the medication effects and add the medication to the list
TRACE_3("adjustments",_heartRateChange,_painReduce,_viscosityChange);
[_target, _className, _timeTillMaxEffect, _timeInSystem, _heartRateChange, _painReduce, _viscosityChange] call EFUNC(medical_status,addMedicationAdjustment);
// Adjust the pain suppression based upon config entry
if (_painReduce > 0) then {
TRACE_1("painReduce", _painReduce);
private _adjustments = _target getVariable [VAR_PAIN_SUPP_ADJ,[]];
_adjustments pushBack [_painReduce, _timeTillMaxEffect, _timeInSystem, 0];
_target setVariable [VAR_PAIN_SUPP_ADJ, _adjustments];
};
// Adjust the peripheral resistance based upon config entry
if (_viscosityChange != 0) then {
TRACE_1("viscosityChange", _viscosityChange);
private _adjustments = _target getVariable [VAR_PERIPH_RES_ADJ,[]];
_adjustments pushBack [_viscosityChange, _timeTillMaxEffect, _timeInSystem, 0];
_target setVariable [VAR_PERIPH_RES_ADJ, _adjustments];
};
};
// Check for medication compatiblity
[_target, _className, _maxDose, _inCompatableMedication] call FUNC(onMedicationUsage);
true

View File

@ -34,6 +34,7 @@ if (_totalTime - _elapsedTime <= (count _bandagedWounds - 1) * 5) then {
_stitchedWounds pushBack _treatedWound;
_target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true];
_target setVariable [QEGVAR(medical,stitchedWounds), _stitchedWounds, true];
TRACE_3("stitched",_treatedWound,count _bandagedWounds,count _stitchedWounds);
};
true

View File

@ -24,3 +24,5 @@ private _tourniquets = GET_TOURNIQUETS(_target);
_tourniquets set [_partIndex, CBA_missionTime];
_target setVariable [VAR_TOURNIQUET, _tourniquets, true];
[_target] call EFUNC(medical_status,updateWoundBloodLoss);

View File

@ -30,6 +30,8 @@ if (_tourniquets select _partIndex == 0) exitWith {
_tourniquets set [_partIndex, 0];
_target setVariable [VAR_TOURNIQUET, _tourniquets, true];
[_target] call EFUNC(medical_status,updateWoundBloodLoss);
// Adding the tourniquet item to the caller
[_caller, "ACE_tourniquet", true] call CBA_fnc_addItem;

View File

@ -14,5 +14,5 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_TREATMENT
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -51,17 +51,7 @@ if (_hemorrhage != GET_HEMORRHAGE(_unit)) then {
_unit setVariable [VAR_HEMORRHAGE, _hemorrhage, true];
};
private _bloodLoss = GET_BLOOD_LOSS(_unit);
if (_bloodLoss > 0) then {
_unit setVariable [QGVAR(bloodloss), _bloodLoss, _syncValues];
if !IS_BLEEDING(_unit) then {
_unit setVariable [VAR_IS_BLEEDING, true, true];
};
} else {
if IS_BLEEDING(_unit) then {
_unit setVariable [VAR_IS_BLEEDING, false, true];
};
};
private _woundBloodLoss = GET_WOUND_BLEEDING(_unit);
private _inPain = GET_PAIN_PERCEIVED(_unit) > 0;
if !(_inPain isEqualTo IS_IN_PAIN(_unit)) then {
@ -80,17 +70,43 @@ if (_tourniquetPain > 0) then {
[_unit, _tourniquetPain] call EFUNC(medical_status,adjustPainLevel);
};
private _heartRate = [_unit, _deltaT, _syncValues] call FUNC(updateHeartRate);
[_unit, _deltaT, _syncValues] call FUNC(updatePainSuppress);
[_unit, _deltaT, _syncValues] call FUNC(updatePeripheralResistance);
// Get Medication Adjustments:
private _hrTargetAdjustment = 0;
private _painSupressAdjustment = 0;
private _peripheralResistanceAdjustment = 0;
private _adjustments = _unit getVariable [VAR_MEDICATIONS,[]];
if !(_adjustments isEqualTo []) then {
private _deleted = false;
{
_x params ["_medication", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust"];
private _timeInSystem = CBA_missionTime - _timeAdded;
if (_timeInSystem >= _maxTimeInSystem) then {
_deleted = true;
_adjustments set [_forEachIndex, objNull];
} else {
private _effectRatio = (((_timeInSystem / _timeTillMaxEffect) ^ 2) min 1) * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem;
if (_hrAdjust != 0) then { _hrTargetAdjustment = _hrTargetAdjustment + _hrAdjust * _effectRatio; };
if (_painAdjust != 0) then { _painSupressAdjustment = _painSupressAdjustment + _painAdjust * _effectRatio; };
if (_hrAdjust != 0) then { _peripheralResistanceAdjustment = _peripheralResistanceAdjustment + _flowAdjust * _effectRatio; };
};
} forEach _adjustments;
if (_deleted) then {
_unit setVariable [VAR_MEDICATIONS, _adjustments - [objNull], true];
_syncValues = true;
};
};
private _heartRate = [_unit, _hrTargetAdjustment, _deltaT, _syncValues] call FUNC(updateHeartRate);
[_unit, _painSupressAdjustment, _deltaT, _syncValues] call FUNC(updatePainSuppress);
[_unit, _peripheralResistanceAdjustment, _deltaT, _syncValues] call FUNC(updatePeripheralResistance);
private _bloodPressure = GET_BLOOD_PRESSURE(_unit);
_unit setVariable [VAR_BLOOD_PRESS, _bloodPressure, _syncValues];
_bloodPressure params ["_bloodPressureL", "_bloodPressureH"];
private _cardiacOutput = [_unit] call EFUNC(medical_status,getCardiacOutput);
// Statements are ordered by most lethal first.
switch (true) do {
case (_bloodVolume < BLOOD_VOLUME_FATAL): {
@ -114,11 +130,11 @@ switch (true) do {
[QEGVAR(medical,FatalVitals), _unit] call CBA_fnc_localEvent;
};
case (_heartRate < 30): { // With a heart rate below 30 but bigger than 20 there is a chance to enter the cardiac arrest state
private _nextCheck = _unit getVariable [QGVAR(lastCheckCriticalHeartRate), CBA_missionTime];
private _nextCheck = _unit getVariable [QGVAR(nextCheckCriticalHeartRate), CBA_missionTime];
private _enterCardiacArrest = false;
if (CBA_missionTime >= _nextCheck) then {
_enterCardiacArrest = random 1 < (0.4 + 0.6*(30 - _heartRate)/10); // Variable chance of getting into cardiac arrest.
_unit setVariable [QGVAR(lastCheckCriticalHeartRate), CBA_missionTime + 5];
_unit setVariable [QGVAR(nextCheckCriticalHeartRate), CBA_missionTime + 5];
};
if (_enterCardiacArrest) then {
TRACE_2("Heart rate critical. Cardiac arrest",_unit,_heartRate);
@ -128,10 +144,10 @@ switch (true) do {
[QEGVAR(medical,CriticalVitals), _unit] call CBA_fnc_localEvent;
};
};
case (_bloodLoss / EGVAR(medical,bleedingCoefficient) > BLOOD_LOSS_KNOCK_OUT_THRESHOLD * _cardiacOutput): {
case (_woundBloodLoss > BLOOD_LOSS_KNOCK_OUT_THRESHOLD): {
[QEGVAR(medical,CriticalVitals), _unit] call CBA_fnc_localEvent;
};
case (_bloodLoss > 0): {
case (_woundBloodLoss > 0): {
[QEGVAR(medical,LoweredVitals), _unit] call CBA_fnc_localEvent;
};
case (_inPain): {
@ -140,9 +156,10 @@ switch (true) do {
};
#ifdef DEBUG_MODE_FULL
private _cardiacOutput = [_unit] call EFUNC(medical_status,getCardiacOutput);
if (!isPlayer _unit) then {
private _painLevel = _unit getVariable [VAR_PAIN, 0];
hintSilent format["blood volume: %1, blood loss: [%2, %3]\nhr: %4, bp: %5, pain: %6", round(_bloodVolume * 100) / 100, round(_bloodLoss * 1000) / 1000, round((_bloodLoss / (0.001 max _cardiacOutput)) * 100) / 100, round(_heartRate), _bloodPressure, round(_painLevel * 100) / 100];
hintSilent format["blood volume: %1, blood loss: [%2, %3]\nhr: %4, bp: %5, pain: %6", round(_bloodVolume * 100) / 100, round(_woundBloodLoss * 1000) / 1000, round((_woundBloodLoss / (0.001 max _cardiacOutput)) * 100) / 100, round(_heartRate), _bloodPressure, round(_painLevel * 100) / 100];
};
#endif

View File

@ -5,42 +5,20 @@
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Time since last update <NUMBER>
* 2: Sync value? <BOOL>
* 1: Heart Rate Adjustments <NUMBER>
* 2: Time since last update <NUMBER>
* 3: Sync value? <BOOL>
*
* ReturnValue:
* Current Heart Rate <NUMBER>
*
* Example:
* [player, 1, false] call ace_medical_vitals_fnc_updateHeartRate
* [player, 0, 1, false] call ace_medical_vitals_fnc_updateHeartRate
*
* Public: No
*/
params ["_unit", "_deltaT", "_syncValue"];
private _hrTargetAdjustment = 0;
private _adjustments = _unit getVariable [VAR_HEART_RATE_ADJ,[]];
if !(_adjustments isEqualTo []) then {
{
_x params ["_value", "_timeTillMaxEffect", "_maxTimeInSystem", "_timeInSystem"];
if (_value != 0 && {_maxTimeInSystem > 0}) then {
if (_timeInSystem >= _maxTimeInSystem) then {
_adjustments set [_forEachIndex, nil];
} else {
_timeInSystem = _timeInSystem + _deltaT;
private _effectRatio = ((_timeInSystem / (1 max _timeTillMaxEffect)) ^ 2) min 1;
_hrTargetAdjustment = _hrTargetAdjustment + _value * _effectRatio * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem;
_x set [3, _timeInSystem];
};
} else {
_adjustments set [_forEachIndex, nil];
};
} forEach _adjustments;
_unit setVariable [VAR_HEART_RATE_ADJ, _adjustments - [nil], _syncValue];
};
params ["_unit", "_hrTargetAdjustment", "_deltaT", "_syncValue"];
private _heartRate = GET_HEART_RATE(_unit);

View File

@ -5,45 +5,26 @@
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Time since last update <NUMBER>
* 2: Sync value? <BOOL>
* 1: Pain Suppress Adjustments <NUMBER>
* 2: Time since last update <NUMBER>
* 3: Sync value? <BOOL>
*
* Return Value:
* None
*
* Example:
* [player, 0, 1, false] call ace_medical_vitals_fnc_updatePainSuppress
*
* Public: No
*/
params ["_unit", "_deltaT", "_syncValue"];
params ["_unit", "_painSupressAdjustment", "_deltaT", "_syncValue"];
private _painSupressAdjustment = 0;
private _adjustments = _unit getVariable [VAR_PAIN_SUPP_ADJ, []];
if !(_adjustments isEqualTo []) then {
{
_x params ["_value", "_timeTillMaxEffect", "_maxTimeInSystem", "_timeInSystem"];
if (_value != 0 && {_maxTimeInSystem > 0}) then {
if (_timeInSystem >= _maxTimeInSystem) then {
_adjustments set [_forEachIndex, nil];
} else {
_timeInSystem = _timeInSystem + _deltaT;
private _effectRatio = ((_timeInSystem / (1 max _timeTillMaxEffect)) ^ 2) min 1;
_painSupressAdjustment = _painSupressAdjustment + _value * _effectRatio * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem;
_x set [3, _timeInSystem];
};
} else {
_adjustments set [_forEachIndex, nil];
};
} forEach _adjustments;
_unit setVariable [VAR_PAIN_SUPP_ADJ, _adjustments - [nil], (_syncValue || {_adjustments isEqualTo []})]; // always sync on last run
_unit setVariable [VAR_PAIN_SUPP, 0 max _painSupressAdjustment, _syncValue];
};
_unit setVariable [VAR_PAIN_SUPP, 0 max _painSupressAdjustment, _syncValue];
// Handle continuous pain reduction
private _pain = GET_PAIN(_unit);
_unit setVariable [QEGVAR(medical_status,pain), 0 max (_pain - _deltaT / PAIN_FADE_TIME), _syncValue];
_unit setVariable [VAR_PAIN, 0 max (_pain - _deltaT / PAIN_FADE_TIME), _syncValue];
// Handles simple medication
if (isNil QEGVAR(medical_treatment,advancedMedication) || {!EGVAR(medical_treatment,advancedMedication)}) then {

View File

@ -5,39 +5,19 @@
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Time since last update <NUMBER>
* 2: Sync value? <BOOL>
* 1: Peripheral Resistance Adjustments <NUMBER>
* 2: Time since last update <NUMBER>
* 3: Sync value? <BOOL>
*
* Return Value:
* None
*
* Example:
* [player, 0, 1, false] call ace_medical_vitals_fnc_updatePeripheralResistance
*
* Public: No
*/
params ["_unit", "_deltaT", "_syncValue"];
params ["_unit", "_peripheralResistanceAdjustment", "_deltaT", "_syncValue"];
private _peripheralResistanceAdjustment = 0;
private _adjustments = _unit getVariable [VAR_PERIPH_RES_ADJ, []];
if !(_adjustments isEqualTo []) then {
{
_x params ["_value", "_timeTillMaxEffect", "_maxTimeInSystem", "_timeInSystem"];
if (_value != 0 && {_maxTimeInSystem > 0}) then {
if (_timeInSystem >= _maxTimeInSystem) then {
_adjustments set [_forEachIndex, nil];
} else {
_timeInSystem = _timeInSystem + _deltaT;
private _effectRatio = ((_timeInSystem / (1 max _timeTillMaxEffect)) ^ 2) min 1;
_peripheralResistanceAdjustment = _peripheralResistanceAdjustment + _value * _effectRatio * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem;
_x set [3, _timeInSystem];
};
} else {
_adjustments set [_forEachIndex, nil];
};
} forEach _adjustments;
_unit setVariable [VAR_PERIPH_RES_ADJ, _adjustments - [nil], _syncValue];
// always sync on last run
_unit setVariable [VAR_PERIPH_RES, 0 max (DEFAULT_PERIPH_RES + _peripheralResistanceAdjustment), _syncValue || {_adjustments isEqualTo []}];
};
_unit setVariable [VAR_PERIPH_RES, 0 max (DEFAULT_PERIPH_RES + _peripheralResistanceAdjustment), _syncValue];

View File

@ -14,5 +14,5 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_VITALS
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -29,11 +29,16 @@ _nozzle setVelocity [0, 0, 0];
private _groundPosition = getPosASL _nozzle;
private _posA = (getPosASL _nozzle) vectorAdd [0,0,0.05];
private _posB = (getPosASL _nozzle) vectorAdd [0,0,-1000];
private _posB = (getPosASL _nozzle) vectorAdd [0,0,- GVAR(hoseLength)];
private _intersections = lineIntersectsSurfaces [_posA, _posB, _unit, _nozzle, true, 1, "GEOM"];
TRACE_1("",_intersections);
if (_intersections isEqualTo []) then {
_groundPosition set [2, (getTerrainHeightASL _groundPosition) + 0.005];
WARNING_1("no ground intersections for nozzle drop @ %1",_groundPosition);
if (!isNull _unit) then {
_groundPosition = getPosASL _unit; // place at unit's feet
} else {
_groundPosition set [2, (getTerrainHeightASL _groundPosition) + 0.005];
};
} else {
_groundPosition = ((_intersections select 0) select 0) vectorAdd [0,0,0.005];
};

View File

@ -0,0 +1,7 @@
class CfgActions {
class None;
class Eject: None {
show = QUOTE(call compile getText (configFile >> 'CfgActions' >> 'Eject' >> 'GVAR(setting)'));
GVAR(setting) = QUOTE(profileNamespace getVariable [ARR_2('GVAR(showEjectAction)',0)]);
};
};

View File

@ -21,3 +21,4 @@ class CfgPatches {
#include "CfgAmmo.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"
#include "CfgActions.hpp"

View File

@ -1,9 +1,21 @@
[
QGVAR(keepEngineRunning),
"CHECKBOX",
[LSTRING(SettingKeepEngineRunningName), LSTRING(SettingKeepEngineRunningDesc)],
localize ELSTRING(common,ACEKeybindCategoryVehicles),
ELSTRING(common,ACEKeybindCategoryVehicles),
false, // default value
true // isGlobal
] call CBA_settings_fnc_init;
] call CBA_fnc_addSetting;
[
QGVAR(hideEjectAction),
"CHECKBOX",
[LSTRING(HideEjectAction), LSTRING(HideEjectActionTooltip)],
ELSTRING(common,ACEKeybindCategoryVehicles),
true,
2, {
profileNamespace setVariable [QGVAR(showEjectAction), parseNumber !_this];
saveProfileNamespace;
},
true // needs restart
] call CBA_fnc_addSetting;

View File

@ -75,5 +75,15 @@
<English>Prevent the automatic shut-off of the engine when exiting vehicles.</English>
<German>Verhindere das automatische Abschalten des Motors beim Verlassen des Fahrzeugs.</German>
</Key>
<Key ID="STR_ACE_Vehicles_HideEjectAction">
<English>Hide Eject Action</English>
<German>Abspringen-Aktion verstecken</German>
<Polish>Ukryj akcję Wyskocz</Polish>
</Key>
<Key ID="STR_ACE_Vehicles_HideEjectActionTooltip">
<English>Hides the Eject entry from the action menu. Requires a game restart.</English>
<German>Versteckt den Abspringen-Eintrag aus dem Aktionsmenü. Benötigt Neustart des Spiels.</German>
<Polish>Usuwa akcję Wyskocz z menu akcji. Wymaga restartu gry.</Polish>
</Key>
</Package>
</Project>

View File

@ -6,7 +6,7 @@ class CfgPatches {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_weather"};
requiredAddons[] = {"ace_common"};
author = ECSTRING(common,ACETeam);
authors[] = {ECSTRING(common,ACETeam), "Glowbal", "Ruthberg"};
url = ECSTRING(main,URL);

View File

@ -219,7 +219,7 @@
{% endif %}
{% if include.component == "medical" %}
`ace_common`
`ace_medical_engine`
{% endif %}
{% if include.component == "medical_ai" %}
@ -467,7 +467,7 @@
{% endif %}
{% if include.component == "winddeflection" %}
`ace_weather`
`ace_common`
{% endif %}
{% if include.component == "yardage450" %}

View File

@ -80,3 +80,23 @@ To create a custom FRIES you will need to look out for a few things:
The `onCut` and `onPrepare` functions are responsible for opening/closing the helicopter doors and animating the FRIES (if equipped) when the FRIES gets prepared and the ropes get cut.
ACE3 provides two functions that are compatible with most helicopters and all ACE3 FRIES. It is recommended to use the naming scheme for doors that is present in the base game so you can use the already existing functions `ace_fastroping_fnc_onCutCommon` and `ace_fastroping_fnc_onPrepareCommon`. You can however define your own functions if you so desire. Note that these functions run in the unscheduled environment, so commands like `sleep` and `waitUntil` will not work unless you use `spawn`. It is recommended to use `ace_common_fnc_waitAndExecute` and `ace_common_fnc_waitUntilAndExecute` instead though.
## 4. Scripting
### 4.1. Add FRIES to helicopter
`ace_fastroping_fnc_equipFRIES`
| | Arguments | Type | Optional (default value)
---| --------- | ---- | ------------------------
0 | Helicopter | Object | Required
**R** | None | None | Return value
### 4.2. Remove FRIES from helicopter
`ace_fastroping_fnc_unequipFRIES`
| | Arguments | Type | Optional (default value)
---| --------- | ---- | ------------------------
0 | Helicopter | Object | Required
**R** | None | None | Return value