Decrease crafting result by one

Discussion in 'Spigot Plugin Development' started by MGlolenstine, Jul 11, 2019.

  1. Ok, so I'm working on a craft item detection, so when someone crafts, for example a cookie(in a set of 8), I'd like to remove one and give them the rest into the inventory.

    This is my current code, but it for some reason removes all items(of type iron when crafting a cauldron) from the inventory.

    Code (Java):
    @EventHandler
        public void OnInventoryChangeEvent(InventoryClickEvent e) {
            System.out.println("I'm detecting something!");
            if (e.getInventory().getHolder() instanceof Player) {
                ItemStack item = e.getCurrentItem();
                if (e.getClickedInventory() != null && (e.getClickedInventory().getType() == InventoryType.CRAFTING || e.getClickedInventory().getType() == InventoryType.WORKBENCH)) {
                    for (int i = 1; i < e.getClickedInventory().getSize(); i++) {
                        if (e.getSlot() == 0) {
                            ItemStack is = e.getClickedInventory().getItem(i);
                            if (is != null) {
                                e.getWhoClicked().sendMessage("Checking the " + is.getType() + " in slot " + i);
                                if (is.getAmount() != 0 && is.getType() != Material.AIR) {
                                    is.setAmount(is.getAmount() - 1);
                                    e.getClickedInventory().setItem(i, is);
                                }
                            }
                        } else {
                            return;
                        }
                    }
                }
                Player p = (Player) e.getInventory().getHolder();
                p.sendMessage("Your inventory is being checked for new items, please stand by!");
                if (item != null) {
                    p.sendMessage("Checking item " + item.getType().name() + ":" + item.getAmount());

                    if (checkForItem(item, p)) {
                        p.sendMessage("Item has been found and we're now removing it from your inventory");
                        item.setAmount(e.getCurrentItem().getAmount() - 1);
                    } else {
                        p.sendMessage("Item hasn't been found!");
                    }
                }
                e.getCursor().setType(item.getType());
                e.getCursor().setAmount(item.getAmount());
            }
        }
    Sometimes the item gets removed with no reason, if I move the item from one slot to another, the item just disappears.
     
  2. RandomHashTags

    Supporter

    Use the CraftItemEvent and set the result amount.
     
  3. That's all good and fine, but what if I only get one item in return? Won't that just not work, as you won't be able to click on the Air itemstack?
     
  4. From the title as well as most of your first post, that seems to be what you wanted. If you want someone to get something every time, just make sure to not change the result if its amount is already 1.
     
  5. Yes, that's true, but the thing is that I'm checking if someone crafted something already, which means that I'm only going to decrease amount the first time someone will craft said thing, but those items can be crafted multiple at the time and/or be 1 in a craft stack size.
    When the item is crafted, I want to remove one item from that crafted item stack. If the amount of items in that itemstack is 1, then the player gets nothing in return.

    I'm sorry if my rumbling is confusing.
     
  6. RandomHashTags

    Supporter

    Why would you want to craft something and not receive the item you crafted? Wouldn't you want to see the result before you craft it?
     
  7. You are correct... That's why I was checking when the item was moved to the inventory and not on the ItemCraftEvent. I have to remove an item and I was trying to get all events for inventorychange, but the code in the OP doesn't work as it should. That's why I posted my question here.

    Sent from my POCOPHONE F1 using Tapatalk
     
  8. You could just remove one in the general case.

    And if the amount is already 1, just add a custom tag (i.e one with a PersistentDataContainer) and remove the item from the inventory a tick later.
    You'll need to consider
    a) items on the cursor
    b) items in the inventory (shift clicks)
    c) items dropped to the ground (Q on the item - check for nearby entities and see if there's an Item that has a similar ItemStack)
     
  9. Thanks, just one more question. What happens, if, for example, I put in the crafting recipe enough iron for 10 hoppers and I shift-click? If I set the result of the crafting to what I'd get -1, wouldn't it set it to 0 and make me unable to get it out of the crafting table? Dayum... We really need a post craft event !


    Sent from my POCOPHONE F1 using Tapatalk
     
  10. No. If you've got enough stuff to make n items, in the result slot you'll still have just the one. Only if you shift click do you get multiple. So in that case you'll have to resort to moving one just like you would if they were crafting just the one item. If you do it correctly and just remove the one single item, you'll have 9 left instead of 10. I've even tested it to an extent.

    Bare in mind, I've only tested this to a certain extent. So if you create multiple ones and only remove the one, it might happen that the other items still have the NBT tag, i.e they might not stack with other similar items, so you might need to take care of that as well, not sure.
     
  11. Ok, another thought... I only want to remove items from the inventory. So I don't care about dropped items, as they'd get detected on pickup and I don't care about items on cursor, as I can detect items when they're put into the inventory. What would be the best way to detect when the item is put into the inventory?

    Sent from my POCOPHONE F1 using Tapatalk
     
  12. Listening to InventoryClickEvent. There are different types of clicks you'll need to consider and it's not all that trivial.

    However, I would strongly advise you to deal with the items when the need for it arises (i.e after the crafting) and not leaving some other (or even multiple) event(s) to deal with it.