Solved Inventory.getContents() giving invalid items?

Discussion in 'Plugin Development' started by Maurdekye, Jan 6, 2014.

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

    Maurdekye

    I've been trying to make a game with multiple types of guns that fire arrows in different ways. Right now I've made a shotgun from a diamond axe that fires up to ten arrows at a time, depending on how much flint you have in your inventory. To simulate using the flint as ammo, I use getContents() to browse through the player's inventory and test how much flint they have. For some reason, when the player has a stack of less than 10 flint in their inventory the program gives an error and stops working.
    Code:java
    1. @EventHandler
    2. public void Click(PlayerInteractEvent event) {
    3. Player ply = event.getPlayer();
    4. if (ply.getItemInHand().getType() == Material.DIAMOND_AXE) {
    5. String enme = event.getAction().toString();
    6. int arrows = 10;
    7. if (enme.equals("LEFT_CLICK_AIR") || enme.equals("LEFT_CLICK_BLOCK")) {
    8. int total = 0;
    9. ItemStack[] plyinv = ply.getInventory().getContents();
    10. for (ItemStack item : plyinv) {
    11. if (item.getType() == Material.FLINT) { // Errors Here
    12. if (item.getAmount() > arrows-total) { // And Here
    13. item.setAmount(item.getAmount()-(arrows-total)); // Here, Too
    14. total = arrows;
    15. break;
    16. } else {
    17. total += item.getAmount(); // Here as Well
    18. ply.getInventory().removeItem(new ItemStack(Material.FLINT, item.getAmount()));
    19. }
    20. }
    21. System.out.println("end\n");
    22. }
    23. System.out.println(total);
    24. if (total == 0) {
    25. ply.sendMessage("Out of ammo!");
    26. } else {
    27. ply.getWorld().playSound(ply.getLocation(), Sound.EXPLODE, total/((float) arrows), (float) Math.random() + 2);
    28. for (int i=0; i<total; i++) {
    29. double rx = Math.random()*2-1;
    30. double ry = Math.random()*2-1;
    31. double rz = Math.random()*2-1;
    32. ply.getWorld().spawnArrow(ply.getLocation().add(new Vector(0, 1.62, 0)), ply.getLocation().getDirection().multiply(4).add(new Vector(rx, 0.75+ry, rz)), 1, 1);
    33. }
    34. }
    35. }
    36. }
    37. }

    It seems to me that getContents() is giving invalid items? I'm not sure. Whenever the program reaches one of these 'invalid' items and tries to call an ItemStack method on it, it falls apart and gives me errors. Does anyone know why this is happening?

    EDIT: Turns out getContents() returns an ItemStack for every space in the inventory, whether or not it's filled. This can give null ItemStack objects for empty inventory spaces, and the quickest way around this is to just check if item == null, and continue if so.
     
  2. Offline

    TeeePeee

    I'll take a shot in the dark almost and say that when iterating through a players inventory, it is possible to retrieve a null value (which is Material.AIR in this case). Since you can't call methods on null objects, you'll get a NPE.
     
    Garris0n likes this.
  3. Offline

    MTN

    That's correct.
     
  4. Offline

    Maurdekye

    Is there a way to test for that? Because it seems every time I try to call a method on it, it breaks.
     
  5. Check for null first. You can skip them in your iteration using continue
     
  6. Offline

    Maurdekye

    I know how to write Java. But they register as null objects? I'll try that.
     
  7. Offline

    Xephiro

    You need make a few cachante in the for

    Code:java
    1. for (ItemStack item : plyinv) {
    2. if (item == null) continue;
    3.  
    4. if (item.getType() == Material.FLINT) {
    5. if (item.getAmount() > arrows-total) {
    6. item.setAmount(item.getAmount()-(arrows-total)); // Here, Too
    7. total = arrows;
    8. break;
    9. } else {
    10. total += item.getAmount(); // Here as Well
    11. ply.getInventory().removeItem(new ItemStack(Material.FLINT, item.getAmount()));
    12. }
    13. }
    14. System.out.println("end\n");
    15. }


    Just add
    Code:java
    1. if (item == null) continue;

    At firt in your for

    Because getInventory().getContents(); take all slotls of the inventory and if any one of slot doesn't have an item give a null object.

    Good Luck
     
  8. Offline

    Maurdekye

    Thanks, that worked.
     
Thread Status:
Not open for further replies.

Share This Page