Exemplo n.º 1
0
        private Composite StateBehaviorPS_PathRetreating()
        {
            return(new PrioritySelector(
                       // If no Egress path, build it...
                       new Decorator(context => Path_Egress == null,
                                     new Action(context =>
            {
                Path_Egress = FollowPath.FindPath_Egress(Mob_ToAvoid);
                QBCLog.Info("Retreating back to safespot due to {0}.",
                            Me.Combat
                            ? "combat"
                            : string.Format("{0} too close (dist: {1:F1})", Mob_ToAvoid.SafeName, Mob_ToAvoid.Distance));
            })),

                       // If we've come to the end of our egress path, move back to safe spot...
                       new Decorator(context => !Path_Egress.Any(),
                                     new Action(context =>
            {
                Path_Ingress = null;
                Path_Egress = null;
                State_MainBehavior = StateType_MainBehavior.MovingToSafespot;
            })),

                       // If we've arrived at the current waypoint, dequeue it...
                       new Decorator(context => Navigator.AtLocation(Path_Egress.Peek().Location),
                                     new Action(context => { Path_Egress.Dequeue(); })),

                       new ActionRunCoroutine(
                           context => UtilityCoroutine.MoveTo(
                               Path_Egress.Peek().Location,
                               "retreat",
                               MovementBy))
                       ));
        }
            public override async Task <bool> Execute()
            {
                // If we have the quest, drop it...
                if (HasQuest(QuestId))
                {
                    Me.QuestLog.AbandonQuestById((uint)QuestId);
                    await Coroutine.Wait(Delay.LagDuration, () => !HasQuest(QuestId));

                    return(true);
                }

                // If we cannot 'see' the mob yet, move to the rough location...
                var questGiver = ObjectManager.GetObjectsOfType <WoWUnit>().FirstOrDefault(u => u.Entry == QuestGiverId);

                if (questGiver == null)
                {
                    await UtilityCoroutine.MoveTo(QuestGiverRoughLocation, "Quest Giver");

                    return(true);
                }

                if (!Navigator.AtLocation(questGiver.Location))
                {
                    return(await UtilityCoroutine.MoveTo(questGiver.Location, questGiver.Name));
                }

                await ScriptHelpers.PickupQuest(questGiver, (uint)QuestId);

                await Coroutine.Wait(Delay.LagDuration, () => HasQuest(QuestId));

                return(false);
            }
        private async Task <bool> UtilityCoroutine_MoveToStartPosition()
        {
            if (Navigator.AtLocation(WaitPoint))
            {
                return(false);
            }

            return(await UtilityCoroutine.MoveTo(WaitPoint, "Moving to start position", MovementByType.NavigatorOnly));
        }
Exemplo n.º 4
0
        protected override Composite CreateMainBehavior()
        {
            return(new PrioritySelector(
                       // If we don't have a selected target, find one...
                       new Decorator(context => !IsMobQualified(SelectedTarget),
                                     new PrioritySelector(
                                         new ActionFail(context => { SelectedTarget = FindQualifiedMob(); }),

                                         // No qualifed mobs in immediate vicinity...
                                         new Decorator(context => !IsMobQualified(SelectedTarget),
                                                       new PrioritySelector(
                                                           new Decorator(context => Me.GotTarget,
                                                                         new Action(context => { Me.ClearTarget(); })),

                                                           // NB: if the terminateBehaviorIfNoTargetsProvider argument evaluates to 'true', calling
                                                           // this sub-behavior will terminate the overall behavior.
                                                           new ActionRunCoroutine(context =>
                                                                                  _noMobsAtCurrentWaypoint ??
                                                                                  (_noMobsAtCurrentWaypoint =
                                                                                       new UtilityCoroutine.NoMobsAtCurrentWaypoint(
                                                                                           () => HuntingGrounds,
                                                                                           () => MovementBy,
                                                                                           null,
                                                                                           () => { if (!WaitForNpcs)
                                                                                                   {
                                                                                                       BehaviorDone("Terminating--\"WaitForNpcs\" is false.");
                                                                                                   }
                                                                                           },
                                                                                           () => TargetExclusionAnalysis.Analyze(
                                                                                               Element,
                                                                                               () => Query.FindMobsAndFactions(MobIds),
                                                                                               TargetExclusionChecks))))))
                                         )),

                       // If qualified mob was found, move within range, if needed...
                       // NB: A mob can lose its 'qualified' status for several reasons.  For instance,
                       // another player moves close to or tags the mob while we're on our way to it.
                       new Decorator(context => IsMobQualified(SelectedTarget),
                                     new PrioritySelector(
                                         new ActionFail(context => { Utility.Target(SelectedTarget); }),
                                         new Decorator(context => IsDistanceCloseNeeded(SelectedTarget),
                                                       new ActionRunCoroutine(
                                                           context => UtilityCoroutine.MoveTo(
                                                               SelectedTarget.Location,
                                                               SelectedTarget.SafeName,
                                                               MovementBy))),
                                         new ActionRunCoroutine(context => CommonCoroutines.StopMoving()),
                                         new Action(context =>
            {
                Utility.Target(SelectedTarget, true);
                BehaviorDone();
            })
                                         ))
                       ));
        }
        private async Task <bool> MainCoroutine()
        {
            if (IsDone)
            {
                return(false);
            }

            if (TookPortal)
            {
                if (Me.IsMoving)
                {
                    await CommonCoroutines.StopMoving();
                }
                await Coroutine.Sleep(_postZoningDelay);

                BehaviorDone("Zoned into portal");
                return(true);
            }

            if (Navigator.AtLocation(StartingPoint) && await WaitToRetry())
            {
                return(true);
            }

            // Move to portal starting position...
            if (!Navigator.AtLocation(StartingPoint))
            {
                if (!await UtilityCoroutine.MoveTo(StartingPoint, "Portal", MovementBy))
                {
                    QBCLog.Fatal("Unable to Navigate to StartingPoint");
                }
                return(true);
            }


            if (await EnterPortal())
            {
                return(true);
            }

            // Zoning failed, do we have any retries left?
            _retryCount += 1;
            if (_retryCount > MaxRetryCount)
            {
                var message = string.Format("Unable to go through portal in {0} attempts.", MaxRetryCount);

                // NB: Posting a 'fatal' message will stop the bot--which is what we want.
                QBCLog.Fatal(message);
                BehaviorDone(message);
                return(true);
            }

            RetryDelayTimer = new Stopwatch();
            return(true);
        }
        private async Task <bool> MainLogic()
        {
            if (!Me.IsAlive)
            {
                return(false);
            }

            var bomb  = Me.BagItems.FirstOrDefault(i => Query.IsViable(i) && i.Entry == 60849 || i.Entry == 60678);
            var bunny = ObjectManager.GetObjectsOfType <WoWUnit>()
                        .Where(r => r.Entry == 44360)
                        .OrderBy(r => r.Distance2D)
                        .FirstOrDefault();

            //Remove hook once were done with the quest
            if (bomb == null)
            {
                RemoveHook();
                return(true);
            }

            if (bunny != null)
            {
                var bunnyDist = bunny.DistanceSqr;
                if (bunnyDist < 5 * 5)
                {
                    bomb.Use();
                    SpellManager.ClickRemoteLocation(bunny.Location);
                    await Coroutine.Sleep(Delay.AfterItemUse.Milliseconds);

                    return(true);
                }
                if (bunnyDist < 35 * 35)
                {
                    return(await UtilityCoroutine.MoveTo(bunny.Location, "Bunny", MovementByType.NavigatorOnly));
                }
            }

            var stickbone = ObjectManager.GetObjectsOfType <WoWUnit>()
                            .Where(r => r.Entry == 44329 && r.IsAlive)
                            .OrderBy(r => r.Distance2D)
                            .FirstOrDefault();

            if (stickbone != null && stickbone.DistanceSqr < 5 * 5)
            {
                bomb.Use();
                SpellManager.ClickRemoteLocation(stickbone.Location);
                await Coroutine.Sleep(Delay.AfterItemUse.Milliseconds);

                return(true);
            }
            return(false);
        }
        private async Task <bool> MainLogic()
        {
            if (GetOffLocation != Vector3.Zero && Me.Location.DistanceSquared(GetOffLocation) < 2 * 2)
            {
                BehaviorDone("Successfully used the transport.");
                return(true);
            }

            if (Me.IsOnTransport || _usedTransport)
            {
                if (TransportLocation != Vector3.Zero && TransportLocation.DistanceSquared(EndLocation) < 1.5 * 1.5)
                {
                    TreeRoot.StatusText = "Moving out of transport";
                    Navigator.PlayerMover.MoveTowards(GetOffLocation);
                    return(true);
                }
                _usedTransport      = true;
                TreeRoot.StatusText = "Waiting for the end location";
                return(true);
            }

            if (Me.IsMoving)
            {
                return(false);
            }

            if (TransportLocation != Vector3.Zero &&
                TransportLocation.DistanceSquared(StartLocation) < 1.5 * 1.5 &&
                WaitAtLocation.DistanceSquared(Me.Location) < 2 * 2)
            {
                // don't do anything that can cause toon to move off course
                LevelBot.BehaviorFlags &= ~(BehaviorFlags.Vendor | BehaviorFlags.FlightPath | BehaviorFlags.Combat | BehaviorFlags.Loot);
                TreeRoot.StatusText     = "Moving inside transport";
                Navigator.PlayerMover.MoveTowards(StandLocation);
                return(true);
            }

            if (WaitAtLocation.DistanceSquared(Me.Location) > 2 * 2)
            {
                await UtilityCoroutine.MoveTo(WaitAtLocation, DestName, MovementBy);

                return(true);
            }
            await CommonCoroutines.LandAndDismount();

            TreeRoot.StatusText = "Waiting for transport";
            return(true);
        }
