예제 #1
0
        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);
        }
예제 #2
0
        internal static async Task <bool> TeleportToClosestAetheryte(FateData fate)
        {
            var aetheryte = await GetClosestAetheryte(fate);

            if (aetheryte.Id == 0)
            {
                Logger.SendDebugLog("No viable aetheryte crystals in this zone.");
                return(false);
            }

            await TeleportToAetheryte(aetheryte.Id);

            if (Core.Player.InCombat)
            {
                OracleFateManager.ClearPoi("We're in combat and need to teleport.");
            }

            return(true);
        }
예제 #3
0
        internal static async Task <bool> NavigateToCurrentFate(bool ignoreCombat)
        {
            OracleFateManager.ReachedCurrentFate = false;
            var currentFate = OracleFateManager.GetCurrentFateData();

            if (currentFate == null || !currentFate.IsValid || currentFate.Status == FateStatus.COMPLETE || currentFate.Status == FateStatus.NOTACTIVE)
            {
                await ClearExpiredFate();

                return(true);
            }

            if (!currentFate.IsValid || currentFate.Status == FateStatus.COMPLETE || currentFate.Status == FateStatus.NOTACTIVE)
            {
                await ClearExpiredFate();

                return(true);
            }

            var cachedFateLocation = currentFate.Location;
            var currentFateRadius  = currentFate.Radius;

            while (Core.Player.Distance(cachedFateLocation) > currentFateRadius * 0.65f || !currentFate.Within2D(Core.Player.Location))
            {
                if (!currentFate.IsValid || currentFate.Status == FateStatus.COMPLETE || currentFate.Status == FateStatus.NOTACTIVE)
                {
                    await ClearExpiredFate();

                    Navigator.Stop();
                    return(true);
                }

                var distanceToFateBoundary = Core.Player.Location.Distance2D(cachedFateLocation) - currentFateRadius;
                if (ActionManager.CanMount == 0 && !Core.Player.IsMounted && IsMountNeeded(distanceToFateBoundary) && ActionManager.AvailableMounts.Any())
                {
                    Navigator.Stop();
                    if (!ignoreCombat && Core.Player.InCombat)
                    {
                        return(true);
                    }

                    await MountUp();
                }

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

                // Throttle navigator path generation requests.
                if (cachedFateLocation.Distance2D(currentFate.Location) > 15f)
                {
                    cachedFateLocation = currentFate.Location;
                }

                Navigator.MoveToPointWithin(cachedFateLocation, currentFateRadius * 0.3f, currentFate.Name);
                await Coroutine.Yield();
            }

            Navigator.Stop();
            OracleFateManager.ReachedCurrentFate = true;
            return(true);
        }
예제 #4
0
        internal static async Task <bool> MoveToCurrentFate(bool ignoreCombat)
        {
            var currentFate = OracleFateManager.GetCurrentFateData();

            if (!ignoreCombat && GameObjectManager.Attackers.Any(attacker => attacker.IsValid) && !Core.Player.IsMounted)
            {
                return(false);
            }

            await LoadFlightMeshIfAvailable();

            if (!ignoreCombat && MovementSettings.Instance.TeleportIfQuicker && currentFate.IsValid)
            {
                if (await OracleTeleportManager.FasterToTeleport(currentFate))
                {
                    if (GameObjectManager.Attackers.Any(attacker => attacker.IsValid))
                    {
                        OracleFateManager.ClearPoi("We're under attack and can't teleport.");
                        return(false);
                    }

                    await Coroutine.Wait(TimeSpan.FromSeconds(10), WorldManager.CanTeleport);

                    if (WorldManager.CanTeleport())
                    {
                        Logger.SendLog("Teleporting to the closest aetheryte crystal to the FATE.");
                        await OracleTeleportManager.TeleportToClosestAetheryte(currentFate);

                        if (GameObjectManager.Attackers.Any(attacker => attacker.IsValid))
                        {
                            OracleFateManager.ClearPoi("We're under attack and can't teleport.");
                            return(false);
                        }
                    }
                    else
                    {
                        Logger.SendErrorLog("Timed out trying to teleport, running to FATE instead.");
                    }
                }
            }

            // Refresh current fate data.
            currentFate = OracleFateManager.GetCurrentFateData();

            var distanceToFateBoundary = Core.Player.Location.Distance2D(currentFate.Location) - currentFate.Radius;

            if (ActionManager.CanMount == 0 && !ignoreCombat && IsMountNeeded(distanceToFateBoundary) && !Core.Player.IsMounted && currentFate.IsValid)
            {
                await MountUp();
            }

            if (!ignoreCombat && WorldManager.CanFly && ZoneFlightMesh != null)
            {
                await FlyToCurrentFate();
            }
            else
            {
                await NavigateToCurrentFate(ignoreCombat);
            }

            return(true);
        }
예제 #5
0
        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);
        }