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);
            }
예제 #2
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))
                       ));
        }
        private async Task <bool> UtilityCoroutine_MoveToStartPosition()
        {
            if (Navigator.AtLocation(WaitPoint))
            {
                return(false);
            }

            return(await UtilityCoroutine.MoveTo(WaitPoint, "Moving to start position", MovementByType.NavigatorOnly));
        }
        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> UtilityCoroutine_MoveAndUseCatapult()
        {
            if (!Query.IsInVehicle() || !IsViable(SelectedCatapult))
            {
                return(false);
            }

            // Move vehicle into position...
            if (!Navigator.AtLocation(CurrentTask.PositionForLaunch))
            {
                Navigator.MoveTo(CurrentTask.PositionForLaunch);
                return(true);
            }

            // Adjust heading...
            if (!WoWMathHelper.IsFacing(WoWMovement.ActiveMover.Location, GetVehicleFacing(),
                                        CurrentTask.PositionToLand, WoWMathHelper.DegreesToRadians(0.5f)))
            {
                // Handle heading...
                double neededHeading = WoWMathHelper.CalculateNeededFacing(Me.Location, CurrentTask.PositionToLand);
                neededHeading = WoWMathHelper.NormalizeRadian((float)neededHeading);
                QBCLog.Info("Adjusting firing heading");
                Me.SetFacing((float)neededHeading);
                await Coroutine.Sleep(200);

                return(true);
            }

            // Adjust azimuth...
            double currentAzimuth = WoWMathHelper.NormalizeRadian(Lua.GetReturnVal <float>("return VehicleAimGetAngle();", 0));
            double neededAzimuth  = NormalizeAngleToPi(CurrentTask.NeededAzimuth);

            double azimuthChangeRequired = neededAzimuth - currentAzimuth;

            if (Math.Abs(azimuthChangeRequired) >= 0.01)
            {
                QBCLog.Info("Adjusting firing azimuth");
                // NB: VehicleAimIncrement() handles negative values of 'increment' correctly...
                Lua.DoString("VehicleAimIncrement({0})", azimuthChangeRequired);
                await Coroutine.Sleep(200);

                return(true);
            }

            // Fire..
            QBCLog.Info("Firing Catapult");
            Lua.DoString(Lua_LaunchCommand);

            await Coroutine.Wait(3000, () => !Query.IsInVehicle());

            return(true);
        }
예제 #6
0
        /// <summary>Turns in a quest at object </summary>
        /// <param name="wowObject"> The turnin object. </param>
        /// <param name="questId"> The quest Id. If 0 (default) then first completed quest is turned in. </param>
        /// <param name="searchLocation">The search location of <paramref name="wowObject" />.</param>
        /// <param name="movementBy">The movement type to use.</param>
        /// <param name="navigationFailedAction">
        ///     The action to take if <paramref name="wowObject" /> or <paramref name="searchLocation"/> cant be navigated to
        /// </param>
        /// <param name="notFoundAction">
        ///     The action to take if <paramref name="wowObject" /> is not found at
        ///     <paramref name="searchLocation" />.
        /// </param>
        /// <returns><c>true</c> if an action was taken; <c>false</c> otherwise</returns>
        /// <exception cref="Exception">A delegate callback throws an exception.</exception>
        public static async Task <bool> TurninQuest(
            WoWObject wowObject,
            WoWPoint searchLocation,
            uint questId = 0,
            MovementByType movementBy     = MovementByType.FlightorPreferred,
            Action navigationFailedAction = null,
            Action notFoundAction         = null)
        {
            if (wowObject == null)
            {
                if (!Navigator.AtLocation(searchLocation))
                {
                    if (await MoveTo(searchLocation, "Quest turnin search area", movementBy))
                    {
                        return(true);
                    }

                    if (navigationFailedAction != null)
                    {
                        navigationFailedAction();
                    }
                    return(false);
                }

                if (notFoundAction != null)
                {
                    notFoundAction();
                }
                else
                {
                    TreeRoot.StatusText = "Waiting for the WoW object selected for quest turnin to spawn";
                }
                return(true);
            }

            if (!wowObject.WithinInteractRange)
            {
                if (await MoveTo(wowObject.Location, wowObject.SafeName, movementBy))
                {
                    return(true);
                }

                if (navigationFailedAction != null)
                {
                    navigationFailedAction();
                }
                return(false);
            }

            return(await ScriptHelpers.TurninQuest(wowObject, questId));
        }
예제 #7
0
        private WoWPoint FindNextHotspot()
        {
            WoWPoint currentHotspot = _hotSpots.Peek();

            // If we haven't reached the current hotspot, it is still the 'next' one...
            if (!Navigator.AtLocation(currentHotspot))
            {
                return(currentHotspot);
            }

            // Otherwise, rotate to the next hotspot in the list...
            _hotSpots.Enqueue(currentHotspot);
            _hotSpots.Dequeue();

            return(_hotSpots.Peek());
        }
예제 #8
0
        /// <summary>Determines whether <paramref name="myLoc" /> is within a tolerable proximity of <paramref name="location" />.</summary>
        /// <param name="myLoc">My loc.</param>
        /// <param name="location">The location.</param>
        /// <param name="tolerance">The tolerance. If <c>null</c>: Falls back to use <see cref="Navigator.AtLocation(Vector3,Vector3)"/>.</param>
        public static bool AtLocation(Vector3 myLoc, Vector3 location, float?tolerance)
        {
            if (!tolerance.HasValue)
            {
                return(Navigator.AtLocation(myLoc, location));
            }

            float tol = tolerance.Value;

            // We are checking if point is in an upright cylinder whose center is positioned at 'location',
            // radius set to 'tolerance' and height set to max(4.5, 'tolerance') x 2.
            // This is the most suitable method when using mesh navigation because the mesh is often above or below the
            // actual ingame terrain so there's a need to clamp the tolerance along the Z axis to an amount that
            // is greater then the maximum terrain/mesh Z coord difference
            return(myLoc.Distance2DSquared(location) <= tol * tol && Math.Abs(myLoc.Z - location.Z) <= Math.Max(4.5f, tol));
        }
