Jump to content
Sign in to follow this  
kyfohatl

How to use brackets ([], (), {}, "",'') properly in a script?

Recommended Posts

I've been learning ARMA 2 scripting, and one of my problems has been brackets in both sqf and sqs files. I've looked at quite a few tutorials, but they never seem to give an in depth explanation on them. So I'm asking for an indepth explanation on when to use what type of bracket in both scripting languages (sqf and sqs).

here's an example of a problem I've been having:

_myStreetLamp = nearestObject [(getPos player), "StreetLamp"]; (sqf format)

So in the example above, why is "getPos player" put in round brackets (why not square or curely ones?) or "streetLamp" which I think is an object in quotation marks? (I thought objects did not need quotes)

Thank you for your help.

Share this post


Link to post
Share on other sites

"STRING"

[array]

{code}

_nearestLamp =nearestObject [getpos player,"StreetLamp"];

will also work.

the "StreetLamp" here is NOT an object, but the CLASSNAME of the object.

ClassNames are put in strings, that is quotes ""

array1 = [1,2,3,4,5] >> this is an array containing 5 elements.

index 0 of array1 will be 1

index 1 == 2

index 2 == 3

so, if you use :

array1 select 0, the result will be 1

curly brackets {} are used to write codes inside.

example :

myCode = {player setdammage 1;hint "player is dead"};

call myCode;

will kill player and show the message "player is dead"

note : the semicolor ';' defines the end of a line.

so

myCode = {player setdammage 1;hint "player is dead"};

EQUALS TO

myCode =

{

player setdammage 1;

hint "player is dead";

};

NOTE : You must inset semicolor after the hint line if you write it in this style.

But the first one is mostly used in the editor.

(Well, someone else can explain you better about this as my native language is not english)

Regards,

Haroon1992

Share this post


Link to post
Share on other sites

Square brackets []:

Square brackets are used for arrays, like

_myArray = [1,2,3,4,5,6];

Round brackets ():

Those are generally used like in math to force the engine to execute the code in round brackets beforehand:

5*6/7 = ?
5*(6/7) = ?

The same way in a line, certain code has to be exectuted before some other code.

Curled brackets {}:

Those are usually containing code in general:

if (bla) then {
 some code
};

Quotation marks "":

Those are used if a data type is a string.

_a = "This is a string";
hint _a;

There are several data types that are strings, most popular are classnames which always are strings.

Regarding your example, getpos Player is in round brackets because the command nearestObject expects a position at this point in XYZ coordinates. You aren't givin these coords directly but as command to get players position. Obviously this has to happen before nearestObject can search for the desired object.

Furthermore nearestObject expects an array with at least 2 entries, position and object to search for. Therefor square brackets (a array).

And finally, Streetlamp is a classname which requires quotation marks.

Don't confuse object with classname. A object is a unique object, regardless if there are hundreds of objects of the same class. There might be dozens of "Streetlamp" class objects.

Share this post


Link to post
Share on other sites

@ Myke and Haroon:

A big thankyou to both of you. An excellent guide for brackets :). It will make my learning much easier. Also I just searched "classnames" in the wiki, and realised the difference between objects and classnames.

One problem that really bogged me was the use of round brackets around "getPos Player", but as haroon said, not having the round brackets will also work. So why did the author (writer of the scripting tutorial) put them there in the first place? To emphasize that they must be processed first by the nearestObject command perhaps?

Anyway thanks again for your help. It was very useful.

Share this post


Link to post
Share on other sites
To emphasize that they must be processed first by the nearestObject command perhaps?

Just to make sure that parameter is an array (the position of the player) when nearestobject is called. This example works either way, but sometimes you can avoid weird and hard to find errors by typing plenty of brackets.

Share this post


Link to post
Share on other sites

Do youself a favour and download squint which will identify syntax errors for you :)

Share this post


Link to post
Share on other sites

The use of parentheses is entirely optional in most cases. They exist mainly to avoid ambiguity. For example, if you write:

x = y + 1 / 2;

When the game compiles this code, it will logically assume to do the division first (so, y + 0.5). Adding parantheses allows you to specify to the game the order in which to process things. So for example, if you intended to do the addition first:

x = (y + 1) / 2;

Which is definately not the same as y + (1 / 2).

Share this post


Link to post
Share on other sites

Ahhh I see. So the brakcets in the case of my example were used simply to avoid ambiguity and possible hard-to-identify errors (so really its just a good scripting practice). Thanks for the responses :bounce3:.

