Home   Help Search Login Register  

Author Topic: [ACCEPTED] Mandohileroute  (Read 7273 times)

0 Members and 1 Guest are viewing this topic.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
[ACCEPTED] Mandohileroute
« on: 07 Jun 2006, 00:34:05 »
The problems:
1 - Long range routes for air units timeout, and the units do not move to destination.
2 - The destination is reached when the unit is closer than 100m.
3 - If you command the helicopter to land, it will land at any position but the destination, in some cases really far away.

So, for example, you cannot command an helicopter to cross an island from one extreme to another and land at the very exact center of the roof of a building.

To solve these problems:

Code: [Select]
;mandoheliroute.sqs by Mandoble
;
;Allows long flying traves avoiding timeouts while resolving routes.
;Allows accurate landings at destination position with only 1.5m possible deviation.
;Allows accurate landings even as close as 2 meters away from the taking off point
;
;Arguments:
;Helicopter unit
;Final position
;Maximum length in meters of each travel segment (2000-4000 are safe values)
;Flying height (-1 if does not apply, maximum allowed is 80m)
;Maximum allowable damage before ejecting
;Final aproach at limited speed or not (true/false)
;Script to be executed upon arrival or after landing (receives helicopter as argument), "" if not needed.
;Script to be executed when ejecting (receives helicopter as argument), "" if not needed.
;Land true/false
;Descend velocity in m/s if land is true
;Minimum alt in meters to stop engines if land is true (>=0.2)
;Camera following helicopter true/false
;
;Notes:
;"mandoheliroute" global variable is updated with the following values:
; 1 - Helicopter is moving to destination
; 2 - Helicopter has reached destination
; 3 - Helicopter has landed at destination (only if land parameter is true)
; 4 - Helicopter got too much damage, eject script executed if provided.
;
;Example:
;heli1 will move from current position to "mk_land" marker pos in "steps" of 2Km and at a height of 40m
;If heli1 gets more than 0.5 damage, ejectnow.sqs will be executed
;Once the destination is reached, heli1 will land, descending at 4m/s and will stop its engine
;when closer to 0.2m of any surface (ground, sea, roofs), once landed and stopped, landed.sqs will be executed.
;The camera will follow heli1 until fully landed.
;[heli1,getMarkerPos "mk_land",2000,40,0.5,false,"landed.sqs","ejectnow.sqs",true,-4,0.2,true]exec"mandoheliroute.sqs"

_heli          = _this select 0
_finpos        = _this select 1
_length        = _this select 2
_height        = _this select 3
_maxdmg        = _this select 4
_slowaproach   = _this select 5
_arrivalscript = _this select 6
_ejectscript   = _this select 7
_land          = _this select 8
_veldown       = _this select 9
_minalt        = _this select 10
_camera        = _this select 11

?_height > 80:_height = 80
?_maxdmg > 0.9:_maxdmg = 0.9
?_camera: _heli switchCamera "EXTERNAL"

;Global to use from external scripts, indicates the helicopter is moving to destination
mandoheliroute = 1

_pilot = driver _heli
_pos1 = [getPos _heli select 0,getPos _heli select 1,0]
_log1 = "logic" camCreate _pos1
_log2 = "logic" camCreate _finpos
_log3 = "logic" camCreate [0,0,0]
_dist = _log1 distance _log2
_ang = ((_finpos select 0) - (_pos1 select 0)) atan2 ((_finpos select 1) - (_pos1 select 1))
_steps = _dist / _length
_i = 0
_pos = _pos1

?_height > 0:_heli flyInHeight _height;_pilot Move getPos _heli

#move
_dist = _log1 distance _log2
?_dist > _length:_dist = _length
_pos = [(_pos select 0) + sin(_ang)*_dist,(_pos select 1) + cos(_ang)*_dist]
_log3 setPos _pos
?_height > 0:_heli flyInHeight _height
_pilot Move _pos
~1
@((_heli distance _log3) < 1000) || (damage _heli > _maxdmg)
?(damage _heli > _maxdmg): goto "eject"
?(_heli distance _log2) < 1050: goto "goal"
_log1 setPos _pos
_i = _i + 1
?_i < _steps:goto "move"

#goal
?_height > 0:_heli flyInHeight _height
?_slowaproach:group _pilot setSpeedMode "LIMITED"
_pilot Move _finpos
~1
@(unitReady _pilot) || (damage _heli > _maxdmg) || ((_heli distance _log2)<200.0)
?(damage _heli > _maxdmg): goto "eject"
?((_heli distance _log2) < 200.0) && _land:mandoheliroute = 2;goto "landsequence"
@(unitReady _pilot) || (damage _heli > _maxdmg)
?(damage _heli > _maxdmg): goto "eject"
mandoheliroute = 2
?_arrivalscript != "":[_heli]exec _arrivalscript
#exit
?_slowaproach:group _pilot setSpeedMode "NORMAL"
deleteVehicle _log1
deleteVehicle _log2
deleteVehicle _log3
~5
?_camera: player switchCamera "EXTERNAL"
exit