예제 #9
0
            /// <summary>
            /// Tries to find a cached surface path distance between the start/destination pair and returns <c>true</c> if successful
            /// </summary>
            /// <param name="start">The start.</param>
            /// <param name="destination">The destination.</param>
            /// <param name="distance">The surface path distance, zero if no cache found or NaN if no path could be fully generated</param>
            /// <returns><c>true</c> if a cache was found, <c>false</c> otherwise.</returns>
            internal static bool TryGet(WoWPoint start, WoWPoint destination, out float distance)
            {
                SurfacePathDistanceCache match = null;
                var now = DateTime.Now;

                // do we need to cleanup old caches?
                var doCleanup = now - s_lastCleanupTime > s_maxCacheTimeSpan;

                // iterate the path cache in revere so we can remove entries safely
                for (int idx = s_pathDistanceCache.Count - 1; idx >= 0; idx--)
                {
                    var entry = s_pathDistanceCache[idx];
                    // check if we need the entry
                    if (doCleanup && now - entry.TimeStamp > s_maxCacheTimeSpan)
                    {
                        s_pathDistanceCache.RemoveAt(idx);
                        continue;
                    }
                    // check if we have a match
                    if (match == null && Navigator.AtLocation(start, entry.Start) && Navigator.AtLocation(destination, entry.Destination))
                    {
                        match = entry;
                        // exit for loop now if not doing a cleanup pass
                        if (!doCleanup)
                        {
                            break;
                        }
                    }
                }


                if (doCleanup)
                {
                    s_lastCleanupTime = now;
                }

                if (match == null)
                {
                    distance = 0;
                    return(false);
                }

                distance = match.Distance;
                return(true);
            }
        private Composite StateBehaviorPS_ReturningToBase()
        {
            return(new PrioritySelector(
                       // Start over...
                       new Decorator(context => !Query.IsInVehicle(),
                                     new Action(context => { BehaviorState = BehaviorStateType.MountingVehicle; })),

                       // Exit vehicle...
                       new Decorator(context => Navigator.AtLocation(PathEnd),
                                     new Action(context => { Lua.DoString("VehicleExit()"); })),

                       // Move back to 'safe mounting' area...
                       new Action(context =>
            {
                TreeRoot.StatusText = "Moving back to safe area";
                Flightor.MoveTo(PathEnd, (float)FlightorMinHeight);
            })
                       ));
        }
예제 #11
0
        /// <summary>
        /// Mounts a vehicle
        /// </summary>
        /// <param name="searchLocation">The search location.</param>
        /// <param name="movementBy">The movement type.</param>
        /// <param name="extraVehicleQualifiers">The extra vehicle qualifiers.</param>
        /// <param name="vehicleIds">The vehicle ids.</param>
        /// <returns>
        ///   <c>true</c> if any action was taken; <c>false</c> otherwise
        /// </returns>
        public static async Task <bool> MountVehicle(
            Vector3 searchLocation,
            MovementByType movementBy = MovementByType.FlightorPreferred,
            Func <WoWUnit, bool> extraVehicleQualifiers = null,
            params int[] vehicleIds)
        {
            if (Query.IsInVehicle())
            {
                return(false);
            }

            var vehicle = Query.FindUnoccupiedVehicles(vehicleIds, extraVehicleQualifiers).FirstOrDefault();

            if (vehicle == null)
            {
                if (!Navigator.AtLocation(searchLocation))
                {
                    return(await MoveTo(searchLocation, "Vehicle search area", movementBy));
                }

                await
                    (s_mountVehicleUserUpdateThrottle ??
                    (s_mountVehicleUserUpdateThrottle =
                         new ThrottleCoroutineTask(
                             TimeSpan.FromSeconds(10),
                             async() => QBCLog.Info("Waiting for a vehicle to become available"))));
                return(true);
            }

            if (!vehicle.WithinInteractRange)
            {
                return(await MoveTo(vehicle.Location, vehicle.SafeName, movementBy, vehicle.InteractRange));
            }

            if (await CommonCoroutines.Dismount("Getting inside vehicle"))
            {
                await Coroutine.Sleep(Delay.BeforeButtonClick);
            }
            vehicle.Interact();
            await Coroutine.Sleep(Delay.AfterInteraction);

            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")))
                       ));
        }
        private async Task <bool> EnterPortal()
        {
            var portalEntryTimer = new WaitTimer(MaxTimeToPortalEntry);

            portalEntryTimer.Reset();
            QBCLog.DeveloperInfo("Portal Entry Timer Started");

            while (true)
            {
                if (TookPortal)
                {
                    return(true);
                }

                // If portal entry timer expired, deal with it...
                if (portalEntryTimer.IsFinished)
                {
                    QBCLog.Warning(
                        "Unable to enter portal within allotted time of {0}",
                        Utility.PrettyTime(MaxTimeToPortalEntry));
                    break;
                }

                // If we are within 2 yards of calculated end point we should never reach...
                if (Me.Location.Distance(MovePoint) < 2)
                {
                    QBCLog.Warning("Seems we missed the portal. Is Portal activated? Profile needs to pick better alignment?");
                    break;
                }

                // If we're not moving toward portal, get busy...
                if (!StyxWoW.Me.IsMoving || Navigator.AtLocation(StartingPoint))
                {
                    QBCLog.DeveloperInfo("Entering portal via {0}", MovePoint);
                    WoWMovement.ClickToMove(MovePoint);
                }
                await Coroutine.Yield();
            }
            return(false);
        }
예제 #14
0
        private static async Task <bool> TryClickToMove(
            WoWPoint destination,
            NavType navType = NavType.Fly)
        {
            var activeMover = WoWMovement.ActiveMover;

            // NB: Do not 'dismount' for CtM.  We may be using it for aerial navigation, also.
            if (await SetMountState(destination, navType))
            {
                return(true);
            }

            // If Navigator can generate a parital path for us, take advantage of it...
            var tempDestination =
                Navigator.GeneratePath(activeMover.Location, destination)
                .Where(p => !Navigator.AtLocation(p))
                .DefaultIfEmpty(destination)
                .FirstOrDefault();

            WoWMovement.ClickToMove(tempDestination);
            return(true);
        }
