Skip to content

Commit

Permalink
Explosives - Add Cellphone/Detonator Keybinds (#9687)
Browse files Browse the repository at this point in the history
Co-authored-by: Grim <[email protected]>
Co-authored-by: johnb432 <[email protected]>
  • Loading branch information
3 people authored Feb 7, 2024
1 parent 28e45c2 commit 2f9b700
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 30 deletions.
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
50 changes: 50 additions & 0 deletions addons/explosives/initKeybinds.inc.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "\a3\ui_f\hpp\defineDIKCodes.inc"

["ACE3 Equipment", 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";

true
}] call CBA_fnc_addKeybind; // Unbound

["ACE3 Equipment", 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);

true
}] call CBA_fnc_addKeybind; // Unbound

["ACE3 Equipment", QGVAR(cycleActiveClacker), LLSTRING(CycleActiveTrigger), {
if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {};

[ACE_player] call FUNC(cycleActiveTrigger);

true
}] call CBA_fnc_addKeybind; // Unbound
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>
<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

0 comments on commit 2f9b700

Please sign in to comment.