Hello I am trying to check if player has 4 or more of an Item Stack then let them click an item in the GUI and get it. The GUI works. My if statement for checking is not working and I don't know what to do. Please help. Thank you My code: Code: package me.gladiator.betraysmp.events; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import java.util.Arrays; public class IngotGUIMain implements Listener { @EventHandler public void IngotGUIFunctions(InventoryClickEvent event) { ItemStack BetrayIngot = new ItemStack(Material.NETHERITE_INGOT); ItemMeta meta = BetrayIngot.getItemMeta(); meta.setDisplayName(ChatColor.LIGHT_PURPLE + "" + ChatColor.BOLD + "Betray Ingot"); meta.setLore(Arrays.asList("The Betray Ingot.", "Use 4 of these to craft a Ban Token.")); BetrayIngot.setItemMeta(meta); ItemStack shell = new ItemStack(Material.NAUTILUS_SHELL); ItemMeta shellmeta = shell.getItemMeta();shellmeta.setDisplayName(ChatColor.YELLOW + "" + ChatColor.BOLD + "Ban Token"); shellmeta.setLore(Arrays.asList("The Ban Token.", "Bans any player for 24 hours.")); shell.setItemMeta(shellmeta); ItemStack sea = new ItemStack(Material.HEART_OF_THE_SEA); ItemMeta seameta = sea.getItemMeta(); seameta.setDisplayName(ChatColor.BLUE + "" + ChatColor.BOLD + "Revive Token"); seameta.setLore(Arrays.asList("The Revive Token.", "Revives any player that is banned.")); sea.setItemMeta(seameta); Player player = (Player) event.getWhoClicked(); ClickType click = event.getClick(); ItemStack item = event.getCurrentItem(); Inventory inventory = event.getInventory(); if (event.getView().getTitle().equalsIgnoreCase(ChatColor.GOLD + "" + ChatColor.BOLD + "Betray Ingot Craft")) { if(BetrayIngot.getAmount() >= 4){ if (item.isSimilar(sea)) { event.setCancelled(true); player.closeInventory(); player.getInventory().addItem(sea); player.getInventory().removeItem(BetrayIngot); player.getInventory().removeItem(BetrayIngot); player.getInventory().removeItem(BetrayIngot); player.getInventory().removeItem(BetrayIngot); } if (item.isSimilar(shell)) { event.setCancelled(true); player.closeInventory();player.getInventory().addItem(shell); player.getInventory().removeItem(BetrayIngot); player.getInventory().removeItem(BetrayIngot); player.getInventory().removeItem(BetrayIngot); player.getInventory().removeItem(BetrayIngot);} } else if(BetrayIngot.getAmount() < 4){ player.sendMessage(ChatColor.RED + "You need 4 Betray Ingots to craft a token."); player.closeInventory();} } }
you are checking if "BetrayIngot" the Itemstack you just created is more or equal to 4 you need to check if "item" is more or equal to 4
if i understand you correctly you want check if a player has 1 item with the amount of 4 or more? if yes then you would need to check every slot in the player inventory and search for this itemstack if yes check if the itemstack has the amount you want and after that do what you want with it Code: if (event.getWhoClicked().getInventory().contains(BetrayIngot)) { // checks if player even has itemstack for (int i = 0; i < event.getInventory().getSize(); i++) { // loops through every slot if (event.getInventory().getItem(i).isSimilar(BetrayIngot)) { // if the slot is Similar to the itemstack if (event.getInventory().getItem(i).getAmount() >= 4) { // if the itemstack of the slot is equal or more than 4 event.getInventory().getItem(i).setAmount(event.getInventory().getItem(i).getAmount() - 4); // remove 4 from the itemstack // code here } } } } what you did here is check if the itemstack has the amount of 4 and even when you change BetrayIngot.getAmount() to click.getAmount() it won't work because you only look at the amount of the itemstack you clicked on i hope i don't miss something here
When I use this code it doesn't even check if you have 4 ingots or not. Here is my code: Code: package me.gladiator.betraysmp.events; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import java.util.Arrays; public class IngotGUIMain implements Listener { @EventHandler public void IngotGUIFunctions(InventoryClickEvent event) { ItemStack BetrayIngot = new ItemStack(Material.NETHERITE_INGOT); ItemMeta meta = BetrayIngot.getItemMeta(); meta.setDisplayName(ChatColor.LIGHT_PURPLE + "" + ChatColor.BOLD + "Betray Ingot"); meta.setLore(Arrays.asList("The Betray Ingot.", "Use 4 of these to craft a Ban Token.")); BetrayIngot.setItemMeta(meta); ItemStack shell = new ItemStack(Material.NAUTILUS_SHELL); ItemMeta shellmeta = shell.getItemMeta(); shellmeta.setDisplayName(ChatColor.YELLOW + "" + ChatColor.BOLD + "Ban Token"); shellmeta.setLore(Arrays.asList("The Ban Token.", "Bans any player for 24 hours.")); shell.setItemMeta(shellmeta); ItemStack sea = new ItemStack(Material.HEART_OF_THE_SEA); ItemMeta seameta = sea.getItemMeta(); seameta.setDisplayName(ChatColor.BLUE + "" + ChatColor.BOLD + "Revive Token"); seameta.setLore(Arrays.asList("The Revive Token.", "Revives any player that is banned.")); sea.setItemMeta(seameta); Player player = (Player) event.getWhoClicked(); ClickType click = event.getClick(); ItemStack item = event.getCurrentItem(); Inventory inventory = event.getInventory(); if (event.getView().getTitle().equalsIgnoreCase(ChatColor.GOLD + "" + ChatColor.BOLD + "Betray Ingot Craft")) { if (event.getWhoClicked().getInventory().contains(BetrayIngot)) { for (int i = 0; i < event.getInventory().getSize(); i++) { if (event.getInventory().getItem(i).isSimilar(BetrayIngot)) { if (event.getInventory().getItem(i).getAmount() >= 4) { event.getInventory().getItem(i).setAmount(event.getInventory().getItem(i).getAmount() - 4); if (item.isSimilar(sea)) { event.setCancelled(true); player.closeInventory(); player.getInventory().addItem(sea); } if (item.isSimilar(shell)) { event.setCancelled(true); player.closeInventory(); player.getInventory().addItem(shell); } } } else if (event.getInventory().getItem(i).getAmount() <= 4) { player.sendMessage(ChatColor.RED + "You need 4 Betray Ingots to craft a token."); player.closeInventory(); } } } } } }
This is wrong, read edit.-----------------------------(The method getInventory().contains() won't trigger since you are you are creating a new ItemStack object every time on click so even though they have the same name/material/lore etc. contains() method won't trigger since they are different objects. So in your case the code doesn't get to the loop.------------------------------------ EDIT: I am wrong, I thought that the class for ItemStack does not override equals() and hashCode() but it does. Your problem here is that when you do contains() it uses the method equals() from the respective object which in our case (ItemStack) looks like this. Code: public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof ItemStack)) { return false; } ItemStack stack = (ItemStack) obj; return getAmount() == stack.getAmount() && isSimilar(stack); } As you can see it also checks for amount, so when you create BetrayIngot it has it's default amount value set to 1 and if you have 4 ingot stacked together in your inventory than contains(BetrayIngot) returns false but if you were to only have 1 ingot it will return true; So this check is useless in your case Code: if (event.getWhoClicked().getInventory().contains(BetrayIngot)) What you want to do is to create a new int variable and loop though the contents of the player's inventory and then check if the item isn't null and the item.isSimilar(yourItem) if it is then add the amount of the respective item to your newly created variable and also check if the value if >= 4 and if it than you can break the loop and continue your code. Here is an example Code: ItemStack[] contents = player.getInventory().getContents(); int value = 0; for(ItemStack item : contents) { if(item == null || !item.isSimilar(yourItem)) continue; value += item.getAmount(); if(value >= 4) break; } if(value < 4) return; //Your code Also I recommend that you don't create the items every single time on click and that you create them in a separate class once at the start of the server and use the same ItemStack for everything else.)
If you use a stream, you can distill all that down: Code: int total = player.getInventory().all(BetrayIngot.getType()).entrySet().stream() .filter(o -> o.getValue().isSimilar(BetrayIngot)) .mapToInt(o -> o.getValue().getAmount()).sum();