예제 #15
0
        // Returns: RunStatus.Success while movement is in progress; othwerise, RunStatus.Failure if no movement necessary
        private Composite UtilityBehavior_MoveWithinRange(LocationDelegate locationDelegate,
                                                          MessageDelegate locationNameDelegate)
        {
            return(new Sequence(
                       // Done, if we're already at destination...
                       new DecoratorContinue(context => Navigator.AtLocation(locationDelegate(context)),
                                             new Decorator(context => Me.IsMoving, // This decorator failing indicates the behavior is complete
                                                           new Action(delegate { WoWMovement.MoveStop(); }))),

                       // Notify user of progress...
                       new CompositeThrottle(TimeSpan.FromSeconds(1),
                                             new Action(context =>
            {
                double destinationDistance = Me.Location.Distance(locationDelegate(context));
                string locationName = locationNameDelegate(context) ?? locationDelegate(context).ToString();
                Utility_NotifyUser(string.Format("Moving to {0} (distance: {1:F1})", locationName, destinationDistance));
            })),

                       new Action(context =>
            {
                WoWPoint destination = locationDelegate(context);

                // Try to use Navigator to get there...
                MoveResult moveResult = Navigator.MoveTo(destination);

                // If Navigator fails, fall back to click-to-move...
                if ((moveResult == MoveResult.Failed) || (moveResult == MoveResult.PathGenerationFailed))
                {
                    WoWMovement.ClickToMove(destination);
                }

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

                       new WaitContinue(_delay_WoWClientMovementThrottle, ret => false, new ActionAlwaysSucceed())
                       ));
        }
예제 #16
0
        /// <summary>Gossips with the specified wow object. Hearthstone bind popups are automatically accepted</summary>
        /// <param name="wowObject">The wow object. Navigates to <paramref name="searchLocation" /> null </param>
        /// <param name="searchLocation">The search location of <paramref name="wowObject" />.</param>
        /// <param name="movementBy">The movement type to use.</param>
        /// <param name="navigationFailedAction">
        ///     The action to take if <paramref name="wowObject" /> or <paramref name="searchLocation"/> cant be navigated to
        /// </param>
        /// <param name="notFoundAction">
        ///     The action to take if <paramref name="wowObject" /> is not found at
        ///     <paramref name="searchLocation" />.
        /// </param>
        /// <param name="noGossipFrameAction">
        ///     The action to take if interaction with <paramref name="wowObject" /> didn't open a
        ///     gossip frame.
        /// </param>
        /// <param name="noMatchingGossipOptionAction">
        ///     <para>The action to take if the passed in gossip type and/or gossip indices </para>
        ///     <para>doesn't match what was offered by <paramref name="wowObject" />.</para>
        /// </param>
        /// <param name="gossipEntryType">
        ///     <para>Type gossip entry type to select. Ignored if set to Unknown.</para>
        ///		<para>If none of this type are found on current page then</para>
        ///     <para> normal gossip types are clicked through in hopes of ending on a page with this gossip type</para>
        /// </param>
        /// <param name="gossipIndexes">
        ///     The gossip indexes to follow through. Has precedence over
        ///     <paramref name="gossipEntryType" />.
        /// </param>
        /// <exception cref="Exception">A delegate callback throws an exception.</exception>
        public static async Task <bool> Gossip(
            WoWObject wowObject,
            WoWPoint searchLocation,
            MovementByType movementBy                   = MovementByType.FlightorPreferred,
            Action navigationFailedAction               = null,
            Action notFoundAction                       = null,
            Action noGossipFrameAction                  = null,
            Action noMatchingGossipOptionAction         = null,
            GossipEntry.GossipEntryType gossipEntryType = GossipEntry.GossipEntryType.Unknown,
            params int[] gossipIndexes)
        {
            if (wowObject == null)
            {
                if (!Navigator.AtLocation(searchLocation))
                {
                    if (await MoveTo(searchLocation, "Gossip object search area", movementBy))
                    {
                        return(true);
                    }

                    navigationFailedAction?.Invoke();
                    return(false);
                }

                if (notFoundAction != null)
                {
                    notFoundAction();
                }
                else
                {
                    TreeRoot.StatusText = "Waiting for the WoW object selected for gossip to spawn";
                }
                return(true);
            }

            if (!wowObject.WithinInteractRange)
            {
                if (await MoveTo(wowObject.Location, wowObject.SafeName, movementBy))
                {
                    return(true);
                }

                navigationFailedAction?.Invoke();
                return(false);
            }

            if (await CommonCoroutines.Dismount("Gossiping with " + wowObject.SafeName))
            {
                await Coroutine.Sleep(Delay.BeforeButtonClick);
            }

            // If gossip frame is open then we must assume that it doesn't belong to the selected gossip object at this point
            if (GossipFrame.Instance.IsVisible)
            {
                GossipFrame.Instance.Close();
                return(true);
            }

            Func <bool> isFrameReadyForInput =
                () =>
                GossipFrame.Instance.IsVisible &&
                (GossipFrame.Instance.GossipOptionEntries != null ||
                 (!gossipIndexes.Any() && gossipEntryType == GossipEntry.GossipEntryType.Unknown));

            wowObject.Interact();
            var openedGossipFrame = await Coroutine.Wait(3000, isFrameReadyForInput);

            if (!openedGossipFrame)
            {
                QBCLog.Warning("No gossip frame was opened after interacting with {0}", wowObject.SafeName);
                noGossipFrameAction?.Invoke();

                return(false);
            }

            int gossipPage = 1;

            // Click through all the gossip indices
            for (var i = 0; i < gossipIndexes.Length; i++)
            {
                var index = gossipIndexes[i] - 1;

                var gossipEntry =
                    GossipFrame.Instance.GossipOptionEntries.Where(g => g.Index == index)
                    .Select(g => (GossipEntry?)g)
                    .FirstOrDefault();

                if (!gossipEntry.HasValue || gossipEntry.Value.Type == GossipEntry.GossipEntryType.Unknown)
                {
                    QBCLog.Warning("{0} does not provide a gossip at index {1} on page {2}", wowObject.SafeName, index + 1, gossipPage);
                    noMatchingGossipOptionAction?.Invoke();
                    return(false);
                }

                await ClickGossipOption(gossipEntry.Value, gossipPage);

                // make sure frame didn't close before we're done.
                if (!isFrameReadyForInput() && (i < gossipIndexes.Length - 1 || gossipEntryType != GossipEntry.GossipEntryType.Unknown))
                {
                    // This can happen if some external event causes object to stop offering gossip frame, such as NPC getting into combat.
                    // Usually this can be fixed by interacting with object again at a later time. We let the caller handle this.
                    QBCLog.Warning("Gossip frame for {0} closed unexpectedly.", wowObject.SafeName);
                    return(true);
                }
                gossipPage++;
            }

            if (gossipEntryType != GossipEntry.GossipEntryType.Unknown)
            {
                if (!gossipIndexes.Any())
                {
                    while (true)
                    {
                        var gossipEntry = GossipFrame.Instance.GossipOptionEntries.FirstOrDefault(g => g.Type == gossipEntryType);
                        // If no gossip indices were specified then we just click through more gossip,
                        // hopefully it leads to the final gossip type
                        if (gossipEntry.Type != gossipEntryType)
                        {
                            gossipEntry =
                                GossipFrame.Instance.GossipOptionEntries.FirstOrDefault(g => g.Type == GossipEntry.GossipEntryType.Gossip);
                        }

                        if (gossipEntry.Type == GossipEntry.GossipEntryType.Unknown)
                        {
                            QBCLog.Warning("{0} does not provide a {0} gossip type", wowObject.SafeName, gossipEntryType);
                            noMatchingGossipOptionAction?.Invoke();
                            return(false);
                        }

                        await ClickGossipOption(gossipEntry, gossipPage);

                        if (!isFrameReadyForInput() && gossipEntry.Type != gossipEntryType)
                        {
                            // This can happen if some external event causes object to stop offering gossip frame, such as NPC getting into combat.
                            // Usually this can be fixed by interacting with object again at a later time. We let the caller handle this.
                            QBCLog.Warning("Gossip frame for {0} closed unexpectedly.", wowObject.SafeName);
                            return(true);
                        }

                        if (gossipEntry.Type == gossipEntryType)
                        {
                            break;
                        }

                        gossipPage++;
                    }
                }
            }

            // Set hearthstone automatically
            const string setHsPopupName = "CONFIRM_BINDER";

            if (Lua.GetReturnVal <bool>($"return StaticPopup_Visible('{setHsPopupName}')", 0))
            {
                uint hsId = StyxWoW.Me.HearthstoneAreaId;
                Lua.DoString(
                    $"local _,frame = StaticPopup_Visible('{setHsPopupName}') if frame then StaticPopup_OnClick(frame, 1) end");

                if (await Coroutine.Wait(5000, () => StyxWoW.Me.HearthstoneAreaId != hsId))
                {
                    await CommonCoroutines.SleepForRandomReactionTime();

                    var boundLocation = Lua.GetReturnVal <string>("return GetBindLocation()", 0);

                    QBCLog.Info(
                        "You are now bound at {0} Inn in {1}({2})",
                        (Query.IsViable(wowObject) ? wowObject.SafeName : "the"),
                        boundLocation,
                        Me.HearthstoneAreaId);
                }
            }
            return(true);
        }
예제 #17
0
        private Composite CreateBehavior_CombatMain()
        {
            return(new Decorator(context => !IsDone,
                                 new PrioritySelector(
                                     // Update information for this BT visit...
                                     new Action(context =>
            {
                HighWarlordDarion = ObjectManager.GetObjectsOfType <WoWUnit>(false, false).FirstOrDefault(u => u.Entry == 29173);

                if ((HighWarlordDarion != null) && (Me.CurrentTarget != HighWarlordDarion))
                {
                    HighWarlordDarion.Target();
                }

                return RunStatus.Failure;
            }),

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


                                                                     #region State: Wait for Warlord
                                                                     new SwitchArgument <StateType_Behavior>(StateType_Behavior.WaitingForWarlordDarion,
                                                                                                             new PrioritySelector(
                                                                                                                 // Move into position to await Warlord arrival...
                                                                                                                 new Decorator(context => !Navigator.AtLocation(Location_WaitToChatWithDarion),
                                                                                                                               new Action(context =>
            {
                TreeRoot.StatusText = "Moving into position to wait on High Warlord Darion to arrive";
                Navigator.MoveTo(Location_WaitToChatWithDarion);
            })),

                                                                                                                 // Warlord has arrived, go have a chat..
                                                                                                                 new Decorator(context => HighWarlordDarion != null,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.ChattingToStartBattle; })),

                                                                                                                 // If warlord is not here, go check the battlefield...
                                                                                                                 new Decorator(context => !IsBattlefieldCheckedForDarion,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.CheckingBattlefieldForWarlordDarion; })),

                                                                                                                 new Action(context =>
            {
                TreeRoot.StatusText = "Waiting for High Warlord Darion to arrive";
                AntiAfk();
            })
                                                                                                                 )),
                                                                     #endregion


                                                                     #region State: Check Battlefield for Warlord
                                                                     new SwitchArgument <StateType_Behavior>(StateType_Behavior.CheckingBattlefieldForWarlordDarion,
                                                                                                             new PrioritySelector(
                                                                                                                 // Move into position to await Warlord arrival...
                                                                                                                 new Decorator(context => !Navigator.AtLocation(Location_WaitForBattleToComplete),
                                                                                                                               new Action(context =>
            {
                TreeRoot.StatusText = "Checking battlefield for High Warlord Darion";
                Navigator.MoveTo(Location_WaitForBattleToComplete);
            })),

                                                                                                                 // If we found Warlord on battlefield, wait for battle to complete...
                                                                                                                 new Decorator(context => HighWarlordDarion != null,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.WaitingForBattleToComplete; })),

                                                                                                                 // If warlord is not here, return to start point and wait...
                                                                                                                 new Decorator(context => HighWarlordDarion == null,
                                                                                                                               new Action(context =>
            {
                IsBattlefieldCheckedForDarion = true;
                State_Behavior = StateType_Behavior.WaitingForWarlordDarion;
            }))
                                                                                                                 )),
                                                                     #endregion


                                                                     #region State: Chat with Warlord
                                                                     new SwitchArgument <StateType_Behavior>(StateType_Behavior.ChattingToStartBattle,
                                                                                                             new PrioritySelector(
                                                                                                                 // If the Warlord disappeared, go find him...
                                                                                                                 new Decorator(context => HighWarlordDarion == null,
                                                                                                                               new Action(context =>
            {
                IsBattlefieldCheckedForDarion = false;
                State_Behavior = StateType_Behavior.WaitingForWarlordDarion;
            })),

                                                                                                                 // Move close enough to chat with Warlord...
                                                                                                                 new Decorator(context => !HighWarlordDarion.WithinInteractRange,
                                                                                                                               new Action(context =>
            {
                TreeRoot.StatusText = "Moving to " + HighWarlordDarion.SafeName;
                Navigator.MoveTo(HighWarlordDarion.Location);
            })),

                                                                                                                 // Chat with warlord...
                                                                                                                 // When we interact with the warlord, he will present us with either:
                                                                                                                 // 1) a Quest frame (with no gossip options)
                                                                                                                 // 2) a Gossip frame (with gossip options) that we use to kick off the event
                                                                                                                 // Both frames always *exist*, what matters is the one the Warlord presents us with.
                                                                                                                 new Decorator(context => HighWarlordDarion.CanGossip,
                                                                                                                               new PrioritySelector(
                                                                                                                                   new Decorator(context => !(GossipFrame.Instance.IsVisible || QuestFrame.Instance.IsVisible),
                                                                                                                                                 new Action(context => { HighWarlordDarion.Interact(); })),

                                                                                                                                   // Process GossipFrame or QuestFrame, whichever was presented...
                                                                                                                                   new Sequence(
                                                                                                                                       // Simulate reading frame text...
                                                                                                                                       new WaitContinue(VariantTimeSpan(2500, 7000), context => false, new ActionAlwaysSucceed()),
                                                                                                                                       // If gossip frame showing, choose correct gossip option...
                                                                                                                                       new DecoratorContinue(context => GossipFrame.Instance.IsVisible &&
                                                                                                                                                             GossipFrame.Instance.GossipOptionEntries.Count() > 0,
                                                                                                                                                             new Action(context => { GossipFrame.Instance.SelectGossipOption(0); })),
                                                                                                                                       new WaitContinue(VariantTimeSpan(1250, 3500), context => false, new ActionAlwaysSucceed()),
                                                                                                                                       // Close gossip frame if that was showing...
                                                                                                                                       new DecoratorContinue(context => GossipFrame.Instance.IsVisible,
                                                                                                                                                             new Action(context => { GossipFrame.Instance.Close(); })),
                                                                                                                                       // Close quest frame if that was showing...
                                                                                                                                       new DecoratorContinue(context => QuestFrame.Instance.IsVisible,
                                                                                                                                                             new Action(context => { QuestFrame.Instance.Close(); })),
                                                                                                                                       new Action(context => { State_Behavior = StateType_Behavior.WaitingForBattleToStart; })
                                                                                                                                       )
                                                                                                                                   )),

                                                                                                                 // Warlord doesn't want to chat, wait for battle to start...
                                                                                                                 new Decorator(context => !HighWarlordDarion.CanGossip,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.WaitingForBattleToStart; }))
                                                                                                                 )),
                                                                     #endregion


                                                                     #region State: Wait for Battle to start
                                                                     new SwitchArgument <StateType_Behavior>(StateType_Behavior.WaitingForBattleToStart,
                                                                                                             new PrioritySelector(
                                                                                                                 // If warlord disappeared, start over...
                                                                                                                 new Decorator(context => HighWarlordDarion == null,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.WaitingForWarlordDarion; })),

                                                                                                                 // If Warlord is already on the battlefield, time to go...
                                                                                                                 new Decorator(context => HighWarlordDarion.Location.Distance(Location_Battlefield.Location) <= Location_Battlefield.Radius,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.WaitingForBattleToComplete; })),

                                                                                                                 // If the warlord is not on the battlefield, follow him at a reasonable distance...
                                                                                                                 new Decorator(context => HighWarlordDarion.Distance > DistanceToFollowWarlord,
                                                                                                                               new Action(context =>
            {
                TreeRoot.StatusText = string.Format("Following {0}", HighWarlordDarion.SafeName);
                Navigator.MoveTo(HighWarlordDarion.Location);
            })),

                                                                                                                 // Move into position to await battle start...
                                                                                                                 new Decorator(context => !HighWarlordDarion.IsMoving && !Navigator.AtLocation(Location_WaitToChatWithDarion),
                                                                                                                               new Action(context =>
            {
                TreeRoot.StatusText = "Waiting for Battle to start";
                Navigator.MoveTo(Location_WaitToChatWithDarion);
            }))
                                                                                                                 )),
                                                                     #endregion


                                                                     #region State: Wait for Battle to complete
                                                                     new SwitchArgument <StateType_Behavior>(StateType_Behavior.WaitingForBattleToComplete,
                                                                                                             new PrioritySelector(
                                                                                                                 // If warlord disappeared, start over...
                                                                                                                 new Decorator(context => HighWarlordDarion == null,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.WaitingForWarlordDarion; })),

                                                                                                                 // If the warlord is on the battlefield, wait at our safespot...
                                                                                                                 new Decorator(context => HighWarlordDarion.Location.Distance(Location_Battlefield.Location) <= Location_Battlefield.Radius,
                                                                                                                               new PrioritySelector(
                                                                                                                                   // Move to our position to wait for battle to be over...
                                                                                                                                   new Decorator(context => !Navigator.AtLocation(Location_WaitForBattleToComplete),
                                                                                                                                                 new Action(context =>
            {
                TreeRoot.StatusText = "Moving to safe spot";
                Navigator.MoveTo(Location_WaitForBattleToComplete);
            })),

                                                                                                                                   // Wait for battle to be over...
                                                                                                                                   new Action(context =>
            {
                TreeRoot.StatusText = "Waiting for battle to complete.";
                AntiAfk();
            }))),

                                                                                                                 // If the warlord has returned to his starting position, then start over...
                                                                                                                 new Decorator(context => HighWarlordDarion.Location.Distance(Location_WaitToChatWithDarion) <= DistanceToFollowWarlord,
                                                                                                                               new Action(context => { State_Behavior = StateType_Behavior.WaitingForWarlordDarion; }))
                                                                                                                 ))
                                                                     #endregion
                                                                     )
                                     )));
        }
        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()
                       ));
        }
