Exemple #1
0
        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> HandleReturnToAetheryte()
        {
            if (Core.Player.Location.Distance2D(Poi.Current.Location) < 15f)
            {
                if (OracleCombatManager.IsPlayerBeingAttacked() && Poi.Current.Type != PoiType.Kill && Poi.Current.Type != PoiType.None)
                {
                    OracleFateManager.ClearPoi("We're being attacked.", false);
                }

                return(true);
            }

            if (!OracleMovementManager.IsFlightMeshLoaded())
            {
                await OracleMovementManager.LoadFlightMeshIfAvailable();

                if (!OracleMovementManager.IsFlightMeshLoaded())
                {
                    await OracleMovementManager.NavigateToLocation(Poi.Current.Location, 15f, true);

                    return(true);
                }
            }

            await OracleMovementManager.FlyToLocation(Poi.Current.Location, 15f, true, true);

            return(true);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
        private static bool ReadyToTurnIn()
        {
            if (Core.Player.InCombat)
            {
                return(false);
            }

            var currentFate = OracleFateManager.GetCurrentFateData();

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

            var oracleFate = OracleFateManager.FateDatabase.GetFateFromId(currentFate.Id);

            if (oracleFate.Type != FateType.Collect)
            {
                return(false);
            }

            if (currentFate.Status == FateStatus.NOTACTIVE)
            {
                return(false);
            }

            var fateItemCount = ConditionParser.ItemCount(oracleFate.ItemId);

            return(fateItemCount >= FateSettings.Instance.CollectTurnInAmount);
        }
Exemple #6
0
        private static async Task <bool> BlacklistUnnavigableAetherytes()
        {
            if (WorldManager.CanFly)
            {
                return(true);
            }

            var aetherytes = OracleFateManager.GetAetheryteIdsForZone(WorldManager.ZoneId);
            var navRequest = aetherytes.Select(target => new CanFullyNavigateTarget
            {
                Id       = target.Item1,
                Position = target.Item2
            }).ToList();
            var navTask    = Navigator.NavigationProvider.CanFullyNavigateTo(navRequest, Core.Player.Location, WorldManager.ZoneId);
            var navResults = await Coroutine.ExternalTask(navTask);

            foreach (var navResult in navResults.Where(result => result.CanNavigate == 0))
            {
                var aetheryte = aetherytes.FirstOrDefault(result => result.Item1 == navResult.Id);
                if (aetheryte != null)
                {
                    Blacklist.Add(aetheryte.Item1, BlacklistFlags.Node, TimeSpan.FromMinutes(10), "Cannot navigate to aetheryte crystal.");
                }
            }

            return(true);
        }
Exemple #7
0
        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.");
        }
