Chest Inventories Help

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

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

    maxben34

    I'm making a plugin that allows players to open a chest only if they are holding a name tag. When they open the chest, it has 3 tnt in it and will break once the tnt are taken. When a player attempts to open the chest with the code I have, nothing happens except for the chest opening sound being made and the chest open animation. This happens whether or not the player is holding a nametag.

    Code:java
    1. @SuppressWarnings("deprecation")
    2. @EventHandler
    3. public void onInventoryClick(InventoryOpenEvent e){
    4. if(e.getInventory().getType() == InventoryType.CHEST){
    5. if(e.getPlayer().getItemInHand() == new ItemStack(Material.NAME_TAG)){
    6. e.getView().setItem(14, new ItemStack(Material.TNT,3));
    7. if(e.getInventory().getContents().length == 0);
    8. Block c = (Block)e.getPlayer().getLocation().getBlock().getRelative(6, 6, 6);
    9. if(e.getPlayer().getLocation().getBlock().getRelative(6, 6, 6).getType() == Material.CHEST){
    10. c.setType(Material.AIR);
    11. c.getWorld().playEffect(c.getLocation(), Effect.STEP_SOUND, c.getTypeId());
    12. }
    13.  
    14. }else{
    15. e.setCancelled(true);
    16. e.getPlayer().damage(.5, e.getPlayer());
    17. }
    18.  
    19. }
    20. }
    21. }


    I should also add that the chest is spawned in from a falling entity.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
  2. Offline

    CraftBang

    maxben34 so what isn't working? did you try like to print messages (or just broadcast them) so you could see where it stops working, and then try to edit where it stops working? :)
     
  3. Offline

    maxben34

    CraftBang
    It's just not showing the chest inventory when right clicked. or the things inside the inventory for that matter.
     
  4. Offline

    CraftBang

    so maxben34 the else parts runs , and it will close and give you 0.5 damage?

    maxben34 you know your void name has nothing to do with the event I guess, you do onInventoryClick but this is when you open up an inventory? mhm ?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
  5. Offline

    maxben34

    I started making this an inventory click event but I changed it.. not big deal. Also, the else happens if somebody else (that doesn't click the chest with the name tag "key")... which damages them .
     
  6. Offline

    CraftBang

    maxben34 well sorry, I don't know how the codes perform in minecraft action so I can't figure it out (and I never used this before) , but maybe try putting messages so you can see what does run and what doesn't run :p
     
  7. Offline

    russjr08

    Well, I believe the first mistake you have is how you're comparing what's in the player's hand. I would compare it with the Material type.

    So something like:
    Code:
    if(player.getItemInHand().getType() == Material.NAME_TAG){
     
     
     
    // Your code
     
     
     
     
    }
     
  8. Offline

    maxben34

    That's true. I'll check that out and get back to you.

    russjr08
    I did it... but it isn't working still.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
    russjr08 likes this.
  9. Offline

    russjr08

    Try putting various debug statements throughout your code, so you can see where its failing.
    Such as
    Code:java
    1. System.out.println("Debug #1");
    2. // Some of your code
    3. System.out.println("Debug #2");
    4. // More of your code
    5.  
    6. // And so on.
     
  10. Offline

    maxben34

    okay :)

    I think that my code is wrong for some reason though... like I did the inventory stuff wrong.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
  11. Offline

    russjr08

    What did it not do?
     
  12. Offline

    maxben34

    The chest "opens" but the player doesn't get the inventory.
     
  13. Offline

    russjr08

    So the inventory of the chest doesn't display to the player? What is your updated code, and what is the last debug statement that gets called?
     
  14. Offline

    maxben34

    I figured out what was wrong with part of it. The inventory new successfully opens with TNT inside. Now, my problem is that the inventory isn't closing and the chest isn't getting destroyed. I'm currently not getting any stacktraces.

    My Code:
    Code:java
    1. @SuppressWarnings("deprecation")
    2. @EventHandler
    3. public void onInventoryClick(InventoryOpenEvent e){
    4. if(e.getInventory().getType() == InventoryType.CHEST){
    5. ((Player) e.getPlayer()).sendMessage("This is a chest");
    6. if(e.getPlayer().getItemInHand().equals(new ItemStack(Material.NAME_TAG))){
    7. e.getView().setItem(13, new ItemStack(Material.TNT,3));
    8. ((Player) e.getPlayer()).sendMessage("You have opened the care package");
    9. if(e.getInventory().getContents().length < 0){
    10. e.getPlayer().closeInventory();
    11. if(e.getPlayer().getLocation().getBlock().getRelative(6, 6, 6).getType().equals(Material.CHEST));
    12. Block c = e.getPlayer().getLocation().getBlock().getRelative(6, 6, 6);
    13. ((Player) e.getPlayer()).sendMessage("The care package is now gone!");
    14. c.setType(Material.AIR);
    15. c.getWorld().playEffect(c.getLocation(), Effect.STEP_SOUND, c.getTypeId());
    16.  
    17. }
    18. }else{
    19. ((Player) e.getPlayer()).sendMessage("You can't open this carepackage");
    20. e.setCancelled(true);
    21. e.getPlayer().damage(1, e.getPlayer());
    22. }
    23.  
    24. }
    25. }
    26. }
     
  15. Offline

    SourceForums

    maxben34
    Can't you simply cancel the event and code it so that it opens a new custom inventory?
     
  16. Offline

    lycano

    maxben34 a more cleaned up structure would be the following code. I fixed some mistakes you made
    • using == instead of .equals when comparing objects
    • possible auto correction mistake from your IDE
    Code:java
    1.  
    2. @EventHandler
    3. public void onInventoryClick(InventoryOpenEvent e){
    4. Inventory inventory = e.getInventory();
    5. if (!inventory.getType().equals(InventoryType.CHEST))
    6. return;
    7.  
    8. // debug message
    9. Player player = e.getPlayer();
    10. player.sendMessage("This is a chest");
    11.  
    12. ItemStack itemInHand = player.getItemInHand();
    13. if (!itemInHand.getType().equals(Material.NAME_TAG)) {
    14. player.sendMessage("You can't open this carepackage");
    15. e.setCancelled(true);
    16. player.damage(1, player);
    17. return;
    18. }
    19.  
    20. // at this point we know he holds Material.NAME_TAG as we said
    21. // return if not itemInHand Material.NAME_TAG
    22.  
    23. // place 3 stacks of TNT in item slot 13
    24. e.getView().setItem(13, new ItemStack(Material.TNT, 3));
    25. player.sendMessage("You have opened the care package");
    26.  
    27. // if the inventory is empty then execute this block
    28. // not sure about length == 0 this could return all empty slots but "< 0" is wrong
    29. // if length is not 0 then you have to loop through its contents and return when something else
    30. // than Material.AIR is found
    31. if (inventory.getContents().length == 0) {
    32. player.closeInventory();
    33.  
    34. // are you sure you wanted this? If with empty body? (semicolon at end of if statement)
    35. /*
    36.   if(e.getPlayer().getLocation().getBlock().getRelative(6, 6, 6).getType().equals(Material.CHEST));
    37.   Block c = e.getPlayer().getLocation().getBlock().getRelative(6, 6, 6);
    38.   ((Player) e.getPlayer()).sendMessage("The care package is now gone!");
    39.   c.setType(Material.AIR);
    40.   c.getWorld().playEffect(c.getLocation(), Effect.STEP_SOUND, c.getTypeId());
    41.   */
    42.  
    43. Location loc = player.getLocation();
    44. if (loc.getBlock().getRelative(6, 6, 6).getType().equals(Material.CHEST)) {
    45. Block c = loc.getBlock().getRelative(6, 6, 6);
    46.  
    47. player.sendMessage("The care package is now gone!");
    48. c.setType(Material.AIR);
    49. c.getWorld().playEffect(c.getLocation(), Effect.STEP_SOUND, c.getTypeId());
    50. }
    51. }
    52. }
    53.  
     
  17. Offline

    maxben34

     
  18. Offline

    lycano

    maxben34 is there something you want to tell me?
     
  19. Offline

    maxben34

    Yea, sorry I was on my ipad and it must have screwed up. I meant to say that im about to go test that out. Thanks.

    lycano I used the code that you gave me above and it did the exact same thing as the previous did before.

    I did some more fiddiling around and still no luck. :/

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
  20. Offline

    lycano

    maxben34 well its just a polished version and i just saw that it could be simplified more ^^ so it should do the same. If not i would have made a mistake.

    If its not working check getContents() and add some debug messages like

    System.out.println("getContents().length: " + getContents().length);

    Use those as pointers and check how far it goes. Place "meaningfull" debug messages before if and after an if statement.

    e.g.

    Code:java
    1.  
    2. System.out.println("something: " + something);
    3. if (something == true) {
    4. System.out.println("Something is true");
    5. // do something
    6. }
    7.  


    This should help you finding out what the problem is. I think that getcontents() will never be 0 and it will actually have maxInventorySlots ItemStacks that are Material.AIR but dunno. Cant test it out since im at work and dont have internet at home at the moment.
     
  21. Offline

    maxben34

    Ok thanks, that's what I thought but I don't know how to detect it if that's the case.
     
  22. Offline

    lycano

    maxben34 well first try to add those debug messages and check what the case is. Using the code from post 20 it should at least send the player the message "You have opened a care package" if the player holds a name_tag in his hand.

    Check if this is the case. If so then checkout what happens if you remove an item from the view. The last part should get executed when you move the last tnt item out of the chest into your inventory.

    If this is not the case thats where we have to debug why. Placing those additional system.out messages may help you a lot.
     
  23. Offline

    maxben34

    Currently is isn't able to detect when the last tnt is removed from the chest.
     
  24. Offline

    lycano

    maxben34 well ... i dont know what to say but it seems that we both didn't checked the event you register.

    You do use InventoryOpenEvent but name the method onInventoryClick which is not the same.

    The event you use only fires when you open an inventory. In your case we defined a filter that will only process CHEST.

    What you want is something else.

    To clarify (what i read from the code):

    You open the inventory -> if it is a chest then -> we check the itemInHand for NAME_TAG -> when found place 3 stacks of TNT in slot 13.

    inventory.getContents().length will never be zero as you place a tnt into the inventory.

    Since InventoryOpen is fired when someone opens an inventory nothing will happen when you click or move items in the inventory.

    What you need is to move the code that is checking for "getContents().length" into InventoryClickEvent or InventoryMoveÎtemEvent (you have to check for yourself which works best) The first is you clicked it and the later you moved it into another inventory.

    I would probably use InventoryMoveItemEvent since you want to close the inventory when its empty.

    Of course you would have to add some parts of the InventoryOpenEvent logic into it like checking if the Inventory is type of CHEST and if the player is holding a NAME_TAG.

    I recommend adding a method that does both of those checks. Then use this method in both events to minimize redundant code.

    public boolean canOpenCarePackage(Player player, Inventory inventory);
     
  25. Offline

    maxben34

    i kinda see what you're getting at. Thanks.
     
Thread Status:
Not open for further replies.

Share This Page