예제 #19
0
        public Composite CreateBehavior_SelectTarget(BehaviorFailIfNoTargetsDelegate failIfNoTargets)
        {
            return(
                new PrioritySelector(

                    // If we haven't engaged the mob when the auto-blacklist timer expires, give up on it and move on...
                    new Decorator(ret => ((CurrentTarget != null) &&
                                          (_currentTargetAutoBlacklistTimer.Elapsed > _currentTargetAutoBlacklistTime)),
                                  new Action(delegate
            {
                QBCLog.Warning("Taking too long to engage '{0}'--blacklisting", CurrentTarget.SafeName);
                CurrentTarget.LocallyBlacklist(_delay_AutoBlacklist);
                CurrentTarget = null;
            })),


                    // If we don't have a current target, select a new one...
                    // Once we select a target, its 'locked in' (unless it gets blacklisted).  This prevents us
                    // from running back and forth between two equidistant targets.
                    new Decorator(ret => ((CurrentTarget == null) ||
                                          !CurrentTarget.IsValid ||
                                          CurrentTarget.IsLocallyBlacklisted()),
                                  new PrioritySelector(context => CurrentTarget = ViableTargets().FirstOrDefault(),

                                                       // If we found next target, we're done...
                                                       new Decorator(ret => (CurrentTarget != null),
                                                                     new Action(delegate
            {
                _huntingGroundWaitPoint = WoWPoint.Empty;

                if (CurrentTarget is WoWUnit)
                {
                    CurrentTarget.ToUnit().Target();
                }

                _currentTargetAutoBlacklistTime = CalculateAutoBlacklistTime(CurrentTarget);
                _currentTargetAutoBlacklistTimer.Reset();
                _currentTargetAutoBlacklistTimer.Start();
            })),

                                                       // If we've exhausted mob/object supply in area, and we need to wait, do so...
                                                       new Decorator(ret => !failIfNoTargets(),

                                                                     // Move back to hunting ground anchor --
                                                                     new PrioritySelector(

                                                                         // If we've more than one hotspot, head to the next one...
                                                                         new Decorator(ret => (_hotSpots.Count() > 1),
                                                                                       new Sequence(context => FindNextHotspot(),
                                                                                                    new Action(nextHotspot => TreeRoot.StatusText = "No targets--moving to hotspot "
                                                                                                                                                    + (WoWPoint)nextHotspot),
                                                                                                    CreateBehavior_InternalMoveTo(() => FindNextHotspot())
                                                                                                    )),

                                                                         // We find a point 'near' our anchor at which to wait...
                                                                         // This way, if multiple people are using the same profile at the same time,
                                                                         // they won't be standing on top of each other.
                                                                         new Decorator(ret => (_huntingGroundWaitPoint == WoWPoint.Empty),
                                                                                       new Action(delegate
            {
                _huntingGroundWaitPoint = HuntingGroundAnchor.FanOutRandom(CollectionDistance * 0.25);
                TreeRoot.StatusText = "No targets--moving near hunting ground anchor point to wait";
                _repopWaitingTime.Reset();
                _repopWaitingTime.Start();
            })),

                                                                         // Move to our selected random point...
                                                                         new Decorator(ret => !Navigator.AtLocation(_huntingGroundWaitPoint),
                                                                                       CreateBehavior_InternalMoveTo(() => _huntingGroundWaitPoint)),

                                                                         // Tell user what's going on...
                                                                         new Sequence(
                                                                             new Action(delegate
            {
                TreeRoot.GoalText = this.GetType().Name + ": Waiting for Repops";
                TreeRoot.StatusText = "No targets in area--waiting for repops.  " + BuildTimeAsString(_repopWaitingTime.Elapsed);
            }),
                                                                             new WaitContinue(_delay_RepopWait, ret => false, new ActionAlwaysSucceed()))
                                                                         ))
                                                       )),

                    // Re-select target, if it was lost (perhaps, due to combat)...
                    new Decorator(ret => ((CurrentTarget is WoWUnit) && (Me.CurrentTarget != CurrentTarget)),
                                  new Action(delegate { CurrentTarget.ToUnit().Target(); }))
                    ));
        }
