コード例 #1
0
        internal static RunStatus StashUpdate(object ret)
        {
            if (FunkyGame.GameIsInvalid)
            {
                ActionsChecked = false;
                FunkyTownRunPlugin.DBLog.InfoFormat("[Funky] Town Run Behavior Failed! (Not In Game/Invalid Actor/misc)");
                return(RunStatus.Failure);
            }

            if (!bUpdatedStashMap)
            {
                // Array for what blocks are or are not blocked
                for (int iRow = 0; iRow <= 49; iRow++)
                {
                    for (int iColumn = 0; iColumn <= 6; iColumn++)
                    {
                        GilesStashSlotBlocked[iColumn, iRow] = false;
                    }
                }
                // Block off the entire of any "protected stash pages"
                foreach (int iProtPage in CharacterSettings.Instance.ProtectedStashPages)
                {
                    for (int iProtRow = 0; iProtRow <= 9; iProtRow++)
                    {
                        for (int iProtColumn = 0; iProtColumn <= 6; iProtColumn++)
                        {
                            GilesStashSlotBlocked[iProtColumn, iProtRow + (iProtPage * 10)] = true;
                        }
                    }
                }
                // Remove rows we don't have
                for (int iRow = (ZetaDia.Me.NumSharedStashSlots / 7); iRow <= 49; iRow++)
                {
                    for (int iColumn = 0; iColumn <= 6; iColumn++)
                    {
                        GilesStashSlotBlocked[iColumn, iRow] = true;
                    }
                }


                // Map out all the items already in the stash
                foreach (ACDItem tempitem in ZetaDia.Me.Inventory.StashItems)
                {
                    if (tempitem.BaseAddress != IntPtr.Zero)
                    {
                        //StashedItems.Add(new CacheACDItem(tempitem));
                        int inventoryRow    = tempitem.InventoryRow;
                        int inventoryColumn = tempitem.InventoryColumn;
                        // Mark this slot as not-free
                        GilesStashSlotBlocked[inventoryColumn, inventoryRow] = true;
                        // Try and reliably find out if this is a two slot item or not
                        PluginItemTypes tempItemType = ItemFunc.DetermineItemType(tempitem.InternalName, tempitem.ItemType, tempitem.FollowerSpecialType, tempitem.ActorSNO);

                        if (ItemFunc.DetermineIsTwoSlot(tempItemType) && inventoryRow != 19 && inventoryRow != 9 && inventoryRow != 29 && inventoryRow != 39 && inventoryRow != 49)
                        {
                            GilesStashSlotBlocked[inventoryColumn, inventoryRow + 1] = true;
                        }
                        else if (ItemFunc.DetermineIsTwoSlot(tempItemType) && (inventoryRow == 19 || inventoryRow == 9 || inventoryRow == 29 || inventoryRow == 39 || inventoryRow == 49))
                        {
                            FunkyTownRunPlugin.DBLog.DebugFormat("GSError: DemonBuddy thinks this item is 2 slot even though it's at bottom row of a stash page: " + tempitem.Name + " [" + tempitem.InternalName +
                                                                 "] type=" + tempItemType.ToString() + " @ slot " + (inventoryRow + 1).ToString(CultureInfo.InvariantCulture) + "/" +
                                                                 (inventoryColumn + 1).ToString(CultureInfo.InvariantCulture));
                        }
                    }
                }                 // Loop through all stash items

                bUpdatedStashMap = true;
            }             // Need to update the stash map?

            return(RunStatus.Success);
        }
