コード例 #1
0
        public override void OnStart()
        {
            // Let QuestBehaviorBase do basic initializaion of the behavior, deal with bad or deprecated attributes,
            // capture configuration state, install BT hooks, etc.  This will also update the goal text.
            var isBehaviorShouldRun = OnStart_QuestBehaviorCore();

            // If the quest is complete, this behavior is already done...
            // So we don't want to falsely inform the user of things that will be skipped.
            if (isBehaviorShouldRun)
            {
                _flightTimer.Reset();
                this.UpdateGoalText(GetQuestId());
            }
        }
コード例 #2
0
        private async Task <bool> Coroutine_CombatMain()
        {
            if (!ImmediatelySwitchToHighestPriorityTarget || !_targetSwitchTimer.IsFinished ||
                BotPoi.Current.Type != PoiType.Kill || !Me.Combat ||
                // Let quest bot handle targeting when we don't have any targets. High priority targets will be picked first as they are weighted more in targeting.
                // Otherwise, there is a race condition happens where we immediately pick a new target when current one dies and we are still in combat for split second.
                // This was causing the looting etc. to be skipped
                Me.CurrentTarget == null || Me.CurrentTarget.IsDead)
            {
                return(false);
            }

            var firstUnit = Targeting.Instance.FirstUnit;

            if (!Query.IsViable(firstUnit))
            {
                return(false);
            }

            if (firstUnit != BotPoi.Current.AsObject)
            {
                BotPoi.Current = new BotPoi(firstUnit, PoiType.Kill, QuestOrder.Instance.NavType);
                QBCLog.Info("Current POI is not the best target. Changing.");
                _targetSwitchTimer.Reset();
            }
            return(false);
        }
コード例 #3
0
        public override void OnStart()
        {
            // Let QuestBehaviorBase do basic initializaion of the behavior, deal with bad or deprecated attributes,
            // capture configuration state, install BT hooks, etc.  This will also update the goal text.
            var isBehaviorShouldRun = OnStart_QuestBehaviorCore();

            // If the quest is complete, this behavior is already done...
            // So we don't want to falsely inform the user of things that will be skipped.
            if (isBehaviorShouldRun)
            {
                int waitDuration = WaitTime + StyxWoW.Random.Next(VariantTime);

                _timer            = new Styx.Common.Helpers.WaitTimer(TimeSpan.FromMilliseconds(waitDuration));
                _waitTimeAsString = Utility.PrettyTime(_timer.WaitTime);

                _timer.Reset();

                this.UpdateGoalText(GetQuestId(), "Waiting for " + _waitTimeAsString);
            }
        }
コード例 #4
0
        /// <summary>Waits until a result is available for a spell cast and then retrurn it.</summary>
        /// <param name="maxTimeoutMs">The maximum timeout in milliseconds.</param>
        public async Task <SpellCastResult> GetResult(int maxTimeoutMs = 15000)
        {
            var timer = new WaitTimer(TimeSpan.FromMilliseconds(StyxWoW.WoWClient.Latency * 2 + 50));

            timer.Reset();
            var         startedCast = false;
            Func <bool> beganCast   = () =>
            {
                startedCast = startedCast || StyxWoW.Me.IsCasting;
                return(startedCast);
            };

            await Coroutine.Wait(maxTimeoutMs, () => HasResult || timer.IsFinished && !beganCast());

            if (!HasResult && timer.IsFinished && !beganCast())
            {
                return(SpellCastResult.NoCastStarted);
            }

            return(Result);
        }
コード例 #5
0
        protected Composite CreateBehavior_Antistuck()
        {
            var      prevPosition  = WoWPoint.Empty;
            WoWPoint myLoc         = WoWPoint.Empty;
            var      moveDirection = WoWMovement.MovementDirection.None;

            return(new PrioritySelector(
                       new Decorator(
                           ctx => _stuckTimer.IsFinished,
                           new Sequence(
                               ctx => myLoc = WoWMovement.ActiveMover.Location,
                               // checks if stuck
                               new DecoratorContinue(
                                   ctx => myLoc.DistanceSqr(prevPosition) < 3 * 3,
                                   new Sequence(
                                       ctx => moveDirection = GetRandomMovementDirection(),
                                       new Action(ctx => QBCLog.Debug("Stuck. Movement Directions: {0}", moveDirection)),
                                       new Action(ctx => WoWMovement.Move(moveDirection)),
                                       new WaitContinue(2, ctx => false, new ActionAlwaysSucceed()),
                                       new Action(ctx => WoWMovement.MoveStop(moveDirection)))),

                               new Action(ctx => prevPosition = myLoc),
                               new Action(ctx => _stuckTimer.Reset())))));
        }
