Skip to content

Commit

Permalink
Pharma/Vitals - Fix Opioid Factor SPo2 (#621)
Browse files Browse the repository at this point in the history
**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 <[email protected]>
  • Loading branch information
Cplhardcore and mazinskihenry authored Oct 15, 2024
1 parent e2f1ca6 commit 0354433
Show file tree
Hide file tree
Showing 16 changed files with 74 additions and 42 deletions.
9 changes: 9 additions & 0 deletions addons/breathing/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
4 changes: 2 additions & 2 deletions addons/main/script_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
10 changes: 5 additions & 5 deletions addons/pharma/ACE_Medical_Treatment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -66,7 +66,7 @@ class ACE_ADDON(Medical_Treatment) {
maxDoseDeviation = 4;
incompatibleMedication[] = {};
viscosityChange = -10;
opioidRelief = 1.2;
opioidRelief = 0.1;
};
class Carbonate {
painReduce = 0;
Expand Down Expand Up @@ -158,7 +158,7 @@ class ACE_ADDON(Medical_Treatment) {
incompatibleMedication[] = {};
viscosityChange = -10;
onOverDose = "";
opioidRelief = 1.5;
opioidRelief = 0.2;
opioidEffect = 0.18;
};
class Ketamine {
Expand Down Expand Up @@ -187,7 +187,7 @@ class ACE_ADDON(Medical_Treatment) {
incompatibleMedication[] = {};
viscosityChange = -5;
onOverDose = "";
opioidRelief = 1.2;
opioidRelief = 0.1;
};
class CWMP {
painReduce = 0.2;
Expand Down
2 changes: 2 additions & 0 deletions addons/pharma/functions/fnc_fullHealLocal.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
2 changes: 1 addition & 1 deletion addons/pharma/functions/fnc_medicationLocal.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};
Original file line number Diff line number Diff line change
@@ -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 <OBJECT>
Expand All @@ -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];
3 changes: 2 additions & 1 deletion addons/vitals/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ PREP(handleRespawn);
PREP(handleOxygenFunction);
PREP(hasStableVitals);
PREP(init);
PREP(updateOpioidEffect);
PREP(updateOpioidEffect);
PREP(updateOpioidRelief);
2 changes: 1 addition & 1 deletion addons/vitals/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions addons/vitals/functions/fnc_addMedicationAdjustment.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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); };
Expand All @@ -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];
17 changes: 13 additions & 4 deletions addons/vitals/functions/fnc_handleOxygenFunction.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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
13 changes: 8 additions & 5 deletions addons/vitals/functions/fnc_handleUnitVitals.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -118,16 +120,17 @@ 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);

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);
};
Expand Down
4 changes: 2 additions & 2 deletions addons/vitals/functions/fnc_updateOpioidEffect.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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];

24 changes: 24 additions & 0 deletions addons/vitals/functions/fnc_updateOpioidRelief.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "..\script_component.hpp"
/*
* Author: Glowbal, modified by Cplhardcore
* Update the opioid relief effect
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Opioid Relief Adjustments <NUMBER>
* 2: Time since last update <NUMBER>
* 3: Sync value? <BOOL>
*
* 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];


0 comments on commit 0354433

Please sign in to comment.