Posted November 14, 20169 yr I want to make crafting recipes that require some of the input ItemStacks to have a stack size of greater than 1. I've worked out how to check the stack sizes when checking if the craft matrix matches the recipe, but I have no idea what to do with getRemainingItems . Looking at the forge vanilla code, I can't figure out what the ForgeHooks.getContainerItem method does, or how to adjust it so that the remaining items have the required stack size subtracted. I'm sure I've seen someone write about making crafting recipes with non-one stack sizes before but I can't find anything now. Can anyone advise and/or link me to somewhere it's been done? My custom recipe class is here. It correctly detects whether the input ItemStacks are large enough (the output slot only shows the output when they are), but when I click on the output the crafting grid slots don't seem to change correctly. package com.jj.jjmod.crafting; import java.util.Arrays; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.world.World; public class ShapedRecipe extends ShapedRecipes { public ShapedRecipe(int width, int height, ItemStack[] inputs, ItemStack output) { super(width, height, inputs, output); } @Override public boolean matches(InventoryCrafting inv, World worldIn) { for (int i = 0; i <= inv.getWidth() - this.recipeWidth; i++) { for (int j = 0; j <= inv.getHeight() - this.recipeHeight; j++) { if (this.checkMatch(inv, i, j, true) || this.checkMatch(inv, i, j, false)) { return true; } } } return false; } private boolean checkMatch(InventoryCrafting inv, int a, int b, boolean flag) { for (int i = 0; i < inv.getWidth(); ++i) { for (int j = 0; j < inv.getHeight(); ++j) { int k = i - a; int l = j - b; ItemStack required = null; if (k >= 0 && l >= 0 && k < this.recipeWidth && l < this.recipeHeight) { if (flag) { required = this.recipeItems[this.recipeWidth - k - 1 + l * this.recipeWidth]; } else { required = this.recipeItems[k + l * this.recipeWidth]; } } ItemStack inInv = inv.getStackInRowAndColumn(i, j); if (inInv != null || required != null) { if (inInv == null && required != null || inInv != null && required == null) { return false; } if (required.getItem() != inInv.getItem()) { return false; } if (required.getMetadata() != 32767 && required.getMetadata() != inInv.getMetadata()) { return false; } if (required.stackSize > inInv.stackSize) { return false; } } } } return true; } } Edit: I think I've solved this, although I don't know if it's the best way I could have done it (I suspect it's very much not). I made a new method in my custom recipe class that returns an array of ints representing how many items from each input stack should be used up. (The code is more or less the same as the way it checks for a matching recipe in the first place, because it has to find the recipe's position in the grid and then check each slot individually). Then I call that in my custom crafting slot's onPickupFromSlot (the same place where getRemainingItems is called) and use it to decrease the crafting grid stack sizes. Here is the code of my new method: public int[] getAmountsUsed(InventoryCrafting inv) { int a = -1; int b = -1; boolean flag = true; outer: for (int i = 0; i <= inv.getWidth() - this.recipeWidth; i++) { for (int j = 0; j <= inv.getHeight() - this.recipeHeight; j++) { if (this.checkMatch(inv, i, j, true)) { a = i; b = j; flag = true; break outer; } if (this.checkMatch(inv, i, j, false)) { a = i; b = j; flag = false; break outer; } } } int[] amounts = new int[inv.getSizeInventory()]; for (int i = 0; i < inv.getWidth(); ++i) { for (int j = 0; j < inv.getHeight(); ++j) { int k = i - a; int l = j - b; int amount = (j * inv.getWidth()) + i; amounts[amount] = 0; if (k >= 0 && l >= 0 && k < this.recipeWidth && l < this.recipeHeight) { if (flag) { amounts[amount] = this.recipeItems[this.recipeWidth - k - 1 + l * this.recipeWidth].stackSize; } else { amounts[amount] = this.recipeItems[k + l * this.recipeWidth].stackSize; } } } } return amounts; } Like I said I have no idea if this is a good way to do it. It seems to work, but although it seems really messy I can't think of a better way at the moment. If anyone has any ideas please let me know.
November 14, 20169 yr Author Oh I should have said, I'm not using the vanilla crafting table. I've got custom crafting blocks as well as a custom inventory container with a crafting grid. Is it possible to do non-one stack size inputs with that?
November 14, 20169 yr Author So it can't be done using the vanilla InventoryCrafting class, you mean? I'm using my own CraftingManager , but with vanilla InventoryCrafting classes for the crafting grids. I forgot about github but all my code is there (link). Here is my CraftingManager class, and here is one of my containers which uses it.
November 14, 20169 yr Author I know that's what I need to do, I'm looking for advice on how to do it!
November 14, 20169 yr Author On how to implement getRemainingItems to use up more than one of the input ItemStack. It seems to be intended only for things like buckets where one item replaces another. But the reduction in stack size of the input items is actually done in SlotCrafting#onPickupFromSlot . So I need some way to get the information about which input stacks are reduced by which amounts (including the potential for the recipe to be in different positions in the crafting grid), and send that back to the crafting slot (which I have extended with my own class so I can do what I want there) to update it when the output is removed. Maybe a new method in my recipe that's like getRemainingItems but returns an array of ints to subtract from the input stack sizes? The trouble is, getRemainingItems just checks the items individually so the positioning of the recipe is irrelevant. But I'd ideally like to be able to have a recipe requiring any amount of different-sized stacks of the same or different items, which would mean somehow checking the input grid to find the exact position of the recipe, getting the stack size reductions, and then converting that to the size and shape of the crafting grid before returning it to be used by the slot. Seems a bit excessive but I can't think of a simpler way at the moment.
November 15, 20169 yr Author Oh I misspoke, I didn't extend SlotCrafting - I just have my own custom output Slot.
November 15, 20169 yr Author Oh well, maybe I didn't explain myself clearly enough. In any case, I think I've solved my own problem now. I'll probably post my code tomorrow in case anyone else wants it, although my solution isn't very elegant.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.