예제 #1
0
        public static async Task <bool> Interact(NetworkObject obj, int attempts)
        {
            if (obj == null)
            {
                GlobalLog.Error("[Interact] Object for interaction is null.");
                return(false);
            }

            var name = obj.Name;

            GlobalLog.Debug($"[Interact] Now going to interact with \"{name}\".");

            for (int i = 1; i <= attempts; i++)
            {
                if (!LokiPoe.IsInGame || LokiPoe.Me.IsDead)
                {
                    break;
                }

                await Coroutines.CloseBlockingWindows();

                await Coroutines.FinishCurrentAction();

                await Wait.LatencySleep();

                if (await Coroutines.InteractWith(obj))
                {
                    GlobalLog.Debug($"[Interact] \"{name}\" has been successfully interacted.");
                    return(true);
                }
                GlobalLog.Error($"[Interact] Fail to interact with \"{name}\". Attempt: {i}/{attempts}.");
                await Wait.SleepSafe(100, 200);
            }
            return(false);
        }
예제 #2
0
        public static async Task <bool> Interact(NetworkObject obj, Func <bool> success, string desc, int timeout = 3000)
        {
            if (obj == null)
            {
                GlobalLog.Error("[Interact] Object for interaction is null.");
                return(false);
            }

            var name = obj.Name;

            GlobalLog.Debug($"[Interact] Now going to interact with \"{name}\".");

            await Coroutines.CloseBlockingWindows();

            await Coroutines.FinishCurrentAction();

            await Wait.LatencySleep();

            if (await Coroutines.InteractWith(obj))
            {
                if (!await Wait.For(success, desc, 100, timeout))
                {
                    return(false);
                }

                GlobalLog.Debug($"[Interact] \"{name}\" has been successfully interacted.");
                return(true);
            }
            GlobalLog.Error($"[Interact] Fail to interact with \"{name}\".");
            await Wait.SleepSafe(300, 500);

            return(false);
        }
예제 #3
0
        private static async Task <bool> CreateNewInstance(AreaTransition transition)
        {
            var name = transition.Name;

            if (!await Coroutines.InteractWith(transition, true))
            {
                GlobalLog.Error($"[CreateNewInstance] Fail to interact with \"{name}\" transition.");
                return(false);
            }

            if (!await Wait.For(() => LokiPoe.InGameState.InstanceManagerUi.IsOpened, "instance manager opening"))
            {
                return(false);
            }

            if (Settings.Instance.ArtificialDelays)
            {
                await Wait.ArtificialDelay();
            }

            GlobalLog.Debug($"[CreateNewInstance] Creating new instance for \"{name}\".");

            var err = LokiPoe.InGameState.InstanceManagerUi.JoinNewInstance();

            if (err != LokiPoe.InGameState.JoinInstanceResult.None)
            {
                GlobalLog.Error($"[CreateNewInstance] Fail to create a new instance. Error: \"{err}\".");
                return(false);
            }
            GlobalLog.Debug($"[CreateNewInstance] New instance for \"{name}\" has been successfully created.");
            return(true);
        }
        /// <summary>
        /// Coroutine logic to execute.
        /// </summary>
        /// <returns>true if logic was executed to handle this type and false otherwise.</returns>
        public async Task <bool> Run()
        {
            // NOTE: This task's Run function is triggered from "hook_post_combat" Logic, as it's added via a secondary TaskManager!

            // If this task needs to be disabled due to errors, support doing so.
            if (_skip)
            {
                return(false);
            }

            // Don't do anything in these cases.
            if (LokiPoe.Me.IsDead || LokiPoe.Me.IsInHideout || LokiPoe.Me.IsInTown || LokiPoe.Me.IsInMapRoom)
            {
                return(false);
            }

            // If we're currently disabled, skip logic.
            if (!MonolithsSettings.Instance.Enabled)
            {
                return(false);
            }

            var myPos = LokiPoe.MyPosition;

            var active = MonolithDataManager.Active;

            // Make sure the monolith is still valid and not blacklisted if it's set.
            // We don't re-eval current against settings, because of the performance overhead.
            if (_current != null)
            {
                if (!_current.IsValid || Blacklist.Contains(_current.Id))
                {
                    _current = null;
                }
            }

            // Find the next best monolith.
            if (_current == null)
            {
                _current =
                    active.Monoliths.Where(m => m.IsValid && !Blacklist.Contains(m.Id) && ShouldActivate(m))
                    .OrderBy(m => m.Position.Distance(myPos))
                    .FirstOrDefault();
                _moveErrors       = 0;
                _interactErrors   = 0;
                _interactAttempts = 0;
            }

            // Nothing to do if there's no monolith.
            if (_current == null)
            {
                return(false);
            }

            // If we can't move to the monolith, blacklist it.
            if (_moveErrors > 5)
            {
                Blacklist.Add(_current.Id, TimeSpan.FromHours(1),
                              string.Format("[HandleMonolithsTask::Logic] Unable to move to the Monolith."));
                _current = null;
                return(true);
            }

            // If we are too far away to interact, move towards the object.
            if (myPos.Distance(_current.WalkablePosition) > 30)
            {
                // Make sure nothing is in the way.
                await Coroutines.CloseBlockingWindows();

                // Try to move towards the location.
                if (!PlayerMoverManager.MoveTowards(_current.WalkablePosition))
                {
                    Log.ErrorFormat("[HandleMonolithsTask::Logic] PlayerMoverManager.MoveTowards({0}) failed for Monolith [{1}].",
                                    _current.WalkablePosition, _current.Id);
                    _moveErrors++;
                    return(true);
                }

                _moveErrors = 0;

                return(true);
            }

            // Make sure we're not doing anything before we interact.
            await Coroutines.FinishCurrentAction();

            // If the user wants to manually open, or just find them without opening, this task just blocks everything else after it,
            // rather than stopping the bot, to avoid deaths.
            if (!MonolithsSettings.Instance.Open)
            {
                return(true);
            }

            // We always want to make sure we never just sit around trying to interact, if the interact has no results.
            if (_interactAttempts > 10)
            {
                Blacklist.Add(_current.Id, TimeSpan.FromHours(1),
                              string.Format("[HandleMonolithsTask::Logic] Unexpected Monolith interaction result."));
                _current = null;
                return(true);
            }

            // If we can't interact with the monolith, blacklist it.
            if (_interactErrors > 5)
            {
                Blacklist.Add(_current.Id, TimeSpan.FromHours(1),
                              string.Format("[HandleMonolithsTask::Logic] Unable to interact with the Monolith."));
                _current = null;
                return(true);
            }

            // Now process the object, but make sure it exists.
            var monolith = _current.NetworkObject;

            if (monolith == null)
            {
                Log.ErrorFormat("[HandleMonolithsTask::Logic] The NetworkObject does not exist for the Monolith [{0}] yet.",
                                _current.Id);
                _interactErrors++;
                return(true);
            }

            Log.InfoFormat("[HandleMonolithsTask::Logic] The Monolith [{0}] is at open phase [{1}].", monolith.Id,
                           monolith.OpenPhase);

            ++_interactAttempts;

            // Attempt to interact with it, we don't want to sleep afterwards because monsters spawn!
            if (!await Coroutines.InteractWith(monolith))
            {
                Log.ErrorFormat("[HandleMonolithsTask::Logic] Coroutines.InteractWith failed for the Monolith [{0}].", monolith.Id);
                _interactErrors++;
                return(true);
            }

            _interactErrors = 0;

            return(true);
        }