Exemple #8
0
        private static async Task <Dictionary <FateData, float> > GetFateDistances()
        {
            if (!MovementSettings.Instance.TeleportIfQuicker || !MovementSettings.Instance.ConsiderAetheryteFateDistances || WorldManager.CanFly)
            {
                return(await OracleFateManager.GetActiveFateDistances());
            }

            Logger.SendDebugLog("Taking into account the distance to a FATE if we teleport to it.");
            var fateDistances = await OracleFateManager.GetActiveFateDistances();

            var fateDistancesFromAetherytes = new List <Dictionary <FateData, float> >();

            foreach (var aetheryte in
                     OracleFateManager.GetAetheryteIdsForZone(WorldManager.ZoneId).Where(item => WorldManager.KnownAetheryteIds.Contains(item.Item1)))
            {
                fateDistancesFromAetherytes.Add(await OracleFateManager.GetActiveFateDistances(aetheryte.Item2));
            }

            foreach (var fateDistance in await OracleFateManager.GetActiveFateDistances())
            {
                if (fateDistance.Key.Progress < MovementSettings.Instance.FateProgressTeleportLimit)
                {
                    continue;
                }

                Logger.SendDebugLog("Ignoring teleport distance for " + fateDistance.Key.Name + ", its progress (" + fateDistance.Key.Progress
                                    + "%) equals or exceeds the limit (" + MovementSettings.Instance.FateProgressTeleportLimit + "%).");
            }

            foreach (var aetheryteDistanceDict in fateDistancesFromAetherytes)
            {
                foreach (var fateDistance in aetheryteDistanceDict)
                {
                    float currentDistance;
                    if (!fateDistances.TryGetValue(fateDistance.Key, out currentDistance))
                    {
                        continue;
                    }

                    if (fateDistance.Key.Progress >= MovementSettings.Instance.FateProgressTeleportLimit)
                    {
                        continue;
                    }

                    // Add the minimum distance delta to ensure we don't teleport if distance saved is under that amount.
                    if (fateDistance.Value + MovementSettings.Instance.MinDistanceToTeleport >= currentDistance)
                    {
                        continue;
                    }

                    fateDistances.Remove(fateDistance.Key);
                    fateDistances.Add(fateDistance.Key, fateDistance.Value);
                }
            }

            return(fateDistances);
        }
        private static double GetWeight(BattleCharacter battleCharacter)
        {
            var weight      = 1800f;
            var currentFate = OracleFateManager.GetCurrentFateData();
            var oracleFate  = new Fate();

            if (currentFate != null)
            {
                oracleFate = OracleFateManager.FateDatabase.GetFateFromFateData(currentFate);
            }

            // If FATE has a preferred target, prioritise it if we're out of combat.
            if (oracleFate.PreferredTargetId != null && oracleFate.PreferredTargetId.Contains(battleCharacter.NpcId) && !Core.Player.InCombat)
            {
                weight += 20000;
            }

            if (battleCharacter.Pointer == Core.Player.PrimaryTargetPtr)
            {
                weight += 150;
            }

            if (battleCharacter.HasTarget && battleCharacter.CurrentTargetId == Core.Player.ObjectId)
            {
                weight += 750;
            }

            if (ChocoboManager.Object != null && battleCharacter.HasTarget && battleCharacter.CurrentTargetId == ChocoboManager.Object.ObjectId)
            {
                weight += 400;
            }

            if (!battleCharacter.TappedByOther)
            {
                weight += 200;
            }

            if (battleCharacter.CurrentTargetId == Core.Player.ObjectId)
            {
                weight += 1000 / Convert.ToSingle(battleCharacter.CurrentHealth) * 3000;
            }

            if (!battleCharacter.InCombat)
            {
                weight += 130;
            }

            // Prefer nearer targets in combat if melee, and always out of combat.
            if (OracleClassManager.IsMeleeDpsClassJob(Core.Player.CurrentJob) || OracleClassManager.IsTankClassJob(Core.Player.CurrentJob) ||
                !Core.Player.InCombat)
            {
                weight -= battleCharacter.Distance(Core.Player) * 30;
            }

            return(weight);
        }
Exemple #10
0
        internal static async Task <bool> HandleGrindMobs()
        {
            if (OracleCombatManager.IsPlayerBeingAttacked() && Poi.Current.Type != PoiType.Kill && Poi.Current.Type != PoiType.None)
            {
                OracleFateManager.ClearPoi("We're being attacked.", false);
                return(true);
            }

            await OracleCombatManager.SelectGrindTarget();

            return(true);
        }
Exemple #11
0
        private static async Task <bool> WaitBeforeMoving()
        {
            var rng            = new Random();
            var currentFate    = OracleFateManager.GetCurrentFateData();
            var minTime        = MovementSettings.Instance.DelayFateMovementMin * 1000;
            var maxTime        = MovementSettings.Instance.DelayFateMovementMax * 1000;
            var randomWaitTime = rng.Next(minTime, maxTime);

            Logger.SendLog("Waiting " + Math.Round(randomWaitTime / 1000f, 2) + " seconds before moving to FATE.");
            await Coroutine.Wait(randomWaitTime, () => currentFate.Status == FateStatus.NOTACTIVE || Core.Player.InCombat);

            return(true);
        }
