コード例 #1
0
        public async Task TapInteractKey(string source)
        {
            await input.TapInteractKey($"Approach target ({source})");

            this.playerReader.LastUIErrorMessage = UI_ERROR.NONE;
            await input.TapStopAttack();
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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;
            }
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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;
            }
        }
コード例 #6
0
        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);
        }