Exemple #1
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);
        }
Exemple #2
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);
        }
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 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 #5
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 #6
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 #7
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 #8
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 #9
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 #10
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 #11
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);
            }
        }