#eject
mandoheliroute = 4
?_ejectscript != "":[_heli]exec _ejectscript
goto "exit"


#landsequence
?_veldown > -1:_veldown = -4
?_veldown < -6:_veldown = -4
?_minalt < 0.2:_minalt = 0.2
hint "LAND"
?_height > 0:_heli flyInHeight _height
?_height <= 0:_heli flyInHeight 30
_pilot move getPos _heli
@(getPos _heli select 2) > 25
~1
@((unitReady _pilot)||(damage _heli > _maxdmg))
?(damage _heli > _maxdmg): goto "eject"
@abs(speed _heli)<5.0
_posh = getPos _heli
_ang = ((_finpos select 0)-(_posh select 0)) atan2 ((_finpos select 1)-(_posh select 1))
_dir = getDir _heli
_dif = _ang - _dir
_delta = _dif / 100.0
_i = 0
#aim
_dir = _dir + _delta
_heli setVelocity [0,0,0]
_heli setDir _dir
_i = _i + 1
~0.05
?(damage _heli > _maxdmg): goto "eject"
?_i < 100:goto "aim"


_vel = [10*sin(_dir),10*cos(_dir), 0]
_log = "logic" camCreate [_finpos select 0, _finpos select 1, _posh select 2]
_distold = 99999
#move2
_heli setVelocity _vel
_heli setDir _dir
~0.05
?(damage _heli > _maxdmg): deleteVehicle _log;goto "eject"
_dist = _log distance _heli
?_dist < _distold:_distold = _dist;goto "move2"
deleteVehicle _log


_vel = [0,0,_veldown]
#descend
_heli setVelocity _vel
_heli setDir _dir
~0.05
?(damage _heli > _maxdmg): goto "eject"
?(getPos _heli select 2) < _minalt:_heli action ["engine off"];_vel = [0,0,0]
?isEngineOn _heli:goto "descend"


_i = 0
#stop
_heli setVelocity _vel
_heli setDir _dir
~0.05
_i = _i + 1
?(damage _heli > _maxdmg): goto "eject"
?_i < 100:goto "stop"
mandoheliroute = 3
?_arrivalscript != "":[_heli]exec _arrivalscript
goto "exit"

To test it quick, create a mission using Nogova island and do the following:
1 - Add the player in front of Lipany's townhall, at the centre of the main square of Lipany (SE of Nogova)
2 - Add an OH-58 helicopter landed at the small island NW of Nogova, coordinates BJ-02 and name it heli1
3 - townshall (object 17732)
4 - The townshall of Nogova is object number 17732, lets try to move the helicopter there. Write the following in the INIT field of the OH-58:
Code: [Select]
heli1 switchCamera "EXTERNAL";driver heli1 move getPos (object 17732)
Now preview the mission. Surprise the OH-58 doesn't move, doesn't even start the engine.
Now go back to the editor and move the helicopter much closer to Lipany, for example two sectors away and preview the mission again. This time the OH-58 starts the engine and moves towards Lipany's towns hall. Certainly it will not stop at the very exact destination position, and, if commanded, it will land outside Lipany's perimeter.

And now lets try the script:
1 - Go back to the editor and place the OH-58 at the original position, SW small island, Bj-02 coordinates.
2 - Change the INIT field code by:
Code: [Select]
[heli1,getPos object(17732),2000,40,0.5,false,"","",true,-4,1,true]exec"mandoheliroute.sqs"3 - Preview the mission and enjoy the travel. This is the final result  ;) :


« Last Edit: 04 Sep 2007, 09:14:00 by bedges »

Offline subroc

  • Members
  • *
iÂ've tested this and it works great!

this would also be great to use for CAS missions, so you dont need to place the choppers "just behind the hill" to get them to do their thing but you could actually place them in an staging area.

as im no big scripter myself i would really like to see a helisupport script suite (CAS/medevac/insertion/evac)
that would only need something like
a chopper named CAS
a chopper named evac
a chopper named Insertion
a chopper named medevac
addAction to a radio


Offline SniperAndy

  • Members
  • *
    • VBS Community
Very nice indeed.
But it seems that the chopper shoots over his target the first time?
Then turns and goes back to land on whatever roof you assigned?
Any way to have him slow done before he gets to the roof and make it on the 1st aproach?

Offline Cold

  • Members
  • *
  • Mission Maker
What I normally do when choppers overshoot their route in my missions is: place a trigger (place the intended DZ or LZ at the center of the trigger) about 200 meters in diameter if the chopper is going normal speed; 400-600 meters if the chopper is going full speed; group the trigger to the helo so that it can be the only thing that activates it and then put "helo1 setspeedmode "limited";

