Jump to content

Recommended Posts

Hey! 

 

I've been trying to make a IED script that uses a triggerman instead of the commonly found pressure plate. So far it's early in "development" but eventually I'm aiming for it to become dynamic and able to spawn random death traps all over the chosen map. 

The problem I've encountered and need help with is that my local variable doesn't work in a trigger. 

//	Pick a spawnpoint
_spawnPoint = selectRandom [
	"spawn_garage", 
	"spawn_hotel",
	"spawn_hotel_2", 
	"spawn_shop", 
	"spawn_office", 
	"spawn_binocular", 
	"spawn_suicide", 
	"spawn_minaret",
	"spawn_wall"
]; 

//	Spawn IED man
_bomberGroup = createGroup [East, True]; 
_bomber = _bomberGroup createUnit ["LOP_AM_OPF_Infantry_Engineer", getMarkerPos _spawnPoint, [], 0, "CAN_COLLIDE"]; 
_bomberGroup setBehaviour "careless"; 
//removeAllWeapons _bomber;
_bomber setCaptive true; 
_bomber disableAI "MOVE"; 
_bomber setUnitPos "UP";
_bomber_weapon = currentWeapon _bomber;
 
//	Custom scripts depending on which spawnpoint is chosen
switch (_spawnPoint) do { 
	case "spawn_garage": {
	hint "GARAGE"; 
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.040]; 
	}; 
	case "spawn_hotel": {
	hint "HOTEL";
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 3.798]; 
	}; 
	case "spawn_shop": {
	hint "SHOP";
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.292];
	}; 
	case "spawn_office": {
	hint "OFFICE";
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 5.787];
	}; 
	case "spawn_binocular": {
	hint "BINOCULAR";
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 3.403];
	}; 
	case "spawn_suicide": {
	hint "SUICIDE";
	}; 
	case "spawn_minaret": {
	hint "MINARET";
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 19.424]; 
	}; 
	case "spawn_hotel_2": {
	hint "HOTEL_2";
	}; 
	case "spawn_wall": {
	hint "WALL";
	}; 
	default {
	hint "ERROR! No spawnpoint chosen";
	};
};

//	Make bomber face IED
_dir = _bomber getDir IED_L;
_bomber setDir _dir;
_bomber setFormDir _dir;

//	Spawn weapon next to bomber
//_wh = "WeaponHolderSimulated" createVehicle position _bomber;
//_wh addWeaponCargoGlobal ["rhs_weap_akm",1];
//_wh addMagazineCargoGlobal ["rhs_30Rnd_762x39mm",1];
//_wh setPos (getpos _bomber);
_wh = "GroundWeaponHolder_Scripted" createVehicle position _bomber;
_wh setPosAtl (getPosATL _bomber); 
_bomber action ["DropWeapon", _wh, _bomber_weapon];

//	Create a trigger on triggermans position to make him combat any player that gets close
//	###THIS IS WHERE IT GETS FUCKY###
_trgr_bomber_1 = createTrigger ["EmptyDetector", getPos _bomber, true];
_trgr_bomber_1 setTriggerArea [10, 10, 0, false];
_trgr_bomber_1 setTriggerActivation ["ANYPLAYER", "PRESENT", false];
_trgr_bomber_1 setTriggerStatements ["this", "hint 'trigger start'; _bomber selectWeapon '_bomber_weapon'; _bomber enableAI 'MOVE'; _bomber setUnitPos 'AUTO'; _bomberGroup setbehaviour 'COMBAT'; _bomber setCaptive false;", "hint 'trigger end'"];

//	Testing to see if set to careless because he kept on throwing grenades
//	Somehow AI still do that in careless I guess? 
sleep 5;
_b = behaviour _bomber; 
hint format ["%1", _b];

/*
ACE Detonation
Needs to be fixed
No clue how to use this at all

//	Connect explosives to bomber
[_bomber, IED_L, "Cellphone"] call ace_explosives_fnc_connectExplosive;

sleep 30; 

//	Boom?
[{
    ["_bomber", "3000", "IED_L", "0", "Cellphone"]; 
	true
}] call ace_explosives_fnc_addDetonateHandler;

*/