Exemplo n.º 8
0
        private async Task <bool> MoveFromEKToSilvermoonCityHorde()
        {
            var portal = ObjectManager.GetObjectsOfType <WoWGameObject>()
                         .FirstOrDefault(g => g.Entry == GameObjectId_OrbOfTranslocation);

            if (portal == null || !portal.WithinInteractRange)
            {
                return(await(UtilityCoroutine.MoveTo(portal?.Location ?? _silvermoonCityPortalLoc,
                                                     "Silvermoon City portal")));
            }

            await CommonCoroutines.StopMoving();

            portal.Interact();
            await Coroutine.Sleep(3000);

            return(true);
        }
        private Composite StateBehaviorPS_ReturningToBase()
        {
            // If we are not returning home...
            return(new PrioritySelector(
                       new Decorator(context => IsInTank(),
                                     new CompositeThrottle(Throttle.UserUpdate,
                                                           new ActionFail(context => { TreeRoot.StatusText = "Returning to base"; })
                                                           )),

                       new Decorator(context => !Navigator.AtLocation(Location_ReturnToSchnottz),
                                     new ActionRunCoroutine(
                                         interactUnitContext => UtilityCoroutine.MoveTo(
                                             Location_ReturnToSchnottz,
                                             "Commander Schnottz",
                                             MovementBy))),

                       new Decorator(context => Me.IsQuestComplete(QuestId),
                                     new Action(context => BehaviorDone("quest complete")))
                       ));
        }
Exemplo n.º 10
0
        // CreateBehavior supplied by QuestBehaviorBase.
        // Instead, provide CreateMainBehavior definition.

        // Dispose provided by QuestBehaviorBase.

        // IsDone provided by QuestBehaviorBase.
        // Call the QuestBehaviorBase.BehaviorDone() method when you want to indicate your behavior is complete.

        // OnFinished provided by QuestBehaviorBase.

        protected override Composite CreateMainBehavior()
        {
            return(new PrioritySelector(

                       new Decorator(ret => Counter >= NumOfTimes,
                                     new Action(ret => BehaviorDone(string.Format("Object used {0} times.", Counter)))),

                       new Decorator(
                           ret => Location.Distance(StyxWoW.Me.Location) > 2,
                           new ActionRunCoroutine(
                               interactUnitContext => UtilityCoroutine.MoveTo(
                                   Location,
                                   "destination",
                                   MovementBy))),

                       new Decorator(ret => StyxWoW.Me.IsMoving,
                                     new Action(ret => { Navigator.PlayerMover.MoveStop(); })),

                       new Decorator(ret => TargetNearest,
                                     new Sequence(
                                         new Action(context => Lua.DoString("TargetNearest()")),
                                         new SleepForLagDuration(),
                                         new ActionAlwaysFail())), // fall through

                       new Decorator(ret => (Item != null) && (Item.Cooldown <= 0),
                                     new Sequence(
                                         new Action(ret =>
            {
                TreeRoot.StatusText = string.Format("Using {0} (count: {1}/{2})", Item.SafeName, Counter, NumOfTimes);
                Item.UseContainerItem();
                Counter++;
            }),
                                         new SleepForLagDuration(),
                                         new Sleep(WaitTime)))
                       ));
        }
        private Composite SubBehavior_CombatWithViableMob()
        {
            return(new PrioritySelector(context => SelectedTarget = Me.CurrentTarget,
                                        // Recall pet, if necessary...
                                        new Decorator(context => (SelectedTarget.HealthPercent < RecallPetAtMobPercentHealth) &&
                                                      (Me.GotAlivePet && Me.Pet.GotTarget),
                                                      new ActionFail(context =>
            {
                QBCLog.Info("Recalling Pet from '{0}' (health: {1:F1})",
                            SelectedTarget.SafeName, SelectedTarget.HealthPercent);
                PetControl.SetStance_Passive();
                PetControl.Follow();
            })),

                                        // If we are beyond the max range allowed to use the item, move within range...
                                        new Decorator(context => SelectedTarget.Distance > MaxRangeToUseItem,
                                                      new ActionRunCoroutine(
                                                          interactUnitContext => UtilityCoroutine.MoveTo(
                                                              SelectedTarget.Location,
                                                              string.Format("within {0} feet of {1}", MaxRangeToUseItem, SelectedTarget.SafeName),
                                                              MovementBy,
                                                              (float)MaxRangeToUseItem))),

                                        // If time to use the item, do so...
                                        new Decorator(context => IsUseItemNeeded(SelectedTarget),
                                                      new PrioritySelector(
                                                          new ActionRunCoroutine(context => CommonCoroutines.StopMoving()),

                                                          // Halt combat until we are able to use the item...
                                                          new Decorator(context => ((UseItemStrategy == UseItemStrategyType.UseItemContinuouslyOnTargetDontDefend) ||
                                                                                    (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend)),
                                                                        new ActionFail(context =>
            {
                // We use LUA to stop casting, since SpellManager.StopCasting() doesn't seem to work...
                if (Me.IsCasting)
                {
                    Lua.DoString("SpellStopCasting()");
                }

                if (Me.IsAutoAttacking)
                {
                    Lua.DoString("StopAttack()");
                }

                TreeRoot.StatusText = string.Format("Combat halted--waiting for {0} to become usable.",
                                                    Utility.GetItemNameFromId(ItemId));
            })),

                                                          new Sequence(
                                                              new ActionRunCoroutine(ctx =>
                                                                                     UtilityCoroutine.UseItemOnTarget(
                                                                                         ItemId,
                                                                                         SelectedTarget,
                                                                                         () => BehaviorDone(string.Format("Terminating behavior due to missing {0}",
                                                                                                                          Utility.GetItemNameFromId(ItemId))))),
                                                              // Allow a brief time for WoWclient to apply aura to mob...
                                                              new WaitContinue(TimeSpan.FromMilliseconds(5000),
                                                                               context => ItemUseAlwaysSucceeds || SelectedTarget.HasAura(ItemAppliesAuraId),
                                                                               new ActionAlwaysSucceed()),
                                                              new ActionFail(context =>
            {
                _waitTimerAfterUsingItem.Reset();

                if (ItemUseAlwaysSucceeds || SelectedTarget.HasAura(ItemAppliesAuraId))
                {
                    // Count our success if no associated quest...
                    if (!VariantQuestIds.Any())
                    {
                        ++Counter;
                    }

                    // If we can only use the item once per target, blacklist this target from subsequent selection...
                    if ((UseItemStrategy == UseItemStrategyType.UseItemOncePerTarget) ||
                        (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend))
                    {
                        SelectedTarget.BlacklistForInteracting(TimeSpan.FromSeconds(InteractBlacklistTimeInSeconds));
                    }

                    // If we can't defend ourselves from the target, blacklist it for combat and move on...
                    if (Query.IsViable(SelectedTarget) &&
                        ((UseItemStrategy == UseItemStrategyType.UseItemContinuouslyOnTargetDontDefend) ||
                         (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend)))
                    {
                        SelectedTarget.BlacklistForCombat(TimeSpan.FromSeconds(InteractBlacklistTimeInSeconds));
                        BotPoi.Clear();
                        Me.ClearTarget();
                        SelectedTarget = null;
                    }
                }

                if ((ItemAppliesAuraId > 0) && !SelectedTarget.HasAura(ItemAppliesAuraId))
                {
                    var auraNamesOnMob = ((SelectedTarget.Auras.Keys.Count > 0)
                                                            ? string.Join(", ", SelectedTarget.Auras.Keys)
                                                            : "none");

                    QBCLog.Warning("{1} did not acquire expected AuraId, \"{2}\"--retrying.{0}"
                                   + "    Auras on {1}: {3}",
                                   Environment.NewLine,
                                   SelectedTarget.SafeName,
                                   Utility.GetSpellNameFromId(ItemAppliesAuraId),
                                   auraNamesOnMob);
                }
            }),

                                                              // Prevent combat, if we're not supposed to defend...
                                                              new Decorator(context => ((UseItemStrategy == UseItemStrategyType.UseItemContinuouslyOnTargetDontDefend) ||
                                                                                        (UseItemStrategy == UseItemStrategyType.UseItemOncePerTargetDontDefend)),
                                                                            new ActionAlwaysSucceed())
                                                              )))
                                        ));
        }
        private Composite StateBehaviorPS_MountingVehicle()
        {
            return(new PrioritySelector(
                       new Decorator(context => Me.IsQuestComplete(QuestId),
                                     new Action(context => { BehaviorDone(); })),

                       // If we're in the vehicle, wait for the ride out to hunting grounds to complete...
                       new Decorator(context => IsInTank(),
                                     new PrioritySelector(
                                         SubBehaviorPS_InitializeVehicleAbilities(),
                                         new Action(context => { BehaviorState = BehaviorStateType.RidingOutToHuntingGrounds; })
                                         )),

                       // If vehicle is in "enter vehicle" animation, wait for the animation to complete...
                       new Decorator(context => FindVehicle_OwnedByMe(MobId_SchnottzSiegeTankInstanced) != null,
                                     new PrioritySelector(
                                         new CompositeThrottle(Throttle.UserUpdate,
                                                               new Action(context =>
            {
                TreeRoot.StatusText =
                    string.Format("Waiting for {0} to become ready.",
                                  Utility.GetObjectNameFromId(MobId_SchnottzSiegeTankInstanced));
            })),
                                         new ActionAlwaysSucceed()
                                         )),

                       // Locate a vehicle to mount...
                       new Decorator(context => !Query.IsViable(Vehicle),
                                     new PrioritySelector(
                                         new Action(context =>
            {
                Vehicle =
                    Query.FindMobsAndFactions(Utility.ToEnumerable(MobId_SchnottzSiegeTank))
                    .FirstOrDefault()
                    as WoWUnit;

                if (Query.IsViable(Vehicle))
                {
                    Utility.Target(Vehicle);
                    return RunStatus.Success;
                }

                return RunStatus.Failure;               // fall through
            }),

                                         // No vehicle found, move to staging area...
                                         new Decorator(ctx => !Navigator.AtLocation(Location_VehicleStagingArea),
                                                       new ActionRunCoroutine(
                                                           interactUnitContext => UtilityCoroutine.MoveTo(
                                                               Location_VehicleStagingArea,
                                                               "Vehicle Staging Area",
                                                               MovementBy))),

                                         // Wait for vehicle to respawn...
                                         new CompositeThrottle(Throttle.UserUpdate,
                                                               new Action(context =>
            {
                TreeRoot.StatusText =
                    string.Format("Waiting for {0} to respawn.", Utility.GetObjectNameFromId(MobId_SchnottzSiegeTank));
            }))
                                         )),

                       // Move to vehicle and enter...
                       new CompositeThrottle(Throttle.UserUpdate,
                                             new Action(context => { TreeRoot.StatusText = string.Format("Moving to {0}", Vehicle.SafeName); })),
                       new Decorator(context => !Vehicle.WithinInteractRange,
                                     new ActionRunCoroutine(
                                         interactUnitContext => UtilityCoroutine.MoveTo(
                                             Vehicle.Location,
                                             Vehicle.SafeName,
                                             MovementBy))),
                       new Decorator(context => Me.IsMoving,
                                     new Action(context => { Navigator.PlayerMover.MoveStop(); })),
                       new Decorator(context => Me.Mounted,
                                     new ActionRunCoroutine(context => UtilityCoroutine.ExecuteMountStrategy(MountStrategyType.DismountOrCancelShapeshift))),
                       new ActionFail(context =>
            {
                // If we got booted out of a vehicle for some reason, reset the weapons...
                WeaponFireCannon = null;

                Utility.Target(Vehicle);
                Vehicle.Interact();
            }),
                       new Wait(TimeSpan.FromMilliseconds(10000), context => IsInTank(), new ActionAlwaysSucceed()),
                       new ActionAlwaysSucceed()
                       ));
        }
