Flying point-to-point (in 3D)

byaussy

Member
I've worked up a basic point-to-point flying script, and wanted to toss it out there for feedback. No, it doesn't integrate with the nav lib yet, but it does allow you to automate some of those annoying overland flights (such as through EJ).

To try it out, save these two files below in your Innserspace/Scripts directory, then in the console type - run flighttest

The flighttest.iss script will fly you from where you port into EJ all the way across the zone to the steps at the entrance to Temple of the Faceless. Feel free to copy this script and replace the navigation points to fly other places.

OK, so the site won't allow me to attach .inc files, so I'm going to post them as code blocks:

First the Flight Routines - save this as flight.inc
Code:
/********************************************************************************************************************/
/* Flight routines                                                                                                  */
/*                                                                                                                  */
/* Description:                                                                                                     */
/* Will fly point to point in 3 dimensions using a combination of move forward (up), tilt camera up (home), tilt    */
/* camera down (end), fly up (pgup) and fly down (pgdn).  The FlyTo method assumes the character is already in      */
/* flight, and does not resume flight in the event that the character stops flying for any reason.                  */
/*                                                                                                                  */
/* If you are not already in flight, you should call the StartFlying method to put you in the air before calling    */
/* FlyTo. Here's a quick example of the usage:                                                                      */
/*                                                                                                                  */
/*    call StartFlying                                                                                              */
/*    call FlyTo -150 83 211                                                                                        */
/*    call FlyTo 940 185 452                                                                                        */
/*    call FlyTo -1253 285 558                                                                                      */
/*    call StopFlying                                                                                               */
/*                                                                                                                  */
/* LIMITATIONS:                                                                                                     */
/* Be sure you are well clear of the ground before calling FlyTo (you can use the StartFlying method to get airborn */
/* Be sure that your flight path keeps you well clear of the ground.  If you make contact with the ground, you      */
/* will stop flying, and run forward looking straight up until you get to your X,Z destination.                     */
/*                                                                                                                  */
/* Don't make the destinations too close together (especially the first one).  It takes a little time to pan the    */
/* camera up and down (there's no way to set the up/down camera angle directly). If your destination is very close, */
/* and your camera is pointed the wrong direction, you might not get the camera tilted up in time to reach your     */
/* target altitude (Y-value) before you reach your X,Z destination.                                                 */
/********************************************************************************************************************/


#ifndef _FLIGHT_MOVE_KEYS_
#define _FLIGHT_MOVE_KEYS_ 2


#define _FORWARD_ w
#define _BACKWARD_ s
#define _STRAFELEFT_ q
#define _STRAFERIGHT_ e
#define _AUTORUN_ "num lock"
#define _TURNLEFT_ a
#define _TURNRIGHT_ d
#define _FLYUP_ home
#define _FLYDOWN_ end
#define _PANUP_ "page up"
#define _PANDOWN_ "page down"


variable string forward=_FORWARD_
variable string backward=_BACKWARD_
variable string strafeleft=_STRAFELEFT_
variable string straferight=_STRAFERIGHT_
variable string autorun=_AUTORUN_
variable string turnleft=_TURNLEFT_
variable string turnright=_TURNRIGHT_
variable string flyup=_FLYUP_
variable string flydown=_FLYDOWN_
variable string panup=_PANUP_
variable string pandown=_PANDOWN_


#endif /* _FLIGHT_MOVE_KEYS_ */


