Jump to content
Sign in to follow this  
[frl]myke

[Beginners guide]: Arrays

Recommended Posts

Hello people,

so you started scripting and already wrote some ubercool awesome scripts. ;)

But if you don't know arrays, well, then you ain't seen nothing yet. Arrays are essential to advanced scripting techniques.

What are arrays?

Simplified, you may see them as list. A container that holds multiple parameters. You ca identify a array by it's surrounding square brackets [ ].

You surely already encountered arrays:

nul = [1,2,3,4] execVM "anyScript.sqf"

I see you remember. There is a array right in front of the execVM command. In this case, the array passes parameters to "anyScript.sqf" for further use. We will look on this particular array a bit later. Let's start inside scripts first.

Creating a array.

Inside a script, a array is build exactly the same way as a variable is defined.

_myArray = [you, me, Maruk];

Now we have a array, named "_myArray" and we filled it with 3 people.

Selecting a specific parameter out of the array

First, we have to know that index numbering is zero-based. So the very first parameter has index 0 and not 1.

To select a specific parameter which position inside the array is known, we use the command select. Example based on the above created array:

_god = _myArray select 2;

I guess you can figure yourself who _god is. ;)

Probably you already used the "getPos" command to get a unit's position. This command also returns a array, containing 3 parameters:

[lattitude, longitude, altitude]

So if we want to know the altitude above ground of any object, we use the select command:

_god = _myArray select 2;
_heaven = getpos _god select 2;

"getpos _god" returns a array from which we select the third parameter, the altitude.

The "foreach" command

Probably the most useful command when it comes to arrays. Let us rearm _god, first without arrays;

_god addMagazine "30Rnd_556x45_Stanag";
_god addMagazine "30Rnd_556x45_Stanag";
_god addMagazine "30Rnd_556x45_Stanag";
_god addMagazine "30Rnd_556x45_Stanag";
_god addMagazine "1Rnd_HE_M203";
_god addMagazine "1Rnd_HE_M203";
_god addMagazine "1Rnd_HE_M203";
_god addMagazine "1Rnd_HE_M203";
_god addMagazine "15Rnd_9x19_M9";
_god addMagazine "15Rnd_9x19_M9";
_god addMagazine "M136";
_god addWeapon "M4A1_RCO_GL";
_god addWeapon "M9";
_god addWeapon "M136";

Ooookay....it works, no doubt. But "advanced scripting" looks a bit different.

{_god addMagazine _x} forEach ["30Rnd_556x45_Stanag","30Rnd_556x45_Stanag","30Rnd_556x45_Stanag","30Rnd_556x45_Stanag", "1Rnd_HE_M203","1Rnd_HE_M203","1Rnd_HE_M203","1Rnd_HE_M203","15Rnd_9x19_M9","15Rnd_9x19_M9","M136"];
{_god addWeapon _x} forEach ["M4A1_RCO_GL", "M9", "M136"];

WTF? Compressing 14 lines into 2? Yes. Let us look what happened. First, please take note of the variable "_x". It is a placeholder and is part of the foreach command. The foreach command takes each parameter of the array separately, puts it on the place of _x and then executes the command(s).

Removing elements from an array

Well, i don't feel comfortable being in one array with _god. ;)

So, let's take "me" out of it. And you don't belong there aswell:

_myArray = [you, me, Maruk];
_myArray = _myArray - [you, me];

After that, the array _myArray only holds Maruk. You and me were removed from it.

End of lesson one. Will be continued one day, don't ask when. Hope it helps.

  • Like 2

Share this post


Link to post
Share on other sites

Mind if I add some things?

Adding elements to an array

You can also add elements to arrays.

_myArray = _myArray + [newElement1,newElement2,newElement3];

These new elements will be appended to the end of the array. So if _myArray began with 2 elements, newElement1 would be at index 2.

The count command

Maybe just as (if not more) useful than forEach. Count actually has 2 syntaxes. The more common one is simply:

_arrayLength = count _myArray;

It will give you the number of elements in _myArray.

