private static async Task <bool> MoveToNpc(GameObject npc) { if (movementTimer.Elapsed < movementCooldown) { return(true); } if (!(Core.Player.Distance2D(npc.Location) > 7f)) { return(true); } // Find random point within 3 yards of NPC. var rng = new Random(); const float radius = 3f; const float radiusSquared = radius * radius; var xOffset = Convert.ToSingle((2 * rng.NextDouble() - 1.0) * radius); var zOffset = Convert.ToSingle((2 * rng.NextDouble() - 1.0) * Math.Sqrt(radiusSquared - xOffset * xOffset)); var location = new Vector3(npc.Location.X + xOffset, npc.Location.Y, npc.Location.Z + zOffset); Logger.SendDebugLog("NPC Location: " + npc.Location + ", Moving to: " + location); var timeout = new Stopwatch(); timeout.Start(); while (Core.Player.Distance2D(location) > 1f) { var currentFate = OracleFateManager.GetCurrentFateData(); if (timeout.Elapsed > TimeSpan.FromSeconds(5)) { Navigator.PlayerMover.MoveStop(); timeout.Reset(); Logger.SendDebugLog("Timed out while attempting to move to random location, navigating back to FATE centre."); await MoveToFateCentre(); return(true); } if (currentFate == null || currentFate.Status == FateStatus.NOTACTIVE || currentFate.Status == FateStatus.COMPLETE) { Navigator.PlayerMover.MoveStop(); timeout.Reset(); OracleFateManager.ClearCurrentFate("Current FATE is finished."); return(true); } Navigator.PlayerMover.MoveTowards(location); await Coroutine.Yield(); } Navigator.PlayerMover.MoveStop(); movementTimer.Restart(); movementCooldown = GetRandomTimeSpan(); Logger.SendDebugLog("Waiting " + movementCooldown.Value.TotalMilliseconds + "ms before moving again."); return(true); }
internal static async Task <bool> HandleMegaBossFate() { var currentFate = OracleFateManager.GetCurrentFateData(); if (currentFate == null || currentFate.Status == FateStatus.NOTACTIVE || currentFate.Status == FateStatus.COMPLETE) { OracleFateManager.ClearCurrentFate("Current FATE is finished."); return(true); } if (currentFate.Status != FateStatus.NOTACTIVE && currentFate.Progress < FateSettings.Instance.MegaBossEngagePercentage && !OracleFateManager.PreviousFateChained()) { if (!FateSettings.Instance.WaitAtMegaBossForProgress) { await OracleFateManager.ClearCurrentFate("Current FATE progress reset below minimum level.", false); } else { Logger.SendLog("Current FATE progress is too low, waiting for it to reach " + FateSettings.Instance.MegaBossEngagePercentage + "%."); } return(true); } if (currentFate.Status != FateStatus.NOTACTIVE && OracleCombatManager.AnyViableFateTargets()) { OracleCombatManager.SelectFateTarget(); } return(true); }
internal static async Task <bool> HandleZoneChange(uint zoneId, bool bind) { const ushort dravanianHinterlands = 399; const uint idyllshireAetheryte = 75; uint aetheryteId; // Ensure we have no FATE selected to prevent null references. await OracleFateManager.ClearCurrentFate("Zone change needed.", false); if (zoneId == dravanianHinterlands) { aetheryteId = idyllshireAetheryte; } else { var aetheryte = OracleFateManager.GetAetheryteIdsForZone(zoneId).FirstOrDefault(); if (aetheryte == null) { Logger.SendErrorLog("There's no aetherytes for this zone."); OracleBot.StopOracle("Cannot teleport to destination."); return(false); } aetheryteId = aetheryte.Item1; } if (!WorldManager.HasAetheryteId(aetheryteId)) { Logger.SendErrorLog("Can't find requested teleport destination, make sure you've unlocked it."); OracleBot.StopOracle("Cannot teleport to destination."); return(false); } if (!WorldManager.CanTeleport()) { return(false); } var zoneName = WorldManager.AvailableLocations.FirstOrDefault(teleport => teleport.AetheryteId == aetheryteId).Name; Logger.SendLog("Teleporting to " + zoneName + "."); await OracleTeleportManager.TeleportToAetheryte(aetheryteId); if (WorldManager.ZoneId != WorldManager.GetZoneForAetheryteId(aetheryteId)) { return(true); } if (bind && MovementSettings.Instance.BindHomePoint) { await BindHomePoint.Main(aetheryteId); } if (aetheryteId == idyllshireAetheryte) { await OracleMovementManager.MoveOutOfIdyllshire(); } return(true); }
private static async Task ClearFate() { // Band-aid fix to stop a bug where the bot waits after turning in last items when FATE ends. // TODO: Look into why this is happening and fix properly. await OracleFateManager.DesyncLevel(); OracleFateManager.ClearCurrentFate("Current FATE is ending or is finished."); }
private static async Task <bool> MoveToFateCentre() { var currentFate = OracleFateManager.GetCurrentFateData(); if (currentFate == null) { OracleFateManager.ClearCurrentFate("Current FATE is finished."); return(true); } var cachedLocation = currentFate.Location; while (Core.Player.Distance2D(cachedLocation) > currentFate.Radius * 0.2f) { if (currentFate.Status == FateStatus.NOTACTIVE || currentFate.Status == FateStatus.COMPLETE) { Navigator.Stop(); OracleFateManager.ClearCurrentFate("Current FATE is finished."); return(true); } var distanceToFateBoundary = Core.Player.Location.Distance2D(cachedLocation) - currentFate.Radius; if (ActionManager.CanMount == 0 && !Core.Player.IsMounted && OracleMovementManager.IsMountNeeded(distanceToFateBoundary) && ActionManager.AvailableMounts.Any()) { Navigator.Stop(); if (Core.Player.InCombat) { return(true); } await OracleMovementManager.MountUp(); } // Throttle navigator path generation requests. if (cachedLocation.Distance2D(currentFate.Location) > 10) { cachedLocation = currentFate.Location; } Navigator.MoveToPointWithin(cachedLocation, currentFate.Radius * 0.2f, "FATE centre"); await Coroutine.Yield(); } return(true); }
internal static async Task <bool> HandleKillFate() { var currentFate = OracleFateManager.GetCurrentFateData(); if (currentFate == null || currentFate.Status == FateStatus.NOTACTIVE || currentFate.Status == FateStatus.COMPLETE) { OracleFateManager.ClearCurrentFate("Current FATE is finished."); return(true); } if (currentFate.Status != FateStatus.NOTACTIVE && OracleCombatManager.AnyViableFateTargets()) { OracleCombatManager.SelectFateTarget(); } return(true); }
internal static async Task <bool> HandleFate() { var currentFate = OracleFateManager.GetCurrentFateData(); if (currentFate == null) { Logger.SendDebugLog("Current FATE could not be found, assuming it's finished."); OracleFateManager.ClearCurrentFate("FATE is " + "no longer" + " active."); return(false); } if (currentFate.Status == FateStatus.NOTACTIVE) { OracleFateManager.ClearCurrentFate("FATE is no longer active."); return(false); } if (Core.Player.Distance(currentFate.Location) > currentFate.Radius * 1.05f) { await OracleMovementManager.MoveToCurrentFate(false); if (OracleFateManager.CurrentFateId == 0) { return(true); } } if (OracleCombatManager.IsPlayerBeingAttacked() && Poi.Current.Type != PoiType.Kill && Poi.Current.Type != PoiType.None) { OracleFateManager.ClearPoi("We're being attacked.", false); return(true); } if (OracleFateManager.IsLevelSyncNeeded(currentFate)) { await OracleFateManager.SyncLevel(currentFate); return(true); } return(await RunFate()); }
internal static async Task <bool> HandleZoneChange() { const uint idyllshireAetheryte = 75; MovementSettings.Instance.ZoneLevels.TryGetValue(OracleClassManager.GetTrueLevel(), out uint aetheryteId); // Ensure we have no FATE selected to prevent null references. await OracleFateManager.ClearCurrentFate("Zone change needed.", false); if (aetheryteId == 0 || !WorldManager.HasAetheryteId(aetheryteId)) { Logger.SendErrorLog("Can't find requested teleport destination, make sure you've unlocked it."); OracleBot.StopOracle("Cannot teleport to destination."); return(false); } if (!WorldManager.CanTeleport()) { return(false); } var zoneName = WorldManager.AvailableLocations.FirstOrDefault(teleport => teleport.AetheryteId == aetheryteId).Name; Logger.SendLog("Character is level " + OracleClassManager.GetTrueLevel() + ", teleporting to " + zoneName + "."); await OracleTeleportManager.TeleportToAetheryte(aetheryteId); if (WorldManager.ZoneId != WorldManager.GetZoneForAetheryteId(aetheryteId)) { return(true); } if (MovementSettings.Instance.BindHomePoint) { await BindHomePoint.Main(aetheryteId); } if (aetheryteId == idyllshireAetheryte) { await OracleMovementManager.MoveOutOfIdyllshire(); } return(true); }
internal static async Task <bool> HandleEscortFate() { var currentFate = OracleFateManager.GetCurrentFateData(); var oracleFate = OracleFateManager.FateDatabase.GetFateFromId(OracleFateManager.CurrentFateId); if (currentFate == null || currentFate.Status == FateStatus.NOTACTIVE || currentFate.Status == FateStatus.COMPLETE) { OracleFateManager.ClearCurrentFate("Current FATE is finished."); return(true); } if (movementTimer == null) { movementTimer = Stopwatch.StartNew(); } if (movementCooldown == null) { movementCooldown = GetRandomTimeSpan(); } if (currentFate.Status != FateStatus.NOTACTIVE && OracleCombatManager.AnyViableFateTargets()) { OracleCombatManager.SelectFateTarget(); } else if (currentFate.Status != FateStatus.NOTACTIVE) { var escortNpc = GameObjectManager.GetObjectByNPCId(oracleFate.NpcId) ?? GameObjectManager.GetObjectsOfType <BattleCharacter>().FirstOrDefault(IsEscortNpc); if (escortNpc == null || !currentFate.Within2D(Core.Player.Location)) { await MoveToFateCentre(); return(true); } await MoveToNpc(escortNpc); } return(true); }
private static bool IsFatePoiSet() { if (Poi.Current.Type != PoiType.Fate) { return(false); } if (Poi.Current.Fate == null) { return(false); } if (!Poi.Current.Fate.IsValid) { OracleFateManager.ClearCurrentFate("FATE is no longer valid."); return(false); } return(Poi.Current.Fate.Id == OracleFateManager.GetCurrentFateData().Id); }
private static async Task <bool> RunFate() { var oracleFate = OracleFateManager.FateDatabase.GetFateFromId(OracleFateManager.CurrentFateId); switch (oracleFate.Type) { case FateType.Kill: await KillFate.HandleKillFate(); return(true); case FateType.Collect: await CollectFate.HandleCollectFate(); return(true); case FateType.Escort: await EscortFate.HandleEscortFate(); return(true); case FateType.Defence: await DefenceFate.HandleDefenceFate(); return(true); case FateType.Boss: await BossFate.HandleBossFate(); return(true); case FateType.MegaBoss: await MegaBossFate.HandleMegaBossFate(); return(true); case FateType.Null: Logger.SendWarningLog("Cannot find FATE in database, using Rebornbuddy's FATE type identifier."); break; default: throw new ArgumentOutOfRangeException(); } var currentFate = OracleFateManager.GetCurrentFateData(); if (currentFate == null) { OracleFateManager.ClearCurrentFate("Cannot determine FATE type and FateData is null"); return(true); } switch (currentFate.Icon) { case FateIconType.Battle: await KillFate.HandleKillFate(); return(true); case FateIconType.Boss: Logger.SendWarningLog("Cannot determine if FATE is a regular or mega-boss, assuming regular."); await BossFate.HandleBossFate(); return(true); case FateIconType.KillHandIn: await CollectFate.HandleCollectFate(); return(true); case FateIconType.ProtectNPC: await EscortFate.HandleEscortFate(); return(true); case FateIconType.ProtectNPC2: await DefenceFate.HandleDefenceFate(); return(true); default: Logger.SendDebugLog("Cannot determine FATE type, blacklisting until end of session."); Blacklist.Add(currentFate.Id, BlacklistFlags.Node, TimeSpan.MaxValue, "Cannot determine FATE type."); OracleFateManager.ClearCurrentFate("Cannot determine FATE type."); return(false); } }