Blanco 0 Posted December 26, 2006 Hi, I always wanted a searchglight in OFP and I'm pleased we got a full working example in Arma. Thx BIS. I've wrote a simple watchscript for the searchlight. - slow moving to make it realistic. clockwise & counterclockwise - random bearing - random pitch (min 2m, max 45m above sealevel, we don't want him to spot planes) - Searchlight stays on when the "gunner" got killed, but turns out when the lens got shot. Here it is : Quote[/b] ];watch script for searchlights 0.2 ;written by Blanco _unit = _this select 0 _dis = 200 #loop ?!alive _unit : exit _dir = random 360 _steps = random 350 + 10 _steps = _steps - _steps %1 ;hint format ["Dir is %1 in %2 steps",_dir,_steps] ~2 ;hint "Heading for a new direction" _x = 0 _i = -1 _maxheight = 45 _minheight = 2 _inc = -0.2 _height = (2 + random 43) ;hint format ["height = %1",_height] ~1 ?random 2 < 1 : _i = 1 ?random 2 < 1 : _inc = 0.2 #steps ?!alive gunner _unit : goto "unitdied" _dir = _dir + _i ?_dir < 0: _dir = _dir +360 ?_dir > 360: _dir = _dir -360 _upos = getpos _unit _cposx = _upos select 0 _cposy = _upos select 1 _cposz = _upos select 2 _height = (_height - _inc) ?(_height > _maxheight) : _inc = 0.2 ?(_height < _minheight) : _inc = -0.2 ?alive _unit : _unit doWatch [_cposx + ((sin _dir) * _dis), _cposy + ((cos _dir) * _dis),(_height - _inc)] ;hint format ["Direction is %1\n%2 Steps to go\nHeight is %3",_dir,_steps,(_height - _inc)] ~0.2 _steps = _steps - 1 ?_steps > 0 : goto "steps" goto "loop" #unitdied ;hint "unitdied" _gl = "logic" createvehicle [0,0,0] _gl moveingunner _unit @!alive _unit deletevehicle _gl exit Run it with : Quote[/b] ] [name of the searchlight] exec "randomwatch.sqs" You may also put the searchlight in a tower with this line in the initialisation field of the searchlight Quote[/b] ] this setpos [(getpos this select 0),(getpos this select 1),3.8] 3.8 is the height, adjust it when necessary Here's a demomission : http://rapidshare.com/files/9033990/Searchlight_watch_script.Sara.zip Hope you like it. Share this post Link to post Share on other sites
sickboy 13 Posted December 26, 2006 Heya m8, very nice job, very useful for many ppl... If you don't mind me suggesting... I would suggest to write everything in SQF format for ArmA, as that's the new / optimized way of coding, aswell as that there are preload and process functions etc. etc. Again, only a suggestion m8, nice job either way! Share this post Link to post Share on other sites
Blanco 0 Posted December 26, 2006 I have to learn that stuff first, I'm not familiar with sqf. Any good tutorials around yet? Or can someone convert my script into the new format so I can see how it's done? Glad you like it. Share this post Link to post Share on other sites
sickboy 13 Posted December 26, 2006 I have to learn that stuff first, I'm not familiar with sqf.Any good tutorials around yet? Or can someone convert my script into the new format so I can see how it's done? Glad you like it. Based on my current knowledge : Basicly, every line that's not comment, the returning result of a function or the opening of a while, if, etc, needs a ; at the end. @... is replaced by waituntil{...}; ~.. is replaced by sleep ..; ;... comment is replaced by // ... comment ? ... : ... is replaced by if (...) then { .. }; and you can use else, this will be ran when the first condition=false instead of true: if (...) then { .. } else { .. }; goto ".." and #.. is replaced by while {..} do { .. }; together with if and else you can recreate the same loop possibilities as before but probably more efficient! Switch is also awesome to use, More info about Control Structures You need to define the used private (not global) variables by: private ["_var1","_var2","_var3"]; you do not have to define _this as that's always private. Instead of running scripts with exec you need to use execVM if you wish to run SQF scripts... Functions work the same as scripts, altough you call the functions instead of execVM them: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">randomInt = compile preprocessfile "functions\randomint.sqf"; <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_i = [1,5] call RandomInt; The difference between scripts (execVM/Spawn) and functions (call) is that scripts can be running parallel, while a function (call) is first completing the function and is usually receiving a returned value, before it continues the script in which you called the function. So you can load different variables in your script, with the output of different functions called with their own parameters. Or the function could just run some code without returned value, while the script will wait for it to complete before continueing the script. What I do is preload the used scripts into variables (like functions): <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">six_scr_misinit = compile preprocessFile "scripts\misinit.sqf"; And then when I need the script, I spawn it (as with functions you would call them): <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">[] spawn six_scr_misinit; The main reason I use this personally, is that the scripts are all compiled and loaded before, and you can keep spawning them as many times as you want without the game reloading the script every single time from file, plus that you find problems with the scripts(syntax) right away as they are processed at the start. You can of coarse preload and spawn things only nececairy for lets say client or server, by creating a gamelogic that's named server (which could actually be named anything), by testing if it's local: if(local server) then { .1. } else { .2. }; if the script is ran on the server, it will run the code at 1, and if it's ran on the client it will run the code at 2. Loaded functions/scripts are global if they are loaded in global variables (without _ in front of them), as such you can initiate (most of) them at the start in init.sqs etc, while using them throughout any script. While more specific scripts or functions can be loaded later, when they are needed. OFPEC has loads of functions in SQF, so you could have a look there and see if there is smth you can use as a base to understand the syntax. http://www.ofpec.com/ed_depot/functions.php The BIS Community WIKI also has some SQF scripting basics afaik: http://community.bistudio.com If you don't get it converted somehow, just let me know, if I got some spare time here and there I will convert it as an example for you Examples: (BTW the forum messes up the tabs etc, so they are replaced by spaces) While and waituntil (this script waits for six_bc to become true, then puts it back to false, executes some code, and then waits again till six_bc = true, until a certain condition is met and then _run is set to false and as such ends the loop):<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">/////////////////////////////////////////////////////////// // ArmA - loop_cl.sqf by Sickboy (sb_at_6thSense.eu) /////////////////////////////////////////////////////////// private ["_run","_obj1f","_obj2f","_obj3f","obj4f"]; _obj1f=false; _obj2f=false; _obj3f=false; _obj4f=false; _run = true; while{_run} do { waitUntil {six_bc}; six_bc = false; if(overcast != six_overcast) then { 0 setOvercast six_overcast }; if(fog != six_fog) then { 0 setFog six_fog }; if(six_daci) then { if(six_obj1act && six_obj1d && !_obj1f) then { _obj1f=true; hint "Objective 1: Done" }; if(six_obj2act && six_obj2d && !_obj2f) then { _obj2f=true; hint "Objective 2: Done" }; if(six_obj3act && six_obj3d && !_obj3f) then { _obj3f=true; hint "Objective 3: Done" }; if(six_obj4act && six_obj4d && !_obj4f) then { _obj4f=true; hint "Objective 4: Done" }; if(six_obj1d && six_obj2d && six_obj3d && six_obj4d) then { "outro" spawn six_scr_cam; _run = false}; }; }; A function, for returning valid players (Alive and not null) as an array of objects, from an array of strings. I define all the possible players=["s1","s2","s3"....] and use a script loop that uses this function to update a currentplayer array according to current alive and valid players, and possibly added players through JIP:<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">/////////////////////////////////////////////////////////// // ArmA - fnPlayers.sqf by Sickboy (sb_at_6thSense.eu) // Input - Array with players as strings // Output - Array with alive players as objects /////////////////////////////////////////////////////////// private ["_y","_f","_r"]; _r = []; { _y = call compile _x; _f = format["%1",_y]; if ((_f != "scalar bool array string 0xe0ffffef") && (_f != "<NULL-object>")) then{if (alive _y) then { _r = _r + [_y] }}; } foreach _this; _r Share this post Link to post Share on other sites
Blanco 0 Posted December 27, 2006 Thx, but I need time to understand the new syntax. It's still Chinese for me. I'm kind of familiar with if, then & else statements but while, do, from, switch are new to me. I 've started with OFP scripting without any scripting knowledge, except for a little BASIC from school. I've learned a lot by watching other people's scripts. I extracted the whole ArmA campaign and I couldn't find one sqf script. At this moment I can't even make the examples on the wiki work... Share this post Link to post Share on other sites
sickboy 13 Posted December 27, 2006 Well, how do you think most of us learned? I haven't had a single computer lesson in my whole life, altough I have been busy with computers at home since I was 10 ) This is the converted script... I did not try it yet, as that needs to wait until at least tonight... but it should work, might even use some optimizations here.. Kegetys posted some nice examples of how to use breakout and breakto... I might update if I feel like it Remember, you must use execVM to run it, or if you preprocessed it into a variable, Spawn. Again... the forum messes my tabs, so I replaced tabs by spaces <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">//watch script for searchlights 0.2 //written by Blanco //converted to SQF by Sickboy (sb_at_6thSense.eu) private ["_run","_unit","_dis","_steps","_x","_i","_maxheight","_minheight","_inc","_height","_upos","_cposx","_cposy","_cposz"]; _unit = _this select 0; _dis = 200; _run = true; while{_run} do {   if (not alive _unit) then   {      _run = false;   } else {      _dir = random 360;      _steps = random 350 + 10;      _steps = _steps - _steps %1;      //hint format ["Dir is %1 in %2 steps",_dir,_steps];      sleep 2;      //hint "Heading for a new direction";      _x = 0;      _i = -1;      _maxheight = 45;      _minheight = 2;      _inc = -0.2;      _height = (2 + random 43);      //hint format ["height = %1",_height];      sleep 1;      if (random 2 < 1) then { _i = 1; _inc = 0.2 };      while{_steps > 0} do      {        if(not alive gunner _unit) then        {           _run = false;        } else {           _upos = getpos _unit; _cposx = _upos select 0; _cposy = _upos select 1;   _cposz = _upos select 2; _height = (_height - _inc);           _dir = _dir + _i;           if(_dir < 0) then { _dir = _dir + 360 };           if(_dir > 360) then { _dir = _dir - 360 };           if(_height > _maxheight) then { _inc = 0.2 };           if(_height < _minheight) then { _inc = -0.2 };           if(alive _unit) then { _unit doWatch [_cposx + ((sin _dir) * _dis), _cposy + ((cos _dir) * _dis),(_height - _inc)] };           //hint format ["Direction is %1\n%2 Steps to go\nHeight is %3",_dir,_steps,(_height - _inc)];           _steps = _steps - 1;           sleep 0.2;        };      };   }; }; //hint "unitdied"; if(alive _unit) then {   _gl = "logic" createvehicle [0,0,0];   _gl moveingunner _unit;   waituntil{not alive _unit};   deletevehicle _gl; }; Share this post Link to post Share on other sites
redface 1 Posted December 27, 2006 terrific script Blanco! this converts one of your many pioneering OFP scripts (need I recall e.g. LogicCam to anyone?) to Armed Assault Share this post Link to post Share on other sites
mattxr 9 Posted December 27, 2006 Sickboy how do i get it to work in the editor it never lets me run [this] execVM "script.sqf" or any other way?? how can i get it to work Share this post Link to post Share on other sites
sickboy 13 Posted December 27, 2006 Sickboy how do i get it to work in the editor it never lets me run[this] execVM "script.sqf" or any other way?? how can i get it to work  Do you get some kind of error while you try to run it like that? I usually load everything in my scripts and use the init fields etc as less as possible, but just give names to all the objects I wish to use in scripts. Please post the contents of script.sqf (if it isn't the sqf that I posted above) if you had an error. I think I read somewhere that "call" could not be used in the mission editor, but afaik execVM should work just as fine as exec.. Just checked, im actually using an execVM in the onActivation of a trigger for displaying some debug info, and that at least works, now im not sure about the init fields... Share this post Link to post Share on other sites
Blanco 0 Posted December 27, 2006 Thx, sickboy. It all looks so obvious when I see the conversion, it definitly helps me to understand the syntax. I did some tests with enemy AI and it seems that AI tries to kill the gamelogic when the original gunner got killed; Good luck I had to add a _gl setcaptive true line at the end to prevent this and I was really suprised it worked. (afaik see) I always thought Setcaptive had no effect on gamelogics but it seems it does. @Redface : I already tried logiccam and It doesn't seems to work anymore in ArmA,I dunno why. Share this post Link to post Share on other sites
Blanco 0 Posted December 28, 2006 I tried you conversion Sickboy and it doesn't work or I don't know how to run it. I've made an init with Quote[/b] ]watchscript=compile preprocessfile "watch.sqf"; sleep 1; [sL1] call watchscript; That gave me an error. http://img.photobucket.com/albums/v228/blanco2/CAtafgan/error.jpg Then I tried it via execVM... Quote[/b] ][sL1] execVM "watch.sqf" or Quote[/b] ]SL1 execVM "watch.sqf" No succes... Can you tell me how to run this, cause I don't have a clue... How can I use parameters? Same way as in sqs scripts? Share this post Link to post Share on other sites
sickboy 13 Posted December 28, 2006 ... Please share the error, as that will help me understand what's wrong ) I can take a look tonight if we don't get it debugged by the error report. You can read your errors back in your arma.rpt folder in %USERPROFILE%\local settings\application data\arma %USERPROFILE% is usually C:\Documents and Settings\yourname <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">watchscript=compile preprocessfile "watch.sqf"; sleep 1; [SL1] call watchscript; is wrong, as it is no function, in this case you should use spawn: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">watchscript=compile preprocessfile "watch.sqf"; sleep 1; [SL1] spawn watchscript; <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">[SL1] execVM "watch.sqf" Is fine Share this post Link to post Share on other sites
Blanco 0 Posted December 28, 2006 the error here's what I found in that rpt file Quote[/b] ]if (not alive _unit) th> Error position: <while{_run} do { if (not alive _unit) th> Error Missing ; Error in expression <this select 0; _dis = 200; _run = true while{_run} do When I run it with [sL1] execVM "watch.sqf" I got : type script expected nothing, i'm not allowed to press the ok button. Share this post Link to post Share on other sites
sickboy 13 Posted December 28, 2006 When I run it with [sL1] execVM "watch.sqf" I got : type script expected nothing, i'm not allowed to press the ok button. Try with: dummy=[sL1] execVM "watch.sqf" Â Â dummy can be anything. (thanks to raedor for the tip), altough I prefer using the loading of the script in a variable and spawning it, especially handy/optimized when using multiple search lights! Will check error and update in a sec...update: _run = true was missing ; so: _run = true; Share this post Link to post Share on other sites
Blanco 0 Posted December 28, 2006 huh..in what line? The 9th? Share this post Link to post Share on other sites
sickboy 13 Posted December 28, 2006 huh..in what line? The 9th? yes, I already updated my post with the fix aswell im gonna take a look at the script within a mission, brb will update Share this post Link to post Share on other sites
Blanco 0 Posted December 28, 2006 Ok, take your time, no need to hurry Share this post Link to post Share on other sites
BadAss -Mapfact.net- 0 Posted December 28, 2006 I'm sorry if i'm messing up your efforts. But I've experienced or suffered some strange behaviour with my own searchlight script. What I wanted to do is a script to let your guard search a defined angle. The script looks just like this: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">comment "Script by BadAss, Feel free to use and modify visit www.mapfact.net and www.mapfact.net/forum_arma contact: badass@mapfact-team.net"; private["_sl","_ang","_del","_dir","_dirneg","_dirpos"]; _sl=_this select 0; _ang=_this select 1; _del=_this select 2; _dir=getDir _sl;_dirneg=_dir-_ang/2;_dirpos=_dir+_ang/2; while {alive gunner _sl} do { while {(alive gunner _sl)&&(_dir>_dirneg)} do { _dir=_dir - 1; _sl setDir _dir;gunner _sl setFormDir _dir; sleep _del; }; sleep (_del*5); while {(alive gunner _sl)&&(_dir<_dirpos)} do { _dir=_dir + 1; _sl setDir _dir;gunner _sl setFormDir _dir; sleep _del; }; }; In theory it works pretty okay but - and that's my pain - not always. In my little test mission only one of three guards is turning his rounds. The two lazy guards will eventually start when you get near enough - not exactly the way a searchlight is expected to work. Sometimes the searchlights are nervously twitching at their turning points. I don't have any clue why. Bad thing: they don't do it regularily. Here's the little testing mission that I've made. Any help and ideas are appreciated, so take my thanks in advance. Share this post Link to post Share on other sites
sickboy 13 Posted December 28, 2006 @ Dec. 28 2006,20:30)]... Roger, looking at both. Had to remove MAP_misc from the addon arrays and the map_misc_logic --> just logic Share this post Link to post Share on other sites
BadAss -Mapfact.net- 0 Posted December 28, 2006 Sorry, you're right. It's just because we're making our first little ArmA ad... erm. Wait and see. And thanks for having a look at it. Share this post Link to post Share on other sites
sickboy 13 Posted December 28, 2006 @ Dec. 28 2006,20:55)]Sorry, you're right. It's just because we're making our first little ArmA ad... erm. Wait and see. As if I didn't know Still on it, it's indeed weird, but I have at least found that if you remove the _sl setdir's the movement is a lot more smooth. BadAss Update: This seems to work fine! Tabs replaced by 4x space for [ code ] block, added extra while loop for 10.000x10.000 loops <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">comment "Script by BadAss, Feel free to use and modify visit www.mapfact.net and www.mapfact.net/forum_arma contact: badass@mapfact-team.net Edited by Sickboy (sb_at_6thSense.eu) with dowatch-direction code from Blanco"; private["_sl","_ang","_del","_dir","_dirneg","_dirpos","_dis","_upos","_cposx","_cposy","_cposz","_run"]; _sl=_this select 0; _ang=_this select 1; _del=_this select 2; _dir=getDir _sl;_dirneg=_dir-_ang/2;_dirpos=_dir+_ang/2; _dis=200;_upos=getpos _sl; _cposx=_upos select 0; _cposy=_upos select 1; _cposz=_upos select 2; _run=true; while {_run} do {   while {alive gunner _sl} do   {     while {(alive gunner _sl)&&(_dir>_dirneg)} do     {       _dir=_dir - 1;       _sl doWatch [_cposx + ((sin _dir) * _dis), _cposy + ((cos _dir) * _dis),_cposz];       sleep _del;     };     sleep (_del*5);     while {(alive gunner _sl)&&(_dir<_dirpos)} do     {       _dir=_dir + 1;       _sl doWatch [_cposx + ((sin _dir) * _dis), _cposy + ((cos _dir) * _dis),_cposz];       sleep _del;     };   }; };The problem seems to be an engine bug or by design?? when an unit is turned with setformdir it doesn't relate properly when ur far away from it :S Can't do better at the moment Blanco: When I used the SQF script as I posted it a few posts ago, it works fine when using: dummy=[this] execVM "script.sqf"  in the init line of the light, should also work for you I guess Share this post Link to post Share on other sites
BadAss -Mapfact.net- 0 Posted December 28, 2006 Great work! Now they're real guards. Thank you! I've never been into that sin and cos stuff, but i'll try and see if i get it someday... Btw. maybe you've noticed? The searchlight guys are really wearing NVGoggles by default. Share this post Link to post Share on other sites
raedor 8 Posted December 28, 2006 @sickboy: Instead of using (and computing everytime) sin dir and cos dir, check the "similarities" to vectorDir Share this post Link to post Share on other sites
sickboy 13 Posted December 28, 2006 @ Dec. 28 2006,22:28)]Great work! Now they're real guards. Thank you! I've never been into that sin and cos stuff, but i'll try and see if i get it someday... Btw. maybe you've noticed? The searchlight guys are really wearing NVGoggles by default. No biggie, and im no star with the cos etc either About the NVG, I actually didn't notice, was concentrating on getting the stuff fixed asap, share it and get on with my own stuff but too bad they dont put it down auto But I guess you solved that already? @sickboy: Instead of using (and computing everytime) sin dir and cos dir, check the "similarities" to vectorDir Thanks for the tip m8! Will take a look at it, but was merely fixing and converting to sqf (for Blanco) without really bothering about the structures or used functions.. That's for another day  Share this post Link to post Share on other sites
BadAss -Mapfact.net- 0 Posted December 28, 2006 @sickboy: Instead of using (and computing everytime) sin dir and cos dir, check the "similarities" to vectorDir What would it look like then? But I guess you solved that already? Just ignored it so far, but why not. Good idea. Share this post Link to post Share on other sites