コード例 #2
0
ファイル: Plugin.cs プロジェクト: Nksn22/Funky
        internal static void LogGoodItems(CacheACDItem thisgooditem, PluginBaseItemTypes thisPluginBaseItemTypes, PluginItemTypes thisPluginItemType)
        {
            try
            {
                //Update this item
                using (ZetaDia.Memory.AcquireFrame())
                {
                    thisgooditem = new CacheACDItem(thisgooditem.ACDItem);
                }
            }
            catch
            {
                DBLog.DebugFormat("Failure to update CacheACDItem during Logging");
            }
            //double iThisItemValue = ItemFunc.ValueThisItem(thisgooditem, thisPluginItemType);

            FileStream LogStream = null;

            try
            {
                string outputPath = FolderPaths.LoggingFolderPath + @"\StashLog.log";

                LogStream = File.Open(outputPath, FileMode.Append, FileAccess.Write, FileShare.Read);
                using (StreamWriter LogWriter = new StreamWriter(LogStream))
                {
                    if (!TownRunManager.bLoggedAnythingThisStash)
                    {
                        TownRunManager.bLoggedAnythingThisStash = true;
                        LogWriter.WriteLine(DateTime.Now.ToString() + ":");
                        LogWriter.WriteLine("====================");
                    }
                    string sLegendaryString = "";
                    if (thisgooditem.ThisQuality >= ItemQuality.Legendary)
                    {
                        if (!thisgooditem.IsUnidentified)
                        {
                            //Prowl.AddNotificationToQueue(thisgooditem.ThisRealName + " [" + thisPluginItemType.ToString() + "] (Score=" + iThisItemValue.ToString() + ". " + TownRunManager.sValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new legendary!", Prowl.ProwlNotificationPriority.Emergency);
                            sLegendaryString = " {legendary item}";
                            // Change made by bombastic
                            DBLog.Info("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+");
                            DBLog.Info("+  Name:       " + thisgooditem.ThisRealName + " (" + thisPluginItemType.ToString() + ")");
                            //DBLog.Info("+  Score:       " + Math.Round(iThisItemValue).ToString());
                            DBLog.Info("+  Attributes: " + thisgooditem.ItemStatString);
                            DBLog.Info("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+");
                        }
                        else
                        {
                            DBLog.Info("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+");
                            DBLog.Info("+  Unid:       " + thisPluginItemType.ToString());
                            DBLog.Info("+  Level:       " + thisgooditem.ThisLevel.ToString());
                            DBLog.Info("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+");
                        }
                    }
                    else
                    {
                        // Check for non-legendary notifications
                        bool bShouldNotify = false;
                        switch (thisPluginBaseItemTypes)
                        {
                        case PluginBaseItemTypes.WeaponOneHand:
                        case PluginBaseItemTypes.WeaponRange:
                        case PluginBaseItemTypes.WeaponTwoHand:
                            //if (ithisitemvalue >= settings.iNeedPointsToNotifyWeapon)
                            //  bShouldNotify = true;
                            break;

                        case PluginBaseItemTypes.Armor:
                        case PluginBaseItemTypes.Offhand:
                            //if (ithisitemvalue >= settings.iNeedPointsToNotifyArmor)
                            //bShouldNotify = true;
                            break;

                        case PluginBaseItemTypes.Jewelry:
                            //if (ithisitemvalue >= settings.iNeedPointsToNotifyJewelry)
                            //bShouldNotify = true;
                            break;
                        }
                        //if (bShouldNotify)
                        //Prowl.AddNotificationToQueue(thisgooditem.ThisRealName + " [" + thisPluginItemType.ToString() + "] (Score=" + iThisItemValue.ToString() + ". " + TownRunManager.sValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new item!", Prowl.ProwlNotificationPriority.Emergency);
                    }
                    if (!thisgooditem.IsUnidentified)
                    {
                        LogWriter.WriteLine(thisgooditem.ThisQuality.ToString() + "  " + thisPluginItemType.ToString() + " '" + thisgooditem.ThisRealName + sLegendaryString);
                        LogWriter.WriteLine("  " + thisgooditem.ItemStatString);
                        LogWriter.WriteLine("");
                    }
                    else
                    {
                        LogWriter.WriteLine(thisgooditem.ThisQuality.ToString() + "  " + thisPluginItemType.ToString() + " '" + sLegendaryString);
                        LogWriter.WriteLine("iLevel " + thisgooditem.ThisLevel.ToString());
                        LogWriter.WriteLine("");
                    }
                }
            }
            catch (IOException)
            {
                DBLog.Info("Fatal Error: File access error for stash log file.");
            }
        }
コード例 #3
0
ファイル: Plugin.cs プロジェクト: herbfunk/FunkyItemPlugin
        internal static void LogJunkItems(CacheACDItem thisgooditem, PluginBaseItemTypes thisPluginBaseItemTypes, PluginItemTypes thisPluginItemType)
        {
            FileStream LogStream = null;
            string outputPath = FolderPaths.LoggingFolderPath + @"\JunkLog.log";

            try
            {
                LogStream = File.Open(outputPath, FileMode.Append, FileAccess.Write, FileShare.Read);
                using (StreamWriter LogWriter = new StreamWriter(LogStream))
                {
                    if (!TownRunManager.bLoggedJunkThisStash)
                    {
                        TownRunManager.bLoggedJunkThisStash = true;
                        LogWriter.WriteLine(DateTime.Now.ToString() + ":");
                        LogWriter.WriteLine("====================");
                    }
                    string sLegendaryString = "";
                    if (thisgooditem.ThisQuality >= ItemQuality.Legendary)
                        sLegendaryString = " {legendary item}";
                    LogWriter.WriteLine(thisgooditem.ThisQuality.ToString() + " " + thisPluginItemType.ToString() + " '" + thisgooditem.ThisRealName + sLegendaryString);
                    LogWriter.Write(thisgooditem.ItemStatProperties.ReturnPrimaryStatString());
                    LogWriter.WriteLine("");
                }

            }
            catch (IOException)
            {
                DBLog.Info("Fatal Error: File access error for junk log file.");
            }
        }
