Booby Trap

Matt L

OpenDayZ Rockstar!
Alright so CommanderRetra and I worked on this for awhile and couldn't get it to work quite right, we had everything down except the explosion. A dude named Buttface adjusted the code to where the explosion would be handled serverside, and it worked. Big thanks to that man.

First off, you will need an overwritten fn_selfActions.sqf and compiles.sqf from dayz_code.pbo. Place these in a Fixes folder in your mission.pbo. Find the line in your compiles.sqf that calls on the fn_selfActions.sqf and change it to look like this
Code:
fnc_usec_selfActions = compile preprocessFileLineNumbers "Fixes\fn_selfActions.sqf";

then open your init.sqf and find the line that controls the compiles, and change it to
Code:
call compile preprocessFileLineNumbers "Fixes\compiles.sqf"; //Compile custom compiles

while your in your init.sqf at the bottom paste this :
Code:
if (isServer) then {
        "DZ_boobyTrap" addPublicVariableEventHandler {[_this select 1] execVM 'Scripts\createBomb.sqf'};
};
now open your selfActions.sqf and at the bottom paste :
Code:
if (("ItemEtool" in weapons player) && ("PartWoodPile" in magazines player)) then {
    hasBombItem = true;
} else {
    hasBombItem = false;
};
if ((speed player <= 1) && hasBombItem) then {
    hasBomb = true;
} else {
    hasBomb = false;
};
if ((hasBomb) && ("HandGrenade_West" in magazines player)) then {
    if (s_player_makeBomb < 0) then {
        s_player_makeBomb = player addAction [("<t color=""#c30000"">" + ("Place Exploding Booby Trap") +"</t>"),"Scripts\setBomb.sqf","",5,false,true,"",""];
    };
} else {
    player removeAction s_player_makeBomb;
    s_player_makeBomb = -1;
};

Then make a Scripts folder in your mission.pbo and create a few files to be placed in there.
continued on next post
 
  • Like
Reactions: Fox
setBomb.sqf:

Code:
private ["_mypos","_bombOwnerUID"];
player playActionNow "Medic";
 
_mypos = getPosATL player;
_bombOwnerUID =  getPlayerUID player;
 
sleep 5;
 
player removeMagazine "PartWoodPile";
player removeMagazine "HandGrenade_West";
 
DZ_boobyTrap = [_bombOwnerUID,_myPos];
publicVariableServer "DZ_boobyTrap"; //Send needed values to server.
DZ_boobyTrap = []; //Clean up global variable.
 
titleText ["You have placed a Booby Trap.","PLAIN DOWN"]; titleFadeOut 5;

createBomb.sqf:
Code:
private ["_bombOwnerUID","_bombPos","_spawnStash","_bombTrigger","_objectUID"];
if (!isServer) exitWith {}; //Make sure this script runs only on server.
 
_bombOwnerUID = (_this select 0) select 0;      //diag_log format ["Bomb owner's UID is %1",_bombOwnerUID];
_bombPos = (_this select 0) select 1;          //diag_log format ["Bomb's position is %1",_bombPos];
 
//Create the stash object
_spawnStash = createVehicle ["StashSmall", [0,0,0], [], 0, "CAN_COLLIDE"];
 
//Prevent server from deleting the object by assigning it a blank UID.
_spawnStash setVariable ["ObjectUID",""];
 
//Create the trigger object
_bombTrigger = createTrigger["EmptyDetector",[0,0,0]];
_bombTrigger setTriggerArea [5,5,0,false];
_bombTrigger setTriggerActivation ["ANY","PRESENT",true];
_bombTrigger setTriggerStatements ["{(isPlayer _x) && (_x isKindOf 'Man')} count thisList > 0;","0 = [thisTrigger,_spawnStash,thislist] execVM 'Scripts\detonateBomb.sqf'",""]; //You don't want a vehicle like a helicopter to set off the trigger.
_bombTrigger setVariable ["ownerUID",_bombOwnerUID];
 
