Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions addons/medical_engine/script_macros_medical.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

#define DEFAULT_HEART_RATE 80
#define DEFAULT_PERIPH_RES 100
#define DEFAULT_STROKE_VOLUME 95e-3

// --- blood
// 0.077 l/kg * 80kg = 6.16l
Expand All @@ -54,6 +55,11 @@
#define BLOOD_VOLUME_CLASS_4_HEMORRHAGE 3.600 // lost more than 40% blood, Class IV Hemorrhage
#define BLOOD_VOLUME_FATAL 3.0 // Lost more than 50% blood, Unrecoverable

#define DEFAULT_BP_MEAN 107
#define DEFAULT_BP_HIGH 120
#define DEFAULT_BP_LOW 80
#define DEFAULT_BLOOD_PRESSURE [DEFAULT_BP_LOW,DEFAULT_BP_HIGH,DEFAULT_BP_MEAN] // at default heart rate

// IV Change per second calculation:
// 250 ml should take 60 seconds to fill. 250 ml / 60 s ~ 4.1667 ml/s.
#define IV_CHANGE_PER_SECOND 4.1667 // in milliliters per second
Expand Down
1 change: 1 addition & 0 deletions addons/medical_status/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PREP(getBloodPressure);
PREP(getBloodVolumeChange);
PREP(getCardiacOutput);
PREP(getMedicationCount);
PREP(getStrokeVolume);
PREP(handleKilled);
PREP(handleKilledMission);
PREP(hasStableVitals);
Expand Down
21 changes: 14 additions & 7 deletions addons/medical_status/functions/fnc_getBloodPressure.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,30 @@
* Return Value:
* 0: BloodPressure Low <NUMBER>
* 1: BloodPressure High <NUMBER>
* 2: Mean Arterial Pressure <NUMBER>
*
* Example:
* [player] call ace_medical_status_fnc_getBloodPressure
*
* Public: No
*/

// Value is taken because with cardic output and resistance at default values, it will put blood pressure High at 120.
#define MODIFIER_BP_HIGH 9.4736842

// Value is taken because with cardic output and resistance at default values, it will put blood pressure Low at 80.
#define MODIFIER_BP_LOW 6.3157894
// Value that gives MAP=107 at default values
#define MODIFIER_BP 8.2168

params ["_unit"];

private _cardiacOutput = [_unit] call FUNC(getCardiacOutput);
private _resistance = _unit getVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES];
private _bloodPressure = _cardiacOutput * _resistance;
private _meanPressure = _cardiacOutput * _resistance * MODIFIER_BP;

private _heartRate = GET_HEART_RATE(_unit);

//https://www.researchgate.net/publication/14609651_Calculation_of_Mean_Arterial_Pressure_During_Exercise_as_a_Function_of_Heart_Rate
private _stFraction = 0 max (0.01*exp(4.14-40.74/_heartRate)) min 0.5;

private _strokeVol = [_unit] call FUNC(getStrokeVolume);
private _pulsePressure = (DEFAULT_BP_HIGH - DEFAULT_BP_LOW) * (_strokeVol / DEFAULT_STROKE_VOLUME) * (_resistance / DEFAULT_PERIPH_RES);

[round(_bloodPressure * MODIFIER_BP_LOW), round(_bloodPressure * MODIFIER_BP_HIGH)]
private _bpLow = _meanPressure - _pulsePressure*_stFraction;
[round _bpLow, round (_bpLow + _pulsePressure), round _meanPressure];
9 changes: 7 additions & 2 deletions addons/medical_status/functions/fnc_getCardiacOutput.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@

params ["_unit"];

private _bloodVolumeRatio = GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME;
private _heartRate = GET_HEART_RATE(_unit);

if (_heartRate <= 1) exitwith {0};

private _strokeVol = [_unit] call FUNC(getStrokeVolume);

/*
// Blood volume ratio dictates how much is entering the ventricle (this is an approximation)
private _entering = linearConversion [0.5, 1, _bloodVolumeRatio, 0, 1, true];
*/