Exemple #12
0
        internal static async Task <bool> Main()
        {
            if (CommonBehaviors.IsLoading)
            {
                return(false);
            }

            if (IsFateSet())
            {
                if (OracleFateManager.GetCurrentFateData() == null)
                {
                    return(true);
                }

                if (!IsFatePoiSet() && Poi.Current.Type != PoiType.Death && !GameObjectManager.Attackers.Any())
                {
                    Poi.Current = new Poi(OracleFateManager.GetCurrentFateData(), PoiType.Fate);
                }

                return(true);
            }

            if (OracleClassManager.ZoneChangeNeeded())
            {
                return(false);
            }

            if (OracleFateManager.PreviousFateChained() && ModeSettings.Instance.OracleOperationMode != OracleOperationMode.SpecificFates)
            {
                await SelectChainFate();
            }
            else if (ModeSettings.Instance.OracleOperationMode == OracleOperationMode.SpecificFates)
            {
                await SelectSpecificFate();
            }
            else
            {
                await SelectClosestFate();
            }

            if (OracleFateManager.GetCurrentFateData() != null && MovementSettings.Instance.DelayFateMovement && !OracleFateManager.DoNotWaitBeforeMovingFlag)
            {
                await WaitBeforeMoving();
            }

            OracleFateManager.DoNotWaitBeforeMovingFlag = false;
            return(IsFateSet() && IsFatePoiSet());
        }
Exemple #13
0
        internal static async Task <bool> HandleWait()
        {
            if (OracleCombatManager.IsPlayerBeingAttacked() && !Core.Player.IsMounted && Poi.Current.Type != PoiType.Kill && Poi.Current.Type != PoiType.None)
            {
                OracleFateManager.ClearPoi("We're being attacked.", false);
                return(true);
            }

            if (await OracleFateManager.AnyViableFates())
            {
                OracleFateManager.ClearPoi("Viable FATE detected.");
                return(true);
            }

            return(await RunWait());
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        internal static async Task <bool> Main()
        {
            if (Poi.Current.Type != PoiType.Kill)
            {
                return(false);
            }

            OracleFateManager.ForceUpdateGameCache();
            if (!Poi.Current.BattleCharacter.IsValid || Poi.Current.BattleCharacter.IsDead)
            {
                OracleFateManager.ClearPoi("Mob is "
                                           + "no longer"
                                           + " valid.",
                                           false);
                return(false);
            }

            if (Core.Player.CurrentHealthPercent < MainSettings.Instance.RestHealthPercent)
            {
                WaitForPlayerRegeneration();
                return(true);
            }

            if (OracleClassManager.IsTankClassJob(Core.Player.CurrentJob) || OracleClassManager.IsMeleeDpsClassJob(Core.Player.CurrentJob) ||
                OracleClassManager.IsRangedDpsClassJob(Core.Player.CurrentJob))
            {
                if (Core.Player.CurrentTPPercent < MainSettings.Instance.RestTPManaPercent)
                {
                    WaitForPlayerRegeneration();
                    return(true);
                }
            }

            if (OracleClassManager.IsCasterClassJob(Core.Player.CurrentJob) || OracleClassManager.IsHealerClassJob(Core.Player.CurrentJob))
            {
                if (Core.Player.CurrentManaPercent < MainSettings.Instance.RestTPManaPercent)
                {
                    WaitForPlayerRegeneration();
                    return(true);
                }
            }

            return(false);
        }
Exemple #17
0
        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());
        }