//Set position of stash and trigger
_spawnStash setPosATL _bombPos;
_bombTrigger setPosATL _bombPos;
DZ_boobyTrap = nil;

detonateBomb.sqf:
Code:
private ["_trigger","_stashObject","_nearbyUnits","_bombOwnerUID","_nearbyPlayers","_theBomb"];
 
if (!isServer) exitWith {};
 
_trigger = _this select 0;              //The trigger object
_stashObject = _this select 1;  //The stash object
_nearbyUnits = _this select 2;  //All units in trigger area (may not be players).
 
//diag_log "Bomb is triggered.";
 
_bombOwnerUID = _trigger getVariable "ownerUID"; //Retrieve owner's UID.
 
//Borrowing some DZAI code here. This filters out non-player units from _nearbyUnits
_nearbyPlayers = [];
{
    if (isPlayer _x) then {
                _nearbyPlayers set [(count _nearbyPlayers),_x];
        };
} forEach _nearbyUnits;
 
//diag_log format ["nearbyUnits: %1, _nearbyPlayers: %2.",_nearbyUnits,_nearbyPlayers];
 
//Check if there is at least one player in trigger area that isn't the bomb owner.
if (({(getPlayerUID _x) != _bombOwnerUID} count _nearbyPlayers) > 0) then {
    //Create bomb on trigger object
    _theBomb = createVehicle ["grenade",getPosATL _trigger,[],0,"NONE"];
        //Remove trigger and stash after bomb is created and detonated.
    deleteVehicle _trigger;
    deleteVehicle _stashObject;
        //diag_log "Exploded bomb. Players in trigger area are not bomb creator.";
} else {
        //diag_log "Bomb creator present.";
};

Paste all of these new files into your Scripts folder. Now if you have an Etool, a m67 frag, and a woodpile, you can create a boobytrap!

If you have an anti hack you will need to whitelist the s_player_makeBomb action.

I should also say that this script was only successful because of Buttface. Without him, it would likely of never succeeded.

 
WOOHOO! Released!!! I shall write up a thread for an incredibly sexy debug monitor courtesy of AlienX later. Bit crook at the moment, be off to the doctors tomorrow. All credit goes to Matt with the Bomb, I had minimal input.
 
Kicks for PublicVariable Restriction #0

Is there exception I can add or do I just have to change whole line to 1 for only logging?

Also booby trap did not explode when I walked to it myself. This is normal?
 
Kicks for PublicVariable Restriction #0

Is there exception I can add or do I just have to change whole line to 1 for only logging?

Also booby trap did not explode when I walked to it myself. This is normal?

Designed not to explode for the person who places it, and I would try to add the exception for the DZ_boobyTrap cause that's the public variable.
 
If anyone wants to, you can restrict access to the bomb addaction so only bandit's can use it it would look like so :
Code:
if ((player getVariable"humanity") <= 0) then {
    if (("ItemEtool" in weapons player) && ("PartWoodPile" in _mags)) then {
        hasBombItem = true;
    } else {
        hasBombItem = false;
    };
    if ((speed player <= 1) && hasBombItem) then {
        hasBomb = true;
    } else {
        hasBomb = false;
    };
    if ((hasBomb) && ("HandGrenade_West" in _mags)) then {
        if (s_player_makeBomb < 0) then {
            s_player_makeBomb = player addAction [("<t color=""#c30000"">" + ("Place Exploding Booby Trap") +"</t>"),"Scripts\setBomb.sqf","",5,false,true,"",""];
        };
    } else {
        player removeAction s_player_makeBomb;
        s_player_makeBomb = -1;
    }; // End toggling of Matt L's Bomb
};

for only heroes to access it, just change the <= 0 to >= 5000.
 
Quick question (hopefully) How do I set the trigger to go off when any unit (zombie bandit or player) activates it?
played with:
_bombTrigger setTriggerStatements ["{(isPlayer _x) && (_x isKindOf 'Man')} count thisList > 0;","0 = [thisTrigger,_spawnStash,thislist] execVM 'Scripts\detonateBomb.sqf'",""];

