diff --git a/addons/advanced_fatigue/ACE_Settings.hpp b/addons/advanced_fatigue/ACE_Settings.hpp index 8abdcc5865b..ec37bb0275f 100644 --- a/addons/advanced_fatigue/ACE_Settings.hpp +++ b/addons/advanced_fatigue/ACE_Settings.hpp @@ -40,6 +40,6 @@ class ACE_Settings { displayName = CSTRING(TerrainGradientFactor); description = CSTRING(TerrainGradientFactor_Description); typeName = "SCALAR"; - value = 1; + value = 0.5; }; }; diff --git a/addons/advanced_fatigue/CfgVehicles.hpp b/addons/advanced_fatigue/CfgVehicles.hpp index 83026e2167a..e7695a5f59b 100644 --- a/addons/advanced_fatigue/CfgVehicles.hpp +++ b/addons/advanced_fatigue/CfgVehicles.hpp @@ -38,7 +38,7 @@ class CfgVehicles { displayName = CSTRING(TerrainGradientFactor); description = CSTRING(TerrainGradientFactor_Description); typeName = "NUMBER"; - defaultValue = 1; + defaultValue = 0.5; }; }; }; diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index 542360c0c36..2624d8d377b 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -1,6 +1,32 @@ #include "script_component.hpp" if (!hasInterface) exitWith {}; +#ifdef DEBUG_MODE_FULL +onEachFrame { + private _normal = surfaceNormal (getPosWorld ACE_player); + private _beg = (getPosWorld ACE_player) vectorAdd (_normal vectorMultiply 0.5); + private _end = _beg vectorAdd (_normal vectorMultiply 2.0); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0,1,0,1]]; + + private _side = vectorNormalized (_normal vectorCrossProduct [0, 0, 1]); + private _end = _beg vectorAdd (_side vectorMultiply 2.0); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0,0,1,1]]; + + private _up = vectorNormalized (_normal vectorCrossProduct _side); + private _end = _beg vectorAdd (_up vectorMultiply 2.0); + drawLine3D [ASLToATL _beg, ASLToATL _end, [1,0,0,1]]; + + private _movementVector = vectorNormalized (velocity ACE_player); + private _end = _beg vectorAdd (_movementVector vectorMultiply 2.0); + drawLine3D [ASLToATL _beg, ASLToATL _end, [1,1,0,1]]; + + private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); + _sideVector set[2, 0]; + private _end = _beg vectorAdd (_sideVector vectorMultiply 2.0); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0,1,1,1]]; +}; +#endif + ["ace_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; diff --git a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf index 629152b6a10..2ddf01f045f 100644 --- a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf +++ b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf @@ -1,6 +1,6 @@ /* * Author: BaerMitUmlaut - * Calculates the duty of the current animation. + * Calculates the duty ('postureWeight') of the current animation. * * Arguments: * 0: Unit diff --git a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf index c2c673fd95c..4c7d5e7aa5f 100644 --- a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf +++ b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf @@ -6,24 +6,29 @@ * Arguments: * 0: Unit * 1: Speed + * 2: Forward Angle + * 3: Side Angle * * Return Value: * Metabolic cost * * Example: - * [player, 3.3] call ace_advanced_fatigue_fnc_getMetabolicCosts + * [player, 3.3, 0, 0] call ace_advanced_fatigue_fnc_getMetabolicCosts * * Public: No */ #include "script_component.hpp" -params ["_unit", "_velocity"]; +params ["_unit", "_speed", "_fwdAngle", "_sideAngle"]; private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor); +private _terrainGradient = 1; +private _terrainFactor = 1; -private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2)); -private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor); -private _duty = GVAR(animDuty); +#ifdef DEBUG_MODE_FULL + systemChat format["---- gearMass: %1 ----", _gearMass toFixed 2]; +#endif +private _duty = GVAR(animDuty); { if (_x isEqualType 0) then { _duty = _duty * _x; @@ -32,20 +37,42 @@ private _duty = GVAR(animDuty); }; } forEach (GVAR(dutyList) select 1); -if (GVAR(isSwimming)) then { - _terrainGradient = 0; +if (!GVAR(isSwimming)) then { + if (_fwdAngle < 0) then { + _terrainGradient = 0.15 * abs(_fwdAngle); + } else { + _terrainGradient = _fwdAngle; + }; + if ((getPosATL _unit) select 2 < 0.01) then { + private _sideGradient = abs(_sideAngle / 45) min 1; + _terrainFactor = 1 + _sideGradient ^ 4; + }; }; -if (_velocity > 2) then { +if (_speed > 2) then { +#ifdef DEBUG_MODE_FULL + // TODO: Remove later + private _baseline = 2.10 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 0.90 * (_speed ^ 2); + private _graded = 2.10 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.90 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = _graded / _baseline; + hintSilent format["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n Impact %5", _fwdAngle toFixed 1, _sideAngle toFixed 1, _terrainFactor toFixed 2, _terrainGradient toFixed 1, _terrainImpact toFixed 2]; +#endif ( 2.10 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.90 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty } else { +#ifdef DEBUG_MODE_FULL + // TODO: Remove later + private _baseline = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 1.15 * (_speed ^ 2); + private _graded = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = _graded / _baseline; + hintSilent format["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n Impact %5", _fwdAngle toFixed 1, _sideAngle toFixed 1, _terrainFactor toFixed 2, _terrainGradient toFixed 1, _terrainImpact toFixed 2]; +#endif ( 1.05 * SIM_BODYMASS - + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty }; diff --git a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf index 111727c826e..682a6abbf04 100644 --- a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf @@ -7,21 +7,23 @@ * 1: Fatigue * 2: Speed * 3: Overexhausted + * 4: Forward Angle + * 5: Side Angle * * Return Value: * None * * Example: - * [_player, 0.5, 3.3, true] call ace_advanced_fatigue_fnc_handleEffects + * [_player, 0.5, 3.3, true, 0, 0] call ace_advanced_fatigue_fnc_handleEffects * * Public: No */ #include "script_component.hpp" -params ["_unit", "_fatigue", "_speed", "_overexhausted"]; +params ["_unit", "_fatigue", "_speed", "_overexhausted", "_fwdAngle", "_sideAngle"]; #ifdef DEBUG_MODE_FULL - systemChat str _fatigue; - systemChat str vectorMagnitude velocity _unit; + systemChat format["---- perceivedFatigue: %1 ----", _fatigue toFixed 2]; + systemChat format["---- speed: %1 ----", _speed toFixed 2]; #endif // - Audible effects ---------------------------------------------------------- @@ -78,10 +80,10 @@ if (_overexhausted) then { if (isForcedWalk _unit && {_fatigue < 0.7}) then { [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); } else { - if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + if ((isSprintAllowed _unit) && (_fatigue > 0.7 || abs(_fwdAngle) > 20 || abs(_sideAngle) > 20)) then { [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if ((!isSprintAllowed _unit) && {_fatigue < 0.6}) then { + if ((!isSprintAllowed _unit) && _fatigue < 0.6 && abs(_fwdAngle) < 20 && abs(_sideAngle) < 20) then { [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }; }; diff --git a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf index 0e31e896451..357e6b29096 100644 --- a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf +++ b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf @@ -54,7 +54,7 @@ GVAR(muscleDamage) = _newUnit getVariable [QGVAR(muscleDamage), 0]; } forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage)]; GVAR(VO2Max) = 35 + 20 * (_newUnit getVariable [QGVAR(performanceFactor), GVAR(performanceFactor)]); -GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * 0.23 * JOULES_PER_ML_O2 / 60; +GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * BIOMECH_EFFICIENCY * JOULES_PER_ML_O2 / 60; GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower); GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362; diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index 4b23153dff9..3ba70cc8046 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -21,6 +21,12 @@ if (!alive ACE_player) exitWith { // Dead people don't breath, Will also handle _staminaBarContainer ctrlCommit 1; }; +private _normal = surfaceNormal (getPosWorld ACE_player); +private _movementVector = vectorNormalized (velocity ACE_player); +private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); +private _fwdAngle = asin (_movementVector select 2) * GVAR(terrainGradientFactor); +private _sideAngle = asin (_sideVector select 2) * GVAR(terrainGradientFactor); + private _currentWork = REE; private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6; @@ -30,7 +36,7 @@ if (GVAR(isProne)) then { }; if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then { - _currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts); + _currentWork = [ACE_player, _currentSpeed, _fwdAngle, _sideAngle] call FUNC(getMetabolicCosts); _currentWork = _currentWork max REE; }; @@ -52,6 +58,11 @@ private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0; GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP; GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP; GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP; +#ifdef DEBUG_MODE_FULL +systemChat format["---- ae2: %1 ----", (GVAR(ae2Reserve) / AE2_MAXRESERVE) toFixed 2]; +systemChat format["---- an: %1 ----", (GVAR(anReserve) / AN_MAXRESERVE) toFixed 2]; +systemChat format["---- anFatigue: %1 ----", GVAR(anFatigue) toFixed 2]; +#endif // Increase anearobic fatigue GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1; @@ -72,7 +83,7 @@ private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Rese private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE; private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage); -[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects); +[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0, _fwdAngle, _sideAngle] call FUNC(handleEffects); if (GVAR(enableStaminaBar)) then { [GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar); diff --git a/addons/advanced_fatigue/script_component.hpp b/addons/advanced_fatigue/script_component.hpp index fcc8abd3c06..3f1379f99a3 100644 --- a/addons/advanced_fatigue/script_component.hpp +++ b/addons/advanced_fatigue/script_component.hpp @@ -2,7 +2,7 @@ #define COMPONENT_BEAUTIFIED Advanced Fatigue #include "\z\ace\addons\main\script_mod.hpp" -// #define DEBUG_MODE_FULL +#define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -20,10 +20,11 @@ #define SIM_BODYMASS 70 #define JOULES_PER_ML_O2 20.9 #define VO2MAX_STRENGTH 4.1 -#define REE 18.83 //((0.5617 * SIM_BODYMASS + 42.57) * 0.23) +#define BIOMECH_EFFICIENCY 0.23 +#define REE 18.83 //((0.5617 * SIM_BODYMASS + 42.57) * BIOMECH_EFFICIENCY) #define OXYGEN 0.9 #define WATTSPERATP 7 -#define AE1_MAXRESERVE 4000000 -#define AE2_MAXRESERVE 84000 -#define AN_MAXRESERVE 2300 +#define AE1_MAXRESERVE 4000000 // mmol +#define AE2_MAXRESERVE 84000 // mmol +#define AN_MAXRESERVE 2300 // mmol