MeskenasBoii
Member
How to check for a specific item in the inventory? Then have that item be removed?
// Nothing too crazy.
PlayerInventory playerInventory = player.getInventory();
// Get the player's inventory and establish our desired target item.
PlayerInventory playerInventory = player.getInventory();
ItemStack targetItem = new ItemStack(Material.STONE);
// Loop through the player's inventory to find the target item.
for (int x = 0; x < playerInventory.getSize(); x++) {
// The current item in the player's inventory.
ItemStack currentItem = playerInventory.getItem(x);
// Check if the current item is equal to our target item.
if (currentItem != null && currentItem.isSimilar(targetItem)) {
// It is, Store what the current item's amount will be after removing one item.
int itemAmount = currentItem.getAmount() - 1;
// Check if the current item's amount will be less than zero after removing one item.
if (itemAmount > 0) {
// It will not, set the new amount.
currentItem.setAmount(itemAmount);
} else {
// It will, remove the item from the player's inventory.
playerInventory.setItem(x, null);
}
// Update the player's inventory and stop looping.
player.updateInventory();
break;
}
}
THIS is how to properly help somebody. *cough* ;3;Firstly, take a look at some of the Spigot JavaDocs. They are very helpful and will show you what you have access to.
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/HumanEntity.html#getInventory--
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/PlayerInventory.html
Accessing an Inventory can be a little different between an Entity, like a Player, and a Tile Entity, like a chest. I assume you want to do something with an ability and therefore are looking to access a Player's Inventory. It is fairly easy to do and is shown below.
The overall process for removing an item from an inventory is as followsCode:// Nothing too crazy. PlayerInventory playerInventory = player.getInventory();
- Get the players inventory.
- Look through that inventory for the first occurrence of your target item.
- Remove that item from the inventory.
Ok, now that we have the overall process defined let's think of what we need to keep track of
- A Player to get the inventory of.
- A PlayerInventory to store the player's inventory.
- An ItemStack to store our target item.
- An ItemStack to store our current item as we loop through the PlayerInventory.
- An int to store our loops index.
- An int to store the current item's amount.
Great, if that all makes sense then let's look at the implementation.
Code:// Get the player's inventory and establish our desired target item. PlayerInventory playerInventory = player.getInventory(); ItemStack targetItem = new ItemStack(Material.STONE); // Loop through the player's inventory to find the target item. for (int x = 0; x < playerInventory.getSize(); x++) { // The current item in the player's inventory. ItemStack currentItem = playerInventory.getItem(x); // Check if the current item is equal to our target item. if (currentItem != null && currentItem.isSimilar(targetItem)) { // It is, Store what the current item's amount will be after removing one item. int itemAmount = currentItem.getAmount() - 1; // Check if the current item's amount will be less than zero after removing one item. if (itemAmount > 0) { // It will not, set the new amount. currentItem.setAmount(itemAmount); } else { // It will, remove the item from the player's inventory. playerInventory.setItem(x, null); } // Update the player's inventory and stop looping. player.updateInventory(); break; } }
Sidenote: To search for a specific item you will need to have that item defined somewhere in your code to make comparisons with. For now, I will assume you have that defined and I will refer to that ItemStack as the "targetItem".
I probably skip through the bunch of what you said, because right now my eyes to lazy to read. So If there is alreadya question to my following question, I apologize in advance: That looks like it loops through the quantity of the item per its stack, doesn't it? If so, I don't wanna spend my time on it when I'm checking for a item that can't be stacked. Is there another way of simply removing that item?Code:// Get the player's inventory and establish our desired target item. PlayerInventory playerInventory = player.getInventory(); ItemStack targetItem = new ItemStack(Material.STONE); // Loop through the player's inventory to find the target item. for (int x = 0; x < playerInventory.getSize(); x++) { // The current item in the player's inventory. ItemStack currentItem = playerInventory.getItem(x); // Check if the current item is equal to our target item. if (currentItem != null && currentItem.isSimilar(targetItem)) { // It is, Store what the current item's amount will be after removing one item. int itemAmount = currentItem.getAmount() - 1; // Check if the current item's amount will be less than zero after removing one item. if (itemAmount > 0) { // It will not, set the new amount. currentItem.setAmount(itemAmount); } else { // It will, remove the item from the player's inventory. playerInventory.setItem(x, null); } // Update the player's inventory and stop looping. player.updateInventory(); break; } }
If you think about it, contains is doing almost exactly the same thing we are doing above. Let's compare the logic path of both.What about using player.getInventory().contains ? Does that do any wonders?
if (player.getInventory().contains(targetItem)) {
// Code
}
// Same as above //
boolean hasItem = false;
for (int x = 0; x < playerInventory.getSize(); x++) {
ItemStack currentItem = playerInventory.getItem(x);
if ((currentItem == null && targetItem == null) || (currentItem != null && currentItem.isSimilar(targetItem))) {
hasItem = true;
}
}
if (hasItem) {
// Code
}
Wow.... Such an inspiration <3If you think about it, contains is doing almost exactly the same thing we are doing above. Let's compare the logic path of both.
Contains: Loop through a collection, as we loop we check if we find a given Object, return true if found, return false if we reach the end.
Search and Remove: Loop through a collection, as we loop we check if we find a given Object, remove one if found.
We could easily add a contains check before our for loop but doing so makes our code slower because we are essentially doing two of the three steps over again. Remember, just because a method is built in does not mean it is faster or possibly better than something you could do on your own. You want to look at a method as what it does and how it does it.
Code:if (player.getInventory().contains(targetItem)) { // Code } // Same as above // boolean hasItem = false; for (int x = 0; x < playerInventory.getSize(); x++) { ItemStack currentItem = playerInventory.getItem(x); if ((currentItem == null && targetItem == null) || (currentItem != null && currentItem.isSimilar(targetItem))) { hasItem = true; } } if (hasItem) { // Code }
Close, you would want to use currentItem. The targetItem variable is only used to compare against the player's inventory items.Ok, so I'm not making an ability, but a command plugin.
Another question unrelated, but how would I go about the loop adding enchantments to the items? Would I have to use targetItem.addEnchantment(**) where the substraction should take place and skip the rest with the if statement?