The second syntax however is very powerful. It works a lot like forEach, only instead of just executing code, you can test a condition against all elements in the array and it will return the number of elements for which the condition was true.

Ex:

_myArray = ["30Rnd_556x45_Stanag","30Rnd_556x45_Stanag","30Rnd_556x45_Stanag","30Rnd_556x45_Stanag", "1Rnd_HE_M203","1Rnd_HE_M203","1Rnd_HE_M203","1Rnd_HE_M203","15Rnd_9x19_M9","15Rnd_9x19_M9","M136"];
_numStanagMags = {_X == "30Rnd_556x45_Stanag"} count _myArray;

Returns 4.

Setting elements

If you want to change the value of an array element without adding/removing (and thus reordering) it, you can use the set command. Set takes an array, an index, and a value as arguments. It takes the array, and replaces the value of the element at the given index with the new given value.

_myArray = [you, me, Maruk];
_myArray set [2, Suma]; // replaces Maruk with Suma

Edit: I should also mention that you can use an index outside of the array's current size, and the array will be resized up to the given index (with some default/null value in all the other new indices).

Nested/2D/XD arrays

Arrays can contain any variable type, including other arrays. You can use this to create multidimensional arrays. For example, if you want to represent a 2D map with a coordinate system:

_myMap = [
[ 0 , 0 , 0 , 0 , A , 0 , 0 , B ],
[ 0 , 0 , C , 0 , 0 , D , 0 , 0 ],
[ 0 , 0 , 0 , 0 , 0 , 0 , E , 0 ]
];
_valueD = (_myMap select 1) select 5;

The index of the primary array would be your Y coordinate, and the index in the subarray at index Y is your X coordinate.

You can also use nested arrays to pass arrays to scripts along with individual arguments.

_handle = [1,5,[0,1,2],"Hello",[player,"goodbye"]] execVM "myScript.sqf"

Inside of myScript.sqf:

_this select 2; // contains the array [0,1,2]
_this select 4; // contains the array [player,"goodbye"]

Edited by Big Dawg KS

Share this post


Link to post
Share on other sites

Thanks for the great info. I appreciate the time you spend to make some of this stuff make sense to us. :)

Share this post


Link to post
Share on other sites

Adding elements to an array

You can also add elements to arrays.

_myArray = _myArray + [newElement1,newElement2,newElement3];

These new elements will be appended to the end of the array. So if _myArray began with 2 elements, newElement1 would be at index 2.

Advanced:

Operator + is in fact very slow compared to the set command (10 times according to my last test).

If you are working with large arrays you might want to consider putting that little extra effort in.

Adding 1 element to an array:

_array1 = _array1 + [1]; // +
_array2 set [count _array2, 1]; // set

Adding elements from 1 array to another:

_array1 = [0,1,2,3,4];
_array2 = [0,1,2,3,4];
_arrayAdd = [5,6,7,8,9];

_array1 = _array1 + _arrayAdd; // +
// set:
for "_i" from 0 to ((count _arrayAdd) - 1) do
{
    _array2 set [count _array2, _arrayAdd select _i];
};

Edited by Deadfast

Share this post


Link to post
Share on other sites

I would further rewrite the horribly long ammo line to something more read and edit friendly:

{_god addMagazine "30Rnd_556x45_Stanag"} forEach [1,2,3,4,5,6];
{_god addMagazine "1Rnd_HE_M203"} forEach [1,2,3,4];
{_god addMagazine "15Rnd_9x19_M9"} forEach [1,2,3,4];
_god addMagazine "M136";

A great source is checking out the variables page.

I'll also mention that if you have one element to add, instead of using

_myArray = _myArray + [newElement];

we should, as it is faster, use

_myArray set [count _myArray, newElement];

Edit: Oh, "set" was already covered.

Todo: Wipe my glasses :D

Edited by CarlGustaffa
Added two missing forEach commands. Funny how nobody noticed :)

Share this post


Link to post
Share on other sites

Thanks for all the input, folks. really excellent and useful contributions, also a lot i didn't knew myself.

Best example that one alone can't know everything. :D

:EDITH:

@Moderators

