protected override void OnDone()
        {
            if (SelectYesno.IsOpen)
            {
                SelectYesno.ClickNo();
            }

            if (Request.IsOpen)
            {
                Request.Cancel();
            }

            if (Window <MasterPieceSupply> .IsOpen)
            {
                MasterPieceSupply.Close();
            }

            if (Window <ShopExchangeCurrency> .IsOpen)
            {
                ShopExchangeCurrency.Close();
            }

            if (SelectIconString.IsOpen)
            {
                SelectIconString.ClickSlot(uint.MaxValue);
            }
        }
        private async Task <bool> PurchaseItems()
        {
            if (ExProfileBehavior.Me.Location.Distance(shopExchangeCurrencyNpc.Location) > 4)
            {
                // too far away, should go back to MoveToNpc
                return(true);
            }

            StatusText = Localization.Localization.ExTurnInCollectable_Purchase;

            var itemsToPurchase      = ShopPurchases.Where(ShouldPurchaseItem).ToArray();
            var npc                  = GameObjectManager.GetObjectByNPCId(shopExchangeCurrencyNpc.NpcId);
            var shopType             = ShopType.RedGatherer50;
            var shopExchangeCurrency = new ShopExchangeCurrency();

            foreach (var purchaseItem in itemsToPurchase)
            {
                var purchaseItemInfo = Data.ShopItemMap[purchaseItem.ShopItem];
                var purchaseItemData = purchaseItemInfo.ItemData;

                if (shopType != purchaseItemInfo.ShopType && shopExchangeCurrency.IsValid)
                {
                    await shopExchangeCurrency.CloseInstanceGently();
                }

                shopType = purchaseItemInfo.ShopType;

                // target
                var ticks = 0;
                while (Core.Target == null && !shopExchangeCurrency.IsValid && ticks++ < 10 && Behaviors.ShouldContinue)
                {
                    npc.Target();
                    await Coroutine.Wait(1000, () => Core.Target != null);
                }

                // check for timeout
                if (ticks > 10)
                {
                    Logger.Error(Localization.Localization.ExTurnInCollectable_TargetingTimeout);
                    isDone = true;
                    return(true);
                }

                // interact
                ticks = 0;
                while (!SelectIconString.IsOpen && !shopExchangeCurrency.IsValid && ticks++ < 10 && Behaviors.ShouldContinue)
                {
                    npc.Interact();
                    await Coroutine.Wait(1000, () => SelectIconString.IsOpen);
                }

                // check for timeout
                if (ticks > 10)
                {
                    Logger.Error(Localization.Localization.ExTurnInCollectable_InteractingTimeout);
                    isDone = true;
                    return(true);
                }

#if RB_CN
                if ((Location == Locations.MorDhona) &&
                    (purchaseItemInfo.ShopType == ShopType.YellowCrafterItems || purchaseItemInfo.ShopType == ShopType.YellowGathererItems))
                {
                    Logger.Warn(Localization.Localization.ExTurnInCollectable_FailedPurchaseMorDhona, purchaseItemData.EnglishName);
                    continue;
                }

                ticks = 0;
                while (SelectIconString.IsOpen && ticks++ < 5 && Behaviors.ShouldContinue)
                {
                    if ((Location == Locations.MorDhona) && (purchaseItemInfo.ShopType == ShopType.RedGatherer50 || purchaseItemInfo.ShopType == ShopType.RedGatherer58))
                    {
                        SelectIconString.ClickSlot((uint)purchaseItemInfo.ShopType - 5);
                    }
                    else
                    {
                        SelectIconString.ClickSlot((uint)purchaseItemInfo.ShopType);
                    }

                    await shopExchangeCurrency.Refresh(5000);
                }
#else
                if ((Location == Locations.MorDhona) &&
                    (purchaseItemInfo.ShopType == ShopType.YellowCrafterItems || purchaseItemInfo.ShopType == ShopType.YellowGathererItems))
                {
                    Logger.Warn(Localization.Localization.ExTurnInCollectable_FailedPurchaseMorDhona, purchaseItemData.EnglishName);
                    continue;
                }

                ticks = 0;
                while (SelectIconString.IsOpen && ticks++ < 5 && Behaviors.ShouldContinue)
                {
                    if ((Location == Locations.MorDhona) && (purchaseItemInfo.ShopType == ShopType.RedGatherer50 || purchaseItemInfo.ShopType == ShopType.RedGatherer58))
                    {
                        SelectIconString.ClickSlot((uint)purchaseItemInfo.ShopType - 5);
                    }
                    else
                    {
                        SelectIconString.ClickSlot((uint)purchaseItemInfo.ShopType);
                    }

                    await shopExchangeCurrency.Refresh(5000);
                }
#endif

                if (ticks > 5 || !shopExchangeCurrency.IsValid)
                {
                    Logger.Error(Localization.Localization.ExTurnInCollectable_InteractingTimeout);
                    if (SelectIconString.IsOpen)
                    {
                        SelectIconString.ClickSlot(uint.MaxValue);
                    }

                    isDone = true;
                    return(true);
                }

                await Coroutine.Sleep(600);

                int scripsLeft;
                while (purchaseItemData.ItemCount() < purchaseItem.MaxCount && (scripsLeft = Memory.Scrips.GetRemainingScripsByShopType(purchaseItemInfo.ShopType)) >= purchaseItemInfo.Cost && Behaviors.ShouldContinue)
                {
                    var qtyLeftToBuy = purchaseItem.MaxCount - (int)purchaseItemData.ItemCount();
                    var qtyBuyable   = scripsLeft / purchaseItemInfo.Cost;
                    var qtyToBuy     = Math.Min(99, Math.Min(qtyLeftToBuy, qtyBuyable));

                    if (!await shopExchangeCurrency.PurchaseItem(purchaseItemInfo.Index, (uint)qtyToBuy, 20))
                    {
                        Logger.Error(Localization.Localization.ExTurnInCollectable_PurchaseTimeout, purchaseItemData.EnglishName);
                        await shopExchangeCurrency.CloseInstance();

                        isDone = true;
                        return(true);
                    }

                    var left = scripsLeft;
                    await
                    Coroutine.Wait(
                        5000,
                        () => (scripsLeft = Memory.Scrips.GetRemainingScripsByShopType(purchaseItemInfo.ShopType)) != left);

                    Logger.Info(
                        Localization.Localization.ExTurnInCollectable_Purchased,
                        purchaseItemData.EnglishName,
                        purchaseItemInfo.Cost * qtyToBuy,
                        purchaseItemInfo.ShopType,
                        WorldManager.EorzaTime,
                        scripsLeft,
                        qtyToBuy);

                    await Coroutine.Yield();
                }

                await Coroutine.Sleep(1000);
            }

            Logger.Info(Localization.Localization.ExTurnInCollectable_PurchaseComplete);
            SelectYesno.ClickNo();
            if (SelectIconString.IsOpen)
            {
                SelectIconString.ClickSlot(uint.MaxValue);
            }

            await shopExchangeCurrency.CloseInstance();

            isDone = true;
            return(true);
        }
        private async Task <bool> ResolveItem()
        {
            if (item != null)
            {
                return(false);
            }

            var slots =
                InventoryManager.FilledInventoryAndArmory.Where(
                    i => !Blacklist.Contains((uint)i.Pointer.ToInt64(), BlacklistFlags.Loot)).ToArray();

            var blackListDictionnary = new Dictionary <string, uint> {
                { "Fire Moraine", 5214 },
                { "Lightning Moraine", 5218 },
                { "Radiant Fire Moraine", 5220 },
                { "Radiant Lightning Moraine", 5224 },
                { "Bright Fire Rock", 12966 },
                { "Bright Lightning Rock", 12967 },
                { "Granular Clay", 12968 },
                { "Peat Moss", 12969 },
                { "Black Soil", 12970 },
                { "Highland Oregano", 12971 },
                { "Furymint", 12972 },
                { "Clary Sage", 12973 },
                { "Lover's Laurel", 15948 },
                { "Radiant Astral Moraine", 15949 },
                { "Near Eastern Antique", 17549 },
                { "Coerthan Souvenir", 17550 },
                { "Maelstrom Materiel ", 17551 },
                { "Heartfelt Gift", 17552 },
                { "Orphanage Donation", 17553 },
                { "Dated Radz-at-Han Coin", 17557 },
                { "Ice Stalagmite", 17558 },
                { "Duskfall Moss", 17559 },
                { "Glass Eye", 17560 },
                { "Rainbow Pigment", 17561 },
                { "Thavnairian Leaf", 17562 },
                { "Ghost Faerie", 17563 },
                { "Red Sky Coral", 17564 },
                { "Lovers' Clam", 17565 },
                { "River Shrimp", 17566 },
                { "Windtea Leaves", 19916 },
                { "Torreya Branch", 19937 },
                { "Schorl", 20009 },
                { "Perlite", 20010 },
                { "Almandine", 20011 },
                { "Doman Yellow", 20012 },
                { "Gyr Abanian Souvenir", 20775 },
                { "Far Eastern Antique", 20776 },
                { "Gold Saucer Consolation Prize", 20777 },
                { "M Tribe Sundries", 20778 },
                { "Resistance Materiel", 20779 },
                { "Starcrack", 20780 },
                { "Shishu Koban", 20781 },
                { "Cotter Dynasty Relic", 20782 },
                { "Peaks Pigment", 20783 },
                { "Yellow Kudzu Root", 20784 },
                { "Gyr Abanian Chub", 20785 },
                { "Coral Horse", 20786 },
                { "Maiden's Heart", 20787 },
                { "Velodyna Salmon", 20788 },
                { "Purple Buckler", 20789 },
                { "Gyr Abanian Remedies", 23143 },
                { "Anti-shark Harpoon", 23144 },
                { "Coerthan Cold-weather Gear", 23145 },
                { "Sui-no-Sato Special", 23146 },
                { "Cloud Pearl", 23147 },
                { "Yanxian Soil", 23220 },
                { "Yanxian Verbena", 23221 }
            };

            if (Collectables == null)
            {
                item = slots.FirstOrDefault(i => i.Collectability > 0 && !blackListDictionnary.ContainsValue(i.RawItemId));
            }
            else
            {
                foreach (var collectable in Collectables)
                {
                    var bagslots = slots.Where(i =>
                                               i.Collectability >= collectable.Value && i.Collectability <= collectable.MaxValueForTurnIn).ToArray();

                    if (collectable.Id > 0)
                    {
                        item =
                            bagslots.FirstOrDefault(i => i.RawItemId == collectable.Id);
                    }

                    item = item ??
                           bagslots.FirstOrDefault(
                        i => string.Equals(collectable.LocalName, i.Name, StringComparison.InvariantCultureIgnoreCase)) ??
                           bagslots.FirstOrDefault(
                        i => string.Equals(collectable.Name, i.EnglishName, StringComparison.InvariantCultureIgnoreCase));

                    if (item != null)
                    {
                        break;
                    }
                }
            }

            if (item != null && item.Item != null)
            {
                Logger.Verbose(Localization.Localization.ExTurnInCollectable_AttemptingTurnin, item.EnglishName, item.Pointer.ToString("X8"));
                return(false);
            }

            if ((turnedItemsIn || ForcePurchase) && !await HandleSkipPurchase())
            {
                return(false);
            }

            if (SelectYesno.IsOpen)
            {
                SelectYesno.ClickNo();
            }

            if (Request.IsOpen)
            {
                Request.Cancel();
            }

            var masterpieceSupply = new MasterPieceSupply();

            if (masterpieceSupply.IsValid)
            {
                await masterpieceSupply.CloseInstanceGently();
            }

            var shopExchangeCurrency = new ShopExchangeCurrency();

            if (shopExchangeCurrency.IsValid)
            {
                await shopExchangeCurrency.CloseInstanceGently();
            }

            if (SelectIconString.IsOpen)
            {
                SelectIconString.ClickSlot(uint.MaxValue);
            }

            return(isDone = true);
        }
		private async Task<bool> ResolveItem()
		{
			if (item != null)
			{
				return false;
			}

			var slots =
				InventoryManager.FilledInventoryAndArmory.Where(
					i => !Blacklist.Contains((uint) i.Pointer.ToInt32(), BlacklistFlags.Loot)).ToArray();

			if (Collectables == null)
			{
				item = slots.FirstOrDefault(i => i.Collectability > 0);
			}
			else
			{
				foreach (var collectable in Collectables)
				{
					var bagslots = slots.Where(i =>
						i.Collectability >= collectable.Value && i.Collectability <= collectable.MaxValueForTurnIn).ToArray();

					if (collectable.Id > 0)
					{
						item =
							bagslots.FirstOrDefault(i => i.RawItemId == collectable.Id);
					}

					item = item ??
						bagslots.FirstOrDefault(
							i => string.Equals(collectable.LocalName, i.Name, StringComparison.InvariantCultureIgnoreCase)) ??
						bagslots.FirstOrDefault(
							i => string.Equals(collectable.Name, i.EnglishName, StringComparison.InvariantCultureIgnoreCase));

					if (item != null)
					{
						break;
					}
				}
			}

			if (item != null && item.Item != null)
			{
				Logger.Verbose(Localization.Localization.ExTurnInCollectable_AttemptingTurnin, item.EnglishName, item.Pointer.ToString("X8"));
				return false;
			}

			if ((turnedItemsIn || ForcePurchase) && !await HandleSkipPurchase())
			{
				return false;
			}

			if (SelectYesno.IsOpen)
			{
				SelectYesno.ClickNo();
			}

			if (Request.IsOpen)
			{
				Request.Cancel();
			}

			var masterpieceSupply = new MasterPieceSupply();
			if (masterpieceSupply.IsValid)
			{
				await masterpieceSupply.CloseInstanceGently();
			}

			var shopExchangeCurrency = new ShopExchangeCurrency();
			if (shopExchangeCurrency.IsValid)
			{
				await shopExchangeCurrency.CloseInstanceGently();
			}

			if (SelectIconString.IsOpen)
			{
				SelectIconString.ClickSlot(uint.MaxValue);
			}

			return isDone = true;
		}
		private async Task<bool> PurchaseItems()
		{
			if (ExProfileBehavior.Me.Location.Distance(shopExchangeCurrencyNpc.Location) > 4)
			{
				// too far away, should go back to MoveToNpc
				return true;
			}

			StatusText = Localization.Localization.ExTurnInCollectable_Purchase;

			var itemsToPurchase = ShopPurchases.Where(ShouldPurchaseItem).ToArray();
			var npc = GameObjectManager.GetObjectByNPCId(shopExchangeCurrencyNpc.NpcId);
			var shopType = ShopType.BlueGatherer;
			var shopExchangeCurrency = new ShopExchangeCurrency();
			foreach (var purchaseItem in itemsToPurchase)
			{
				var purchaseItemInfo = Data.ShopItemMap[purchaseItem.ShopItem];
				var purchaseItemData = purchaseItemInfo.ItemData;

				if (shopType != purchaseItemInfo.ShopType && shopExchangeCurrency.IsValid)
				{
					await shopExchangeCurrency.CloseInstanceGently();
				}

				shopType = purchaseItemInfo.ShopType;

				// target
				var ticks = 0;
				while (Core.Target == null && !shopExchangeCurrency.IsValid && ticks++ < 10 && Behaviors.ShouldContinue)
				{
					npc.Target();
					await Coroutine.Wait(1000, () => Core.Target != null);
				}

				// check for timeout
				if (ticks > 10)
				{
					Logger.Error(Localization.Localization.ExTurnInCollectable_TargetingTimeout);
					isDone = true;
					return true;
				}

				// interact
				ticks = 0;
				while (!SelectIconString.IsOpen && !shopExchangeCurrency.IsValid && ticks++ < 10 && Behaviors.ShouldContinue)
				{
					npc.Interact();
					await Coroutine.Wait(1000, () => SelectIconString.IsOpen);
				}

				// check for timeout
				if (ticks > 10)
				{
					Logger.Error(Localization.Localization.ExTurnInCollectable_InteractingTimeout);
					isDone = true;
					return true;
				}

				if (Location == Locations.MorDhona
				    && (purchaseItemInfo.ShopType == ShopType.RedCrafter || purchaseItemInfo.ShopType == ShopType.RedGatherer))
				{
					Logger.Warn(Localization.Localization.ExTurnInCollectable_FailedPurchaseMorDhona, purchaseItemData.EnglishName);
					continue;
				}

				ticks = 0;
				while (SelectIconString.IsOpen && ticks++ < 5 && Behaviors.ShouldContinue)
				{
					if (Location == Locations.MorDhona)
					{
						// Blue crafter = 0, Blue gather = 1
						SelectIconString.ClickSlot((uint) purchaseItemInfo.ShopType/2);
					}
					else
					{
						SelectIconString.ClickSlot((uint) purchaseItemInfo.ShopType);
					}

					await shopExchangeCurrency.Refresh(5000);
				}

				if (ticks > 5 || !shopExchangeCurrency.IsValid)
				{
					Logger.Error(Localization.Localization.ExTurnInCollectable_InteractingTimeout);
					if (SelectIconString.IsOpen)
					{
						SelectIconString.ClickSlot(uint.MaxValue);
					}

					isDone = true;
					return true;
				}

				await Coroutine.Sleep(600);
				int scripsLeft;
				while (purchaseItemData.ItemCount() < purchaseItem.MaxCount
				       &&
				       (scripsLeft = Memory.Scrips.GetRemainingScripsByShopType(purchaseItemInfo.ShopType)) >= purchaseItemInfo.Cost
				       && Behaviors.ShouldContinue)
				{
					if (!await shopExchangeCurrency.PurchaseItem(purchaseItemInfo.Index, 20))
					{
						Logger.Error(Localization.Localization.ExTurnInCollectable_PurchaseTimeout, purchaseItemData.EnglishName);
						await shopExchangeCurrency.CloseInstance();
						isDone = true;
						return true;
					}

					// wait until scrips changed
					var left = scripsLeft;
					await
						Coroutine.Wait(
							5000,
							() => (scripsLeft = Memory.Scrips.GetRemainingScripsByShopType(purchaseItemInfo.ShopType)) != left);

					Logger.Info(
                        Localization.Localization.ExTurnInCollectable_Purchased,
						purchaseItemData.EnglishName,
						purchaseItemInfo.Cost,
						purchaseItemInfo.ShopType,
						WorldManager.EorzaTime,
						scripsLeft);

					await Coroutine.Yield();
				}

				await Coroutine.Sleep(1000);
			}

			Logger.Info(Localization.Localization.ExTurnInCollectable_PurchaseComplete);
			SelectYesno.ClickNo();
			if (SelectIconString.IsOpen)
			{
				SelectIconString.ClickSlot(uint.MaxValue);
			}

			await shopExchangeCurrency.CloseInstance();
			isDone = true;
			return true;
		}