Exemplo n.º 13
0
        protected override Composite CreateMainBehavior()
        {
            return(new PrioritySelector(
                       // PvP server considerations...
                       // Combat is disabled while on the Taxi.  If on the ground, we want it enabled
                       // in case we get attacked on a PvP server.
                       new Decorator(context => !LevelBot.BehaviorFlags.HasFlag(BehaviorFlags.Combat),
                                     new Action(context => { LevelBot.BehaviorFlags |= BehaviorFlags.Combat; })),

                       // Move to flight master, and interact to take taxi ride...
                       new Decorator(context => !Me.OnTaxi,
                                     new PrioritySelector(context =>
            {
                FlightMaster =
                    Query.FindMobsAndFactions(Utility.ToEnumerable <int>(MobId_FlightMaster))
                    .FirstOrDefault()
                    as WoWUnit;

                return context;
            },

                                                          // If flight master not in view, move to where he should be...
                                                          new Decorator(context => FlightMaster == null,
                                                                        new ActionRunCoroutine(
                                                                            context => UtilityCoroutine.MoveTo(
                                                                                WaitLocation,
                                                                                "FlightMaster location",
                                                                                MovementBy))),

                                                          // Make certain the bombs are in our backpack...
                                                          new ActionRunCoroutine(
                                                              ctx => _waitForInventoryItem
                                                              ?? (_waitForInventoryItem = new UtilityCoroutine.WaitForInventoryItem(
                                                                      () => ItemId_Bomb,
                                                                      () =>
            {
                QBCLog.ProfileError(
                    "Cannot continue without required item: {0}",
                    Utility.GetItemNameFromId(ItemId_Bomb));
                BehaviorDone();
            }))),
                                                          // Move to flightmaster, and gossip to hitch a ride...
                                                          new Decorator(context => FlightMaster != null,
                                                                        new PrioritySelector(
                                                                            new Decorator(context => !FlightMaster.WithinInteractRange,
                                                                                          new ActionRunCoroutine(
                                                                                              context => UtilityCoroutine.MoveTo(
                                                                                                  FlightMaster.Location,
                                                                                                  FlightMaster.SafeName,
                                                                                                  MovementBy))),
                                                                            new ActionRunCoroutine(context => CommonCoroutines.StopMoving()),
                                                                            new Decorator(ctx => Me.Mounted, new ActionRunCoroutine(ctx => CommonCoroutines.LandAndDismount())),
                                                                            new Decorator(context => !GossipFrame.Instance.IsVisible,
                                                                                          new Action(context => { FlightMaster.Interact(); })),
                                                                            new Action(context => { GossipFrame.Instance.SelectGossipOption(GossipOption); })
                                                                            ))
                                                          ))
                       ));
        }
