Spatsiba 89 Posted August 17, 2018 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
scottb613 263 Posted August 17, 2018 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,ScottSent from my iPad using Tapatalk 1 Share this post Link to post Share on other sites
Spatsiba 89 Posted August 17, 2018 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
Muzzleflash 111 Posted August 17, 2018 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; 1 1 Share this post Link to post Share on other sites
Spatsiba 89 Posted August 17, 2018 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 :) 1 Share this post Link to post Share on other sites
HazJ 1289 Posted August 17, 2018 You can also wrap your code inside spawn block. 0 = thisList spawn { // code... }; https://community.bistudio.com/wiki/spawn Share this post Link to post Share on other sites
Spatsiba 89 Posted August 17, 2018 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
davidoss 552 Posted August 17, 2018 //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
HazJ 1289 Posted August 17, 2018 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
davidoss 552 Posted August 17, 2018 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
HazJ 1289 Posted August 17, 2018 @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
davidoss 552 Posted August 17, 2018 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
HazJ 1289 Posted August 17, 2018 @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
Spatsiba 89 Posted August 17, 2018 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
HazJ 1289 Posted August 17, 2018 @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. 1 Share this post Link to post Share on other sites
Spatsiba 89 Posted August 17, 2018 @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