Exemple #18
0
        private static async Task <bool> SelectChainFate()
        {
            if (!OracleFateManager.WaitingForChainFate())
            {
                return(false);
            }

            var chainId             = OracleFateManager.FateDatabase.GetFateFromId(OracleFateManager.PreviousFateId).ChainId;
            var chainOracleFateInfo = OracleFateManager.FateDatabase.GetFateFromId(chainId);

            if (chainFateTimer == null || !chainFateTimer.IsRunning)
            {
                chainFateTimer = Stopwatch.StartNew();
            }
            else if (chainFateTimer.Elapsed > TimeSpan.FromSeconds(FateSettings.Instance.ChainWaitTimeout))
            {
                Logger.SendLog("Timed out waiting for the next FATE in the chain to appear.");
                OracleFateManager.PreviousFateId = 0;
                chainFateTimer.Reset();
            }

            Logger.SendLog("Waiting for the follow up FATE: " + chainOracleFateInfo.Name + ".");
            var chainFateData = FateManager.ActiveFates.FirstOrDefault(result => result.Id == chainId);

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

            // Fix for FATEs that spawn instantly after the previous ends.
            if (chainFateData.Name.Equals(string.Empty))
            {
                Logger.SendLog("Selected FATE: " + chainOracleFateInfo.Name + ".");
            }
            else
            {
                Logger.SendLog("Selected FATE: " + chainFateData.Name + ".");
            }

            OracleFateManager.CurrentFateId = chainFateData.Id;
            Poi.Current = new Poi(chainFateData, PoiType.Fate);
            chainFateTimer.Reset();
            return(true);
        }
Exemple #19
0
        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);
        }
Exemple #20
0
        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);
        }
Exemple #21
0
        internal static async Task <bool> HandleWaitInPlace()
        {
            if (OracleCombatManager.IsPlayerBeingAttacked() && Poi.Current.Type != PoiType.Kill && Poi.Current.Type != PoiType.None)
            {
                OracleFateManager.ClearPoi("We're being attacked.", false);
                return(true);
            }

            if (Poi.Current.Type != PoiType.Wait)
            {
                return(false);
            }

            if (await OracleFateManager.AnyViableFates())
            {
                OracleFateManager.ClearPoi("Found a FATE.");
            }

            return(true);
        }
Exemple #22
0
        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);
        }
Exemple #23
0
        internal static async Task <bool> Main()
        {
            if (!Request.IsOpen)
            {
                return(false);
            }

            if (GameObjectManager.Attackers.Any())
            {
                return(false);
            }

            var currentFate   = OracleFateManager.GetCurrentFateData();
            var itemId        = OracleFateManager.FateDatabase.GetFateFromId(currentFate.Id).ItemId;
            var turnInBagSlot = GetBagSlotFromItemId(itemId);

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

            Logger.SendLog("Attempting to hand over " + turnInBagSlot.Count + " of the item '" + turnInBagSlot.Name + "'.");
            turnInBagSlot.Handover();

            await Coroutine.Sleep(MainSettings.Instance.ActionDelay);

            if (!Request.IsOpen || !Request.HandOverButtonClickable)
            {
                Logger.SendErrorLog("Hand over failed.");
                Request.Cancel();

                return(false);
            }

            Logger.SendDebugLog("Pressing 'Hand Over' button.");
            Request.HandOver();
            await Coroutine.Sleep(MainSettings.Instance.ActionDelay);

            return(true);
        }
Exemple #24
0
        private static async Task <bool> SelectClosestFate()
        {
            if (!await OracleFateManager.AnyViableFates())
            {
                return(false);
            }

            var fateDistances = await GetFateDistances();

            var closestFates = fateDistances.OrderBy(kvp => kvp.Value).Where(fate => OracleFateManager.FateFilter(fate.Key)).ToArray();

            foreach (var fate in closestFates)
            {
                if (fate.Value > 0)
                {
                    Logger.SendDebugLog("Found FATE '" + fate.Key.Name + "'. Distance to it is " + Math.Round(fate.Value, 2) + " yalms.");
                }
                else
                {
                    Logger.SendDebugLog("Found FATE '" + fate.Key.Name + "'. Distance to it is 0 yalms.");
                }
            }

            if (!closestFates.Any())
            {
                return(false);
            }

            Logger.SendLog("Selecting closest viable FATE.");
            var closestFate = closestFates.FirstOrDefault().Key;

            Logger.SendLog("Selected FATE: " + closestFate.Name + ".");
            Logger.SendDebugLog("Location of FATE: " + closestFate.Location);
            OracleFateManager.CurrentFateId = closestFate.Id;
            Poi.Current = new Poi(closestFate, PoiType.Fate);

            return(true);
        }
