#include "..\script_component.hpp" /* * Author: Brett Mayson * Update the oxygen levels * * Arguments: * 0: The Unit * 1: Time since last update * 2: Sync value? * * ReturnValue: * Current SPO2 * * 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];