Skip to content

Commit

Permalink
Common - Use MagazineReloading event for reload mutex (#8432)
Browse files Browse the repository at this point in the history
Co-authored-by: Salluci <[email protected]>
Co-authored-by: PabstMirror <[email protected]>
Co-authored-by: LinkIsGrim <>
Co-authored-by: johnb432 <[email protected]>
  • Loading branch information
4 people authored Dec 18, 2024
1 parent fdd33fd commit 4916ec5
Showing 1 changed file with 71 additions and 46 deletions.
117 changes: 71 additions & 46 deletions addons/common/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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
//////////////////////////////////////////////////
Expand Down

0 comments on commit 4916ec5

Please sign in to comment.