Exemplo n.º 14
0
        protected override Composite CreateMainBehavior()
        {
            return(_root ?? (_root =
                                 new PrioritySelector(
                                     // don't drop down while wait timer is running
                                     new Decorator(ctx => !_waitTimer.IsFinished, new ActionAlwaysSucceed()),

                                     new Decorator(ret => Counter > NumOfTimes,
                                                   new Action(ret => BehaviorDone(string.Format("Used the item {0} times", NumOfTimes)))),

                                     // If item is not in our backpack, behavior is done...
                                     new Decorator(context => Item == null,
                                                   new Action(context =>
            {
                QBCLog.Error("ItemId({0}) is not in our backpack", ItemId);
                TreeRoot.Stop();
                BehaviorDone("Item is not in our backpack");
            })),

                                     // Wait for item to come off of cooldown...
                                     new Decorator(context => Item.CooldownTimeLeft > TimeSpan.Zero,
                                                   new Action(context => QBCLog.Info("Waiting for {0} to leave cooldown (time remaining: {1})",
                                                                                     Item.SafeName, Item.CooldownTimeLeft))),

                                     new Decorator(
                                         ret => UseType == QBType.PointToPoint,
                                         new PrioritySelector(
                                             new Decorator(
                                                 ret => Me.Location.Distance(MoveToLocation) > 3,
                                                 new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(MoveToLocation, "Destination", MovementBy))),
                                             new Sequence(
                                                 new Action(ret => TreeRoot.StatusText = string.Format("Using Quest Item: {0} Out of {1} Times",
                                                                                                       Counter, NumOfTimes)),
                                                 new Action(ret => Navigator.PlayerMover.MoveStop()),
                                                 new Action(ret => Me.SetFacing(ClickToLocation)),
                                                 new SleepForLagDuration(),
                                                 new Action(ret => Item.UseContainerItem()),
                                                 new SleepForLagDuration(),
                                                 new Action(ret => Counter++),
                                                 new Action(ret => SpellManager.ClickRemoteLocation(ClickToLocation)),
                                                 new Action(ctx => _waitTimer.Reset())
                                                 ))),

                                     new Decorator(
                                         ret => UseType == QBType.PointToObject,
                                         new PrioritySelector(
                                             new Decorator(
                                                 ret => UseObject == null && Me.Location.DistanceSqr(MoveToLocation) >= 2 * 2,
                                                 new Sequence(
                                                     new Action(ret => TreeRoot.StatusText = "Moving to location"),
                                                     new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(MoveToLocation, "Destination", MovementBy)))),
                                             new Decorator(
                                                 ret => UseObject != null,
                                                 new PrioritySelector(
                                                     new Decorator(
                                                         ret => UseObject.DistanceSqr >= Range * Range,
                                                         new Sequence(
                                                             new Action(ret => TreeRoot.StatusText = "Moving closer to the object"),
                                                             new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(UseObject.Location, "UseObject location", MovementBy)))),
                                                     new Decorator(
                                                         ret => UseObject.DistanceSqr < MinRange * MinRange,
                                                         new Sequence(
                                                             new Action(ret => TreeRoot.StatusText = "Too Close, Backing Up"),
                                                             new ActionRunCoroutine(context =>
                                                                                    UtilityCoroutine.MoveTo(
                                                                                        WoWMathHelper.CalculatePointFrom(Me.Location, UseObject.Location, (float)MinRange + 2f),
                                                                                        "Backing up",
                                                                                        MovementBy))
                                                             )),
                                                     new Sequence(
                                                         new Action(ret => TreeRoot.StatusText = string.Format("Using Item: {0} {1} Out of {2} Times",
                                                                                                               UseObject.SafeName, Counter, NumOfTimes)),
                                                         new Action(ret => Navigator.PlayerMover.MoveStop()),
                                                         new Action(ret => Me.SetFacing(UseObject.Location)),
                                                         new SleepForLagDuration(),
                                                         new Action(ret => Item.UseContainerItem()),
                                                         new Action(ret => Counter++),
                                                         new SleepForLagDuration(),
                                                         new Action(ret => SpellManager.ClickRemoteLocation(UseObject.Location)),
                                                         new Action(ret => _npcBlacklist.Add(UseObject.Guid)),
                                                         new Action(ctx => _waitTimer.Reset())))),
                                             new Action(ret => TreeRoot.StatusText = "No objects around. Waiting")
                                             )),

                                     new Decorator(
                                         ret => UseType == QBType.ToObject,
                                         new PrioritySelector(
                                             new Decorator(
                                                 ret => UseObject != null,
                                                 new PrioritySelector(
                                                     new Decorator(
                                                         ret => UseObject.DistanceSqr >= Range * Range,
                                                         new Sequence(
                                                             new Action(ret => TreeRoot.StatusText = "Moving to object's range"),
                                                             new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(UseObject.Location, "UseObject location", MovementBy)))),
                                                     new Decorator(
                                                         ret => UseObject.DistanceSqr < MinRange * MinRange,
                                                         new Sequence(
                                                             new Action(ret => TreeRoot.StatusText = "Too Close, Backing Up"),
                                                             new ActionRunCoroutine(
                                                                 context =>
                                                                 UtilityCoroutine.MoveTo(
                                                                     WoWMathHelper.CalculatePointFrom(Me.Location, UseObject.Location, (float)MinRange + 2f),
                                                                     "Backing up",
                                                                     MovementBy))
                                                             )),
                                                     new Sequence(
                                                         new Action(ret => TreeRoot.StatusText = string.Format("Using Item: {0} {1} Out of {2} Times",
                                                                                                               UseObject.SafeName, Counter, NumOfTimes)),
                                                         new Action(ret => Navigator.PlayerMover.MoveStop()),
                                                         new Action(ret => Me.SetFacing(UseObject.Location)),
                                                         new SleepForLagDuration(),
                                                         new Action(ret => Item.UseContainerItem()),
                                                         new Action(ret => Counter++),
                                                         new SleepForLagDuration(),
                                                         new Action(ret => SpellManager.ClickRemoteLocation(UseObject.Location)),
                                                         new Action(ret => _npcBlacklist.Add(UseObject.Guid)),
                                                         new Action(ctx => _waitTimer.Reset())))),
                                             new Decorator(
                                                 ret => Me.Location.DistanceSqr(MoveToLocation) > 2 * 2,
                                                 new Sequence(
                                                     new Action(ret => TreeRoot.StatusText = "Moving to location"),
                                                     new ActionRunCoroutine(context => UtilityCoroutine.MoveTo(MoveToLocation, "Destination", MovementBy))))
                                             ))
                                     )));
        }
Exemplo n.º 15
0
        private async Task <bool> TrainMount()
        {
            if (!TrainInOutland && !TrainInOldWorld)
            {
                return(false);
            }

            var trainerId = GetTrainerId();

            if (trainerId == 0)
            {
                return(false);
            }

            var trainer = ObjectManager.GetObjectsOfType <WoWUnit>()
                          .Where(u => u.Entry == trainerId && !u.IsDead)
                          .OrderBy(u => u.DistanceSqr).FirstOrDefault();
            WoWPoint trainerLoc;
            string   trainerName;

            if (trainer == null)
            {
                var traderEntry = Styx.CommonBot.ObjectDatabase.Query.GetNpcById((uint)trainerId);
                if (traderEntry == null)
                {
                    return(false);
                }
                trainerLoc  = traderEntry.Location;
                trainerName = traderEntry.Name;
            }
            else
            {
                trainerLoc  = trainer.Location;
                trainerName = trainer.SafeName;
            }

            if (trainer == null || !trainer.WithinInteractRange)
            {
                return(await UtilityCoroutine.MoveTo(trainerLoc, "Riding Trainer: " + trainerName));
            }

            if (await CommonCoroutines.StopMoving())
            {
                return(true);
            }

            // Turnin any quests since they can interfer with training.
            if (trainer.HasQuestTurnin())
            {
                return(await UtilityCoroutine.TurninQuest(trainer, trainer.Location));
            }

            if (!TrainerFrame.Instance.IsVisible)
            {
                trainer.Interact();
                await CommonCoroutines.SleepForLagDuration();

                return(true);
            }

            TrainerFrame.Instance.BuyAll();
            await CommonCoroutines.SleepForRandomUiInteractionTime();

            return(true);
        }
        protected async Task <bool> CombatMainLogic()
        {
            if (IsDone)
            {
                return(false);
            }
            _combatContext.Update(MobId_Kobai, MobId_MalevolentFury);
            if (Me.Combat)
            {
                // If the Blind Rage Trap is not on cooldown, move right next to Kobai and use it...
                // NB: We don't want to drop the trap unless we're pounding on Kobai
                if ((_combatContext.Kobai != null) &&
                    (Me.CurrentTarget == _combatContext.Kobai) &&
                    (_combatContext.BlindingRageTrap != null) &&
                    (_combatContext.BlindingRageTrap.CooldownTimeLeft <= TimeSpan.Zero))
                {
                    QBCLog.Info("Using Blinding Rage Trap");

                    if (!_combatContext.Kobai.IsWithinMeleeRange)
                    {
                        return(await UtilityCoroutine.MoveTo(_combatContext.Kobai.Location, "Kobai", MovementByType.NavigatorOnly));
                    }

                    if (Me.IsMoving)
                    {
                        await CommonCoroutines.StopMoving();
                    }

                    if (!Me.IsSafelyFacing(_combatContext.Kobai))
                    {
                        _combatContext.Kobai.Face();
                        await Coroutine.Sleep(Delay.LagDuration.Milliseconds);
                    }
                    await Coroutine.Sleep(Delay.BeforeButtonClick.Milliseconds);

                    _combatContext.BlindingRageTrap.Use();
                    await Coroutine.Sleep(Delay.AfterItemUse.Milliseconds);

                    return(true);
                }
                // "Steal Mask" aura...
                // If Kobai is blinded by rage, and the Malevolent Fury is not on the battlefield,
                // move right next to Kobai, and steal the mask...
                // NB: We only want to cause one Malevolet Fury to spawn.  If we click multiple times
                // then we get more.  So, only click if Fury is not already up.
                if ((_combatContext.Kobai != null) &&
                    Me.HasAura(AuraId_StealMask) &&
                    (_combatContext.MalevolentFury == null))
                {
                    QBCLog.Info("Pilfering Mask");

                    if (!_combatContext.Kobai.IsWithinMeleeRange)
                    {
                        return(await UtilityCoroutine.MoveTo(_combatContext.Kobai.Location, "Kobai", MovementByType.NavigatorOnly));
                    }

                    if (Me.CurrentTargetGuid != _combatContext.Kobai.Guid)
                    {
                        _combatContext.Kobai.Target();
                        if (!await Coroutine.Wait(
                                2000,
                                () => _combatContext.Kobai.IsValid &&
                                Me.CurrentTarget == _combatContext.Kobai))
                        {
                            return(false);
                        }
                    }
                    Lua.DoString("ExtraActionButton1:Click()");
                    await Coroutine.Sleep(Delay.AfterItemUse.Milliseconds);

                    return(true);
                }
            }
            // If we're not in combat, but have found Kobai, move to engage him...
            else
            {
                if (_combatContext.Kobai != null)
                {
                    // If Kobai is not in kill zone...
                    if (_combatContext.Kobai.Location.Distance(KobaiSafePullAreaAnchor) > KobaiSafePullAreaRadius)
                    {
                        if (await UtilityCoroutine_MoveToStartPosition())
                        {
                            return(true);
                        }

                        // Wait for Kobai to arrive...
                        QBCLog.Info("Waiting for Kobai to move into kill zone (dist: {0:F1})",
                                    Math.Max(_combatContext.Kobai.Location.Distance(KobaiSafePullAreaAnchor) - KobaiSafePullAreaRadius, 0.0));
                        await Coroutine.Wait(5000, () => Me.Combat);

                        return(true);
                    }

                    // Kobai in kill zone, pull him...
                    if (_combatContext.Kobai.Location.Distance(KobaiSafePullAreaAnchor) <= KobaiSafePullAreaRadius)
                    {
                        if (BotPoi.Current.Type != PoiType.Kill)
                        {
                            QBCLog.Info("Engaging Kobai");
                            BotPoi.Current = new BotPoi(_combatContext.Kobai, PoiType.Kill);
                            if (Me.CurrentTarget != _combatContext.Kobai)
                            {
                                _combatContext.Kobai.Target();
                                await Coroutine.Sleep(Delay.LagDuration.Milliseconds);

                                return(true);
                            }
                        }
                        return(false);
                    }

                    // Can't find Kobai--must've just been killed--wait for repop...
                    if (_combatContext.Kobai == null && Navigator.AtLocation(WaitPoint))
                    {
                        QBCLog.Info("Waiting for Kobai to respawn");
                        await Coroutine.Wait(5000, () => Me.Combat);

                        return(true);
                    }
                }

                if (!UtilIsProgressRequirementsMet(QuestId, QuestRequirementInLog, QuestRequirementComplete))
                {
                    BehaviorDone("Finished");
                    return(true);
                }

                // Move to start position, if needed...
                return(await UtilityCoroutine_MoveToStartPosition());
            }

            return(false);
        }
