I cant figure out how to make sure player inventory is empty

Discussion in 'Spigot Plugin Development' started by Shayne, May 29, 2017.

  1. Code (Text):
    if (p.getInventory().getContents().length < 0 && p.getInventory().getHelmet() == null && p.getInventory().getChestplate() == null && p.getInventory().getLeggings() == null && p.getInventory().getBoots() == null ) {





                                World w = Bukkit.getServer().getWorld("robak");
                                 Location location = new Location(w, 101, 118, 146);

                                 p.teleport(location);

                                 p.sendMessage("&f&lBlist&9&lMC &8// &7tped");
    }
    Basically I want my plugin to teleport them to said world and coordinates only when their inventory and armor IS EMPTY


    I tried this but it doesnt work, does someone know why?
     
  2. The length of the contents will always be the size of the inventory, if its empty all entries in the array will be null.
     
  3. Code (Text):
    p.getInventory().getContents().length < 0
    Do you see an issue here? This will never occur, the length will not be less than 0. Fix this part of the code. Everything else looks fine and should work after this is fixed. Instead, you might want to look into inventory.firstEmpty().

    Code (Text):
    int firstEmpty()

    Returns the first empty Slot.

    Returns: The first empty Slot found, or -1 if no empty slots.
     
  4. This is a pretty good util.
    Code (Text):
    /**
    * Checks if a player has an empty inventory
    *
    * @param player The player to check for
    * @return True if their inventory is completely empty
    * @since 1.4
    */
    public static boolean hasEmptyInv(Player player) {
      // Player is null, hard to run a check then!
      if (player == null) return false;

      for(ItemStack it : player.getInventory().getContents())
      {
        // Oops, an item was found. Not empty!
        if(it != null) return false;
      }

      // Loop is done, and no items were found.
      return true;
    }
     
  5. Code (Text):
    public boolean hasEmptyInventory(Player player){
        return player.getInventory().getContents().length == 0;
    }
    EDIT: Not working ^^
     
    #5 MrDienns, May 29, 2017
    Last edited: May 29, 2017
    • Optimistic Optimistic x 2
  6. That's not true. The getContents size never changes. You need to check if every value in the Array is null.
    Code (Text):
    Arrays.stream(i.getContents()).allMatch(item -> item==null); // <= Inventory Empty
     
  7. The documentation states:
    Code (Text):
    ItemStack[] org.bukkit.inventory.Inventory.getContents()

    Returns all ItemStacks from the inventory

    Returns:
        An array of ItemStacks from the inventory.
    I am fairly sure it simply returns an empty array when the inventory is empty. I haven't used it in a while, but I'm fairly positive about it. You're returning the contents of an inventory, thus the items. You're not returning the slots, but the contents. I'd say test it out, but I'm almost fully sure it only returns actual itemstacks and not empty slots.
     
  8. MiniDigger

    Supporter

    nope.
    minecraft internally returns a full array, where some stacks might be marked as empty. craftbukkit converts those empty itemstacks to null:
    https://hub.spigotmc.org/stash/proj...bukkit/inventory/CraftInventory.java#59,75-78
     
  9. Yeah, because that is how new ItemStack[42] works :) Entries can be null here.
    Well, that is if you look at the documentation. But in Java, you can pre-define the size of an array using Array[size].

    So ItemStack[] myArray = new ItemStack[4];

    myArray[0] == null, but does exist in the array hence the size being > 0.
    myArray[1] == null.
    myArray[2] == null.
    myArray[3] == null.
    myArray[4] == would throw a IndexOutOfBoundsException exception.

    Calling myArray.size() would output 3.

    EDIT: Opps, minedigger already explained.
     
    #11 ExpDev, May 29, 2017
    Last edited: May 29, 2017
  10. int contents = Arrays.asList(inventory.getContents()).stream().filter(obj -> obj != null).collect(Collectors.toList()).size();
     
  11. I think you ment array.length
     
  12. Yes. Yes I did :). size() can only be called on objects extending Collection. Oopsz
     
  13. ;)
     
  14. A better way to do this is by using the count method on the stream,

    Code (Text):
    ((int) Stream.of(inventory.getContents()).filter(Objects::isNull).count());
    If this number is equal to Inventory#getSize, then it's empty...
     
  15. Thats a way to do it too, and looks a lot cleaner than collect(...).size()
    Personally i prefer lambdas though
     
  16. Method references are lambdas...