in createBomb.sqf but not getting it.

Any help available?
 
Quick question (hopefully) How do I set the trigger to go off when any unit (zombie bandit or player) activates it?
played with:
_bombTrigger setTriggerStatements ["{(isPlayer _x) && (_x isKindOf 'Man')} count thisList > 0;","0 = [thisTrigger,_spawnStash,thislist] execVM 'Scripts\detonateBomb.sqf'",""];

in createBomb.sqf but not getting it.

Any help available?
Try this
Code:
_bombTrigger setTriggerStatements ["{(_x isKindOf 'Man')} count thisList > 0;","0 = [thisTrigger,_spawnStash,thislist] execVM 'Scripts\detonateBomb.sqf'",""];
 
That helped, not getting RPT errors, but still no earth shattering kaboom (M4 modulator?)

I think it may be in the detonation script here:

Code:
[code]/Borrowing some DZAI code here. This filters out non-player units from _nearbyUnits
_nearbyPlayers = [];
{
    if (isPlayer _x) then {
                _nearbyPlayers set [(count _nearbyPlayers),_x];
        };
} forEach _nearbyUnits;

//diag_log format ["nearbyUnits: %1, _nearbyPlayers: %2.",_nearbyUnits,_nearbyPlayers];

//Check if there is at least one player in trigger area that isn't the bomb owner.
if (({(getPlayerUID _x) != _bombOwnerUID} count _nearbyPlayers) > 0) then {
    //Create bomb on trigger object
[/code]

once again played with it but not too sharp on this language.
As a side note, once I (we?) get this working, will be adding flare effects for trip flares variant :)

Any help appreciated.
 
Last edited:
We do not need to filter the unit again as it was done in our trigger statement. Also at the top of the script you will notice
Code:
_nearbyUnits = _this select 2;
This variable is returning the number of units in the trigger.
The stuff borrowed from DZAI is not necessary anymore because we don't care if the unit is not a player.
Therefore we just need to change the variable '_nearbyPlayers' in the bottom if statement to '_nearbyUnits'.

detonateBomb.sqf
Code:
private ["_trigger","_stashObject","_nearbyUnits","_bombOwnerUID","_nearbyPlayers","_theBomb"];

if (!isServer) exitWith {};

_trigger = _this select 0;              //The trigger object
_stashObject = _this select 1;  //The stash object
_nearbyUnits = _this select 2;  //All units in trigger area (may not be players).

//diag_log "Bomb is triggered.";

_bombOwnerUID = _trigger getVariable "ownerUID"; //Retrieve owner's UID.
//Check if there is at least one unit in trigger area that isn't the bomb owner.
if (({(getPlayerUID _x) != _bombOwnerUID} count _nearbyUnits) > 0) then {
    //Create bomb on trigger object
    _theBomb = createVehicle ["grenade",getPosATL _trigger,[],0,"NONE"];
        //Remove trigger and stash after bomb is created and detonated.
    deleteVehicle _trigger;
    deleteVehicle _stashObject;
        //diag_log "Exploded bomb. Players in trigger area are not bomb creator.";
} else {
        //diag_log "Bomb creator present.";
};
 
Works like a treat with one caveat - explodes on placement :)
Now, that brings up a great feature, Id like players to be susceptible to their own booby traps.
Is there a way to put on a 30 second cooldown on trigger to give trapper time to get away.
Ive tried a few things but the syntax is killing me. something along the lines of Sleep30 command in createBomb.sqf.

will mess around some more


Thanks again for your time, any other insights welcome

EDIT: Added "Sleep 15;" before trigger creation in createBomb.sqf (along with updated warning text) works like a charm. Trap layer can set off own trap.

One thing is weird - Zombies will not cross into trigger area, as if an invisible fence, Will change CAN_COLLIDE switch on placeholder item and see. anyone have any ideas?
 
