diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index c981a4a2b1..43bea6242f 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -540,21 +540,30 @@ GVAR(deviceKeyCurrentIndex) = -1; [0xC7, [true, false, false]], false] call CBA_fnc_addKeybind; //SHIFT + Home Key -["ACE3 Weapons", QGVAR(unloadWeapon), LLSTRING(unloadWeapon), { - // Conditions: - if !([ACE_player, objNull, ["isNotInside"]] call FUNC(canInteractWith)) exitWith {false}; +["ACE3 Weapons", QGVAR(unloadWeapon), LSTRING(unloadWeapon), { + private _unit = ACE_player; - private _currentWeapon = currentWeapon ACE_player; - if !(_currentWeapon != primaryWeapon _unit && {_currentWeapon != handgunWeapon _unit} && {_currentWeapon != secondaryWeapon _unit}) exitWith {false}; + // Conditions + if !([_unit, objNull, ["isNotInside"]] call FUNC(canInteractWith)) exitWith {false}; - private _currentMuzzle = currentMuzzle ACE_player; - private _currentAmmoCount = ACE_player ammo _currentMuzzle; - if (_currentAmmoCount < 1) exitWith {false}; + if !(_unit call CBA_fnc_canUseWeapon) exitWith {false}; + + (weaponState _unit) params ["_weapon", "_muzzle", "", "_magazine", "_ammo"]; + + // Check if there is any ammo + if (_ammo < 1) exitWith {false}; + + // Check if the unit has a weapon + if (_weapon == "") exitWith {false}; + + // Check if the unit has a weapon selected + if !(_weapon in [primaryWeapon _unit, handgunWeapon _unit, secondaryWeapon _unit]) exitWith {false}; + + // Statement + [_unit, _weapon, _muzzle, _magazine, _ammo, false] call FUNC(unloadUnitWeapon); - // Statement: - [ACE_player, _currentWeapon, _currentMuzzle, _currentAmmoCount, false] call FUNC(unloadUnitWeapon); true -}, {false}, [19, [false, false, true]], false] call CBA_fnc_addKeybind; //ALT + R Key +}, {false}, [19, [false, false, true]], false] call CBA_fnc_addKeybind; // Alt + R ["CBA_loadoutSet", { params ["_unit", "_loadout"]; diff --git a/addons/common/functions/fnc_unloadUnitWeapon.sqf b/addons/common/functions/fnc_unloadUnitWeapon.sqf index d82684fe22..e3dabe5949 100644 --- a/addons/common/functions/fnc_unloadUnitWeapon.sqf +++ b/addons/common/functions/fnc_unloadUnitWeapon.sqf @@ -1,37 +1,61 @@ #include "script_component.hpp" /* - * Author: drofseh & Commy2 + * Author: drofseh, commy2, johnb43 * Unload the magazine from the unit's weapon and attempt to put it in a sensible place. * * Arguments: - * 0: Player + * 0: Unit * 1: Weapon - * 2: Muzzle (optional, default: Weapon) - * 3: Ammo count (optional, default: ammo currentMuzzle Player) - * 4: Skip animation? (optional, default: false) + * 2: Muzzle (default: Weapon) + * 3: Magazine (default: magazine in Weapon) + * 4: Ammo count (default: Unit ammo Muzzle) + * 5: Skip animation? (default: false) * * Return Value: * None * * Example: - * [ACE_player, currentWeapon ACE_player, currentMuzzle ACE_player, 23, false] call ace_common_fnc_unloadUnitWeapon + * [ACE_player, currentWeapon ACE_player, currentMuzzle ACE_player, currentMagazine ACE_player, 23, false] call ace_common_fnc_unloadUnitWeapon * * Public: No */ -params ["_unit", "_weapon", ["_muzzle", _weapon], ["_ammoCount", _unit ammo _muzzle ], ["_skipAnim", false]]; -TRACE_5("params",_unit,_weapon,_muzzle,_ammoCount,_skipAnim); +params ["_unit", "_weapon", "_muzzle", "_magazine", "_ammoCount", ["_skipAnim", false]]; +TRACE_6("params",_unit,_weapon,_muzzle,_magazine,_ammoCount,_skipAnim); -// audiovisual effects +if (_unit getVariable [QGVAR(isUnloadingWeapon), false]) exitWith {}; + +// Only allow 1 weapon to be unloaded at a time (because of animation length) +_unit setVariable [QGVAR(isUnloadingWeapon), true]; + +if (isNil "_muzzle") then { + _muzzle = _weapon; +}; + +if (isNil "_magazine") then { + private _weaponState = _unit weaponState _muzzle; + + _magazine = _weaponState select 3; + _ammoCount = _weaponState select 4; +}; + +if (isNil "_ammoCount") then { + _ammoCount = _unit ammo _muzzle; +}; + +// Audiovisual effects private _delay = 0; -if !(_skipAnim) then { + +if (!_skipAnim) then { _delay = 1.5; + private _config = configFile >> "CfgWeapons" >> _weapon; + if (_weapon != _muzzle) then { _config = _config >> _muzzle; }; - // get and play animation + // Get and play animation private _unloadAction = getText (_config >> "ACE_unloadAction"); if (_unloadAction == "") then { @@ -40,22 +64,31 @@ if !(_skipAnim) then { [_unit, _unloadAction, 1] call FUNC(doGesture); - // get and play sound + // Get and play sound private _unloadSound = getText (_config >> "ACE_unloadSound"); if (_unloadSound == "") then { _unloadSound = "A3\Sounds_F\arsenal\weapons\Rifles\Katiba\reload_Katiba.wss"; + private _unloadSoundArray = getArray (_config >> "reloadMagazineSound"); - // file extention is required for playSound3D + // File extention is required for playSound3D if (_unloadSoundArray isNotEqualTo []) then { private _wssTest = format ["%1.wss", _unloadSoundArray select 0]; + if (fileExists _wssTest) then { _unloadSound = _wssTest; } else { private _wavTest = format ["%1.wav", _unloadSoundArray select 0]; + if (fileExists _wavTest) then { _unloadSound = _wavTest; + } else { + private _oggTest = format ["%1.ogg", _unloadSoundArray select 0]; + + if (fileExists _oggTest) then { + _unloadSound = _oggTest; + }; }; }; }; @@ -64,24 +97,32 @@ if !(_skipAnim) then { playSound3D [_unloadSound, _unit]; }; -// remove magazine from weapon and add it to inventory +// Remove magazine from weapon and add it to inventory [{ - params ["_unit", "_weapon", "_ammoCount"]; + params ["_unit", "_weapon", "_muzzle", "_magazine", "_ammoCount"]; - // remove weapon item - private _magazineClass = currentMagazine _unit; + _unit setVariable [QGVAR(isUnloadingWeapon), nil]; - switch true do { - case (_weapon == primaryWeapon _unit): { - _unit removePrimaryWeaponItem _magazineClass; + private _returnMagazine = true; + + // Check if it's possible to remove given item from weapon; If possible, remove weapon item + switch (true) do { + case (_weapon == primaryWeapon _unit && {_weapon canAdd [_magazine, _muzzle]}): { + _unit removePrimaryWeaponItem _magazine; }; - case (_weapon == handgunWeapon _unit): { - _unit removeHandgunItem _magazineClass; + case (_weapon == handgunWeapon _unit && {_weapon canAdd [_magazine, _muzzle]}): { + _unit removeHandgunItem _magazine; }; - case (_weapon == secondaryWeapon _unit): { - _unit removeSecondaryWeaponItem _magazineClass; + case (_weapon == secondaryWeapon _unit && {_weapon canAdd [_magazine, _muzzle]}): { + _unit removeSecondaryWeaponItem _magazine; + }; + default { + _returnMagazine = false; }; }; - [_unit, _magazineClass, _ammoCount, true] call CBA_fnc_addMagazine; -}, [_unit, _weapon, _ammoCount], _delay] call CBA_fnc_waitAndExecute; + // Avoid duplicating magazines (e.g. by switching weapons mid unload) + if (!_returnMagazine) exitWith {}; + + [_unit, _magazine, _ammoCount, true] call CBA_fnc_addMagazine; +}, [_unit, _weapon, _muzzle, _magazine, _ammoCount], _delay] call CBA_fnc_waitAndExecute;