Exemplo n.º 17
0
        private async Task <bool> StateCoroutine_MountingVehicle()
        {
            if (Me.IsQuestComplete(QuestId))
            {
                BehaviorDone();
                return(true);
            }

            if (IsInBalloon())
            {
                await SubCoroutine_InitializeVehicleAbilities();

                BehaviorState = BehaviorStateType.RidingOutToHuntingGrounds;
                return(true);
            }

            // Locate a vehicle to mount...
            if (!Query.IsViable(Vehicle))
            {
                Vehicle = Query.FindMobsAndFactions(Utility.ToEnumerable(MobId_SteamwheedleRescueBalloon))
                          .FirstOrDefault() as WoWUnit;

                if (Query.IsViable(Vehicle))
                {
                    Utility.Target(Vehicle);
                    return(true);
                }

                // No vehicle found, move to staging area...
                if (!Navigator.AtLocation(VehicleStagingArea))
                {
                    return(await UtilityCoroutine.MoveTo(VehicleStagingArea, "Vehicle Staging Area", MovementBy));
                }

                await(_updateUser_MountingVehicle_waitingForSpawn ?? (_updateUser_MountingVehicle_waitingForSpawn =
                                                                          new ThrottleCoroutineTask(
                                                                              Throttle.UserUpdate,
                                                                              async() => TreeRoot.StatusText = string.Format("Waiting for {0} to respawn.",
                                                                                                                             Utility.GetObjectNameFromId(MobId_SteamwheedleRescueBalloon)))));
                // Wait for vehicle to respawn...
                return(true);
            }
            // Wait for vehicle to respawn...
            await(_updateUser_MountingVehicle_movingToVehicle ?? (_updateUser_MountingVehicle_movingToVehicle =
                                                                      new ThrottleCoroutineTask(
                                                                          Throttle.UserUpdate,
                                                                          async() => TreeRoot.StatusText = string.Format("Moving to {0}", Vehicle.SafeName))));

            if (!Vehicle.WithinInteractRange)
            {
                return(await UtilityCoroutine.MoveTo(Vehicle.Location, Vehicle.SafeName, MovementBy));
            }

            if (Me.IsMoving)
            {
                await CommonCoroutines.StopMoving();
            }

            if (Me.Mounted && await UtilityCoroutine.ExecuteMountStrategy(
                    MountStrategyType.DismountOrCancelShapeshift))
            {
                return(true);
            }
            // If we got booted out of a vehicle for some reason, reset the weapons...
            WeaponLifeRocket           = null;
            WeaponPirateDestroyingBomb = null;
            WeaponEmergencyRocketPack  = null;

            Utility.Target(Vehicle);
            await Coroutine.Sleep((int)Delay.AfterInteraction.TotalMilliseconds);

            Vehicle.Interact();
            await Coroutine.Wait(10000, IsInBalloon);

            return(true);
        }
Exemplo n.º 18
0
        private async Task <bool> PurchaseGroundMount_Alliance()
        {
            switch (Me.Race)
            {
            case WoWRace.Human:
                return(await TurninQuestAndBuyMount(
                           MobId_RandalHunter,
                           _randalHunterLoc,
                           QuestId_LearnToRide_Human,
                           MobId_KatieHunter,
                           _katieHunterLoc,
                           ItemId_PintoBridle));

            case WoWRace.Pandaren:
                return(await TurninQuestAndBuyMount(
                           MobId_MeiLin,
                           _meiLinLoc,
                           QuestId_LearnToRide_Pandaren,
                           MobId_OldWhitenose,
                           _oldWhitenoseLoc,
                           ItemId_ReinsOfTheBlackDragonTurtle));

            case WoWRace.Gnome:
                return(await TurninQuestAndBuyMount(
                           MobId_BinjyFeatherwhistle,
                           _binjyFeatherwhistleLoc,
                           QuestId_LearnToRide_Gnome,
                           MobId_MilliFeatherwhistle,
                           _milliFeatherwhistleLoc,
                           ItemId_BlueMechanostrider));

            case WoWRace.Dwarf:
                return(await TurninQuestAndBuyMount(
                           MobId_UlthamIronhorn,
                           _ulthamIronhornLoc,
                           QuestId_LearnToRide_Dwarf,
                           MobId_VeronAmberstill,
                           _veronAmberstillLoc,
                           ItemId_WhiteRam));

            case WoWRace.NightElf:
                if (InEasternKingdoms)
                {
                    return(await UtilityCoroutine.UseTransport(
                               GameObjectId_Ship_TheBravery,
                               _theBraveryStartLoc,
                               _theBraveryEndLoc,
                               _theBraveryWaitAtLoc,
                               _theBraveryStandAtLoc,
                               _theBraveryGetOffAtLoc));
                }

                if (!InKalimdor)
                {
                    return(false);
                }

                return(await TurninQuestAndBuyMount(
                           MobId_Jartsam,
                           _jartsamLoc,
                           QuestId_LearnToRide_NightElf,
                           MobId_Lelanai,
                           _lelanaiLoc,
                           ItemId_ReinsOfTheStripedNightsaber));

            case WoWRace.Draenei:
                if (InEasternKingdoms)
                {
                    return(await UtilityCoroutine.UseTransport(
                               GameObjectId_Ship_TheBravery,
                               _theBraveryStartLoc,
                               _theBraveryEndLoc,
                               _theBraveryWaitAtLoc,
                               _theBraveryStandAtLoc,
                               _theBraveryGetOffAtLoc));
                }

                // port over to Exodar
                if (InKalimdor && Me.ZoneId != 3557)
                {
                    var portal = ObjectManager.GetObjectsOfType <WoWGameObject>()
                                 .FirstOrDefault(g => g.Entry == GameObjectId_PortalToExodar);

                    if (portal == null || !portal.WithinInteractRange)
                    {
                        return(await(UtilityCoroutine.MoveTo(portal != null ? portal.Location : _exodarPortalLoc, "Exodar portal")));
                    }

                    portal.Interact();
                    await CommonCoroutines.SleepForLagDuration();

                    return(true);
                }
                if (Me.ZoneId != 3557)
                {
                    return(false);
                }

                // Turnin the 'Learn To Ride At The Exodar' quest if in log
                if (_profileHelpers.HasQuest(QuestId_LearnToRideAtTheExodar) && _profileHelpers.IsQuestCompleted(QuestId_LearnToRideAtTheExodar))
                {
                    return(await UtilityCoroutine.TurninQuest(MobId_Aalun, _aalunLoc, QuestId_LearnToRideAtTheExodar));
                }

                return(await TurninQuestAndBuyMount(
                           MobId_Aalun,
                           _aalunLoc,
                           QuestId_LearnToRide_Draenei,
                           MobId_ToralliusThePackHandler,
                           _toralliusThePackHandlerLoc,
                           ItemId_BrownElekk));
            }

            return(false);
        }
