mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
76 lines
2.7 KiB
Plaintext
76 lines
2.7 KiB
Plaintext
|
#include "..\script_component.hpp"
|
||
|
/*
|
||
|
* Author: Brett Mayson
|
||
|
* Update the oxygen levels
|
||
|
*
|
||
|
* Arguments:
|
||
|
* 0: The Unit <OBJECT>
|
||
|
* 1: Time since last update <NUMBER>
|
||
|
* 2: Sync value? <BOOL>
|
||
|
*
|
||
|
* ReturnValue:
|
||
|
* Current SPO2 <NUMBER>
|
||
|
*
|
||
|
* Example:
|
||
|
* [player, 1, false] call ace_medical_vitals_fnc_updateOxygen
|
||
|
*
|
||
|
* Public: No
|
||
|
*/
|
||
|
|
||
|
params ["_unit", "_deltaT", "_syncValue"];
|
||
|
|
||
|
if (!GVAR(simulateSpO2)) exitWith {}; // changing back to default is handled in initSettings.inc.sqf
|
||
|
|
||
|
#define IDEAL_PPO2 0.255
|
||
|
|
||
|
private _current = GET_SPO2(_unit);
|
||
|
private _heartRate = GET_HEART_RATE(_unit);
|
||
|
|
||
|
private _altitude = EGVAR(common,mapAltitude) + ((getPosASL _unit) select 2);
|
||
|
private _po2 = if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then {
|
||
|
private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight);
|
||
|
private _pressure = _altitude call EFUNC(weather,calculateBarometricPressure);
|
||
|
[_temperature, _pressure, EGVAR(weather,currentHumidity)] call EFUNC(weather,calculateOxygenDensity)
|
||
|
} else {
|
||
|
// Rough approximation of the partial pressure of oxygen in the air
|
||
|
0.25725 * (_altitude / 1000 + 1)
|
||
|
};
|
||
|
|
||
|
private _oxygenSaturation = (IDEAL_PPO2 min _po2) / IDEAL_PPO2;
|
||
|
|
||
|
// Check gear for oxygen supply
|
||
|
[goggles _unit, headgear _unit, vest _unit] findIf {
|
||
|
_x in GVAR(oxygenSupplyConditionCache) &&
|
||
|
{ACE_player call (GVAR(oxygenSupplyConditionCache) get _x)} &&
|
||
|
{ // Will only run this if other conditions are met due to lazy eval
|
||
|
_oxygenSaturation = 1;
|
||
|
_po2 = IDEAL_PPO2;
|
||
|
true
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Base oxygen consumption rate
|
||
|
private _negativeChange = BASE_OXYGEN_USE;
|
||
|
|
||
|
// Fatigue & exercise will demand more oxygen
|
||
|
// Assuming a trained male in midst of peak exercise will have a peak heart rate of ~180 BPM
|
||
|
// Ref: https://academic.oup.com/bjaed/article-pdf/4/6/185/894114/mkh050.pdf table 2, though we don't take stroke volume change into account
|
||
|
if (_unit == ACE_player && {missionNamespace getVariable [QEGVAR(advanced_fatigue,enabled), false]}) then {
|
||
|
_negativeChange = _negativeChange - ((1 - EGVAR(advanced_fatigue,aeReservePercentage)) * 0.1) - ((1 - EGVAR(advanced_fatigue,anReservePercentage)) * 0.05);
|
||
|
};
|
||
|
|
||
|
// Effectiveness of capturing oxygen
|
||
|
// increases slightly as po2 starts lowering
|
||
|
// but falls off quickly as po2 drops further
|
||
|
private _capture = 1 max ((_po2 / IDEAL_PPO2) ^ (-_po2 * 3));
|
||
|
private _positiveChange = _heartRate * 0.00368 * _oxygenSaturation * _capture;
|
||
|
|
||
|
private _breathingEffectiveness = 1;
|
||
|
|
||
|
private _rateOfChange = _negativeChange + (_positiveChange * _breathingEffectiveness);
|
||
|
|
||
|
private _spo2 = (_current + (_rateOfChange * _deltaT)) max 0 min 100;
|
||
|
|
||
|
_unit setVariable [VAR_OXYGEN_DEMAND, _negativeChange - BASE_OXYGEN_USE];
|
||
|
_unit setVariable [VAR_SPO2, _spo2, _syncValue];
|