Anyone else do anything like that? I'm sure there's more advanced ways to do it, but this normally fixes my problem.
A leader is best when people barely know he exists, when his work is done, his aim fulfilled, they will say: we did it ourselves. <br />Lao Tzu

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
When you move a chopper but you dont want to land it, the accuracy of the final position is not really important. It will end hovering no farther than 50m of the destination, which is good enough. But if you want to land it, doesnt matter the speed, it will land where it wants, not where you want (unless you use helipads and waypoints). The script solves that problem too, making the chopper to land exactly at the destination position.

Offline SniperAndy

  • Members
  • *
    • VBS Community
well, here your chopper form your script passes his destination first by about 50m. hten he hoovers in the air for about 5 seconds, then he turns, goes back to his LZ and finally lands.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Correct. What the script does is the following:
1 - Resolve the route to destination in segments no larger than indicated distance.
2 - If it needs to land, wait for the chopper speed to be less to 1 km/h.
3 - Align the chopper with the destination landing point (this is not done by the pilot).
4 - Move the chopper object towards the landing destination (this is not done by the pilot).
5 - Descend and stop engines at indicated altitude.


So, it is very accurate in landings, and standar accuracy in airborne moves. To increase accuracy in airborne moves (for the final aproach to the destination point), you may add a change in speed to the chopper, as indicated by Cold.

The last move command before reaching the destination is just after #goal label
Code: [Select]
#goal
?_height > 0:_heli flyInHeight _height
_pilot Move _posfin
~1
@((unitReady _pilot) || (damage _heli > _maxdmg))

To change it:
Code: [Select]
#goal
?_height > 0:_heli flyInHeight _height
group _pilot setSpeedMode "LIMITED"
_pilot Move _posfin
~1
@((unitReady _pilot) || (damage _heli > _maxdmg))
group _pilot setSpeedMode "NORMAL"

That should give you more accuracy for final aproach to destination.
« Last Edit: 08 Jun 2006, 23:08:23 by Mandoble »

Offline SniperAndy

  • Members
  • *
    • VBS Community
Thanks for the quick reply.
I will give this a try tomorrow.
Even if it doesn't work like I was hoping... still one excellent script you made mate.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
How were you hoping the script to work?

Offline SniperAndy

  • Members
  • *
    • VBS Community
Didn't have a chance to check your changes yet you posted above.
I was hoping for the chopper to go to the LZ spot when he aproaches it.
And not going past, hoover, turn and then land.

Put I will look more into this tomorrow.
Also, would I use the same array again to have this Chopper leave the roof again and return to Base after he executed my disembark.sqs? Or should I use the second array in th einit line to call another script to send him home?

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Ah, now I understand. To do what you want is as simple as triggering the landing sequence just after the #goal label. Currently, it waits until the chopper ends its last move command before checking whether it should land or not. The end of the last move command is what causes the small overshots. Triggering the landsequence before this last move command would solve the "problem".

To control the movements and states of the chopper, there is a global variable (as explained in the script heading). You may use this to sync different parallel actions while the chopper is cruising or landing.

Your disembark.sqs script may wait till all cargo units are out and then execute a similar similar script (without the disembark.sqs script) so send the chopper back to home.

All in all, mandoheliroute.sqs is a substitute of doMove, move and land commands for choppers.

Offline SniperAndy

  • Members
  • *
    • VBS Community
thanks again...
I will check it all out and get back to you on this.

Offline Wadmann

  • OFPEC Patron
  • ****
  • I'm the next evolutionary step after a llama!
I have not had a chance to try your script in game (maybe tonight), but I was looking at it a little closer due to SA's concern about overshooting the LZ.

Taking a closer look, I saw this:

Code: [Select]
#goal
?_height > 0:_heli flyInHeight _height
_pilot Move _posfin

I could not find where _posfin is defined, but I could see where _finpos is defined.

Am I missing something obvious here?

Wadmann
Check out my Camouflage Collection! New items added 31 July 2005.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Just modified the script so:
1 - You may choose between fast or slow speed final aproach to destination (as suggested by Cold).
2 - Landing sequence is triggered as soon as you are closer than 200m from destination, so you dont overshoot. If you choose a very fast chopper, you may overshoot by 5-10 meters if slow final aproach is not selected, else you will never overshoot.

Wadmann, you are right, that position is not defined (a type mistake), so the helicopter kept flying to the last "good" position, this is also solved now.

There is a "new" feature, now you may order a chopper to takeoff and land as close as 2 meters away from the take off position, so, routes shorter than 100m are now supported (as long as you set landing to true).

Offline SniperAndy

  • Members
  • *
    • VBS Community
you mind posting the modified script mate?

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
you mind posting the modified script mate?

It is already posted, I modified the original one (the very first post of this topic).

Offline SniperAndy

  • Members
  • *
    • VBS Community
cheers mate,
been away for a week.
looking forward to test the modified script.

Offline MehMan

  • Members
  • *
Sorry for bumping this up, but I gotta say, Mandoble, THANK YOU! You just solved a problem that's been bugging me for a couple of weeks now, grrr, nearly lost my mind, but now it works! THANK YOU.
Shit happens.