
tompinn23
Forge Modder-
Posts
13 -
Joined
-
Last visited
Converted
-
Gender
Undisclosed
-
Personal Text
I am new!
tompinn23's Achievements

Tree Puncher (2/8)
0
Reputation
-
[1.11.2] Crash when trying to open my custom gui. [Solved]
tompinn23 replied to tompinn23's topic in Modder Support
Thanks -
Hi I have created a custom furnace but when i try to open the gui i get this crash here is my code. ---- Minecraft Crash Report ---- // This doesn't make any sense! Time: 1/11/17 8:58 PM Description: Ticking player java.lang.NullPointerException: Ticking player at net.minecraft.item.ItemStack.areItemStacksEqual(ItemStack.java:442) at net.minecraft.inventory.Container.detectAndSendChanges(Container.java:89) at com.github.tompinn23.tprocessing.gui.ContainerTFurnace.detectAndSendChanges(ContainerTFurnace.java:162) at net.minecraft.entity.player.EntityPlayerMP.onUpdate(EntityPlayerMP.java:318) at net.minecraft.world.World.updateEntityWithOptionalForce(World.java:2108) at net.minecraft.world.WorldServer.updateEntityWithOptionalForce(WorldServer.java:875) at net.minecraft.world.World.updateEntity(World.java:2075) at net.minecraft.world.WorldServer.tickPlayers(WorldServer.java:676) at net.minecraft.world.World.updateEntities(World.java:1864) at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:647) at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:794) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:698) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:547) at java.lang.Thread.run(Thread.java:745) A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Server thread Stacktrace: at net.minecraft.item.ItemStack.areItemStacksEqual(ItemStack.java:442) at net.minecraft.inventory.Container.detectAndSendChanges(Container.java:89) at com.github.tompinn23.tprocessing.gui.ContainerTFurnace.detectAndSendChanges(ContainerTFurnace.java:162) at net.minecraft.entity.player.EntityPlayerMP.onUpdate(EntityPlayerMP.java:318) at net.minecraft.world.World.updateEntityWithOptionalForce(World.java:2108) at net.minecraft.world.WorldServer.updateEntityWithOptionalForce(WorldServer.java:875) at net.minecraft.world.World.updateEntity(World.java:2075) -- Player being ticked -- Details: Entity Type: null (net.minecraft.entity.player.EntityPlayerMP) Entity ID: 71 Entity Name: Player76 Entity's Exact location: 1173.95, 4.00, -1346.13 Entity's Block location: World: (1173,4,-1347), Chunk: (at 5,0,13 in 73,-85; contains blocks 1168,0,-1360 to 1183,255,-1345), Region: (2,-3; contains chunks 64,-96 to 95,-65, blocks 1024,0,-1536 to 1535,255,-1025) Entity's Momentum: 0.00, -0.08, 0.00 Entity's Passengers: [] Entity's Vehicle: ~~ERROR~~ NullPointerException: null Stacktrace: at net.minecraft.world.WorldServer.tickPlayers(WorldServer.java:676) at net.minecraft.world.World.updateEntities(World.java:1864) at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:647) -- Affected level -- Details: Level name: New World All players: 1 total; [EntityPlayerMP['Player76'/71, l='New World', x=1173.95, y=4.00, z=-1346.13]] Chunk stats: ServerChunkCache: 657 Drop: 0 Level seed: -4789802384015756941 Level generator: ID 01 - flat, ver 0. Features enabled: true Level generator options: Level spawn location: World: (1179,4,-1250), Chunk: (at 11,0,14 in 73,-79; contains blocks 1168,0,-1264 to 1183,255,-1249), Region: (2,-3; contains chunks 64,-96 to 95,-65, blocks 1024,0,-1536 to 1535,255,-1025) Level time: 31784 game time, 3208 day time Level dimension: 0 Level storage version: 0x04ABD - Anvil Level weather: Rain time: 54992 (now: false), thunder time: 9323 (now: true) Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: true Stacktrace: at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:794) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:698) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:547) at java.lang.Thread.run(Thread.java:745) -- System Details -- Details: Minecraft Version: 1.11.2 Operating System: Windows 10 (amd64) version 10.0 Java Version: 1.8.0_111, Oracle Corporation Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation Memory: 1007328424 bytes (960 MB) / 1339031552 bytes (1277 MB) up to 2856321024 bytes (2724 MB) JVM Flags: 0 total; IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0 FML: MCP 9.38 Powered by Forge 13.20.0.2206 5 mods loaded, 5 mods active States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored UCHIJAAAA minecraft{1.11.2} [Minecraft] (minecraft.jar) UCHIJAAAA mcp{9.19} [Minecraft Coder Pack] (minecraft.jar) UCHIJAAAA FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.11.2-13.20.0.2206.jar) UCHIJAAAA forge{13.20.0.2206} [Minecraft Forge] (forgeSrc-1.11.2-13.20.0.2206.jar) UCHIJAAAA tprocessing{1.0.0} [T's Processing] (Modding) Loaded coremods (and transformers): GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread. Profiler Position: N/A (disabled) Player Count: 1 / 8; [EntityPlayerMP['Player76'/71, l='New World', x=1173.95, y=4.00, z=-1346.13]] Type: Integrated Server (map_client.txt) Is Modded: Definitely; Client brand changed to 'fml,forge' ContainerTFurnace package com.github.tompinn23.tprocessing.gui; import com.github.tompinn23.tprocessing.block.TileEntityTFurnace; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.*; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; /** * Created by Tom Pinnock on 11/01/2017. */ public class ContainerTFurnace extends Container { // Stores the tile entity instance for later use private TileEntityTFurnace tileEntityTFurnace; // These store cache values, used by the server to only update the client side tile entity when values have changed private int [] cachedFields; // must assign a slot index to each of the slots used by the GUI. // For this container, we can see the furnace fuel, input, and output slots as well as the player inventory slots and the hotbar. // Each time we add a Slot to the container using addSlotToContainer(), it automatically increases the slotIndex, which means // 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - // 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35) // 36 - 37 = fuel slots (tileEntity 0 - 1) // 37 - 38 = input slots (tileEntity 1 - 2) // 38 - 39 = output slots (tileEntity 2 - 3) private final int HOTBAR_SLOT_COUNT = 9; private final int PLAYER_INVENTORY_ROW_COUNT = 3; private final int PLAYER_INVENTORY_COLUMN_COUNT = 3; private final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT; private final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT; public final int FUEL_SLOTS_COUNT = 1; public final int INPUT_SLOTS_COUNT = 1; public final int OUTPUT_SLOTS_COUNT = 1; public final int FURNACE_SLOTS_COUNT = 3; // slot index is the unique index for all slots in this container i.e. 0 - 35 for invPlayer then 36 - 39 for tileEntityTFurnace private final int VANILLA_FIRST_SLOT_INDEX = 0; private final int FIRST_FUEL_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT; private final int FIRST_INPUT_SLOT_INDEX = FIRST_FUEL_SLOT_INDEX + FUEL_SLOTS_COUNT; private final int FIRST_OUTPUT_SLOT_INDEX = FIRST_INPUT_SLOT_INDEX + INPUT_SLOTS_COUNT; // slot number is the slot number within each component; i.e. invPlayer slots 0 - 35, and tileEntityTFurnace slots 0 - 14 private final int FIRST_FUEL_SLOT_NUMBER = 0; private final int FIRST_INPUT_SLOT_NUMBER =1; private final int FIRST_OUTPUT_SLOT_NUMBER = 2; public ContainerTFurnace(InventoryPlayer inventory, TileEntityTFurnace tileEntityTFurnace) { this.tileEntityTFurnace = tileEntityTFurnace; final int SLOT_X_SPACING = 18; final int SLOT_Y_SPACING = 18; final int HOTBAR_XPOS = 8; final int HOTBAR_YPOS = 142; // Add the players hotbar to the gui - the [xpos, ypos] location of each item for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) { int slotNumber = x; addSlotToContainer(new Slot(inventory, slotNumber, HOTBAR_XPOS + SLOT_X_SPACING * x, HOTBAR_YPOS)); } final int PLAYER_INVENTORY_XPOS = 8; final int PLAYER_INVENTORY_YPOS = 84; // Add the rest of the players inventory to the gui for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) { for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) { int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x; int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_X_SPACING; int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_Y_SPACING; addSlotToContainer(new Slot(inventory, slotNumber, xpos, ypos)); } } final int FUEL_SLOTS_XPOS = 56; final int FUEL_SLOTS_YPOS = 53; // Add the tile fuel slots addSlotToContainer(new SlotFuel(tileEntityTFurnace, 0, FUEL_SLOTS_XPOS, FUEL_SLOTS_YPOS)); final int INPUT_SLOTS_XPOS = 56; final int INPUT_SLOTS_YPOS = 17; // Add the tile input slots addSlotToContainer(new SlotSmeltableInput(tileEntityTFurnace, 1, INPUT_SLOTS_XPOS, INPUT_SLOTS_YPOS)); final int OUTPUT_SLOTS_XPOS = 134; final int OUTPUT_SLOTS_YPOS = 24; // Add the tile output slots addSlotToContainer(new SlotOutput(tileEntityTFurnace, 2, OUTPUT_SLOTS_XPOS, OUTPUT_SLOTS_YPOS)); System.out.println(super.inventorySlots.size()); System.out.println(tileEntityTFurnace.getSizeInventory()); } @Override public boolean canInteractWith(EntityPlayer playerIn) { return tileEntityTFurnace.isUseableByPlayer(playerIn); } @Override public ItemStack transferStackInSlot(EntityPlayer player, int sourceSlotIndex) { Slot sourceSlot = (Slot)inventorySlots.get(sourceSlotIndex); if (sourceSlot == null || !sourceSlot.getHasStack()) return null; ItemStack sourceStack = sourceSlot.getStack(); ItemStack copyOfSourceStack = sourceStack.copy(); // Check if the slot clicked is one of the vanilla container slots if (sourceSlotIndex >= VANILLA_FIRST_SLOT_INDEX && sourceSlotIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) { // This is a vanilla container slot so merge the stack into one of the furnace slots // If the stack is smeltable try to merge merge the stack into the input slots if(TileEntityTFurnace.getSmeltingResultForItem(sourceStack) != null){ if (!mergeItemStack(sourceStack, FIRST_INPUT_SLOT_INDEX, FIRST_INPUT_SLOT_INDEX + INPUT_SLOTS_COUNT, false)){ return null; } } else if(TileEntityTFurnace.getItemBurnTime(sourceStack) > 0) { if (!mergeItemStack(sourceStack, FIRST_FUEL_SLOT_INDEX, FIRST_FUEL_SLOT_INDEX + FUEL_SLOTS_COUNT, true)) { // Setting the boolean to true places the stack in the bottom slot first return null; } } else { return null; } } else if (sourceSlotIndex >= FIRST_FUEL_SLOT_INDEX && sourceSlotIndex < FIRST_FUEL_SLOT_INDEX + FURNACE_SLOTS_COUNT) { // This is a furnace slot so merge the stack into the players inventory: try the hotbar first and then the main inventory // because the main inventory slots are immediately after the hotbar slots, we can just merge with a single call if (!mergeItemStack(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) { return null; } } else { System.err.print("Invalid slotIndex:" + sourceSlotIndex); return null; } // If stack size == 0 (the entire stack was moved) set slot contents to null if (sourceStack.getCount() == 0) { sourceSlot.putStack(null); } else { sourceSlot.onSlotChanged(); } sourceSlot.onTake(player, sourceStack); return copyOfSourceStack; } /* Client Synchronization */ // This is where you check if any values have changed and if so send an update to any clients accessing this container // The container itemstacks are tested in Container.detectAndSendChanges, so we don't need to do that // We iterate through all of the TileEntity Fields to find any which have changed, and send them. // You don't have to use fields if you don't wish to; just manually match the ID in sendProgressBarUpdate with the value in // updateProgressBar() // The progress bar values are restricted to shorts. If you have a larger value (eg int), it's not a good idea to try and split it // up into two shorts because the progress bar values are sent independently, and unless you add synchronisation logic at the // receiving side, your int value will be wrong until the second short arrives. Use a custom packet instead. @Override public void detectAndSendChanges() { super.detectAndSendChanges(); boolean allFieldsHaveChanged = false; boolean fieldHasChanged [] = new boolean[tileEntityTFurnace.getFieldCount()]; if (cachedFields == null) { cachedFields = new int[tileEntityTFurnace.getFieldCount()]; allFieldsHaveChanged = true; } for (int i = 0; i < cachedFields.length; ++i) { if (allFieldsHaveChanged || cachedFields[i] != tileEntityTFurnace.getField(i)) { cachedFields[i] = tileEntityTFurnace.getField(i); fieldHasChanged[i] = true; } } // go through the list of listeners (players using this container) and update them if necessary for (IContainerListener listener : this.listeners) { for (int fieldID = 0; fieldID < tileEntityTFurnace.getFieldCount(); ++fieldID) { if (fieldHasChanged[fieldID]) { // Note that although sendProgressBarUpdate takes 2 ints on a server these are truncated to shorts listener.sendProgressBarUpdate(this, fieldID, cachedFields[fieldID]); } } } } // Called when a progress bar update is received from the server. The two values (id and data) are the same two // values given to sendProgressBarUpdate. In this case we are using fields so we just pass them to the tileEntity. @SideOnly(Side.CLIENT) @Override public void updateProgressBar(int id, int data) { tileEntityTFurnace.setField(id, data); } // SlotFuel is a slot for fuel items public class SlotFuel extends Slot { public SlotFuel(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } // if this function returns false, the player won't be able to insert the given item into this slot @Override public boolean isItemValid(ItemStack stack) { return tileEntityTFurnace.isItemValidForFuelSlot(stack); } } // SlotSmeltableInput is a slot for input items public class SlotSmeltableInput extends Slot { public SlotSmeltableInput(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } // if this function returns false, the player won't be able to insert the given item into this slot @Override public boolean isItemValid(ItemStack stack) { return tileEntityTFurnace.isItemValidForInputSlot(stack); } } // SlotOutput is a slot that will not accept any items public class SlotOutput extends Slot { public SlotOutput(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } // if this function returns false, the player won't be able to insert the given item into this slot @Override public boolean isItemValid(ItemStack stack) { return tileEntityTFurnace.isItemValidForOutputSlot(stack); } } } GuiTFurnace package com.github.tompinn23.tprocessing.gui; import com.github.tompinn23.tprocessing.block.TileEntityTFurnace; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.awt.*; import java.util.ArrayList; import java.util.List; /** * Created by Tom Pinnock on 11/01/2017. */ @SideOnly(Side.CLIENT) public class GuiTFurnace extends GuiContainer{ private static final ResourceLocation texture = new ResourceLocation("tprocessing", "textures/gui/tfurnace.png"); private final TileEntityTFurnace tileEntity; public GuiTFurnace(InventoryPlayer inventory, TileEntityTFurnace tileEntityTFurnace) { super(new ContainerTFurnace(inventory, tileEntityTFurnace)); // Set the width and height of the gui xSize = 176; ySize = 166; this.tileEntity = tileEntityTFurnace; } // some [x,y] coordinates of graphical elements final int COOK_BAR_XPOS = 79; final int COOK_BAR_YPOS = 35; final int COOK_BAR_ICON_U = 176; // texture position of white arrow icon final int COOK_BAR_ICON_V = 14; final int COOK_BAR_WIDTH = 24; final int COOK_BAR_HEIGHT = 17; final int FLAME_XPOS = 57; final int FLAME_YPOS = 37; final int FLAME_ICON_U = 176; // texture position of flame icon final int FLAME_ICON_V = 0; final int FLAME_WIDTH = 14; final int FLAME_HEIGHT = 14; @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int x, int y) { // Bind the image texture Minecraft.getMinecraft().getTextureManager().bindTexture(texture); // Draw the image GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); // get cook progress as a double between 0 and 1 double cookProgress = tileEntity.fractionOfCookTimeComplete(); // draw the cook progress bar drawTexturedModalRect(guiLeft + COOK_BAR_XPOS, guiTop + COOK_BAR_YPOS, COOK_BAR_ICON_U, COOK_BAR_ICON_V, (int)(cookProgress * COOK_BAR_WIDTH), COOK_BAR_HEIGHT); // draw the burn remaining double burnRemaining = tileEntity.fractionOfFuelRemaining(); int yOffset = (int)((1.0 - burnRemaining) * FLAME_HEIGHT); drawTexturedModalRect(guiLeft + FLAME_XPOS , guiTop + FLAME_YPOS + yOffset, FLAME_ICON_U, FLAME_ICON_V + yOffset, FLAME_WIDTH, FLAME_HEIGHT - yOffset); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { super.drawGuiContainerForegroundLayer(mouseX, mouseY); final int LABEL_XPOS = 5; final int LABEL_YPOS = 5; fontRendererObj.drawString(tileEntity.getDisplayName().getUnformattedText(), LABEL_XPOS, LABEL_YPOS, Color.darkGray.getRGB()); List<String> hoveringText = new ArrayList<String>(); // If the mouse is over the progress bar add the progress bar hovering text if (isInRect(guiLeft + COOK_BAR_XPOS, guiTop + COOK_BAR_YPOS, COOK_BAR_WIDTH, COOK_BAR_HEIGHT, mouseX, mouseY)){ hoveringText.add("Progress:"); int cookPercentage =(int)(tileEntity.fractionOfCookTimeComplete() * 100); hoveringText.add(cookPercentage + "%"); } // If the mouse is over one of the burn time indicator add the burn time indicator hovering text if (isInRect(guiLeft + FLAME_XPOS , guiTop + FLAME_YPOS, FLAME_WIDTH, FLAME_HEIGHT, mouseX, mouseY)) { hoveringText.add("Fuel Time:"); hoveringText.add(tileEntity.secondsOfFuelRemaining() + "s"); } // If hoveringText is not empty draw the hovering text if (!hoveringText.isEmpty()){ drawHoveringText(hoveringText, mouseX - guiLeft, mouseY - guiTop, fontRendererObj); } // // You must re bind the texture and reset the colour if you still need to use it after drawing a string // Minecraft.getMinecraft().getTextureManager().bindTexture(texture); // GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); } // Returns true if the given x,y coordinates are within the given rectangle public static boolean isInRect(int x, int y, int xSize, int ySize, int mouseX, int mouseY){ return ((mouseX >= x && mouseX <= x+xSize) && (mouseY >= y && mouseY <= y+ySize)); } } BlockTFurnace package com.github.tompinn23.tprocessing.block; import com.github.tompinn23.tprocessing.TProcessing; import com.github.tompinn23.tprocessing.gui.TGuiHandler; import com.github.tompinn23.tprocessing.item.ItemModelProvider; import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockHorizontal; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyDirection; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.stats.StatList; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFurnace; import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; /** * Created by Tom Pinnock on 09/01/2017. */ public class BlockTFurnace extends BlockContainer implements ItemModelProvider { public static final PropertyDirection FACING = BlockHorizontal.FACING; public BlockTFurnace() { super(Material.ROCK); this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH)); setUnlocalizedName("t_furnace"); setRegistryName("t_furnace"); setCreativeTab(TProcessing.creativeTab); } public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (worldIn.isRemote) { return true; } else { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof TileEntityTFurnace) { playerIn.openGui(TProcessing.instance, TGuiHandler.getGuiID(), worldIn, pos.getX(), pos.getY(), pos.getZ()); playerIn.addStat(StatList.FURNACE_INTERACTION); return true; } return true; } } @Override public EnumBlockRenderType getRenderType(IBlockState state) { return EnumBlockRenderType.MODEL; } private void setDefaultFacing(World worldIn, BlockPos pos, IBlockState state) { if (!worldIn.isRemote) { IBlockState iblockstate = worldIn.getBlockState(pos.north()); IBlockState iblockstate1 = worldIn.getBlockState(pos.south()); IBlockState iblockstate2 = worldIn.getBlockState(pos.west()); IBlockState iblockstate3 = worldIn.getBlockState(pos.east()); EnumFacing enumfacing = (EnumFacing)state.getValue(FACING); if (enumfacing == EnumFacing.NORTH && iblockstate.isFullBlock() && !iblockstate1.isFullBlock()) { enumfacing = EnumFacing.SOUTH; } else if (enumfacing == EnumFacing.SOUTH && iblockstate1.isFullBlock() && !iblockstate.isFullBlock()) { enumfacing = EnumFacing.NORTH; } else if (enumfacing == EnumFacing.WEST && iblockstate2.isFullBlock() && !iblockstate3.isFullBlock()) { enumfacing = EnumFacing.EAST; } else if (enumfacing == EnumFacing.EAST && iblockstate3.isFullBlock() && !iblockstate2.isFullBlock()) { enumfacing = EnumFacing.WEST; } worldIn.setBlockState(pos, state.withProperty(FACING, enumfacing), 2); } } @Override @SuppressWarnings("deprecation") public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); } /** * Convert the given metadata into a BlockState for this Block */ @Override @SuppressWarnings("deprecation") public IBlockState getStateFromMeta(int meta) { EnumFacing enumfacing = EnumFacing.getFront(meta); if (enumfacing.getAxis() == EnumFacing.Axis.Y) { enumfacing = EnumFacing.NORTH; } return this.getDefaultState().withProperty(FACING, enumfacing); } /** * Convert the BlockState into the correct metadata value */ @Override public int getMetaFromState(IBlockState state) { return ((EnumFacing)state.getValue(FACING)).getIndex(); } /** * Returns the blockstate with the given rotation from the passed blockstate. If inapplicable, returns the passed * blockstate. */ @Override @SuppressWarnings("deprecation") public IBlockState withRotation(IBlockState state, Rotation rot) { return state.withProperty(FACING, rot.rotate((EnumFacing)state.getValue(FACING))); } @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, new IProperty[] {FACING}); } @Override public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileEntityTFurnace(); } @Override public void registerItemModel(Item item) { TProcessing.proxy.registerItemRenderer(item, 0, "t_furnace"); } } TileEntityTFurnace package com.github.tompinn23.tprocessing.block; import com.github.tompinn23.tprocessing.ModItems; import com.sun.istack.internal.Nullable; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.*; import net.minecraft.item.*; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagInt; import net.minecraft.nbt.NBTTagList; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFurnace; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import java.util.Arrays; /** * Created by Tom Pinnock on 09/01/2017. */ public class TileEntityTFurnace extends TileEntity implements IInventory, ITickable { // Create and initialize the itemStacks variable that will store store the itemStacks public static final int FUEL_SLOTS_COUNT = 1; public static final int TOTAL_SLOTS_COUNT = 3; private ItemStack[] itemStacks = new ItemStack[TOTAL_SLOTS_COUNT]; /** The number of burn ticks remaining on the current piece of fuel */ private int burnTimeRemaining; /** The initial fuel value of the currently burning fuel (in ticks of burn duration) */ private int burnTimeInitialValue; /**The number of ticks the current item has been cooking*/ private short cookTime; /**The number of ticks required to cook an item*/ private static final short COOK_TIME_FOR_COMPLETION = 200; // vanilla value is 200 = 10 seconds private int cachedNumberOfBurningSlots = -1; /** * Returns the amount of fuel remaining on the currently burning item * @return fraction remaining, between 0 - 1 */ public double fractionOfFuelRemaining() { if (burnTimeInitialValue <= 0 ) return 0; double fraction = burnTimeRemaining / (double)burnTimeInitialValue; return MathHelper.clamp(fraction, 0.0, 1.0); } /** * return the remaining burn time of the fuel slot * @return seconds remaining */ public int secondsOfFuelRemaining() { if (burnTimeRemaining <= 0 ) return 0; return burnTimeRemaining / 20; // 20 ticks per second } /** * Returns the amount of cook time completed on the currently cooking item. * @return fraction remaining, between 0 - 1 */ public double fractionOfCookTimeComplete() { double fraction = cookTime / (double)COOK_TIME_FOR_COMPLETION; return MathHelper.clamp(fraction, 0.0, 1.0); } // This method is called every tick to update the tile entity, i.e. // - see if the fuel has run out, and if so turn the furnace "off" and slowly uncook the current item (if any) // - see if any of the items have finished smelting // It runs both on the server and the client. @Override public void update() { // If there is nothing to smelt or there is no room in the output, reset cookTime and return if (canSmelt()) { int numberOfFuelBurning = burnFuel(); // If fuel is available, keep cooking the item, otherwise start "uncooking" it at double speed if (numberOfFuelBurning > 0) { cookTime += numberOfFuelBurning; } else { cookTime -= 2; } if (cookTime < 0) cookTime = 0; // If cookTime has reached maxCookTime smelt the item and reset cookTime if (cookTime >= COOK_TIME_FOR_COMPLETION) { smeltItem(); cookTime = 0; } } else { cookTime = 0; } } /** * for each fuel slot: decreases the burn time, checks if burnTimeRemaining = 0 and tries to consume a new piece of fuel if one is available * @return the number of fuel slots which are burning */ private int burnFuel() { int burningCount = 0; boolean inventoryChanged = false; if (burnTimeRemaining > 0) { --burnTimeRemaining; ++burningCount; } if (burnTimeRemaining == 0) { if (itemStacks[0] != null && getItemBurnTime(itemStacks[0]) > 0) { // If the stack in this slot is not null and is fuel, set burnTimeRemaining & burnTimeInitialValue to the // item's burn time and decrease the stack size burnTimeRemaining = burnTimeInitialValue = getItemBurnTime(itemStacks[0]); int size = itemStacks[0].getCount(); --size; itemStacks[0].setCount(size); ++burningCount; inventoryChanged = true; // If the stack size now equals 0 set the slot contents to the items container item. This is for fuel // items such as lava buckets so that the bucket is not consumed. If the item dose not have // a container item getContainerItem returns null which sets the slot contents to null if (itemStacks[0].getCount() == 0) { itemStacks[0] = itemStacks[0].getItem().getContainerItem(itemStacks[0]); } } } if (inventoryChanged) markDirty(); return burningCount; } /** * Check if any of the input items are smeltable and there is sufficient space in the output slots * @return true if smelting is possible */ private boolean canSmelt() {return smeltItem(false);} /** * Smelt an input item into an output slot, if possible */ private void smeltItem() {smeltItem(true);} /** * checks that there is an item to be smelted in one of the input slots and that there is room for the result in the output slots * If desired, performs the smelt * @param performSmelt if true, perform the smelt. if false, check whether smelting is possible, but don't change the inventory * @return false if no items can be smelted, true otherwise */ private boolean smeltItem(boolean performSmelt) { Integer firstSuitableInputSlot = null; Integer firstSuitableOutputSlot = null; ItemStack result = null; // finds the first input slot which is smeltable and whose result fits into an output slot (stacking if possible) if (itemStacks[1] != null) { result = getSmeltingResultForItem(itemStacks[1]); if (result != null) { // find the first suitable output slot- either empty, or with identical item that has enough space ItemStack outputStack = itemStacks[2]; if (outputStack == null) { firstSuitableInputSlot = 1; firstSuitableOutputSlot = 2; } if (outputStack.getItem() == result.getItem() && (!outputStack.getHasSubtypes() || outputStack.getMetadata() == outputStack.getMetadata()) && ItemStack.areItemStackTagsEqual(outputStack, result)) { int combinedSize = itemStacks[2].getCount() + result.getCount(); if (combinedSize <= getInventoryStackLimit() && combinedSize <= itemStacks[2].getMaxStackSize()) { firstSuitableInputSlot = 1; firstSuitableOutputSlot = 2; } } } } if (firstSuitableInputSlot == null) return false; if (!performSmelt) return true; // alter input and output int size = itemStacks[firstSuitableInputSlot].getCount(); --size; itemStacks[firstSuitableInputSlot].setCount(size); if (itemStacks[firstSuitableInputSlot].getCount() <=0) itemStacks[firstSuitableInputSlot] = null; if (itemStacks[firstSuitableOutputSlot] == null) { itemStacks[firstSuitableOutputSlot] = result.copy(); // Use deep .copy() to avoid altering the recipe } else { int osize = itemStacks[firstSuitableOutputSlot].getCount(); osize += result.getCount(); itemStacks[firstSuitableOutputSlot].setCount(osize); } markDirty(); return true; } // returns the smelting result for the given stack. Returns null if the given stack can not be smelted public static ItemStack getSmeltingResultForItem(ItemStack stack) { return FurnaceRecipes.instance().getSmeltingResult(stack); } // returns the number of ticks the given item will burn. Returns 0 if the given item is not a valid fuel public static short getItemBurnTime(ItemStack stack) { int burntime = TileEntityFurnace.getItemBurnTime(stack); // just use the vanilla values return (short)MathHelper.clamp(burntime, 0, Short.MAX_VALUE); } // Gets the number of slots in the inventory @Override public int getSizeInventory() { return itemStacks.length; } @Override public boolean isEmpty() { return false; } // Gets the stack in the given slot @Override public ItemStack getStackInSlot(int i) { return itemStacks[i]; } /** * Removes some of the units from itemstack in the given slot, and returns as a separate itemstack * @param slotIndex the slot number to remove the items from * @param count the number of units to remove * @return a new itemstack containing the units removed from the slot */ @Override public ItemStack decrStackSize(int slotIndex, int count) { ItemStack itemStackInSlot = getStackInSlot(slotIndex); if (itemStackInSlot == null) return null; ItemStack itemStackRemoved; if (itemStackInSlot.getCount() <= count) { itemStackRemoved = itemStackInSlot; setInventorySlotContents(slotIndex, null); } else { itemStackRemoved = itemStackInSlot.splitStack(count); if (itemStackInSlot.getCount() == 0) { setInventorySlotContents(slotIndex, null); } } markDirty(); return itemStackRemoved; } // overwrites the stack in the given slotIndex with the given stack @Override public void setInventorySlotContents(int slotIndex, ItemStack itemstack) { itemStacks[slotIndex] = itemstack; if (itemstack != null && itemstack.getCount() > getInventoryStackLimit()) { itemstack.setCount(getInventoryStackLimit()); } markDirty(); } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUsableByPlayer(EntityPlayer player) { return false; } // Return true if the given player is able to use this block. In this case it checks that // 1) the world tileentity hasn't been replaced in the meantime, and // 2) the player isn't too far away from the centre of the block public boolean isUseableByPlayer(EntityPlayer player) { if (this.world.getTileEntity(this.pos) != this) return false; final double X_CENTRE_OFFSET = 0.5; final double Y_CENTRE_OFFSET = 0.5; final double Z_CENTRE_OFFSET = 0.5; final double MAXIMUM_DISTANCE_SQ = 8.0 * 8.0; return player.getDistanceSq(pos.getX() + X_CENTRE_OFFSET, pos.getY() + Y_CENTRE_OFFSET, pos.getZ() + Z_CENTRE_OFFSET) < MAXIMUM_DISTANCE_SQ; } // Return true if the given stack is allowed to be inserted in the given slot // Unlike the vanilla furnace, we allow anything to be placed in the fuel slots static public boolean isItemValidForFuelSlot(ItemStack itemStack) { if (TileEntityFurnace.isItemFuel(itemStack) || itemStack.getItem() == ModItems.energyCoupler){ return true; } else { return false; } } // Return true if the given stack is allowed to be inserted in the given slot // Unlike the vanilla furnace, we allow anything to be placed in the fuel slots static public boolean isItemValidForInputSlot(ItemStack itemStack) { return true; } // Return true if the given stack is allowed to be inserted in the given slot // Unlike the vanilla furnace, we allow anything to be placed in the fuel slots static public boolean isItemValidForOutputSlot(ItemStack itemStack) { return false; } // This is where you save any data that you don't want to lose when the tile entity unloads // In this case, it saves the state of the furnace (burn time etc) and the itemstacks stored in the fuel, input, and output slots @Override public NBTTagCompound writeToNBT(NBTTagCompound parentNBTTagCompound) { super.writeToNBT(parentNBTTagCompound); // The super call is required to save and load the tiles location // // Save the stored item stacks // to use an analogy with Java, this code generates an array of hashmaps // The itemStack in each slot is converted to an NBTTagCompound, which is effectively a hashmap of key->value pairs such // as slot=1, id=2353, count=1, etc // Each of these NBTTagCompound are then inserted into NBTTagList, which is similar to an array. NBTTagList dataForAllSlots = new NBTTagList(); for (int i = 0; i < this.itemStacks.length; ++i) { if (this.itemStacks[i] != null) { NBTTagCompound dataForThisSlot = new NBTTagCompound(); dataForThisSlot.setByte("Slot", (byte) i); this.itemStacks[i].writeToNBT(dataForThisSlot); dataForAllSlots.appendTag(dataForThisSlot); } } // the array of hashmaps is then inserted into the parent hashmap for the container parentNBTTagCompound.setTag("Items", dataForAllSlots); // Save everything else parentNBTTagCompound.setShort("CookTime", cookTime); parentNBTTagCompound.setTag("burnTimeRemaining", new NBTTagInt(burnTimeRemaining)); parentNBTTagCompound.setTag("burnTimeInitial", new NBTTagInt(burnTimeInitialValue)); return parentNBTTagCompound; } // This is where you load the data that you saved in writeToNBT @Override public void readFromNBT(NBTTagCompound nbtTagCompound) { super.readFromNBT(nbtTagCompound); // The super call is required to save and load the tiles location final byte NBT_TYPE_COMPOUND = 10; // See NBTBase.createNewByType() for a listing NBTTagList dataForAllSlots = nbtTagCompound.getTagList("Items", NBT_TYPE_COMPOUND); Arrays.fill(itemStacks, null); // set all slots to empty for (int i = 0; i < dataForAllSlots.tagCount(); ++i) { NBTTagCompound dataForOneSlot = dataForAllSlots.getCompoundTagAt(i); byte slotNumber = dataForOneSlot.getByte("Slot"); if (slotNumber >= 0 && slotNumber < this.itemStacks.length) { this.itemStacks[slotNumber] = new ItemStack(dataForOneSlot); } } // Load everything else. Trim the arrays (or pad with 0) to make sure they have the correct number of elements cookTime = nbtTagCompound.getShort("CookTime"); burnTimeRemaining = nbtTagCompound.getInteger("burnTimeRemaining"); burnTimeInitialValue = nbtTagCompound.getInteger("burnTimeInitial"); cachedNumberOfBurningSlots = -1; } // // When the world loads from disk, the server needs to send the TileEntity information to the client // // it uses getUpdatePacket(), getUpdateTag(), onDataPacket(), and handleUpdateTag() to do this @Override @Nullable public SPacketUpdateTileEntity getUpdatePacket() { NBTTagCompound updateTagDescribingTileEntityState = getUpdateTag(); final int METADATA = 0; return new SPacketUpdateTileEntity(this.pos, METADATA, updateTagDescribingTileEntityState); } @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) { NBTTagCompound updateTagDescribingTileEntityState = pkt.getNbtCompound(); handleUpdateTag(updateTagDescribingTileEntityState); } /* Creates a tag containing the TileEntity information, used by vanilla to transmit from server to client Warning - although our getUpdatePacket() uses this method, vanilla also calls it directly, so don't remove it. */ @Override public NBTTagCompound getUpdateTag() { NBTTagCompound nbtTagCompound = new NBTTagCompound(); writeToNBT(nbtTagCompound); return nbtTagCompound; } /* Populates this TileEntity with information from the tag, used by vanilla to transmit from server to client Warning - although our onDataPacket() uses this method, vanilla also calls it directly, so don't remove it. */ @Override public void handleUpdateTag(NBTTagCompound tag) { this.readFromNBT(tag); } //------------------------ // set all slots to empty @Override public void clear() { Arrays.fill(itemStacks, null); } // will add a key for this container to the lang file so we can name it in the GUI @Override public String getName() { return "container.mbe31_inventory_furnace.name"; } @Override public boolean hasCustomName() { return false; } // standard code to look up what the human-readable name is @Nullable @Override public ITextComponent getDisplayName() { return this.hasCustomName() ? new TextComponentString(this.getName()) : new TextComponentTranslation(this.getName()); } // Fields are used to send non-inventory information from the server to interested clients // The container code caches the fields and sends the client any fields which have changed. // The field ID is limited to byte, and the field value is limited to short. (if you use more than this, they get cast down // in the network packets) // If you need more than this, or shorts are too small, use a custom packet in your container instead. private static final byte COOK_FIELD_ID = 0; private static final byte FIRST_BURN_TIME_REMAINING_FIELD_ID = 1; private static final byte FIRST_BURN_TIME_INITIAL_FIELD_ID = FIRST_BURN_TIME_REMAINING_FIELD_ID + (byte)FUEL_SLOTS_COUNT; private static final byte NUMBER_OF_FIELDS = FIRST_BURN_TIME_INITIAL_FIELD_ID + (byte)FUEL_SLOTS_COUNT; @Override public int getField(int id) { if (id == COOK_FIELD_ID) return cookTime; if (id >= FIRST_BURN_TIME_REMAINING_FIELD_ID && id < FIRST_BURN_TIME_REMAINING_FIELD_ID + FUEL_SLOTS_COUNT) { return burnTimeRemaining; } if (id >= FIRST_BURN_TIME_INITIAL_FIELD_ID && id < FIRST_BURN_TIME_INITIAL_FIELD_ID + FUEL_SLOTS_COUNT) { return burnTimeInitialValue; } System.err.println("Invalid field ID in TileInventorySmelting.getField:" + id); return 0; } @Override public void setField(int id, int value) { if (id == COOK_FIELD_ID) { cookTime = (short)value; } else if (id >= FIRST_BURN_TIME_REMAINING_FIELD_ID && id < FIRST_BURN_TIME_REMAINING_FIELD_ID + FUEL_SLOTS_COUNT) { burnTimeRemaining = value; } else if (id >= FIRST_BURN_TIME_INITIAL_FIELD_ID && id < FIRST_BURN_TIME_INITIAL_FIELD_ID + FUEL_SLOTS_COUNT) { burnTimeInitialValue = value; } else { System.err.println("Invalid field ID in TileInventorySmelting.setField:" + id); } } @Override public int getFieldCount() { return NUMBER_OF_FIELDS; } // ----------------------------------------------------------------------------------------------------------- // The following methods are not needed for this example but are part of IInventory so they must be implemented // Unused unless your container specifically uses it. // Return true if the given stack is allowed to go in the given slot @Override public boolean isItemValidForSlot(int slotIndex, ItemStack itemstack) { return false; } /** * This method removes the entire contents of the given slot and returns it. * Used by containers such as crafting tables which return any items in their slots when you close the GUI * @param slotIndex * @return */ @Override public ItemStack removeStackFromSlot(int slotIndex) { ItemStack itemStack = getStackInSlot(slotIndex); if (itemStack != null) setInventorySlotContents(slotIndex, null); return itemStack; } @Override public void openInventory(EntityPlayer player) {} @Override public void closeInventory(EntityPlayer player) {} }
-
10.12.0.1024
-
Hello i get this error when i load the world and it says Please could some one help im not sure what it means
-
Well then which class do i return
-
but ive got it extending Container so am i returning the wrong class
-
What the class InventoryGenerator must be GuiScreen like extends it or what
-
hello i dont understand what you mean heres my getClientGuiElement public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { TileEntity entity = world.getTileEntity(x, y, z); if(entity != null){ switch(ID){ //case usefulStuff.guiIDSludger: //if(entity instanceof TileEntitySludger){ ////return new GuiSludger(player.inventory, (TileEntitySludger) entity); case usefulStuff.guiIDGenerator: // Create an Object of our TE, so we can give that to our inventory. generatorTileEntity tileEntityGeneratorContainer = (generatorTileEntity) world.getTileEntity(x, y, z); return new InventoryGenerator(player.inventory, tileEntityGeneratorContainer); } } return null; }
-
hello i try to open my custom gui and i get this error java.lang.ClassCastException: tompinn23.usefulStuff.InventoryGenerator cannot be cast to net.minecraft.client.gui.GuiScreen at cpw.mods.fml.client.FMLClientHandler.showGuiScreen(FMLClientHandler.java:415) at cpw.mods.fml.common.FMLCommonHandler.showGuiScreen(FMLCommonHandler.java:288) at cpw.mods.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:94) at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2255) at tompinn23.usefulStuff.blockGenerator.onBlockActivated(blockGenerator.java:30) at net.minecraft.client.multiplayer.PlayerControllerMP.onPlayerRightClick(PlayerControllerMP.java:349) at net.minecraft.client.Minecraft.func_147121_ag(Minecraft.java:1442) at net.minecraft.client.Minecraft.runTick(Minecraft.java:1949) at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:953) at net.minecraft.client.Minecraft.run(Minecraft.java:870) at net.minecraft.client.main.Main.main(Main.java:103) 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:134) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) I can see it is a classcast exception but i dont know how to fix it
-
Hello I'm trying to make a solar generator but i am having trouble figuring out how to detect whether there is sunlight above the block here is what i found in the daylight detector code but really i just need it to return true or false. public void func_149957_e(World world, int x, int y, int z) { if (world.provider.hasNoSky) { return; } int i = world.getBlockMetadata(x, y, z); int j = world.getSavedLightValue(EnumSkyBlock.Sky, x, y, z) - world.skylightSubtracted; float f = world.getCelestialAngleRadians(1.0F); if (f < 3.141593F) { f += (0.0F - f) * 0.2F; } else { f += (6.283186F - f) * 0.2F; } j = Math.round(j * MathHelper.cos(f)); if (j < 0) { j = 0; } if (j > 15) { j = 15; } if (i != j) { world.setBlockMetadataWithNotify(x, y, z, j, 3); } }
-
Thank you EDIT: How do you check all slots of the crafting table and also how do you make the item stay after crafting but lose durabilty
-
Hello i am trying to make my mod know when a item(the transmutation orb)is being used in a recipe here is my code for the main class file. package tompinn23.usefulStuff; import net.minecraft.block.Block; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.common.MinecraftForge; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.GameRegistry; @Mod(modid = usefulStuff.modid, version = usefulStuff.version) public class usefulStuff { public static final String modid = "UsefulStuff"; public static final String version = "0.1.0 Alpha"; public static Block blockHardQuartz; public static Item itemHardenedQuartz; public static Item itemTransOrb; public static CreativeTabs usefulTab = new CreativeTabs("usefulStuffTab"){ public Item getTabIconItem() { return Items.wooden_pickaxe; } }; @EventHandler public void preInit(FMLPreInitializationEvent e){ //Items itemHardenedQuartz = new Item().setUnlocalizedName("itemHardenedQuartz").setCreativeTab(usefulTab).setTextureName(modid + ":" + "itemHardenedQuartz"); GameRegistry.registerItem(itemHardenedQuartz, "itemHardenedQuartz" ); itemTransOrb = new Item().setUnlocalizedName("itemTransOrb").setCreativeTab(usefulTab).setTextureName(modid + ":" + "itemTransOrb"); GameRegistry.registerItem(itemTransOrb,"itemTransOrb" ); //Blocks blockHardQuartz = new blockHardQuartz().setBlockName("blockHardQuartz").setCreativeTab(usefulTab).setBlockTextureName(modid + ":" + "blockHardQuartz"); GameRegistry.registerBlock(blockHardQuartz, "blockHardQuartz"); } @EventHandler public void init(FMLInitializationEvent e){ FMLCommonHandler.instance().bus().register(new CustomEventListener()); ItemStack TransStack = new ItemStack(itemTransOrb); GameRegistry.addRecipe(new ItemStack(Blocks.cobblestone), "xyy", "y "," ", 'x', TransStack, 'y', new ItemStack(Blocks.cobblestone)); } } Also my CustomEventhandler package tompinn23.usefulStuff; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import cpw.mods.fml.common.gameevent.PlayerEvent.ItemCraftedEvent; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; public class CustomEventListener { @SubscribeEvent public void onItemCraftedEvent(PlayerEvent.ItemCraftedEvent event) { if (event.craftMatrix.getStackInSlot(0) == new ItemStack(usefulStuff.itemTransOrb)) { System.out.println("Hay"); } } } Please Help Tom