Basically, if you can understand my mess, I have two issues

 

1: the "_trgr_bomber_1" doesn't know what "_bomber" is so it can't make him pickup a gun and activate standard AI combat. 

2: AI still throw grenades at me like 17th century grenadiers even though they're set to "CARELESS". 

 

Any help would be greatly appreciated and I'm pretty sure it's an easy fix for anyone who's actually a coder. 

Share this post


Link to post
Share on other sites
Hey! 
 
I've been trying to make a IED script that uses a triggerman instead of the commonly found pressure plate. So far it's early in "development" but eventually I'm aiming for it to become dynamic and able to spawn random death traps all over the chosen map. 
The problem I've encountered and need help with is that my local variable doesn't work in a trigger. 
Basically, if you can understand my mess, I have two issues
 
1: the "_trgr_bomber_1" doesn't know what "_bomber" is so it can't make him pickup a gun and activate standard AI combat. 
2: AI still throw grenades at me like 17th century grenadiers even though they're set to "CARELESS". 
 
Any help would be greatly appreciated and I'm pretty sure it's an easy fix for anyone who's actually a coder. 


Hi...

I’m no expert but I’ve written a few complex scripts - and I’ve seen the issue where private variables are not recognized in specific instances - where I would think they should - is there a reason you can’t switch to “global” variables by removing the underscore prefix ? That worked to fix my specific issues...

Regards,
Scott



Sent from my iPad using Tapatalk
  • Thanks 1

Share this post


Link to post
Share on other sites
6 minutes ago, scottb613 said:

 


Hi...

I’m no expert but I’ve written a few complex scripts - and I’ve seen the issue where private variables are not recognized in specific instances - where I would think they should - is there a reason you can’t switch to “global” variables by removing the underscore prefix ? That worked to fix my specific issues...

Regards,
Scott



Sent from my iPad using Tapatalk

 

Hey Scott!

Thanks for your reply. :)

 

In this specific scenario I probably could but later on when I'd run the script more than once I'm not sure if it'd break something. IE: make two bombers connect to the same trigger etc. 

Share this post


Link to post
Share on other sites

When you create the trigger store the bomber on it (using setVariable), and I recommend you move your activation code to a separate script:

_trgr_bomber_1 setVariable ["Spatsiba_TriggerMan", _bomber, true];
_trgr_bomber_1 setTriggerStatements ["this", "[thisTrigger] execVM 'activateTriggerman.sqf';", ""];

Then you move the activation code to that script instead, and here you can the associated triggerman from the trigger.
 

// This is activateTriggerMan.sqf
params ["_trigger"];
private _bomber = _trigger getVariable "Spatsiba_TriggerMan";
if (not alive _bomber) exitWith {};
private _bomberGroup = group _bomber;

hint 'trigger start';
_bomber selectWeapon '_bomber_weapon';
_bomber enableAI 'MOVE';
_bomber setUnitPos 'AUTO';
_bomberGroup setbehaviour 'COMBAT';
_bomber setCaptive false;

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
1 hour ago, Muzzleflash said:

When you create the trigger store the bomber on it (using setVariable), and I recommend you move your activation code to a separate script:


_trgr_bomber_1 setVariable ["Spatsiba_TriggerMan", _bomber, true];
_trgr_bomber_1 setTriggerStatements ["this", "[thisTrigger] execVM 'activateTriggerman.sqf';", ""];

Then you move the activation code to that script instead, and here you can the associated triggerman from the trigger.
 


// This is activateTriggerMan.sqf
params ["_trigger"];
private _bomber = _trigger getVariable "Spatsiba_TriggerMan";
if (not alive _bomber) exitWith {};
private _bomberGroup = group _bomber;

hint 'trigger start';
_bomber selectWeapon '_bomber_weapon';
_bomber enableAI 'MOVE';
_bomber setUnitPos 'AUTO';
_bomberGroup setbehaviour 'COMBAT';
_bomber setCaptive false;

 

I was actually playing around with that but didn't get it to work. I made a fnc inside the same script and called it in the trigger. I'll try your version and see if it works but just looking at the code it seems like a fix. Thank you! Will come back with results :) 

 