Exemple #25
0
        private static Vector3 GetClosestAetheryteLocation()
        {
            var aetherytes     = OracleFateManager.GetAetheryteIdsForZone(WorldManager.ZoneId);
            var playerLocation = Core.Player.Location;
            var location       = Vector3.Zero;

            // Vectors are non-nullable, so return zeroed location and handle in task.
            if (aetherytes == null || aetherytes.Length == 0)
            {
                return(location);
            }

            foreach (var aetheryte in aetherytes)
            {
                if (!Blacklist.Contains(aetheryte.Item1) &&
                    (location == Vector3.Zero || playerLocation.Distance2D(location) > playerLocation.Distance2D(aetheryte.Item2)))
                {
                    location = aetheryte.Item2;
                }
            }

            return(location);
        }
Exemple #26
0
        private static bool IsEscortNpc(BattleCharacter battleCharacter)
        {
            var currentFate = OracleFateManager.GetCurrentFateData();
            var oracleFate  = OracleFateManager.FateDatabase.GetFateFromId(OracleFateManager.CurrentFateId);

            if (oracleFate.NpcId == battleCharacter.NpcId)
            {
                return(true);
            }

            if (!battleCharacter.IsFate)
            {
                return(false);
            }

            if (battleCharacter.CanAttack)
            {
                return(false);
            }

            if (battleCharacter.FateId != currentFate.Id)
            {
                return(false);
            }

            if (!battleCharacter.IsVisible)
            {
                return(false);
            }

            if (!battleCharacter.IsTargetable)
            {
                return(false);
            }

            return(true);
        }
Exemple #27
0
        private static async Task <bool> Main()
        {
            OracleFateManager.ForceUpdateGameCache();

            if (OracleFateManager.FateDatabase == null)
            {
                await LoadOracleDatabase.Main();
            }

            if (Poi.Current == null)
            {
                Poi.Current = new Poi(Vector3.Zero, PoiType.None);
                return(false);
            }

            if (Poi.Current.Type == PoiType.Death || Core.Player.IsDead)
            {
                if (Poi.Current.Type == PoiType.Death || Core.Player.IsDead)
                {
                    Logger.SendLog("We died, attempting to recover.");
                }

                if (Poi.Current.Type != PoiType.Death)
                {
                    Poi.Current = new Poi(Core.Player, PoiType.Death);
                }

                return(false);
            }

            await ChocoboHandler.HandleChocobo();

            if (Poi.Current.Type == PoiType.Kill)
            {
                await CombatHandler.HandleCombat();

                return(false);
            }

            if (OracleInventoryManager.ShouldRestockGreens())
            {
                await RestockGysahlGreens.HandleRestockGyshalGreens();

                return(false);
            }

            switch (ModeSettings.Instance.OracleOperationMode)
            {
            case OracleOperationMode.FateGrind:
                await FateGrind.HandleFateGrind();

                break;

            case OracleOperationMode.LevelMode:
                await Levelling.HandleLevelling();

                break;

            case OracleOperationMode.MultiLevelMode:
                await MultiLevelling.HandleMultiLevelling();

                break;

            case OracleOperationMode.SpecificFates:
                await SpecificFates.HandleSpecificFates();

                break;

            case OracleOperationMode.AtmaGrind:
                await AtmaGrind.HandleAtmaGrind();

                break;

            case OracleOperationMode.AnimusGrind:
                await AnimusGrind.HandleAnimusGrind();

                break;

            case OracleOperationMode.AnimaGrind:
                await AnimaGrind.HandleAnimaGrind();

                break;

            case OracleOperationMode.YokaiWatchGrind:
                await YokaiWatchGrind.HandleYokaiWatchGrind();

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (Poi.Current.Type == PoiType.Fate || OracleFateManager.CurrentFateId != 0)
            {
                await FateHandler.HandleFate();

                return(false);
            }

            if (Poi.Current.Type == PoiType.Wait)
            {
                await WaitHandler.HandleWait();
            }

            // Always return false to not block the tree.
            return(false);
        }
Exemple #28
0
        internal static async Task <bool> HandleChocobo()
        {
            if (!MainSettings.Instance.ChocoboHandlingEnabled)
            {
                return(false);
            }

            if (ModeSettings.Instance.OracleOperationMode == OracleOperationMode.YokaiWatchGrind)
            {
                return(false);
            }

            if (ChocoboManager.BlockSummon)
            {
                return(false);
            }

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

            if (!ChocoboManager.Summoned && ChocoboManager.CanSummon)
            {
                // Check for whether or not the dead/dismissed/expired Chocobo is still in the party. If it is, game won't let us summon.
                if (PartyManager.IsInParty && PartyManager.AllMembers != null &&
                    PartyManager.AllMembers.Any(member => member.GameObject != null && member.GameObject.SummonerGameObject == Core.Player))
                {
                    return(false);
                }

                var summonResult = await SummonChocobo();

                if (summonResult == SummonChocoboResult.Success)
                {
                    Logger.SendLog(ChocoboName + " has been summoned successfully!");
                }

                return(true);
            }

            // Safety checks for when the Chocobo may be summoned, but can't be accessed by RebornBuddy.
            if (!ChocoboManager.Summoned || ChocoboManager.Object == null || !ChocoboManager.Object.IsValid)
            {
                OracleFateManager.ForceUpdateGameCache();
                return(false);
            }

            if (Core.Player.CurrentHealthPercent < MainSettings.Instance.ChocoboStancePlayerHealthThreshold)
            {
                await SetChocoboStance(CompanionStance.Healer);
            }
            else if (ChocoboManager.Object.CurrentHealthPercent < MainSettings.Instance.ChocoboStanceChocoboHealthThreshold)
            {
                await SetChocoboStance(CompanionStance.Healer);
            }
            else if (Core.Player.CurrentHealthPercent >= MainSettings.Instance.ChocoboStanceReturnToAttackThreshold)
            {
                await SetChocoboStance(CompanionStance.Attacker);
            }
            else if (ChocoboManager.Stance != CompanionStance.Attacker && ChocoboManager.Stance != CompanionStance.Healer)
            {
                await SetChocoboStance(CompanionStance.Attacker);
            }

            return(false);
        }
Exemple #29
0
        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);
            }
        }