private _cardiacOutput = (_entering * VENTRICLE_STROKE_VOL) * _heartRate / 60;
private _cardiacOutput = _strokeVol * _heartRate / 60;

0 max _cardiacOutput
51 changes: 51 additions & 0 deletions addons/medical_status/functions/fnc_getStrokeVolume.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "script_component.hpp"
/*
* Author: Pterolatypus
* Calculate the stroke volume.
*
* Arguments:
* 0: The Unit <OBJECT>
*
* Return Value:
* stroke volume (ml) <NUMBER>
*
* Example:
* [player] call ace_medical_status_fnc_getStrokeVolume
*
* Public: No
*/

// Value taken from https://doi.org/10.1093%2Feurheartj%2Fehl336
// as 94/95 ml ± 15 ml
#define VENTRICLE_STROKE_VOL 95e-3

params ["_unit"];

private _heartRate = GET_HEART_RATE(_unit);
private _bloodVolumeRatio = GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME;
_unit getVariable [VAR_BLOOD_PRESS, DEFAULT_BLOOD_PRESSURE] params ["_bpLow", "_bpHigh", "_bpMean"];

// Blood is pushed into the heart by Central Venous Pressure
// Approximated here using blood volume and (arterial) blood pressure
private _fillPressure = 0.7*_bloodVolumeRatio + 0.3*_bpMean/DEFAULT_BP_MEAN;
// Afterload (the force the heart must overcome to pump blood) depends primarily on systolic bp
private _afterload = _bpHigh/DEFAULT_BP_HIGH;
// TODO: Force of the heart contraction is influenced by medication.
private _contractility = 1;

// End diastolic volume (volume the heart fills to) based on filling pressure and time available to fill
private _fillTime = DEFAULT_HEART_RATE/_heartRate;
private _fillPortion = 1 - exp (-3*_fillTime);
private _edv = _fillPortion * _fillPressure * 1.053 * 1.5 * VENTRICLE_STROKE_VOL;

// End systolic volume (volume the heart contracts to) is based on afterload and contractility
private _esv = _afterload/_contractility * 0.5*VENTRICLE_STROKE_VOL;

private _strokeVol = (_edv - _esv) max 0;

#ifdef DEBUG_MODE_FULL
if (_unit getVariable [QGVAR(trace_strokevol), false]) then {
TRACE_10("Stroke volume trace",_bpHigh,_bpMean,_heartRate,_fillPressure,_fillTime,_fillPortion,_afterload,_edv,_esv,_strokeVol);
}
#endif
_strokeVol
2 changes: 1 addition & 1 deletion addons/medical_status/script_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define COMPONENT_BEAUTIFIED Medical Status
#include "\z\ace\addons\main\script_mod.hpp"

// #define DEBUG_MODE_FULL
#define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS

Expand Down
8 changes: 4 additions & 4 deletions addons/medical_vitals/functions/fnc_updateHeartRate.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ if IN_CRDC_ARRST(_unit) then {
private _targetHR = 0;
private _bloodVolume = GET_BLOOD_VOLUME(_unit);
if (_bloodVolume > BLOOD_VOLUME_CLASS_4_HEMORRHAGE) then {
GET_BLOOD_PRESSURE(_unit) params ["_bloodPressureL", "_bloodPressureH"];
private _meanBP = (2/3) * _bloodPressureH + (1/3) * _bloodPressureL;
GET_BLOOD_PRESSURE(_unit) params ["_bloodPressureL", "_bloodPressureH", "_meanBP"];
//private _meanBP = (2/3) * _bloodPressureH + (1/3) * _bloodPressureL;
private _painLevel = GET_PAIN_PERCEIVED(_unit);

private _targetBP = 107;
if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then {
_targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME);
//_targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME);
};

_targetHR = DEFAULT_HEART_RATE;
if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then {
if (_bloodVolume < 6) then {
_targetHR = _heartRate * (_targetBP / (45 max _meanBP));
};
if (_painLevel > 0.2) then {
Expand Down