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:
;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:
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:
[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
: