예제 #1
0
        public override async Task <bool> BehaviorRoutine()
        {
            if (await base.BehaviorRoutine())
            {
                return(true);
            }

            if (IsDone)
            {
                return(false);
            }

            if (await StartMovement.MoveTo())
            {
                return(true);
            }

            if (!InteractionObjectValid)
            {
                GarrisonBase.Err("Interaction Object Id {0} not valid or found!", InteractionEntryId);
                return(false);
            }

            if (GossipHelper.IsOpen)
            {
                int index = QuestHelper.GetAvailableQuestIndexFromGossipFrame(QuestID);
                if (index == -1)
                {
                    GarrisonBase.Err("Failed to find quest {0} in gossip frame!", QuestID);
                    return(false);
                }
                GossipFrame.Instance.SelectAvailableQuest(index);
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                return(true);
            }

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

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

            if (_specialMovement != null && await _specialMovement.ClickToMove())
            {
                return(true);
            }

            if (await EndMovement.MoveTo())
            {
                return(true);
            }

            IsDone = true;
            return(false);
        }
예제 #2
0
        private static async Task <bool> DisenchantInteraction(List <C_WoWItem> items)
        {
            if (Player.CurrentPendingCursorSpellId == DisenchantSpellId)
            {
                //Item Interaction!
                GarrisonBase.Log("Disenchant Cursor!");

                if (items.Count > 0)
                {
                    var item = items[0];
                    GarrisonBase.Debug("Disenchanting Item {0} ({1}) Quality {2}", item.Name, item.Entry, item.Quality);
                    bool bagChanged = await CommonCoroutines.WaitForLuaEvent(
                        "BAG_UPDATE",
                        6200,
                        null,
                        item.Use);

                    PlayerInventory.ItemDisenchantingBlacklistedGuids.Add(item.Guid);

                    //Force update if bag didn't change.. (so we ignore this item now)
                    if (!bagChanged)
                    {
                        Player.Inventory.UpdateBagItems();
                    }

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

            var spell = DisenchantSpell;

            if (spell != null)
            {
                bool cursorChanged = await CommonCoroutines.WaitForLuaEvent(
                    "CURRENT_SPELL_CAST_CHANGED",
                    StyxWoW.Random.Next(555, 2002),
                    null,
                    spell.Cast);

                await CommonCoroutines.SleepForRandomUiInteractionTime();

                await Coroutine.Yield();

                await Coroutine.Sleep(StyxWoW.Random.Next(1222, 2222));
            }
            else
            {
                GarrisonBase.Err("Disenchanting Spell returned null!");
                return(false);
            }



            return(true);
        }
예제 #3
0
 public GossipOptionEntry(string text, string type)
 {
     Text = text;
     try
     {
         Type = (GossipEntry.GossipEntryType)Enum.Parse(typeof(GossipEntry.GossipEntryType), type, true);
     }
     catch (Exception)
     {
         GarrisonBase.Err("Failed to parse gossip entry type from {0}", type);
         Type = GossipEntry.GossipEntryType.Unknown;
     }
 }
예제 #4
0
        private static async Task <bool> CheckLootFrame()
        {
            // loot everything.
            if (!LuaEvents.LootOpened)
            {
                return(false);
            }

            var lootSlotInfos = new List <LootSlotInfo>();

            for (int i = 0; i < LootFrame.Instance.LootItems; i++)
            {
                lootSlotInfos.Add(LootFrame.Instance.LootInfo(i));
            }

            if (await Coroutine.Wait(2000, () =>
            {
                LootFrame.Instance.LootAll();
                return(!LuaEvents.LootOpened);
            }))
            {
                GarrisonBase.Log("Succesfully looted: ");
                foreach (LootSlotInfo lootinfo in lootSlotInfos)
                {
                    try
                    {
                        string lootQuanity = lootinfo.LootQuantity.ToString();
                        string lootName    = lootinfo.LootName;
                        GarrisonBase.Log(lootQuanity + "x " + lootName);
                    }
                    catch
                    {
                        GarrisonBase.Log("exception occured");
                    }
                }
            }
            else
            {
                GarrisonBase.Err("Failed to loot from Frame.");
            }
            await CommonCoroutines.SleepForLagDuration();

            return(true);
        }
        private async Task <bool> Movement()
        {
            if (CommandTable == null)
            {
                //Error Cannot find object!
                GarrisonBase.Err("Could Not Find Command Table!");
                IsDone = true;
                return(false);
            }

            if (CommandTable.Distance < 4.56 && CommandTable.LineOfSight)
            {
                if (GarrisonMissionFrame.Instance.IsVisible)
                {
                    _interactattempts = 0;
                    return(false);
                }

                CommandTable.Interact();
                _interactattempts++;
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                if (_interactattempts > 3)
                {
                    GarrisonBase.Err("Attempted over 3 interactions with command table! Starting mvoement..");
                    StartMovement.CurrentMovementQueue.Enqueue(MovementCache.GarrisonEntrance);
                    _interactattempts = 0;
                }

                return(true);
            }



            if (_movement == null)
            {
                _movement = new Movement(CommandTable.Location, 4.55f, name: "CommandTable");
            }

            await _movement.MoveTo(false);

            return(true);
        }
예제 #6
0
        private async Task <bool> Movement()
        {
            if (LuaEvents.MailOpen)
            {
                return(false);
            }

            if (Mailbox == null)
            {
                if (await StartMovement.MoveTo())
                {
                    return(true);
                }

                //No object found..
                IsDone = true;
                GarrisonBase.Err("Could not find mail box object!");
                return(false);
            }

            if (Mailbox.WithinInteractRange)
            {
                Mailbox.Interact();
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                await Coroutine.Sleep(StyxWoW.Random.Next(1250, 2555));

                return(true);
            }

            if (_movement == null)
            {
                _movement = new Movement(Mailbox.Location, 6f, name: "Mailbox");
            }

            await _movement.MoveTo(false);

            return(true);
        }
        private async Task <bool> Movement()
        {
            if (Building.CheckedWorkOrderStartUp)
            {
                return(false);
            }

            if (WorkOrderObject == null)
            {
                GarrisonBase.Err("Could not find Work Order Npc Id {0}", Building.WorkOrderNpcEntryId);
                //Error Cannot find object!
                Building.CheckedWorkOrderStartUp = true;
                return(false);
            }



            if (WorkOrderObject.WithinInteractRange)
            {
                if (StyxWoW.Me.IsMoving)
                {
                    await CommonCoroutines.StopMoving();
                }
                await CommonCoroutines.SleepForLagDuration();

                if (_interactionAttempts > 3)
                {
                    GarrisonBase.Log("Interaction Attempts for {0} has exceeded 3! Preforming movement..",
                                     WorkOrderObject.Name);
                    StartMovement.Reset();
                    _interactionAttempts = 0;
                    return(true);
                }


                if (LuaUI.WorkOrder.IsVisible())
                {
                    //Workorder frame is displayed!
                    _interactionAttempts = 0;
                    return(false);
                }

                if (Building.Type == BuildingType.Barn && GossipHelper.IsOpen)
                {
                    //var entries = GossipHelper.GossipOptions.Where(
                    //                entry => entry.Text.ToLower().Contains(BarnWorkOrderGossipString)).ToList();
                    var entries = GossipHelper.GossipOptions.Where(
                        entry => entry.Index == BarnGossipIndex).ToList();
                    if (entries.Count > 0)
                    {
                        int index = entries[0].Index;
                        QuestManager.GossipFrame.SelectGossipOption(index);
                        await CommonCoroutines.SleepForRandomUiInteractionTime();

                        return(true);
                    }
                    else
                    {
                        GarrisonBase.Err("Could not find gossip index for barn currency {0}",
                                         CurrentBarnCurrceny[0].Item1.ToString());
                    }
                }

                _interactionAttempts++;
                WorkOrderObject.Interact();
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                return(true);
            }


            //Setup the NPC movement!
            if (_movement == null || _movement.CurrentMovementQueue.Count == 0)
            {
                _movement = new Movement(WorkOrderObject, WorkOrderObject.InteractRange - 0.50f, WorkOrderObject.Name);
            }

            await _movement.MoveTo();

            return(true);
        }
예제 #8
0
        private async Task <bool> CheckHearthStone()
        {
            if (await Common.CheckCommonCoroutines())
            {
                return(true);
            }

            if (FlightPathBehavior != null && !FlightPathBehavior.IsDone && await FlightPathBehavior.BehaviorRoutine())
            {
                return(true);
            }

            if (MovementBehavior != null && MovementBehavior.CurrentMovementQueue.Count > 0 && await MovementBehavior.MoveTo())
            {
                return(true);
            }


            if (!StyxWoW.Me.IsCasting)
            {
                var hearthstone = Player.Inventory.GarrisonHearthstone;
                if (hearthstone != null)
                {
                    bool oncooldown       = false;
                    var  cooldownTimeLeft = hearthstone.ref_WoWItem.CooldownTimeLeft;
                    if (cooldownTimeLeft.TotalSeconds > 0)
                    {
                        oncooldown = true;
                        GarrisonBase.Log("Garrison Hearthstone on cooldown! {0} seconds left",
                                         cooldownTimeLeft.TotalSeconds);

                        if (cooldownTimeLeft.TotalSeconds < 60)
                        {
                            await Coroutine.Sleep((int)cooldownTimeLeft.TotalMilliseconds);

                            return(true);
                        }
                    }



                    if (!oncooldown && hearthstone.ref_WoWItem.Usable)
                    {
                        if (StyxWoW.Me.IsMoving)
                        {
                            await CommonCoroutines.StopMoving();
                        }
                        hearthstone.Use();
                        await CommonCoroutines.SleepForRandomUiInteractionTime();

                        await Coroutine.Wait(10000, () => StyxWoW.Me.IsCasting);

                        await Coroutine.Yield();

                        if (!await Coroutine.Wait(25000, () => StyxWoW.Me.CurrentMap.IsGarrison))
                        {
                            GarrisonBase.Err("Used garrison hearthstone but not in garrison yet.");
                            return(false);
                        }

                        //If we are using taxi.. finish it!
                        if (BehaviorManager.CurrentBehavior.Type == BehaviorType.Taxi)
                        {
                            BehaviorManager.CurrentBehavior.IsDone = true;
                        }
                    }
                    else
                    {
                        if (Player.MapExpansionId != 5)
                        {
                            //Not in draenor!
                            GarrisonBase.Err("Garrison Hearthstone is on cooldown and not currently in draenor!");
                            return(false);
                        }

                        if (!attemptedFlightPath)
                        {
                            GarrisonBase.Debug("Attempting flight path to garrison");
                            FlightPathBehavior  = new BehaviorUseFlightPath(MovementCache.GarrisonEntrance);
                            attemptedFlightPath = true;
                        }
                        else
                        {
                            GarrisonBase.Debug("Attempting movement to garrison");
                            if (MovementBehavior == null)
                            {
                                MovementBehavior = new Movement(MovementCache.GarrisonEntrance, 50f, name: "GarrisonMovement");
                            }
                        }

                        return(true);
                    }
                }
            }

            await Coroutine.Sleep(StyxWoW.Random.Next(1232, 3323));

            return(true);
        }
        public override async Task <bool> BehaviorRoutine()
        {
            if (await base.BehaviorRoutine())
            {
                return(true);
            }
            if (IsDone)
            {
                return(false);
            }

            if (GossipHelper.IsOpen)
            {
                if (GossipHelper.GossipOptions.Count == 0)
                {
                    _failedToFindGossipEntries++;
                    if (_failedToFindGossipEntries > 3)
                    {
                        GarrisonBase.Err("Could not find any valid gossip entries!");
                        GossipFrame.Instance.Close();
                        IsDone = true;
                        return(false);
                    }

                    await Coroutine.Yield();

                    return(true);
                }

                GossipHelper.GossipOptionEntry gossipEntry = null;
                if (_gossipIndex > -1)
                {
                    gossipEntry = GossipHelper.GossipOptions[_gossipIndex];
                }
                else if (!string.IsNullOrEmpty(_gossipText))
                {
                    gossipEntry = GossipHelper.GossipOptions.FirstOrDefault(g => g.Text.ToLower().Contains(_gossipText));
                }

                if (gossipEntry == null)
                {
                    GarrisonBase.Err("Could not find any valid gossip entries index [{0}] text [{1}]", _gossipIndex, _gossipText);
                    GossipFrame.Instance.Close();
                    IsDone = true;
                    return(false);
                }

                GarrisonBase.Debug("Selecting Gossip Option {0}", gossipEntry.Index);
                var success = await CommonCoroutines.WaitForLuaEvent("GOSSIP_SHOW", 2500, null,
                                                                     () => GossipFrame.Instance.SelectGossipOption(gossipEntry.Index));


                GarrisonBase.Debug("Gossip Selection success = {0}", success);

                await CommonCoroutines.SleepForRandomUiInteractionTime();

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

                if (_oneTime)
                {
                    IsDone = true;
                }
                return(!_oneTime);
            }
            C_WoWObject validobj = NpcObject != null ? NpcObject:
                                   InteractionObject != null?InteractionObject:null;

            if (validobj == null || !validobj.IsValid)
            {
                GarrisonBase.Err("Could not find object {0} to interact with!", _npcId);
                IsDone = true;
                return(false);
            }
            if (_npcMovement == null)
            {
                _npcMovement = new Movement(validobj.Location, _interactDistance, name: "GossipInteract");
            }

            if (await _npcMovement.MoveTo(false))
            {
                return(true);
            }

            if (validobj.CheckDistance(_interactDistance))
            {
                if (StyxWoW.Me.IsMoving)
                {
                    await CommonCoroutines.StopMoving();
                }
                await CommonCoroutines.SleepForLagDuration();

                if (GossipHelper.IsOpen)
                {
                    //frame is displayed!
                    return(true);
                }

                validobj.Interact();
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                return(true);
            }

            return(true);
        }
예제 #10
0
        private async Task <bool> Interaction()
        {
            TreeRoot.StatusText = String.Format("Behavior {0} Interaction", Type.ToString());

            if (Character.Player.Inventory.TotalFreeSlots == 0)
            {
                GarrisonBase.Err("Bags are full!");
                IsDone = true;
                return(false);
            }

            RefreshInboxMailItemsCollection();

            if (InboxMailItems.Count > 0)
            {
                if (!LuaEvents.MailOpen)
                {
                    return(true);
                }

                if (LuaUI.InboxPreviousPage.IsEnabled())
                {
                    //We need to reset back to first page!
                    while (LuaUI.InboxPreviousPage.IsEnabled())
                    {
                        LuaUI.InboxPreviousPage.Click();
                        await CommonCoroutines.SleepForRandomUiInteractionTime();
                    }
                }

                int highestInboxPageIndex = 1;
                foreach (var item in InboxMailItems)
                {
                    if (item.InboxPageIndex > highestInboxPageIndex)
                    {
                        highestInboxPageIndex = item.InboxPageIndex;
                    }
                }

                if (highestInboxPageIndex > 1)
                {
                    //We want to loot mail that is not on the first page..
                    if (!LuaUI.InboxPreviousPage.IsEnabled())
                    {
                        for (int i = 1; i < highestInboxPageIndex; i++)
                        {//Click next page until we are at the correct page.
                            LuaUI.InboxNextPage.Click();
                            await CommonCoroutines.SleepForRandomUiInteractionTime();
                        }
                    }
                }

                //Now get all items on the same page.. order by highest index first (last item)
                var itemsToGet =
                    InboxMailItems.Where <InboxMailItem>(i => i.InboxPageIndex == highestInboxPageIndex)
                    .OrderByDescending(i => i.Index)
                    .ToList();

                foreach (var inboxMailItem in itemsToGet)
                {
                    //Open the mail item..
                    LuaCommands.ClickMailItemButton(inboxMailItem.RealIndex);
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    if (LuaCommands.OpenMailFrameIsVisible())
                    {
                        //Click the attachments..
                        for (int i = 0; i < inboxMailItem.ItemCount; i++)
                        {
                            LuaCommands.ClickOpenMailAttachmentButton(i + 1);
                            await CommonCoroutines.SleepForRandomUiInteractionTime();
                        }

                        //Close the open mail frame (if visible..)
                        if (LuaCommands.OpenMailFrameIsVisible())
                        {
                            LuaUI.InboxClose.Click();
                            await CommonCoroutines.SleepForRandomUiInteractionTime();
                        }
                    }

                    //LuaCommands.AutoLootMailItem(inboxMailItem.Index);
                    //await CommonCoroutines.SleepForRandomUiInteractionTime();
                }

                return(true);
            }

            return(false);
        }
예제 #11
0
        private async Task <bool> VerifyFlightNpc()
        {
            if (TaxiFlightHelper.IsOpen)
            {
                await CommonCoroutines.SleepForLagDuration();

                //TaxiFrame.Instance.Close();
                return(TaxiFlightHelper.TaxiNodes.Count == 0);
            }

            if (GossipHelper.IsOpen)
            {
                if (GossipHelper.GossipOptions.All(o => o.Type != GossipEntry.GossipEntryType.Taxi))
                {
                    //Could not find Taxi Option!
                    GarrisonBase.Debug("UseFlightPath gossip frame contains no taxi options!");
                    Common.CloseOpenFrames();
                    return(true);
                }
                var gossipOptionTaxi = GossipHelper.GossipOptions.FirstOrDefault(o => o.Type == GossipEntry.GossipEntryType.Taxi);

                QuestManager.GossipFrame.SelectGossipOption(gossipOptionTaxi.Index);
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                return(true);
            }


            if (_taxiNpc != null && _taxiNpc.IsValid)
            {//We got a valid object.. so lets move into interact range!
                if (_taxiNpc.WithinInteractRange)
                {
                    if (StyxWoW.Me.IsMoving)
                    {
                        await CommonCoroutines.StopMoving();
                    }
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    _taxiNpc.Interact();
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    await CommonCoroutines.SleepForLagDuration();

                    return(true);
                }

                if (_taxiMovement == null || _taxiMovement.CurrentMovementQueue.Count == 0)
                {
                    _taxiMovement = new Movement(_taxiNpc.Location, 5f - 0.25f, name: "TaxiNpcMovement");
                }

                await _taxiMovement.MoveTo();

                return(true);
            }


            if (_taxiMovement != null && _taxiMovement.CurrentMovementQueue.Count > 0)
            {
                await _taxiMovement.MoveTo();

                return(true);
            }

            if (FlightPaths.NearestFlightMerchant == null)
            {
                //Attempt to get location of nearest FP..
                if (_nearestflightPathInfo == null)
                {
                    _nearestflightPathInfo = TaxiFlightHelper.NearestFlightPath;
                    if (_nearestflightPathInfo == null)
                    {//Failed!
                        GarrisonBase.Err("UseFlightPath could not find valid flight path to move to!");
                        IsDone = true;
                        return(true);
                    }
                }


                GarrisonBase.Debug("Could not find Nearest Flight Merchant, but using nearest flight path location! {0} at {1}", _nearestflightPathInfo.Name, _nearestflightPathInfo.Location);
                _taxiMovement = new Movement(_nearestflightPathInfo.Location, 20f, name: "taxiNpcMovement");
                return(true);
            }

            //Found valid npc object..
            _taxiNpc      = FlightPaths.NearestFlightMerchant;
            _taxiMovement = new Movement(_taxiNpc.Location, 5f - 0.25f, name: "taxinpcMovement");


            return(true);
        }
예제 #12
0
        private async Task <bool> Interaction()
        {
            if (_questActionFinished || !QuestFrame.Instance.IsVisible)
            {
                return(false);
            }

            if (_completeQuest)
            {
                if (QuestHelper.QuestFrameType == QuestHelper.QuestFrameTypes.Complete)
                {
                    if (_rewardIndex > -1)
                    {
                        GarrisonBase.Log("Selecting Reward Index {0}", _rewardIndex);
                        QuestFrame.Instance.SelectQuestReward(_rewardIndex);
                        await CommonCoroutines.SleepForRandomUiInteractionTime();
                    }

                    if (BaseSettings.CurrentSettings.DEBUG_FAKEFINISHQUEST)
                    {
                        if (_specialMovement != null)
                        {
                            _specialMovement.UseDeqeuedPoints(true);
                        }
                        _questActionFinished = true;
                        return(false);
                    }

                    var successTurnedIn = await CommonCoroutines.WaitForLuaEvent(
                        "QUEST_TURNED_IN",
                        7500,
                        null,
                        QuestFrame.Instance.CompleteQuest);

                    if (successTurnedIn)
                    {
                        if (_specialMovement != null)
                        {
                            _specialMovement.UseDeqeuedPoints(true);
                        }
                        _questActionFinished = true;
                        return(false);
                    }

                    return(true);
                }

                if (QuestHelper.QuestFrameType == QuestHelper.QuestFrameTypes.Progress)
                {
                    QuestFrame.Instance.ClickContinue();
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    await Coroutine.Yield();

                    return(true);
                }

                GarrisonBase.Err("QuestPickup attempted to complete quest but was not on correct frame!");
                _questActionFinished = true;
                return(false);
            }

            var successAccepted = await CommonCoroutines.WaitForLuaEvent(
                "QUEST_ACCEPTED",
                7500,
                null,
                QuestFrame.Instance.AcceptQuest);

            //
            if (successAccepted)
            {
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                await CommonCoroutines.SleepForLagDuration();

                await Coroutine.Sleep(1250);

                _questActionFinished = true;
                return(false);
            }

            return(true);
        }
예제 #13
0
        private async Task <bool> Interaction()
        {
            /*
             * Check Cursor Spell ID
             * Click Interaction
             * Await for event CURRENT_SPELL_CAST_CHANGED
             *      -If event did not fire then check for confirmation popup
             *
             * Item Interaction
             *
             *
             */

            if (Player.CurrentPendingCursorSpellId == 160201)
            {
                //Item Interaction!
                GarrisonBase.Log("Disenchant Cursor!");

                if (Player.Inventory.DisenchantItems.Count > 0)
                {
                    var item = Player.Inventory.DisenchantItems[0];
                    GarrisonBase.Debug("Disenchanting Item {0} ({1}) Quality {2}", item.Name, item.Entry, item.Quality);
                    bool bagChanged = await CommonCoroutines.WaitForLuaEvent(
                        "BAG_UPDATE",
                        6200,
                        null,
                        item.Use);

                    PlayerInventory.ItemDisenchantingBlacklistedGuids.Add(item.Guid);

                    //Force update if bag didn't change.. (so we ignore this item now)
                    if (!bagChanged)
                    {
                        Player.Inventory.UpdateBagItems();
                    }

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

            bool cursorChanged = await CommonCoroutines.WaitForLuaEvent(
                "CURRENT_SPELL_CAST_CHANGED",
                StyxWoW.Random.Next(555, 2002),
                null,
                DisenchantingObject.Interact);


            await CommonCoroutines.SleepForRandomUiInteractionTime();

            await Coroutine.Yield();

            await Coroutine.Sleep(StyxWoW.Random.Next(1222, 2222));

            if (!cursorChanged)
            {
                if (LuaCommands.IsStaticPopupVisible())
                {
                    LuaCommands.ClickStaticPopupButton(1);
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    return(true);
                }
                GarrisonBase.Err("Could not find static popup confirmation frame!");
            }


            return(true);
        }
        public override async Task <bool> BehaviorRoutine()
        {
            if (await base.BehaviorRoutine())
            {
                return(true);
            }
            if (IsDone)
            {
                return(false);
            }

            if (InteractionObject == null)
            {
                if (await StartMovement.MoveTo())
                {
                    return(true);
                }
            }



            if (GossipHelper.IsOpen)
            {
                if (GossipHelper.GossipOptions.All(o => o.Type != GossipEntry.GossipEntryType.Vendor))
                {
                    //Could not find Vendor Option!
                    GarrisonBase.Err("Primal Trader behavior could not find vendoring gossip!");
                    return(false);
                }
                var gossipEntryVendor = GossipHelper.GossipOptions.FirstOrDefault(o => o.Type == GossipEntry.GossipEntryType.Vendor);

                QuestManager.GossipFrame.SelectGossipOption(gossipEntryVendor.Index);
                await CommonCoroutines.SleepForRandomUiInteractionTime();

                return(true);
            }

            if (MerchantHelper.IsOpen)
            {
                await Coroutine.Yield();

                if (ExchangeItemInfo.Cost <= TotalPrimalSpiritCount)
                {
                    if (StyxWoW.Me.IsMoving)
                    {
                        await CommonCoroutines.StopMoving();
                    }

                    await Coroutine.Sleep(StyxWoW.Random.Next(1005, 1666));

                    bool success = false;

                    await CommonCoroutines.WaitForLuaEvent("BAG_UPDATE",
                                                           StyxWoW.Random.Next(1255, 1777),
                                                           null,
                                                           () => success = MerchantHelper.BuyItem(ExchangeItemInfo.ItemId, 1, true));

                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    await Coroutine.Yield();

                    if (success)
                    {
                        return(true);
                    }
                }

                IsDone = true;
                return(false);
            }

            if (InteractionObject != null)
            {
                if (InteractionObject.WithinInteractRange)
                {
                    if (StyxWoW.Me.IsMoving)
                    {
                        await CommonCoroutines.StopMoving();
                    }
                    await CommonCoroutines.SleepForLagDuration();

                    InteractionObject.Interact();
                    await CommonCoroutines.SleepForRandomUiInteractionTime();

                    return(true);
                }

                if (_npcMovement == null)
                {
                    _npcMovement = new Movement(InteractionObject, InteractionObject.InteractRange - 0.25f);
                }

                await _npcMovement.MoveTo(false);

                return(true);
            }


            return(false);
        }