Posted February 28, 20169 yr Hello all! I have working on a customer 4x4 crafting table that I am working on updating to 1.8 from 1.7. Everything seems to be order with the exception that when I craft an items it does not remove the source items once the item is crafted. I have included my container and crafting manager class below. Any direction on where I should proceed would be greatly appreciated. Container: package com.tiredguy.mod.container; import com.tiredguy.mod.blocks.TGBlocks; import com.tiredguy.mod.crafting.DraftingBoardCraftingManager; import com.tiredguy.mod.slot.TGSlotDraftingBoard; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.util.BlockPos; import net.minecraft.world.World; public class ContainerDraftingBoard extends Container { /** The crafting matrix inventory (3x3). */ public InventoryCrafting craftMatrix = new InventoryCrafting(this, 4, 4); public IInventory craftResult = new InventoryCraftResult(); private World worldObj; /** Position of the workbench */ private BlockPos pos; public ContainerDraftingBoard(InventoryPlayer invPlayer, World worldIn, BlockPos pos) { this.worldObj = worldIn; this.addSlotToContainer(new SlotCrafting(invPlayer.player, this.craftMatrix, this.craftResult, 0, 141, 43)); for (int i = 0; i < 4; i++) { for(int k = 0; k < 4; k++) { this.addSlotToContainer(new Slot(craftMatrix, k + i * 4, 8 + k * 18, 7 + i * 18)); } } for (int i = 0; i < 3; i++) { for(int k = 0; k < 9; k++) { this.addSlotToContainer(new Slot(invPlayer, k + i * 9 + 9, 8 + k * 18, 106 + i * 18)); } } for (int i = 0; i < 9; i++) { this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 164)); } onCraftMatrixChanged(craftMatrix); } public ContainerDraftingBoard(InventoryPlayer invPlayer, World worldIn, int x, int y, int z) { this.worldObj = worldIn; this.addSlotToContainer(new SlotCrafting(invPlayer.player, this.craftMatrix, this.craftResult, 0, 141, 43)); for (int i = 0; i < 4; i++) { for(int k = 0; k < 4; k++) { this.addSlotToContainer(new Slot(craftMatrix, k + i * 4, 8 + k * 18, 7 + i * 18)); } } for (int i = 0; i < 3; i++) { for(int k = 0; k < 9; k++) { this.addSlotToContainer(new Slot(invPlayer, k + i * 9 + 9, 8 + k * 18, 106 + i * 18)); } } for (int i = 0; i < 9; i++) { this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 164)); } onCraftMatrixChanged(craftMatrix); } public void onCraftMatrixChanged(IInventory inventoryIn) { this.craftResult.setInventorySlotContents(0, DraftingBoardCraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); } public void onContainerClosed(EntityPlayer playerIn) { super.onContainerClosed(playerIn); if (!this.worldObj.isRemote) { for (int i = 0; i < 9; ++i) { ItemStack itemstack = this.craftMatrix.removeStackFromSlot(i); if (itemstack != null) { playerIn.dropPlayerItemWithRandomChoice(itemstack, false); } } } } @Override public boolean canInteractWith(EntityPlayer playerIn) { return this.craftResult.isUseableByPlayer(playerIn); //return this.worldObj.getBlockState(this.pos).getBlock() != NGBlocks.draftingTable ? false : playerIn.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; } /** * Take a stack from the specified inventory slot. */ public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack itemstack = null; Slot slot = (Slot)this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index == 0) { if (!this.mergeItemStack(itemstack1, 10, 46, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } else if (index >= 10 && index < 37) { if (!this.mergeItemStack(itemstack1, 37, 46, false)) { return null; } } else if (index >= 37 && index < 46) { if (!this.mergeItemStack(itemstack1, 10, 37, false)) { return null; } } else if (!this.mergeItemStack(itemstack1, 10, 46, false)) { return null; } if (itemstack1.stackSize == 0) { slot.putStack((ItemStack)null); } else { slot.onSlotChanged(); } if (itemstack1.stackSize == itemstack.stackSize) { return null; } slot.onPickupFromSlot(playerIn, itemstack1); } return itemstack; } /** * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in * is null for the initial slot that was double-clicked. */ public boolean canMergeSlot(ItemStack stack, Slot p_94530_2_) { return p_94530_2_.inventory != this.craftResult && super.canMergeSlot(stack, p_94530_2_); } } CraftingManager: package com.tiredguy.mod.crafting; import java.util.Collections; import java.util.List; import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.tiredguy.mod.items.TGItems; import net.minecraft.block.Block; import net.minecraft.init.Items; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.ShapedRecipes; import net.minecraft.item.crafting.ShapelessRecipes; import net.minecraft.world.World; public class DraftingBoardCraftingManager { /** The static instance of this class */ private static final DraftingBoardCraftingManager instance = new DraftingBoardCraftingManager(); private final List<IRecipe> recipes = Lists.<IRecipe>newArrayList(); /** * Returns the static instance of this class */ public static DraftingBoardCraftingManager getInstance() { /** The static instance of this class */ return instance; } public DraftingBoardCraftingManager() { this.addRecipe(new ItemStack(TGItems.ironHammer, 1), new Object[] { "IIII", "IZZI", " ZZ ", " ZZ ", 'I', Items.iron_ingot, 'Z', TGItems.zincIngot}); Collections.sort(this.recipes, new DraftingBoardRecipeSorter(this)); } /** * Adds a shaped recipe to the games recipe list. */ public DraftingBoardShapedRecipes addRecipe(ItemStack stack, Object... recipeComponents) { String s = ""; int i = 0; int j = 0; int k = 0; if (recipeComponents[i] instanceof String[]) { String[] astring = (String[])((String[])recipeComponents[i++]); for (int l = 0; l < astring.length; ++l) { String s2 = astring[l]; ++k; j = s2.length(); s = s + s2; } } else { while (recipeComponents[i] instanceof String) { String s1 = (String)recipeComponents[i++]; ++k; j = s1.length(); s = s + s1; } } Map<Character, ItemStack> map; for (map = Maps.<Character, ItemStack>newHashMap(); i < recipeComponents.length; i += 2) { Character character = (Character)recipeComponents[i]; ItemStack itemstack = null; if (recipeComponents[i + 1] instanceof Item) { itemstack = new ItemStack((Item)recipeComponents[i + 1]); } else if (recipeComponents[i + 1] instanceof Block) { itemstack = new ItemStack((Block)recipeComponents[i + 1], 1, 32767); } else if (recipeComponents[i + 1] instanceof ItemStack) { itemstack = (ItemStack)recipeComponents[i + 1]; } map.put(character, itemstack); } ItemStack[] aitemstack = new ItemStack[j * k]; for (int i1 = 0; i1 < j * k; ++i1) { char c0 = s.charAt(i1); if (map.containsKey(Character.valueOf(c0))) { aitemstack[i1] = ((ItemStack)map.get(Character.valueOf(c0))).copy(); } else { aitemstack[i1] = null; } } DraftingBoardShapedRecipes shapedrecipes = new DraftingBoardShapedRecipes(j, k, aitemstack, stack); this.recipes.add(shapedrecipes); return shapedrecipes; } /** * Adds a shapeless crafting recipe to the the game. */ public void addShapelessRecipe(ItemStack stack, Object... recipeComponents) { List<ItemStack> list = Lists.<ItemStack>newArrayList(); for (Object object : recipeComponents) { if (object instanceof ItemStack) { list.add(((ItemStack)object).copy()); } else if (object instanceof Item) { list.add(new ItemStack((Item)object)); } else { if (!(object instanceof Block)) { throw new IllegalArgumentException("Invalid shapeless recipe: unknown type " + object.getClass().getName() + "!"); } list.add(new ItemStack((Block)object)); } } this.recipes.add(new ShapelessRecipes(stack, list)); } /** * Adds an IRecipe to the list of crafting recipes. */ public void addRecipe(IRecipe recipe) { this.recipes.add(recipe); } /** * Retrieves an ItemStack that has multiple recipes for it. */ public ItemStack findMatchingRecipe(InventoryCrafting p_82787_1_, World worldIn) { for (IRecipe irecipe : this.recipes) { if (irecipe.matches(p_82787_1_, worldIn)) { return irecipe.getCraftingResult(p_82787_1_); } } return null; } public ItemStack[] func_180303_b(InventoryCrafting p_180303_1_, World worldIn) { for (IRecipe irecipe : this.recipes) { if (irecipe.matches(p_180303_1_, worldIn)) { return irecipe.getRemainingItems(p_180303_1_); } } ItemStack[] aitemstack = new ItemStack[p_180303_1_.getSizeInventory()]; for (int i = 0; i < aitemstack.length; ++i) { aitemstack[i] = p_180303_1_.getStackInSlot(i); } return aitemstack; } public List<IRecipe> getRecipeList() { return this.recipes; } }
February 28, 20169 yr Author It looks like SlotCrafting has some protected methods. Should I create my own slot class for it?
February 28, 20169 yr Yes, you would need to, but in the custom slot replace the CraftingManager#getInstance#func_180303_b with you CraftingManager equivalent method.
February 28, 20169 yr Author I updated the Crafting Manager and I am getting a different behavior now. Error Log: Description: Updating screen events java.lang.NullPointerException: Updating screen events at com.nealegaming.mod.slot.NGSlotDraftingBoard.onPickupFromSlot(NGSlotDraftingBoard.java:88) at net.minecraft.inventory.Container.slotClick(Container.java:334) at net.minecraft.client.multiplayer.PlayerControllerMP.windowClick(PlayerControllerMP.java:535) at net.minecraft.client.gui.inventory.GuiContainer.handleMouseClick(GuiContainer.java:679) at net.minecraft.client.gui.inventory.GuiContainer.mouseClicked(GuiContainer.java:421) at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:620) at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:586) at net.minecraft.client.Minecraft.runTick(Minecraft.java:1761) at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1080) at net.minecraft.client.Minecraft.run(Minecraft.java:380) at net.minecraft.client.main.Main.main(Main.java:116) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:26) NGSlotDraftingBoard: package com.tiredguy.mod.slot; import com.tiredguy.mod.crafting.DraftingBoardCraftingManager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.stats.AchievementList; public class NGSlotDraftingBoard extends Slot { /** The craft matrix inventory linked to this result slot. */ private final InventoryCrafting craftMatrix; /** The player that is using the GUI where this slot resides. */ private final EntityPlayer thePlayer; /** The number of items that have been crafted so far. Gets passed to ItemStack.onCrafting before being reset. */ private int amountCrafted; public NGSlotDraftingBoard(EntityPlayer player, InventoryCrafting craftingInventory, IInventory p_i45790_3_, int slotIndex, int xPosition, int yPosition) { super(p_i45790_3_, slotIndex, xPosition, yPosition); this.thePlayer = player; this.craftMatrix = craftingInventory; } /** * Check if the stack is a valid item for this slot. Always true beside for the armor slots. */ public boolean isItemValid(ItemStack stack) { return false; } /** * Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new * stack. */ public ItemStack decrStackSize(int amount) { if (this.getHasStack()) { this.amountCrafted += Math.min(amount, this.getStack().stackSize); } return super.decrStackSize(amount); } /** * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood. Typically increases an * internal count then calls onCrafting(item). */ public void onCrafting(ItemStack stack, int amount) { this.amountCrafted += amount; this.onCrafting(stack); } /** * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not ore and wood. */ public void onCrafting(ItemStack stack) { if (this.amountCrafted > 0) { stack.onCrafting(this.thePlayer.worldObj, this.thePlayer, this.amountCrafted); } this.amountCrafted = 0; } public void onPickupFromSlot(EntityPlayer playerIn, ItemStack stack) { net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerCraftingEvent(playerIn, stack, craftMatrix); this.onCrafting(stack); net.minecraftforge.common.ForgeHooks.setCraftingPlayer(playerIn); ItemStack[] aitemstack = DraftingBoardCraftingManager.getInstance().func_180303_b(craftMatrix, playerIn.worldObj); net.minecraftforge.common.ForgeHooks.setCraftingPlayer(null); for (int i = 0; i < aitemstack.length; ++i) { ItemStack itemstack = this.craftMatrix.getStackInSlot(i); ItemStack itemstack1 = aitemstack[i]; if (itemstack != null) { this.craftMatrix.decrStackSize(i, 1); } if (itemstack1 != null) { if (this.craftMatrix.getStackInSlot(i) == null) { this.craftMatrix.setInventorySlotContents(i, itemstack1); } else if (!this.thePlayer.inventory.addItemStackToInventory(itemstack1)) { this.thePlayer.dropPlayerItemWithRandomChoice(itemstack1, false); } } } } } I can't seem to figure out what is null.
February 28, 20169 yr Your DraftingBoardCraftingManager#func_180303_b returns null , which returns in a NullPointerException[code] when trying to call [code][code]aitemstack.length . BTW, you could've figured this out yourself by looking at the things which can be null on line 88. Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support. 1.12 -> 1.13 primer by williewillus. 1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support. http://www.howoldisminecraft1710.today/
March 2, 20169 yr Author I ran a breakpoint and I can see where the aitemstack is coming up empty, but I can't figure out why. Is there something wrong in my crafting manager that isn't adding the recipe? I backtracked func_180303_b and the best I can guess is that it's empty.
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.