EDIT: Ok, it worked. Only problem now is the AI won't pickup the gun at his feet. Going to have to find a way to do that and learn how to use ACE3 explosives with AI now. 

 

EDIT EDIT: The only problem now is triggering the explosive with ACE3. If anyone wants the finished code I can post it here on demand. I don't want to bump the thread for no reason. Thanks for the help scott and muzzle for the solution :)

  • Like 1

Share this post


Link to post
Share on other sites
2 hours ago, HazJ said:

You can also wrap your code inside spawn block.


0 = thisList spawn
{
	// code...
};

https://community.bistudio.com/wiki/spawn

How do you mean? 

 

Is there anyone who can explain switch case variables? I'm trying to do this: 


//	Custom scripts depending on which spawnpoint is chosen
switch (_spawnPointBomber) do { 
	case "spawn_garage": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.040]; 
	}; 
	case "spawn_hotel": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 3.798]; 
	}; 
	case "spawn_shop": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.292];
	}; 
	case "spawn_office": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 5.787];
	}; 
	case "spawn_binocular": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 3.403];
	}; 
	case "spawn_suicide": {
	}; 
	case "spawn_minaret": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 17.424]; 
	}; 
	case "spawn_hotel_2": {
	private _bomberX = 12; 
	private _bomberY = 20;
	private _bomberC = true; 
	}; 
	case "spawn_wall": {
	}; 
	case "spawn_hotel_3": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.087]; 
	}; 
	default {
	hint "ERROR! No spawnpoint chosen";
	};
};

_trgr_bomber setTriggerArea [_bomberX, _bomberY, _bomberC];

and keep getting error undefined variable in expression _bomberX, _bomberY, and _bomberC

 

I get that it has to do with the scope but I don't fully understand these things even though I've searched and read about it. 

Share this post


Link to post
Share on other sites
//script scope
private _ass = 1;
if (_ass > 0) then
{
//scope 1
private _ass2 = _ass +1;
};
//script scope
_ass3 = _ass2+_ass; // error _ass2 is private to scope 1 and stays undefined for script scope
	case "spawn_hotel_2": {
	//scope "case spawn_hotel_2"
	private _bomberX = 12; 
	private _bomberY = 20;
	private _bomberC = true; 
	 isNil "_bomberX"  // false
 	isNil "_bomberY" // false
	 isNil "_bomberC" // false
	}; 

 isNil "_bomberX"  // true
 isNil "_bomberY" // true
 isNil "_bomberC" // true
	private _bomberX = 0; 
	private_bomberY = 0;
	private _bomberC = false; 

switch (_spawnPointBomber) do { 
case "spawn_hotel_2": {
	_bomberX = 12;  
	_bomberY = 20;
	_bomberC = true; 
	}; 
};

	(_bomberX == 12) // true
	(_bomberY == 20) //true
	(_bomberC )// true 

 

Share this post


Link to post
Share on other sites

Couple of things...

@Spatsiba

0 = thisList spawn
{
	_name = name player;
	hintSilent format ["Your name is: %1", _name];
};

@davidoss

(_bomberX == 12)
(_bomberY == 20)
(_bomberC)

I believe the last will overwrite the others. Simply do this to resolve:

[_bomberX, _bomberY, _bomberC]

In the file that you call the function:

_result = [arguments] call TAG_fnc_functionName;
if ((_result select 0) isEqualTo 12) then {}; // 0 would be bomberX and so on, so fourth
// You can do the check in the function itself if you really want but you sort of limit it to return a BOOLEAN - All comes down to you and what you really are going to use it for

 

Share this post


Link to post
Share on other sites
4 minutes ago, HazJ said:

(_bomberX == 12)
(_bomberY == 20)
(_bomberC)

I believe the last will overwrite the others. Simply do this to resolve:

 

If you cant recognize 2 equal signs i will change this to:

(_bomberX isEqualTo 12)
(_bomberY isEqualTo 20)
(_bomberC)

What it will replace now?

Share this post


Link to post
Share on other sites

@davidoss

Huh??? That won't do anything on it's own like that. My point was related to the function returned result when using call command.

_return