Example #6
0
        private async Task <bool> ResolveItem()
        {
            if (item != null)
            {
                return(false);
            }

            var slots =
                InventoryManager.FilledInventoryAndArmory.Where(
                    i => !Blacklist.Contains((uint)i.Pointer.ToInt64(), BlacklistFlags.Loot)).ToArray();

            Dictionary <string, uint> BlackListDictionnary = new Dictionary <string, uint> {
                { "Fire Moraine", 5214 },
                { "Lightning Moraine", 5218 },
                { "Radiant Fire Moraine", 5220 },
                { "Radiant Lightning Moraine", 5224 },
                { "Bright Fire Rock", 12966 },
                { "Bright Lightning Rock", 12967 },
                { "Granular Clay", 12968 },
                { "Peat Moss", 12969 },
                { "Black Soil", 12970 },
                { "Highland Oregano", 12971 },
                { "Furymint", 12972 },
                { "Clary Sage", 12973 },
                { "Lover's Laurel", 15948 },
                { "Radiant Astral Moraine", 15949 },
                { "Dated Radz-at-Han Coin", 17557 },
                { "Ice Stalagmite", 17558 },
                { "Duskfall Moss", 17559 },
                { "Glass Eye", 17560 },
                { "Rainbow Pigment", 17561 },
                { "Thavnairian Leaf", 17562 },
                { "Ghost Faerie", 17563 },
                { "Red Sky Coral", 17564 },
                { "Lovers' Clam", 17565 },
                { "River Shrimp", 17566 },
                { "Windtea Leaves", 19916 },
                { "Torreya Branch", 19937 },
                { "Schorl", 20009 },
                { "Perlite", 20010 },
                { "Almandine", 20011 },
                { "Doman Yellow", 20012 }
            };

            if (Collectables == null)
            {
                item = slots.FirstOrDefault(i => i.Collectability > 0 && !BlackListDictionnary.ContainsValue(i.RawItemId));
            }
            else
            {
                foreach (var collectable in Collectables)
                {
                    var bagslots = slots.Where(i =>
                                               i.Collectability >= collectable.Value && i.Collectability <= collectable.MaxValueForTurnIn).ToArray();

                    if (collectable.Id > 0)
                    {
                        item =
                            bagslots.FirstOrDefault(i => i.RawItemId == collectable.Id);
                    }

                    item = item ??
                           bagslots.FirstOrDefault(
                        i => string.Equals(collectable.LocalName, i.Name, StringComparison.InvariantCultureIgnoreCase)) ??
                           bagslots.FirstOrDefault(
                        i => string.Equals(collectable.Name, i.EnglishName, StringComparison.InvariantCultureIgnoreCase));

                    if (item != null)
                    {
                        break;
                    }
                }
            }

            if (item != null && item.Item != null)
            {
                Logger.Verbose(Localization.Localization.ExTurnInCollectable_AttemptingTurnin, item.EnglishName, item.Pointer.ToString("X8"));
                return(false);
            }

            if ((turnedItemsIn || ForcePurchase) && !await HandleSkipPurchase())
            {
                return(false);
            }

            if (SelectYesno.IsOpen)
            {
                SelectYesno.ClickNo();
            }

            if (Request.IsOpen)
            {
                Request.Cancel();
            }

            var masterpieceSupply = new MasterPieceSupply();

            if (masterpieceSupply.IsValid)
            {
                await masterpieceSupply.CloseInstanceGently();
            }

            var shopExchangeCurrency = new ShopExchangeCurrency();

            if (shopExchangeCurrency.IsValid)
            {
                await shopExchangeCurrency.CloseInstanceGently();
            }

            if (SelectIconString.IsOpen)
            {
                SelectIconString.ClickSlot(uint.MaxValue);
            }

            return(isDone = true);
        }
        private async Task <bool> PurchaseItems()
        {
            if (ExProfileBehavior.Me.Location.Distance(shopExchangeCurrencyNpc.Location) > 4)
            {
                // too far away, should go back to MoveToNpc
                return(true);
            }

            StatusText = Localization.Localization.ExTurnInCollectable_Purchase;

            var itemsToPurchase      = ShopPurchases.Where(ShouldPurchaseItem).ToArray();
            var npc                  = GameObjectManager.GetObjectByNPCId(shopExchangeCurrencyNpc.NpcId);
            var shopType             = ShopType.Yellow50;
            var shopExchangeCurrency = new ShopExchangeCurrency();

            foreach (var purchaseItem in itemsToPurchase)
            {
                var purchaseItemInfo = Data.ShopItemMap[purchaseItem.ShopItem];
                var purchaseItemData = purchaseItemInfo.ItemData;

                if (shopType != purchaseItemInfo.ShopType && shopExchangeCurrency.IsValid)
                {
                    await shopExchangeCurrency.CloseInstanceGently();
                }

                shopType = purchaseItemInfo.ShopType;

                // target
                var ticks = 0;
                while (Core.Target == null && !shopExchangeCurrency.IsValid && ticks++ < 10 && Behaviors.ShouldContinue)
                {
                    npc.Target();
                    await Coroutine.Wait(1000, () => Core.Target != null);
                }

                // check for timeout
                if (ticks > 10)
                {
                    Logger.Error(Localization.Localization.ExTurnInCollectable_TargetingTimeout);
                    isDone = true;
                    return(true);
                }

                // interact
                ticks = 0;
                while (!SelectIconString.IsOpen && !shopExchangeCurrency.IsValid && ticks++ < 10 && Behaviors.ShouldContinue)
                {
                    npc.Interact();
                    await Coroutine.Wait(1000, () => SelectIconString.IsOpen);
                }

                // check for timeout
                if (ticks > 10)
                {
                    Logger.Error(Localization.Localization.ExTurnInCollectable_InteractingTimeout);
                    isDone = true;
                    return(true);
                }

                if (purchaseItemInfo.Index == (int)ShopItem.OnHighOrchestrionRoll && Location != Locations.RhalgrsReach ||
                    purchaseItemInfo.Index >= (int)ShopItem.MoonbeamSilk && purchaseItemInfo.Index <= (int)ShopItem.RaziqcoatHq && Location != Locations.RhalgrsReach ||
                    purchaseItemInfo.Index == (int)ShopItem.GardenGravel && Location != Locations.RhalgrsReach ||
                    purchaseItemInfo.Index == (int)ShopItem.SongsofSaltandSufferingOrchestrionRoll && Location != Locations.RhalgrsReach)
                {
                    Logger.Warn(Localization.Localization.ExTurnInCollectable_FailedPurchaseGorRhalgrsReach, purchaseItemData.EnglishName);
                    continue;
                }

                ticks = 0;
                while (SelectIconString.IsOpen && ticks++ < 5 && Behaviors.ShouldContinue)
                {
                    SelectIconString.ClickSlot((uint)purchaseItemInfo.ShopJob);
                    await Coroutine.Wait(1000, () => SelectString.IsOpen);

                    SelectString.ClickSlot((purchaseItemInfo.ShopJob == ShopJob.Gatherer && purchaseItemInfo.ShopType > ShopType.Yellow61) ? (uint)purchaseItemInfo.ShopType - 1 : (uint)purchaseItemInfo.ShopType);

                    await shopExchangeCurrency.Refresh(5000);
                }

                if (ticks > 5 || !shopExchangeCurrency.IsValid)
                {
                    Logger.Error(Localization.Localization.ExTurnInCollectable_InteractingTimeout);
                    if (SelectIconString.IsOpen)
                    {
                        SelectIconString.ClickSlot(uint.MaxValue);
                    }

                    isDone = true;
                    return(true);
                }

                await Coroutine.Sleep(600);

                int scripsLeft;
                while (purchaseItemData.ItemCount() < purchaseItem.MaxCount && (scripsLeft = Memory.Scrips.GetRemainingScripsByShopType(purchaseItemInfo.ShopJob, purchaseItemInfo.ShopType)
                                                                                ) >= purchaseItemInfo.Cost &&
                       Behaviors.ShouldContinue)
                {
                    var qtyLeftToBuy = purchaseItem.MaxCount - (int)purchaseItemData.ItemCount();
                    var qtyBuyable   = scripsLeft / purchaseItemInfo.Cost;
                    var qtyToBuy     = Math.Min(99, Math.Min(qtyLeftToBuy, qtyBuyable));

                    var indexPurchaseItem = (Location != Locations.Idyllshire && Location != Locations.RhalgrsReach && purchaseItemInfo.ShopJob == ShopJob.Crafter && purchaseItemInfo.ShopType == ShopType.Yellow58 &&
                                             purchaseItemInfo.Index >= (int)ShopItem.MoonbeamSilk - 200)
                            ? purchaseItemInfo.Index - 12
                            : purchaseItemInfo.Index;

                    if (!await shopExchangeCurrency.PurchaseItem(indexPurchaseItem, (uint)qtyToBuy, 20))
                    {
                        Logger.Error(Localization.Localization.ExTurnInCollectable_PurchaseTimeout, purchaseItemData.EnglishName);
                        await shopExchangeCurrency.CloseInstance();

                        isDone = true;
                        return(true);
                    }

                    var left = scripsLeft;
                    await
                    Coroutine.Wait(
                        5000,
                        () => (scripsLeft = Memory.Scrips.GetRemainingScripsByShopType(purchaseItemInfo.ShopJob, purchaseItemInfo.ShopType)) != left);

                    Logger.Info(
                        Localization.Localization.ExTurnInCollectable_Purchased,
                        purchaseItemData.EnglishName,
                        purchaseItemInfo.Cost * qtyToBuy,
                        purchaseItemInfo.ShopType,
                        WorldManager.EorzaTime,
                        scripsLeft,
                        qtyToBuy);

                    await Coroutine.Yield();
                }

                await Coroutine.Sleep(1000);
            }

            Logger.Info(Localization.Localization.ExTurnInCollectable_PurchaseComplete);
            SelectYesno.ClickNo();
            if (SelectIconString.IsOpen)
            {
                SelectIconString.ClickSlot(uint.MaxValue);
            }

            await shopExchangeCurrency.CloseInstance();

            isDone = true;
            return(true);
        }
        private async Task <bool> ResolveItem()
        {
            if (item != null)
            {
                return(false);
            }

            var slots =
                InventoryManager.FilledInventoryAndArmory.Where(
                    i => !Blacklist.Contains((uint)i.Pointer.ToInt64(), BlacklistFlags.Loot)).ToArray();

            if (Collectables == null)
            {
                item = slots.FirstOrDefault(i => i.Collectability > 0);
            }
            else
            {
                foreach (var collectable in Collectables)
                {
                    var bagslots = slots.Where(i =>
                                               i.Collectability >= collectable.Value && i.Collectability <= collectable.MaxValueForTurnIn).ToArray();

                    if (collectable.Id > 0)
                    {
                        item =
                            bagslots.FirstOrDefault(i => i.RawItemId == collectable.Id);
                    }

                    item = item ??
                           bagslots.FirstOrDefault(
                        i => string.Equals(collectable.LocalName, i.Name, StringComparison.InvariantCultureIgnoreCase)) ??
                           bagslots.FirstOrDefault(
                        i => string.Equals(collectable.Name, i.EnglishName, StringComparison.InvariantCultureIgnoreCase));

                    if (item != null)
                    {
                        break;
                    }
                }
            }

            if (item != null && item.Item != null)
            {
                Logger.Verbose(Localization.Localization.ExTurnInCollectable_AttemptingTurnin, item.EnglishName, item.Pointer.ToString("X8"));
                return(false);
            }

            if ((turnedItemsIn || ForcePurchase) && !await HandleSkipPurchase())
            {
                return(false);
            }

            if (SelectYesno.IsOpen)
            {
                SelectYesno.ClickNo();
            }

            if (Request.IsOpen)
            {
                Request.Cancel();
            }

            var masterpieceSupply = new MasterPieceSupply();

            if (masterpieceSupply.IsValid)
            {
                await masterpieceSupply.CloseInstanceGently();
            }

            var shopExchangeCurrency = new ShopExchangeCurrency();

            if (shopExchangeCurrency.IsValid)
            {
                await shopExchangeCurrency.CloseInstanceGently();
            }

            if (SelectIconString.IsOpen)
            {
                SelectIconString.ClickSlot(uint.MaxValue);
            }

            return(isDone = true);
        }