예제 #20
0
        private async Task <bool> ScareSpiders()
        {
            // if not in a turret than move to one and interact with it
            if (!Query.IsInVehicle())
            {
                var mustang = GetMustang();
                if (mustang == null)
                {
                    QBCLog.Warning("No mustang was found nearby");
                    return(false);
                }

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

                await CommonCoroutines.LandAndDismount();

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

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

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

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

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

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

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

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

                await Coroutine.Sleep(200);

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

            return(true);
        }
        private async static Task <bool> FollowPath()
        {
            if (!AutoAnglerSettings.Instance.Poolfishing && !AutoAnglerBot.Instance.Profile.FishAtHotspot)
            {
                return(false);
            }

            if (!AutoAnglerBot.Instance.Profile.FishAtHotspot &&
                (BotPoi.Current.Type == PoiType.Harvest || LootTargeting.Instance.FirstObject != null))
            {
                return(false);
            }

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

            //  dks can refresh water walking while flying around.
            if (AutoAnglerSettings.Instance.UseWaterWalking &&
                Me.Class == WoWClass.DeathKnight &&
                !WaterWalking.IsActive &&
                await WaterWalking.Cast())
            {
                return(true);
            }

            var moveto = AutoAnglerBot.Instance.Profile.CurrentPoint;

            if (moveto == WoWPoint.Zero)
            {
                return(false);
            }

            if (AutoAnglerBot.Instance.Profile.FishAtHotspot && Navigator.AtLocation(moveto))
            {
                return(false);
            }

            float precision = Me.IsFlying ? AutoAnglerSettings.Instance.PathPrecision : 3;

            if (Me.Location.Distance(moveto) <= precision)
            {
                AutoAnglerBot.Instance.Profile.CycleToNextPoint();
            }

            if (AutoAnglerSettings.Instance.Fly)
            {
                if (!StyxWoW.Me.Mounted && Flightor.MountHelper.CanMount)
                {
                    var zenFlightAura = StyxWoW.Me.GetAuraByName("Zen Flight");
                    if (zenFlightAura != null)
                    {
                        zenFlightAura.TryCancelAura();
                        await CommonCoroutines.SleepForLagDuration();
                    }
                    Flightor.MountHelper.MountUp();
                    return(true);
                }

                Flightor.MoveTo(moveto);
            }
            else
            {
                if (!StyxWoW.Me.Mounted && Mount.ShouldMount(moveto) && Mount.CanMount())
                {
                    Mount.MountUp(() => moveto);
                }
                var result = Navigator.MoveTo(moveto);
                if (result != MoveResult.Failed && result != MoveResult.PathGenerationFailed)
                {
                    InactivityDetector.Reset();
                }
            }
            return(true);
        }
        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
                                                           )));
        }