maybe worth a sticky? If possible, merge the posts from Big Dawg KS, Deadfast and CarlGustaffa with the first post, also if possible with author name.

@CarlGustaffa

could you add that for the example you brought, the content of the array doesn't matter but the count of elements?

Edited by [FRL]Myke

Share this post


Link to post
Share on other sites

Deadfast, I really pitty the man having to work with such large amounts of data in SQF. :p It's just not built for it.

Share this post


Link to post
Share on other sites

The difference is somewhat linear, even with 2 elements set is 10 times faster. It doesn't just magically kick in.

Share this post


Link to post
Share on other sites

Adding elements to an array

You can also add elements to arrays.

_myArray = _myArray + [newElement1,newElement2,newElement3];

While this is not wrong, it's slow, since you're not really appending the new elements to your already existing array, but you create a new one. Now this might be exactly what you want to do in case you still need to original array intact. But since your examples intention is to append some elements to an array, this is really not the prefered way to do this. Instead:

{
  _myArray set [(count _myArray), _x];
} forEach [newElement1,newElement2,newElement3];

would be faster, especially for if you append elements in a loop. And since this is a pretty common task, I suggest you put something like this in a function:

fn_arrayAppend.sqf:

/*
  Author:
   rübe

  Description:
   appends an array onto another one, modifying the
   original array (which is faster than creating a
   new list alltogether)

  Parameter(s):
   _this select 0: original list (array)
   _this select 1: items (array)

  Returns:
   original list (array)
*/

private ["_n"];

_n = count (_this select 0);

{
  (_this select 0) set [_n, _x];
  _n = _n + 1;
} forEach (_this select 1);

(_this select 0)

What are arrays?

Simplified, you may see them as list.

Actually they _are_ lists. There is no simplification involved here. And especially newbies should use this term, because the concept of a list is pretty much common to everyone. A list is either empty or it contains items that are in a specific order.

And this is where fundamental concepts come in, such as searching a list, filtering a list, sorting a list and finally modifying or mapping a list. These operations are that fundamental, that you really should have a set of generic functions for each of these operations. I'm a bit surprised, that the BIS function library doesn't really offer that. Well, no problem. We will write our own then, I guess:

Filtering a list

The good must be put in the dish,

The bad you may eat if you wish.

What ever you're going to do, the sooner or later you're going to need to filter a list. Need a list of all AT units in your group? Do you wanna rearm all units beeing out of ammo? You wanna get a list of objects in range of a certain position?

FN_arrayFilter.sqf:

/*
  Author:
   rübe

  Description:
   returns a filtered list, not touching the original one,
   by means of a custom filter. 

  Parameter(s):
   _this select 0: list (array)
   _this select 1: filter (code)
                   - the filter gets passed the current item
                   - the filter has to return boolean:
                     - true: keep
                     - false: discard

  Returns:
   array
*/

private ["_filtered", "_i"];

_filtered = [];
_i = 0;

{
  if (_x call (_this select 1)) then
  {
     _filtered set [_i, _x];
     _i = _i + 1;
  };
} forEach (_this select 0);

_filtered

Example:

// 1. get a list of all units beeing out of ammo
_outOfAmmo = [
  (units group player), 
  {
     (!(someAmmo _x))
  }
] call FN_arrayFilter;

// 2. get a list of all units in range of the player
_unitsInRange = [
  allUnits, 
  {
     ((_x distance player) < 200)
  }
] call FN_arrayFilter;

Sorting a list

Don't prematurely skip this topic, thinking that you won't need to sort anything anyway. Maybe you do afterall, since sorting has also much in common with searching a list. For example you might need to select the object nearest to you out of a list of objects (or objectives or whatever). Sounds like searching? Well, how about you sort your list according to the distance and then you can easily pick the first item in your list. Searching for something is often just another case of sorting a list, and then selecting the first one(s).

Anyway, sorting a list is that important, that there are many clever ways/algorithms to do it. Unfortunately, you can't say that any one is the best algorithm, since it highly depends upon the input list, what algorithm will be the most appropriate/fastest one. Is your original list one big mess? Or is it already pretty much sorted? .. well you probably don't care anyway, so aslong you don't go with bubble-sort, you should be fine. A good choice for the everyday needs in Arma is shell-sort, which should do fine in the usual cases. But since we're probably not going to sort lists of numbers, we need a generic function for this:

fn_shellSort.sqf:

/*
  Author:
   rübe

  Description:
   generic shell sort implementation. The original list does 
   NOT get altered.

   Shellsort is not sensitive to the initial ordering of the
   given list. Hard to compare to other sorting methods but
   shellsort is often the method of choice for many sorting
   applications:

    - acceptable runtime even for moderately large lists,
      (Sedgewick says up to "five thousand elements")
    - yet very easy algorithm.

  Parameter(s):
   _this select 0: the list to be sorted (array of any)
   _this select 1: sort value selector/calculator (string or code; optional)
                   - gets passed a list item, must return scalar
                   - if a string gets passed, we compile it first

                   -> if the list does not consist of numbers but a complex 
                      data structure (like arrays), you may pass a simple
                      function, that accesses (or calculates) the "value" 
                      in this structure the list will be sorted on.

                   -> to simply invert the sort order, pass {_this * -1} as
                      second parameter (for numbers).

                      default sorting order is ASCENDING

  Returns:
   sorted list
*/

private ["_list", "_selectSortValue", "_n", "_cols", "_j", "_k", "_h", "_t"];

_list = +(_this select 0);
_selectSortValue = { _this };

if ((count _this) > 1) then
{
  if ((typeName (_this select 1)) == "CODE") then
  {
     _selectSortValue = _this select 1;
  } else {
     _selectSortValue = compile (_this select 1);
  };
};

// shell sort
_n = count _list;
// we take the increment sequence (3 * h + 1), which has been shown
// empirically to do well... 
_cols = [3501671, 1355339, 543749, 213331, 84801, 27901, 11969, 4711, 1968, 815, 271, 111, 41, 13, 4, 1];

for "_k" from 0 to ((count _cols) - 1) do
{
  _h = _cols select _k;
  for [{_i = _h}, {_i < _n}, {_i = _i + 1}] do
  {
     _t = _list select _i;
     _j = _i;

     while {(_j >= _h)} do
     {
        if (!(((_list select (_j - _h)) call _selectSortValue) > 
              (_t call _selectSortValue))) exitWith {};
        _list set [_j, (_list select (_j - _h))];
        _j = _j - _h;
     };


     _list set [_j, _t];
  };
};

_list

Example:

// get the most injured units/sort by damage, descending
// we might first filter out units, that aren't injured at all...
_medicPriorityList = [
  (units group player), 
  {
     ((damage _x) * -1)
  }
] call FN_shellSort;

// sort a list of objectives by distance to the player
_objectivesPriority = [
  _objectives, 
  {
     (_x distance player)
  }
] call FN_shellSort;

// shuffle a list
_shuffledList = [
  _items, 
  {
     (random 1)
  }
] call FN_shellSort;

Mapping a list

Modifying (or applying a certain function to) every item in a list is called mapping a list. While it's not that usefull as filtering or sorting a list (in an enviroment such as Arma), if you need to, a generic function comes in handy nevertheless.

fn_arrayMap.sqf:

/*
  Author:
   rübe

  Description:
   applys a function to every item in an array, altering
   the original array per default.

  Parameter(s):
   _this select 0: list (array)
   _this select 1: function (code)
   _this select 2: copy (boolean, optional; default = false)

  Returns:
   array
*/

private ["_list"];

_list = _this select 0;

if ((count _this) > 2) then
{
  if (_this select 2) then
  {
     _list = +(_this select 0);
  };
};

for "_i" from 0 to ((count _list) - 1) do
{
  _list set [_i, ((_list select _i) call (_this select 1))];
};

_list

Share this post


Link to post
Share on other sites
The difference is somewhat linear, even with 2 elements set is 10 times faster. It doesn't just magically kick in.

But does the average mission maker care how fast it is? Certainly not beginners. Besides, it's not like I said adding was the only way and I certainly didn't say it was the best. I simply said it was possible. Nonetheless, maybe someone will find it useful.

