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; } }
@timtower but what if i don't want them assigned to a slot, rather just placed before the non-permitted items?
@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
@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.
@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.
@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.
@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
@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); } }
@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.
@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?
@TerroDoor Config is the best option, or a custom class that contains the required information AND the kit info.
@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.
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
@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.
@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.
@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) :/
@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.
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.