/*******************************************************************************************************************/
/* FlyTo                                                                                                           */
/*                                                                                                                 */
/* Syntax:                                                                                                         */
/*     call FlyTo X Y Z [horizontalPrecision] [verticalTiltPrecision]                                              */
/*                                                                                                                 */
/* Description:                                                                                                    */
/* Will fly to the destination point using a combination of move forward (up), tilt camera up (home), tilt         */
/* camera down (end), fly up (pgup) and fly down (pgdn).  This method assumes the character is already in flight,  */
/* and does not resume flight in the event that the character stops flying.                                        */
/*                                                                                                                 */
/* Parameters:                                                                                                     */
/* tX, tY, tZ:  coordinates of destination                                                                         */
/* precision3D: once we're within this distinace of our destination (horizontally) we have 'arrived'.              */
/*              default is 4.                                                                                      */
/* tiltLag:     this is used to tweak the camera panning precision.  If you're seeing your camera jerk up and down */
/*              while flying, increase this number.  To tighten up the vertical precision, make this smaller.      */
/*              default is 3.                                                                                      */
/*                                                                                                                 */
/* LIMITATIONS:                                                                                                    */
/* Be sure you are well clear of the ground before calling this (you can use StartFlying method below)             */
/* Be sure that your flight path keeps you well clear of the ground.  If you make contact with the ground, you     */
/* will stop flying, and run forward looking straight up until you get to your X,Z destination.                    */
/*                                                                                                                 */
/* Don't make the destinations too close to (especially the first one).  It takes a little time to pan the camera  */
/* up and down (there's no way to set the up/down camera angle directly). If your destination is very close, and   */
/* your camera is pointed the wrong direction, you might not get the camera tilted up in time to reach your        */
/* target altitude (Y-value) before you reach your X,Z destination.                                                */
/*******************************************************************************************************************/
function FlyTo(int tX, int tY, int tZ, int precision3D = 4, int tiltLag = 3)
{
    variable float totalHorz = 0        /* total straight-line distance in the X,Z plane */
    variable float totalVert = 0        /* total vertical distance (in the Y direction) */
    variable float tiltSave = 0         /* saved tilt (elevation) angle */
    variable bool tiltLocked = FALSE    /* tilt angle locked? yes/no */
    variable float vertDist = 0         /* remaining vertical distance (in the Y direction) */
    variable float horzDist = 0         /* remaining straight line distance in tye X,Z plane */
    variable float vertVelocity = 0     /* instantaneous vertical component of velocity */
    variable float horzVelocity = 0     /* instantaneous horizontal (in the X,Z plane) component of velocity */
    variable float currentTilt = 0      /* current angle of elevation (above or below the horizon) of the camera */
    variable float targetTilt = 0       /* target angle of elevation, based on angle to destination */
    variable float tiltError = 0        /* instantaneous difference between desired and actual tilt */


    variable bool tiltingUp = FALSE
    variable bool tiltingDown = FALSE
    variable bool flyingUp = FALSE
    variable bool flyingDown = FALSE
    variable bool moving = FALSE


    echo FlyTo: Flying To ${tX}, ${tY}, ${tZ}


    ;// calculate distance from ME to my destination.  
    ;// I'll need both the horizontal component and the vertical component
    horzDist:Set[${Math.Distance[${tX},${tZ},${Me.X},${Me.Z}]}]
    vertDist:Set[${Math.Calc[${tY}-${Me.Y}]}]
    totalHorz:Set[${horzDist}]
    totalVert:Set[${vertDist}]


    ;// if we're not already at our horizontal destination, start moving
    if ${horzDist} > ${precision3D}
    {
        do
        {
            if ${QueuedCommands}
            {
                ExecuteQueued
            }


            Face ${tX} ${tZ}
            if (${horzDist}>${precision3D})
            {
                if !${moving}
                {
                    moving:Set[TRUE]
                    EQ2Press -hold up
                    wait 1
                }
            }
            else
            {
                if ${moving}
                {
                    echo FlyTo(): Arrived at ${Me.X}, ${Me.Y}, ${Me.Z}
                    moving:Set[FALSE]
                    EQ2Press -release up
                    wait 1
                }
            }
            
            ;// read our components of velocity
            horzVelocity:Set[${Math.Sqrt[(${Me.ToActor.Velocity.X}*${Me.ToActor.Velocity.X})+(${Me.ToActor.Velocity.Z}*${Me.ToActor.Velocity.Z})]}]
            vertVelocity:Set[${Me.ToActor.Velocity.Y}]


            ;// calculate current tilt by extracting the vertical component of our current velocity
            if ${horzVelocity} > 0
            {
                currentTilt:Set[${Math.Atan[${vertVelocity}/${horzVelocity}]}]
            }
            else
            {
                currentTilt:Set[0]
            }


            ;// calculate target tilt based on the elevation angle between our current location and
            ;// the destination point
            if ${horzDist} > 0
            {
                targetTilt:Set[${Math.Atan[${vertDist}/${horzDist}]}]
            }
            else
            {
                targetTilt:Set[0]
            }


            ;// if we're at least halfway to the destination, we'll cage-lock 
            ;// the tilt angle to prevent histeresis near the destination
            ;// this will prevent any more large changes to tilt angle
            if ${Math.Calc[${horzDistance}*2]} > ${totalHorz} && !${tiltLocked}
            {
                tiltSave:Set[${currentTilt}]
                tiltLocked:Set[TRUE]
            }


            ;// if we have a tilt error, and it's greater than tiltLag, we neeed to correct it 
            ;// press and hold either HOME(tilt camera up) or END(tilt camera down) to begin 
            ;// the correction
            tiltError:Set[${Math.Calc[${targetTilt}-${currentTilt}]}]


            ;// if we need to pan up and we're not cage-locked
            ;// or we're cage-locked but the correction is minor
            if (${tiltError} > ${tiltLag}) && !${tiltingUp} && !(${tiltLocked} && ${tiltError}>${tiltLag})
            {
                ;// in case we were panning down during the previous loop
                if ${tiltingDown}
                {
                    tiltingDown:Set[FALSE]
                    press -release _PANDOWN_
                    ;waitframe
                }
                ;// tilt camera up to correct the vertical flight path error
                tiltingUp:Set[TRUE]
                press -hold _PANUP_
                waitframe
            }


            ;// if we need to pan down and we're not cage-locked
            ;// or we're cage-locked but the correction is minor
            if (${tiltError} < (1-${tiltLag})) && !${tiltingDown} && !(${tiltLocked} && ${tiltError}>${tiltLag})
            {
                ;// in case we were panning up during the previous loop
                if ${tiltingUp}
                {
                    tiltingUp:Set[FALSE]
                    press -release _PANUP_
                    ;waitframe
                }
                ;// tilt camera down to correct the vertical flight path error
                tiltingDown:Set[TRUE]
                press -hold _PANDOWN_
                waitframe
            }


            ;// if tiltError is within precision (tiltLag)
            ;// or if we're almost at our destination
            ;// or if cage-lock is active
            ;// stop panning up/down
            if (${tiltError} < ${tiltLag} && ${tiltError} > 1-${tiltLag}) || ${horzDist} < ${Math.Calc[${precision3D}*3]} || (${tiltLocked} && ${tiltError}>${tiltLag})
            {
                if ${tiltingUp}
                {
                    tiltingUp:Set[FALSE]
                    press -release _PANUP_
                }
                if ${tiltingDown}
                {
                    tiltingDown:Set[FALSE]
                    press -release _PANDOWN_
                }
                waitframe
            }


            horzDist:Set[${Math.Distance[${tX},${tZ},${Me.X},${Me.Z}]}]
            vertDist:Set[${Math.Calc[${tY}-${Me.Y}]}]
        } 
        while ${Math.Distance[${tX},${tZ},${Me.X},${Me.Z}]} > ${precision3D}
    }


    ;// release camera tilt up/down and moving keys since we're at our horizontal destination
    if ${tiltingUp}
    {
        tiltingUp:Set[FALSE]
        press -release _PANUP_
    }
    if ${tiltingDown}
    {
        tiltingDown:Set[FALSE]
        press -release _PANDOWN_
    }
    if ${moving}
    {
        moving:Set[FALSE]
        EQ2Press -release up
    }
    waitframe


    ;// if we're already at our horizontal destination, but not yet at our vertical destination, use flyup/flydown to get there
    while ${vertDistance}>${precision3D}
    {
        if ${QueuedCommands}
        {
            ExecuteQueued
        }


        echo FlyTo: Vertial Error remains at Destination: Target altitude is ${tY}, Actual altitude is ${Me.Y}


        vertDist:Set[${Math.Calc[${tY}-${Me.Y}]}]
        if (${vertDistance} > ${precision3D}) && !${flyingUp}
        {
            if ${flyingDown}
            {
                flyingDown:Set[FALSE]
                press -release _FLYDOWN_
            }
            flyingUp:Set[TRUE]
            press -hold _FLYUP_
        }
        if (0-${vertDistance} > ${precision3D}) && !${flyingDown}
        {
            if ${flyingUp}
            {
                flyingUp:Set[FALSE]
                press -release _FLYUP_
            }
            flyingDown:Set[TRUE]
            press -hold _FLYDOWN_
        }
        waitframe
    }


    ;// release Fly Up and/or Fly Down keys
    if ${flyingUp}
    {
        flyingUp:Set[FALSE]
        press -release _FLYUP_
    }
    if ${flyingDown}
    {
        flyingDown:Set[FALSE]
        press -release _FLYDOWN_
    }
    waitframe
}


function StartFlying()
{
    press -hold _FLYUP_
    wait 10
    press -release _FLYUP_
}


function StopFlying()
{
    press -hold _FLYDOWN_
    wait 5
    do
    {
        press -hold _FLYDOWN_
        wait 1
    }
    while ${Me.ToActor.Velocity.Y} < 0
    press -release _FLYDOWN_
}
And the example script - save this as flighttest.iss
Code:
#include "${LavishScript.HomeDirectory}/Scripts/Buddy/flight.inc"

/* This will fly you from where you zone into EJ (from Feerrot) to the steps at the entrance of Temple of the Faceless */
function main(int _Skip=0)
{
    call StartFlying
    call FlyTo -150 83 211
    call FlyTo -940 185 452
    call FlyTo -1253 285 558
    call FlyTo -1695 285 889
    call FlyTo -1861 275 1030
    call FlyTo -2041 275 1123
    call FlyTo -2154 275 1043
    call FlyTo -2217 275 944
    call FlyTo -2204 250 874
    call FlyTo -2161 230 765
    call StopFlying
}
 
Last edited:
Top Bottom