fBaseXtensions.XML.MoveItemTag.BackpackStashAttempt C# (CSharp) Method

BackpackStashAttempt() private method

private BackpackStashAttempt ( CacheACDItem item, int &XY ) : bool
item fBaseXtensions.Items.CacheACDItem
XY int
return bool
        private bool BackpackStashAttempt(CacheACDItem item, out int[] XY)
        {
            XY = new[] { -1, -1 };

            int iPlayerDynamicID = ZetaDia.Me.CommonData.DynamicId;
            int iOriginalGameBalanceId = item.ThisBalanceID;
            int iOriginalDynamicID = item.ThisDynamicID;
            int iOriginalStackQuantity = (int)item.ThisItemStackQuantity;
            string sOriginalItemName = item.ThisRealName;
            string sOriginalInternalName = item.ThisInternalName;
            PluginItemTypes OriginalPluginItemType = ItemFunc.DetermineItemType(item);
            PluginBaseItemTypes thisGilesBaseType = ItemFunc.DetermineBaseType(OriginalPluginItemType);
            bool bOriginalTwoSlot = item.IsTwoSlot;
            bool bOriginalIsStackable = item.IsStackableItem;
            int iAttempts;
            if (_dictItemStashAttempted.TryGetValue(iOriginalDynamicID, out iAttempts))
            {
                Logger.DBLog.InfoFormat("GSError: Detected a duplicate stash attempt, DB item mis-read error, now forcing this item as a 2-slot item");
                _dictItemStashAttempted[iOriginalDynamicID] = iAttempts + 1;
                bOriginalTwoSlot = true;
                bOriginalIsStackable = false;
                if (iAttempts > 6)
                {
                    Logger.DBLog.InfoFormat("GSError: Detected an item stash loop risk, now re-mapping stash treating everything as 2-slot and re-attempting");
                    // Array for what blocks are or are not blocked
                    for (int iRow = 0; iRow <= 5; iRow++)
                        for (int iColumn = 0; iColumn <= 9; iColumn++)
                            BackpackSlotBlocked[iColumn, iRow] = false;
                    // Block off the entire of any "protected stash pages"
                    foreach (InventorySquare iProtPage in CharacterSettings.Instance.ProtectedBagSlots)
                        BackpackSlotBlocked[iProtPage.Column, iProtPage.Row] = true;

                    // Map out all the items already in the stash
                    foreach (ACDItem tempitem in ZetaDia.Me.Inventory.Backpack)
                    {
                        if (tempitem.BaseAddress != IntPtr.Zero)
                        {
                            CacheACDItem tempCacheItem = new CacheACDItem(tempitem);

                            int inventoryRow = tempCacheItem.invRow;
                            int inventoryColumn = tempCacheItem.invCol;
                            // Mark this slot as not-free
                            BackpackSlotBlocked[inventoryColumn, inventoryRow] = true;
                            // Try and reliably find out if this is a two slot item or not
                            //BackpackSlotBlocked[inventoryColumn, inventoryRow + 1] = true;
                            if (inventoryRow != 5 && tempCacheItem.IsTwoSlot)
                            {
                                BackpackSlotBlocked[inventoryColumn, inventoryRow + 1] = true;
                            }
                        }
                    }
                }
                if (iAttempts > 15)
                {
                    Logger.DBLog.InfoFormat("***************************");
                    Logger.DBLog.InfoFormat("GSError: Emergency Stop: No matter what we tried, we couldn't prevent an infinite stash loop. Sorry. Now stopping the bot.");
                    BotMain.Stop();
                    return false;
                }
            }
            else
            {
                _dictItemStashAttempted.Add(iOriginalDynamicID, 1);
            }
            // Safety incase it's not actually in the backpack anymore
            /*if (item.InventorySlot != InventorySlot.PlayerBackpack)
            {
                 FunkyTownRunPlugin.DBLog.InfoFormat("GSError: Diablo 3 memory read error, or item became invalid [StashAttempt-4]", true);
                 return false;
            }*/
            int iLeftoverStackQuantity;

            int iPointX = -1;
            int iPointY = -1;
            // First check if we can top-up any already-existing stacks in the stash
            if (bOriginalIsStackable)
            {
                foreach (ACDItem tempitem in ZetaDia.Me.Inventory.Backpack)
                {
                    if (tempitem.BaseAddress == IntPtr.Zero)
                    {
                        Logger.DBLog.InfoFormat("GSError: Diablo 3 memory read error, or stash item became invalid [StashAttempt-5]");
                        return false;
                    }
                    // Check if we combine the stacks, we won't overfill them
                    if ((tempitem.GameBalanceId == iOriginalGameBalanceId) && (tempitem.ItemStackQuantity < tempitem.MaxStackCount))
                    {
                        iLeftoverStackQuantity = (int)((tempitem.ItemStackQuantity + iOriginalStackQuantity) - tempitem.MaxStackCount);
                        iPointX = tempitem.InventoryColumn;
                        iPointY = tempitem.InventoryRow;

                        // Will we have leftovers?
                        if (iLeftoverStackQuantity <= 0)
                            goto FoundStashLocation;
                        goto HandleStackMovement;
                    }
                }
            HandleStackMovement:
                if ((iPointX >= 0) && (iPointY >= 0))
                {
                    ZetaDia.Me.Inventory.MoveItem(iOriginalDynamicID, iPlayerDynamicID, InventorySlot.BackpackItems, iPointX, iPointY);
                }
            }
            iPointX = -1;
            iPointY = -1;
            // If it's a 2-square item, find a double-slot free
            if (bOriginalTwoSlot)
            {
                for (int iRow = 0; iRow <= 5; iRow++)
                {
                    bool bBottomPageRow = iRow == 5;
                    for (int iColumn = 0; iColumn <= 9; iColumn++)
                    {
                        // If nothing in the 1st row
                        if (!BackpackSlotBlocked[iColumn, iRow])
                        {
                            bool bNotEnoughSpace = false;
                            // Bottom row of a page = no room
                            if (bBottomPageRow)
                                bNotEnoughSpace = true;
                            // Already something in the stash in the 2nd row)
                            else if (BackpackSlotBlocked[iColumn, iRow + 1])
                                bNotEnoughSpace = true;
                            if (!bNotEnoughSpace)
                            {
                                iPointX = iColumn;
                                iPointY = iRow;
                                goto FoundStashLocation;
                            }
                        }
                    }
                }
            } // 2 slot item?
            // Now deal with any leftover 1-slot items
            else
            {
                // First we try and find somewhere "sensible"
                for (int iRow = 0; iRow <= 5; iRow++)
                {
                    bool bTopPageRow = iRow == 0;
                    bool bBottomPageRow = (iRow == 5);
                    for (int iColumn = 0; iColumn <= 9; iColumn++)
                    {
                        // Nothing in this slot
                        if (!BackpackSlotBlocked[iColumn, iRow])
                        {
                            bool bSensibleLocation = false;
                            if (!bTopPageRow && !bBottomPageRow)
                            {
                                // Something above and below this slot, or an odd-numbered row, so put something here
                                if ((BackpackSlotBlocked[iColumn, iRow + 1] && BackpackSlotBlocked[iColumn, iRow - 1]) ||
                                     (iRow) % 2 != 0)
                                    bSensibleLocation = true;
                            }
                            // Top page row with something directly underneath already blocking
                            else if (bTopPageRow)
                            {
                                if (BackpackSlotBlocked[iColumn, iRow + 1])
                                    bSensibleLocation = true;
                            }
                            // Bottom page row with something directly over already blocking
                            else
                            {
                                bSensibleLocation = true;
                            }
                            // Sensible location? Yay, stash it here!
                            if (bSensibleLocation)
                            {
                                iPointX = iColumn;
                                iPointY = iRow;
                                // Keep looking for places if it's a stackable to try to stick it at the end
                                if (!bOriginalIsStackable)
                                    goto FoundStashLocation;
                            }
                        }
                    }
                }
                // Didn't find a "sensible" place, let's try and force it in absolutely anywhere
                if ((iPointX < 0) || (iPointY < 0))
                {
                    for (int iRow = 0; iRow <= 5; iRow++)
                    {
                        for (int iColumn = 0; iColumn <= 9; iColumn++)
                        {
                            // Nothing in this spot, we're good!
                            if (!BackpackSlotBlocked[iColumn, iRow])
                            {
                                iPointX = iColumn;
                                iPointY = iRow;
                                // Keep looking for places if it's a stackable to try to stick it at the end
                                if (!bOriginalIsStackable)
                                    goto FoundStashLocation;
                            }
                        }
                    }
                }
            }
            FoundStashLocation:
            if ((iPointX < 0) || (iPointY < 0))
            {
                Logger.DBLog.DebugFormat("Fatal Error: No valid stash location found for '" + sOriginalItemName + "' [" + sOriginalInternalName + " - " + OriginalPluginItemType.ToString() + "]");
                Logger.DBLog.InfoFormat("***************************");
                Logger.DBLog.InfoFormat("GSError: Emergency Stop: You need to stash an item but no valid space could be found. Stash is full? Stopping the bot to prevent infinite town-run loop.");

                BotMain.Stop(true, "No Room To Stash!");
                //ZetaDia.Service.Party.LeaveGame();
                return false;
            }
            // We have two valid points that are empty, move the object here!
            BackpackSlotBlocked[iPointX, iPointY] = true;
            if (bOriginalTwoSlot)
                BackpackSlotBlocked[iPointX, iPointY + 1] = true;

            XY = new[] { iPointX, iPointY };

            return true;
        }