public async Task TapInteractKey(string source) { await input.TapInteractKey($"Approach target ({source})"); this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; await input.TapStopAttack(); }
public async Task <bool> Pull() { if (Keys.Count != 0) { await input.TapStopAttack(); await wait.Update(1); } if (playerReader.Bits.HasPet && !playerReader.PetHasTarget) { await input.TapPetAttack(); } bool castAny = false; foreach (var item in Keys) { var success = await castingHandler.CastIfReady(item, item.DelayBeforeCast); if (success) { if (!playerReader.HasTarget) { return(false); } castAny = true; if (item.WaitForWithinMeleeRange) { await WaitForWithinMeleeRange(item, success); } } } if (castAny) { (bool interrupted, double elapsedMs) = await wait.InterruptTask(1000, () => playerReader.TargetTarget == TargetTargetEnum.TargetIsTargettingMe || playerReader.TargetTarget == TargetTargetEnum.TargetIsTargettingPet); if (!interrupted) { Log($"Entered combat after {elapsedMs}ms"); } } return(playerReader.Bits.PlayerInCombat); }
public virtual async Task InteractOnUIError() { var lastError = this.playerReader.LastUIErrorMessage; switch (this.playerReader.LastUIErrorMessage) { case UI_ERROR.ERR_BADATTACKFACING: case UI_ERROR.ERR_SPELL_FAILED_S: case UI_ERROR.ERR_SPELL_OUT_OF_RANGE: case UI_ERROR.ERR_BADATTACKPOS: case UI_ERROR.ERR_AUTOFOLLOW_TOO_FAR: await input.TapStopAttack(this.playerReader.LastUIErrorMessage.ToString()); logger.LogInformation($"Interact due to: this.playerReader.LastUIErrorMessage: {this.playerReader.LastUIErrorMessage}"); var facing = this.playerReader.Direction; var location = this.playerReader.PlayerLocation; if (this.classConfig.Interact.MillisecondsSinceLastClick > 1000) { await input.TapInteractKey("CombatActionBase InteractOnUIError 1"); await Task.Delay(50); } if (lastError == UI_ERROR.ERR_SPELL_FAILED_S) { await input.TapInteractKey("CombatActionBase InteractOnUIError 2"); await playerReader.WaitForNUpdate(1); //3 if (this.playerReader.LastUIErrorMessage == UI_ERROR.ERR_BADATTACKPOS && this.playerReader.Direction == facing) { logger.LogInformation("Turning 180 as I have not moved!"); var desiredDirection = facing + Math.PI; desiredDirection = desiredDirection > Math.PI * 2 ? desiredDirection - Math.PI * 2 : desiredDirection; await this.direction.SetDirection(desiredDirection, new WowPoint(0, 0), "InteractOnUIError"); } } this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; break; } }
public async Task <GoapGoal?> GetAction() { if (playerReader.HealthPercent > 1 && blacklist.IsTargetBlacklisted()) { logger.LogWarning($"{GetType().Name}: Target is blacklisted - StopAttack & ClearTarget"); await input.TapStopAttack(""); await input.TapClearTarget(""); UpdateWorldState(); } var goal = new HashSet <KeyValuePair <GoapKey, GoapPreCondition> >(); //Plan Queue <GoapGoal> plan = planner.Plan(AvailableGoals, WorldState, goal); if (plan != null && plan.Count > 0) { if (CurrentGoal == plan.Peek() && !CurrentGoal.Repeatable) { logger.LogInformation($"Plan= {CurrentGoal.GetType().Name} is not Repeatable!"); CurrentGoal = null; } else { CurrentGoal = plan.Peek(); } } else { if (CurrentGoal != null && !CurrentGoal.Repeatable) { logger.LogInformation($"Plan= {CurrentGoal.GetType().Name} is not Repeatable!"); CurrentGoal = null; await stopMoving.Stop(); } } return(CurrentGoal); }
public override async Task PerformAction() { await input.TapStopAttack(); this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; if ((DateTime.Now - LastActive).TotalSeconds > 5) { PullStartTime = DateTime.Now; } LastActive = DateTime.Now; /* * if ((DateTime.Now - PullStartTime).TotalSeconds > 30) * { * //await wowProcess.KeyPress(ConsoleKey.F3, 50); // clear target * await wowProcess.TapClearTarget(); * await this.wowProcess.KeyPress(ConsoleKey.RightArrow, 1000, "Turn after pull timeout"); * return; * } */ SendActionEvent(new ActionEventArgs(GoapKey.fighting, true)); if (playerReader.PlayerBitValues.IsMounted) { logger.LogInformation($"Dismount"); await input.Dismount(); } if (ShouldStopBeforePull) { logger.LogInformation($"Stop approach"); await this.stopMoving.Stop(); await input.TapStopAttack(); await input.TapStopKey(); } bool pulled = await Pull(); if (!pulled) { if (HasPickedUpAnAdd) { logger.LogInformation($"Combat={this.playerReader.PlayerBitValues.PlayerInCombat}, Is Target targetting me={this.playerReader.PlayerBitValues.TargetOfTargetIsPlayer}"); logger.LogInformation($"Add on approach"); await this.stopMoving.Stop(); await input.TapStopKey(); //await wowProcess.KeyPress(ConsoleKey.F3, 50); // clear target //await wowProcess.TapClearTarget(); await input.TapNearestTarget(); if (this.playerReader.HasTarget && playerReader.PlayerBitValues.TargetInCombat) { if (this.playerReader.TargetTarget == TargetTargetEnum.TargetIsTargettingMe) { return; } } await input.TapClearTarget(); return; } if (!this.stuckDetector.IsMoving()) { await this.stuckDetector.Unstick(); } await Interact(); await this.playerReader.WaitForNUpdate(1); } else { this.SendActionEvent(new ActionEventArgs(GoapKey.pulled, true)); this.playerReader.LastUIErrorMessage = UI_ERROR.NONE; } }
public async Task <bool> CastIfReady(KeyAction item, int sleepBeforeCast = 0) { if (!CanRun(item)) { return(false); } if (item.ConsoleKey == 0) { return(false); } if (item.Name == classConfig.Approach.Name || item.Name == classConfig.AutoAttack.Name || item.Name == classConfig.Interact.Name) { await PressKeyAction(item); return(true); } bool beforeUsable = addonReader.UsableAction.Is(item); var beforeForm = playerReader.Form; if (!await SwitchToCorrectStanceForm(beforeForm, item)) { return(false); } if (beforeForm != playerReader.Form && !beforeUsable && !addonReader.UsableAction.Is(item)) { item.LogInformation(" ... after Form switch still not usable!"); return(false); } if (playerReader.Bits.IsAutoRepeatSpellOn_Shoot) { await input.TapStopAttack("Stop AutoRepeat Shoot"); await input.TapStopAttack("Stop AutoRepeat Shoot"); await wait.Update(1); (bool interrupted, double elapsedMs) = await wait.InterruptTask(GCD, () => addonReader.UsableAction.Is(item)); if (!interrupted) { item.LogInformation($" ... waited to end Shoot {elapsedMs}ms"); } } if (sleepBeforeCast > 0) { if (item.StopBeforeCast || item.HasCastBar) { await stopMoving.Stop(); await wait.Update(1); await stopMoving.Stop(); await wait.Update(1); } item.LogInformation($" Wait {sleepBeforeCast}ms before press."); await Task.Delay(sleepBeforeCast); } bool beforeHasTarget = playerReader.HasTarget; int auraHash = playerReader.AuraCount.Hash; if (!await WaitForGCD(item, beforeHasTarget)) { return(false); } if (!item.HasCastBar) { if (!await CastInstant(item)) { // try again after reacted to UI_ERROR if (!await CastInstant(item)) { return(false); } } } else { if (!await CastCastbar(item)) { // try again after reacted to UI_ERROR if (!await CastCastbar(item)) { return(false); } } } if (item.AfterCastWaitBuff) { (bool notappeared, double elapsedMs) = await wait.InterruptTask(MaxWaitBuffTimeMs, () => auraHash != playerReader.AuraCount.Hash); item.LogInformation($" ... AfterCastWaitBuff: Buff: {!notappeared} | pb: {playerReader.AuraCount.PlayerBuff} | pd: {playerReader.AuraCount.PlayerDebuff} | tb: {playerReader.AuraCount.TargetBuff} | td: {playerReader.AuraCount.TargetDebuff} | Delay: {elapsedMs}ms"); } if (item.DelayAfterCast != defaultKeyAction.DelayAfterCast) { if (item.DelayUntilCombat) // stop waiting if the mob is targetting me { item.LogInformation($" ... DelayUntilCombat ... delay after cast {item.DelayAfterCast}ms"); var sw = new Stopwatch(); sw.Start(); while (sw.ElapsedMilliseconds < item.DelayAfterCast) { await wait.Update(1); if (playerReader.Bits.TargetOfTargetIsPlayer) { break; } } } else if (item.DelayAfterCast > 0) { item.LogInformation($" ... delay after cast {item.DelayAfterCast}ms"); var result = await wait.InterruptTask(item.DelayAfterCast, () => beforeHasTarget != playerReader.HasTarget); if (!result.Item1) { item.LogInformation($" .... delay after cast interrupted, target changed {result.Item2}ms"); } else { item.LogInformation($" .... delay after cast not interrupted {result.Item2}ms"); } } } else { if (item.RequirementObjects.Any()) { (bool firstReq, double firstReqElapsedMs) = await wait.InterruptTask(SpellQueueTimeMs, () => !item.CanRun() ); item.LogInformation($" ... instant interrupt: {!firstReq} | CanRun:{item.CanRun()} | Delay: {firstReqElapsedMs}ms"); } } if (item.StepBackAfterCast > 0) { input.SetKeyState(ConsoleKey.DownArrow, true, false, $"Step back for {item.StepBackAfterCast}ms"); (bool notStepback, double stepbackElapsedMs) = await wait.InterruptTask(item.StepBackAfterCast, () => beforeHasTarget != playerReader.HasTarget); if (!notStepback) { item.LogInformation($" .... interrupted stepback | lost target? {beforeHasTarget != playerReader.HasTarget} | {stepbackElapsedMs}ms"); } input.SetKeyState(ConsoleKey.DownArrow, false, false); } if (item.AfterCastWaitNextSwing) { await wait.Update(1); } item.ConsumeCharge(); return(true); }