mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Explosives - Add code handler for detonation (#5115)
* Explosives - Add code handler for detonation * Add info to wiki * Fix cellphone in demo code, move example to wiki
This commit is contained in:
parent
68a6782078
commit
08217f460e
@ -2,6 +2,7 @@
|
||||
PREP(addCellphoneIED);
|
||||
PREP(addClacker);
|
||||
PREP(addDetonateActions);
|
||||
PREP(addDetonateHandler);
|
||||
PREP(addExplosiveActions);
|
||||
PREP(addToSpeedDial);
|
||||
PREP(addTransmitterActions);
|
||||
|
@ -25,4 +25,6 @@ if (isServer) then {
|
||||
GVAR(explosivesOrientations) = []
|
||||
};
|
||||
|
||||
GVAR(detonationHandlers) = [];
|
||||
|
||||
ADDON = true;
|
||||
|
@ -43,7 +43,7 @@ _explosivesList = [];
|
||||
{(_this select 2) call FUNC(detonateExplosive);},
|
||||
{true},
|
||||
{},
|
||||
[_unit,_range,_x]
|
||||
[_unit,_range,_x,_detonator]
|
||||
] call EFUNC(interact_menu,createAction),
|
||||
[],
|
||||
_unit
|
||||
@ -62,7 +62,7 @@ if (_detonator != "ACE_DeadManSwitch") then {
|
||||
{(_this select 2) call FUNC(detonateExplosiveAll);},
|
||||
{true},
|
||||
{},
|
||||
[_unit,_range,_explosivesList]
|
||||
[_unit,_range,_explosivesList, _detonator]
|
||||
] call EFUNC(interact_menu,createAction),
|
||||
[],
|
||||
_unit
|
||||
|
24
addons/explosives/functions/fnc_addDetonateHandler.sqf
Normal file
24
addons/explosives/functions/fnc_addDetonateHandler.sqf
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Add a explosive detonation handler.
|
||||
* Should be called on all machines.
|
||||
* Code needs to return BOOL: true(allowed) / false(blocked)
|
||||
* See https://ace3mod.com/wiki/framework/explosives-framework.html for an example.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Code <CODE>
|
||||
* - Passed [Unit<OBJECT>, MaxRange <NUMBER>, Explosive <OBJECT>, FuzeTime <NUMBER>, TriggerItem <STRING>]
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [{false}] call ace_explosives_fnc_addDetonateHandler;
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params [["_code", {true}, [{}]]];
|
||||
|
||||
GVAR(detonationHandlers) pushBack _code;
|
@ -21,7 +21,7 @@ TRACE_2("params",_unit,_explosive);
|
||||
|
||||
if (GVAR(ExplodeOnDefuse) && {(random 1.0) < (getNumber (ConfigFile >> "CfgAmmo" >> typeOf _explosive >> QGVAR(explodeOnDefuseChance)))}) exitWith {
|
||||
TRACE_1("exploding on defuse",_explosive);
|
||||
[_unit, -1, [_explosive, 1], true] call FUNC(detonateExplosive);
|
||||
[_unit, -1, [_explosive, 1], "#ExplodeOnDefuse"] call FUNC(detonateExplosive);
|
||||
[QGVAR(explodeOnDefuse), [_explosive, _unit]] call CBA_fnc_globalEvent;
|
||||
};
|
||||
|
||||
|
@ -8,28 +8,35 @@
|
||||
* 2: Explosive <ARRAY>
|
||||
* 0: Explosive <OBJECT>
|
||||
* 1: Fuse time <NUMBER>
|
||||
* 3: Trigger Item Classname <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, 100, [Explosive, 1]] call ACE_Explosives_fnc_detonateExplosive; // has to be within range
|
||||
* [player, -1, [Explosive, 1]] call ACE_Explosives_fnc_detonateExplosive; // range ignored.
|
||||
* [player, 100, [Explosive, 1], "ACE_Clacker"] call ACE_Explosives_fnc_detonateExplosive; // has to be within range
|
||||
* [player, -1, [Explosive, 1], "ACE_Cellphone"] call ACE_Explosives_fnc_detonateExplosive; // range ignored.
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", "_range", "_item"];
|
||||
TRACE_3("params",_unit,_range,_item);
|
||||
params ["_unit", "_range", "_item", ["_triggerClassname", "#unknown", [""]]];
|
||||
TRACE_4("detonateExplosive",_unit,_range,_item,_triggerClassname);
|
||||
|
||||
private ["_result", "_ignoreRange", "_pos"];
|
||||
|
||||
_ignoreRange = (_range == -1);
|
||||
_result = true;
|
||||
|
||||
if (!_ignoreRange && {(_unit distance (_item select 0)) > _range}) exitWith {TRACE_1("out of range",_range); false};
|
||||
|
||||
_result = true;
|
||||
{
|
||||
// Pass [Unit<OBJECT>, MaxRange <NUMBER>, Explosive <OBJECT>, FuzeTime <NUMBER>, TriggerItem <STRING>]
|
||||
private _handlerResult = [_unit, _range, _item select 0, _item select 1, _triggerClassname] call _x;
|
||||
if (_handlerResult isEqualTo false) then {TRACE_1("Handler Failed",_forEachIndex); _result = false};
|
||||
} forEach GVAR(detonationHandlers);
|
||||
if (!_result) exitWith {false};
|
||||
|
||||
if (getNumber (ConfigFile >> "CfgAmmo" >> typeOf (_item select 0) >> "TriggerWhenDestroyed") == 0) then {
|
||||
private ["_exp", "_previousExp"];
|
||||
_previousExp = _item select 0;
|
||||
|
@ -8,20 +8,21 @@
|
||||
* 2: Explosives to detonate <ARRAY>
|
||||
* 0: Explosive <OBJECT>
|
||||
* 1: Fuse time <NUMBER>
|
||||
* 3: Trigger Item Classname <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, -1, [[c4,0.5]]] call ACE_Explosives_fnc_detonateExplosiveAll;
|
||||
* [player, -1, [[c4,0.5]], "ACE_Clacker"] call ACE_Explosives_fnc_detonateExplosiveAll;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", "_range", "_explosivesList"];
|
||||
TRACE_3("Params",_unit,_range,_explosivesList);
|
||||
params ["_unit", "_range", "_explosivesList", "_triggerClassname"];
|
||||
TRACE_4("Params",_unit,_range,_explosivesList,_triggerClassname);
|
||||
|
||||
{
|
||||
[_unit,_range,_x] call FUNC(detonateExplosive);
|
||||
[_unit,_range,_x,_triggerClassname] call FUNC(detonateExplosive);
|
||||
} forEach _explosivesList;
|
||||
|
@ -41,6 +41,6 @@ if (_unit == ace_player) then {
|
||||
playSound3D [QUOTE(PATHTO_R(Data\Audio\Cellphone_Ring.wss)),objNull, false, getPosASL (_this select 1),3.16228,1,75];
|
||||
(_this select 0) setVariable [QGVAR(Dialing), false, true];
|
||||
}, [_unit,_explosive select 0], 0.25 * (count _arr - 4)] call CBA_fnc_waitAndExecute;
|
||||
[_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2)] call FUNC(startTimer);
|
||||
[_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2), "ACE_Cellphone"] call FUNC(startTimer);
|
||||
};
|
||||
};
|
||||
|
@ -31,7 +31,7 @@ private _explosive = [_code] call FUNC(getSpeedDialExplosive);
|
||||
if (_i >= (count _arr + 2)) then {
|
||||
[_pfID] call CALLSTACK(CBA_fnc_removePerFrameHandler);
|
||||
if ((count _explosive) > 0) then {
|
||||
[_unit, -1, [_explosive select 0, _explosive select 2]] call FUNC(detonateExplosive);
|
||||
[_unit, -1, [_explosive select 0, _explosive select 2], "ACE_Cellphone"] call FUNC(detonateExplosive);
|
||||
};
|
||||
_unit setVariable [QGVAR(Dialing), false, true];
|
||||
if (_unit == ace_player) then {
|
||||
|
@ -26,7 +26,7 @@ private _range = getNumber (configFile >> "CfgWeapons" >> "ACE_DeadManSwitch" >>
|
||||
private _deadman = [_unit, "DeadManSwitch"] call FUNC(getPlacedExplosives);
|
||||
TRACE_2("placed",_deadman,_range);
|
||||
{
|
||||
[_unit, _range, _x, true] call FUNC(detonateExplosive);
|
||||
[_unit, _range, _x, "ACE_DeadManSwitch"] call FUNC(detonateExplosive);
|
||||
} forEach _deadman;
|
||||
|
||||
//Handle deadman connected to explosive in inventory
|
||||
@ -47,5 +47,5 @@ if (_connectedInventoryExplosive != "") then {
|
||||
|
||||
private _explosive = createVehicle [_ammo, (getPos _unit), [], 0, "NONE"];
|
||||
_explosive setPosASL (getPosASL _unit);
|
||||
[_unit, -1, [_explosive, 0.5]] call FUNC(detonateExplosive); //Explode, ignoring range, with a 0.5 second delay
|
||||
[_unit, -1, [_explosive, 0.5], "ACE_DeadManSwitch"] call FUNC(detonateExplosive); //Explode, ignoring range, with a 0.5 second delay
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Arguments:
|
||||
* 0: Explosives objects to detonate <OBJECT or ARRAY>
|
||||
* 1: Fuze delay (for each explosive; use negative number for random time up to value) <NUMBER> <OPTIONAL>
|
||||
* 2: Trigger Item Classname <STRING><OPTIONAL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -18,7 +19,7 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params [["_explosiveArr", [], [[], objNull]], ["_fuzeTime", 0, [0]]];
|
||||
params [["_explosiveArr", [], [[], objNull]], ["_fuzeTime", 0, [0]], ["_triggerClassname", "#scripted", [""]]];
|
||||
|
||||
if (_explosiveArr isEqualType objNull) then {
|
||||
_explosiveArr = [_explosiveArr];
|
||||
@ -26,5 +27,5 @@ if (_explosiveArr isEqualType objNull) then {
|
||||
|
||||
{
|
||||
private _detTime = if (_fuzeTime < 0) then {random abs _fuzeTime} else {_fuzeTime};
|
||||
[objNull, -1, [_x, _detTime]] call FUNC(detonateExplosive);
|
||||
[objNull, -1, [_x, _detTime], _triggerClassname] call FUNC(detonateExplosive);
|
||||
} forEach _explosiveArr;
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Arguments:
|
||||
* 0: Explosive <OBJECT>
|
||||
* 1: Time till detonate <NUMBER>
|
||||
* 2: Trigger Item Classname <STRING><OPTIONAL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -16,13 +17,13 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_explosive", "_delay"];
|
||||
TRACE_2("params",_explosive,_delay);
|
||||
params ["_explosive", "_delay", ["_triggerClassname", "#timer", [""]]];
|
||||
TRACE_3("startTimer",_explosive,_delay,_triggerClassname);
|
||||
|
||||
[{
|
||||
params ["_explosive"];
|
||||
params ["_explosive", "_triggerClassname"];
|
||||
TRACE_1("Explosive Going Boom",_explosive);
|
||||
if (!isNull _explosive) then {
|
||||
[_explosive, -1, [_explosive, 0]] call FUNC(detonateExplosive);
|
||||
[_explosive, -1, [_explosive, 0], _triggerClassname] call FUNC(detonateExplosive);
|
||||
};
|
||||
}, [_explosive], _delay] call CBA_fnc_waitAndExecute;
|
||||
}, [_explosive, _triggerClassname], _delay] call CBA_fnc_waitAndExecute;
|
||||
|
@ -170,3 +170,34 @@ Name | Use
|
||||
0 | `player` | Unit explosive will connect to
|
||||
1 | `claymore1` | Explosive object that will be connected
|
||||
2 | `"ACE_Clacker"` | Detonator type class name
|
||||
|
||||
#### 5.3 Detonation Handler.
|
||||
|
||||
Detonation Handlers are called when something attempts to trigger an explosive. They can be used to block the detonation.
|
||||
|
||||
These are only used for script based triggers like clackers, cellphone and timers (anything that uses `detonateExplosive`).
|
||||
Sensor based triggers like AT Mines, Tripwires are uneffected.
|
||||
All added handlers will be called, if ANY one returns false, the detonation will be blocked.
|
||||
|
||||
`[{CODE}] call ace_explosives_fnc_addDetonateHandler;`
|
||||
|
||||
CODE will be passed `[Unit<OBJECT>, MaxRange <NUMBER>, Explosive <OBJECT>, FuzeTime <NUMBER>, TriggerItem <STRING>]` and should return a bool: true(allowed) / false(blocked)
|
||||
|
||||
#### 5.3.1 Example
|
||||
|
||||
Jammer that blocks RF triggers:
|
||||
|
||||
```cpp
|
||||
[{
|
||||
params ["_unit", "_range", "_explosive", "_fuzeTime", "_triggerItem"];
|
||||
if (_triggerItem == "ace_cellphone") exitWith { systemChat "Blocking Cell Phone"; false }; // always block cell phones
|
||||
if (_triggerItem == "ace_m26_clacker") exitWith {
|
||||
_range = _range / 1000;
|
||||
private _actualRange = _unit distance _explosive;
|
||||
systemChat format ["Limited Range For RF Clacker [%1m / %2m]", _actualRange toFixed 1, _range toFixed 1];
|
||||
(_actualRange < _range) // return bool
|
||||
};
|
||||
// allow anything else (like timers / wired clackers)
|
||||
true
|
||||
}] call ace_explosives_fnc_addDetonateHandler;
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user