Exemple #1
0
        private async Task UseItem(int x)
        {
            var g = Geomancer(_spots[x]);

            if (!Query.IsViable(g))
            {
                return;
            }

            if (g.DistanceSqr > 5 * 5)
            {
                await CommonCoroutines.MoveTo(g.Location);

                return;
            }

            if (Me.CurrentTarget != g)
            {
                g.Target();
                return;
            }

            await CommonCoroutines.Dismount();

            Rock.Use();
        }
Exemple #2
0
        public static async Task <bool> Rotation()
        {
            if (Me.Mounted)
            {
                if (await CommonCoroutines.Dismount())
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #3
0
        public static async Task <bool> Rotation()
        {
            if (!Me.Mounted && !Me.IsInTravelForm())
            {
                return(await Combat.Rotation());
            }
            if (await CommonCoroutines.Dismount())
            {
                return(true);
            }

            return(await Combat.Rotation());
        }
Exemple #4
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);
        }
        /// <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);
        }
Exemple #6
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);
        }
Exemple #7
0
        private Composite CreateBehavior_GetInVehicle()
        {
            const uint oldBlastyId = 43562;

            WoWUnit vehicle = null;

            return(new Decorator(ctx => !Query.IsInVehicle(),
                                 new PrioritySelector(
                                     ctx => vehicle = ObjectManager.GetObjectsOfTypeFast <WoWUnit>().FirstOrDefault(u => u.Entry == oldBlastyId),
                                     new Decorator(ctx => vehicle != null && !vehicle.WithinInteractRange, new Action(ctx => Navigator.MoveTo(vehicle.Location))),
                                     new Decorator(
                                         ctx => vehicle != null && vehicle.WithinInteractRange,
                                         new PrioritySelector(
                                             new Decorator(ctx => Me.Mounted,
                                                           new ActionRunCoroutine(context => CommonCoroutines.Dismount("Getting in vehicle"))),
                                             new Action(ctx => vehicle.Interact()))))));
        }
        protected async override Task Run()
        {
            if (Me.IsFlying && await CommonCoroutines.Dismount("Crafting an item"))
            {
                return;
            }

            if (!IsRecipe)
            {
                CheckTradeskillList();
            }

            if (Casted >= CalculatedRepeat)
            {
                Finished();
                return;
            }

            // can't make recipe so stop trying.
            if (IsRecipe && Recipe.CanRepeatNum2 <= 0)
            {
                Finished("Not enough material.");
                return;
            }

            if (Me.IsCasting && Me.CastingSpellId != Entry)
            {
                SpellManager.StopCasting();
            }

            // we should confirm the last recipe in list so we don't make an axtra
            if (Casted + 1 < CalculatedRepeat || (Casted + 1 == CalculatedRepeat &&
                                                  (Confimed || !_spamControl.IsRunning ||
                                                   (_spamControl.ElapsedMilliseconds >=
                                                    (_recastTime + (_recastTime / 2)) + _waitTime &&
                                                    !StyxWoW.Me.IsCasting))))
            {
                if (!_spamControl.IsRunning || Me.IsCasting && Me.CurrentCastTimeLeft <= TimeSpan.FromMilliseconds(250) ||
                    (!StyxWoW.Me.IsCasting && _spamControl.ElapsedMilliseconds >= _waitTime))
                {
                    if (StyxWoW.Me.IsMoving)
                    {
                        WoWMovement.MoveStop();
                    }
                    if (!QueueIsRunning)
                    {
                        Lua.Events.AttachEvent("UNIT_SPELLCAST_SUCCEEDED", OnUnitSpellCastSucceeded);
                        QueueIsRunning      = true;
                        TreeRoot.StatusText = string.Format("Casting: {0}",
                                                            IsRecipe
                                                                                                                                ? Recipe.Name
                                                                                                                                : Entry.ToString());
                    }
                    WoWSpell spell = WoWSpell.FromId((int)Entry.Value);
                    if (spell == null)
                    {
                        PBLog.Warn("{0}: {1}", Strings["Error_UnableToFindSpellWithEntry"], Entry.Value.ToString(CultureInfo.InvariantCulture));
                        return;
                    }

                    _recastTime = spell.CastTime;
                    ProfessionbuddyBot.Debug("Casting {0}, recast :{1}", spell.Name, _recastTime);
                    if (CastOnItem)
                    {
                        WoWItem item = TargetedItem;
                        if (item != null)
                        {
                            spell.CastOnItem(item);
                        }
                        else
                        {
                            PBLog.Warn(
                                "{0}: {1}",
                                Strings["Error_UnableToFindItemToCastOn"],
                                IsRecipe
                                                                        ? Recipe.Name
                                                                        : Entry.Value.ToString(CultureInfo.InvariantCulture));
                            IsDone = true;
                        }
                    }
                    else
                    {
                        spell.Cast();
                    }
                    _waitTime = Util.WowWorldLatency * 3 + 50;
                    Confimed  = false;
                    _spamControl.Reset();
                    _spamControl.Start();
                }
            }
        }
