im stuck

Discussion in 'Plugin Development' started by TerroDoor, Aug 31, 2019.

  1. Offline

    TerroDoor

    im trying to use a for each loop to iterate through a itemstack list, the items add but it's not what i want.

    im trying to set the permitted items before the nonpermitted items, any help would be nice, thanks.

    Code:
    
    public class Kits implements Listener {
    
        private Inventory kitinv = Bukkit.createInventory(null, 9, "select a kit");
        private ItemStack sk = new ItemStack(Material.DIAMOND_SWORD);
        private ItemStack ak = new ItemStack(Material.BOW);
        private ArrayList<ItemStack> kits = new ArrayList<ItemStack>();   
       
     @EventHandler
        public void onOpenInv(PlayerInteractEvent e) {
          
      Player p = (Player)e.getPlayer();
            kits.add(sk);
            kits.add(ak);
            
    if (p.getInventory().getItemInMainHand().getType() == Material.BOOK) {
                if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
                    for (ItemStack i : kits) {
                        if (p.hasPermission("jkits")) {
                            kitinv.addItem(i);
                        }
                    }
                 
       p.openInventory(kitinv);       
    
                } else {
                    return;
                }
            }
            return;
        }
    }
    
     
  2. Offline

    timtower Moderator Moderator

    @TerroDoor Then you set them on specific slots, not just adding them.
     
  3. Offline

    TerroDoor

    @timtower but what if i don't want them assigned to a slot, rather just placed before the non-permitted items?
     
  4. Offline

    timtower Moderator Moderator

    @TerroDoor Then you use an index to put the in the right place.
     
  5. Offline

    TerroDoor

    @timtower thanks, I kinda understand. what method gets the index? Also, it's based on permissions so does that mean i need to use an if statement for each item? is there a better way to this? Thanks
     
  6. Offline

    timtower Moderator Moderator

    @TerroDoor You can do setItem(slot, item), or something similar.
    Then you increase the slot number.
    And no, you have them in a separate list, so that is fine.
    Configuration might be a good idea, specific kit in a specific slot with a specific permission.
     
  7. Offline

    TerroDoor

    @timtower I've tried but im having some trouble, do you have time to show me any examples? I can't find any topics similar online to my problem im having.

    i've been using this

    Code:
    
                    for (ItemStack i : kits) {
                        kitinv.setItem(0, kits.get(0));
                           
                       
                        }
                    }
                    p.openInventory(kitinv);       
    
    
    That gets the index 0 and sets it to slot 0 right? But, what if the player didn't have permission? it would need to be moved to another slot to replace the slot for the kits the player does have permission for

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
  8. Offline

    timtower Moderator Moderator

    @TerroDoor You increment the slot number every time you add an item.
     
  9. Offline

    TerroDoor

    @timtower so inside the loop i just use i++?

    I cant because it's not an int.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
  10. Offline

    timtower Moderator Moderator

    @TerroDoor No, you need to have it as a separate value outside of the for loop.
     
  11. Offline

    TerroDoor

    @timtower sorry for making this confusing, so from what i understand i need to loop the kitinv, check every item that the player has permission for, then assign each kit to the inv slots, followed after by the kits they dont own.

    Could you help with showing me a way to set (not add) the permitted items to the inv
     
  12. Offline

    timtower Moderator Moderator

  13. Offline

    TerroDoor

    @timtower how do i structure it inside the parenthesis? inside of my loop shown above, thanks for your patience btw!!

    update: is getSize grabbing all slots?

    Code:
    
        private int slots = kitinv.getSize();
    
                    for (ItemStack i : kits) {
                        if (p.hasPermission("jkits" + i)) {
                            kitinv.setItem(slots, i);
                        }
                    }
    
     
  14. Offline

    timtower Moderator Moderator

    @TerroDoor getSize() grabs the slot count.
    But you need a int variable for which slot you are using. Not sure if you want to use the itemstack in the permission though, that name can be a little bit weird.
     
  15. Offline

    TerroDoor

    @timtower thanks for pointing that out, how would i create permission nodes for each seperate kit? etc pvp would be "jkits." + "pvp" and so on. is it a String list?
     
  16. Offline

    timtower Moderator Moderator

    @TerroDoor Config is the best option, or a custom class that contains the required information AND the kit info.
     
  17. Offline

    TerroDoor

    @timtower
    kitinv.setItem(slots, i); throws an NPE

    @timtower I switched to using .firstEmpty(); instead of the getSize() method.

    I've now got this:

    Code:
    
        private int slots = kitinv.firstEmpty();
    
        private ItemStack sk = new ItemStack(Material.DIAMOND_SWORD);
        private ItemStack ak = new ItemStack(Material.BOW);
    
        @EventHandler
        public void onOpenInv(PlayerInteractEvent e) {
            Player p = (Player)e.getPlayer();
          
      kits.add(sk);
            kits.add(ak);
             
       if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
                    for (ItemStack i : kits) {
                       
                        if (p.hasPermission("jkits.")) {
                           
                           
                                kitinv.setItem(slots, i);
                           
                        }
                    }
                    p.openInventory(kitinv);       
                } else {
                    return;
                }
    
    It's only showing the BOW in the first slot, but it's progress!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Aug 31, 2019
  18. Offline

    wand555

    Not quite sure if relative to the NPE, but you set the index in the loop only to the size of the inventory. You need to decrement the value after each loop.
    EDIT: firstEmpty returns -1 if the inventory is full, make sure to check that as well before setting an item to that index
     
  19. Offline

    KarimAKL

    @TerroDoor Because 'slots' returns 1 number higher than the highest number allowed. (9 instead of 8, etc.)
    Btw, you can use a for loop instead of an enhanced for loop.
     
    TerroDoor likes this.
  20. Offline

    wand555

    @KarimAKL Does this throw a NPE, thought this throws an ArrayIndexOutOfBoundsException
     
  21. Offline

    TerroDoor

    @KarimAKL thanks for your response, I''ve got myself super confused on this. Could you please explain how I could understand how to do this, thanks.
     
  22. Offline

    wand555

    @TerroDoor
    First of all, as Karim mentioned, you don't need an enhanced for loop, since you actually need the iterate variable.
    Code:
    for(int i=0; i<kits.size; i++) {
       if(p.hasPermission("jkits.") {
          if(kitinv.firstEmpty() != -1) {
             kitinv.setItem(kitinv.firstEmpty(), kits.get(i));
          }
       }
    }
    I don't know if that's what you want, because if it is, you could do it with the enhanced for loop as well.
    EDIT: Realised that what I wrote is basically just addItem(item) :/
     
    Last edited: Aug 31, 2019
  23. Offline

    TerroDoor

    @wand555 Thanks for the response, I was up really late last night trying to solve this and I just confused myself terribly. I just recently finished a 100+ series on Java and I'm slowly grasping onto it, appreciate your time also @timtower , @KarimAKL

    I will fiddle with this when I am back to my laptop, thanks.

    @wand555

    Here's what i've got so far. it adds the items based on perms. but if i open the inv again it stores the previous items and duplicates it.

    Code:
    
        private String[] perms = {"pvp, archer"};
       
        public String[] getPerms() {
       
            return perms;
        }
    
    
    here's the loop using your code above, i feel like it has something to do with the i++, correct me if im wrong as im stuck again, thanks!
    Code:
    
                    for(int i = 0; i < kits.size(); i++) {
                        if (p.hasPermission("jkits." + main.getPerms())) {
                           
                            kitinv.setItem(kitinv.firstEmpty(), kits.get(i));
                           
                        }
                    }
                }
                p.openInventory(kitinv);
                return;
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Sep 1, 2019
    KarimAKL likes this.
  24. Offline

    Strahan

    Move the variables to within the scope of the event function. This is a really weird way to do it anyway, as it requires you to recompile every time you want to modify the kit options. You should redo it using the config. I'd also refactor it to use negative checks, you can get rid of pointless indentation that way. No affect on anything, just makes it more readable IMO.

    Also you can't do the permissions like that, it won't work trying to append a String[] to a String as a node to be checked.

    PS here, to give you an idea here is a pseudocode of the class the way I'd prob do it:
    Code:
    public class PlayerInteract implements Listener {
      PluginMainObject plugin;
    
      PlayerInteract(PluginMainObject instance) {
        plugin = instance;
      }
    
      PlayerInteractEvent {
        Create Player variable
        Is the item in hand not a book?  Return
        Is the action not correct?  Return
        Is the config section for kits null?  Return
    
       Create the Inventory object
       Loop the kits config section keys {
         Does the player not have permission?  Continue
         Add an item to the kitinv, using the menuOption function to create the item
        }
        Open the inventory
      }
    
      ItemStack menuOption(String kit) {
        Create a material from the specified type in config, use barrier as default
        Create an ItemStack using that material
        Create an ItemMeta and give it a display name from config, kit name as default
        Set the ItemMeta to the ItemStack and return said ItemStack
      }
    }
    Using a config like:

    Code:
    kits:
      pvp:
        icon: DIAMOND_SWORD
        displayname: PVP - Slaughter your enemies
        items:
        (List<ItemStack> of the items in kit)
      archer:
        icon: BOW
        items:
        (List<ItemStack> of the items in kit)
    PS this only covers how I'd build the inv; this gives no consideration to functionality beyond that.
     
    Last edited: Sep 3, 2019

Share This Page