Exemplo n.º 19
0
        protected override Composite CreateBehavior_CombatMain()
        {
            return(new Decorator(context => !IsDone,
                                 new PrioritySelector(

                                     // Update values for this BT node visit...
                                     new Action(context =>
            {
                VehicleUnoccupied = FindUnoccupiedVehicle();

                // Figure out our final destination (i.e., a location or a mob)...
                // NB: this can change as we travel.  If our destination is a mob,
                // We can't "see" distant mobs until we get within 100 yards or so of them.
                // Until we close that distance, we'll head towards the provided location.
                // As soon as we "see" the mob, we'll switch to the mob as the destination.
                FinalDestination = Destination;
                FinalDestinationName = "destination";

                if (MobIds.Count() > 0)
                {
                    // If we can see our destination mob, calculate a path to it...
                    var nearestMob = Query.FindMobsAndFactions(MobIds).OrderBy(u => u.Distance).FirstOrDefault() as WoWUnit;
                    if (nearestMob != null)
                    {
                        // Target destination mob as feedback to the user...
                        Utility.Target(nearestMob);

                        FinalDestination = nearestMob.Location;
                        FinalDestinationName = nearestMob.SafeName;
                    }
                }

                return RunStatus.Failure;           // fall thru
            }),


                                     // Proceed if we're not in combat, or are ignoring it...
                                     new Decorator(context => !Me.Combat || IgnoreCombat,
                                                   new PrioritySelector(
                                                       // If we were successfully mounted...
                                                       // and within a few yards of our destination when we were dismounted, we must
                                                       // assume we were auto-dismounted, and the behavior is complete...
                                                       new Decorator(context => DidSuccessfullyMount && !IsInVehicle() &&
                                                                     (WoWMovement.ActiveMover.Location.Distance(FinalDestination) < 15.0),
                                                                     new Action(context => { BehaviorDone(); })),

                                                       // Enable combat while not in a vehicle
                                                       new Decorator(ctx => (LevelBot.BehaviorFlags & BehaviorFlags.Combat) == 0 && !Query.IsInVehicle(),
                                                                     new Action(ctx => LevelBot.BehaviorFlags |= BehaviorFlags.Combat)),

                                                       // Disable combat while in a vehicle
                                                       new Decorator(ctx => (LevelBot.BehaviorFlags & BehaviorFlags.Combat) != 0 && Query.IsInVehicle(),
                                                                     new Action(ctx => LevelBot.BehaviorFlags &= ~BehaviorFlags.Combat)),

                                                       // If we're not in a vehicle, go fetch one...
                                                       new Decorator(context => !IsInVehicle() && Query.IsViable(VehicleUnoccupied),
                                                                     new Sequence(
                                                                         new CompositeThrottleContinue(
                                                                             Throttle.UserUpdate,
                                                                             new Action(context =>
            {
                TreeRoot.StatusText = string.Format("Moving to {0} {1}",
                                                    VehicleUnoccupied.SafeName,
                                                    Me.Combat ? "(ignoring combat)" : "");
            })),
                                                                         new DecoratorContinue(context => VehicleUnoccupied.WithinInteractRange,
                                                                                               new Action(context => { VehicleUnoccupied.Interact(); })),
                                                                         new ActionRunCoroutine(
                                                                             interactUnitContext => UtilityCoroutine.MoveTo(
                                                                                 VehicleUnoccupied.Location,
                                                                                 VehicleUnoccupied.SafeName,
                                                                                 MovementBy))
                                                                         )),

                                                       // If we can't find a vehicle, terminate if requested...
                                                       new CompositeThrottle(
                                                           context => !IsInVehicle() && !Query.IsViable(VehicleUnoccupied),
                                                           Throttle.UserUpdate,
                                                           new Action(context =>
            {
                if (!WaitForVehicle)
                {
                    BehaviorDone(string.Format("No Vehicle, and WaitForVehicle=\"{0}\"", WaitForVehicle));
                }
                else
                {
                    TreeRoot.StatusText = "No vehicles in area--waiting for vehicle to become available.";
                }
            })),


                                                       // Move vehicle to destination...
                                                       new Decorator(context => IsInVehicle(),
                                                                     new PrioritySelector(
                                                                         // If we successfully mounted the vehicle, record the fact...
                                                                         new Decorator(context => !DidSuccessfullyMount,
                                                                                       new Action(context => { DidSuccessfullyMount = true; })),

                                                                         new Decorator(context => !Navigator.AtLocation(FinalDestination),
                                                                                       new ActionRunCoroutine(
                                                                                           interactUnitContext => UtilityCoroutine.MoveTo(
                                                                                               FinalDestination,
                                                                                               FinalDestinationName,
                                                                                               MovementBy))),

                                                                         new Decorator(context => WoWMovement.ActiveMover.IsMoving,
                                                                                       new Action(context => { WoWMovement.MoveStop(); })),

                                                                         // Arrived at destination, use spell if necessary...
                                                                         // NB: We want to make certain movement is settled before we attempt
                                                                         // to cast spell, so we won't be interrupted.
                                                                         new SleepForLagDuration(),
                                                                         CreateSpellBehavior()
                                                                         ))
                                                       )),

                                     // Squelch combat, if requested...
                                     new Decorator(context => IgnoreCombat,
                                                   new ActionAlwaysSucceed())
                                     )));
        }
        private Composite CreateMainBehavior()
        {
            return(new PrioritySelector(

                       // If quest is done, behavior is done...
                       new Decorator(context => IsDone,
                                     new Action(context =>
            {
                _isBehaviorDone = true;
                QBCLog.Info("Finished");
            })),


                       // Stateful Operation:
                       new Switch <StateType_MainBehavior>(context => State_MainBehavior,
                                                           #region State: DEFAULT
                                                           new Action(context => // default case
            {
                QBCLog.MaintenanceError("StateType_MainBehavior({0}) is unhandled", State_MainBehavior);
                TreeRoot.Stop();
                _isBehaviorDone = true;
            }),
                                                           #endregion


                                                           #region State: Dropping Off Victim
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.DroppingOffVictim,
                                                                                                       new PrioritySelector(
                                                                                                           // If Watchman dropped off, go get another...
                                                                                                           new Decorator(context => !Me.HasAura(AuraId_RescueDrowningWatchman),
                                                                                                                         new Action(context =>
            {
                WoWMovement.MoveStop();
                _currentPath = null;
                SelectedTarget = null;
                State_MainBehavior = StateType_MainBehavior.PathingOutToVictim;
            })),

                                                                                                           // Move to drop off spot...
                                                                                                           new Decorator(context => Me.Location.Distance(PositionToMakeLandfall) > Navigator.PathPrecision,
                                                                                                                         new ActionRunCoroutine(
                                                                                                                             context => UtilityCoroutine.MoveTo(
                                                                                                                                 PositionToMakeLandfall,
                                                                                                                                 "back to shore")))
                                                                                                           )),
                                                           #endregion


                                                           #region State: Pathing Out to Victim
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.PathingOutToVictim,
                                                                                                       new PrioritySelector(
                                                                                                           // If our selected target is no good, find another...
                                                                                                           new Decorator(context => !IsViableDrowningWatchman(SelectedTarget),
                                                                                                                         new Action(context =>
            {
                QBCLog.Info("Finding new Drowning Watchman to save");
                _currentPath = null;
                SelectedTarget = FindDrowningWatchman();
            })),

                                                                                                           // Show user which target we're after...
                                                                                                           new Decorator(context => Me.CurrentTarget != SelectedTarget,
                                                                                                                         new Action(context => { SelectedTarget.Target(); })),

                                                                                                           // If we don't have a path to victim, find one...
                                                                                                           new Decorator(context => _currentPath == null,
                                                                                                                         new Action(context => { _currentPath = FindPath(Me.Location, SelectedTarget.Location); })),

                                                                                                           // If path completely consumed, we're done...
                                                                                                           new Decorator(context => _currentPath.Count() <= 0,
                                                                                                                         new Action(context => { State_MainBehavior = StateType_MainBehavior.Rescuing; })),

                                                                                                           // If we've arrived at the current waypoint, dequeue it...
                                                                                                           new Decorator(context => Navigator.AtLocation(_currentPath.Peek()),
                                                                                                                         new Action(context => { _currentPath.Dequeue(); })),

                                                                                                           // Follow the prescribed path...
                                                                                                           new ActionRunCoroutine(
                                                                                                               context => UtilityCoroutine.MoveTo(
                                                                                                                   _currentPath.Peek(),
                                                                                                                   "out to Drowned Watcman"))
                                                                                                           )),
                                                           #endregion


                                                           #region State: Rescuing
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.Rescuing,
                                                                                                       new PrioritySelector(
                                                                                                           // If we've got the Watchman, start heading in...
                                                                                                           new Decorator(context => Me.HasAura(AuraId_RescueDrowningWatchman),
                                                                                                                         new Action(context =>
            {
                _currentPath = null;
                State_MainBehavior = StateType_MainBehavior.PathingIntoShore;
            })),

                                                                                                           // If our selected target is no good, find another...
                                                                                                           new Decorator(context => !IsViableDrowningWatchman(SelectedTarget),
                                                                                                                         new Action(context =>
            {
                _currentPath = null;
                SelectedTarget = null;
                State_MainBehavior = StateType_MainBehavior.PathingOutToVictim;
            })),

                                                                                                           // Go get a fresh Drowning Watchman...
                                                                                                           UtilityBehavior_InteractWithMob(context => SelectedTarget)
                                                                                                           )),
                                                           #endregion


                                                           #region State: Pathing Into Shore
                                                           new SwitchArgument <StateType_MainBehavior>(StateType_MainBehavior.PathingIntoShore,
                                                                                                       new PrioritySelector(
                                                                                                           // If we don't have a path, find the correct one...
                                                                                                           new Decorator(context => _currentPath == null,
                                                                                                                         new Action(context => { _currentPath = FindPath(Me.Location, PositionToMakeLandfall); })),

                                                                                                           // If path completely consumed, we're done...
                                                                                                           new Decorator(context => _currentPath.Count() <= 0,
                                                                                                                         new Action(context => { State_MainBehavior = StateType_MainBehavior.DroppingOffVictim; })),

                                                                                                           // If we've lost the Watchman we rescued, go fetch another...
                                                                                                           new Decorator(context => !Me.HasAura(AuraId_RescueDrowningWatchman),
                                                                                                                         new Action(context =>
            {
                _currentPath = null;
                SelectedTarget = null;
                State_MainBehavior = StateType_MainBehavior.PathingOutToVictim;
            })),

                                                                                                           // If we've arrived at the current waypoint, dequeue it...
                                                                                                           new Decorator(context => Navigator.AtLocation(_currentPath.Peek()),
                                                                                                                         new Action(context => { _currentPath.Dequeue(); })),

                                                                                                           // Follow the prescribed path...
                                                                                                           new ActionRunCoroutine(
                                                                                                               context => UtilityCoroutine.MoveTo(
                                                                                                                   _currentPath.Peek(),
                                                                                                                   "in to drop off Drowned Watchman"))
                                                                                                           ))
                                                           #endregion
                                                           )));
        }
            public override async Task <bool> Execute()
            {
                // If we cannot 'see' the mob yet, move to the rough location...
                var gossipMob = ObjectManager.GetObjectsOfType <WoWUnit>().FirstOrDefault(u => u.Entry == GossipMobId);

                if (gossipMob == null)
                {
                    await UtilityCoroutine.MoveTo(GossipMobRoughLocation, "Gossip mob");

                    return(true);
                }

                // Move into interact range of mob...
                if (Me.Location.Distance(gossipMob.Location) > gossipMob.InteractRange)
                {
                    if (await UtilityCoroutine.MoveTo(gossipMob.Location, gossipMob.Name))
                    {
                        return(true);
                    }
                }
                WoWMovement.MoveStop();

                // Pull up gossip frame, if not visible
                if (!IsGossipFrameVisible())
                {
                    await UtilityCoroutine.Interact(gossipMob);

                    await Coroutine.Sleep(Delay.AfterInteraction);

                    return(true);
                }

                TreeRoot.StatusText = string.Format("Gossiping with {0}", gossipMob.Name);
                var gossipPageIndex = 0;

                while (gossipPageIndex < GossipOptions.Length)
                {
                    GossipEntry gossipEntry;
                    if (!TryGetGossipEntry(GossipOptions[gossipPageIndex], out gossipEntry))
                    {
                        QBCLog.Fatal(
                            "{0} is not offering gossip option {1} on page {2}."
                            + "  Did competing player alter NPC state?"
                            + "  Did you stop/start Honorbuddy?"
                            + "  Terminating behavior.",
                            gossipMob.Name,
                            GossipOptions[gossipPageIndex] + 1,
                            gossipPageIndex + 1);
                        Utility.CloseAllNpcFrames();
                        Me.ClearTarget();
                        return(false);
                    }

                    // Log the gossip option we're about to take...
                    QBCLog.DeveloperInfo(
                        "Selecting Gossip Option({0}) on page {1}: \"{2}\"",
                        gossipEntry.Index + 1,
                        gossipPageIndex + 1,
                        gossipEntry.Text);

                    GossipFrame.Instance.SelectGossipOption(GossipOptions[gossipPageIndex]);
                    ++gossipPageIndex;
                    await Coroutine.Wait((int)Delay.AfterInteraction.TotalMilliseconds, () => !IsGossipFrameVisible());
                }

                // Gossip is complete, claim credit...
                Utility.CloseAllNpcFrames();
                var message = string.Format("Gossip with {0} complete.", gossipMob.Name);

                QBCLog.DeveloperInfo(message);
                TreeRoot.StatusText = message;
                return(true);
            }
        private Composite UtilityBehavior_InteractWithMob(WoWUnitDelegate unitToInteract)
        {
            return(new PrioritySelector(interactUnitContext => unitToInteract(interactUnitContext),
                                        new Decorator(interactUnitContext => IsViable((WoWUnit)interactUnitContext),
                                                      new PrioritySelector(
                                                          // Show user which unit we're going after...
                                                          new Decorator(interactUnitContext => Me.CurrentTarget != (WoWUnit)interactUnitContext,
                                                                        new Action(interactUnitContext => { ((WoWUnit)interactUnitContext).Target(); })),

                                                          // If not within interact range, move closer...
                                                          new Decorator(interactUnitContext => !((WoWUnit)interactUnitContext).WithinInteractRange,
                                                                        new ActionRunCoroutine(
                                                                            interactUnitContext => UtilityCoroutine.MoveTo(
                                                                                ((WoWUnit)interactUnitContext).Location,
                                                                                "to interact with " + ((WoWUnit)interactUnitContext).SafeName))),

                                                          new Decorator(interactUnitContext => Me.IsMoving,
                                                                        new Action(interactUnitContext => { WoWMovement.MoveStop(); })),
                                                          new Decorator(interactUnitContext => !Me.IsFacing((WoWUnit)interactUnitContext),
                                                                        new Action(interactUnitContext => { Me.SetFacing((WoWUnit)interactUnitContext); })),

                                                          // Blindly interact...
                                                          // Ideally, we would blacklist the unit if the interact failed.  However, the HB API
                                                          // provides no CanInteract() method (or equivalent) to make this determination.
                                                          new Action(interactUnitContext =>
            {
                QBCLog.DeveloperInfo("Interacting with {0}", ((WoWUnit)interactUnitContext).SafeName);
                ((WoWUnit)interactUnitContext).Interact();
                return RunStatus.Failure;
            }),
                                                          new Wait(TimeSpan.FromMilliseconds(1000), context => false, new ActionAlwaysSucceed())
                                                          ))));
        }