예제 #23
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);
            }))
                       ));
        }
예제 #24
0
        protected Composite CreateBehavior_QuestbotMain()
        {
            return(_root ?? (_root =
                                 new Decorator(ret => !IsDone && (!AllowCombat || !Me.Combat),
                                               new PrioritySelector(
                                                   new Decorator(ret => !Path.Any() && Counter >= NumOfTimes,
                                                                 new Action(delegate
            {
                _isBehaviorDone = true;
            })),
                                                   new Decorator(ret => !Path.Any(),
                                                                 new Action(delegate
            {
                Counter++;
                ParsePath();
            })),
                                                   new Decorator(ret => Navigator.AtLocation(Path.Peek()),
                                                                 new PrioritySelector(
                                                                     new Decorator(ret => Me.IsMoving && WaitTime > 0,
                                                                                   new Sequence(
                                                                                       new Action(ret => WoWMovement.MoveStop()),
                                                                                       new Action(ret => TreeRoot.GoalText = "RunLikeHell pausing " + WaitTime + " ms"),
                                                                                       new WaitContinue(TimeSpan.FromMilliseconds(WaitTime), ret => false, new ActionAlwaysSucceed())
                                                                                       )
                                                                                   ),
                                                                     new Decorator(ret => MobId != 0 && Mob.Distance > Range,
                                                                                   new Action(delegate
            {
                TreeRoot.GoalText = "RunLikeHell wait for " + Mob.SafeName + " within " + Range + " yds";
            })),
                                                                     new Action(delegate
            {
                Path.Dequeue();
            }))
                                                                 ),
                                                   new Action(delegate
            {
                if (NumOfTimes > 1)
                {
                    TreeRoot.GoalText = "RunLikeHell[Lap " + Counter + "] to " + Path.Peek().ToString();
                }
                else
                {
                    TreeRoot.GoalText = "RunLikeHell to " + Path.Peek().ToString();
                }

                if (UseCTM)
                {
                    WoWMovement.ClickToMove(Path.Peek());
                }
                else
                {
                    Navigator.MoveTo(Path.Peek());
                }

                return _lastStateReturn;
            })
                                                   )
                                               )
                             ));
        }
