private async Task <bool> LookForTarget() { if (this.playerReader.HasTarget && !this.playerReader.PlayerBitValues.TargetIsDead && !blacklist.IsTargetBlacklisted()) { return(true); } else { await input.TapNearestTarget(); if (!playerReader.HasTarget) { npcNameFinder.ChangeNpcType(NpcNameFinder.NPCType.Enemy); if (npcNameFinder.NpcCount > 0) { await this.npcNameFinder.FindAndClickNpc(0, true); } } } if (this.playerReader.HasTarget && !blacklist.IsTargetBlacklisted()) { if (playerReader.PlayerBitValues.IsMounted) { //await wowProcess.Dismount(); } await input.TapInteractKey("FollowRouteAction 4"); return(true); } return(false); }
public async Task TapInteractKey(string source) { await input.TapInteractKey($"Approach target ({source})"); this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; await input.TapStopAttack(); }
private async Task Interact() { if (this.classConfiguration.Interact.GetCooldownRemaining() == 0) { await input.TapInteractKey("PullTargetAction"); } await this.castingHandler.InteractOnUIError(); }
private async Task CreatureTargetMeOrMyPet() { await wait.Update(1); if (playerReader.PetHasTarget && addonReader.CreatureHistory.CombatDeadGuid.Value != playerReader.PetTargetGuid) { logger.LogWarning("---- My pet has a target!"); ResetCooldowns(); await input.TapTargetPet(); await input.TapTargetOfTarget(); await wait.Update(1); return; } if (addonReader.CombatCreatureCount > 1) { await input.TapNearestTarget($"{GetType().Name}: Checking target in front of me"); await wait.Update(1); if (playerReader.HasTarget) { if (playerReader.Bits.TargetInCombat && playerReader.Bits.TargetOfTargetIsPlayer) { ResetCooldowns(); logger.LogWarning("---- Somebody is attacking me!"); await input.TapInteractKey("Found new target to attack"); await stopMoving.Stop(); await wait.Update(1); return; } await input.TapClearTarget(); await wait.Update(1); } else { // threat must be behind me var anyDamageTakens = addonReader.CreatureHistory.DamageTaken.Where(x => (DateTime.Now - x.LastEvent).TotalSeconds < 10 && x.HealthPercent > 0); if (anyDamageTakens.Any()) { logger.LogWarning($"---- Possible threats found behind {anyDamageTakens.Count()}. Waiting for my target to change!"); await wait.Interrupt(2000, () => playerReader.HasTarget); } } } }
public override async Task PerformAction() { lastLoot = playerReader.LastLootTime; await stopMoving.Stop(); combatUtil.Update(); await input.TapLastTargetKey($"{GetType().Name}: No corpse name found - check last dead target exists"); await wait.Update(1); if (playerReader.HasTarget) { if (playerReader.Bits.TargetIsDead) { await input.TapInteractKey($"{GetType().Name}: Found last dead target"); await wait.Update(1); (bool foundTarget, bool moved) = await combatUtil.FoundTargetWhileMoved(); if (foundTarget) { Log("Goal interrupted!"); return; } if (moved) { await input.TapInteractKey($"{GetType().Name}: Last dead target double"); } } else { await input.TapClearTarget($"{GetType().Name}: Don't attack the target!"); } } await GoalExit(); }
public override async Task PerformAction() { if (playerReader.PlayerBitValues.IsMounted) { await input.Dismount(); } /* * if (HasPickedUpAnAdd) * { * logger.LogInformation($"Combat={this.playerReader.PlayerBitValues.PlayerInCombat}, Is Target targetting me={this.playerReader.PlayerBitValues.TargetOfTargetIsPlayerOrPet}"); * logger.LogInformation($"Add on combat"); * await this.stopMoving.Stop(); * await wowProcess.TapStopKey(); * await wowProcess.TapClearTarget(); * return; * } */ if ((DateTime.Now - lastActive).TotalSeconds > 5 && (DateTime.Now - lastPulled).TotalSeconds > 5) { logger.LogInformation("Interact and stop"); await input.TapInteractKey("CombatActionBase PerformAction"); //await this.castingHandler.PressKey(ConsoleKey.UpArrow, "", 57); } await stopMoving.Stop(); SendActionEvent(new ActionEventArgs(GoapKey.fighting, true)); await this.castingHandler.InteractOnUIError(); await Fight(); await KillCheck(); lastActive = DateTime.Now; }
public override async Task PerformAction() { long lastHealth = playerReader.HealthCurrent; WowPoint lastPosition = playerReader.PlayerLocation; SendActionEvent(new ActionEventArgs(GoapKey.shouldskin, !playerReader.Unskinnable)); await input.TapInteractKey("interact target"); while (IsPlayerMoving(lastPosition)) { logger.LogInformation("wait till the player become stil!"); lastPosition = playerReader.PlayerLocation; if (!await Wait(100, () => playerReader.HealthCurrent < lastHealth)) { return; } } if (!await Wait(100, () => playerReader.HealthCurrent < lastHealth)) { return; } await input.TapInteractKey("Looting..."); // wait grabbing the loot if (!await Wait(200, () => playerReader.HealthCurrent < lastHealth)) { return; } logger.LogDebug("Loot was Successfull"); SendActionEvent(new ActionEventArgs(GoapKey.shouldloot, false)); //clear target //await wowProcess.KeyPress(ConsoleKey.F3, 50); await input.TapClearTarget(); }
public override async Task PerformAction() { WowPoint lastPosition = playerReader.PlayerLocation; Log("Search for corpse"); npcNameFinder.ChangeNpcType(NpcNameFinder.NPCType.Corpse); await stopMoving.Stop(); await npcNameFinder.WaitForNUpdate(1); bool lootSuccess = await npcNameFinder.FindByCursorType(Cursor.CursorClassification.Loot); if (lootSuccess) { Log("Found corpse - interact with it"); await playerReader.WaitForNUpdate(1); if (classConfiguration.Skin) { var targetSkinnable = !playerReader.Unskinnable; AddEffect(GoapKey.shouldskin, targetSkinnable); Log($"Should skin ? {targetSkinnable}"); SendActionEvent(new ActionEventArgs(GoapKey.shouldskin, targetSkinnable)); } bool hadToMove = false; if (IsPlayerMoving(lastPosition)) { hadToMove = true; Log("Goto corpse - Wait till player become stil!"); } while (IsPlayerMoving(lastPosition)) { lastPosition = playerReader.PlayerLocation; if (!await Wait(100, DiDEnteredCombat())) { await AquireTarget(); return; } } // TODO: damn spell batching // arriving to the corpse min distance to interact location // and says you are too far away // so have to wait and retry the action // at this point the player have a target // might be a good idea to check the last error message :shrug: if (hadToMove) { if (!await Wait(200, DiDEnteredCombat())) { await AquireTarget(); return; } } await input.TapInteractKey("Approach corpse"); // TODO: find a better way to get notified about the successful loot // challlange: // - the mob might have no loot at all so cant check inventory change // - loot window could be checked /* * if (!await Wait(400, DiDEnteredCombat())) * { * await AquireTarget(); * return; * } */ Log("Loot Successfull"); await GoalExit(); } else { Log($"No corpse found - Npc Count: {npcNameFinder.NpcCount}"); if (!await Wait(100, DiDEnteredCombat())) { await AquireTarget(); } else { await GoalExit(); } } }
public override async Task PerformAction() { SendActionEvent(new ActionEventArgs(GoapKey.fighting, false)); if (await AquireTarget()) { await stopMoving.StopTurn(); if (playerReader.PlayerClass == PlayerClassEnum.Hunter) { if (playerReader.PlayerBitValues.TargetCanBeHostile) { await input.TapInteractKey("approach target as hunter"); } else { await input.TapClearTarget("not hostile"); } } return; } await SwitchGatherType(); await playerReader.WaitForNUpdate(1); if (this.playerReader.PlayerBitValues.PlayerInCombat && this.classConfiguration.Mode != Mode.AttendedGather) { return; } var timeSinceResetSeconds = (DateTime.Now - LastReset).TotalSeconds; if ((DateTime.Now - LastActive).TotalSeconds > 10 || routeToWaypoint.Count == 0 || timeSinceResetSeconds > 80) { logger.LogInformation("Trying to path a new route."); // recalculate next waypoint var pointsRemoved = 0; while (AdjustNextPointToClosest() && pointsRemoved < 5) { pointsRemoved++; } ; await RefillRouteToNextWaypoint(true); if (routeToWaypoint.Count == 0) { logger.LogError("Didn't found path."); } } else { var playerLocation = new WowPoint(playerReader.XCoord, playerReader.YCoord); var distanceToRoute = WowPoint.DistanceTo(playerLocation, routeToWaypoint.Peek()); if (routeToWaypoint.Count <= 1 && distanceToRoute > 200) { logger.LogError("wtf too far away kekw"); routeToWaypoint.Pop(); return; } //wowProcess.SetKeyState(ConsoleKey.UpArrow, true, false, "FollowRouteAction 1"); input.SetKeyState(ConsoleKey.UpArrow, true, false); } await RandomJump(); var location = new WowPoint(playerReader.XCoord, playerReader.YCoord); var distance = WowPoint.DistanceTo(location, routeToWaypoint.Peek()); var heading = DirectionCalculator.CalculateHeading(location, routeToWaypoint.Peek()); await AdjustHeading(heading); if (lastDistance < distance) { AdjustNextPointToClosest(); await playerDirection.SetDirection(heading, routeToWaypoint.Peek(), "Further away"); } else if (!this.stuckDetector.IsGettingCloser()) { // stuck so jump input.SetKeyState(ConsoleKey.UpArrow, true, false, "FollowRouteAction 2"); await Task.Delay(100); if (HasBeenActiveRecently()) { await this.stuckDetector.Unstick(); distance = WowPoint.DistanceTo(location, routeToWaypoint.Peek()); } else { await Task.Delay(1000); logger.LogInformation("Resuming movement"); } } else // distance closer { await AdjustHeading(heading); } lastDistance = distance; //if (distance < PointReachedDistance((int)(avgDistance / 2))) //if (distance < PointReachedDistance(5)) if (distance < PointReachedDistance(10)) { Log($"Move to next point"); ReduceRouteByDistance(); lastDistance = 999; if (routeToWaypoint.Count == 0) { wayPoints.Pop(); await RefillRouteToNextWaypoint(false); } this.stuckDetector.SetTargetLocation(this.routeToWaypoint.Peek()); heading = DirectionCalculator.CalculateHeading(location, routeToWaypoint.Peek()); await playerDirection.SetDirection(heading, routeToWaypoint.Peek(), "Move to next point"); } // should mount await MountIfRequired(); LastActive = DateTime.Now; }
public async Task <bool> CastIfReady(KeyAction item, int sleepBeforeCast = 0) { if (!CanRun(item)) { return(false); } if (item.ConsoleKey == 0) { return(false); } if (!await SwitchToCorrectShapeShiftForm(item)) { return(false); } if (this.playerReader.IsShooting) { await input.TapInteractKey("Stop casting shoot"); await Task.Delay(1500); // wait for shooting to end } if (sleepBeforeCast > 0) { item.LogInformation($" Wait before {sleepBeforeCast}."); await Task.Delay(sleepBeforeCast); } await PressKey(item.ConsoleKey, item.Name, item.PressDuration); item.SetClicked(); if (!item.HasCastBar) { var result = await WaitInterrupt(item.DelayAfterCast, () => playerReader.PlayerBitValues.TargetIsDead || playerReader.TargetHealthPercentage < 5); item.LogInformation($" ... no castbar delay after cast {result.Item2}ms"); await InteractOnUIError(); } else { await playerReader.WaitForNUpdate(1); if (!this.playerReader.IsCasting && this.playerReader.HasTarget) { await this.InteractOnUIError(); item.LogInformation($"Not casting, pressing it again"); await PressKey(item.ConsoleKey, item.Name, item.PressDuration); await playerReader.WaitForNUpdate(1); if (!this.playerReader.IsCasting && this.playerReader.HasTarget) { item.LogInformation($"Still not casting !"); await this.InteractOnUIError(); return(false); } } item.LogInformation(" waiting for cast bar to end."); for (int i = 0; i < 15000; i += 100) { if (!this.playerReader.IsCasting) { await playerReader.WaitForNUpdate(1); break; } // wait after cast if the delay is different to the default value if (item.DelayAfterCast != new KeyAction().DelayAfterCast) { item.LogInformation($" ... delay after cast {item.DelayAfterCast}"); if (item.DelayUntilCombat) // stop waiting if the mob is targetting me { var sw = new Stopwatch(); sw.Start(); while (sw.ElapsedMilliseconds < item.DelayAfterCast) { await Task.Delay(10); if (this.playerReader.PlayerBitValues.TargetOfTargetIsPlayer) { break; } } } else { var result = await WaitInterrupt(item.DelayAfterCast, () => playerReader.PlayerBitValues.TargetIsDead || playerReader.TargetHealthPercentage < 5); item.LogInformation($" ... castbar delay after cast {result.Item2}ms"); } } await playerReader.WaitForNUpdate(1); } } if (item.StepBackAfterCast > 0) { await this.input.KeyPress(ConsoleKey.DownArrow, item.StepBackAfterCast, $"Step back for {item.StepBackAfterCast}ms"); } item.ConsumeCharge(); return(true); }
public override async Task PerformAction() { lastLoot = playerReader.LastLootTime; await stopMoving.Stop(); combatUtil.Update(); Log($"Try to find {NpcNames.Corpse}"); await npcNameTargeting.WaitForNUpdate(1); int attempts = 1; while (attempts < 5) { if (await combatUtil.EnteredCombat()) { if (await combatUtil.AquiredTarget()) { Log("Interrupted!"); return; } } bool foundCursor = await npcNameTargeting.FindBy(CursorType.Skin); if (foundCursor) { Log("Found corpse - interacted with right click"); await wait.Update(1); (bool foundTarget, bool moved) = await combatUtil.FoundTargetWhileMoved(); if (foundTarget) { Log("Interrupted!"); return; } if (moved) { await input.TapInteractKey($"{GetType().Name}: Had to move so interact again"); await wait.Update(1); } // wait until start casting await wait.Interrupt(500, () => playerReader.IsCasting); Log("Started casting..."); playerReader.LastUIErrorMessage = UI_ERROR.NONE; await wait.Interrupt(3000, () => !playerReader.IsCasting || playerReader.LastUIErrorMessage != UI_ERROR.NONE); Log("Cast finished!"); if (playerReader.LastUIErrorMessage != UI_ERROR.ERR_SPELL_FAILED_S) { playerReader.LastUIErrorMessage = UI_ERROR.NONE; Log($"Skinning Successful! {playerReader.LastUIErrorMessage}"); await GoalExit(); return; } else { Log($"Skinning Failed! Retry... Attempts: {attempts}"); attempts++; } } else { Log($"Target is not skinnable - NPC Count: {npcNameTargeting.NpcCount}"); await GoalExit(); return; } } }
public override async Task PerformAction() { lastLoot = playerReader.LastLootTime; await stopMoving.Stop(); combatUtil.Update(); await npcNameTargeting.WaitForNUpdate(2); bool foundCursor = await npcNameTargeting.FindBy(CursorType.Loot); if (foundCursor) { Log("Found corpse - clicked"); (bool notFoundTarget, double elapsedMs) = await wait.InterruptTask(200, () => playerReader.TargetId != 0); if (!notFoundTarget) { Log($"Found target after {elapsedMs}ms"); } CheckForSkinning(); (bool foundTarget, bool moved) = await combatUtil.FoundTargetWhileMoved(); if (foundTarget) { Log("Interrupted!"); return; } if (moved) { await input.TapInteractKey($"{GetType().Name}: Had to move so interact again"); await wait.Update(1); } } else { await input.TapLastTargetKey($"{GetType().Name}: No corpse name found - check last dead target exists"); await wait.Update(1); if (playerReader.HasTarget) { if (playerReader.Bits.TargetIsDead) { CheckForSkinning(); await input.TapInteractKey($"{GetType().Name}: Found last dead target"); await wait.Update(1); (bool foundTarget, bool moved) = await combatUtil.FoundTargetWhileMoved(); if (foundTarget) { Log("Goal interrupted!"); return; } if (moved) { await input.TapInteractKey($"{GetType().Name}: Last dead target double"); } } else { await input.TapClearTarget($"{GetType().Name}: Don't attack the target!"); } } } await GoalExit(); }
public async Task ReactToLastUIErrorMessage(string source) { //var lastError = playerReader.LastUIErrorMessage; switch (playerReader.LastUIErrorMessage) { case UI_ERROR.NONE: break; case UI_ERROR.CAST_START: break; case UI_ERROR.CAST_SUCCESS: break; case UI_ERROR.ERR_SPELL_FAILED_STUNNED: int debuffCount = playerReader.AuraCount.PlayerDebuff; if (debuffCount != 0) { logger.LogInformation($"{source} -- React to {UI_ERROR.ERR_SPELL_FAILED_STUNNED} -- Wait till losing debuff!"); await wait.While(() => debuffCount == playerReader.AuraCount.PlayerDebuff); await wait.Update(1); playerReader.LastUIErrorMessage = UI_ERROR.NONE; } else { logger.LogInformation($"{source} -- Didn't know how to react {UI_ERROR.ERR_SPELL_FAILED_STUNNED} when PlayerDebuffCount: {debuffCount}"); } break; case UI_ERROR.ERR_SPELL_OUT_OF_RANGE: if (playerReader.Class == PlayerClassEnum.Hunter && playerReader.IsInMeleeRange) { logger.LogInformation($"{source} -- As a Hunter didn't know how to react {UI_ERROR.ERR_SPELL_OUT_OF_RANGE}"); return; } logger.LogInformation($"{source} -- React to {UI_ERROR.ERR_SPELL_OUT_OF_RANGE} -- Face enemy and start moving forward"); await input.TapInteractKey(""); input.SetKeyState(ConsoleKey.UpArrow, true, false, ""); await wait.Update(1); playerReader.LastUIErrorMessage = UI_ERROR.NONE; break; case UI_ERROR.ERR_BADATTACKFACING: if (playerReader.IsInMeleeRange) { logger.LogInformation($"{source} -- React to {UI_ERROR.ERR_BADATTACKFACING} -- Interact!"); await input.TapInteractKey(""); } else { logger.LogInformation($"{source} -- React to {UI_ERROR.ERR_BADATTACKFACING} -- Turning 180!"); double desiredDirection = playerReader.Direction + Math.PI; desiredDirection = desiredDirection > Math.PI * 2 ? desiredDirection - (Math.PI * 2) : desiredDirection; await direction.SetDirection(desiredDirection, new WowPoint(0, 0), ""); } await wait.Update(1); playerReader.LastUIErrorMessage = UI_ERROR.NONE; break; case UI_ERROR.SPELL_FAILED_MOVING: logger.LogInformation($"{source} -- React to {UI_ERROR.SPELL_FAILED_MOVING} -- Stop moving!"); await stopMoving.Stop(); await wait.Update(1); playerReader.LastUIErrorMessage = UI_ERROR.NONE; break; case UI_ERROR.ERR_SPELL_FAILED_ANOTHER_IN_PROGRESS: logger.LogInformation($"{source} -- React to {UI_ERROR.ERR_SPELL_FAILED_ANOTHER_IN_PROGRESS} -- Wait till casting!"); await wait.While(() => playerReader.IsCasting); await wait.Update(1); playerReader.LastUIErrorMessage = UI_ERROR.NONE; break; case UI_ERROR.ERR_SPELL_COOLDOWN: logger.LogInformation($"{source} -- Cant react to {UI_ERROR.ERR_SPELL_FAILED_ANOTHER_IN_PROGRESS}"); await wait.Update(1); playerReader.LastUIErrorMessage = UI_ERROR.NONE; break; case UI_ERROR.ERR_BADATTACKPOS: if (playerReader.Bits.IsAutoRepeatSpellOn_AutoAttack) { logger.LogInformation($"{source} -- React to {UI_ERROR.ERR_BADATTACKPOS} -- Interact!"); await input.TapInteractKey(""); await stopMoving.Stop(); await wait.Update(1); playerReader.LastUIErrorMessage = UI_ERROR.NONE; } else { logger.LogInformation($"{source} -- Didn't know how to React to {playerReader.LastUIErrorMessage}"); } break; default: logger.LogInformation($"{source} -- Didn't know how to React to {playerReader.LastUIErrorMessage}"); break; //case UI_ERROR.ERR_SPELL_FAILED_S: //case UI_ERROR.ERR_BADATTACKPOS: //case UI_ERROR.ERR_SPELL_OUT_OF_RANGE: //case UI_ERROR.ERR_AUTOFOLLOW_TOO_FAR: // this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; // break; } }
public override async Task PerformAction() { Log("Try to find Corpse"); npcNameFinder.ChangeNpcType(NpcNameFinder.NPCType.Corpse); await stopMoving.Stop(); // TODO: have to wait for the cursor to switch from loot -> skinning // sometimes takes a lot of time await npcNameFinder.WaitForNUpdate(1); if (await DiDEnteredCombat()) { await AquireTarget(); return; } Log("Found corpses: " + npcNameFinder.NpcCount); WowPoint lastPosition = playerReader.PlayerLocation; bool skinSuccess = await npcNameFinder.FindByCursorType(Cursor.CursorClassification.Skin); if (skinSuccess) { await Wait(100, () => false); if (IsPlayerMoving(lastPosition)) { Log("Goto corpse - Wait till the player become stil!"); } while (IsPlayerMoving(lastPosition)) { lastPosition = playerReader.PlayerLocation; if (!await Wait(100, DiDEnteredCombat())) { await AquireTarget(); return; } } await input.TapInteractKey("Skinning Attempt..."); do { await playerReader.WaitForNUpdate(1); if (await DiDEnteredCombat()) { await AquireTarget(); return; } } while (playerReader.IsCasting); // Wait for to update the LastUIErrorMessage await playerReader.WaitForNUpdate(1); var lastError = this.playerReader.LastUIErrorMessage; if (lastError != UI_ERROR.ERR_SPELL_FAILED_S) { this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; logger.LogDebug("Skinning Successful!"); await GoalExit(); } else { logger.LogDebug("Skinning Failed! Retry..."); } } else { logger.LogDebug($"Target is not skinnable - NPC Count: {npcNameFinder.NpcCount}"); await GoalExit(); } }