Solved Sort not getting through entire Inventory

Discussion in 'Spigot Plugin Development' started by GeorgeZ, Jun 2, 2016.

  1. Hello! I am working on an inventory sorting plugin and everything is working except... the sorting! I thought it was working but when I started working on a double chest I realized that not all of the items were being sorted completely, when comparing ID's pairs were good but the entire chest was not. (See pictures:)
    [​IMG]

    [​IMG]


    Here is my current sort class:
    Code (Text):
    package com.george.invPlugin;

    import java.util.ArrayList;

    import org.bukkit.Material;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.material.MaterialData;

    @SuppressWarnings("unused")
    public final class SortMain {

        public void setItemlist(ArrayList<ItemStack> itemlist) {
            this.itemlist = itemlist;
        }

        private ArrayList<ItemStack> itemlist;
       
        @SuppressWarnings("deprecation")
        private static int item(ItemStack item) {
            return item.getTypeId();
        }
           
        public static ArrayList<ItemStack> SortArrayList(ArrayList<ItemStack> itemlist) {
            //System.out.println("UNSORTED: " + itemlist);
            ArrayList<ItemStack> sortedItemlist = BubbleSort(itemlist);
            //System.out.println("SORTED: " + sortedItemlist);
            return sortedItemlist;
        }
       
        private static ArrayList<ItemStack> BubbleSort (ArrayList<ItemStack> itemlist) {
            boolean flag = true;
            ArrayList<ItemStack> sortedItemlist = itemlist;
            while (flag) {
                flag = false;
                for (int i = 0; i < sortedItemlist.size() - 1; i++) {          
                    for (int j = 1; j < sortedItemlist.size() - i; j++) {              
                        if (compare(sortedItemlist.get(j-1), sortedItemlist.get(j)) < 0) {
                            ItemStack temp = itemlist.get(j-1);
                            sortedItemlist.set(j-1, sortedItemlist.get(j));
                            sortedItemlist.set(j, temp);
                            flag = true;
                        }
                    }
                }
            }
            return sortedItemlist;
        }
       
        private static int compare(ItemStack o1, ItemStack o2) {
            return Integer.compare(item(o1),item(o2));
        }  
    }
     
    My question is: How can I verify that the sorting is getting through to every single item in the itemlist?

    Thank you for your help!
     
  2. You could just run a quick test and have it print the items it is checking. If you do it for a few different lists and it works then you're probably fine.
     
    • Like Like x 1
  3. I just realized something, it's not sorting the double chests because it is only checking for a single block that the player is looking at. How would I change that?

    Code (Text):

    package com.george.invPlugin;

    import java.util.ArrayList;
    import java.util.Set;

    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.block.Chest;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.PlayerInventory;

    public class CommandSort implements CommandExecutor {
     
        ArrayList<ItemStack> itemlist = new ArrayList<ItemStack>();
     
        @SuppressWarnings("deprecation")
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (sender instanceof Player) {
                // Setting player and inventory variables
                Player player = (Player) sender;
                Block block = player.getTargetBlock((Set<Material>)null, 5);
                // If player is looking at a chest
                if (block.getType() == Material.CHEST) {
                    Chest chest = (Chest) block.getState();
                    Inventory inv = chest.getBlockInventory();
                    ItemStack[] items = inv.getContents();
                   int len = inv.getSize();
                   int affected = 0;
                   for (int i = 0; i < len; i++) {
                       ItemStack item = items[i];
                       // Avoid infinite stacks and stacks with durability
                       if (item == null || item.getAmount() <= 0) {
                           continue;
                       }
                      int max = item.getMaxStackSize();
                      if (item.getAmount() < max) {
                          int needed = max - item.getAmount();
                           // Find another stack of the same type
                           for (int j = i + 1; j < inv.getSize(); j++) {
                               ItemStack item2 = items[j];
                              // Avoid infinite stacks and stacks with durability
                               if (item2 == null || item2.getAmount() <= 0
                                       || (item.getMaxStackSize() == 1)) {
                                   continue;
                               }
                               if (item2.getType() == item.getType() && item2.getData().getData() == item.getData().getData()) {
                                   // This stack won't fit in the parent stack
                                   if (item2.getAmount() > needed) {
                                       item.setAmount(max);
                                       item2.setAmount(item2.getAmount() - needed);
                                       break;
                                   }
                                   // This stack will
                                   else {
                                       items[j] = null;
                                       item.setAmount(item.getAmount() + item2.getAmount());
                                       needed = max - item.getAmount();
                                   }
                                   affected ++;
                               }
                          }
                      }
                       if (affected > 0) {
                           inv.setContents(items);
                       }
                   }
                   boolean dbl = false;
                   BlockFace[] aside = new BlockFace[]{BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
                   for(BlockFace bf : aside) {
                       if(block.getRelative(bf, 1).getType() == Material.CHEST) {
                           dbl = true;
                           break;
                       }
                   }
                   if (dbl) {
                      for (int i = 0; i < 54 ; i ++) {
                       ItemStack item = inv.getItem(i);
                       // Make sure if slot is empty that it will add air instead
                      if (item != null) {
                              // Add ItemStack to itemlist
                               itemlist.add(item);
                               inv.clear(i);
                           }
                      }
                   }
                   else
                   {
                       for (int i = 0; i < 27 ; i ++) {
                           ItemStack item = inv.getItem(i);
                           // Make sure if slot is empty that it will add air instead
                          if (item != null) {
                              // Add ItemStack to itemlist
                               itemlist.add(item);
                               inv.clear(i);
                           }
                       }  
                   }
                   // Send itemlist to SortMain Class to be sorted and set sortedlist
                   ArrayList<ItemStack> sortedlist = SortMain.SortArrayList(itemlist);
                    int it = 0;
                    // Add items of sortedlist to the players inventory
                   for (ItemStack item : sortedlist) {
                      inv.setItem(it, item);
                      // Because setItem() takes an index and an item as arguments, add one to the index so the next item doesn't overwrite the previous
                      it ++;
                   }
                   // Reset lists and integers
                   it = 0;
                    itemlist.clear();
                    sortedlist.clear();            
                }
                // If player is not looking at a chest
                else {
                  // Begin stacking like ItemStacks
                    PlayerInventory inv = player.getInventory();
                   ItemStack[] items = inv.getContents();
                   int len = inv.getSize();
                   int affected = 0;
                   for (int i = 0; i < len; i++) {
                       ItemStack item = items[i];
                       // Avoid infinite stacks and stacks with durability
                       if (item == null || item.getAmount() <= 0) {
                           continue;
                       }
                      int max = item.getMaxStackSize();
                      if (item.getAmount() < max) {
                          int needed = max - item.getAmount();
                           // Find another stack of the same type
                           for (int j = i + 1; j < inv.getSize(); j++) {
                               ItemStack item2 = items[j];
                              // Avoid infinite stacks and stacks with durability
                               if (item2 == null || item2.getAmount() <= 0
                                       || (item.getMaxStackSize() == 1)) {
                                   continue;
                               }
                               if (item2.getType() == item.getType() && item2.getData().getData() == item.getData().getData()) {
                                   // This stack won't fit in the parent stack
                                   if (item2.getAmount() > needed) {
                                       item.setAmount(max);
                                       item2.setAmount(item2.getAmount() - needed);
                                       break;
                                   }
                                   // This stack will
                                   else {
                                       items[j] = null;
                                       item.setAmount(item.getAmount() + item2.getAmount());
                                       needed = max - item.getAmount();
                                   }
                                   affected ++;
                               }
                          }
                      }
                       if (affected > 0) {
                           inv.setContents(items);
                       }
                   }
                  // Loop through inventory and add ItemStack to itemlist
                   for (int i = 9; i < 36 ; i ++) {
                       ItemStack item = inv.getItem(i);
                       // Make sure if slot is empty that it will add air instead
                      if (item == null) {
                          item = new ItemStack(Material.AIR);
                       }
                      // Add ItemStack to itemlist
                       itemlist.add(item);
                       inv.clear(i);
                   }
                   // Send itemlist to SortMain Class to be sorted and set sortedlist
                   ArrayList<ItemStack> sortedlist = SortMain.SortArrayList(itemlist);
                   // 9 is the first slot not in the hotbar
                    int it = 9;
                    // Add items of sortedlist to the players inventory
                   for (ItemStack item : sortedlist) {
                      inv.setItem(it, item);
                      // Because setItem() takes an index and an item as arguments, add one to the index so the next item doesn't overwrite the previous
                      it ++;
                   }
                   // Reset lists and integers
                   it = 9;
                    itemlist.clear();
                    sortedlist.clear();
                }
            }
            return true;
        }
    }
     
    Edit: Updated code, but I am getting null errors at line 84:
    Code (Text):

                   boolean dbl = false;
                   BlockFace[] aside = new BlockFace[]{BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
                   for(BlockFace bf : aside) {
                       if(block.getRelative(bf, 1).getType() == Material.CHEST) {
                           dbl = true;
                           break;
                       }
                   }
                   if (dbl) {
                      for (int i = 0; i < 54 ; i ++) {
                       ItemStack item = inv.getItem(i); // LINE 84
                       // Make sure if slot is empty that it will add air instead
                      if (item != null) {
                              // Add ItemStack to itemlist
                               itemlist.add(item);
                               inv.clear(i);
                           }
                      }
     
     
    #3 GeorgeZ, Jun 2, 2016
    Last edited: Jun 2, 2016
  4. The variable inv is null
     
    • Useful Useful x 1
  5. Ah okay! That's good to know, so do I need to set the variable inv at a different point or do I need to set a different value?
     
  6. We'll it depends where you set the variable you always need to set it to something
     
    • Like Like x 1
  7. I'm confused though because I've used that code before with the player inventory and it works. I don't understand why inv is null.

    Thank you for your help by the way

    Edit: Never mind haha figured it out!

    I changed up this part:
    Code (Text):

                if (block.getState() instanceof Chest) {
                    Chest chest = (Chest) block.getState();
                    Inventory inv = chest.getInventory();
     
    Before inv was chest.getBlockInventory(); which wasn't working, as well as the if statement.
     
    #7 GeorgeZ, Jun 2, 2016
    Last edited: Jun 2, 2016