The Open Source OFP Trig Guide (version 0.1)

by toadlife

This short tutorial will explain how trigonometry can be used to do many useful things in your Operation Flashpoint scripts. If you are a newbie scripter, may I suggest Johan Gustafsson’s Scripting Tutorial (2nd edition).

This guide is "open source", and may be modified by anyone at any time. I just ask that someone who wants to add to it sends their additions to me, so I can verify the content and resubmit it.

**Finding
a Location/Position Using an Object’s Position and Direction**

Lets start with a picture. Below is a diagram of Desert Island, the popular testing ground in Operation Flashpoint. The example script I am going to use is the air strike/targeting system script, that I wrote. Take a look at the picture below and then read on.

In the picture above, the green dot represents a unit. This could be any unit, such as a soldier, tank, helicopter, or jeep. The “24” you see near the unit is the angle (0-360) that it is facing, and the “300” is a predetermined distance – one side of the triangle you see in the picture. The green X is the spot that we want the coordinates of. The X and Y are the two unknown sides of the triangle we will use to calculate the target’s position.

Lets start by getting
the units position (green dot). We would do this in a script with the command
‘getpos unit’. For this example, we will pretend that the unit’s position
on the map is [2341,3642,0]. The numbers are explained below.

2341 = unit’s X position (East/West)

3642 = unit’s Y position (North/South)

0 = unit’s Z position (Altitude – Not used in this
example)

Here is an example script that will extract these
numbers for you:

_unitposition = getpos unit

_uposx = _unitposition select 0

_uposy = _unitposition select 1

_uposz = _unitposition select 2

There are three sides
to a right triangle, the opposite, the adjacentand the hypotenuse. To find
the target’s location, we must first find the length of the opposite and
adjacent sides of the triangle. We already know the hypotenuse – this is
the predetermined distance from the unit to the target (300).

The length of the oppositeside of the triangle (X)
is found using the formula below:

opposite = sin(24) x 300

The length of the adjacentside of the triangle (Y)
is found using the formula below:

adjacent = cos(24) x 300

Here are the results of the two formulas above:

sin(24) x 300 = 122 (rounded)

cos(24) x 300 = 274 (rounded)

**Lets have a look at our triangle
once we know the length of all of the sides:**

From here, finding the target’s coordinates is a matter
of adding two sets of numbers together.

The target’s X position is found by adding the unit’s
X position to the length of the opposite side of the triangle. So…

Targetsxposition = 2341 + 122

Targetsxposition = 2463

The target’s Y position is found by adding the unit’s
Y position to the length of the adjacent side of the triangle. So…

Targetsyposition = 3642 + 122

Targetsyposition = 3916

Now we have the target’s true position on the ground.
It is:

[2463,3916,0]

Below is part of my airstrike script that uses these
formula’s. I’ve inserted comments througout the script, that try to explain
what it happening. The script is included with this document in the scriptsfolder.

START “callstrikes.sqs”

;## Script by toadlife (toadlife@hotmail.com) http://toadlife.tripod.com/ofpmissions.html

; the unit that will select the target and calls the strikes

unit = _this select 0

; the default starting distance (hypotenuse of “virtual triangle”) - a public variable

dis = _this select 1

; public variable used later in the script ( @(findtarget == 1) )

findtarget = 0

; add targeting system actions to middle mouse button – these actions set the the two

; public variables 'dis' and 'findtarget'

unit AddAction ["Find Target","findtarget.sqs"]

unit AddAction ["Increase Distance","idis15.sqs"]

unit AddAction ["Decrease Distance","ddis15.sqs"]

; ## Wait until target=1, then proceed

#targetloop

findtarget = 0

~0.1

; wait until the public variable 'findtarget' equals 1, and then move on

@(findtarget == 1)

; set the target to nothing; in other words, no target

btarget = objnull

#find

; get the direction of the unit; this is the angle we know in the example above(24)

_udir = getdir unit

; get the position of the unit; [2341,3642,0] in the example above

_upos = getpos unit

; extract the units X position (2341)

_cposx = _upos select 0

; extract the units Y position (3642)

_cposy = _upos select 1

; extract the units Z position (0)

_cposz = _upos select 2

~0.1

; ## Find a target

; private variable used later the reset the distance if no target is found

_sdis = dis

#target

; find the nearest object at the calculated position.

; **look at this part and try and try to match the formulas in the example**

; Calculation of the X position = _cposx + ((sin _udir) * dis)

; Calculation of the Y posittion = _cposy + ((cos _udir) * dis

btarget = NearestObject [_cposx + ((sin _udir) * dis), _cposy + ((cos _udir) * dis), 0]

goto "command"

; Check target

#command

; if the target is NOT alive (no object was found or object is detroyed)

; then goto the #adjust section

?(not alive btarget): goto "adjust"

; if the object cannot fire (an inanimate object like a rock or tree)

; then goto the #adjust section

?(!CanFire btarget): goto "adjust"

; display the target in a hint box

hint format ["Target: %1", btarget]

~0.02

; go back to the start (#targetloop)

goto "targetloop"

; adjustment made if no target found

#adjust

; if the distance is 600 or greater then give up and go to #notarget

?(dis >= 600): goto "notarget"

; add 1 to the distance and check again for a target

; (this adjustment will automatically happen until the distance is 600 or more)

dis = (dis + 1)

goto "target"

; targetfinder has scanned out to 600+ meters and still did not find a target

#notarget

; set the target to nothing; in other words, no target

btarget = objnull

; reset the distance to the starting distance (see '_sdis' above)

dis = _sdis

Hint "No target found"

; go back to the start (#targetloop)

goto "targetloop"

END “callstrikes.sqs”

The above script is not the entire air strike/targeting
system, but just one of 5 separate scripts that work together to give the
player a dynamic Air strike/Targeting system, probably similar to the one
that will be included in the 1.30 patch for Operation Flashpoint (they stole
my idea dammit!).

If you want to examine the entire targeting system,
you can download it at the Operation Flashpoint
Edidting Center.

**A
Challenge!**

Now that you’ve gone through
and fully understand the above example, why not test your newly acquired
knowledge with a little challenge.

Write a script that will
make one unit follow another unit and have the follower always stay at one
side (behind, in front of, to the left, to the right, ect.). Examine the
picture below to get an idea of what you need to do. An answer (my example)
is included with this document in the scriptsfolder.

**Another
example script**

After you are done with (or have given up on) the challenge, check out the third script included with this tutorial, called “watch.sqs”. It is a script that emulates the “Watch Direction” command that you can give your troops during the singleplayer game.

**-toadlife
out**