private static async Task <Vector3> GetFateLandingLocation() { var oracleFate = OracleFateManager.GetCurrentOracleFate(); var currentFate = OracleFateManager.GetCurrentFateData(); Logger.SendDebugLog("Generating a landing spot."); var landingLocation = await GenerateRandomSpot(currentFate.Location, currentFate.Radius *oracleFate.LandingRadius); if (await CommonTasks.CanLand(landingLocation) == CanLandResult.No) { Logger.SendDebugLog("Landing spot generation failed: we can't land at " + landingLocation + "."); return(Core.Player.Location); } // Add a random height to the landing location so we fly above it, then land using the landing task. landingLocation.Y = landingLocation.Y + Convert.ToSingle(MathEx.Random(7, 13)); // Raycast to generated location from current location to check we can move there. Vector3 collision; if (WorldManager.Raycast(Core.Player.Location, landingLocation, out collision) && WorldManager.Raycast(landingLocation, Core.Player.Location, out collision)) { Logger.SendDebugLog("Landing spot generation failed: there's a collision at " + collision + "."); return(Core.Player.Location); } Logger.SendDebugLog("Landing spot generation succeeded."); return(landingLocation); }
private static async Task <bool> Land() { if (!MovementManager.IsFlying || MovementManager.IsSwimming) { return(true); } int ticks = 0; if (await CommonTasks.CanLand() == CanLandResult.Yes) { while (ticks < 100 && await CommonTasks.Land()) { if (!MovementManager.IsFlying) { break; } await Coroutine.Sleep(100); ticks++; } if (ticks >= 100) { Logging.WriteVerbose("Timeout whilst trying to land."); } } else { var closestObject = GameObjectManager.GameObjects.OrderBy(r => r.DistanceSqr(Core.Me.Location)).FirstOrDefault(); if (await CommonTasks.DescendTo(closestObject.Y) == DescendToResult.Success) { MovementManager.StopDescending(); Logging.WriteVerbose("Manual descend complete."); } } 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); }