---------- Post added at 10:36 AM ---------- Previous post was at 10:32 AM ----------

Actually they _are_ lists. There is no simplification involved here.

Actually, I would compare them to an ArrayList, since while they are not fixed size like real arrays, they can be indexed. How they work internally though is really of no concern to your average scripter.

Edited by Big Dawg KS

Share this post


Link to post
Share on other sites
I would further rewrite the horribly long ammo line to something more read and edit friendly:

{_god addMagazine "30Rnd_556x45_Stanag"} forEach [1,2,3,4,5,6];
{_god addMagazine "1Rnd_HE_M203"} [1,2,3,4];
{_god addMagazine "15Rnd_9x19_M9"} [1,2,3,4];
_god addMagazine "M136";

Should there be a forEach after the second and third set of {} (for M203 and M9 mags)? I assume so, but am new at this so want to be sure.

@CarlGustaffa

could you add that for the example you brought, the content of the array doesn't matter but the count of elements?

This was my other question. I assume the [1,2,3,4,5,6] is arbitrary as being easy on the eyes/mind, right? It could just as well be [1,1,1,1,1,1]? Or [one,two,three,four,five,six]? Just makes much more sense to count numerals for a quick confirmation of how many?

Thanks for the great tutorial guys!

Share this post


Link to post
Share on other sites
This was my other question. I assume the [1,2,3,4,5,6] is arbitrary as being easy on the eyes/mind, right? It could just as well be [1,1,1,1,1,1]? Or [one,two,three,four,five,six]? Just makes much more sense to count numerals for a quick confirmation of how many?

Yep, you got it right. Using increasing numbering is easier to read. But as long the _x variable is not used, the content is irrelevant for this purpose.

Share this post


Link to post
Share on other sites
Actually, I would compare them to an ArrayList, since while they are not fixed size like real arrays, they can be indexed. How they work internally though is really of no concern to your average scripter.

Every list (no matter how they are implemented) is an indexed list, whether explicitly or implicitly. There is no such thing like a pool of things without order in computing (though sure, you might ignore that information).

Anyway the point is this: this thread is addressed to beginners. No matter how much knowledge you already have, you will know the concept of a list. A list might be empty. A list is a sequence of items, thus there is some order, and so on. Everybody thinks in lists, it is that natural. Thus this already aquired knowledge should be transfered, by using the term list instead of introducing some new and akward term such as array or array list or whatever.

However I totally agree that it's of no concern how arrays are implemented. Though, this is IMHO yet another argument to call those things simply lists.

Share this post


Link to post
Share on other sites

Great post (and supplements).

Really informative for us scripting laymen.

I really wish I saw more of these types of posts.

Two thumbs up!

Share this post


Link to post
Share on other sites
Anyway the point is this: this thread is addressed to beginners. No matter how much knowledge you already have, you will know the concept of a list. A list might be empty. A list is a sequence of items, thus there is some order, and so on. Everybody thinks in lists, it is that natural. Thus this already aquired knowledge should be transfered, by using the term list instead of introducing some new and akward term such as array or array list or whatever.

Ah darn, I think I lost my shopping array!

Hehe, fully agreed and have to admit I'm a bit guilty too...

But does the average mission maker care how fast it is? Certainly not beginners.

I tagged it 'advanced' for a reason. Think of it as an information for intermediate "scholars" :)

As for why I put there in the first place people who come here will be in the stage of developing their own "way". This is the easiest time to learn new things.

Besides, it's not like I said adding was the only way and I certainly didn't say it was the best. I simply said it was possible.

I never claimed you were wrong or anything, I just offered an alternative. I don't understand why you are so defensive.

Share this post


Link to post
Share on other sites

Please no discussion about what's right and what's wrong. You may point to some disadvantages using a certain technique (as you all did already, thanks for that) but beside that, keep it informative in any way you can and will.

Basically, if it works error free, it is right. Anything else is a matter of shortly point and then go on.

Don't get me wrong, i welcome any sort of discussion anytime but in the same time i'll try to keep the topic straight so beginners will not get lost in endless discussions that might start.

