Home   Help Search Login Register  

Author Topic: findNearestWaypoint (function) (ACCEPTED)  (Read 3711 times)

0 Members and 1 Guest are viewing this topic.

Offline Wolfrug

  • Addons Depot
  • Former Staff
  • ****
  • Official OFPEC Old Timer
findNearestWaypoint (function) (ACCEPTED)
« on: 20 Sep 2007, 20:29:53 »
Hello all!

In working a bit on my mission, I realised I needed a function for determining the closest waypoint to any particular map spot. So what I did was I...erm...created one.  ;) I suck at math, I really do, and I'm not generally too skilled with all kinds of embedded commands and whatnot. Also I'm not very skilled at properly setting up things (with tabs and {'s and ]'s all in the right place), so it might not be the fastest, most efficient, nor the prettiest way of doing this...but well, it's not a particularly complicated thing it does anyway.

***********
findNearestWaypoint.sqf function:

Input 2d position (from onMapSingleClick or waypointPosition for instance).
Input name of trigger that covers wider area you want checked/is activated by side you want checked (or Anybody if you don't care).
(Optionally input minimum distance the waypoint has to be from the 2d position for it to return anything)

Output : waypoint (in waypoint format, i.e. [GroupName, WaypointNumber]) closest to position input.
************

I'm sure Mandoble or someone could rewrite this script in about 15 minutes to only take up three lines or so, but what the heck.  :cool2: They're busy doing other things. Basically what the function does is:

1) Create list from trigger of all possible units within the trigger radius.
2) Determine groups by finding out which are the group leaders of the units
3) Create an array of all the waypoints of all the groups
4) Check which waypoints are within the needed distance (by default, 1000m from the 2d position)
5) Check which waypoint is closest.
6) Output closest waypoint.

Use:

preload the file by calling it for instance in the init.sqs with:

RUG_FNWP = compile loadFile "findNearestWaypoint.sqf"

Create a trigger, give it an area corresponding to the WHOLE area of -units- you want checked, and make it Activated By: (SIDE you want checked - or anybody).

Call the function by inputting the two necessary pieces of data: a 2d position ([x,y]) + name of the trigger created above. Example: hint format ["%1", [waypointPosition (waypoints Player select 1), TriggerName] call RUG_FNWP]

Enjoy!

Example mission + readme attached below. Enjoy!  :good:

Wolfrug out.


OFPEC DOWNLOAD
« Last Edit: 11 Aug 2009, 16:25:48 by hoz »
"When 900 years YOU reach, look as good you will not!"

Offline hoz

  • OFPEC Site
  • Administrator
  • *****
Re: findNearestWaypoint (function)
« Reply #1 on: 20 Sep 2007, 20:57:50 »
Why not dynamically create a trigger from the position of the passed to the function. This makes it less tedious for the n00b mission maker. You could also to dynamically create the size of the desired trigger area.

I spent days and days on my two functions.   :D
Xbox Rocks

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: findNearestWaypoint (function)
« Reply #2 on: 20 Sep 2007, 21:04:25 »
Ok, got a tricky question, why in your mission you might need to find the closest waypoint to a position (remember, the question itself is tricky :D )?

Offline Wolfrug

  • Addons Depot
  • Former Staff
  • ****
  • Official OFPEC Old Timer
Re: findNearestWaypoint (function)
« Reply #3 on: 20 Sep 2007, 21:21:08 »
@Hoz

This was my original way of doing it, HOWEVER, this turned out to be a bit buggy. Since ArmA 1.08, functions apparently do not support the sleep command any more, and when I dynamically created the trigger I had to put in a whole second's worth of Sleep for the list of units to update properly. So what I did was change it around a bit like this. If you can make it work with a dynamic trigger, then that's cool. :)

@Mandoble

I'm suspecting trickery here. :dry: Hrm. Anyway, it's to do with the Syncronize Waypoint command: I was thinking of letting people synchronize two waypoints by themselves thusly (together with my Squad Control System v.0.2, which will be an updated version of the one found in Operation Dawning Hope). Also I can use it in the same system to manipulate waypoints in other ways (maybemaybe!).

Why? -_- Is there already a way to do this I just haven't noticed?

Wolfrug out.
"When 900 years YOU reach, look as good you will not!"

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: findNearestWaypoint (function)
« Reply #4 on: 20 Sep 2007, 22:25:22 »
Do you mean to sync several waypoints on-the-fly?

Offline Wolfrug

  • Addons Depot
  • Former Staff
  • ****
  • Official OFPEC Old Timer
Re: findNearestWaypoint (function)
« Reply #5 on: 20 Sep 2007, 22:29:37 »
Yes, well. I mean to synch waypoint 1 with waypoint 2, basically. Also, this can be used to, for instance, select other waypoints made visible on the map with i.e. dynamically updating markers and manipulate them.

Several uses. All in the realm of waypoint-adjusting, of course. :) I'll post my SCS once v.02 is done.

Wolfrug out.
"When 900 years YOU reach, look as good you will not!"

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: findNearestWaypoint (function)
« Reply #6 on: 20 Sep 2007, 22:37:37 »
Ok, for that purpose should the player be able to:
- See the groups and the placement of the current waypoints these groups are currently trying to reach?
- See the list of waypoints of each group to ensure the best possible synchronization?
- Be able to cancel an already synced pair of waypoints because a group stopped there waiting for a another would ensure the anihilation of the waiting group?

Offline Wolfrug

  • Addons Depot
  • Former Staff
  • ****
  • Official OFPEC Old Timer
Re: findNearestWaypoint (function)
« Reply #7 on: 21 Sep 2007, 08:29:43 »
Heh. Many questions.