コード例 #6
0
        public Composite CreateBehavior_KillMantid()
        {
            WoWUnit   attackTarget   = null;
            WoWUnit   yeti           = null;
            WaitTimer leapSmashTimer = WaitTimer.TenSeconds;

            return(new Decorator(r => !Me.IsQuestComplete(QuestId) && Query.IsInVehicle() && (yeti = Me.CharmedUnit) != null,
                                 new PrioritySelector(ctx => attackTarget = GetAttackTarget(),
                                                      new Decorator(ctx => attackTarget != null,
                                                                    new PrioritySelector(
                                                                        new ActionFail(ctx => _stuckTimer.Reset()),
                                                                        new ActionSetActivity("Moving to Attack"),
                                                                        new Decorator(ctx => Me.CurrentTargetGuid != attackTarget.Guid,
                                                                                      new ActionFail(ctx => attackTarget.Target())),
                                                                        new Decorator(ctx => !Me.IsSafelyFacing(attackTarget) || !yeti.IsSafelyFacing(attackTarget),
                                                                                      new ActionFail(ctx => attackTarget.Face())),
                                                                        // cast 'Hozen Snack' ability to heal up.
                                                                        new Decorator(ctx => yeti.HealthPercent <= 70,
                                                                                      new ActionFail(ctx => Lua.DoString("CastPetAction(4)"))),
                                                                        // cast 'Leap Smash' ability on targets outside of melee
                                                                        new Decorator(
                                                                            ctx =>
                                                                            yeti.Location.DistanceSqr(attackTarget.Location) > 30 * 30 && yeti.Location.DistanceSqr(attackTarget.Location) < 90 * 90 && leapSmashTimer.IsFinished,
                                                                            new Sequence(
                                                                                new Action(ctx => Lua.DoString("CastPetAction(1)")),
                                                                                new WaitContinue(2, ctx => StyxWoW.Me.CurrentPendingCursorSpell != null, new ActionAlwaysSucceed()),
                                                                                new Action(ctx => SpellManager.ClickRemoteLocation(attackTarget.Location)),
                                                                                new Action(ctx => leapSmashTimer.Reset()))),
                                                                        // cast 'Headbutt' ability on melee range target.
                                                                        new Decorator(
                                                                            ctx => yeti.Location.DistanceSqr(attackTarget.Location) <= 25 * 25,
                                                                            new PrioritySelector(
                                                                                new Decorator(
                                                                                    ctx => yeti.Location.DistanceSqr(attackTarget.Location) <= 25 * 25 && (Me.IsMoving || Me.CharmedUnit.IsMoving),
                                                                                    new ActionFail(ctx => WoWMovement.ClickToMove(Me.CharmedUnit.Location))),
                                                                                new Action(ctx => Lua.DoString("CastPetAction(2)")))),
                                                                        new Decorator(ctx => yeti.Location.DistanceSqr(attackTarget.Location) > 25 * 25,
                                                                                      new Action(ctx => Navigator.MoveTo(attackTarget.Location))))),
                                                      new Decorator(
                                                          ctx => attackTarget == null,
                                                          new PrioritySelector(
                                                              new Decorator(
                                                                  ctx => yeti.Location.DistanceSqr(_waitPoint) > 10 * 10,
                                                                  new PrioritySelector(
                                                                      // can't set path precision so I'll just handle it directly...
                                                                      // the yeti takes wide turns so needs a higher path precision than normal
                                                                      new Decorator(
                                                                          ctx =>
            {
                var nav = Navigator.NavigationProvider as MeshNavigator;
                if (nav == null)
                {
                    return false;
                }
                if (nav.CurrentMovePath == null || nav.CurrentMovePath.Index >= nav.CurrentMovePath.Path.Points.Length)
                {
                    return false;
                }
                WoWPoint point = nav.CurrentMovePath.Path.Points[nav.CurrentMovePath.Index];
                return point.DistanceSqr(yeti.Location) < 6 * 6;
            },
                                                                          new Action(ctx => ((MeshNavigator)Navigator.NavigationProvider).CurrentMovePath.Index++)),

                                                                      CreateBehavior_Antistuck(),

                                                                      new Action(ctx => Navigator.MoveTo(_waitPoint)))),
                                                              new ActionSetActivity("No viable targets, waiting."))),
                                                      new ActionAlwaysSucceed())));
        }
        private async Task <bool> MainCoroutine()
        {
            if (IsDone)
            {
                return(false);
            }

            if (!Query.IsInVehicle())
            {
                return(await UtilityCoroutine.MountVehicle((int)KovokId, _kovokLoc));
            }

            var ct        = Me.CurrentTarget;
            var transport = (WoWUnit)Me.Transport;

            if (transport == null)
            {
                return(false);
            }

            if (ct == null)
            {
                var newTarget = GetNearestAttacker() ?? GetNearestTarget();
                if (newTarget != null)
                {
                    newTarget.Target();
                    _targetTimer.Reset();
                    return(true);
                }
                // move to waypoints searching for targets.
                if (transport.Location.DistanceSqr(_path.Peek()) < 15 * 15)
                {
                    _path.Dequeue();
                }
                return((await CommonCoroutines.MoveTo(_path.Peek())).IsSuccessful());
            }

            if (ct.IsDead)
            {
                Me.ClearTarget();
                return(true);
            }

            // blacklist target if it's taking too long to kill.
            if (_targetTimer.IsFinished)
            {
                Blacklist.Add(ct, BlacklistFlags.Combat, TimeSpan.FromMinutes(3));
                Me.ClearTarget();
            }


            if (transport.Location.DistanceSqr(ct.Location) > 35 * 35)
            {
                return((await CommonCoroutines.MoveTo(ct.Location)).IsSuccessful());
            }

            if (!transport.IsSafelyFacing(ct, 40))
            {
                ct.Face();
                return(true);
            }

            if (transport.IsMoving)
            {
                //WoWMovement.MoveStop();
                // WoWMovement.MoveStop doesn't seem to work...
                WoWMovement.ClickToMove(transport.Location);
                return(true);
            }

            var actionButton = ActionBar.Active.Buttons.FirstOrDefault(b => b.Index != 2 && b.CanUse);

            if (actionButton != null)
            {
                actionButton.Use();
                await Coroutine.Sleep(Delay.AfterWeaponFire);

                return(true);
            }

            return(false);
        }
コード例 #8
0
        private async Task <bool> ScareSpiders()
        {
            // if not in a turret than move to one and interact with it
            if (!Query.IsInVehicle())
            {
                var mustang = GetMustang();
                if (mustang == null)
                {
                    QBCLog.Warning("No mustang was found nearby");
                    return(false);
                }

                TreeRoot.StatusText = "Moving To Mustang";
                if (mustang.DistanceSqr > 5 * 5)
                {
                    return((await CommonCoroutines.MoveTo(mustang.Location)).IsSuccessful());
                }

                await CommonCoroutines.LandAndDismount();

                QBCLog.Info("Interacting with Mustang");
                mustang.Interact();
                return(true);
            }

            // Find the nearest spider and if none exist then move to the spawn location
            if (!Query.IsViable(_currentTarget) || !_currentTarget.IsAlive)
            {
                _currentTarget = ObjectManager.GetObjectsOfType <WoWUnit>()
                                 .Where(u => u.IsAlive && u.Entry == 44284 && !Blacklist.Contains(u, BlacklistFlags.Interact))
                                 .OrderBy(u => u.DistanceSqr).FirstOrDefault();

                if (_currentTarget == null)
                {
                    if (!Navigator.AtLocation(_spiderSpawnLocation))
                    {
                        return((await CommonCoroutines.MoveTo(_spiderSpawnLocation)).IsSuccessful());
                    }
                    TreeRoot.StatusText = "Waiting for spiders to spawn";
                    return(true);
                }
                _noMoveBlacklistTimer.Reset();
                _blacklistTimer.Reset();
                QBCLog.Info("Locked on a new target. Distance {0}", _currentTarget.Distance);
            }

            TreeRoot.StatusText = "Scaring spider towards lumber mill";

            var moveToPoint = WoWMathHelper.CalculatePointFrom(_lumberMillLocation, _currentTarget.Location, -6);

            if (moveToPoint.DistanceSqr((WoWMovement.ActiveMover ?? StyxWoW.Me).Location) > 4 * 4)
            {
                return((await CommonCoroutines.MoveTo(moveToPoint)).IsSuccessful());
            }

            // spider not moving? blacklist and find a new target.
            if (_noMoveBlacklistTimer.ElapsedMilliseconds > 20000 && _currentTarget.Location.DistanceSqr(_spiderScareLoc) < 10 * 10)
            {
                Blacklist.Add(_currentTarget, BlacklistFlags.Interact, TimeSpan.FromMinutes(3), "Spider is not moving");
                _currentTarget = null;
            }
            else if (_blacklistTimer.IsFinished)
            {
                Blacklist.Add(_currentTarget, BlacklistFlags.Interact, TimeSpan.FromMinutes(3), "Took too long");
                _currentTarget = null;
            }
            else if (!_currentTarget.HasAura("Fear"))
            {
                await CommonCoroutines.StopMoving();

                Me.SetFacing(_lumberMillLocation);
                await CommonCoroutines.SleepForLagDuration();

                await Coroutine.Sleep(200);

                if (!_noMoveBlacklistTimer.IsRunning || _currentTarget.Location.DistanceSqr(_spiderScareLoc) >= 10 * 10)
                {
                    _noMoveBlacklistTimer.Restart();
                    _spiderScareLoc = _currentTarget.Location;
                }
                Lua.DoString("CastSpellByID(83605)");
                await Coroutine.Wait(3000, () => Query.IsViable(_currentTarget) && _currentTarget.HasAura("Fear"));
            }

            return(true);
        }
コード例 #9
0
        public Composite CreateBehavior_KillMantid()
        {
            WoWUnit   attackTarget        = null;
            WoWUnit   IronShredder        = null;
            WaitTimer DeathFromAboveTimer = WaitTimer.TenSeconds;

            return(new Decorator(r => !Me.IsQuestComplete(QuestId) && Query.IsInVehicle() && (IronShredder = Me.CharmedUnit) != null,
                                 new PrioritySelector(ctx => attackTarget = GetAttackTarget(),
                                                      new Decorator(ctx => attackTarget != null,
                                                                    new PrioritySelector(
                                                                        new ActionSetActivity("Moving to Attack"),
                                                                        new Decorator(ctx => Me.CurrentTargetGuid != attackTarget.Guid,
                                                                                      new ActionFail(ctx => attackTarget.Target())),
                                                                        new Decorator(ctx => !Me.IsSafelyFacing(attackTarget) || !IronShredder.IsSafelyFacing(attackTarget),
                                                                                      new ActionFail(ctx => attackTarget.Face())),

                                                                        // cast 'Death From Above' ability on targets outside of melee
                                                                        new Decorator(
                                                                            ctx =>
                                                                            IronShredder.Location.DistanceSquared(attackTarget.Location) > 10 * 10 && IronShredder.Location.DistanceSquared(attackTarget.Location) < 70 * 70 && DeathFromAboveTimer.IsFinished,
                                                                            new Sequence(
                                                                                new Action(ctx => Lua.DoString("CastPetAction(2)")),
                                                                                new WaitContinue(2, ctx => StyxWoW.Me.CurrentPendingCursorSpell != null, new ActionAlwaysSucceed()),
                                                                                new Action(ctx => SpellManager.ClickRemoteLocation(attackTarget.Location)),
                                                                                new Action(ctx => DeathFromAboveTimer.Reset()))),

                                                                        // cast 'Elecrostatic Distortion' ability on melee range target.
                                                                        new Decorator(
                                                                            ctx => IronShredder.Location.DistanceSquared(attackTarget.Location) <= 25 * 25,
                                                                            new PrioritySelector(
                                                                                new Decorator(
                                                                                    ctx => IronShredder.Location.DistanceSquared(attackTarget.Location) <= 25 * 25 && (Me.IsMoving || Me.CharmedUnit.IsMoving),
                                                                                    new ActionFail(ctx => WoWMovement.ClickToMove(Me.CharmedUnit.Location))),
                                                                                new Action(ctx => Lua.DoString("CastPetAction(1)")))),
                                                                        new Decorator(ctx => IronShredder.Location.DistanceSquared(attackTarget.Location) > 25 * 25,
                                                                                      new Action(ctx => Navigator.MoveTo(attackTarget.Location))))),
                                                      new Decorator(
                                                          ctx => attackTarget == null,
                                                          new PrioritySelector(
                                                              new Decorator(
                                                                  ctx => IronShredder.Location.DistanceSquared(_waitPoint) > 10 * 10,
                                                                  new PrioritySelector(
                                                                      new Action(ctx => Navigator.MoveTo(_waitPoint)))),
                                                              new ActionSetActivity("No viable targets, waiting."))),
                                                      new ActionAlwaysSucceed())));
        }
        public Composite CreateBehavior_KillGnomereganStealthFighter()
        {
            WoWUnit   attackTarget           = null;
            WoWUnit   PrideofKezan           = null;
            WaitTimer WildWeaselRocketsTimer = WaitTimer.FiveSeconds;

            return(new Decorator(r => !Me.IsQuestComplete(QuestId) && Query.IsInVehicle() && (PrideofKezan = Me.CharmedUnit) != null,
                                 new PrioritySelector(ctx => attackTarget = GetAttackTarget(),
                                                      new Decorator(ctx => attackTarget != null,
                                                                    new PrioritySelector(
                                                                        new ActionSetActivity("Moving to Attack"),
                                                                        new Decorator(ctx => Me.CurrentTargetGuid != attackTarget.Guid,
                                                                                      new ActionFail(ctx => attackTarget.Target())),
                                                                        new Decorator(ctx => !Me.IsSafelyFacing(attackTarget) || !PrideofKezan.IsSafelyFacing(attackTarget),
                                                                                      new ActionFail(ctx => attackTarget.Face())),

                                                                        // cast 'Wild Weasel Rockets' ability
                                                                        new Decorator(
                                                                            ctx => PrideofKezan.Location.DistanceSqr(attackTarget.Location) < 25 * 25 && WildWeaselRocketsTimer.IsFinished,
                                                                            new Sequence(
                                                                                new Action(ctx => Lua.DoString("CastPetAction(2)")),
                                                                                new Action(ctx => WildWeaselRocketsTimer.Reset()))),

                                                                        // cast 'Machine Gun' ability
                                                                        new Decorator(
                                                                            ctx => PrideofKezan.Location.DistanceSqr(attackTarget.Location) <= 25 * 25,
                                                                            new Sequence(
                                                                                new Action(ctx => Lua.DoString("CastPetAction(1)")))),

                                                                        new Decorator(ctx => PrideofKezan.Location.DistanceSqr(attackTarget.Location) > 25 * 25,
                                                                                      new Action(ctx => WoWMovement.ClickToMove(attackTarget.Location))))),
                                                      new Decorator(
                                                          ctx => attackTarget == null,
                                                          new PrioritySelector(
                                                              new Decorator(
                                                                  ctx => PrideofKezan.Location.DistanceSqr(_waitPoint) > 10 * 10,
                                                                  new Sequence(
                                                                      new Action(ctx => WoWMovement.ClickToMove(_waitPoint)))),
                                                              new ActionSetActivity("No viable targets, waiting."))),
                                                      new ActionAlwaysSucceed())));
        }