I thought you were returning multiple things one after the other, as least it looked like that. You can do this but in an array.

https://community.bistudio.com/wiki/isEqualTo

Quote

Some differences between isEqualTo and ==:

It performs case sensitive comparison on Strings

It doesn't throw error when comparing different types, i.e. ("eleven" isEqualTo 11)

It can compare Arrays, Scripts and Booleans (alive player isEqualTo true)

It can compare non-existent game objects (grpNull isEqualTo grpNull)

It can compare Namespaces (As of Arma 3 v1.47)

It is slightly faster than ==, especially when comparing Strings

 

Share this post


Link to post
Share on other sites

Sorry im just tried to answer to

"Is there anyone who can explain switch case variables? I'm trying to do this"

and

"and keep getting error undefined variable in expression _bomberX, _bomberY, and _bomberC

I get that it has to do with the scope but I don't fully understand these things even though I've searched and read about it. "

its not a straight solution for his problem

 

Share this post


Link to post
Share on other sites

@Spatsiba

@davidoss

Ah. I think I misunderstood. Just looked again. Those variables will be undefined out of the scope. Just define them before.

private _bomberX = 12;
private _bomberY = 20;
private _bomberC = true;

Do this above switch block. You don't use them anywhere else anyway. None of the switch blocks change them. Where is _trgr_bomber defined?

Share this post


Link to post
Share on other sites
29 minutes ago, HazJ said:

@Spatsiba

@davidoss

Ah. I think I misunderstood. Just looked again. Those variables will be undefined out of the scope. Just define them before.


private _bomberX = 12;
private _bomberY = 20;
private _bomberC = true;

Do this above switch block. You don't use them anywhere else anyway. None of the switch blocks change them. Where is _trgr_bomber defined?

Spoiler



//	Pick a spawnpoint for triggerman
_spawnPointBomber = selectRandom [
	"spawn_garage", 
	"spawn_hotel",
	"spawn_hotel_2", 
	"spawn_shop", 
	"spawn_office", 
	"spawn_binocular", 
	"spawn_suicide", 
	"spawn_minaret",
	"spawn_wall"
]; 

_spawnPointBomber = "spawn_hotel_2";
//	Pick tyoe of IED
_IEDType = selectRandom [
//	"IEDLandBig_F",
//	"IEDLandSmall_F",
	"IEDUrbanBig_F",
	"IEDUrbanSmall_F"
];

//	Spawn IED
_IED = createVehicle [_IEDType, getMarkerPos "spawn_ied_1", ["spawn_ied_2","spawn_ied_3","spawn_ied_4"], 0, "NONE"];

//	Spawn IED man
_bomberGroup = createGroup [East, True]; 
_bomber = _bomberGroup createUnit ["LOP_AM_OPF_Infantry_Engineer", getMarkerPos _spawnPointBomber, [], 0, "CAN_COLLIDE"]; 
_bomberGroup setBehaviour "careless"; 
//removeAllWeapons _bomber;
_bomber setCaptive true; 
_bomber disableAI "MOVE"; 
_bomber setUnitPos "UP";
_bomber_weapon = currentWeapon _bomber;
 
//	Custom scripts depending on which spawnpoint is chosen
switch (_spawnPointBomber) do { 
	case "spawn_garage": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.040]; 
	}; 
	case "spawn_hotel": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 3.798]; 
	}; 
	case "spawn_shop": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.292];
	}; 
	case "spawn_office": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 5.787];
	}; 
	case "spawn_binocular": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 3.403];
	}; 
	case "spawn_suicide": {
	}; 
	case "spawn_minaret": {
	private _bomberX = 14; 
	private _bomberY = 5;
	private _bomberC = false; 
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 17.424]; 
	}; 
	case "spawn_hotel_2": {
	private _bomberX = 20; 
	private _bomberY = 12;
	private _bomberC = true; 
	}; 
	case "spawn_wall": {
	}; 
	case "spawn_hotel_3": {
	_bomber setPos [getPos _bomber select 0, getPos _bomber select 1, 4.087]; 
	}; 
	default {
	hint "ERROR! No spawnpoint chosen";
	};
};

