ElectroEsper 14 Posted May 17, 2015 (edited) Hi, So here is my problem. I'm trying to make a script that will simulate a mortar attack into a certain zone (that much actually work), and to do that will create an explosion at a random distance from a randomly selected player. Now the problem is that I can't seem to find a way to reliably make it happen. if (isServer) then { _mortartype = "Sh_82mm_AMOS"; _time = _this select 0; _mortarcrew = _this select 1; _mortarpit = _this select 2; _mortarzone = _this select 3; //List of targets //Run in loop until crew is dead. while {alive _mortarcrew} do { //Select a random target _target = [{_x in list _mortarzone} count playableUnits]; _unit = _target select floor random count _target; //If the target is inside the "range" of the mortar and further away or equal to 20 meters, mortar "shoots". if (_unit in list _mortarzone && (_unit distance _mortarcrew) >= 20) then { //Find the unit's location _mortarLoc = (getPos _unit); _mortarLocX = ((getPos _unit) select 0); _mortarLocY = ((getPos _unit) select 1); _mortarLocZ = ((getPos _unit) select 2); _mortar = _mortartype createVehicle [_mortarLocX + random 150 - random 150, _mortarLocY + random 150 - random 150, _mortarLocZ + 30]; _mortar setVelocity [0,0,-10]; //If the mortar shell is under 75 meters of the mortar, it is deleted to protect the mortar crew from FF. if ((_mortar distance _mortarcrew) <= 75) then { deleteVehicle _mortar; }; sleep 1; sleep _time + random _time - random _time; }else { sleep 0.01; }; }; }; Now the part that causes the problem is this one: _target = [{_x in list _mortarzone} count playableUnits]; _unit = _target select floor random count _target; I also tried using this without better results... _target = []; { if ((isPlayer _x) && (_x in list _mortarzone) then { _target pushBack _x; } } foreach playableUnits; _unit = _target select floor random count _target Let me explain what I'm trying to do. Simply said: -I want to randomly select a player (that will then be _unit) -But I want the script to only use players that are in the radius of a certain trigger (_mortarzone) for the randomization. -Since its in a loop, the player selection will "refresh" then redo the "lottery" draw. Now I went around and searched many thread on many forums and so far none have solved my issue. I hope you can help me! Have a good day. Edited May 17, 2015 by ElectroEsper Share this post Link to post Share on other sites
jshock 513 Posted May 17, 2015 Your second try is much closer but try replacing the "in list" with the following: https://community.bistudio.com/wiki/BIS_fnc_inTrigger Share this post Link to post Share on other sites
mad_cheese 593 Posted May 17, 2015 _target = [{_x in list _mortarzone} count playableUnits]; _unit = _target select floor random count _target; If you use count this way, you end up with _target being an array containing the number/amount of playableUnits that would be in _mortarZone. something like [2] for example, which causes the rest of your script to fall apart. For your second try, I also recall some issue I had with the list command - in my case it was related to my onactivation/triggeractivation settings. JShock's advice is going to cure this, but if the area you're checking can be a circle... Why not use a marker (i.e. named "MortarCenter") instead of a trigger? A trigger will also have it's condition checked once per frame which I don't think is necessary in your case. _targets = []; _mortarCenter = getmarkerpos "MortarCenter"; { if (isPlayer _x) then { if (_x distance _mortarCenter > 20) then { if (_x distance _mortarCenter < 500) then { //replace 500 by whatever maxRange you like _targets pushBack _x; }; }; }; } foreach playableUnits; _unit = _targets select (floor random count _targets); I may be coming across as a smartass when recommending performance saving and lazy eval but is still a good habit I guess. Share this post Link to post Share on other sites
ElectroEsper 14 Posted May 17, 2015 (edited) Ok, I made changes base on your answers and ended up with this. 15:24:57 Error in expression <t (floor random count _targets); if (_unit in list _mortarzone && (_unit dist> 15:24:57 Error position: <_unit in list _mortarzone && (_unit dist> 15:24:57 Error Undefined variable in expression: _unit 15:24:57 File C:\Users\William\Documents\Arma 3 - Other Profiles\Esper%20[AM%201]\missions\co45_rock_n_arrow_500.pja305\scripts\mortar_upgraded.sqf, line 39 Updated code: if (isServer) then { _mortartype = "Sh_82mm_AMOS"; _time = _this select 0; _mortarcrew = _this select 1; _mortarpit = _this select 2; _mortarCenter = _this select 3; //List of targets //Run in loop until crew is dead or no player in range. while {alive _mortarcrew} do { //Select a random target _targets = []; _mortarPos = getmarkerpos _mortarCenter; { if (isPlayer _x) then { if (_x distance _mortarPos > 20) then { if (_x distance _mortarPos < 750) then { //replace 750 by whatever maxRange you like _targets pushBack _x; }; }; }; } foreach playableUnits; _unit = _targets select (floor random count _targets); if (_unit in list _mortarzone && (_unit distance _mortarcrew) >= 20) then { //<------ Line 39 //Find the unit's location _mortarLoc = (getPos _unit); _mortarLocX = ((getPos _unit) select 0); _mortarLocY = ((getPos _unit) select 1); _mortarLocZ = ((getPos _unit) select 2); _mortar = _mortartype createVehicle [_mortarLocX + random 150 - random 150, _mortarLocY + random 150 - random 150, _mortarLocZ + 30]; _mortar setVelocity [0,0,-10]; if ((_mortar distance _mortarcrew) <= 75) then { deleteVehicle _mortar; }; sleep 1; sleep _time + random _time - random _time; }else { sleep 1; }; }; }; I'm kind-of at the same state I was. Any clue on why it does that? Edit: Did some progress, was not testing in a MP environment so the game disliked it much. Now I'm on for more debuging, will ask if more help is needed. Thanks people :) Edited May 17, 2015 by ElectroEsper Share this post Link to post Share on other sites
ElectroEsper 14 Posted May 17, 2015 (edited) Ok, now I made the whole script work properly, however there is a small problem with it. Because of its nature the script run non-stop, creating monstruous RPT in a few seconds. So I would like to use WaitUntil the very line following while {alive _mortarcrew} do and make it "stop waiting" when x number of player enter the mortar range. Now here I'm kind-of at a lost as to what to do. I tried this: waitUntil { {(isPlayer _x) && (_x in list _mortarRange)} count playableUnits >0 }; Do not work... Hope you can help me again! Thanks in advance. Edit: Figured it out, had to write it this way... waitUntil ({ {(isPlayer _x) && (_x in list _mortarRange)} count playableUnits >0 }); Edited May 18, 2015 by ElectroEsper Share this post Link to post Share on other sites