private static bool Player_CanBuyItem(Func <Player, int, int, bool> orig, Player self, int price, int customCurrency)
        {
            if (customCurrency != -1)
            {
                return(CustomCurrencyManager.BuyItem(self, price, customCurrency));
            }

            long inventoryCount = Utils.CoinsCount(out bool _, self.inventory, 58, 57, 56, 55, 54);
            long piggyCount     = Utils.CoinsCount(out bool _, self.bank.item);
            long safeCount      = Utils.CoinsCount(out bool _, self.bank2.item);
            long defendersCount = Utils.CoinsCount(out bool _, self.bank3.item);
            long walletCount    = self.inventory.OfType <Wallet>().Sum(wallet => wallet.Handler.Items.CountCoins());
            long combined       = Utils.CoinsCombineStacks(out bool _, inventoryCount, piggyCount, safeCount, defendersCount, walletCount);

            return(combined >= price);
        }
        private static bool Player_BuyItem(On.Terraria.Player.orig_BuyItem orig, Player self, int price, int customCurrency)
        {
            if (customCurrency != -1)
            {
                return(CustomCurrencyManager.BuyItem(self, price, customCurrency));
            }

            long inventoryCount = Utils.CoinsCount(out bool _, self.inventory, 58, 57, 56, 55, 54);
            long piggyCount     = Utils.CoinsCount(out bool _, self.bank.item);
            long safeCount      = Utils.CoinsCount(out bool _, self.bank2.item);
            long defendersCount = Utils.CoinsCount(out bool _, self.bank3.item);
            long walletCount    = self.inventory.OfType <Wallet>().Sum(wallet => wallet.Handler.Items.CountCoins());

            long combined = Utils.CoinsCombineStacks(out bool _, inventoryCount, piggyCount, safeCount, defendersCount, walletCount);

            if (combined < price)
            {
                return(false);
            }

            List <Item[]> list = new List <Item[]>();
            Dictionary <int, List <int> > ignoredSlots = new Dictionary <int, List <int> >();
            List <Point> coins          = new List <Point>();
            List <Point> emptyInventory = new List <Point>();
            List <Point> emptyPiggy     = new List <Point>();
            List <Point> emptySafe      = new List <Point>();
            List <Point> emptyDefenders = new List <Point>();
            List <Point> emptyWallet    = new List <Point>();

            list.Add(self.inventory);
            list.Add(self.bank.item);
            list.Add(self.bank2.item);
            list.Add(self.bank3.item);
            list.AddRange(self.inventory.OfType <Wallet>().Select(x => x.Handler.Items.ToArray()));
            for (int i = 0; i < list.Count; i++)
            {
                ignoredSlots[i] = new List <int>();
            }

            ignoredSlots[0] = new List <int>
            {
                58,
                57,
                56,
                55,
                54
            };
            for (int j = 0; j < list.Count; j++)
            {
                for (int k = 0; k < list[j].Length; k++)
                {
                    if (!ignoredSlots[j].Contains(k) && list[j][k].IsCoin())
                    {
                        coins.Add(new Point(j, k));
                    }
                }
            }

            int num6 = 0;

            for (int l = list[num6].Length - 1; l >= 0; l--)
            {
                if (!ignoredSlots[num6].Contains(l) && (list[num6][l].type == 0 || list[num6][l].stack == 0))
                {
                    emptyInventory.Add(new Point(num6, l));
                }
            }

            num6 = 1;
            for (int m = list[num6].Length - 1; m >= 0; m--)
            {
                if (!ignoredSlots[num6].Contains(m) && (list[num6][m].type == 0 || list[num6][m].stack == 0))
                {
                    emptyPiggy.Add(new Point(num6, m));
                }
            }

            num6 = 2;
            for (int n = list[num6].Length - 1; n >= 0; n--)
            {
                if (!ignoredSlots[num6].Contains(n) && (list[num6][n].type == 0 || list[num6][n].stack == 0))
                {
                    emptySafe.Add(new Point(num6, n));
                }
            }

            num6 = 3;
            for (int num7 = list[num6].Length - 1; num7 >= 0; num7--)
            {
                if (!ignoredSlots[num6].Contains(num7) && (list[num6][num7].type == 0 || list[num6][num7].stack == 0))
                {
                    emptyDefenders.Add(new Point(num6, num7));
                }
            }

            num6 = 4;
            for (int i = num6; i < list.Count - 4; i++)
            {
                for (int n = list[i].Length - 1; n >= 0; n--)
                {
                    if (!ignoredSlots[i].Contains(n) && (list[i][n].type == 0 || list[i][n].stack == 0))
                    {
                        emptyWallet.Add(new Point(i, n));
                    }
                }
            }

            return(!Player_TryPurchasing(price, list, coins, emptyInventory, emptyPiggy, emptySafe, emptyDefenders, emptyWallet));
        }