protected async Task Fight() { if (playerReader.Bits.HasPet && !playerReader.PetHasTarget) { await input.TapPetAttack(""); } foreach (var item in Keys) { if (!playerReader.HasTarget) { logger.LogInformation($"{GetType().Name}: Lost Target!"); await stopMoving.Stop(); return; } else { lastKnwonPlayerDirection = playerReader.Direction; lastKnownMinDistance = playerReader.MinRange; lastKnownMaxDistance = playerReader.MaxRange; } if (await castingHandler.CastIfReady(item, item.DelayBeforeCast)) { if (item.Name == classConfiguration.Approach.Name || item.Name == classConfiguration.AutoAttack.Name) { await castingHandler.ReactToLastUIErrorMessage($"{GetType().Name}: Fight {item.Name}"); } break; } } }
private async Task <bool> CastInstant(KeyAction item) { if (item.StopBeforeCast) { await stopMoving.Stop(); await wait.Update(1); } playerReader.CastEvent.ForceUpdate(0); int beforeCastEventValue = playerReader.CastEvent.Value; int beforeSpellId = playerReader.CastSpellId.Value; bool beforeUsable = addonReader.UsableAction.Is(item); await PressKeyAction(item); bool inputNotHappened; double inputElapsedMs; if (item.AfterCastWaitNextSwing) { (inputNotHappened, inputElapsedMs) = await wait.InterruptTask(MaxSwingTimeMs, interrupt : () => !addonReader.CurrentAction.Is(item), repeat : async() => { if (classConfig.Approach.GetCooldownRemaining() == 0) { await input.TapApproachKey(""); } }); } else { (inputNotHappened, inputElapsedMs) = await wait.InterruptTask(MaxWaitCastTimeMs, interrupt : () => (beforeSpellId != playerReader.CastSpellId.Value && beforeCastEventValue != playerReader.CastEvent.Value) || beforeUsable != addonReader.UsableAction.Is(item) ); } if (!inputNotHappened) { item.LogInformation($" ... instant input {inputElapsedMs}ms"); } else { item.LogInformation($" ... instant input not registered! {inputElapsedMs}ms"); return(false); } item.LogInformation($" ... usable: {beforeUsable}->{addonReader.UsableAction.Is(item)} -- ({(UI_ERROR)beforeCastEventValue}->{(UI_ERROR)playerReader.CastEvent.Value})"); if (!CastSuccessfull((UI_ERROR)playerReader.CastEvent.Value)) { await ReactToLastCastingEvent(item, $"{item.Name}-{GetType().Name}: CastInstant"); return(false); } return(true); }
public override async Task OnEnter() { await base.OnEnter(); if (playerReader.Bits.IsMounted) { await input.TapDismount(); } await input.TapApproachKey($"{GetType().Name}: OnEnter - Face the target and stop"); await stopMoving.Stop(); await wait.Update(1); pullStart = DateTime.Now; }
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() { 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() { if (playerReader.PlayerBitValues.IsMounted) { await input.Dismount(); } if (NeedsToReset) { this.stuckDetector.ResetStuckParameters(); } var location = playerReader.PlayerLocation; if (!playerReader.PlayerBitValues.PlayerInCombat) { playerWasInCombat = false; } else { // we are in combat if (!playerWasInCombat && HasPickedUpAnAdd) { logger.LogInformation("WARN Bodypull -- Looks like we have an add on approach"); logger.LogInformation($"Combat={this.playerReader.PlayerBitValues.PlayerInCombat}, Is Target targetting me={this.playerReader.PlayerBitValues.TargetOfTargetIsPlayer}"); await this.stopMoving.Stop(); await input.TapClearTarget(); await input.TapStopKey(); if (playerReader.PetHasTarget) { await this.input.TapTargetPet(); await this.input.TapTargetOfTarget(); } } playerWasInCombat = true; } await this.TapInteractKey("ApproachTargetAction 1"); await this.playerReader.WaitForNUpdate(1); var newLocation = playerReader.PlayerLocation; if ((location.X == newLocation.X && location.Y == newLocation.Y && SecondsSinceLastFighting > 5) || this.playerReader.LastUIErrorMessage == UI_ERROR.ERR_AUTOFOLLOW_TOO_FAR) { input.SetKeyState(ConsoleKey.UpArrow, true, false, "ApproachTargetAction"); await Wait(100, () => false); await input.TapJump(); this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; } await RandomJump(); // int approachSeconds = (int)(this.stuckDetector.actionDurationSeconds); if (approachSeconds > 20) { await this.stuckDetector.Unstick(); await this.TapInteractKey("ApproachTargetAction unstick"); await Task.Delay(250); } if (playerReader.WithInCombatRange && ( playerReader.PlayerClass == PlayerClassEnum.Rogue || playerReader.PlayerClass == PlayerClassEnum.Warrior || playerReader.PlayerClass == PlayerClassEnum.Paladin)) { Log("WithInCombatRange -- Strictly melee -- Wait a moment"); await stopMoving.Stop(); await this.TapInteractKey("ApproachTargetAction engage"); await Task.Delay(200); } }
public override async Task PerformAction() { if (Keys.Any(k => k.StopBeforeCast)) { await stopMoving.Stop(); await wait.Update(1); if (playerReader.Bits.IsMounted) { await input.TapDismount(); await wait.Update(1); //if (!await Wait(1000, () => playerReader.PlayerBitValues.PlayerInCombat)) return; // vanilla after dismout GCD } } await AsyncExt.Loop(Keys, async (KeyAction key) => { var pressed = await castingHandler.CastIfReady(key, key.DelayBeforeCast); key.ResetCooldown(); key.SetClicked(); }); bool wasDrinkingOrEating = playerReader.Buffs.Drinking || playerReader.Buffs.Eating; logger.LogInformation($"Waiting for {Name}"); DateTime startTime = DateTime.Now; while ((playerReader.Buffs.Drinking || playerReader.Buffs.Eating || playerReader.IsCasting) && !playerReader.Bits.PlayerInCombat) { await wait.Update(1); if (playerReader.Buffs.Drinking && playerReader.Buffs.Eating) { if (playerReader.ManaPercentage > 98 && playerReader.HealthPercent > 98) { break; } } else if (playerReader.Buffs.Drinking) { if (playerReader.ManaPercentage > 98) { break; } } else if (playerReader.Buffs.Eating) { if (playerReader.HealthPercent > 98) { break; } } if ((DateTime.Now - startTime).TotalSeconds >= 25) { logger.LogInformation($"Waited (25s) long enough for {Name}"); break; } } if (wasDrinkingOrEating) { await input.TapStandUpKey(); } }
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() { lastPlayerLocation = playerReader.PlayerLocation; await wait.Update(1); if (!playerReader.Bits.PlayerInCombat) { playerWasInCombat = false; } else { // we are in combat if (!playerWasInCombat && HasPickedUpAnAdd) { logger.LogInformation("WARN Bodypull -- Looks like we have an add on approach"); logger.LogInformation($"Combat={playerReader.Bits.PlayerInCombat}, Is Target targetting me={playerReader.Bits.TargetOfTargetIsPlayer}"); await stopMoving.Stop(); await input.TapClearTarget(); await wait.Update(1); if (playerReader.PetHasTarget) { await input.TapTargetPet(); await input.TapTargetOfTarget(); await wait.Update(1); } } playerWasInCombat = true; } if (input.ClassConfig.Approach.GetCooldownRemaining() == 0) { await input.TapApproachKey(""); } lastPlayerDistance = WowPoint.DistanceTo(lastPlayerLocation, playerReader.PlayerLocation); if (lastPlayerDistance < 0.05 && playerReader.LastUIErrorMessage == UI_ERROR.ERR_AUTOFOLLOW_TOO_FAR) { playerReader.LastUIErrorMessage = UI_ERROR.NONE; input.SetKeyState(ConsoleKey.UpArrow, true, false, $"{GetType().Name}: Too far, start moving forward!"); await wait.Update(1); } if (SecondsSinceApproachStarted > 1 && lastPlayerDistance < 0.05 && !playerReader.Bits.PlayerInCombat) { await input.TapClearTarget(""); await wait.Update(1); await input.KeyPress(random.Next(2) == 0?ConsoleKey.LeftArrow : ConsoleKey.RightArrow, 1000, $"Seems stuck! Clear Target. Turn away. d: {lastPlayerDistance}"); approachStart = DateTime.Now; } if (SecondsSinceApproachStarted > 15 && !playerReader.Bits.PlayerInCombat) { await input.TapClearTarget(""); await wait.Update(1); await input.KeyPress(random.Next(2) == 0?ConsoleKey.LeftArrow : ConsoleKey.RightArrow, 1000, "Too long time. Clear Target. Turn away."); approachStart = DateTime.Now; } if (playerReader.TargetGuid == initialTargetGuid) { var initialTargetMinRange = playerReader.MinRange; if (!playerReader.Bits.PlayerInCombat) { await input.TapNearestTarget("Try to find closer target..."); await wait.Update(1); } if (playerReader.TargetGuid != initialTargetGuid) { if (playerReader.HasTarget) // blacklist { if (playerReader.MinRange < initialTargetMinRange) { Log($"Found a closer target! {playerReader.MinRange} < {initialTargetMinRange}"); initialMinRange = playerReader.MinRange; } else { initialTargetGuid = -1; await input.TapLastTargetKey($"Stick to initial target!"); await wait.Update(1); } } else { Log($"Lost the target due blacklist!"); } } } if (initialMinRange < playerReader.MinRange && !playerReader.Bits.PlayerInCombat) { Log($"We are going away from the target! {initialMinRange} < {playerReader.MinRange}"); await input.TapClearTarget(); await wait.Update(1); approachStart = DateTime.Now; } await RandomJump(); }
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 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(); } }