예제 #25
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())
                                         ))
                       ));
        }
예제 #26
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())
                                     )));
        }
        protected override Composite CreateBehavior()
        {
            return(_Root ?? (_Root =
                                 new PrioritySelector(context => !s_isBehaviorDone,

                                                      #region MyHotSpot
                                                      // Store our current location.
                                                      new Decorator(context => MyHotSpot == WoWPoint.Empty,
                                                                    new Sequence(
                                                                        new DecoratorContinue(context => Me.IsMoving,
                                                                                              new WaitContinue(TimeSpan.FromMilliseconds(2000), context => false, new ActionAlwaysSucceed())
                                                                                              ),
                                                                        new DecoratorContinue(context => !Me.IsMoving,
                                                                                              new Action(context => MyHotSpot = Me.Location)
                                                                                              )
                                                                        )
                                                                    ),
                                                      #endregion

                                                      #region MinLevel
                                                      // Should we check for partymember minumum level ?
                                                      new Decorator(context => (MinLevel > 0),
                                                                    new Sequence(
                                                                        // Someone is below MinLevel.
                                                                        new DecoratorContinue(context => !CheckLevel(),
                                                                                              new Sequence(
                                                                                                  new Action(context => QBCLog.Info("Someone in your party is below level {0}.", MinLevel)),
                                                                                                  new Action(context => s_isBehaviorDone = true)
                                                                                                  )
                                                                                              ),
                                                                        // Everyone is equal or above MinLevel.
                                                                        new DecoratorContinue(context => CheckLevel(),
                                                                                              new Action(context => MinLevel = 0)
                                                                                              )
                                                                        )
                                                                    ),
                                                      #endregion

                                                      #region CheckRange
                                                      // Should we wait for party members to be in range ?
                                                      new Decorator(context => (CheckRange != 0),
                                                                    new Sequence(
                                                                        // Everyone isn't within interact range, lets wait abit before checking again.
                                                                        new DecoratorContinue(context => !CheckPartyRange(),
                                                                                              new Sequence(
                                                                                                  new DecoratorContinue(context => !Navigator.AtLocation(MyHotSpot),
                                                                                                                        new Sequence(
                                                                                                                            new DecoratorContinue(context => Navigator.CanNavigateFully(Me.Location, MyHotSpot),
                                                                                                                                                  new Action(context => Navigator.MoveTo(MyHotSpot))
                                                                                                                                                  ),
                                                                                                                            new DecoratorContinue(context => !Navigator.CanNavigateFully(Me.Location, MyHotSpot),
                                                                                                                                                  new Action(context => Flightor.MoveTo(MyHotSpot))
                                                                                                                                                  )
                                                                                                                            )
                                                                                                                        ),
                                                                                                  new WaitContinue(TimeSpan.FromMilliseconds(300), context => false, new ActionAlwaysSucceed())
                                                                                                  )
                                                                                              ),
                                                                        // Everyone is within interact range.
                                                                        new DecoratorContinue(context => CheckPartyRange(),
                                                                                              new Sequence(
                                                                                                  new Action(context => QBCLog.Info("Everyone is within range.")),
                                                                                                  new Action(context => CheckRange = 0)
                                                                                                  )
                                                                                              )
                                                                        )
                                                                    ),
                                                      #endregion

                                                      #region ChkExp
                                                      // Disabled until I can find out a safer way to to it.

                                                      /*
                                                       * new Decorator(context => (ChkExp != 0),
                                                       *  new Sequence(
                                                       *      new DecoratorContinue(context => !AreWeDone(),
                                                       *          new Action(context => CheckExpansions())
                                                       *      ),
                                                       *      new DecoratorContinue(context => AreWeDone(),
                                                       *          new Sequence(
                                                       *              new DecoratorContinue(context => !DoAllHaveExp(),
                                                       *                  new Sequence(
                                                       *                      new Action(context => QBCLog.Info("Everyone in your group doesn't have ExpansionLevel '{0}'", ChkExp)),
                                                       *                      new Action(context => _isBehaviorDone = true)
                                                       *                  )
                                                       *              ),
                                                       *              new DecoratorContinue(context => DoAllHaveExp(),
                                                       *                  new Sequence(
                                                       *                      new Action(context => QBCLog.Info("Everyone has atleast ExpansionLevel '{0}'", ChkExp)),
                                                       *                      new Action(context => ChkExp = 0)
                                                       *                  )
                                                       *              )
                                                       *          )
                                                       *      )
                                                       *  )
                                                       * ),
                                                       */
                                                      #endregion

                                                      #region RemotePath
                                                      // Load the remote profile...
                                                      new Decorator(context => RemotePath != "",
                                                                    new Sequence(
                                                                        // You have included a RemotePath but not a ProfileName.
                                                                        new DecoratorContinue(context => ProfileName == "",
                                                                                              new Sequence(
                                                                                                  new Action(context => QBCLog.Error("You need to include a ProfileName.")),
                                                                                                  new Action(context => s_isBehaviorDone = true)
                                                                                                  )
                                                                                              ),
                                                                        // Remote Profile doesn't exist.
                                                                        new DecoratorContinue(context => (ProfileName != "" && !UrlExists(NewRemoteProfilePath)),
                                                                                              new Sequence(
                                                                                                  new Action(context => QBCLog.Error("Profile '{0}' does not exist.", ProfileName)),
                                                                                                  new Action(context => s_isBehaviorDone = true)
                                                                                                  )
                                                                                              ),
                                                                        // Everything is ok, Load the remote Profile
                                                                        new DecoratorContinue(context => (ProfileName != "" && UrlExists(NewRemoteProfilePath)),
                                                                                              new Sequence(
                                                                                                  new Action(context => TreeRoot.StatusText = "Loading profile '" + ProfileName + "'"),
                                                                                                  new Action(context => QBCLog.Info("Loading profile '{0}'", ProfileName)),
                                                                                                  new Action(context => ProfileManager.LoadNew(new MemoryStream(new WebClient().DownloadData(NewRemoteProfilePath)))),
                                                                                                  new WaitContinue(TimeSpan.FromMilliseconds(300), context => false, new ActionAlwaysSucceed()),
                                                                                                  new Action(context => s_isBehaviorDone = true)
                                                                                                  )
                                                                                              )
                                                                        )
                                                                    ),
                                                      #endregion

                                                      #region ProfileName
                                                      // Load the local profile...
                                                      new Decorator(context => (ProfileName != "" && RemotePath == ""),
                                                                    new PrioritySelector(
                                                                        // Local Profile doesn't exist.
                                                                        new Decorator(context => !IsStoreProfile && !File.Exists(NewLocalProfilePath),
                                                                                      new Sequence(
                                                                                          new Action(context => QBCLog.Error("Profile '{0}' does not exist.", ProfileName)),
                                                                                          new Action(context => s_isBehaviorDone = true)
                                                                                          )
                                                                                      ),
                                                                        // Everything is ok, Load the local Profile.
                                                                        new Sequence(
                                                                            new Action(context => TreeRoot.StatusText = "Loading profile '" + ProfileName + "'"),
                                                                            new Action(context => QBCLog.Error("Loading profile '{0}'", ProfileName)),
                                                                            new Action(context => ProfileManager.LoadNew(NewLocalProfilePath, false)),
                                                                            new WaitContinue(TimeSpan.FromMilliseconds(300), context => false, new ActionAlwaysSucceed()),
                                                                            new Action(context => s_isBehaviorDone = true)
                                                                            )
                                                                        )
                                                                    ),
                                                      #endregion

                                                      #region Behavior Done
                                                      // Everyone is within interact range and we shouldn't load a profile, then end the Quest Behavior.
                                                      new Decorator(context => !s_isBehaviorDone,
                                                                    new Action(context => s_isBehaviorDone = true)
                                                                    )
                                                      #endregion
                                                      )
                             ));
        }