Exemplo n.º 23
0
        private async Task <bool> Coroutine_CombatMain()
        {
            if (IsDone)
            {
                return(false);
            }

            if (!Query.IsInVehicle())
            {
                // only move to vehicle if doing nothing else
                if (!Targeting.Instance.IsEmpty() || BotPoi.Current.Type != PoiType.None)
                {
                    return(false);
                }

                WoWUnit amber = Amber;
                // Wait for Amber to load in the ObjectMananger.
                if (amber == null || !amber.WithinInteractRange)
                {
                    var moveTo = amber != null ? amber.Location : _vehicleLoc;
                    await UtilityCoroutine.MoveTo(moveTo, "Moving to Start Amber(Human) Story", MovementBy);

                    return(true);
                }

                if (await CommonCoroutines.StopMoving())
                {
                    return(true);
                }

                if (!GossipFrame.Instance.IsVisible)
                {
                    amber.Interact();
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    return(true);
                }

                if (GossipFrame.Instance.GossipOptionEntries != null)
                {
                    GossipFrame.Instance.SelectGossipOption(0);
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    return(true);
                }
                return(true);
            }

            if (await InteractWithUnit(HozenEnemy))
            {
                return(true);
            }

            if (await InteractWithUnit(OrcEnemy))
            {
                return(true);
            }

            if (!Me.HasAura("See Quest Invis 5"))
            {
                var turret = Turret;
                if (TurretLocation.DistanceSqr(Me.Location) > 3 * 3)
                {
                    await UtilityCoroutine.MoveTo(TurretLocation, "Turret Location", MovementBy);

                    return(true);
                }
                if (turret == null)
                {
                    TreeRoot.StatusText = "Waiting for turret to spawn";
                    return(true);
                }

                if (!turret.WithinInteractRange)
                {
                    await UtilityCoroutine.MoveTo(TurretLocation, "interact range of turret", MovementBy);

                    return(true);
                }

                if (await CommonCoroutines.StopMoving())
                {
                    return(true);
                }

                QBCLog.Info("Using turret");
                Turret.Interact();
                return(true);
            }
            return(false);
        }
