private async Task <bool> Exploring() { if (_useIgnoreRegions) { ExplorationHelpers.UpdateIgnoreRegions(); } if (_currentDestination == null || _currentDestination.IsVisited) { if (_explorationDataMaxWaitUntil != DateTime.MinValue && DateTime.UtcNow > _explorationDataMaxWaitUntil) { Core.Logger.Debug($"[Exploration] Timeout waiting for exploration data"); State = States.Completed; return(false); } if (!ExplorationGrid.Instance.WalkableNodes.Any()) { if (_explorationDataMaxWaitUntil == DateTime.MinValue) { _explorationDataMaxWaitUntil = DateTime.UtcNow + TimeSpan.FromSeconds(15); } Core.Scenes.Update(); await Coroutine.Sleep(1000); Core.Logger.Debug($"[Exploration] Patiently waiting for exploration data"); return(false); } _explorationDataMaxWaitUntil = DateTime.MinValue; if (_currentDestination != null) { _currentDestination.IsCurrentDestination = false; } var destination = ExplorationHelpers.NearestWeightedUnvisitedNode(_levelAreaIds); // Ignore marking nodes as Visited for bounties. if (destination != null && ZetaDia.Storage.Quests.ActiveBounty == null) { WorldScene destScene = destination.Scene; Vector3 destinationPos = destination.NavigableCenter; var exitPositions = destScene.ExitPositions; var connectedScenes = destScene.ConnectedScenes(); var unconnectedExits = exitPositions.Where(ep => connectedScenes.FirstOrDefault(cs => cs.Direction == ep.Key) == null); if (destinationPos.Distance(ExplorationHelpers.PriorityPosition) >= 15) { if (!unconnectedExits.Any(ep => destinationPos.Distance(ep.Value) <= 15) && ZetaDia.Minimap.IsExplored(destinationPos, AdvDia.CurrentWorldDynamicId)) { destination.IsVisited = true; destination.IsKnown = true; return(false); } } } if (destination == null) { Core.Logger.Debug($"[Exploration] No more unvisited nodes to explore, so we're done."); State = States.Completed; return(false); } if (_currentDestination != destination) { Core.Logger.Debug($"[Exploration] Destination Changed from {_currentDestination?.NavigableCenter} to {destination.NavigableCenter}"); _currentDestination = destination; } if (_currentDestination != null) { Core.Logger.Debug($"[Exploration] Current Destination {_currentDestination?.NavigableCenter}, CanRayWalk={CanRayWalkDestination} MyPosition={AdvDia.MyPosition}"); _currentDestination.IsCurrentDestination = true; } //_newNodePickTimer.Reset(); } if (_currentDestination != null) { if (await NavigationCoroutine.MoveTo(_currentDestination.NavigableCenter, 15)) { if (NavigationCoroutine.LastResult == CoroutineResult.Failure && (NavigationCoroutine.LastMoveResult == MoveResult.Failed || NavigationCoroutine.LastMoveResult == MoveResult.PathGenerationFailed)) { _currentDestination.FailedNavigationAttempts++; var canClientPathTo = await AdvDia.Navigator.CanFullyClientPathTo(_currentDestination.NavigableCenter); if (_currentDestination.FailedNavigationAttempts >= 10 && !canClientPathTo) { Core.Logger.Debug($"[Exploration] Unable to client path to {_currentDestination.NavigableCenter} and failed {_currentDestination.FailedNavigationAttempts} times; Ignoring Node."); _currentDestination.IsVisited = true; _currentDestination.IsIgnored = true; _currentDestination.IsCurrentDestination = false; _currentDestination = null; _failedNavigationAttempts++; } else if (!CanRayWalkDestination && _currentDestination.Distance < 25f && _currentDestination.FailedNavigationAttempts >= 3 || _currentDestination.FailedNavigationAttempts >= 15) { Core.Logger.Debug($"[Exploration] Failed to Navigate to {_currentDestination.NavigableCenter} {_currentDestination.FailedNavigationAttempts} times; Ignoring Node."); _currentDestination.IsVisited = true; _currentDestination.IsIgnored = true; _currentDestination.IsCurrentDestination = false; _currentDestination = null; _failedNavigationAttempts++; } } else { Core.Logger.Debug($"[Exploration] Destination Reached!"); _currentDestination.FailedNavigationAttempts = 0; _currentDestination.IsVisited = true; _currentDestination.IsCurrentDestination = false; _currentDestination = null; } if (_failedNavigationAttempts > 25) { if (_allowReExplore) { Core.Logger.Debug($"[Exploration] Exploration Resetting"); Core.Scenes.Reset(); Navigator.Clear(); _failedNavigationAttempts = 0; } else { Core.Logger.Debug($"[Exploration] too many failed navigation attempts, aborting."); State = States.Completed; return(false); } } } return(false); } Core.Logger.Debug($"[Exploration] We found no explore destination, so we're done."); Core.Scenes.Reset(); Navigator.Clear(); State = States.Completed; return(false); }