@sbsmac: hmmm... good tool (especially for noobs like me). Downloading... ;)

Share this post


Link to post
Share on other sites

No, brackets aren't that useless.

If you type :

getpos player select 0 move getpos man; 

you'll get errors.

(getpos player select 0) move (getpos man); 

will work fine, however the below is the most appropriate :

((getpos player) select 0) move (getpos man); 

--------------------------------------------------------------

Another sample :

10*5 - 5 

Sometimes it will return 0 instead of 45.

(10*5) - 5  

ensures that answer is 45

and

10*(5-5) 

ensures that answer is only 0

Correct me if anything is wrong. :)

Regards,

Haroon1992

Share this post


Link to post
Share on other sites

Code:

10*5 - 5

Sometimes it will return 0 instead of 45.

I've never experienced this. You sure it was not in some other way? Can you replicate this?

Share this post


Link to post
Share on other sites
No, brackets aren't that useless.

Noone made that claim. But indeed, ambiguity can cause ArmA 2 to parse code incorrectly, and more often than not that generates compile errors. I was going to point that out but you beat me to it. I just have to mention though that your example will still produce errors, because move takes a group, not a number. :j:

For complex lines of code with lots of nested commands, it typically requires parentheses. This is due to the nature in which the game interprets script code. Good practice is to use parentheses to encapsulate expressions that evaluate into logical independent entities. There are a few times where you can probably get away with not using parentheses, such as if your commands all appear in the order in which they are to be evaluated, but you can never be certain.

One other thing I should mention though: If you start using lots of nested pairs of parentheses, code can get pretty unreadable. To make things easier for us people, it's good practice to break complex expressions down into smaller (and more readable) expressions using variables. For example:

player setPos (((getPos player) nearestObject "12345") buildingPos 2);

// is more readable as
_playerPos = getPos player;
_myHouse = _playerPos nearestObject "12345";
player setPos (_myHouse buildingPos 2);

Well, maybe the above example isn't so bad to read, but trust me, when you start getting long expressions where the order of evaluation jumps all over the place, breaking it down is really nice.

Edited by Big Dawg KS

Share this post


Link to post
Share on other sites
If you start using lots of nested pairs of parentheses, code can get pretty unreadable.

Nonsense! If it can't be written with one line of code it shouldn't be written in the first place. Viva la parentheses! :yay:

Share this post


Link to post
Share on other sites

http://en.wikipedia.org/wiki/Order_of_operations

Probably just a generalized example. Round brackets can be used as a bare minimum as required by the code to get the desired results if you know the order of operations, or you can use additional ones if you're not sure. It's the same for (_var select 0), if you know the order of operations (how the engine interprets it), they may not be required. But it's generally common practice to use them regardless.

@kylania: No, Big Dang KS is right. Long one liners are problematic. But also keep in mind that you can use parentheses combined with line breaks and indents to increase the readability of your script.

This command is actually a one-liner:

player kbTell [_speaker,d_kb_topic_side_arti,"ArtilleryRequest",["Team","",_firstsecondstr,[_firstsecondstr]],["Type","",d_ari_type,_vocaltype],["Mode","",if (_mode == "grid") then {" at grid"} else {", observer position"},[]],["Location","",if (_mode == "grid") then {if (count _input == 8) then {_position call Xf_ToGrid8} else {mapGridPosition getMarkerPos D_ARTI_MARKER_HELPER};} else {format ["%1. Angle %2 mils at %3 meters", _grid,_mils,_dist]},_vocalarray],["Rounds","",str(d_ari_salvos),[]],true]

A one liner from hell!

I prefer to break it down to this:

player kbTell [_speaker,d_kb_topic_side_arti,"ArtilleryRequest",
["Team","",_firstsecondstr,[_firstsecondstr]],
["Type","",d_ari_type,_vocaltype],
["Mode","",
	if (_mode == "grid") then {
		" at grid"
	} else {
		", observer position"
	},[]
],
["Location","",
	if (_mode == "grid") then {
		if (count _input == 8) then {
			_position call Xf_ToGrid8
		} else {
			mapGridPosition getMarkerPos D_ARTI_MARKER_HELPER
		};
	} else {
		format ["%1. Angle %2 mils at %3 meters", _grid,_mils,_dist]
	},_vocalarray],
["Rounds","",str(d_ari_salvos),[]],
true
];

