/// <summary>The bot Start event.</summary> public void Start() { _skip = false; _current = null; // Force clear, in case settings changed. BreachDataManager.Start(); // Will check IsInGame as needed }
public override void Tick(bool isActive) { // If we're not in the current area, don't do anything for now. if (!isActive) { return; } // Update currently seen breaches, but not the mini ones. var breaches = LokiPoe.ObjectManager.GetObjectsByType <Breach>().ToList(); foreach (var breach in breaches) { BreachCache cache; if (!_breaches.TryGetValue(breach.Id, out cache)) { cache = new BreachCache(breach); _breaches.Add(breach.Id, cache); } cache.Update(breach); } // Validate all cached breaches. foreach (var kvp in _breaches) { kvp.Value.Validate(); } }
bool ShouldActivate(BreachCache breach) { // Cache and reuse this for performance reasons. if (breach.Activate != null) { return(breach.Activate.Value); } Log.DebugFormat("[HandleBreachesTask] The Breach [{0}] will be activated.", breach.Id); breach.Activate = true; return(false); }
/// <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 (!BreachesSettings.Instance.Enabled) { return(false); } var myPos = LokiPoe.MyPosition; var active = BreachDataManager.Active; if (active == null) { return(false); } // Make sure the breach 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 breach. if (_current == null) { _current = active.Breaches.Where(m => m.IsValid && !Blacklist.Contains(m.Id) && ShouldActivate(m)) .OrderBy(m => m.Position.Distance(myPos)) .FirstOrDefault(); _moveErrors = 0; } // Nothing to do if there's no breach. if (_current == null) { return(false); } // If we can't move to the breach, blacklist it. if (_moveErrors > 5) { Blacklist.Add(_current.Id, TimeSpan.FromHours(1), string.Format("[HandleBreachesTask::Logic] Unable to move to the Breach.")); _current = null; return(true); } // If we are too far away to interact, move towards the object. if (myPos.Distance(_current.WalkablePosition) > 50) { // Make sure nothing is in the way. await Coroutines.CloseBlockingWindows(); // Try to move towards the location. if (!PlayerMoverManager.MoveTowards(_current.WalkablePosition)) { Log.ErrorFormat("[HandleBreachesTask::Logic] PlayerMoverManager.MoveTowards({0}) failed for Breach [{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 (!BreachesSettings.Instance.Open) { return(true); } // Now process the object, but make sure it exists. var breach = _current.NetworkObject; if (breach == null) { _current.Activate = false; Log.ErrorFormat("[HandleBreachesTask::Logic] The NetworkObject does not exist for the Breach [{0}] yet.", _current.Id); _current = null; return(true); } // Try to move towards the location. if (!PlayerMoverManager.MoveTowards(_current.WalkablePosition)) { Log.ErrorFormat("[HandleBreachesTask::Logic] PlayerMoverManager.MoveTowards({0}) failed for Breach [{1}].", _current.WalkablePosition, _current.Id); _moveErrors++; return(true); } return(true); }