コード例 #4
0
ファイル: Plugin.cs プロジェクト: herbfunk/FunkyItemPlugin
        internal static void LogGoodItems(CacheACDItem thisgooditem, PluginBaseItemTypes thisPluginBaseItemTypes, PluginItemTypes thisPluginItemType)
        {
            try
            {
                //Update this item
                using (ZetaDia.Memory.AcquireFrame())
                {
                    thisgooditem = new CacheACDItem(thisgooditem.ACDItem);
                }
            }
            catch
            {
                DBLog.DebugFormat("Failure to update CacheACDItem during Logging");
            }
            //double iThisItemValue = ItemFunc.ValueThisItem(thisgooditem, thisPluginItemType);

            FileStream LogStream = null;
            try
            {
                string outputPath = FolderPaths.LoggingFolderPath + @"\StashLog.log";

                LogStream = File.Open(outputPath, FileMode.Append, FileAccess.Write, FileShare.Read);
                using (StreamWriter LogWriter = new StreamWriter(LogStream))
                {
                    if (!TownRunManager.bLoggedAnythingThisStash)
                    {
                        TownRunManager.bLoggedAnythingThisStash = true;
                        LogWriter.WriteLine(DateTime.Now.ToString() + ":");
                        LogWriter.WriteLine("====================");
                    }
                    string sLegendaryString = "";
                    if (thisgooditem.ThisQuality >= ItemQuality.Legendary)
                    {
                        if (!thisgooditem.IsUnidentified)
                        {
                            //Prowl.AddNotificationToQueue(thisgooditem.ThisRealName + " [" + thisPluginItemType.ToString() + "] (Score=" + iThisItemValue.ToString() + ". " + TownRunManager.sValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new legendary!", Prowl.ProwlNotificationPriority.Emergency);
                            sLegendaryString = " {legendary item}";
                            // Change made by bombastic
                            DBLog.Info("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+");
                            DBLog.Info("+  Name:       " + thisgooditem.ThisRealName + " (" + thisPluginItemType.ToString() + ")");
                            //DBLog.Info("+  Score:       " + Math.Round(iThisItemValue).ToString());
                            DBLog.Info("+  Attributes: " + thisgooditem.ItemStatString);
                            DBLog.Info("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+");
                        }
                        else
                        {
                            DBLog.Info("+=+=+=+=+=+=+=+=+ LEGENDARY FOUND +=+=+=+=+=+=+=+=+");
                            DBLog.Info("+  Unid:       " + thisPluginItemType.ToString());
                            DBLog.Info("+  Level:       " + thisgooditem.ThisLevel.ToString());
                            DBLog.Info("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+");
                        }

                    }
                    else
                    {
                        // Check for non-legendary notifications
                        bool bShouldNotify = false;
                        switch (thisPluginBaseItemTypes)
                        {
                            case PluginBaseItemTypes.WeaponOneHand:
                            case PluginBaseItemTypes.WeaponRange:
                            case PluginBaseItemTypes.WeaponTwoHand:
                                //if (ithisitemvalue >= settings.iNeedPointsToNotifyWeapon)
                                //  bShouldNotify = true;
                                break;
                            case PluginBaseItemTypes.Armor:
                            case PluginBaseItemTypes.Offhand:
                                //if (ithisitemvalue >= settings.iNeedPointsToNotifyArmor)
                                //bShouldNotify = true;
                                break;
                            case PluginBaseItemTypes.Jewelry:
                                //if (ithisitemvalue >= settings.iNeedPointsToNotifyJewelry)
                                //bShouldNotify = true;
                                break;
                        }
                        //if (bShouldNotify)
                        //Prowl.AddNotificationToQueue(thisgooditem.ThisRealName + " [" + thisPluginItemType.ToString() + "] (Score=" + iThisItemValue.ToString() + ". " + TownRunManager.sValueItemStatString + ")", ZetaDia.Service.Hero.Name + " new item!", Prowl.ProwlNotificationPriority.Emergency);
                    }
                    if (!thisgooditem.IsUnidentified)
                    {

                        LogWriter.WriteLine(thisgooditem.ThisQuality.ToString() + "  " + thisPluginItemType.ToString() + " '" + thisgooditem.ThisRealName + sLegendaryString);
                        LogWriter.WriteLine("  " + thisgooditem.ItemStatString);
                        LogWriter.WriteLine("");
                    }
                    else
                    {
                        LogWriter.WriteLine(thisgooditem.ThisQuality.ToString() + "  " + thisPluginItemType.ToString() + " '" + sLegendaryString);
                        LogWriter.WriteLine("iLevel " + thisgooditem.ThisLevel.ToString());
                        LogWriter.WriteLine("");
                    }
                }

            }
            catch (IOException)
            {
                DBLog.Info("Fatal Error: File access error for stash log file.");
            }
        }
