Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safemode - Refactor #10111

Merged
merged 11 commits into from
Aug 2, 2024
23 changes: 17 additions & 6 deletions addons/common/functions/fnc_getWeaponMuzzles.sqf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "..\script_component.hpp"
/*
* Author: commy2
* Author: commy2, johnb43
* Get the muzzles of a weapon.
*
* Arguments:
Expand All @@ -10,19 +10,30 @@
* All weapon muzzles <ARRAY>
*
* Example:
* ["gun"] call ace_common_fnc_getWeaponMuzzles
* "arifle_AK12_F" call ace_common_fnc_getWeaponMuzzles
*
* Public: Yes
*/

params [["_weapon", "", [""]]];

private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles");
private _config = configFile >> "CfgWeapons" >> _weapon;

if (!isClass _config) exitWith {
[] // return
};

private _muzzles = [];

// Get config case muzzle names
{
if (_x == "this") then {
_muzzles set [_forEachIndex, configName (configFile >> "CfgWeapons" >> _weapon)];
_muzzles pushBack (configName _config);
} else {
if (isClass (_config >> _x)) then {
_muzzles pushBack (configName (_config >> _x));
};
};
} forEach _muzzles;
} forEach getArray (_config >> "muzzles");

_muzzles
_muzzles // return
8 changes: 5 additions & 3 deletions addons/overheating/functions/fnc_jamWeapon.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ if (_unit getVariable [QGVAR(JammingActionID), -1] == -1) then {

private _condition = {
private _unit = _this select 1;
[_unit] call CBA_fnc_canUseWeapon
&& {currentMuzzle _unit in (_unit getVariable [QGVAR(jammedWeapons), []])}
&& {!(currentMuzzle _unit in (_unit getVariable [QEGVAR(safemode,safedWeapons), []]))}
(weaponState _unit) params ["_currentWeapon", "_currentMuzzle"];

_unit call CBA_fnc_canUseWeapon
&& {_currentMuzzle in (_unit getVariable [QGVAR(jammedWeapons), []])}
&& {!(["ace_safemode"] call EFUNC(common,isModLoaded)) || {!([_unit, _currentWeapon, _currentMuzzle] call EFUNC(safemode,getWeaponSafety))}}
};

private _statement = {
Expand Down
1 change: 0 additions & 1 deletion addons/safemode/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
Expand Down
4 changes: 2 additions & 2 deletions addons/safemode/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

PREP(getWeaponSafety);
PREP(lockSafety);
PREP(playChangeFiremodeSound);
PREP(setSafeModeVisual);
PREP(unlockSafety);
PREP(setWeaponSafety);
PREP(unlockSafety);
20 changes: 14 additions & 6 deletions addons/safemode/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,26 @@

if (!hasInterface) exitWith {};

["ACE3 Weapons", QGVAR(safeMode), localize LSTRING(SafeMode), {
["ACE3 Weapons", QGVAR(safeMode), LLSTRING(SafeMode), {
// Conditions: canInteract
if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false};

(weaponState ACE_player) params ["_currentWeapon", "_currentMuzzle"];

// Conditions: specific
if !([ACE_player] call CBA_fnc_canUseWeapon && {currentWeapon ACE_player != binocular ACE_player} && {currentWeapon ACE_player != ""}) exitWith {false};
if !(ACE_player call CBA_fnc_canUseWeapon && {_currentWeapon != ""} && {_currentWeapon != binocular ACE_player}) exitWith {false};

// Statement: Toggle weapon safety
[ACE_player, _currentWeapon, _currentMuzzle] call FUNC(lockSafety);

// Statement
[ACE_player, currentWeapon ACE_player, currentMuzzle ACE_player] call FUNC(lockSafety);
true
}, {false}, [DIK_GRAVE, [false, true, false]], false] call CBA_fnc_addKeybind;

["unit", {
private _weaponSafe = currentWeapon ACE_player in (ACE_player getVariable [QGVAR(safedWeapons), []]);
[!_weaponSafe] call FUNC(setSafeModeVisual);
(weaponState ACE_player) params ["_currentWeapon", "_currentMuzzle"];

private _weaponSafe = [ACE_player, _currentWeapon, _currentMuzzle] call FUNC(getWeaponSafety);

// Player HUD
!_weaponSafe call FUNC(setSafeModeVisual);
}] call CBA_fnc_addPlayerEventHandler;
45 changes: 45 additions & 0 deletions addons/safemode/functions/fnc_getWeaponSafety.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Getter for weapon safety state.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Weapon <STRING>
* 2: Muzzle <STRING> (default: current muzzle of weapon)
*
* Return Value:
* Safety status <BOOL>
*
* Example:
* [ACE_player, currentWeapon ACE_player] call ace_safemode_fnc_getWeaponSafety
*
* Public: Yes
*/

params [
["_unit", objNull, [objNull]],
["_weapon", "", [""]],
["_muzzle", nil, [""]]
];

if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {false};

// Check if weapon is a binocular
if ((_weapon call EFUNC(common,getItemType)) select 1 == "binocular") exitWith {false};

// Check for invalid muzzles
_muzzle = if (isNil "_muzzle") then {
// Get current weapon muzzle if not defined
(_unit weaponState _weapon) select 1
} else {
// Get config case muzzle names
private _muzzles = _weapon call EFUNC(common,getWeaponMuzzles);

_muzzles param [_muzzles findIf {_x == _muzzle}, ""]
};

// Weapon is not available
if (_muzzle == "") exitWith {false};

_muzzle in ((_unit getVariable [QGVAR(safedWeapons), createHashMap]) getOrDefault [_weapon, createHashMap]) // return
89 changes: 48 additions & 41 deletions addons/safemode/functions/fnc_lockSafety.sqf
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#include "..\script_component.hpp"
/*
* Author: commy2
* Put weapon on safety, or take it off safety if safety is already put on.
* Author: commy2, johnb43
* Puts weapon on safety, or take it off safety if safety is already put on.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Weapon <STRING>
* 2: Muzzle <STRING>
* 3: Show hint <BOOL>
* 3: Show hint <BOOL> (default: true)
*
* Return Value:
* None
Expand All @@ -18,67 +18,74 @@
* Public: No
*/

params ["_unit", "_weapon", "_muzzle", ["_hint", true, [true]]];
params ["_unit", "_weapon", "_muzzle", ["_hint", true]];

private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []];
private _safedWeapons = _unit getVariable QGVAR(safedWeapons);

if (_weapon in _safedWeapons) exitWith {
_this call FUNC(unlockSafety);
if (isNil "_safedWeapons") then {
_safedWeapons = createHashMap;

_unit setVariable [QGVAR(safedWeapons), _safedWeapons];
};

// See if the current weapon has locked muzzles
private _safedWeaponMuzzles = _safedWeapons getOrDefault [_weapon, createHashMap, true];

// If muzzle is locked, unlock it (toggle)
if (_muzzle in _safedWeaponMuzzles) exitWith {
[_unit, _weapon, _muzzle, _hint] call FUNC(unlockSafety);
};

_safedWeapons pushBack _weapon;
private _firemode = (_unit weaponState _muzzle) select 2;

_unit setVariable [QGVAR(safedWeapons), _safedWeapons];
// This syntax of selectWeapon doesn't mess with gun lights and lasers
_unit selectWeapon [_weapon, _muzzle, _firemode];

if (_unit getVariable [QGVAR(actionID), -1] == -1) then {
// Store new muzzle & firemode
_safedWeaponMuzzles set [_muzzle, _firemode];

// Lock muzzle
if (isNil {_unit getVariable QGVAR(actionID)}) then {
_unit setVariable [QGVAR(actionID), [
_unit, "DefaultAction", {
params ["", "_unit"];

if (
[_this select 1] call CBA_fnc_canUseWeapon
&& {
if (currentMuzzle (_this select 1) in ((_this select 1) getVariable [QGVAR(safedWeapons), []])) then {
if (inputAction "nextWeapon" > 0) exitWith {
[_this select 1, currentWeapon (_this select 1), currentMuzzle (_this select 1)] call FUNC(unlockSafety);
_unit call CBA_fnc_canUseWeapon && {
(weaponState _unit) params ["_currentWeapon", "_currentMuzzle"];

// Block firing the muzzle in safe mode
if (_currentMuzzle in ((_unit getVariable [QGVAR(safedWeapons), createHashMap]) getOrDefault [_currentWeapon, createHashMap])) then {
if (inputAction "nextWeapon" > 0 || {inputAction "prevWeapon" > 0}) exitWith {
[_unit, _currentWeapon, _currentMuzzle] call FUNC(unlockSafety);

false
};

true
} else {false}
} else {
false
}
}
) then {
// player hud
[false] call FUNC(setSafeModeVisual);
// Player HUD
false call FUNC(setSafeModeVisual);

true
} else {
// player hud
[true] call FUNC(setSafeModeVisual);
// Player HUD
true call FUNC(setSafeModeVisual);

false
};
}, {}
] call EFUNC(common,addActionEventHandler)];
};

if (_muzzle isEqualType "") then {
private _laserEnabled = _unit isIRLaserOn _weapon || {_unit isFlashlightOn _weapon};

_unit selectWeapon _muzzle;

if (
_laserEnabled
&& {
_muzzle == primaryWeapon _unit // prevent UGL switch
|| {"" == primaryWeapon _unit} // Arma switches to primary weapon if exists
}
) then {
{_unit action [_x, _unit]} forEach ["GunLightOn", "IRLaserOn"];
};
};

// play fire mode selector sound
// Play fire mode selector sound
[_unit, _weapon, _muzzle] call FUNC(playChangeFiremodeSound);

// show info box unless disabled
// Show info box unless disabled
if (_hint) then {
private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture");
[localize LSTRING(PutOnSafety), _picture] call EFUNC(common,displayTextPicture);
[LLSTRING(PutOnSafety), getText (configFile >> "CfgWeapons" >> _weapon >> "picture")] call EFUNC(common,displayTextPicture);
};

20 changes: 11 additions & 9 deletions addons/safemode/functions/fnc_playChangeFiremodeSound.sqf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: commy2
* Play weapon firemode change sound.
* Plays weapon firemode change sound.
*
* Arguments:
* 0: Unit <OBJECT>
Expand All @@ -21,21 +21,23 @@ params ["_unit", "_weapon"];
private _sound = getArray (configFile >> "CfgWeapons" >> _weapon >> "changeFiremodeSound");

if (_sound isEqualTo []) exitWith {
playSound "ACE_Sound_Click";
playSoundUI ["ACE_Sound_Click"];
};

// get position where to play the sound (position of the weapon)
private _position = _unit modelToWorldVisualWorld (_unit selectionPosition "RightHand");

_sound params ["_filename", ["_volume", 1], ["_soundPitch", 1], ["_distance", 0]];
_sound params [["_filename", ""], ["_volume", 1], ["_soundPitch", 1], ["_distance", 0]];

if (_filename == "") exitWith {
playSound "ACE_Sound_Click";
playSoundUI ["ACE_Sound_Click"];
};

// add file extension .wss as default
// Add file extension .wss as default
if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then {
_filename = format ["%1.wss", _filename];
};

playSound3D [_filename, objNull, false, _position, _volume, _soundPitch, _distance];
// Get position where to play the sound (position of the weapon)
private _position = _unit modelToWorldVisualWorld (_unit selectionPosition "RightHand");

playSound3D [_filename, objNull, insideBuilding _unit >= 0.5, _position, _volume, _soundPitch, _distance];

nil // return
8 changes: 4 additions & 4 deletions addons/safemode/functions/fnc_setSafeModeVisual.sqf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: commy2
* Show firemode indicator, representing safety lock
* Shows firemode indicator, representing safety lock.
*
* Arguments:
* 0: Show firemode <BOOL>
Expand All @@ -10,7 +10,7 @@
* None
*
* Example:
* [true] call ace_safemode_fnc_setSafeModeVisual
* true call ace_safemode_fnc_setSafeModeVisual
*
* Public: No
*/
Expand All @@ -27,8 +27,8 @@ if (_show) then {
private _config = configFile >> "RscInGameUI" >> "RscUnitInfoSoldier" >> "WeaponInfoControlsGroupLeft" >> "controls" >> "CA_ModeTexture";

_control ctrlSetPosition [getNumber (_config >> "x"), getNumber (_config >> "y"), getNumber (_config >> "w"), getNumber (_config >> "h")];
_control ctrlCommit 0;
} else {
_control ctrlSetPosition [0, 0, 0, 0];
_control ctrlCommit 0;
};

_control ctrlCommit 0;
Loading