Skip to content

Commit

Permalink
Safemode - Refactor (acemod#10111)
Browse files Browse the repository at this point in the history
* Refactor safemode

* Further improvements and fixes

* Update XEH_postInit.sqf

* Don't allow binoculars to be set to safe

* Add API for getting weapon safety status

* Update fnc_jamWeapon.sqf

* Added doc

* Update fnc_playChangeFiremodeSound.sqf

* Update addons/overheating/functions/fnc_jamWeapon.sqf

Co-authored-by: PabstMirror <[email protected]>

* Update addons/weaponselect/functions/fnc_selectWeaponMode.sqf

Co-authored-by: PabstMirror <[email protected]>

---------

Co-authored-by: PabstMirror <[email protected]>
  • Loading branch information
2 people authored and blake8090 committed Aug 18, 2024
1 parent d180ed8 commit 1f5c3fa
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 137 deletions.
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

0 comments on commit 1f5c3fa

Please sign in to comment.