[SPIGOT-1009] Crafting items using shift causes insufficient CraftItemEvent Created: 29/Jun/15 Updated: 24/Jun/20 |
|
Status: | Open |
Project: | Spigot |
Component/s: | None |
Affects Version/s: | None |
Fix Version/s: | None |
Type: | Bug | Priority: | Minor |
Reporter: | Lukas | Assignee: | Unassigned |
Resolution: | Unresolved | Votes: | 4 |
Labels: | Craftbukkit, bug, event | ||
Environment: |
Windows 7 with Java JDK 8 |
Attachments: |
![]() ![]() |
Description |
Look at the attachements for example. I've got two iron ingots and two flints in my crafting menu. Now using shift + left click crafts two flint and steel. But there is only 1 CraftItemEvent called having the following content:
I've also tested it with torches producing the same bug. That is a problem if you want to modify every item beeing crafted, like reducing durability of flint and steel. |
Comments |
Comment by YourCoal [ 24/Jun/20 ] |
I think it would be best if there was some sort of way to call the event multiple times perhaps when items are crafted, or if there was some way to detect the multiple stacks resulted, like multiple pickaxes, have a List of ItemStacks. |
Comment by Foorcee [ 25/Feb/20 ] |
|
Comment by Foorcee [ 23/Feb/20 ] |
The issue still exists. |
Comment by lizardfreak321 [ 01/Aug/16 ] |
I was able to manually calculate how many there would be, but just in case I got it wrong I canceled the event and re-implemented the features that shift-click does. This is how I do it: int numberOfItems = originalResult.getAmount(); if (event.isShiftClick()) { // Looks for the ingredient with the lowest amount. int itemsChecked = 0; for (ItemStack item : event.getInventory().getMatrix()) { if (item != null && !item.getType().equals(Material.AIR)) { if (itemsChecked == 0) numberOfItems = item.getAmount(); else numberOfItems = Math.min(numberOfItems, item.getAmount()); itemsChecked++; } } // Cancels it because this plugin is taking over. event.setResult(Result.DENY); event.setCancelled(true); int number = compatibleSlots(originalResult, event.getWhoClicked().getInventory()); // There needs to be enough room to put these items, so it checks which one is numberOfItems = Math.min(number, numberOfItems * originalResult.getAmount()); // Adds the items to the user's inventory here } public int compatibleSlots(ItemStack compatibleWith, Inventory inv) { int slots = 0; for (int i = 0; i < inv.getSize(); i++) { if (inv.getItem(i) == null || inv.getItem(i).getType().equals(Material.AIR)) slots += compatibleWith.getMaxStackSize(); else if (isCompatible(compatibleWith, inv.getItem(i))) slots += (compatibleWith.getMaxStackSize() - inv.getItem(i).getAmount()); } return slots; } My code works but it is far from perfect. If there was some easy way to get how many items Minecraft's code intends to do, it would be better since I can imagine there being times where my code is inaccurate. That is why I completely redid the craft item event on shift, because my code cannot afford any inaccuracies. |
Comment by PixelPerfect [ 16/Jul/16 ] |
Might be worth sticking a PostCraftItemEvent on which could contain a function for getting how many items were crafted and another returning a list of slots they went to. From that, multiple easy workarounds would be possible. |
Comment by md_5 [ 11/Jul/16 ] |
Right so this is due to a design flaw in the CraftItemEvent which returns what is in the slot which you clicked. Also Minecraft uses a recursive implementation, so it doesn't know how much it can craft ahead of time :\ |
Comment by Lukas [ 07/Jul/15 ] |
In some cases, there might be a workaround. In my case, i wanted to set durability to each flint and steel ever crafted. So i can iterate through the whole inventory after each crafting process: } |