예제 #28
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);
        }
예제 #29
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);
        }
예제 #30
0
        public static async Task <bool> DoFishing()
        {
            if (AutoAnglerBot.Instance.Profile.FishAtHotspot && !Navigator.AtLocation(AutoAnglerBot.Instance.Profile.CurrentPoint))
            {
                return(false);
            }

            if (AutoAnglerSettings.Instance.Poolfishing &&
                BotPoi.Current.Type != PoiType.Harvest)
            {
                return(false);
            }

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

            // refresh water walking if needed
            if (!Me.Mounted && WaterWalking.CanCast &&
                !WaterWalking.IsActive &&
                await WaterWalking.Cast())
            {
                return(true);
            }

            if (AutoAnglerSettings.Instance.Poolfishing)
            {
                var pool = BotPoi.Current.AsObject as WoWGameObject;
                if (pool == null || !pool.IsValid)
                {
                    BotPoi.Clear();
                    return(false);
                }

                if (await MoveToPool(pool))
                {
                    return(true);
                }
            }

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

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

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

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

            if (!AutoAnglerSettings.Instance.Poolfishing &&
                AutoAnglerBot.Instance.ShouldFaceWaterNow)
            {
                AutoAnglerBot.Instance.ShouldFaceWaterNow = false;
                if (await FaceWater())
                {
                    return(true);
                }
            }

            if (Me.Mounted && await CommonCoroutines.Dismount("Fishing"))
            {
                return(true);
            }

            if (!await Coroutine.Wait(10000, () => !Me.IsFalling))
            {
                AutoAnglerBot.Log("Falling for 10 seconds; I don't think this will end good.");
                return(false);
            }

            if (Me.IsSwimming)
            {
                await JumpOnWaterSurface();
            }

            if (Me.IsMoving)
            {
                WoWMovement.MoveStop();
                if (!await Coroutine.Wait(4000, () => !Me.IsMoving))
                {
                    return(false);
                }
            }
            // Checks if we got a bite and recasts if needed.
            if (await CheckFishLine())
            {
                return(true);
            }

            return(false);
        }