User Tools

Site Tools


ofp:missions:variables_arrays

Variables & Arrays

Variables & Arrays by Dinger

A variable can take the place of an absolute value in an expression and in effect refers to a value. Since this signified value can vary, we call it a variable.

For example, 2 is an absolute value (numeric).

We can have the expression:

~2

to wait two seconds.

Now, we can set a variable, named A to the value 2:

A=2
~A

Unlike 2, which stays at the value 2, the value associated with variable A can change.

Fair enough. You knew that already.

Variables

Variables come in two flavors:

Local and Global.

Local variables are set apart by being preceded with an underline.

_variable

Global variables have no underline

variable

As the names imply, Local Variables are only accessible within the script in which they appear. Several scripts can use the same named local variables without interference. Global Variables are accessible throughout the mission, in all scripts and in the mission editor (for triggers, waypoints and such).

The Multiplayer engine does not automatically share variable values with other machines.

So, some Global Variables (numbers, booleans, units) can be shared across several computers in a multiplayer mission by using the PublicVariable command, with the syntax:

publicVariable "VariableName";

OFP admits of several types of variables, they are as follows:

Numeric

A floating point number Format: A=0 Transformations to String: Format [“%1”, NumericVariable] Null Value: Nothing

Reserved Numeric Variables: (not a complete list)

Pi       PI (3.14159)
time     time since game started
_time    time since script started
daytime  time of day (in hours)

String

A series of characters, strings are case sensitive. Format: A = “Hello There” Null Value: “” Transformations: Use the ForEach command. e.g., TransString = “321”

    "Numeric = " + TransString Foreach [0]

Object/Unit

An object, unit, GameLogic or Trigger in OFP.
Last I checked (this may be different for 1.75, in fact it probably is), you can't enter the absolute value of an object/or unit, (e.g., WEST:Alpha Black 1).
You can, via the editor, assign it an object name variable (in the name field).
Format: A = player
null Value: ObjNull
Transformations to string: Format [“%1”, UnitVariable]
To Group: Group UnitVariable

Reserved Object/Unit Names:

Player: The current player
this: In the init field of a unit (or a waypoint), the name of the unit whose init field it is (or – I think – the group name for the waypoint).

Group

The group a unit belongs to.
Again, you can't get at this info directly (at least I don't think you can).
Format: A = group player
Transformations to string: Format [“%1”, GroupVariable]
To an Array of Units: units GroupVariable

Boolean

True or False values
Format: A = False
nullvalue: none

Other Variable Types:

Markers
Sides

Some words on using variables

Any Boolean conditional on an undefined value will result false, so for example if you haven't defined UndefinedVariable, both:

Not (UndefinedVariable)

and

UndefinedVariable

will result FALSE.

For objects and groups, you can use IsNull to determine if the object/unit or group exists. All variables can be destroyed by being set to Nil

e.g.:

A = nil

will destroy variable A

Arrays

Arrays in OFP consist of a series of values assigned to one variable name.
Format: A = [value1, value2, value3…]
Transformations to string: Format [“%1”, ArrayName]
Null value: NullArray = []

The elements in an array can be of any value type described above, including other arrays.

For example, you could have:

SampleArray = [52, "Barney", player, ["bite me", nearestbuilding getpos player]]

Extracting values from an array

You can get a single value out of an array using SELECT.

The format is:

Array Select PositionInArray

Array positions begin with zero. So in the samplearray above if we called:

B = SampleArray select 1

the value of B would be “Barney” and not 52.

You can get the size of an array by using COUNT:

Count SampleArray

This, for example, would return a value of 4

You can check for a value in an array by using IN:

"Barney" in SAmpleArray 

Would return TRUE

Note: This doesn't work too well for nested arrays, so

"bite me" in sampleArray

would return FALSE

You can also count the number of occurrences of a given condition by using a variation of the COUNT command (See below: Actions on elements in arrays).

Setting Values in an array

First, an array has to be initialized. It can be done in one of three ways:

MyArray = []
MyArray = [value1, value2, value3]
MyArray = +MyOtherArray

I don't know if (and don't think) this is still the case, but the documentation tells us that if we set one variable to be equal to another array variable, both variables will refer to the same array.

In theory, this would mean:

a = []
b = []
a = b
b = [barney1, barney2]

would result in variable a being equal to [barney1, barney2] as well.

For this reason + forces OFP to make a copy of the array.

Adding Values to an array

You can add a value to the end of an array by using +. You can only add arrays to arrays.

So,

MyArray = [Barney1, Barney2]
MyArray = MyArray + [Barney3]

NOT

MyArray = MyArray + Barney3

Subtracting Values from an array

You can subtract a value from an array by using -. Note that every instance of that value will be deleted.

So,

[Barney1, Barney2, Barney1] - [Barney1] 

will equal

[Barney2]

You can work around this using the Set command (See below).

Resizing an array

You can change the size of an array by using the Resize command.

MyArray Resize 5

If MyArray was [1,2,3,4,5,6], MyArray will now be [1,2,3,4,5] If MyArray was [1,2,3,4], MyArray is now [1,2,3,4, ]

Setting a value within an array

You can change the value within an array by using the Set command:

MyArray set [ArrayPosition, Value]

so

["Fred", "Barney", "Wilma", "Thelma"] set [3, "Dino"]

will produce

["Fred", "Barney", "Wilma", "Dino"]

You can use Set to delete individual elements by the following trick:

Set the element you want to change to something recognizable and unique, like “DELETEME”. Subtract [“DELETEME”] from the array.

MyArray set [3, "DELETEME"]
MyArray = MyArray - ["DELETEME"]

Will get rid of “Dino”

Performing actions on elements in an array

Count

“condition” Count MyArray

“condition” is in quotes, the condition to check for.

Use the reserved variable _x to take the place of the element of the array. This will return a numeric value.

So,

"_x > 0" count MyArray

will return a value of 1

Note that the condition is in quotes. Local variables will not work inside the condition, nor will absolute string values (because of the quotes). So convert local variables to globals before checking them with Count, and convert absolute string values to variables as well. So in order to count the appearances of “Barney” in an array, we'd do:

BarneyName = "Barney"
"_x == BarneyName" Count SAmpleArray

ForEach works similarly, but allows you to execute commands on each element.

For example, if I had a trigger named Deathcloud, set to (West Present), condition “This and Time > 1200, I could put this in the activation field:

"_x setdammage 1" ForEach thislist

(thislist is the array of units capable of activating the presence trigger). This would go through each of the units in the array thislist and kill them.

Reserved arrays (not a complete list)

thislist When in a trigger's fields, an array of the units who currently satisfy the conditions of the trigger.
_this The array passed to a script via the exec command.

That's right, in:

[] exec "MyScript.sqs";

The [] is not just for show – it's a null array. Put something in there and you can access it via _this

_this does not have to be an array, for you can pass a single value to a script. But good scripting disciplines requires that it be an array.

For scripts started via the addaction command, _this has the following value:

[unit to whom action is attached, unit that called action, number of action on unit to whom action is attached]

Useful Arrays

list triggername: Calls up the array of units that currently satisfy a trigger's conditions. This is useful for area detection and the rest.
units groupname: Gives an array of units in a given group.

Metavariables

Metavariables are variables whose name in an instruction or operation is itself variable. Metavariables in OFP scripting are extremely rare (As I write this, I know of nobody else who uses them), but they are extremely powerful.

What we do is take advantage of the transformation rules above for extremely powerful and fast results.

“Count” and “ForEach” process strings, turning them into instructions and operations respectively.
“Format” turns any variable into a string.

So, for instance, to create a series of variables, starting with dude0, that corresponds to the (variable) number of units in the player's group, we can use this simple instruction: (note that double quotes ”“ can be used to signify quotes within quotes, beyond that level we have to use global variables)

tempnum = 0
"Format [""dude%1 = units group player select tempnum"", tempnum]; ForEach [0]; tempnum = tempnum + 1" ForEach units group player

Or to trap the laser designator dot:

Make a trigger called “detectlaser”, and make it as big as the area you want to detect the laser in (like the whole map). Set the trigger to “Anybody Present Repeatedly” (an untested improvement is “Civilian Present Repeatedly”, and put in the condition field:

this && "LaserTarget" CountType list detectlaser > 0

In the on activation field, put:

"Format [""LaserTarget%1 = _X"", ""LaserTarget"" CountType [_x]] ForEach [_x]" ForEach list DetectLaser; LaserInitialized = True

On deactivation, put:

LaserInitialized = False

Then when LaserInitialized is TRUE, metavariable LaserTarget1 will indicate the Laser Designator Dot.

ofp/missions/variables_arrays.txt · Last modified: 2007-07-13 01:27 (external edit)