コード例 #5
0
ファイル: MoveItemTag.cs プロジェクト: Nksn22/Funky
        }         // Custom stashing routine

        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 = 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 = (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);
        }         // Custom stashing routine
コード例 #6
0
ファイル: MoveItemTag.cs プロジェクト: Nksn22/Funky
        private void UpdateStashSlots()
        {
            Logger.DBLog.DebugFormat("Updating Stash Slots!");

            // Array for what blocks are or are not blocked
            for (int iRow = 0; iRow <= 49; iRow++)
            {
                for (int iColumn = 0; iColumn <= 6; iColumn++)
                {
                    StashSlotBlocked[iColumn, iRow] = false;
                }
            }
            // Block off the entire of any "protected stash pages"
            foreach (int iProtPage in CharacterSettings.Instance.ProtectedStashPages)
            {
                for (int iProtRow = 0; iProtRow <= 9; iProtRow++)
                {
                    for (int iProtColumn = 0; iProtColumn <= 6; iProtColumn++)
                    {
                        StashSlotBlocked[iProtColumn, iProtRow + (iProtPage * 10)] = true;
                    }
                }
            }
            // Remove rows we don't have
            for (int iRow = (ZetaDia.Me.NumSharedStashSlots / 7); iRow <= 49; iRow++)
            {
                for (int iColumn = 0; iColumn <= 6; iColumn++)
                {
                    StashSlotBlocked[iColumn, iRow] = true;
                }
            }


            // Map out all the items already in the stash
            foreach (ACDItem tempitem in ZetaDia.Me.Inventory.StashItems)
            {
                if (tempitem.BaseAddress != IntPtr.Zero)
                {
                    //StashedItems.Add(new CacheACDItem(tempitem));
                    int inventoryRow    = tempitem.InventoryRow;
                    int inventoryColumn = tempitem.InventoryColumn;
                    // Mark this slot as not-free
                    StashSlotBlocked[inventoryColumn, inventoryRow] = true;
                    // Try and reliably find out if this is a two slot item or not
                    PluginItemTypes tempItemType = ItemFunc.DetermineItemType(tempitem.InternalName, tempitem.ItemType, tempitem.FollowerSpecialType, tempitem.ActorSNO);

                    if (ItemFunc.DetermineIsTwoSlot(tempItemType) && inventoryRow != 19 && inventoryRow != 9 && inventoryRow != 29 && inventoryRow != 39 && inventoryRow != 49)
                    {
                        StashSlotBlocked[inventoryColumn, inventoryRow + 1] = true;
                    }
                    else if (ItemFunc.DetermineIsTwoSlot(tempItemType) && (inventoryRow == 19 || inventoryRow == 9 || inventoryRow == 29 || inventoryRow == 39 || inventoryRow == 49))
                    {
                        Logger.DBLog.DebugFormat("GSError: DemonBuddy thinks this item is 2 slot even though it's at bottom row of a stash page: " + tempitem.Name + " [" + tempitem.InternalName +
                                                 "] type=" + tempItemType.ToString() + " @ slot " + (inventoryRow + 1).ToString(CultureInfo.InvariantCulture) + "/" +
                                                 (inventoryColumn + 1).ToString(CultureInfo.InvariantCulture));
                    }
                }
            }             // Loop through all stash items

            bUpdatedStashMap = true;
        }