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

Explosives - Add Cellphone/Detonator Keybinds #9687

Merged
merged 18 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions addons/explosives/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ PREP(cancelPlacement);
PREP(canDefuse);
PREP(canDetonate);
PREP(connectExplosive);
PREP(cycleActiveTrigger);
PREP(defuseExplosive);
PREP(detonateExplosive);
PREP(detonateExplosiveAll);
Expand Down
3 changes: 3 additions & 0 deletions addons/explosives/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

#include "initKeybinds.inc.sqf"
#include "initSettings.inc.sqf"

GVAR(activeTrigger) = "";

GVAR(detonationHandlers) = [];
GVAR(excludedMines) = [];

Expand Down
88 changes: 58 additions & 30 deletions addons/explosives/functions/fnc_addDetonateActions.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,43 @@ private _explosivesList = [];
};
};
} forEach _result;
if (_detonator != "ACE_DeadManSwitch") then {
// Add action to detonate all explosives tied to the detonator
if (count _explosivesList > 0) then {
_children pushBack [

// If the detonator is not active, is a clacker and has assigned explosives, generate an interaction to make it the active detonator for use with the "trigger all" keybind
if (
_detonator != GVAR(activeTrigger) &&
{_detonator != "Cellphone"} &&
{
_explosivesList isNotEqualTo [] ||
{_detonator == "ACE_DeadManSwitch" && {_unit getVariable [QGVAR(deadmanInvExplosive), ""] != ""}}
}
) then {
_children pushBack [
[
"Explosive_All",
localize LSTRING(DetonateAll),
getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"),
{(_this select 2) call FUNC(detonateExplosiveAll);},
QGVAR(setActiveTrigger),
LLSTRING(SetActiveTrigger),
"",
{GVAR(activeTrigger) = (_this select 2) select 0;},
{true},
{},
[_unit,_range,_explosivesList, _detonator]
[_detonator]
] call EFUNC(interact_menu,createAction),
[],
_unit
];
};

if (_detonator != "ACE_DeadManSwitch") then {
// Add action to detonate all explosives tied to the detonator
if (count _explosivesList > 1) then {
_children pushBack [
[
"Explosive_All",
LLSTRING(DetonateAll),
getText (configFile >> "CfgWeapons" >> _detonator >> "picture"),
{(_this select 2) call FUNC(detonateExplosiveAll);},
{true},
{},
[_unit, _range, _explosivesList, _detonator]
] call EFUNC(interact_menu,createAction),
[],
_unit
Expand All @@ -69,15 +94,15 @@ if (_detonator != "ACE_DeadManSwitch") then {
} else {
//Add action to detonate all explosives (including the inventory explosive):
_children pushBack [
[
"Explosive_All_Deadman",
localize LSTRING(DetonateAll),
getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"),
{[_player] call FUNC(onIncapacitated)},
{true}
] call EFUNC(interact_menu,createAction),
[],
_unit
[
"Explosive_All_Deadman",
LLSTRING(DetonateAll),
getText (configFile >> "CfgWeapons" >> _detonator >> "picture"),
{[_player] call FUNC(onIncapacitated)},
{true}
] call EFUNC(interact_menu,createAction),
[],
_unit
];

//Adds actions for the explosives you can connect to the deadman switch.
Expand All @@ -89,7 +114,7 @@ if (_detonator != "ACE_DeadManSwitch") then {

_connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""];
if (_connectedInventoryExplosive != "") then {
//Add the disconect action
//Add the disconnect action
private _magConfig = configFile >> "CfgMagazines" >> _connectedInventoryExplosive;
private _name = if ((getText (_magConfig >> "displayNameShort")) != "") then {
getText (_magConfig >> "displayNameShort")
Expand All @@ -99,17 +124,20 @@ if (_detonator != "ACE_DeadManSwitch") then {
private _picture = getText (_magConfig >> "picture");

_children pushBack [
([
"Deadman_disconnect",
format ["%1 %2", localize "str_disp_disconnect", _name],
_picture,
{
params ["_player"];
TRACE_1("clear",_player);
_player setVariable [QGVAR(deadmanInvExplosive), "", true];
},
{true}
] call EFUNC(interact_menu,createAction)), [], _unit];
([
"Deadman_disconnect",
format ["%1 %2", localize "str_disp_disconnect", _name],
_picture,
{
params ["_player"];
TRACE_1("clear",_player);
_player setVariable [QGVAR(deadmanInvExplosive), "", true];
},
{true}
] call EFUNC(interact_menu,createAction)),
[],
_unit
];

} else {
//Add all magazines that would work with the deadman switch
Expand Down
53 changes: 53 additions & 0 deletions addons/explosives/functions/fnc_cycleActiveTrigger.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "..\script_component.hpp"
/*
* Author: mrschick
* Cycles the "Active Trigger" of a unit and shows a CBA Hint that displays the new Active Trigger.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [ACE_player] call ace_explosives_fnc_cycleActiveTrigger;
*
* Public: No
*/

params ["_unit"];
TRACE_1("params",_unit);

private _detonators = _unit call FUNC(getDetonators);

// Remove ACE_Cellphone from list, as it should never be the active trigger due to having its own keybind
_detonators deleteAt (_detonators findIf {_x == "ACE_Cellphone"});

// Reset Active Trigger if none available
if (_detonators isEqualTo []) exitWith {
GVAR(activeTrigger) = "";
};

private _activeTrigger = GVAR(activeTrigger);
private _index = _detonators findIf {_x == _activeTrigger};
private _count = count _detonators;

if (_activeTrigger != "" && {_index != -1} && {_count > 1}) then {
// If active trigger is set and among current detonators, switch to the next one
if (_index < _count - 1) then {
_index = _index + 1;
} else {
_index = 0;
};
_activeTrigger = _detonators select _index;
} else {
// Assign first detonator in list as the active one
_activeTrigger = _detonators select 0;
};

GVAR(activeTrigger) = _activeTrigger;
private _triggerConfig = configFile >> "CfgWeapons" >> _activeTrigger;
private _triggerName = getText (_triggerConfig >> "displayName");
private _triggerIcon = getText (_triggerConfig >> "picture");

[format ["%1: %2", LLSTRING(ActiveTrigger), _triggerName], _triggerIcon] call EFUNC(common,displayTextPicture);
9 changes: 9 additions & 0 deletions addons/explosives/functions/fnc_selectTrigger.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ TRACE_3("params",_explosive,_magazine,_trigger);

private _config = ConfigFile >> "ACE_Triggers" >> _trigger;

// Make selected trigger the active one (for keybind) if it's the first to be connected
private _activeTrigger = GVAR(activeTrigger);
if (
_activeTrigger == "" &&
{(["Command", "MK16_Transmitter", "DeadManSwitch"] findIf {_x == _trigger}) != -1}
) then {
GVAR(activeTrigger) = getArray (_config >> "requires") select 0;
};

// If the onSetup function returns true, it is handled elsewhere
if (isText(_config >> "onSetup") && {[_explosive,_magazine] call compile getText (_config >> "onSetup")}) exitWith {
TRACE_2("onSetup returned true",_explosive,_trigger);
Expand Down
42 changes: 42 additions & 0 deletions addons/explosives/initKeybinds.inc.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "\a3\ui_f\hpp\defineDIKCodes.inc"

["ACE Explosives", QGVAR(openCellphone), LLSTRING(cellphone_displayName), {
if (
!([ACE_player, "ACE_Cellphone"] call EFUNC(common,hasItem)) ||
!([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith))
) exitWith {};
closeDialog 0;
createDialog "Rsc_ACE_PhoneInterface";
}, {false}, [DIK_C, [false, false, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+C)

["ACE Explosives", QGVAR(detonateActiveClacker), LLSTRING(DetonateAllOnActive), {
// Prevent use of keybind while surrendering or captive
if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {};

private _detonator = GVAR(activeTrigger);
if (_detonator == "" || !(_detonator in ([ACE_player] call FUNC(getDetonators)))) exitWith {};

// When using a Dead Man's Switch, skip all other logic and just call fnc_onIncapacitated, since it already handles everything that is required to detonate all connected explosives
if (_detonator == "ACE_DeadManSwitch") exitWith {
[ACE_player] call FUNC(onIncapacitated);
};

private _range = getNumber (configFile >> "CfgWeapons" >> _detonator >> QGVAR(Range));

private _explosivesList = [];
{
if (!isNull (_x select 0)) then {
private _required = getArray (configFile >> "ACE_Triggers" >> _x select 4 >> "requires");
if (_detonator in _required) then {
_explosivesList pushBack _x;
};
};
} forEach ([ACE_player] call FUNC(getPlacedExplosives));

[ACE_player, _range, _explosivesList, _detonator] call FUNC(detonateExplosiveAll);
}, {false}, [DIK_C, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (CTRL+ALT+C)

["ACE Explosives", QGVAR(cycleActiveClacker), LLSTRING(CycleActiveTrigger), {
if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {};
[ACE_player] call FUNC(cycleActiveTrigger);
}, {false}, [DIK_C, [false, true, false]], false, 0] call CBA_fnc_addKeybind; // (CTRL+C)
mrschick marked this conversation as resolved.
Show resolved Hide resolved
20 changes: 20 additions & 0 deletions addons/explosives/stringtable.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@
<Chinese>引爆全部</Chinese>
<Turkish>Hepsini Patlat</Turkish>
</Key>
<Key ID="STR_ACE_Explosives_DetonateAllOnActive">
<English>Detonate All on Active Clacker</English>
<German>Alle auf Standardzünder zünden</German>
<Italian>Detona Tutti sul Detonatore Attivo</Italian>
</Key>
<Key ID="STR_ACE_Explosives_SetActiveTrigger">
<English>Set Active Clacker</English>
<German>Als Standardzünder Wählen</German>
<Italian>Imposta Detonatore Attivo</Italian>
</Key>
<Key ID="STR_ACE_Explosives_CycleActiveTrigger">
<English>Cycle Active Clacker</English>
<German>Standardzünder Wechseln</German>
mrschick marked this conversation as resolved.
Show resolved Hide resolved
<Italian>Cambia Detonatore Attivo</Italian>
</Key>
<Key ID="STR_ACE_Explosives_ActiveTrigger">
<English>Active Clacker</English>
<German>Standardzünder</German>
<Italian>Detonatore Attivo</Italian>
</Key>
<Key ID="STR_ACE_Explosives_DetonateCode">
<English>Explosive code: %1</English>
<German>Sprengstoffcode: %1</German>
Expand Down
1 change: 1 addition & 0 deletions docs/wiki/feature/explosives.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Enables attaching explosives to vehicles.
- Interact with the explosive <kbd>⊞&nbsp;Win</kbd> (ACE3 default key bind `Interact Key`).
- Choose the arming method.
- For clackers use Self Interaction `Explosives` &rarr; `Detonate` and choose the corresponding Firing Device.
- Alternatively, use <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>C</kbd> (ACE3 default key bind `Detonate All on Active Clacker`) to detonate all explosives tied to the `Active Detonator`, which can be changed via the `Set Active Detonator` interaction on the desired Clacker / Dead Man Switch.

### 2.3 Defusing explosives
- A `Defusal Kit` is required.
Expand Down
Loading