Exemple #30
0
        internal static async Task <bool> HandleCollectFate()
        {
            var currentFate   = OracleFateManager.GetCurrentFateData();
            var oracleFate    = OracleFateManager.FateDatabase.GetFateFromId(OracleFateManager.CurrentFateId);
            var fateItemCount = ConditionParser.ItemCount(oracleFate.ItemId);

            if (currentFate == null)
            {
                await ClearFate();

                return(true);
            }

            if (currentFate.Status != FateStatus.NOTACTIVE)
            {
                if (GameObjectManager.GetObjectByNPCId(oracleFate.NpcId) != null)
                {
                    if (Core.Player.InCombat)
                    {
                        return(false);
                    }

                    if (fateItemCount >= FateSettings.Instance.CollectTurnInAmount)
                    {
                        Logger.SendLog("Turning in what we've collected.");
                        await TurnInFateItems(GameObjectManager.GetObjectByNPCId(oracleFate.NpcId));

                        return(true);
                    }
                }
            }

            if (currentFate.Status != FateStatus.NOTACTIVE && currentFate.TimeLeft < TimeSpan.FromMinutes(1))
            {
                if (Core.Player.InCombat)
                {
                    return(false);
                }

                if (fateItemCount >= 1)
                {
                    Logger.SendLog("FATE is ending, turning in remaining items.");
                    await TurnInFateItems(GameObjectManager.GetObjectByNPCId(oracleFate.NpcId));

                    if (fateItemCount >= 1)
                    {
                        return(false);
                    }
                }

                await ClearFate();

                return(true);
            }

            if (currentFate.Status != FateStatus.NOTACTIVE && OracleCombatManager.AnyViableFateTargets())
            {
                OracleCombatManager.SelectFateTarget();
            }

            return(true);
        }