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); }
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); }
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); }