Harzach 2518 Posted March 28, 2013 (edited) Well, I've really dug myself a nice hole here. I'm very close to completing the first version of my randomized IED/ambush script system and have run up against a point of confusion. What happens so far: - ied/ambush sites are generated (_zones) - IED objects are placed (_ieds) - ambush spawn locations are generated (_spawns) Now I just need to generate triggers at each _zone, which is working fine, except for the onAct statement. The relevant code: { _trg = createTrigger ["EmptyDetector", getPos _x]; _trg setTriggerArea [15,15,0,false]; _trg setTriggerActivation ["WEST","PRESENT",false]; _trg setTriggerTimeout [1,1,1,false]; _trg setTriggerStatements ["((vehicle player) in thisList) and ((getPos (vehicle player) select 2) < 2)", "bomb = ""Sh_105_HE"" createVehicle (_ieds select _iedparam); nul = [opforALPHA, [(_spawns select _spawnparam)], [(_zones select _zoneparam)], 5, 1] execVM ""scripts\RUIS.sqf"";", ""]; _iedparam = (_iedparam +1); _spawnparam = (_spawnparam +1); _zoneparam = (_zoneparam +1); } foreach _zones; The triggers are being created and fired (hints in RUIS.sqf appear when I enter the trigger area), but the bomb effect is not executing, nor are the arrays in the script call populating correctly. Basically, the "_array select _arrayparam" thing isn't working. I have tried wrapping them in various ways, to no avail. I am assuming that I either have my syntax wrong or am simply going about this the wrong way. Thanks for any insight! Here's the full code for reference: The system makes use of Shuko's Random Position script (SHK_pos) and Igneous01's Random Unit Invasion Script (RUIS.sqf) /////////////////////////////////////// //null = [] execVM "scripts\ria.sqf";// /////////////////////////////////////// private ["_pos","_dist1","_dist2","_ambcount","_popcount","_center","_exclude1","_exclude2","_home","_zones","_checking","_name","_wplogic","_grp","_zmark","_ied","_iedradial","_iedradius","_iedX","_iedY","_iedcount","_ambradial","_ambradius","_ambX","_ambY","_spawncount","_trg","_trigcount","_zoneparam","_iedparam","_spawnparam","_ieds","_spawns","_trigs"]; _ambcount = _this select 0; //TO BE IMPLEMENTED LATER: //_ruisleader = this select 1 //_ruisspawndelay = this select 2 //_ruisspawncount = this select 3 //_ambdist = this select 4; /////////////////////////////// //cache vars and clear arrays// /////////////////////////////// _popcount = 0; _iedcount = 0; _spawncount = 0; _trigcount = 0; _zoneparam = 0; _iedparam = 0; _spawnparam = 0; _center = getMarkerPos "center"; _exclude1 = getMarkerPos "exclude_location_1"; _exclude2 = getMarkerPos "exclude_location_2"; _grp = creategroup east; _pos = []; _dist1 = []; _dist2 = []; _zones = []; _ieds = []; _spawns = []; _trigs = []; //////////////// //create zones// //////////////// while {_popcount < _ambcount} do { _name = str(_popcount) + str(random 100); _checking = false; while {!_checking} do { _pos = [_center, random 10000, random 359, false, [1, 5000]] call SHK_pos; _dist1 = (_pos distance _exclude1); _dist2 = (_pos distance _exclude2); if ((_dist1 > 1500) && (_dist2 > 700)) then {_checking = true}; }; _wplogic = str(_name) + str(random 100); "Logic" createunit [getMarkerPos "home",_grp,"_wplogic = this"]; _wplogic setPos _pos; _zones set [_popcount, _wplogic]; _popcount = (_popcount +1); sleep 0.1; }; { _name = str(_x) + str(random 100); _zmark = createMarker [_name, (getPos _x)]; _zmark setMarkerShape "ICON"; _zmark setMarkerType "DOT"; } foreach _zones; /////////////// //create IEDs// /////////////// { _iedradial = (0 + (random 359)); _iedradius = 8; _iedX = round(_iedradius * cos _iedradial); _iedY = round(_iedradius * sin _iedradial); _ied = "BAF_ied_v4" createVehicle [(getPos _x select 0) + _iedX, (getPos _x select 1) + _iedY, -0.05]; _name = str(_x) + str(random 100); _ieds set [_iedcount, _name]; _iedcount = (_iedcount +1); } foreach _zones; ///////////////// //create spawns// ///////////////// { _ambradial = (0 + (random 359)); _ambradius = 300; _ambX = round(_ambradius * cos _ambradial); _ambY = round(_ambradius * sin _ambradial); _name = str(_x) + str(random 100); "Logic" createunit [[(getPos _x select 0) + _ambX, (getPos _x select 1) + _ambY, 0],_grp,_name]; _spawns set [_spawncount, _name]; _spawncount = (_spawncount +1); } foreach _zones; /////////////////// //create triggers// /////////////////// { _trg = str(_x) + str(random 100); _trg = createTrigger ["EmptyDetector", getPos _x]; _trg setTriggerArea [15,15,0,false]; _trg setTriggerActivation ["WEST","PRESENT",false]; _trg setTriggerTimeout [1,1,1,false]; _trg setTriggerStatements ["((vehicle player) in thisList) and ((getPos (vehicle player) select 2) < 2)", "bomb = ""Sh_105_HE"" createVehicle (_ieds select _iedparam); nul = [opforALPHA, [(_spawns select _spawnparam)], [(_zones select _zoneparam)], 5, 1] execVM ""scripts\RUIS.sqf"";", ""]; _trigs set [_trigcount, _name]; _trigcount = (_trigcount +1); _iedparam = (_iedparam +1); _spawnparam = (_spawnparam +1); _zoneparam = (_zoneparam +1); } foreach _zones; Edited March 28, 2013 by Harzach Share this post Link to post Share on other sites
xxanimusxx 2 Posted March 28, 2013 Afaik you can't use local variables in triggers as they aren't existent in there (global scope, trying to use local variables in triggers while in editor will get you an error message). You could try this assumptions in converting the local variables you use in your activation field to global ones (just remove the underscore of every variable you use in there and of course in your script above). Share this post Link to post Share on other sites
Harzach 2518 Posted March 28, 2013 (edited) Just tried it and it definitely does not work. The "good" news is that it got me thinking about variables differently. Or rather, about how I've been thinking about them incorrectly here. Let me break it down. If I call the script with an _ambcount of 12, the script will generate 12 IED ambush locations. This involves generating 12 random locations, 12 gamelogics each to fill the _zones and _spawns arrays, and 12 physical IEDs to fill the _ieds array. The last step is to generate 12 triggers for each IED ambush. The problem here is in extracting the parameters from the arrays to use in the statement lines of those triggers. So now I'm trying this (trigger section only): { _iedproxy = _ieds select _iedparam; spawnproxy = _spawns select _spawnparam; zoneproxy = _zones select _zoneparam; _trg = createTrigger ["EmptyDetector", getPos _x]; _trg setTriggerArea [15,15,0,false]; _trg setTriggerActivation ["WEST","PRESENT",false]; _trg setTriggerTimeout [1,1,1,false]; _trg setTriggerStatements ["((vehicle player) in thisList) and ((getPos (vehicle player) select 2) < 2)", "bomb = ""Sh_105_HE"" createVehicle _iedproxy; nul = [opforALPHA, [spawnproxy], [zoneproxy], 5, 1] execVM ""scripts\RUIS.sqf"";", ""]; player globalChat format ["zoneproxy = %1", zoneproxy]; _iedparam = (_iedparam +1); _spawnparam = (_spawnparam +1); _zoneparam = (_zoneparam +1); sleep 1; } foreach _zones; The globalChat is returning the expected result, but I'm still not seeing any explosion effect and RUIS.sqf doesn't seem to be accepting those global variables. It basically errors out on "spawnproxy" - RUIS.sqf converts it to a local variable then does a getPos on it, where it sees it as a string, not an object. Edited March 28, 2013 by Harzach Share this post Link to post Share on other sites
xxanimusxx 2 Posted March 28, 2013 Okay the next thing is: a trigger is non-sheduled and asynchronus, which means the trigger can be used the way triggers are used: activated whenever the condition is met, it can be in some seconds or hours. So basically what your trigger does here is: "Oh, the condition is met, lets execute the code in my activation field. Oh, what's that? A global variable? No problems, just lemme grab the current value of it!". And there's your problem: Assigning the same global Variable in the parameters of your script leads to unwanted results, as in your script gets the same value every time any of these triggers are activated, namely the last element of _zones, _spawns and _ieds. Okay I edited your script from your first post: /////////////////////////////////////// //null = [] execVM "scripts\ria.sqf";// /////////////////////////////////////// private ["_pos","_dist1","_dist2","_ambcount","_popcount","_center","_exclude1","_exclude2","_home","_zones","_checking","_name","_wplogic","_grp","_zmark","_ied","_iedradial","_iedradius","_iedX","_iedY","_iedcount","_ambradial","_ambradius","_ambX","_ambY","_spawncount","_trg","_trigcount","_zoneparam","_iedparam","_spawnparam","_ieds","_spawns","_trigs"]; _ambcount = _this select 0; //TO BE IMPLEMENTED LATER: //_ruisleader = this select 1 //_ruisspawndelay = this select 2 //_ruisspawncount = this select 3 //_ambdist = this select 4; /////////////////////////////// //cache vars and clear arrays// /////////////////////////////// _popcount = 0; _iedcount = 0; _spawncount = 0; _trigcount = 0; _zoneparam = 0; _iedparam = 0; _spawnparam = 0; _activation = ""; _center = getMarkerPos "center"; _exclude1 = getMarkerPos "exclude_location_1"; _exclude2 = getMarkerPos "exclude_location_2"; _grp = creategroup east; _pos = []; _dist1 = []; _dist2 = []; zones = []; ieds = []; spawns = []; _trigs = []; //////////////// //create zones// //////////////// while {_popcount < _ambcount} do { _name = str(_popcount) + str(random 100); _checking = false; while {!_checking} do { _pos = [_center, random 10000, random 359, false, [1, 5000]] call SHK_pos; _dist1 = (_pos distance _exclude1); _dist2 = (_pos distance _exclude2); if ((_dist1 > 1500) && (_dist2 > 700)) then {_checking = true}; }; _wplogic = str(_name) + str(random 100); "Logic" createunit [getMarkerPos "home",_grp,"_wplogic = this"]; _wplogic setPos _pos; zones set [_popcount, _wplogic]; _popcount = (_popcount +1); sleep 0.1; }; { _name = str(_x) + str(random 100); _zmark = createMarker [_name, (getPos _x)]; _zmark setMarkerShape "ICON"; _zmark setMarkerType "DOT"; } foreach zones; /////////////// //create IEDs// /////////////// { _iedradial = (0 + (random 359)); _iedradius = 8; _iedX = round(_iedradius * cos _iedradial); _iedY = round(_iedradius * sin _iedradial); _ied = "BAF_ied_v4" createVehicle [(getPos _x select 0) + _iedX, (getPos _x select 1) + _iedY, -0.05]; _name = str(_x) + str(random 100); ieds set [_iedcount, _name]; _iedcount = (_iedcount +1); } foreach zones; ///////////////// //create spawns// ///////////////// { _ambradial = (0 + (random 359)); _ambradius = 300; _ambX = round(_ambradius * cos _ambradial); _ambY = round(_ambradius * sin _ambradial); _name = str(_x) + str(random 100); "Logic" createunit [[(getPos _x select 0) + _ambX, (getPos _x select 1) + _ambY, 0],_grp,_name]; spawns set [_spawncount, _name]; _spawncount = (_spawncount +1); } foreach zones; /////////////////// //create triggers// /////////////////// for "_i" from 0 to ((count zones)-1) do { _x = zones select _i; _trg = str(_x) + str(random 100); _trg = createTrigger ["EmptyDetector", getPos _x]; _trg setTriggerArea [15,15,0,false]; _trg setTriggerActivation ["WEST","PRESENT",false]; _trg setTriggerTimeout [1,1,1,false]; _activation = format["bomb = ""Sh_105_HE"" createVehicle (ieds select %1); nul = [opforALPHA, [(spawns select %1)], [(zones select %1)], 5, 1] execVM ""scripts\RUIS.sqf"";", _i]; _trg setTriggerStatements ["((vehicle player) in thisList) and ((getPos (vehicle player) select 2) < 2)", _activation, ""]; _trigs set [_trigcount, _name]; _trigcount = (_trigcount +1); _iedparam = (_iedparam +1); _spawnparam = (_spawnparam +1); _zoneparam = (_zoneparam +1); }; The first thing I noticed is: You could write all of your code into the while-loop in the top, because the forEach loops are also tied to the number of the elements in the zone-array, which is first determined in the while-loop. You could save a lot of cycles with that :) Okay, what I did here is I simply erased the underscore off of zones, ieds and spawns to make them global (global means global across scripts). Then I replaced the forEach-loop with a counting loop for the triggers. Doing this enables you to use format[] and enumarate through your arrays which are global. Again, I didn't test this so it could throw some errors :D Share this post Link to post Share on other sites
Harzach 2518 Posted March 29, 2013 Interesting! I'm really enjoying learning this stuff. And I suspected that was what was happening with the statement variables. Darn it. Using the new version, I'm getting: 'bomb = "Sh_105_HE" createVehicle (ieds select %1); nul = [op...' Error: createvehicle, Type String, expected Array I'm going to dig into it tomorrow and try to assimilate some of this information. Thanks once again, you're a real trooper! Share this post Link to post Share on other sites
xxanimusxx 2 Posted March 29, 2013 Ah yeah, the createVehicle you're using expects a position-array but you're providing a string (a random name you generated above). I think you have to change ieds set [_iedcount, _name]; into ieds set [_iedcount, _ied]; in the corresponding forEach-loop and further change bomb = ""Sh_105_HE"" createVehicle (ieds select %1); into bomb = ""Sh_105_HE"" createVehicle (getPos (ieds select %1)); Another useful fact: using createVehicle_array is up to 500x faster than using the createVehicle command :D Share this post Link to post Share on other sites
Harzach 2518 Posted March 29, 2013 Ah, that's it! Now I just need to figure out how to pass the params from zones and spawns to RUIS.sqf properly. Right now, I'm getting this error from RUIS: Error getpos: Type String, expected Object,Location I'm going to spend some time this afternoon to parse all of this so as to gain a clear(er) understanding. Thanks! Share this post Link to post Share on other sites