Last edited:
One thing is weird - Zombies will not cross into trigger area, as if an invisible fence, Will change CAN_COLLIDE switch on placeholder item and see. anyone have any ideas?
Hmmm... not sure about that. Sorry. But the object is already has the 'CAN_COLLIDE' properties so this shouldn't be a problem. I presume it would be something related to the unspeakable AI paths.

Added "Sleep 15;" before trigger creation in createBomb.sqf (along with updated warning text) works like a charm. Trap layer can set off own trap.
I have made some enhancements with the delay, makes it a bit more player friendly. I'm going to assume that your detonateBomb.sqf looks something like this...
Code:
private ["_trigger","_stashObject","_nearbyUnits","_theBomb"];

if (!isServer) exitWith {};

_trigger = _this select 0;      //The trigger object
_stashObject = _this select 1;  //The stash object
_nearbyUnits = _this select 2;  //All units in trigger area (may not be players).

//Check if there is at least one unit in trigger area
if ((count _nearbyUnits) > 0) then {
    //Create bomb on trigger object
    _theBomb = createVehicle ["grenade",getPosATL _trigger,[],0,"NONE"];
        //Remove trigger and stash after bomb is created and detonated.
    deleteVehicle _trigger;
    deleteVehicle _stashObject;
};

As for createBomb.sqf I have added a cutText so it will delay the creation of the trigger therefore making it safe to walk around the bomb site for the amount of time defined in the '_setTime' variable. The cutText will also display the countdown in seconds to activation.
Code:
private ["_bombPos","_spawnStash","_bombTrigger","_objectUID","_time","_setTime"];
if (!isServer) exitWith {}; //Make sure this script runs only on server.

_bombPos = (_this select 0) select 1;
_setTime = 30;//Time in seconds
_time = _setTime;
//Create the stash object
_spawnStash = createVehicle ["StashSmall", [0,0,0], [], 0, "CAN_COLLIDE"];

//Prevent server from deleting the object by assigning it a blank UID.
_spawnStash setVariable ["ObjectUID",""];
for "_i" from 0 to _setTime do {
    sleep 1;
    _time = _time - 1;
    if (_time > 0) then {
        cutText [format["You have placed a Booby Trap. %1 seconds before activation.",_time], "PLAIN DOWN"];
    };
};
//Create the trigger object
_bombTrigger = createTrigger["EmptyDetector",[0,0,0]];
_bombTrigger setTriggerArea [5,5,0,false];
_bombTrigger setTriggerActivation ["ANY","PRESENT",true];
_bombTrigger setTriggerStatements ["(_x isKindOf 'Man') count thisList > 0;","0 = [thisTrigger,_spawnStash,thislist] execVM 'Scripts\detonateBomb.sqf'",""];


//Set position of stash and trigger
_spawnStash setPosATL _bombPos;
_bombTrigger setPosATL _bombPos;
DZ_boobyTrap = nil;
In the setBomb.sqf I just cleaned up the unused variables.
Code:
private ["_mypos"];
player playActionNow "Medic";

_mypos = getPosATL player;

sleep 5;

player removeMagazine "PartWoodPile";
player removeMagazine "HandGrenade_West";

DZ_boobyTrap = [_myPos];
publicVariableServer "DZ_boobyTrap"; //Send needed values to server.
DZ_boobyTrap = []; //Clean up global variable.
 
Last edited:
I like the countdown, better than my solution of creating the stash object (which I changed to the belt buckle) appear same time as the trigger (if you see it its live).
Ive moved it over to the right click system on grenades to set trap, and have copied and renamed the sqf files to use on flares (tripflares). Havent had time to test it yet but should only need to change public variable DZ_boobyTrap to something like DZ_tripflare, edit init.sqf lead to new sqf when called, and change create vehicle grenade to create vehicle (flareeffectclassname).

If this belongs in a new thread let me know.
 
Back
Top