Another bad example of a one liner is the ECS mod for Arma1 ;) The engine reads everything as a line, it doesn't care about line breaks. That allows a mod to be written as a single line of code. The only reason for doing so is attempting to make it more cryptic to understand and learn from, or condensing the code. You need a hefty bit of macro programming in order to restore it into readable form.

Edited by CarlGustaffa

Share this post


Link to post
Share on other sites

One of the things that hung me up for awhile was when varibles are passed in an array to another script.

For example, one script may have a line in it like:

[loc,truck,guard] execVM "random.sqf"

So when your working in random.sqf you'll see things like:

_next = _this select 0;

In this example you'll need to search your project folder for random.sqf in your files and see where it is being called from at which time you can see that _next = loc;

Edited by callihn

Share this post


Link to post
Share on other sites

For example, one script may have a line in it like:

[loc,truck,guard] execVM "random.sqf"

So when your working in random.sqf you'll see things like:

_next = select 0;

In this example you'll need to search your project folder for random.sqf and see where it is being called from at which time you can see that _next = loc;

You mean:

_next = [b]_this[/b] select 0;

Share this post


Link to post
Share on other sites

@kylania: No, Big Dang KS is right.

He was being sarcastic.

Share this post


Link to post
Share on other sites
You mean:

_next = [b]_this[/b] select 0;

Yes exactly, shows how well I was paying attention.

I'll correct that.

---------- Post added at 04:17 PM ---------- Previous post was at 04:13 PM ----------

One other thing I should mention though: If you start using lots of nested pairs of parentheses, code can get pretty unreadable. To make things easier for us people, it's good practice to break complex expressions down into smaller (and more readable) expressions using variables.

Bah! F**k humans! What is this blasphamy! There are no humans around here.

Share this post


Link to post
Share on other sites

I would also like to say thanks for this thread. I can't (or won't) tell you how embarrasingly long it took me to come up with this:

{[_x] join player} forEach units rgrp;

I finally found a previous example in all my saved forum threads, but it still looks goofy. Works though!

RR

Share this post


Link to post
Share on other sites
I would also like to say thanks for this thread. I can't (or won't) tell you how embarrasingly long it took me to come up with this:

{[_x] join player} forEach units rgrp;

I finally found a previous example in all my saved forum threads, but it still looks goofy. Works though!

RR

Ehhmm what about

rgrp join player;
//If that doesn't work then
(units rgrp) join player;

Share this post


Link to post
Share on other sites
I would also like to say thanks for this thread. I can't (or won't) tell you how embarrasingly long it took me to come up with this:

{[_x] join player} forEach units rgrp;

I finally found a previous example in all my saved forum threads, but it still looks goofy. Works though!

RR

Yea, well I still don't get the [_x]. :o

I've never experienced this. You sure it was not in some other way? Can you replicate this?

5-5*10 maybe?

One would think that without () then it would work through it one step at a time, though I'm not sure it does.

Share this post


Link to post
Share on other sites

_x is a magic variable which is equal to the current value of the array fed into a forEach each time through.

{hint format["%1",_x]} forEach [1,2,3,4];

Would display four hints: 1, 2 3 and 4. _x being equal to 1 the first time through, 2 the second time and so on.

In the join example it's [_x], an array with one element, since join requires an array input.

Share this post


Link to post
Share on other sites
_x is a magic variable which is equal to the current value of the array fed into a forEach each time through.

{hint format["%1",_x]} forEach [1,2,3,4];

Would display four hints: 1, 2 3 and 4. _x being equal to 1 the first time through, 2 the second time and so on.

In the join example it's [_x], an array with one element, since join requires an array input.

Ohhhhh... So that's what it is. I looked at four tutorials, and I still couldn't understand what it actually does (:o). Thanks Kylania :).

Anyway, thanks for all the good responses in this thread. Just like Rick Rawlings, I can't tell you how useful this thread was.

Share this post


Link to post
Share on other sites

It might return the correct answer but what about the following code?

Do you think it will return what you expected?

5-5*10-2

The result can be -2,-47 or 0

(This happens when that is used in a large script with a loop that cycles every 0.5 seconds or faster)

If you want to get -47,

5-(5*10)-2

5-(5*10)-2 >> 5-50-2 >> 5-52 >> -47

If you want to get -2,

((5-5)*10) - 2

((5-5)*10) - 2 >> 0 - 2 >> -2

This shows that the use of round brackets is also useful for some calculations...

Arguments are welcome.......

Regards,

Haroon1992

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
Sign in to follow this  

×