So, keep it comming, everything is helpful.

Thanks again, really appreciate it.

Share this post


Link to post
Share on other sites
I never claimed you were wrong or anything, I just offered an alternative. I don't understand why you are so defensive.

Don't worry about it. It's just that everyone started quoting it and saying "use set instead", naturally I had to defend it as still a valid option. I don't want new scripters to think they shouldn't use it. I just wanted to keep things simple. Also, introducing new concepts like script performance is perhaps a topic for another thread, for advanced scripters.

---------- Post added at 11:49 AM ---------- Previous post was at 11:36 AM ----------

Please no discussion about what's right and what's wrong. You may point to some disadvantages using a certain technique (as you all did already, thanks for that) but beside that, keep it informative in any way you can and will.

Basically, if it works error free, it is right. Anything else is a matter of shortly point and then go on.

I agree.

Myke, what's next, eventhandlers? I can say quite a bit about eventhandlers... :cool:

Share this post


Link to post
Share on other sites

Allow me - as a scripting novice, potentially confused by overly complex information - to give my take on the level of information offered here.

I think it is great with input about alternative ways (execution swiftness).

I would agree with Myke, that heavy discussion about which code is best, is a sure way to confuse scripting noobs like myself. On the other hand, it is great to have pros and cons pointed out.

In regards to the "Set command", I read it, and figured that just adding to arrays with '+' seemed more simple and manageable for me, so I'll propably go with that for now. But I'm glad to be aware of the 'set' command. I have bookmarked this thread, and will surely return to play around with the set command, once I'm a bit more comfortable around arrays.

One thing this discussion let me thinking was: How big a role is script execution speed playing in the performance of my missions? How big a deal is this? And when should I opt for one command over another. When giving alternative views on commands, it would be really helpfull if people pointed out, how, when and why I should use a given command over another.

Regards

EDIT: BTW, I would love your guys' wisdom on eventhandlers to :D

Edited by Nielsen

Share this post


Link to post
Share on other sites
Myke, what's next, eventhandlers? I can say quite a bit about eventhandlers...

Excellent idea, when do you start the thread? :D

Share this post


Link to post
Share on other sites
@CarlGustaffa

could you add that for the example you brought, the content of the array doesn't matter but the count of elements?

Ehm, not entirely sure what that means. Sorry, I'm not english, and sometimes I get easily confused :p Note that _x isn't even used, meaning the contents of the numbers could probably be anything. I just use [1,2,3,4...] so I can easily check the last number to see the count. [4,7,2,7,3] makes it a little harder :) And no, I've never checked to see if it even works :)

I'll provide a concrete example where arrays and "manipulating them" takes a strong part.

What I wanted: During a rainful mission, I wanted to make rain "wash away" the camo paint of players and other AI. Face is preset using CfgIdentities in description.ext, easing up the process for creating many similar missions using the same identities. So I needed to construct an array containing ids, faces, and speaker, then assign the correct face to the correct unit, using the startup camo (camo5, camo6 not used).

So, in my example, I have my:

Units named uLI1, uLI2, uSN1 etc stored in mission.sqm in the unit names.

Ids named "idLI1", "idLI2", "idSN1" etc defined in description.ext CfgIdentities.

Note that idEN1 through idEN100 is reserved for enemy units, and must be placed after the friendly units (not tested though, not there yet) since speed may be of the essence. Better to exit as early as possible, rather having to check everything.

The script, with plenty of added comments to easily follow what it does:

_speaker = ""; //Since it is used in two "scopes" ([url="http://community.bistudio.com/wiki/Block"]blocks[/url]), we need to declare this. This can also be achieved using the [url="http://community.bistudio.com/wiki/private"]private[/url] command.
aFaces = []; //Using arrays, the parameter [b]must[/b] be decleared an actual array. Using [url="http://community.bistudio.com/wiki/private"]private[/url] alone is not good enough, and wouldn't work anyway as it's not a local variable.
for "_i" from 0 to (count (missionConfigFile/"CfgIdentities") - 1) do { //Do for every elements in description.ext
_currentID = configName ((missionConfigFile >> "CfgIdentities") select _i); //Lookup CfgIdentities in missionConfigFile (aka description.ext)
_currentFace = getText (missionConfigFile >> "CfgIdentities" >> _currentID >> "face"); //"face" is what we are interrested in
_speaker = getText (missionConfigFile >> "CfgIdentities" >> _currentID >> "speaker"); //_speaker = "Male02EN"
_speaker = toArray _speaker; //Convert "Male02EN" to an array of numbers
_speaker = [_speaker select 5]; //I'm only interrested in the "2" element, but store it as an array, which toString needs.
_speaker = toString _speaker; //Now we can convert [50] back to a string, i.e. "2"
_speaker = parseNumber _speaker; //And finally convert string "2" to the number 2. Phew...
_array = [_currentID, _currentFace, _speaker]; //["idLI1", "face14", 2]
_tmp = toArray _currentID; //Convert "idLI1" (string) to an array of numbers
if (_tmp select 2 == 69 && _tmp select 3 == 78) exitWith {}; //Skip enemy IDs labeled id[b]EN[/b]1-id[b]EN[/b]100
//	aFaces = aFaces + [_array];	//Too slow, see next line
aFaces set [count aFaces, _array]; //Much faster way. aFaces = [["idLI1","face14",2],["idLI2","face15",4], ...] etc
};
//Set initial camo faces, since identity faces have only regular faces.
for "_i" from 0 to count aFaces - 1 do { //Below notes show what happens when _i = 1
_id = (aFaces select _i) select 0; //_id = "idLI1", a string from aFaces we built above.
_unit = toArray _id; //_unit = an array containing the numbers that make up the string idLI1
_unit set [0,objNull]; //mark for deletion
_unit set [1, 117]; //change letter d to letter u
_unit = _unit - [objNull]; //Remove element that was marked for deletion
_unit = toString _unit; //_unit = "uLI1"
_face = (aFaces select _i) select 1; //_face = "Face14"
_unit = call compile _unit; //_unit = uLI1 as object instead of "uLI1" as string
_unit setVariable ["sFace", _face]; //Store the variable so we can easily reference it later in the mission, due to missing getFace command.
_unit setVariable ["sID", _id]; //Store the variable so we can easily reference it later in the mission, due to missing getIdentity command.
_unit setVariable ["speaker", (aFaces select _i) select 2]; //Store the variable so we can easily reference it later in the mission. We have no getSpeaker command.
_face = _face + "_camo5"; //_face = "Face14_camo5"
_unit setIdentity _id; //Attach unit identity idLI1 to unit called uLI1 (_unit), but this has Face14 used, not the camo version.
_unit setFace _face; //Set the face of uLI1 (_unit) to "Face14_camo" (_face)
};
//aFaces = nil; //Uncomment this line if you don't need it anymore for other scripts.

You now have the option of using aFaces as a lookup table, or simply getting what you need using getVariable, for lack or certain missing commands. Converting speaker "Male02EN" to the number 2 is naturally not needed, I just provided it as another example of how to manipulate the things in the array.

Hopefully you can see what I'm doing here, what the end benefits are:

  • Prepare an array for further lookup purposes should it be needed.
  • Store everything via setVariable so I can quickly have access to the data I need other places in the mission due to missing commands (getFace, getIdentity, and getSpeaker).
  • One example shortening this stored data so it takes the least amount of space possible. If I had female or foreign voices, I would have to store more data.

Edited by CarlGustaffa
setVariable for "speaker was wrong", corrected it.

Share this post


Link to post
Share on other sites

well this thread started off pretty simple but got more complicated the further you read into it .

Beginners guide = keep it simple.. :yay:

Share this post


Link to post
Share on other sites
well this thread started off pretty simple but got more complicated the further you read into it .

Beginners guide = keep it simple.. :yay:

It's pretty simple:

- you're beginner, start with first post.

- you got mastered what's in the first post, read the rest. ;)

Best advice, read what is actually interesting for you and your actual work. Keep the rest for another day and/or project.

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  

×