internal static async Task <bool> NavigateToLocation(Vector3 location, float precision, bool stopOnFateSpawn)
        {
            var movementParams = new MoveToParameters
            {
                Location          = location,
                DistanceTolerance = precision
            };

            while (Core.Player.Location.Distance(location) > precision)
            {
                if (ActionManager.CanMount == 0 && !Core.Player.IsMounted && IsMountNeeded(Core.Player.Location.Distance(location)) &&
                    ActionManager.AvailableMounts.Any())
                {
                    Navigator.Stop();
                    if (Core.Player.InCombat)
                    {
                        return(true);
                    }

                    await MountUp();
                }

                if (stopOnFateSpawn && await OracleFateManager.AnyViableFates())
                {
                    Navigator.Stop();
                    OracleFateManager.ClearPoi("FATE found.");
                    return(true);
                }

                if (Core.Player.IsDead)
                {
                    OracleFateManager.ClearPoi("Died while moving.");
                    Navigator.Stop();
                    return(true);
                }

                Navigator.MoveTo(movementParams);
                await Coroutine.Yield();
            }

            Navigator.Clear();
            return(true);
        }
        internal static async Task <bool> FlyToLocation(Vector3 location, float precision, bool land, bool stopOnFateSpawn)
        {
            if (!IsFlightMeshLoaded())
            {
                await NavigateToLocation(location, precision, stopOnFateSpawn);

                return(true);
            }

            if (ActionManager.CanMount != 0 && !Core.Player.IsMounted)
            {
                return(false);
            }

            if (!Core.Player.IsMounted)
            {
                if (Core.Player.InCombat)
                {
                    return(false);
                }

                await MountUp();
            }

            // Ensure precision isn't too strong, else we get flip-flopping.
            if (precision < 2f)
            {
                precision = 2f;
            }

            var path = await GenerateFlightPathToLocation(location);

            if (path == null)
            {
                return(false);
            }

            if (!MovementManager.IsFlying)
            {
                await CommonTasks.TakeOff();
            }

            var enumerablePath = path as IList <Vector3> ?? path.ToList();

            foreach (var step in enumerablePath)
            {
                var processedStep = !enumerablePath.Last().Equals(step) ? ProcessFlightStep(step) : step;
                if (Core.Player.Location.Distance(location) < Core.Player.Location.Distance(processedStep))
                {
                    Logger.SendDebugLog("Destination is closer than next hop. Ending navigation early.");
                    break;
                }

                while (Core.Player.Location.Distance(processedStep) > 2f)
                {
                    if (!Core.Player.IsMounted && ActionManager.AvailableMounts.Any())
                    {
                        Navigator.PlayerMover.MoveStop();
                        if (Core.Player.InCombat)
                        {
                            return(true);
                        }

                        await MountUp();
                    }

                    if (!MovementManager.IsFlying)
                    {
                        Navigator.PlayerMover.MoveStop();
                        await CommonTasks.TakeOff();
                    }

                    if (stopOnFateSpawn && await OracleFateManager.AnyViableFates())
                    {
                        Navigator.PlayerMover.MoveStop();
                        OracleFateManager.ClearPoi("FATE found.");
                        return(true);
                    }

                    if (Core.Player.IsDead)
                    {
                        OracleFateManager.ClearPoi("Died while moving.");
                        return(true);
                    }

                    Logger.SendLog("Flying to hop: " + processedStep);
                    Navigator.PlayerMover.MoveTowards(processedStep);
                    await Coroutine.Yield();
                }
            }

            // Move to destination.
            while (Core.Player.Location.Distance(location) > precision)
            {
                Navigator.PlayerMover.MoveTowards(location);
                await Coroutine.Yield();
            }

            Navigator.PlayerMover.MoveStop();

            if (land && MovementManager.IsFlying && await CommonTasks.CanLand(Core.Player.Location) == CanLandResult.Yes)
            {
                await CommonTasks.Land();
            }

            return(true);
        }