Basically what I'm working with is, as mentioned, my own little Squad Control System, which is an ugly bunch of scripts built around the fact that you can move waypoints defined as "Always Visible" in-game the same way you can in-editor. So I have one script that checks the waypoints for movement (when moved, they need to be "activated" again by simply moving them to their present location once, otherwise the AI won't realise the WP is moved), which also updateds which waypoint was the latest to be moved, then I have one script which adds new waypoints, and a dialog which allows you to manipulate the waypoint to your heart's content (i.e., type, combat mode, behaviour, formation, even timeout). Also, I've stolen Spooner's script (based on your math) which allows for the drawing of a line between two points: this allows me to draw lines between the dynamically moved/created WPs. Furthermore, I have a script which moves a marker (named after the string of the WP itself - thus unique) with each waypoint, which also tells the player the number of the waypoint. Colours are also definable, to allow for easy distinction between waypoints. Finally I have a simple "squadtrack" script which updates the current location of the group leader with a marker.

So yes: in the integrated system of the SCS, seeing other waypoints is easy, and by using the drawLine function, I can even give a visual representation of which waypoints are synchronized.

The problem lies in the french line number three there.

Quote
- Be able to cancel an already synced pair of waypoints because a group stopped there waiting for a another would ensure the anihilation of the waiting group?

-> I tried various ways of using the synchronizeWaypoint command to UNsynchronize the waypoint: with little success. I.e., synchronize waypoint with itself/with nothing did not work. This does mean that there's no easy way to "cancel" the synchronization.
-> Current solution: dynamically create a "Switch" type trigger on prompting from the player, which will cancel out the waypoint itself, thus dissolving the Synchronization. Alternatively I could just delete the waypoint, since the effect is basically the same.  :dry: Of course just being able to de-synchro would be the best, but...  :confused:

Picture attached below to illustrate.

Wolfrug out.
"When 900 years YOU reach, look as good you will not!"

Offline hoz

  • OFPEC Site
  • Administrator
  • *****
Re: findNearestWaypoint (function)
« Reply #8 on: 25 Sep 2007, 03:09:14 »
Quote
Since ArmA 1.08, functions apparently do not support the sleep command any more, and when I dynamically created the trigger I had to put in a whole second's worth of Sleep for the list of units to update properly.

I'm pretty sure that sleep will work in a function. I had a similar problem where my function was running so fast that it was returning the information before the hud was fully initialized (hint, sidechat). If I made it sleep for 1 sec and then I was able to get the display.
Xbox Rocks

Offline Wolfrug

  • Addons Depot
  • Former Staff
  • ****
  • Official OFPEC Old Timer
Re: findNearestWaypoint (function)
« Reply #9 on: 25 Sep 2007, 08:17:26 »
There is a different between functions and scripts.  :D

Quote
Functions should be used for any processes where the result or calculation done in the function is important. This result or calculation should be made in the least time possible. They are unlike scripts, where timing is important.

BIKI on Functions
BIKI on Scripts

And finally, BIKI on Sleep(read the comments section). Basically if you want to use the "compile loadfile" commands (which I do want to use), sleep cannot be used in the script body.

However, turning this function into a script which does the same, and doesn't need the ready-made trigger, is fairly easy, since that is what it was designed for at start. Simply have it make the trigger at the start, and instead of inserting i.e. the name of the trigger from which the list is to be taken, insert something else such as its radius (in an array, if you want). Then simply change the line which says "_allunits = list _triggerName" (or somesuch) into the name of your newly created trigger.

And also remember to put the sleep 1.0; after making the trigger, or the list might not have time to update.  :)

(and finally remember to run it with i.e. execVM, and not try to compile it beforehand).

 :good:

Wolfrug out.
"When 900 years YOU reach, look as good you will not!"

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: findNearestWaypoint (function)
« Reply #10 on: 25 Sep 2007, 08:39:34 »
use spawn instead of call and you will be able to use sleep, but spawn doesnt return values.

Offline Wolfrug

  • Addons Depot
  • Former Staff
  • ****
  • Official OFPEC Old Timer
Re: findNearestWaypoint (function)
« Reply #11 on: 25 Sep 2007, 11:43:37 »
 :)

This is a function because I want to return one single thing: the closest waypoint.

I do not want to do this by using global variables (i.e., a script which at the end of itself defines a global variable GlobalVar = _nearestwaypoint), nor do I want to integrate other scripts into this (i.e., at the end of the script put something like [_nearestwp] execVM "function.sqf"). I want to call it, and use it within the code itself. Which is the purpose of functions.

I am aware of the alternative methods of calling .sqf scripts, but unless you can point me at one which allows me to BOTH return a value AND use the sleep command, I don't see the problem.  :) If you definately want to use a dynamic trigger, integrate the function into a normal .sqf or .sqs script, which first creates the trigger, sleeps one second, calls the function, waits until it has finished running, and then deletes the waypoint. Same result.

Presently, I'm also using this same function to,by means of alt-clicking on the map, select the waypoint closest to the click for editing. I know there aren't -that- many other uses for this function, but...well...that's what it does. It returns the closest waypoint. C'est tout. :)

Wolfrug out.
"When 900 years YOU reach, look as good you will not!"

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re: findNearestWaypoint (function)
« Reply #12 on: 25 Sep 2007, 17:02:53 »
A discussion on the BIS forums indicated you can use sleep in a function, but only if the function is called from a script that is itself called from execVM. I'll dig out the thread in a moment.

edit:I believe it is in this thread somewhere if you have an hour to kill...
« Last Edit: 25 Sep 2007, 17:10:19 by Mr.Peanut »
urp!