From bd700f471858b742d9a17a2246ca3662bf5efc8d Mon Sep 17 00:00:00 2001 From: Cplhardcore <135324281+Cplhardcore@users.noreply.github.com> Date: Thu, 30 Jan 2025 19:51:32 -0800 Subject: [PATCH] Vitals - Improve oxygen function to handle respiratory depression (#643) **When merged this pull request will:** - Adds respiratory depression to the vitals loop - Adds pneumothorax's to the oxygen calculation to affect multiple areas ### IMPORTANT - [Development Guidelines](https://ace3.acemod.org/wiki/development/) are read, understood and applied. - Title of this PR uses our standard template `Component - Add|Fix|Improve|Change|Make|Remove {changes}`. --------- Co-authored-by: mazinskihenry <33608576+mazinskihenry@users.noreply.github.com> --- addons/breathing/functions/fnc_checkBreathing.sqf | 8 +++++++- addons/breathing/stringtable.xml | 6 ++++++ addons/main/script_macros.hpp | 4 ++++ addons/vitals/functions/fnc_fullHealLocal.sqf | 1 + .../vitals/functions/fnc_handleOxygenFunction.sqf | 15 +++++++++++---- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/addons/breathing/functions/fnc_checkBreathing.sqf b/addons/breathing/functions/fnc_checkBreathing.sqf index 686debc71..292ab4d82 100644 --- a/addons/breathing/functions/fnc_checkBreathing.sqf +++ b/addons/breathing/functions/fnc_checkBreathing.sqf @@ -30,11 +30,17 @@ private _breathing_log = localize ACELSTRING(medical_treatment,Check_Pulse_Norma private _breath = ""; private _breathRate = "RR: "; -if ((_patient getVariable [QGVAR(pneumothorax), 0] > 0) || (_patient getVariable [QEGVAR(chemical,airPoisoning), false])) then { +private _respiratoryDepth = _patient getVariable [QEGVAR(vitals,respiratoryDepth), 10]; +if (((10 > _respiratoryDepth) && (_respiratoryDepth >= 7)) || (_patient getVariable [QEGVAR(chemical,airPoisoning), false])) then { _breathing = LLSTRING(breathing_isShallow); _breathing_log = LLSTRING(breathing_shallow); }; +if (_respiratoryDepth < 7) then { + _breathing = LLSTRING(breathing_isVeryShallow); + _breathing_log = LLSTRING(breathing_Veryshallow); +}; + if (_ph < 7.2) then { _breath = LLSTRING(breath_mild); diff --git a/addons/breathing/stringtable.xml b/addons/breathing/stringtable.xml index 970003a9b..53d58d24b 100644 --- a/addons/breathing/stringtable.xml +++ b/addons/breathing/stringtable.xml @@ -2505,6 +2505,12 @@ 呼吸速度: 正常 RR : Normal + + Patient's breathing is very shallow + + + Very Shallow + Patient is not breathing 患者は呼吸していない diff --git a/addons/main/script_macros.hpp b/addons/main/script_macros.hpp index f30ea8623..e31f44366 100644 --- a/addons/main/script_macros.hpp +++ b/addons/main/script_macros.hpp @@ -280,6 +280,7 @@ #define DEFAULT_PH 7.4 #define DEFAULT_ETCO2 37 #define DEFAULT_BLOOD_GAS [DEFAULT_PACO2, DEFAULT_PAO2, DEFAULT_O2SAT, DEFAULT_HCO3, DEFAULT_PH, DEFAULT_ETCO2] +#define DEFAULT_RESPIRATORY_DEPTH 10 #define DEFAULT_ANEROBIC_EXCHANGE 0.8 #define DEFAULT_TEMPERATURE 37 @@ -302,6 +303,9 @@ #define VAR_SURFACE_AREA 400 #define GET_KAT_SURFACE_AREA(unit) (VAR_SURFACE_AREA - (((unit getVariable [QEGVAR(breathing,pneumothorax), 0]) * 75))) +#define VAR_RESPIRATORY_DEPTH QEGVAR(vitals,respiratoryDepth) +#define GET_KAT_RESPIRATORY_DEPTH(unit) (unit getVariable [QEGVAR(vitals,respiratoryDepth), 10]) + #define VAR_BLOOD_GAS QEGVAR(circulation,bloodGas) #define VAR_BREATHING_RATE QEGVAR(breathing,breathRate) diff --git a/addons/vitals/functions/fnc_fullHealLocal.sqf b/addons/vitals/functions/fnc_fullHealLocal.sqf index 8b4cd8329..a34b00a0d 100644 --- a/addons/vitals/functions/fnc_fullHealLocal.sqf +++ b/addons/vitals/functions/fnc_fullHealLocal.sqf @@ -18,6 +18,7 @@ params ["_patient"]; _patient setVariable [QGVAR(simpleMedical), false, true]; +_patient setVariable [QGVAR(respiratoryDepth), DEFAULT_RESPIRATORY_DEPTH, true]; if (GVAR(enableSimpleMedical)) then { _patient setVariable [QGVAR(simpleMedical), true, true]; diff --git a/addons/vitals/functions/fnc_handleOxygenFunction.sqf b/addons/vitals/functions/fnc_handleOxygenFunction.sqf index 05ce2a563..0347fad91 100644 --- a/addons/vitals/functions/fnc_handleOxygenFunction.sqf +++ b/addons/vitals/functions/fnc_handleOxygenFunction.sqf @@ -31,8 +31,10 @@ params ["_unit", "_actualHeartRate", "_anerobicPressure", "_bloodGas", "_tempera #define PACO2_MAX_CHANGE 0.05 #define PAO2_MAX_CHANGE 0.1 #define DEFAULT_FIO2 0.21 +#define MINIMUM_DEPTH 0.2 private _respiratoryRate = 0; +private _respiratoryDepression = 0; private _demandVentilation = 0; private _actualVentilation = 0; private _previousCyclePaco2 = (_bloodGas select 0); @@ -41,6 +43,7 @@ private _previousCyclePao2 = (_bloodGas select 1); if (IN_CRDC_ARRST(_unit)) then { // When in arrest, there should be no effecive breaths but still a minimum O2 demand. Zero O2 demand would mean a dead patient. Actual ventilation is 1 to prevent issues in the gas tension functions _demandVentilation = MINIMUM_VENTILATION; + _respiratoryDepression = 1; _respiratoryRate = [0, 20] select (_unit getVariable [QEGVAR(breathing,BVMInUse), false]); _actualVentilation = 1; } else { @@ -48,8 +51,12 @@ if (IN_CRDC_ARRST(_unit)) then { _demandVentilation = ((((_actualHeartRate * HEART_RATE_CO2_MULTIPLIER) / _anerobicPressure) + ((_previousCyclePaco2 - DEFAULT_PACO2) * 200)) max MINIMUM_VENTILATION); private _tidalVolume = GET_KAT_SURFACE_AREA(_unit); - // Respiratory Rate is supressed by Opioids - _respiratoryRate = [((_demandVentilation / _tidalVolume) - (_opioidDepression * 5)) min MAXIMUM_RR, 20] select (_unit getVariable [QEGVAR(breathing,BVMInUse), false]); + // Tidal Volume is modified by respiratory depth which can be supressed by opioids and pneumothroax + private _respiratoryDepth = [((DEFAULT_RESPIRATORY_DEPTH / 10) - (_opioidDepression / 1.5)), 10] select (_unit getVariable [QEGVAR(breathing,BVMInUse), false]); + private _tidalVolume = GET_KAT_SURFACE_AREA(_unit) * (_respiratoryDepth / 1); + + // Respiratory Rate Calculation + _respiratoryRate = [((_demandVentilation / _tidalVolume)) min MAXIMUM_RR, 20] select (_unit getVariable [QEGVAR(breathing,BVMInUse), false]); // If respiratory rate is low due to PaCO2, it starts increasing faster to compensate if (_previousCyclePaco2 > 50) then { _respiratoryRate = (_respiratoryRate + ((_previousCyclePaco2 - 50) * 0.2)) min MAXIMUM_RR}; @@ -76,7 +83,7 @@ if (IN_CRDC_ARRST(_unit)) then { }; } else { // Generated ETCO2 quadratic. Ensures ETCO2 moves with Respiratory Rate and is constantly below PaCO2 - _etco2 = ((_paco2 - 3) - ((-0.0416667 * (_respiratoryRate^2)) + (3.09167 * (_respiratoryRate)) - DEFAULT_ETCO2) max 5); + _etco2 = (((_paco2 - 3) - ((-0.0416667 * (_respiratoryRate^2)) + (3.09167 * (_respiratoryRate))) * (_respiratoryDepth)) - DEFAULT_ETCO2) max 5; }; private _externalPh = 0; @@ -123,5 +130,5 @@ private _o2Sat = ((_pao2 max 1)^2.7 / ((25 - (((_pH / DEFAULT_PH) - 1) * 150))^2 _unit setVariable [VAR_BREATHING_RATE, (_respiratoryRate max 0), _syncValues]; _unit setVariable [VAR_BLOOD_GAS, [_paco2, _pao2, _o2Sat, 24, _pH, _etco2], _syncValues]; - +_unit setVariable [QGVAR(respiratoryDepth), (_respiratoryDepth max 0), _syncValues]; _o2Sat * 100