if (isServer) then {
	hint format ["%1", _spawnPointBomber]; 
};

//	Make bomber face IED
_dir = _bomber getDir _IED;
_bomber setDir _dir;
_bomber setFormDir _dir;

//	Spawn weapon next to bomber
//_wh = "WeaponHolderSimulated" createVehicle position _bomber;
//_wh addWeaponCargoGlobal ["rhs_weap_akm",1];
//_wh addMagazineCargoGlobal ["rhs_30Rnd_762x39mm",1];
//_wh setPos (getpos _bomber);
_wh = "GroundWeaponHolder_Scripted" createVehicle position _bomber;
_wh setPosAtl (getPosAtl _bomber); 
_bomber action ["DropWeapon", _wh, _bomber_weapon];
_bomber removeWeapon "throw";

//	Create a trigger on triggermans position to make him combat any player that gets close
_trgr_bomber = createTrigger ["EmptyDetector", getPos _bomber, true];
//	_bomberX = x distance, _bomberY = y distance, _bomberC = circle (true)/square (false)
_trgr_bomber setTriggerArea [_bomberX, _bomberY, _bomberC];
_trgr_bomber setTriggerActivation ["ANYPLAYER", "PRESENT", false];
_trgr_bomber setVariable ["Spatsiba_Bomber", _bomber, true];
_trgr_bomber setVariable ["Spatsiba_wh", _wh, true];
_trgr_bomber setVariable ["Spatsiba_bomberWeap", _bomber_weapon, true];
_trgr_bomber setTriggerStatements ["this", "[thisTrigger] execVM 'scripts\IED\activateBomber.sqf';", ""];

//	Create a trigger on IED's position to make it blow if triggerman *wants to*
_trgr_IED = createTrigger ["EmptyDetector", getPos _IED, true];
_trgr_IED setTriggerArea [10, 10, 0, false];
_trgr_IED setTriggerActivation ["ANYPLAYER", "PRESENT", false];
_trgr_IED setTriggerStatements ["this", "[] execVM 'scripts\IED\activateIED.sqf';", ""];

sleep 15; 
[_IED, -1, "cellphone"] call ace_explosives_fnc_scriptedExplosive;

/*
//	Testing to see if set to careless because he kept on throwing grenades
//	Somehow AI still do that in careless I guess? 
sleep 5;
_b = behaviour _bomber; 
hint format ["%1", _b];
*/

/*
ACE Detonation
Needs to be fixed
No clue how to use this at all

//	Connect explosives to bomber
[_bomber, IED_L, "Cellphone"] call ace_explosives_fnc_connectExplosive;

sleep 30; 

//	Boom?
[{
    ["_bomber", "3000", "IED_L", "0", "Cellphone"]; 
	true
}] call ace_explosives_fnc_addDetonateHandler;

*/


 

This is all the code minus the activateBomber. I want the trigger to be different sizes depending on which spot the bomber spawns at. 

 

EDIT: That last trigger and ace stuff is very WIP as I don't fully understand the ace functions neither. 

Share this post


Link to post
Share on other sites

@Spatsiba

Define default before switch block as I said above.

// defaults
private _bomberX = 0;
private _bomberY = 0;
private _bomberC = false;

... switch block ...
// override values in case

You don't really need a whole switch block for this if you are defining the same kinda stuff over and over. What you can also do is something like:

_spawnPointData = selectRandom
[
	["spawn_garage", 0, 0, false, 0],
	["spawn_hotel_2", 20, 12, true, 4.040]
];

hintSilent format ["Bomber spawn point: %1", (_spawnPointData select 0)];
_bomberX = _spawnPointData select 1;
_bomberY = _spawnPointData select 2;
_bomberC = _spawnPointData select 3;
_bomber setPos [(getPos _bomber select 0), (getPos _bomber select 1), (_spawnPointData select 4)];

Hopefully you get the idea. Not tested. More than enough to get you started.

  • Thanks 1

Share this post


Link to post
Share on other sites

@HazJ

 

Ok, thank you! I'm not a coder I just taught myself how to do the basics in ArmA. The more advanced stuff is completely new to me. This is kind of a small project I made to learn the slightly less basic basics. 

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×