mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Medical - Improve adjustment calcs / wound blood loss / medications (#6910)
* Improve adjustment calcs / wound blood loss / medications fix func descriptions Calc wound blood loss on events reorder includes so scritpmacroMed has global effect trivial optimization for getCardiacOutput Fix var Fix wounds not reopening (nil _category) Fix surgical kit inherting canBandage conditional debug hitpoints Update ACE_Medical_Treatment_Actions.hpp Use woundBleeding for IS_BLEEDING macro rework medication vars comments Reset var in init / fullHeal Update addons/medical_treatment/functions/fnc_onMedicationUsage.sqf Co-Authored-By: PabstMirror <pabstmirror@gmail.com> * Update addons/medical_treatment/functions/fnc_onMedicationUsage.sqf Co-Authored-By: PabstMirror <pabstmirror@gmail.com>
This commit is contained in:
parent
2cfe7ebd0c
commit
847d2d4179
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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) \
|
||||
|
@ -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])
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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];
|
@ -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];
|
@ -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))
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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), []];
|
||||
|
@ -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)})
|
||||
|
42
addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf
Normal file
42
addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf
Normal 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];
|
||||
};
|
@ -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"
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
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;
|
||||
@ -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"];
|
||||
_injury params ["", "_classID", "_bodyPartN", "", "", "", "_category"];
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -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), []];
|
||||
private _fnc_getMedicationCount = {
|
||||
params ["_target", "_medication"];
|
||||
private _return = 0;
|
||||
{
|
||||
_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];
|
||||
_x params ["_xMed", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem"];
|
||||
if (_xMed == _medication) then {
|
||||
private _timeInSystem = CBA_missionTime - _timeAdded;
|
||||
_return = _return + linearConversion [_timeTillMaxEffect, _maxTimeInSystem, _timeInSystem, 1, 0, true];
|
||||
};
|
||||
_foundEntry = true;
|
||||
};
|
||||
} forEach _allUsedMedication;
|
||||
|
||||
if (!_foundEntry) then {
|
||||
_allUsedMedication pushBack [_variable, [_className]];
|
||||
_target setVariable [QEGVAR(medical,allUsedMedication), _allUsedMedication];
|
||||
} forEach (_target getVariable [VAR_MEDICATIONS, []]);
|
||||
TRACE_2("getMedicationCount",_medication,_return);
|
||||
_return
|
||||
};
|
||||
|
||||
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 _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;
|
||||
};
|
||||
|
||||
private _hasOverDosed = 0;
|
||||
// Check incompatible medication (format [med,limit])
|
||||
{
|
||||
_x params ["_med", "_limit"];
|
||||
{
|
||||
_x params ["", "_classNamesUsed"];
|
||||
if ({_x == _med} count _classNamesUsed > _limit) then {
|
||||
_hasOverDosed = _hasOverDosed + 1;
|
||||
_x params ["_xMed", "_xLimit"];
|
||||
private _inSystem = [_target, _xMed] call _fnc_getMedicationCount;
|
||||
if (_inSystem> _xLimit) then {
|
||||
_overdosedMedications pushBackUnique _xMed;
|
||||
};
|
||||
} forEach _allUsedMedication;
|
||||
} 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"); };
|
||||
};
|
||||
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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
||||
// 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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"];
|
||||
|
||||
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
|
||||
params ["_unit", "_painSupressAdjustment", "_deltaT", "_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 {
|
||||
|
@ -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];
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user