Detecting when a chest inventory is empty

Discussion in 'Plugin Development' started by maxben34, Nov 6, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    maxben34

    I am unable to detect when a chest inventory is empty for some reason. I'm trying to make carepackages that fall with random items inside (this works fine) but when the items are taken from the inventory, the chest isn't getting destroyed... due to the fact that it can't detect that the chest inventory is empty. Can anybody help?
     
  2. Offline

    NinjaWAffles

    After doing a little bit of research, it didn't seem too hard to pull off. Below I'll post an example code that I threw together quickly and it worked for me. I'm not sure how efficient it is, but it worked for me.

    Code:java
    1.  
    2. public void onInventoryClosed(InventoryCloseEvent e)
    3. {
    4. if(e.getInventory().getType() == InventoryType.CHEST)
    5. {
    6. ItemStack[] items = e.getInventory().getContents();
    7.  
    8. for(ItemStack item : items)
    9. {
    10. if(item != null) { return; }
    11. }
    12.  
    13. //Run code to execute if the chest is empty.
    14. }
    15. }
    16.  


    The code should be pretty self-explanatory, but if it isn't, it'll simply wait for the 'InventoryCloseEvent' to be fired, check if the inventory is a chest, iterator through the contents; and if they're all null (empty), some code will then be run. In your case, you can make it despawn after a certain amount of time. It doesn't matter. :p
     
  3. Offline

    maxben34

    NinjaWAffles
    To further relate this to what I'm doing:
    This is what I was using... It wasn't deleting the chest after the TNT were taken from it.
    Code:java
    1. @SuppressWarnings("deprecation")
    2. @EventHandler
    3. public void onInventoryClick(InventoryOpenEvent e){
    4. Inventory inventory = e.getInventory();
    5. if (!inventory.getType().equals(InventoryType.CHEST))
    6. return;
    7. Player player = (Player) e.getPlayer();
    8. player.sendMessage("This is a chest");
    9. ItemStack itemInHand = player.getItemInHand();
    10. if (!itemInHand.getType().equals(Material.NAME_TAG)) {
    11. player.sendMessage("You can't open this carepackage");
    12. e.setCancelled(true);
    13. player.damage(1.0, player);
    14. return;
    15. }
    16. e.getInventory().setItem(13, new ItemStack(Material.TNT, 3));
    17. player.sendMessage("You have opened the care package");
    18. if (inventory.getItem(13) == new ItemStack(Material.AIR)) {
    19. player.sendMessage("You got the items from the care package!");
    20. Location loc = player.getLocation();
    21. if (loc.getBlock().getRelative(6, 6, 6).getType().equals(Material.CHEST)) {
    22. Block c = loc.getBlock().getRelative(6, 6, 6);
    23. player.sendMessage("The care package is now gone!");
    24. c.setType(Material.AIR);
    25. c.getWorld().playEffect(c.getLocation(), Effect.STEP_SOUND, c.getTypeId());
    26. }
    27.  
    28. }
    29.  
    30. }
    31. }
    32.  
    33.  
     
  4. Offline

    NinjaWAffles

    I believe the reason your code isn't working is because the slot is never empty. What you're doing is listening for an "InventoryOpenEvent," which is called each time the inventory is opened; and before your code is run checking if it's empty, the previous code has already put in more TNT, thus that slot never being empty.

    I'm not sure if anyone else would like to elaborate on a better idea, but I would simply cancel the event when the chest is opened and create my own inventory with a custom name, like "Care Package" or something, and then use the "InventoryCloseEvent," and put an if statement making sure that the chest has the name we predefined earlier, then look for chests around the player with the same name that are empty and delete them. This might be going way out of your way, however.
     
  5. Offline

    maxben34

    It's a bit out of the way but I guess it's the best I got :/

    Ok, so I started working on this. This is what I have. I'm getting a problem when the carepackage inventory opens though, It has the TNT in it, but my mouse is stuck to one location so it's very very hard to close it. I believe that's because it keeps looping the inventory open, but I'm really not sure.

    In the code, know that care is my custom inventory, and that cpackage(); is my method that adds tnt to the inventory.
    Code:
        @EventHandler
        public void onInventoryClick(InventoryOpenEvent e){
     
            Inventory inventory = e.getInventory();
     
            if (inventory.getType().equals(InventoryType.CHEST)){
                  final Player player = (Player) e.getPlayer();
                  ItemStack itemInHand = player.getItemInHand();
                  if (!itemInHand.getType().equals(Material.NAME_TAG)) {
                      e.setCancelled(true);
                      player.damage(1.0, player);
                      return;
                  }
                  Bukkit.getScheduler().scheduleSyncDelayedTask(this,new Runnable(){
                      public void run(){
                          player.openInventory(care);
                          cpackage();
                      }
                      },1);
                }
            } 
             
    @EventHandler
    public void onCarePackageTake(InventoryClickEvent e){
        if(e.getInventory().getName().equals(care.getName())){
            Player player = (Player) e.getWhoClicked();
            ItemStack clicked = e.getCurrentItem();
        Material c = clicked.getType();
        player.getInventory().setItem(8, new ItemStack(c));
        player.closeInventory();
        }
    }
    @SuppressWarnings("deprecation")
    @EventHandler
    public void onInventoryClose(InventoryCloseEvent e){
        if(e.getInventory().getName().equals(care.getName())){
            Location loc = e.getPlayer().getLocation();
            if (loc.getBlock().getRelative(6, 6, 6).getType().equals(Material.CHEST)) {
                Block c = loc.getBlock().getRelative(6, 6, 6);
                ((Player) e.getPlayer()).sendMessage("The care package is now gone!");
                c.setType(Material.AIR);
                c.getWorld().playEffect(c.getLocation(), Effect.STEP_SOUND, c.getTypeId());
        }
     
    }
    }
    }
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
  6. Offline

    xTrollxDudex

    maxben34
    You could've used c.breakNaturally(), it will break it and play the sound.
     
  7. Offline

    maxben34

    Suprisingly enough, the effect "step_sound" makes block break particles or step particles appear. Either way the carepackage is still not working right :/

    I still haven't figured out why it's glitching out :/

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
Thread Status:
Not open for further replies.

Share This Page