From 0354433cfad290a08d64c200f586d4c7a25d21a4 Mon Sep 17 00:00:00 2001 From: Cplhardcore <135324281+Cplhardcore@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:00:18 -0700 Subject: [PATCH] Pharma/Vitals - Fix Opioid Factor SPo2 (#621) **When merged this pull request will:** - Tie in opioid relief into the vitals calc, so it is removed when the medication runs out - Adds PaCO2 padding to increase ventilation delayed after opioids take effect - Changes opioidFactor baseline from 1 to 0 to make it easier to work with - Morphine/Fentanyl/Nalbuphine local are kept in for BWC/ future PRs ### 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/XEH_preInit.sqf | 9 +++++++ addons/main/script_macros.hpp | 4 ++-- addons/pharma/ACE_Medical_Treatment.hpp | 10 ++++---- addons/pharma/functions/fnc_fullHealLocal.sqf | 2 ++ .../pharma/functions/fnc_medicationLocal.sqf | 2 +- .../fnc_treatmentAdvanced_FentanylLocal.sqf | 5 ---- .../fnc_treatmentAdvanced_MorphineLocal.sqf | 5 ---- .../fnc_treatmentAdvanced_NalbuphineLocal.sqf | 5 ---- .../fnc_treatmentAdvanced_NaloxoneLocal.sqf | 7 +++--- addons/vitals/XEH_PREP.hpp | 3 ++- addons/vitals/XEH_preInit.sqf | 2 +- .../functions/fnc_addMedicationAdjustment.sqf | 4 ++-- .../functions/fnc_handleOxygenFunction.sqf | 17 +++++++++---- .../vitals/functions/fnc_handleUnitVitals.sqf | 13 ++++++---- .../functions/fnc_updateOpioidEffect.sqf | 4 ++-- .../functions/fnc_updateOpioidRelief.sqf | 24 +++++++++++++++++++ 16 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 addons/vitals/functions/fnc_updateOpioidRelief.sqf diff --git a/addons/breathing/XEH_preInit.sqf b/addons/breathing/XEH_preInit.sqf index 9f9749a30..3ce7884c6 100644 --- a/addons/breathing/XEH_preInit.sqf +++ b/addons/breathing/XEH_preInit.sqf @@ -118,6 +118,15 @@ PREP_RECOMPILE_END; true ] call CBA_Settings_fnc_init; +[ + QGVAR(paco2Active), + "CHECKBOX", + [LLSTRING(PACO2_ENABLE), LLSTRING(PACO2_ENABLE_DESC)], + [CBA_SETTINGS_CAT, ELSTRING(GUI,SubCategory_Basic)], + [false], + true +] call CBA_Settings_fnc_init; + //Settable list for using Pulseoximeter per medical class [ QGVAR(medLvl_Pulseoximeter), diff --git a/addons/main/script_macros.hpp b/addons/main/script_macros.hpp index 803129dd7..d18adf1f7 100644 --- a/addons/main/script_macros.hpp +++ b/addons/main/script_macros.hpp @@ -188,11 +188,11 @@ #undef GET_BLOOD_VOLUME -#define GET_OPIOID_FACTOR(unit) (unit getVariable [QEGVAR(pharma,opioidFactor), 1]) +#define GET_OPIOID_FACTOR(unit) (unit getVariable [QEGVAR(pharma,opioidFactor), 0]) #define GET_PAIN_PERCEIVED(unit) (0 max ((GET_PAIN(unit) - GET_PAIN_SUPPRESS(unit)) min 1)) #undef GET_DAMAGE_THRESHOLD -#define GET_DAMAGE_THRESHOLD(unit) ((unit getVariable [QACEGVAR(medical,damageThreshold), [ACEGVAR(medical,AIDamageThreshold),ACEGVAR(medical,playerDamageThreshold)] select (isPlayer unit)]) * GET_OPIOID_FACTOR(unit)) +#define GET_DAMAGE_THRESHOLD(unit) ((unit getVariable [QACEGVAR(medical,damageThreshold), [ACEGVAR(medical,AIDamageThreshold),ACEGVAR(medical,playerDamageThreshold)] select (isPlayer unit)]) * (GET_OPIOID_FACTOR(unit) + 1)) #define DEFAULT_TOURNIQUET_VALUES [0,0,0,0,0,0] #define GET_TOURNIQUETS(unit) (unit getVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES]) diff --git a/addons/pharma/ACE_Medical_Treatment.hpp b/addons/pharma/ACE_Medical_Treatment.hpp index fbdd40c60..71ec22cca 100644 --- a/addons/pharma/ACE_Medical_Treatment.hpp +++ b/addons/pharma/ACE_Medical_Treatment.hpp @@ -25,8 +25,8 @@ class ACE_ADDON(Medical_Treatment) { // Max amount of pain the medication can remove maxRelief = 0; // Reduction of damage from wounds - opioidRelief = 1; - + opioidRelief = 0; + // How strong should opioid visuals be opioidEffect = 0; class Epinephrine { @@ -66,7 +66,7 @@ class ACE_ADDON(Medical_Treatment) { maxDoseDeviation = 4; incompatibleMedication[] = {}; viscosityChange = -10; - opioidRelief = 1.2; + opioidRelief = 0.1; }; class Carbonate { painReduce = 0; @@ -158,7 +158,7 @@ class ACE_ADDON(Medical_Treatment) { incompatibleMedication[] = {}; viscosityChange = -10; onOverDose = ""; - opioidRelief = 1.5; + opioidRelief = 0.2; opioidEffect = 0.18; }; class Ketamine { @@ -187,7 +187,7 @@ class ACE_ADDON(Medical_Treatment) { incompatibleMedication[] = {}; viscosityChange = -5; onOverDose = ""; - opioidRelief = 1.2; + opioidRelief = 0.1; }; class CWMP { painReduce = 0.2; diff --git a/addons/pharma/functions/fnc_fullHealLocal.sqf b/addons/pharma/functions/fnc_fullHealLocal.sqf index 9e6d969f3..289a7c4c7 100644 --- a/addons/pharma/functions/fnc_fullHealLocal.sqf +++ b/addons/pharma/functions/fnc_fullHealLocal.sqf @@ -46,6 +46,8 @@ _patient setVariable [QGVAR(IVmenuActive), false, true]; _patient setVariable [QGVAR(externalPh), 0, true]; _patient setVariable [QGVAR(pH), 0, true]; +_patient setVariable [QGVAR(opioidFactor), 0, true]; + _patient setVariable [QGVAR(kidneyFail), false, true]; _patient setVariable [QGVAR(kidneyArrest), false, true]; _patient setVariable [QGVAR(kidneyPressure), false, true]; diff --git a/addons/pharma/functions/fnc_medicationLocal.sqf b/addons/pharma/functions/fnc_medicationLocal.sqf index 6d78425ae..3c42367e6 100644 --- a/addons/pharma/functions/fnc_medicationLocal.sqf +++ b/addons/pharma/functions/fnc_medicationLocal.sqf @@ -109,7 +109,7 @@ if (_maxRelief > 0) then { // Adjust the medication effects and add the medication to the list TRACE_3("adjustments",_heartRateChange,_painReduce,_viscosityChange); -[_patient, _className, _timeTillMaxEffect, _timeInSystem, _heartRateChange, _painReduce, _viscosityChange, _alphaFactor, _opioidEffect] call EFUNC(vitals,addMedicationAdjustment); +[_patient, _className, _timeTillMaxEffect, _timeInSystem, _heartRateChange, _painReduce, _viscosityChange, _alphaFactor, _opioidRelief, _opioidEffect] call EFUNC(vitals,addMedicationAdjustment); // Check for medication compatiblity [_patient, _className, _maxDose, _maxDoseDeviation, _incompatibleMedication] call ACEFUNC(medical_treatment,onMedicationUsage); diff --git a/addons/pharma/functions/fnc_treatmentAdvanced_FentanylLocal.sqf b/addons/pharma/functions/fnc_treatmentAdvanced_FentanylLocal.sqf index e2090ec8c..20d8f37a8 100644 --- a/addons/pharma/functions/fnc_treatmentAdvanced_FentanylLocal.sqf +++ b/addons/pharma/functions/fnc_treatmentAdvanced_FentanylLocal.sqf @@ -19,8 +19,3 @@ /// ChromAberration effect params ["_target", "_bodyPart", "_opioidRelief"]; - -private _opioidFactor = _target getVariable [QGVAR(opioidFactor), 1]; -if (_opioidFactor == 1) then { - _target setVariable [QGVAR(opioidFactor), _opioidRelief, true]; -}; \ No newline at end of file diff --git a/addons/pharma/functions/fnc_treatmentAdvanced_MorphineLocal.sqf b/addons/pharma/functions/fnc_treatmentAdvanced_MorphineLocal.sqf index 221dbe1eb..a038248c7 100644 --- a/addons/pharma/functions/fnc_treatmentAdvanced_MorphineLocal.sqf +++ b/addons/pharma/functions/fnc_treatmentAdvanced_MorphineLocal.sqf @@ -16,8 +16,3 @@ */ params ["_patient", "_bodyPart", "_opioidRelief"]; - -private _opioidFactor = _patient getVariable [QGVAR(opioidFactor), 1]; -if (_opioidFactor == 1) then { - _patient setVariable [QGVAR(opioidFactor), _opioidRelief, true]; -}; \ No newline at end of file diff --git a/addons/pharma/functions/fnc_treatmentAdvanced_NalbuphineLocal.sqf b/addons/pharma/functions/fnc_treatmentAdvanced_NalbuphineLocal.sqf index 14ecda81f..72f8a6cd3 100644 --- a/addons/pharma/functions/fnc_treatmentAdvanced_NalbuphineLocal.sqf +++ b/addons/pharma/functions/fnc_treatmentAdvanced_NalbuphineLocal.sqf @@ -16,8 +16,3 @@ */ params ["_patient", "_bodyPart", "_opioidRelief"]; - -private _opioidFactor = _patient getVariable [QGVAR(opioidFactor), 1]; -if (_opioidFactor == 1) then { - _patient setVariable [QGVAR(opioidFactor), _opioidRelief, true]; -}; \ No newline at end of file diff --git a/addons/pharma/functions/fnc_treatmentAdvanced_NaloxoneLocal.sqf b/addons/pharma/functions/fnc_treatmentAdvanced_NaloxoneLocal.sqf index 03119d46e..7bfb9f37c 100644 --- a/addons/pharma/functions/fnc_treatmentAdvanced_NaloxoneLocal.sqf +++ b/addons/pharma/functions/fnc_treatmentAdvanced_NaloxoneLocal.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Mazinski.H - * Locates and Removes 1x Morphine after the administration of Naloxone. + * Locates and Removes one opioid after the administration of Naloxone. * * Arguments: * 0: Patient @@ -21,10 +21,9 @@ private _medicationArray = _patient getVariable [QACEGVAR(medical,medications), { _x params ["_medication"]; - - if (_medication isEqualTo "Morphine" || _medication isEqualTo "Fentanyl" || _medication isEqualTo "Nalbuphine") exitWith { + if (_medication isEqualTo "Morphine" || _medication isEqualTo "Fentanyl" || _medication isEqualTo "Nalbuphine") then { _medicationArray deleteAt (_medicationArray find _x); }; -} forEach (_medicationArray); +} forEach _medicationArray; _patient setVariable [QACEGVAR(medical,medications), _medicationArray, true]; diff --git a/addons/vitals/XEH_PREP.hpp b/addons/vitals/XEH_PREP.hpp index df304c6e8..5691dcbad 100644 --- a/addons/vitals/XEH_PREP.hpp +++ b/addons/vitals/XEH_PREP.hpp @@ -7,4 +7,5 @@ PREP(handleRespawn); PREP(handleOxygenFunction); PREP(hasStableVitals); PREP(init); -PREP(updateOpioidEffect); \ No newline at end of file +PREP(updateOpioidEffect); +PREP(updateOpioidRelief); \ No newline at end of file diff --git a/addons/vitals/XEH_preInit.sqf b/addons/vitals/XEH_preInit.sqf index 1f942547e..89a8639a1 100644 --- a/addons/vitals/XEH_preInit.sqf +++ b/addons/vitals/XEH_preInit.sqf @@ -11,7 +11,7 @@ PREP_RECOMPILE_END; [ QGVAR(simpleMedical), "CHECKBOX", - LLSTRING(SIMPLEMED_ENABLE), + [LLSTRING(SIMPLEMED_ENABLE), LLSTRING(SIMPLEMED_ENABLE_DESC)], [CBA_SETTINGS_CAT, ELSTRING(GUI,SubCategory_Basic)], [false], true diff --git a/addons/vitals/functions/fnc_addMedicationAdjustment.sqf b/addons/vitals/functions/fnc_addMedicationAdjustment.sqf index 47b3a4cf9..c293d1345 100644 --- a/addons/vitals/functions/fnc_addMedicationAdjustment.sqf +++ b/addons/vitals/functions/fnc_addMedicationAdjustment.sqf @@ -20,7 +20,7 @@ * * Public: No */ -params ["_unit", "_medication", "_timeToMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust", "_alphaFactor", "_opioidAdjust"]; +params ["_unit", "_medication", "_timeToMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust", "_alphaFactor", "_opioidRelief", "_opioidEffect"]; TRACE_7("addMedicationAdjustment",_unit,_medication,_timeToMaxEffect,_maxTimeInSystem,_hrAdjust,_painAdjust,_flowAdjust); if (_maxTimeInSystem <= 0) exitWith { WARNING_1("bad value for _maxTimeInSystem - %1",_this); }; @@ -29,6 +29,6 @@ _timeToMaxEffect = _timeToMaxEffect max 1; private _adjustments = _unit getVariable [VAR_MEDICATIONS, []]; -_adjustments pushBack [_medication, CBA_missionTime, _timeToMaxEffect, _maxTimeInSystem, _hrAdjust, _painAdjust, _flowAdjust, _alphaFactor, _opioidAdjust]; +_adjustments pushBack [_medication, CBA_missionTime, _timeToMaxEffect, _maxTimeInSystem, _hrAdjust, _painAdjust, _flowAdjust, _alphaFactor, _opioidRelief, _opioidEffect]; _unit setVariable [VAR_MEDICATIONS, _adjustments, true]; diff --git a/addons/vitals/functions/fnc_handleOxygenFunction.sqf b/addons/vitals/functions/fnc_handleOxygenFunction.sqf index 2ff90dfcc..f0e5cbc8d 100644 --- a/addons/vitals/functions/fnc_handleOxygenFunction.sqf +++ b/addons/vitals/functions/fnc_handleOxygenFunction.sqf @@ -49,12 +49,21 @@ if (IN_CRDC_ARRST(_unit)) then { private _tidalVolume = GET_KAT_SURFACE_AREA(_unit); // Respiratory Rate is supressed by Opioids - _respiratoryRate = [((_demandVentilation / _tidalVolume) - (_opioidDepression * 10)) min MAXIMUM_RR, 20] select (_unit getVariable [QEGVAR(breathing,BVMInUse), false]); + _respiratoryRate = [((_demandVentilation / _tidalVolume) - (_opioidDepression * 5)) 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}; + _actualVentilation = _tidalVolume * _respiratoryRate; }; -// The greater the imbalance between CO2 explusion and O2 intake, the higher PaCO2 gets -private _paco2 = if ((_demandVentilation / _actualVentilation) == 1) then { _previousCyclePaco2 + (PACO2_MAX_CHANGE min (-PACO2_MAX_CHANGE max ((DEFAULT_PACO2 + ((_anerobicPressure max 1) - 1) * 150) - _previousCyclePaco2))) } else { [ _previousCyclePaco2 - (PACO2_MAX_CHANGE * _deltaT), _previousCyclePaco2 + (PACO2_MAX_CHANGE * _deltaT)] select ((_demandVentilation / _actualVentilation) > 0) }; +private _paco2 = 40; + +if (EGVAR(breathing,paco2Active)) then { + // The greater the imbalance between CO2 explusion and O2 intake, the higher PaCO2 gets + _paco2 = if ((_demandVentilation / _actualVentilation) == 1) then { _previousCyclePaco2 + (PACO2_MAX_CHANGE min (-PACO2_MAX_CHANGE max ((DEFAULT_PACO2 + ((_anerobicPressure max 1) - 1) * 150) - _previousCyclePaco2))) } else { [ _previousCyclePaco2 - (PACO2_MAX_CHANGE * _deltaT), _previousCyclePaco2 + (PACO2_MAX_CHANGE * _deltaT)] select ((_demandVentilation / _actualVentilation) > 1) }; +}; + // Generated ETCO2 quadratic. Ensures ETCO2 moves with Respiratory Rate and is constantly below PaCO2 private _etco2 = [((_paco2 - 3) - ((-0.0416667 * (_respiratoryRate^2)) + (3.09167 * (_respiratoryRate)) - DEFAULT_ETCO2) max 10), 0] select (IN_CRDC_ARRST(_unit)); @@ -89,7 +98,7 @@ _pao2 = if (_previousCyclePao2 != _pao2) then { ([ _previousCyclePao2 - (PAO2_MA // Oxy-Hemo Dissociation Curve, driven by PaO2 with shaping done by pH private _o2Sat = ((_pao2 max 1)^2.7 / ((25 - (((_pH / DEFAULT_PH) - 1) * 150))^2.7 + _pao2^2.7)) min 0.999; -_unit setVariable [VAR_BREATHING_RATE, _respiratoryRate, _syncValues]; +_unit setVariable [VAR_BREATHING_RATE, (_respiratoryRate max 0), _syncValues]; _unit setVariable [VAR_BLOOD_GAS, [_paco2, _pao2, _o2Sat, 24, _pH, _etco2], _syncValues]; _o2Sat * 100 diff --git a/addons/vitals/functions/fnc_handleUnitVitals.sqf b/addons/vitals/functions/fnc_handleUnitVitals.sqf index f854d1c95..bc669d252 100644 --- a/addons/vitals/functions/fnc_handleUnitVitals.sqf +++ b/addons/vitals/functions/fnc_handleUnitVitals.sqf @@ -90,12 +90,13 @@ private _painSupressAdjustment = 0; private _peripheralResistanceAdjustment = 0; private _alphaFactorAdjustment = 0; private _opioidAdjustment = 0; +private _opioidEffectAdjustment = 0; private _adjustments = _unit getVariable [VAR_MEDICATIONS,[]]; if !(_adjustments isEqualTo []) then { private _deleted = false; { - _x params ["_medication", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust", "_alphaFactor", "_opioidAdjust"]; + _x params ["_medication", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust", "_alphaFactor", "_opioidRelief", "_opioidEffect"]; private _timeInSystem = CBA_missionTime - _timeAdded; if (_timeInSystem >= _maxTimeInSystem) then { _deleted = true; @@ -106,7 +107,8 @@ if !(_adjustments isEqualTo []) then { if (_painAdjust != 0) then { _painSupressAdjustment = _painSupressAdjustment + _painAdjust * _effectRatio; }; if (_flowAdjust != 0) then { _peripheralResistanceAdjustment = _peripheralResistanceAdjustment + _flowAdjust * _effectRatio; }; if (_alphaFactor != 0) then { _alphaFactorAdjustment = _alphaFactorAdjustment + _alphaFactor * _effectRatio; }; - if (_opioidAdjust != 0) then {_opioidAdjustment = _opioidAdjustment + _opioidAdjust * _effectRatio; }; + if (_opioidRelief != 0) then {_opioidAdjustment = _opioidAdjustment + _opioidRelief * _effectRatio; }; + if (_opioidEffect != 0) then {_opioidEffectAdjustment = _opioidEffectAdjustment + _opioidEffect * _effectRatio; }; }; } forEach _adjustments; @@ -118,7 +120,8 @@ if !(_adjustments isEqualTo []) then { [_unit, _painSupressAdjustment, _deltaT, _syncValues] call ACEFUNC(medical_vitals,updatePainSuppress); //Leave alone [_unit, _peripheralResistanceAdjustment, _deltaT, _syncValues] call ACEFUNC(medical_vitals,updatePeripheralResistance); -[_unit, _opioidAdjustment, _deltaT, _syncValues] call FUNC(updateOpioidEffect); +[_unit, _opioidAdjustment, _deltaT, _syncValues] call FUNC(updateOpioidRelief); +[_unit, _opioidEffectAdjustment, _deltaT, _syncValues] call FUNC(updateOpioidEffect); private _heartRate = [_unit, _hrTargetAdjustment, 0, _bloodVolume, _deltaT, _syncValues] call FUNC(handleCardiacFunction); @@ -126,8 +129,8 @@ private _spo2 = 97; if (EGVAR(breathing,enable)) then { // Additional variables for Respiration functions private _bloodGas = GET_BLOOD_GAS(_unit); - private _opioidDepression = (GET_OPIOID_FACTOR(_unit) - 1); - private _anerobicPressure = (DEFAULT_ANEROBIC_EXCHANGE * (6 / _bloodVolume) - 0) min 1.2; + private _opioidDepression = GET_OPIOID_FACTOR(_unit); + private _anerobicPressure = (DEFAULT_ANEROBIC_EXCHANGE * (6 / (_bloodVolume max 6))) min 1.2; _spo2 = [_unit, _heartRate, _anerobicPressure, _bloodGas, _temperature, _baroPressure, _opioidDepression, _deltaT, _syncValues] call FUNC(handleOxygenFunction); }; diff --git a/addons/vitals/functions/fnc_updateOpioidEffect.sqf b/addons/vitals/functions/fnc_updateOpioidEffect.sqf index 9df2dceb6..797f86414 100644 --- a/addons/vitals/functions/fnc_updateOpioidEffect.sqf +++ b/addons/vitals/functions/fnc_updateOpioidEffect.sqf @@ -18,7 +18,7 @@ * Public: No */ -params ["_unit", "_opioidAdjustment", "_deltaT", "_syncValue"]; +params ["_unit", "_opioidEffectAdjustment", "_deltaT", "_syncValue"]; -_unit setVariable [VAR_PP, 0 max _opioidAdjustment, _syncValue]; +_unit setVariable [VAR_PP, 0 max _opioidEffectAdjustment, _syncValue]; diff --git a/addons/vitals/functions/fnc_updateOpioidRelief.sqf b/addons/vitals/functions/fnc_updateOpioidRelief.sqf new file mode 100644 index 000000000..437faf27b --- /dev/null +++ b/addons/vitals/functions/fnc_updateOpioidRelief.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, modified by Cplhardcore + * Update the opioid relief effect + * + * Arguments: + * 0: The Unit + * 1: Opioid Relief Adjustments + * 2: Time since last update + * 3: Sync value? + * + * Return Value: + * None + * + * Example: + * [player, 0, 1, false] call kat_vitals_fnc_updateOpioidRelief + * + * Public: No + */ + +params ["_unit", "_opioidAdjustment", "_deltaT", "_syncValue"]; +_unit setVariable [QEGVAR(pharma,opioidFactor), _opioidAdjustment, _syncValue]; + +