From 4916ec540e57c2a05367070e07faf70dbb7c3326 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:27:44 -0300 Subject: [PATCH] Common - Use MagazineReloading event for reload mutex (#8432) Co-authored-by: Salluci <69561145+Salluci@users.noreply.github.com> Co-authored-by: PabstMirror Co-authored-by: LinkIsGrim <> Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/common/XEH_postInit.sqf | 117 ++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index f5bea2958f8..ced3bf305b1 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -473,59 +473,84 @@ addMissionEventHandler ["PlayerViewChanged", { ////////////////////////////////////////////////// GVAR(isReloading) = false; -GVAR(reloadMutex_lastMagazines) = []; -// When reloading, the new magazine is removed from inventory, an animation plays and then the old magazine is added -// If the animation is interrupted, the new magazine will be lost -["loadout", { - params ["_unit", "_newLoadout"]; - private _mags = magazines _unit; - // if our magazine count dropped by 1, we might be reloading - if ((count GVAR(reloadMutex_lastMagazines)) - (count _mags) == 1) then { - private _weapon = currentWeapon _unit; - private _muzzle = currentMuzzle _unit; - if (_weapon == "") exitWith {}; - private _wpnMzlConfig = configFile >> "CfgWeapons" >> _weapon; - if (_muzzle != _weapon) then { _wpnMzlConfig = _wpnMzlConfig >> _muzzle; }; - - private _compatMags = [_wpnMzlConfig] call CBA_fnc_compatibleMagazines; - private _lastCompatMagCount = {_x in _compatMags} count GVAR(reloadMutex_lastMagazines); - private _curCompatMagCount = {_x in _compatMags} count _mags; - TRACE_3("",_wpnMzlConfig,_lastCompatMagCount,_curCompatMagCount); - if (_lastCompatMagCount - _curCompatMagCount != 1) exitWith {}; // check if magazines for our specific muzzle dropped by 1 - - private _gesture = getText (_wpnMzlConfig >> "reloadAction"); - if (_gesture == "") exitWith {}; //Ignore weapons with no reload gesture (binoculars) - private _isLauncher = _weapon isKindOf ["Launcher", configFile >> "CfgWeapons"]; - private _duration = 0; - if (_isLauncher) then { - _duration = getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> _gesture >> "speed"); - }; - if (_duration == 0) then { - _duration = getNumber (configFile >> "CfgGesturesMale" >> "States" >> _gesture >> "speed"); - }; - if (_duration != 0) then { - _duration = if (_duration < 0) then { abs _duration } else { 1 / _duration }; - } else { - _duration = 6; - }; +["unit", { + params ["_newPlayer"]; + + // Catch the current unit reloading + private _weaponState = weaponState _newPlayer; + GVAR(isReloading) = (_weaponState select 6) != 0; + + if (!GVAR(isReloading)) exitWith {}; - TRACE_2("Reloading, blocking gestures",_weapon,_duration); - GVAR(reloadingETA) = CBA_missionTime + _duration; + GVAR(magazineReloadPhase) = 0; - if (!GVAR(isReloading)) then { - GVAR(isReloading) = true; + // Wait until reload animation has finished (if weapon is no longer available, it returns -1) + [{ + private _magazineReloadingPhase = ((_this select 0) weaponState (_this select 1)) select 6; + + // Need to check the reloading phase, as if you interrupt reloading with a gesture, the phase will remain stuck at a value > 0 + if (GVAR(magazineReloadPhase) == _magazineReloadingPhase) exitWith { + TRACE_2("Interrupted magazine reloading",_this select 0,_this select 1); - [{ - CBA_missionTime > GVAR(reloadingETA) - },{ - GVAR(isReloading) = false; - }] call CBA_fnc_waitUntilAndExecute; + true }; - }; - GVAR(reloadMutex_lastMagazines) = _mags; + + GVAR(magazineReloadPhase) = _magazineReloadingPhase; + + _magazineReloadingPhase <= 0 + }, { + TRACE_2("End magazine reloading",_this select 0,_this select 1); + + // Player might switch units before reload finishes + if ((_this select 0) isNotEqualTo ACE_player) exitWith {}; + + GVAR(isReloading) = false; + }, [_newPlayer, _weaponState select 1]] call CBA_fnc_waitUntilAndExecute; }, true] call CBA_fnc_addPlayerEventHandler; +[QGVAR(magazineReloading), "MagazineReloading", { + params ["_unit", "", "_muzzle"]; + + TRACE_2("Init magazine reloading",_unit,_muzzle); + + // Wait until reload animation has started + [{ + ((_this select 0) weaponState (_this select 1)) select 6 != 0 + }, { + TRACE_2("Start magazine reloading",_this select 0,_this select 1); + + // Player might switch units before reload starts + if ((_this select 0) isNotEqualTo ACE_player) exitWith {}; + + GVAR(isReloading) = true; + GVAR(magazineReloadPhase) = 0; + + // Wait until reload animation has finished (if weapon is no longer available, it returns -1) + [{ + private _magazineReloadingPhase = ((_this select 0) weaponState (_this select 1)) select 6; + + // Need to check the reloading phase, as if you interrupt reloading with a gesture, the phase will remain stuck at a value > 0 + if (GVAR(magazineReloadPhase) == _magazineReloadingPhase) exitWith { + TRACE_2("Interrupted magazine reloading",_this select 0,_this select 1); + + true + }; + + GVAR(magazineReloadPhase) = _magazineReloadingPhase; + + _magazineReloadingPhase <= 0 + }, { + TRACE_2("End magazine reloading",_this select 0,_this select 1); + + // Player might switch units before reload finishes + if ((_this select 0) isNotEqualTo ACE_player) exitWith {}; + + GVAR(isReloading) = false; + }, _this] call CBA_fnc_waitUntilAndExecute; + }, [_unit, _muzzle], 5] call CBA_fnc_waitUntilAndExecute; +}] call CBA_fnc_addBISPlayerEventHandler; + ////////////////////////////////////////////////// // Start the sway loop //////////////////////////////////////////////////