Exemple #9
0
        private Composite CreateBehavior_Antistuck()
        {
            return(new PrioritySelector(
                       new Decorator(context => _stuckTimer.IsFinished,
                                     new Sequence(context => _antiStuckMyLoc = WoWMovement.ActiveMover.Location,

                                                  // Check if stuck...
                                                  new DecoratorContinue(context => _antiStuckMyLoc.DistanceSqr(_antiStuckPrevPosition) < (3 * 3),
                                                                        new Sequence(context => _antiStuckPerformSimpleSequence = _antiStuckStuckSucceedTimer.IsFinished,
                                                                                     new DecoratorContinue(context => Me.IsMounted() && !Me.IsFlying,
                                                                                                           new ActionRunCoroutine(context => CommonCoroutines.Dismount("Stuck"))),

                                                                                     // Perform simple unstuck proceedure...
                                                                                     new DecoratorContinue(context => _antiStuckPerformSimpleSequence,
                                                                                                           new Sequence(
                                                                                                               new Action(context => QBCLog.Debug("Stuck. Trying to jump")),
                                                                                                               new Action(context =>
            {
                // ensure bot is moving forward when jumping (Wow will sometimes automatically
                // stop moving if running against a wall)
                if (ShouldPerformCTM)
                {
                    WoWMovement.ClickToMove(Destination);
                }
                WoWMovement.Move(WoWMovement.MovementDirection.JumpAscend);
            }),
                                                                                                               new Sleep(1000),
                                                                                                               new Action(context => WoWMovement.MoveStop(WoWMovement.MovementDirection.JumpAscend))
                                                                                                               )),

                                                                                     // perform less simple unstuck proceedure
                                                                                     new DecoratorContinue(context => !_antiStuckPerformSimpleSequence,
                                                                                                           new Sequence(context => _antiStuckMoveDirection = GetRandomMovementDirection(),
                                                                                                                        new Action(context => QBCLog.Debug("Stuck. Movement Directions: {0}", _antiStuckMoveDirection)),
                                                                                                                        new Action(context => WoWMovement.Move(_antiStuckMoveDirection)),
                                                                                                                        new Sleep(2000),
                                                                                                                        new Action(context => WoWMovement.MoveStop(_antiStuckMoveDirection)))),

                                                                                     new Action(context => _antiStuckStuckSucceedTimer.Reset()))),

                                                  new Action(context => _antiStuckPrevPosition = _antiStuckMyLoc),
                                                  new Action(context => _stuckTimer.Reset())
                                                  ))));
        }
        private Composite CreateBehavior_GetInVehicle()
        {
            const uint flamebringerId = 27292;

            WoWUnit flamebringer = null;

            return
                (new PrioritySelector(
                     ctx =>
                     flamebringer =
                         ObjectManager.GetObjectsOfTypeFast <WoWUnit>().FirstOrDefault(u => u.Entry == flamebringerId),
                     // move out to framebringers location
                     new Decorator(ctx => flamebringer == null, CreateBehavior_MoveTo(ctx => _flamebringerLocation)),
                     new Decorator(ctx => flamebringer.Distance > 5, CreateBehavior_MoveTo(ctx => flamebringer.Location)),
                     // dismount and cancel shapeshift
                     new Decorator(ctx => Me.IsMounted(), new ActionRunCoroutine(context => CommonCoroutines.Dismount("Getting on Flamebringger"))),
                     new Decorator(ctx => Me.IsShapeshifted(), new Action(ctx => Lua.DoString("CancelShapeshiftForm()"))),
                     new Decorator(ctx => Me.IsMoving, new Action(ctx => WoWMovement.MoveStop())),
                     // interact with and talk to flamebringer
                     new Decorator(ctx => !GossipFrame.Instance.IsVisible, new Action(ctx => flamebringer.Interact())),
                     new Decorator(
                         ctx => GossipFrame.Instance.IsVisible,
                         new Action(ctx => GossipFrame.Instance.SelectGossipOption(0)))));
        }
        public async static Task <bool> MoveToPool(WoWGameObject pool)
        {
            if (!AutoAnglerSettings.Instance.Poolfishing || AutoAnglerBot.Instance.Profile.FishAtHotspot)
            {
                return(false);
            }

            if (pool == null || !pool.IsValid)
            {
                return(false);
            }

            if (_lastPoolGuid != pool.Guid)
            {
                MoveToPoolTimer.Reset();
                _lastPoolGuid = pool.Guid;
                if (!FindPoolPoint(pool, out _poolPoints) || !_poolPoints.Any())
                {
                    Utility.BlacklistPool(pool, TimeSpan.FromDays(1), "Found no landing spots");
                    return(false);
                }
            }

            // should never be true.. but being safe..
            if (!_poolPoints.Any())
            {
                Utility.BlacklistPool(pool, TimeSpan.FromDays(1), "Pool landing points mysteriously disapear...");
                return(false);
            }

            var myLoc  = Me.Location;
            var moveto = _poolPoints[0];

            TreeRoot.StatusText = "Moving to " + pool.Name;
            if (myLoc.DistanceSqr(moveto) > 4 * 4)
            {
                MoveResult moveResult;
                if (AutoAnglerSettings.Instance.Fly)
                {
                    // don't bother mounting up if we can use navigator to walk over if it's less than 25 units away
                    if (myLoc.DistanceSqr(moveto) < 25 * 25 && !Me.Mounted)
                    {
                        moveResult = Navigator.MoveTo(moveto);
                        if (moveResult != MoveResult.Failed && moveResult != MoveResult.PathGenerationFailed)
                        {
                            return(true);
                        }
                    }

                    //if (!Me.Mounted && !SpellManager.GlobalCooldown)
                    //{
                    //	Flightor.MountHelper.MountUp();
                    //	return true;
                    //}
                    Flightor.MoveTo(WoWMathHelper.CalculatePointFrom(myLoc, moveto, -1f));
                    return(true);
                }

                moveResult = Navigator.MoveTo(moveto);
                if (moveResult == MoveResult.UnstuckAttempt ||
                    moveResult == MoveResult.PathGenerationFailed ||
                    moveResult == MoveResult.Failed)
                {
                    if (!RemovePointAtTop(pool))
                    {
                        return(true);
                    }
                    AutoAnglerBot.Debug("Unable to path to pool point, switching to a new point");
                    _poolPoints.Sort((a, b) => a.DistanceSqr(myLoc).CompareTo(b.DistanceSqr(myLoc)));
                }

                // if it takes more than 25 seconds to get to a point remove that point and try another.
                if (MoveToPoolTimer.IsFinished)
                {
                    if (!RemovePointAtTop(pool))
                    {
                        return(false);
                    }
                }
                return(true);
            }
            // wait for bot to reach destination before dismounting
            await Coroutine.Wait(2000, () => !Me.IsMoving);

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

            // can't fish while swimming..
            if (Me.IsSwimming && !WaterWalking.IsActive && !WaterWalking.CanCast)
            {
                AutoAnglerBot.Debug("Moving to new PoolPoint since I'm swimming at current PoolPoint");
                if (!RemovePointAtTop(pool))
                {
                    return(false);
                }
                return(true);
            }
            return(false);
        }