コード例 #11
0
        private async Task TargetLogic(WoWUnit target)
        {
            if (!Query.IsViable(target))
            {
                return;
            }

            var targetDistSqr = target.Location.DistanceSquared(Vehicle.Location);

            if (PickUpPassengerButton == 0)
            {
                TreeRoot.StatusText = string.Format("Blowing stuff up. {0} mins before resummon is required",
                                                    _flightTimer.TimeLeft.TotalMinutes);

                if (HealButton > 0 && targetDistSqr < 60 * 60 &&
                    (Vehicle.HealthPercent <= HealPercent || Vehicle.ManaPercent <= HealPercent) &&
                    UseVehicleButton(HealButton))
                {
                    QBCLog.Info("Used heal button {0} on NPC:{1}", HealButton, target.SafeName);
                    return;
                }

                // return when a button is used.
                foreach (var button in Buttons)
                {
                    if (UseVehicleButton(button))
                    {
                        return;
                    }
                }
                return;
            }

            TreeRoot.StatusText = string.Format("Rescuing {0}", target.SafeName);
            var pickTimer = new WaitTimer(TimeSpan.FromSeconds(20));

            pickTimer.Reset();
            while (target.IsValid && target.IsAlive && !UnitIsRidingMyVehicle(target) && Query.IsInVehicle() && !pickTimer.IsFinished)
            {
                Vector3 clickLocation = target.Location.RayCast(target.Rotation, 6);
                clickLocation.Z += 3;
                if (Vehicle.Location.DistanceSquared(clickLocation) > 3 * 3)
                {
                    Stopwatch timer = Stopwatch.StartNew();
                    do
                    {
                        Flightor.MoveTo(clickLocation);
                        await Coroutine.Yield();
                    } while (timer.ElapsedMilliseconds < 1000 && Vehicle.Location.DistanceSquared(clickLocation) > 3 * 3);
                }
                else
                {
                    if (Vehicle.IsMoving)
                    {
                        await CommonCoroutines.StopMoving(string.Format("Picking up {0}", target.SafeName));
                    }
                    UseVehicleButton(PickUpPassengerButton);
                    if (await Coroutine.Wait(4000, () => UnitIsRidingMyVehicle(target)))
                    {
                        QBCLog.Info("Successfully picked up passenger {0}", target.SafeName);
                        return;
                    }
                    QBCLog.Info("Failed to picked up passenger {0}", target.SafeName);
                    await Coroutine.Yield();
                }
            }
        }