/// <summary> /// Gets the route to objective. /// </summary> /// <returns>List<Vector3>.</returns> public List <Vector3> CreateRouteToObjective() { var route = new List <Vector3>(); FindObjectiveMarker(); if (_mapMarkerLastPosition == Vector3.Zero) { return(route); } var currentScene = SceneSegmentation.CurrentScene; if (!currentScene.IsExplored) { Logger.Log("Exploring Current Scene {0}", currentScene.Name); _isExploring = true; return(SceneSegmentation.GetSceneExploreRoute(currentScene)); } var objectiveDirection = MathUtil.GetDirectionToPoint(_mapMarkerLastPosition); var nextScene = SceneSegmentation.GetConnectedScene(objectiveDirection) ?? SceneSegmentation.GetConnectedScene(); if (nextScene == null) { Logger.Warn("Unable to find connected scene"); _isDone = true; return(route); } Logger.Log("Plotting Route through {0} ObjectiveDirection={1} SceneDirection={2}", nextScene.Name, objectiveDirection, MathUtil.GetDirectionToPoint(nextScene.Center)); route = SceneSegmentation.GetVectorPathToScene(nextScene); return(route); }
/// <summary> /// Creates a path to the nearest unexplored scene /// </summary> private List <Vector3> CreateRouteToUnexploredScene() { var route = new List <Vector3>(); var unexploredScene = SceneSegmentation.GetNearestUnexploredScene(); if (unexploredScene != null) { Logger.Warn("Found Unexplored Scene {0}", unexploredScene); route = SceneSegmentation.GetVectorPathToScene(unexploredScene); if (route != null) { return(route); } } Logger.Log("Unable to find alternate route to objective - finished!"); _isDone = true; return(route); }
protected async Task <bool> MoveToObjectiveRoutine() { if (ZetaDia.Me.IsDead || ZetaDia.IsLoadingWorld) { Logger.Log("IsDead={0} IsLoadingWorld={1}", ZetaDia.Me.IsDead, ZetaDia.IsLoadingWorld); return(false); } SceneSegmentation.Update(); if (_route.Any() || _currentRouteDestination != Vector3.Zero) { return(MoveAlongRoute(_route)); } // If the bot has failed to run directly towards the objective marker too many times // We'll blacklist it for 30 seconds to allow adjacent scenes to be explored. if (FailedAttempts >= FailedAttemptMax) { Logger.Log("Blacklisting Objective Marker for 60 seconds"); BlacklistMarkerExpires = DateTime.UtcNow.AddSeconds(60); FailedAttempts = 0; _route = CreateRouteToUnexploredScene(); return(false); } // While the bot is currently blacklisted from directly running at the objective // Generate a route to go through some nearby scenes if (DateTime.UtcNow < BlacklistMarkerExpires) { _route = CreateRouteToObjective(); return(false); } // 'ReachedDestination' is returned when finding a path to destination has failed. if (_lastMoveResult == MoveResult.ReachedDestination && _objectiveObject == null) { if (_miniMapMarker != null && _miniMapMarker.IsValid && _miniMapMarker.IsPointOfInterest) { var distance = ZetaDia.Me.Position.Distance(_miniMapMarker.Position); if (distance > 100) { FailedAttempts++; Logger.Log("Direct Pathfinding failed towards Objective Marker. Attempts={0}/{1}", FailedAttempts, FailedAttemptMax); } else if (distance < 30) { Logger.Log("ReachedDestination no Objective found - finished!"); _isDone = true; return(true); } } } // Find the objective minimap marker FindObjectiveMarker(); // If the marker is found or was previously found, find a nearby actor if (_mapMarkerLastPosition != Vector3.Zero) { RefreshActorInfo(); } if (_objectiveObject == null && _miniMapMarker == null && Position == Vector3.Zero) { Logger.Log("Error: Could not find Objective Marker! {0}", Status()); _isDone = true; return(true); } // Finish if World Changed if (ZetaDia.CurrentWorldId != _startWorldId) { Logger.Log("World changed from {0} to {1}, finished {2}", _startWorldId, ZetaDia.CurrentWorldId, Status()); _isDone = true; return(true); } // Finish because Objective Found if (IsValidObjective() && _objectiveObject is DiaUnit && _objectiveObject.Position.Distance(ZetaDia.Me.Position) <= PathPrecision) { Logger.Log("We found the objective and its a monster, ending tag so we can kill it. {0}", Status()); _isDone = true; return(true); } // Objective Object is available if (_objectiveObject != null && _objectiveObject.IsFullyValid()) { // Move Closer to Objective Object if (_lastMoveResult != MoveResult.ReachedDestination) { Logger.Debug("Moving to actor {0} {1}", _objectiveObject.ActorSNO, Status()); _lastMoveResult = await CommonCoroutines.MoveTo(_objectiveObject.Position); return(true); } if (_objectiveObject is GizmoPortal) { if (_lastMoveResult == MoveResult.ReachedDestination && _objectiveObject.Distance > InteractRange) { Logger.Log("ReachedDestination but not within InteractRange, finished"); _isDone = true; return(true); } if (GameUI.PartyLeaderBossAccept.IsVisible || GameUI.PartyFollowerBossAccept.IsVisible) { Logger.Debug("Party Boss Button visible"); return(true); } if (ZetaDia.Me.Movement.IsMoving) { await CommonBehaviors.MoveStop().ExecuteCoroutine(); } _objectiveObject.Interact(); _completedInteractAttempts++; Logger.Debug("Interacting with portal object {0}, result: {1}", _objectiveObject.ActorSNO, Status()); await Coroutine.Sleep(500); GameEvents.FireWorldTransferStart(); return(true); } } if (_miniMapMarker != null && ObjectiveObjectIsNullOrInvalid()) { if (_miniMapMarker != null && _miniMapMarker.Position.Distance(ZetaDia.Me.Position) > PathPrecision) { Logger.Debug("Moving to Objective Marker {0}, {1}", _miniMapMarker.NameHash, Status()); _lastMoveResult = await CommonCoroutines.MoveTo(_miniMapMarker.Position); return(true); } if (_miniMapMarker != null && _miniMapMarker.Position.Distance(ZetaDia.Me.Position) < PathPrecision) { Logger.Debug("Successfully Moved to Objective Marker {0}, {1}", _miniMapMarker.NameHash, Status()); _isDone = true; return(true); } } if (_miniMapMarker == null && Position != Vector3.Zero && Position.Distance(ZetaDia.Me.Position) > PathPrecision) { _lastMoveResult = CommonCoroutines.MoveTo(Position).Result; if (_lastMoveResult == MoveResult.ReachedDestination) { Logger.Log("ReachedDestination of Position, minimap marker not found, finished."); _isDone = true; return(true); } } Logger.Error("MoveToObjective Error: marker={0} actorNull={1} actorValid={2} completedInteracts={3} isPortal={4} dist={5} interactRange={6}", _miniMapMarker != null, _objectiveObject != null, (_objectiveObject != null && _objectiveObject.IsFullyValid()), _completedInteractAttempts, IsPortal, (_objectiveObject != null && _objectiveObject.IsFullyValid() ? _objectiveObject.Position.Distance(ZetaDia.Me.Position) : 0f), InteractRange); return(false); }