Exemplo n.º 24
0
        private Composite StateBehaviorPS_MovingToSafeSpot()
        {
            return(new PrioritySelector(
                       // If a "Move Near" mob was specified, move to it...
                       new Decorator(context => MobIdToMoveNear > 0,
                                     new PrioritySelector(
                                         new Decorator(context => Query.IsViable(Mob_ToMoveNear),
                                                       new PrioritySelector(
                                                           // Target the MoveToNpc, as feedback to the user...
                                                           new ActionFail(context => { Utility.Target(Mob_ToMoveNear); }),

                                                           // Move to mob...
                                                           new Decorator(ctx => !Navigator.AtLocation(Mob_ToMoveNear.Location),
                                                                         new ActionRunCoroutine(
                                                                             context => UtilityCoroutine.MoveTo(
                                                                                 Mob_ToMoveNear.Location,
                                                                                 Mob_ToMoveNear.SafeName,
                                                                                 MovementBy)))
                                                           )),

                                         // Need to wait for Mob to respawn...
                                         new Decorator(context => !Query.IsViable(Mob_ToMoveNear),
                                                       new Action(context =>
            {
                TreeRoot.StatusText = string.Format("Waiting for {0} to respawn", Utility.GetObjectNameFromId(MobIdToMoveNear));
            }))
                                         )),

                       // No "Move Near" mob, so use the provided Safe spot coordinates...
                       new Decorator(context => MobIdToMoveNear <= 0 && !Navigator.AtLocation(SafespotLocation),
                                     new ActionRunCoroutine(
                                         context => UtilityCoroutine.MoveTo(
                                             SafespotLocation,
                                             "safe spot",
                                             MovementBy))),

                       // Dismount once we've arrived at mob or destination...
                       new Decorator(ctx => Me.Mounted, new ActionRunCoroutine(ctx => CommonCoroutines.LandAndDismount())),

                       new Decorator(ctx => StyxWoW.Me.IsMoving, new Action(ctx => WoWMovement.MoveStop())),

                       // Target and Face the AvoidNpc, as feedback to the user...
                       new ActionFail(
                           context =>
                           { Utility.Target(Mob_ToAvoid, true); }),

                       // If AvoidNpc is not around,
                       // or if AvoidNpc is prescribed distance away, and facing away from us,
                       // we're done...
                       new Decorator(context => IsSafeToMoveToDestination(Mob_ToAvoid),
                                     new Action(context =>
            {
                FollowPath.DismissPetIfNeeded();
                Path_Ingress = null;
                Path_Egress = null;
                State_MainBehavior = StateType_MainBehavior.PathIngressing;
            })),

                       // Tell user what we're up to...
                       new CompositeThrottle(Throttle.UserUpdate,
                                             new Action(context =>
            {
                TreeRoot.StatusText =
                    string.Format("Waiting for '{0}' to move {1:F1}/{2:F1} yards away, and pathing away from us.",
                                  Mob_ToAvoid.SafeName,
                                  Mob_ToAvoid.Distance,
                                  AvoidDistance);
            }))
                       ));
        }
Exemplo n.º 25
0
        private async Task <bool> MainCoroutine()
        {
            // break if we are done or we are not in combat and targting is not empty, we want the botbase to clear path for us.
            if (IsDone || (!Me.Combat && Targeting.Instance.FirstUnit != null) || !Me.IsAlive)
            {
                return(false);
            }

            if (!Query.IsViable(SelectedNpc))
            {
                SelectedNpc = GetNpc();
            }

            if (!Query.IsViable(SelectedNpc) || !Me.IsActuallyInCombat && Targeting.Instance.FirstUnit == null)
            {
                // move to search area
                if (SearchLocation != Vector3.Zero && !Navigator.AtLocation(SearchLocation))
                {
                    await UtilityCoroutine.MoveTo(SearchLocation, "Search Area", MovementBy);
                }
                // Dismount after reaching search location.
                else if ((SearchLocation == Vector3.Zero || Navigator.AtLocation(SearchLocation)) && Me.Mounted)
                {
                    await UtilityCoroutine.ExecuteMountStrategy(MountStrategyType.Dismount);
                }
                else
                {
                    TreeRoot.StatusText = "Waiting for NPC to spawn";
                }
                return(true);
            }

            if (SelectedNpc.IsDead && SelectedNpc.TaggedByMe && !VariantQuestIds.Any())
            {
                BehaviorDone();
                return(true);
            }

            if (SelectedNpc.HasAura(ImmunityAuraId))
            {
                if (BotPoi.Current.AsObject == SelectedNpc)
                {
                    BotPoi.Clear("Mob is immune");
                }

                var targetedMob = Targeting.Instance.FirstUnit;
                if (targetedMob != null && ImmunityBreakingMobIds.Contains((int)targetedMob.Entry))
                {
                    if (targetedMob.IsTargetingMeOrPet)
                    {
                        // move close enough to shielded NPC so that the exploding mobs will hit it when killed.
                        var myMinDistance = Math.Max(2, MaxRange - targetedMob.MeleeRange);
                        if (SelectedNpc.DistanceSqr > myMinDistance * myMinDistance)
                        {
                            TreeRoot.StatusText = string.Format("Moving closer to {0} before killing {1}", SelectedNpc.SafeName, targetedMob.SafeName);
                            Navigator.MoveTo(SelectedNpc.Location);
                            return(true);
                        }
                        // wait for exploding mob to get within range of shielded mob.
                        if (targetedMob.Location.DistanceSquared(SelectedNpc.Location) > MaxRange * MaxRange)
                        {
                            TreeRoot.StatusText = string.Format(
                                "Waiting for {0} to move withing range of {1}",
                                targetedMob.SafeName,
                                SelectedNpc.SafeName);
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Exemplo n.º 26
0
        private Composite StateBehaviorPS_PathIngressing()
        {
            return(new PrioritySelector(
                       // If no Ingress path exists, build it...
                       new Decorator(context => Path_Ingress == null,
                                     new Action(context => { Path_Ingress = FollowPath.FindPath_Ingress(); })),

                       // If we've consumed our Ingress path (or the one we initially built is empty), we're done...
                       new Decorator(context => !Path_Ingress.Any(),
                                     new Action(context => { State_MainBehavior = StateType_MainBehavior.DestinationReached; })),

                       // If Mob_ToAvoid is too close or we get in combat, abandon current ingress, and retreat back to safespot...
                       new Decorator(context => Query.IsViable(Mob_ToAvoid) &&
                                     ((Mob_ToAvoid.Distance < FollowPath.EgressDistance) || Me.Combat),
                                     new Action(context =>
            {
                Path_Ingress = null;
                Path_Egress = null;
                State_MainBehavior = StateType_MainBehavior.PathRetreating;
            })),

                       new Switch <SafePathType.StrategyType>(context => FollowPath.Strategy,
                                                              new Action(context => // default case
            {
                var message = string.Format("FollowPathStrategyType({0}) is unhandled", FollowPath.Strategy);
                QBCLog.MaintenanceError(message);
                TreeRoot.Stop();
                BehaviorDone(message);
            }),

                                                              new SwitchArgument <SafePathType.StrategyType>(SafePathType.StrategyType.StalkMobAtAvoidDistance,
                                                                                                             new Decorator(context => Query.IsViable(Mob_ToAvoid) && (Mob_ToAvoid.Distance < AvoidDistance),
                                                                                                                           new PrioritySelector(
                                                                                                                               new ActionRunCoroutine(context => CommonCoroutines.StopMoving()),
                                                                                                                               new ActionAlwaysSucceed()
                                                                                                                               ))),

                                                              new SwitchArgument <SafePathType.StrategyType>(SafePathType.StrategyType.WaitForAvoidDistance,
                                                                                                             new PrioritySelector(
                                                                                                                 // No addition action needed to implement strategy for now
                                                                                                                 ))
                                                              ),

                       // If we've arrived at the current ingress waypoint, dequeue it...
                       new Decorator(context => Navigator.AtLocation(Path_Ingress.Peek().Location),
                                     new Action(context =>
            {
                FollowPath.DismissPetIfNeeded();
                Path_Ingress.Dequeue();
            })),

                       // Follow the prescribed ingress path, if its still safe to proceed...
                       new Decorator(context => IsSafeToMoveToDestination(Mob_ToAvoid),
                                     new ActionRunCoroutine(
                                         context => UtilityCoroutine.MoveTo(
                                             Path_Ingress.Peek().Location,
                                             "follow ingress path",
                                             MovementBy))),

                       // If mob is heading our direction, hold position...
                       new Decorator(context => !IsSafeToMoveToDestination(Mob_ToAvoid),
                                     new Sequence(
                                         new Action(context =>
            {
                TreeRoot.StatusText = string.Format("Holding position to evaluate {0}'s actions.", Mob_ToAvoid.SafeName);
            }),
                                         new ActionRunCoroutine(context => CommonCoroutines.StopMoving())
                                         ))
                       ));
        }