private async Task <bool> SetUsedGatesToIgnored() { // 'Reference' positions are hardcoded gate positions by SceneSnoId. // These allow gate nativation as soon as a scene is discovered. // And may be slightly off from actual gate actor positions. if (_deathGate != null) { Core.Logger.Debug($"Added origin gate to ignore list. (DiaGizmo) {_deathGate.Position}"); _deathGateIgnoreList[_deathGate.Position] = DateTime.UtcNow; } if (_deathGate?.Position != _deathGatePosition) { Core.Logger.Debug($"Added origin gate position to ignore list. (Reference) {_deathGatePosition}"); _deathGateIgnoreList[_deathGatePosition] = DateTime.UtcNow; } var destinationGate = ActorFinder.FindNearestDeathGate(); if (destinationGate != null) { Core.Logger.Debug($"Added destination gate to ignore list (DiaGizmo) {destinationGate}"); _deathGateIgnoreList[destinationGate.Position] = DateTime.UtcNow; } var destinationGateReferencePosition = DeathGates.NearestGateToPosition(AdvDia.MyPosition); if (destinationGateReferencePosition != Vector3.Zero) { Core.Logger.Debug($"Added destination gate to ignore list (Reference) {destinationGateReferencePosition}"); _deathGateIgnoreList[destinationGateReferencePosition] = DateTime.UtcNow; } return(false); }
private async Task <bool> Interacting() { var startSide = DeathGates.MySide; var startGate = ActorFinder.FindNearestDeathGate(); if (startGate == null) { Core.Logger.Debug("Can't find a gate nearby"); State = States.Failed; return(false); } if (startGate.Distance > startGate.CollisionSphere.Radius) { Core.Logger.Debug("Gate is too far away to interact"); State = States.MovingToGate; return(false); } if (_interactionCoroutine == null || _interactionCoroutine.IsDone) { Core.Logger.Debug($"Interacting with {startGate.Name} at {startGate.Position} Distance={startGate.Distance} CurrentScene={CurrentGateScene}"); _interactionCoroutine = new InteractionCoroutine(startGate.ActorSnoId, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(1), 5); } if (!await _interactionCoroutine.GetCoroutine()) { return(false); } if (_interactionCoroutine.State == InteractionCoroutine.States.Failed) { Core.Logger.Debug("InteractionCoroutine reports interaction with gate failed"); State = States.Failed; return(false); } if (TargetGatePosition.Distance(AdvDia.MyPosition) <= 10f) { Core.Logger.Debug("Interaction with gate failed, we didnt move anywhere."); State = States.Failed; return(false); } _gatesUsed++; //var endGateInteractPos = DeathGates.NearestGateToPosition(endGate.Position); var endGateInteractPos = CurrentGateScene.PortalPositions.FirstOrDefault(p => p != TargetGatePosition); Core.Logger.Debug($"Ignoring Gate at {endGateInteractPos} within {CurrentGateScene.Name} {DeathGates.MySide}"); _usedGatePositions.Add(endGateInteractPos); Core.Logger.Debug($"Ignoring Gate at {TargetGatePosition} within {CurrentGateScene.Name} {startSide}"); _usedGatePositions.Add(TargetGatePosition); Core.Logger.Debug($"Gate #{_gatesUsed} at {TargetGatePosition} within {CurrentGateScene.Name} ({startSide}=>{DeathGates.MySide}) was used successfully"); if (_gatesToUse >= 0 && _gatesUsed >= _gatesToUse) { Core.Logger.Debug($"We've used all the gates we're supposed to ({_gatesUsed})"); State = States.Completed; return(false); } State = States.Searching; return(false); }
private async Task <bool> Moving() { // Account for portals directly below current terrain. var zDiff = Math.Abs((float)(Destination.Z - AdvDia.MyPosition.Z)); var distanceToDestination = AdvDia.MyPosition.Distance(Destination); if (_timeout == DateTime.MaxValue) { _timeout = DateTime.UtcNow + TimeSpan.FromSeconds(240); } //if (_mover == Mover.StraightLine && (!Core.Grids.CanRayWalk(AdvDia.MyPosition, Destination) || !await AdvDia.Navigator.CanFullyClientPathTo(Destination))) //{ // Core.Logger.Debug("Unable to straight line path, switching to navigator pathing"); // _mover = Mover.Navigator; //} if (Destination != Vector3.Zero) { if (_distance != 0 && distanceToDestination <= _distance && zDiff < 4 || Core.Player.IsDead && !Core.Player.IsGhosted) { Navigator.PlayerMover.MoveStop(); LastMoveResult = MoveResult.ReachedDestination; } else { //if (_mover == Mover.StraightLine && PluginTime.ReadyToUse(_lastRaywalkCheck, 200)) //{ // if (!Core.Grids.CanRayWalk(AdvDia.MyPosition, Destination)) // { // _mover = Mover.Navigator; // } // _lastRaywalkCheck = PluginTime.CurrentMillisecond; //} switch (_mover) { case Mover.StraightLine: Navigator.PlayerMover.MoveTowards(Destination); LastMoveResult = MoveResult.Moved; Core.Logger.Debug($"MoveTowards Destination={Destination} Dist3D={AdvDia.MyPosition.Distance(Destination)} Dist2D={AdvDia.MyPosition.Distance2D(Destination)}"); return(false); case Mover.Navigator: if (AdvDia.Navigator != null) { LastMoveResult = await AdvDia.Navigator.MoveTo(Destination); } else { LastMoveResult = await Navigator.MoveTo(Destination); } Core.Logger.Debug($"Navigator MoveResult = {LastMoveResult}, Destination={Destination} Dist3D={AdvDia.MyPosition.Distance(Destination)} Dist2D={AdvDia.MyPosition.Distance2D(Destination)}"); break; } } switch (LastMoveResult) { case MoveResult.ReachedDestination: if (_distance != 0 && distanceToDestination <= _distance || distanceToDestination <= 5f) { Core.Logger.Debug("Completed (Distance to destination: {0})", distanceToDestination); State = States.Completed; } else { // DB Navigator will report ReachedDestination when failing to navigate to positions that require a death gate to reach. Redirect to gate position. if (Core.Rift.IsInRift && ActorFinder.FindNearestDeathGate() != null) { Core.Logger.Debug($"Starting Death Gate Sequence."); State = States.MovingToDeathGate; } else { Core.Logger.Debug($"Navigator reports DestinationReached but we're not at destination, failing. Mover={_mover}"); State = States.LastResortMovement; LastMoveResult = MoveResult.Failed; } } return(false); case MoveResult.Failed: Core.Logger.Debug($"Navigator reports Failed movement attempt. Mover={_mover}"); State = States.LastResortMovement; return(false); break; case MoveResult.PathGenerationFailed: Core.Logger.Debug("[Navigation] Path generation failed."); Core.PlayerMover.MoveTowards(Destination); if (distanceToDestination < 100 && Core.Grids.CanRayWalk(AdvDia.MyPosition, Destination)) { _mover = Mover.StraightLine; return(false); } State = States.Failed; return(false); case MoveResult.UnstuckAttempt: await Navigator.StuckHandler.DoUnstick(); if (_unstuckAttemps > 3) { State = States.Failed; return(false); } _unstuckAttemps++; Core.Logger.Debug("[Navigation] Unstuck attempt #{0}", _unstuckAttemps); break; case MoveResult.PathGenerated: case MoveResult.Moved: break; case MoveResult.PathGenerating: if (_pathGenetionTimer.IsFinished) { Core.Logger.Log("Patiently waiting for the Navigation Server"); _pathGenetionTimer.Reset(); } break; } return(false); } State = States.Completed; return(false); }
private async Task <bool> Interacting() { if (ZetaDia.Me.IsFullyValid() && (_castWaitStartTime.Subtract(DateTime.UtcNow).TotalSeconds < 10 || _castWaitStartTime == DateTime.MinValue)) { if (ZetaDia.Me.CommonData.AnimationState == AnimationState.Casting) { _castWaitStartTime = DateTime.UtcNow; Core.Logger.Debug("Waiting while AnimationState.Casting"); await Coroutine.Sleep(500); return(false); } if (ZetaDia.Me.CommonData.AnimationState == AnimationState.Channeling) { _castWaitStartTime = DateTime.UtcNow; Core.Logger.Debug("Waiting while AnimationState.Channeling"); await Coroutine.Sleep(500); return(false); } } if (ZetaDia.Globals.IsLoadingWorld) { Core.Logger.Debug("Waiting for world load"); await Coroutine.Sleep(500); return(false); } if (ZetaDia.Globals.WorldSnoId != _startingWorldId) { Core.Logger.Debug("World changed, assuming done!"); await Coroutine.Sleep(2500); State = States.Completed; return(false); } var actor = GetActor(); if (actor == null) { Core.Logger.Debug("Nothing to interact, failing. "); State = States.Failed; return(false); } if (!string.IsNullOrEmpty(_endAnimation)) { var anim = actor.CommonData?.CurrentAnimation.ToString().ToLowerInvariant(); if (!string.IsNullOrEmpty(anim) && anim.Contains(_endAnimation.ToLowerInvariant())) { Core.Logger.Debug($"Specified end animation was detected {_endAnimation}, done!"); State = States.Completed; return(false); } } if (!string.IsNullOrEmpty(_startAnimation)) { var anim = actor.CommonData?.CurrentAnimation.ToString().ToLowerInvariant(); if (!string.IsNullOrEmpty(anim) && !anim.Contains(_startAnimation.ToLowerInvariant())) { Core.Logger.Debug($"Specified start animation was no longer detected {_startAnimation}, done!"); State = States.Completed; return(false); } } var unit = actor as DiaUnit; if (_isQuestGiver && unit != null && !unit.IsQuestGiver) { Core.Logger.Debug($"Unit {actor.Name} is no longer a quest giver, assuming done!"); State = States.Completed; return(false); } //if (actor.Distance > 75f) //{ // Core.Logger.Debug($"Actor is way too far away. {actor.Distance}"); // State = States.Failed; // return false; //} // Assume done if (!_ignoreSanityChecks && !actor.IsInteractableQuestObject()) { State = States.Completed; return(false); } if (_currentInteractAttempt > _interactAttempts) { Core.Logger.Debug($"Max interact attempts reached ({_interactAttempts})"); State = States.Completed; return(true); } if (_currentInteractAttempt > 1 && actor.Position.Distance(ZetaDia.Me.Position) > 5f) { Navigator.PlayerMover.MoveTowards(actor.Position); await Coroutine.Sleep(250 *_currentInteractAttempt); } if (_isPortal || actor.IsFullyValid() && GameData.PortalTypes.Contains(actor.CommonData.GizmoType)) { var worldId = ZetaDia.Globals.WorldSnoId; if (worldId != _startingWorldId) { Core.Logger.Debug($"World changed from {_startingWorldId} to {worldId}, assuming done."); State = States.Completed; return(true); } } if (_timeoutCheckEnabled) { if (_interactionStartedAt == default(DateTime)) { _interactionStartedAt = DateTime.UtcNow; } else { if (DateTime.UtcNow - _interactionStartedAt > _timeOut) { Core.Logger.Debug("Interaction timed out after {0} seconds", (DateTime.UtcNow - _interactionStartedAt).TotalSeconds); State = States.TimedOut; return(false); } } } if (!actor.IsFullyValid()) { Core.Logger.Debug($"Actor is no longer valid, assuming done."); State = States.Completed; return(true); } Core.Logger.Debug($"Attempting to interact with {((SNOActor)actor.ActorSnoId)} at distance {actor.Distance} #{_currentInteractAttempt}"); var interactionResult = await Interact(actor); await Coroutine.Sleep(300); if (ActorFinder.IsDeathGate(actor)) { var nearestGate = ActorFinder.FindNearestDeathGate(); if (nearestGate.CommonData.AnnId != actor.CommonData.AnnId && actor.Distance > 10f) { Core.Logger.Debug("Arrived at Gate Destination (AnnId Check)"); State = States.Completed; return(true); } } //// Sleep time would have to be set to 0/low for this to be checked during gate travel. //if (ZetaDia.Me.IsUsingDeathGate()) //{ // Core.Logger.Debug("Used Death Gate!"); // await Coroutine.Wait(5000, () => !ZetaDia.Me.IsUsingDeathGate()); // Core.Logger.Debug("Arrived at Gate Destination (Travelling Check)"); // State = States.Completed; // return true; //} if (interactionResult) { if (_currentInteractAttempt <= _interactAttempts) { _currentInteractAttempt++; return(false); } if (!_isPortal && !_isNephalemStone && !_isOrek && actor.IsInteractableQuestObject()) { return(false); } if (_isNephalemStone && !UIElements.RiftDialog.IsVisible) { return(false); } if (_isOrek && AdvDia.RiftQuest.State != QuestState.Completed) { return(false); } State = States.Completed; } Core.Logger.Debug($"Interaction Failed"); return(false); }
private void ScanForObjective() { if (_previouslyFoundLocation != Vector3.Zero && PluginTime.ReadyToUse(_returnTimeForPreviousLocation, 60000)) { _objectiveLocation = _previouslyFoundLocation; _previouslyFoundLocation = Vector3.Zero; _returnTimeForPreviousLocation = PluginTime.CurrentMillisecond; Core.Logger.Debug("[EnterLevelArea] Returning previous objective location."); return; } if (PluginTime.ReadyToUse(_lastScanTime, 250)) { _lastScanTime = PluginTime.CurrentMillisecond; if (_portalMarker != 0) { if (_objectiveLocation == Vector3.Zero) { // Help with weighting exploration nodes even if its unreachable/unpathable. var markerlocation = BountyHelpers.ScanForMarkerLocation(_portalMarker, 5000); ExplorationHelpers.SetExplorationPriority(markerlocation); } _objectiveLocation = BountyHelpers.ScanForMarkerLocation(_portalMarker, _objectiveScanRange); if (ExplorationData.FortressLevelAreaIds.Contains(AdvDia.CurrentLevelAreaId)) { _deathGateLocation = DeathGates.GetBestGatePosition(_objectiveLocation); if (_deathGateLocation != Vector3.Zero) { if (Navigator.StuckHandler.IsStuck && _deathGateLocation.Distance(AdvDia.MyPosition) < 125f) { var nearestGate = ActorFinder.FindNearestDeathGate(); if (nearestGate != null) { Core.Logger.Warn("Found death gate location"); _objectiveLocation = nearestGate.Position; } } } } } if (_objectives != null && _objectives.Any()) { BountyHelpers.ObjectiveActor objective; _objectiveLocation = BountyHelpers.TryFindObjectivePosition(_objectives, _objectiveScanRange, out objective); if (objective != null) { _objective = objective; _portalActorId = objective.ActorId; _destinationWorldId = objective.DestWorldId; } } // Belial if (_objectiveLocation == Vector3.Zero && _portalActorId == 159574) { _objectiveLocation = BountyHelpers.ScanForActorLocation(_portalActorId, _objectiveScanRange); } //if (_objectiveLocation == Vector3.Zero && _portalActorId != 0) //{ // _objectiveLocation = BountyHelpers.ScanForActorLocation(_portalActorId, _objectiveScanRange); //} if (_objectiveLocation != Vector3.Zero) { Core.Logger.Log("[EnterLevelArea] Found the objective at distance {0}", AdvDia.MyPosition.Distance(_objectiveLocation)); ExplorationHelpers.SetExplorationPriority(_objectiveLocation); } } }
private async Task <bool> MovingToDeathGate() { if (_deathGate != null && _deathGate.IsFullyValid()) { if (AdvDia.MyPosition.Distance(_deathGate.Position) <= 7f) { Navigator.PlayerMover.MoveStop(); MoveResult = MoveResult.ReachedDestination; } else { _deathGate = ActorFinder.FindNearestDeathGate(_deathGateIgnoreList); if (_deathGate == null) { MoveResult = MoveResult.Failed; State = States.Failed; return(false); } MoveResult = await CommonCoroutines.MoveTo(_deathGate.Position); } switch (MoveResult) { case MoveResult.ReachedDestination: var distance = AdvDia.MyPosition.Distance(_deathGate.Position); if (distance <= 7f) { _interactionCoroutine = new InteractionCoroutine(_deathGate.ActorSnoId, new TimeSpan(0, 0, 1), new TimeSpan(0, 0, 3)); State = States.InteractingWithDeathGate; } else { _deathGateIgnoreList.Add(_deathGate.ACDId); State = States.Moving; } break; case MoveResult.Failed: case MoveResult.PathGenerationFailed: State = States.Failed; break; case MoveResult.PathGenerated: break; case MoveResult.UnstuckAttempt: if (_unstuckAttemps > 1) { State = States.Failed; return(false); } _unstuckAttemps++; Logger.Debug("[Navigation] Unstuck attempt #{0}", _unstuckAttemps); break; case MoveResult.Moved: case MoveResult.PathGenerating: break; } return(false); } State = States.Failed; return(false); }
private async Task <bool> Moving() { var distanceToDestination = AdvDia.MyPosition.Distance(_destination); if (_destination != Vector3.Zero) { if (_distance != 0 && distanceToDestination <= _distance) { Navigator.PlayerMover.MoveStop(); MoveResult = MoveResult.ReachedDestination; } else { if (_mover == Mover.StraightLine && PluginTime.ReadyToUse(_lastRaywalkCheck, 200)) { if (!NavigationGrid.Instance.CanRayWalk(AdvDia.MyPosition, _destination)) { _mover = Mover.Navigator; } _lastRaywalkCheck = PluginTime.CurrentMillisecond; } switch (_mover) { case Mover.StraightLine: Navigator.PlayerMover.MoveTowards(_destination); MoveResult = MoveResult.Moved; return(false); case Mover.Navigator: MoveResult = await Navigator.MoveTo(_destination); break; } } switch (MoveResult) { case MoveResult.ReachedDestination: if ((_distance != 0 && distanceToDestination <= _distance) || distanceToDestination <= 7f) { Logger.Debug("[Navigation] Completed (Distance to destination: {0})", distanceToDestination); State = States.Completed; } else { _deathGate = ActorFinder.FindNearestDeathGate(_deathGateIgnoreList); if (_deathGate != null) { State = States.MovingToDeathGate; } else { State = States.Failed; MoveResult = MoveResult.Failed; } } return(false); case MoveResult.Failed: break; case MoveResult.PathGenerationFailed: var navProvider = Navigator.NavigationProvider as DefaultNavigationProvider; if (navProvider != null) { Logger.Debug("[Navigation] Path generation failed."); navProvider.Clear(); } if (distanceToDestination < 100 && NavigationGrid.Instance.CanRayWalk(AdvDia.MyPosition, _destination)) { _mover = Mover.StraightLine; return(false); } State = States.Failed; return(false); case MoveResult.UnstuckAttempt: if (_unstuckAttemps > 1) { State = States.Failed; return(false); } _unstuckAttemps++; Logger.Debug("[Navigation] Unstuck attempt #{0}", _unstuckAttemps); break; case MoveResult.PathGenerated: case MoveResult.Moved: break; case MoveResult.PathGenerating: if (_pathGenetionTimer.IsFinished) { Logger.Info("Patiently waiting for the Navigation Server"); _pathGenetionTimer.Reset(); } break; } return(false); } State = States.Completed; return(false); }