hyper1423 Posted June 22, 2019 Posted June 22, 2019 (edited) My custom furnace uses the input in milliseconds but doesn't make output. Also it doesn't drop container item when destroyed. (I watched HarryTalks' tutorial) The code is here: Block Class Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import java.util.Random; import java.util.logging.Logger; import com.hyper1423.somestuff.Main; import com.hyper1423.somestuff.blocks.BlockBase; import com.hyper1423.somestuff.init.ModBlocks; import com.hyper1423.somestuff.util.Reference; import net.minecraft.block.BlockHorizontal; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; 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.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class BlastFurnace extends BlockBase implements ITileEntityProvider { int currentFuel = 0; public static final PropertyDirection FACING = BlockHorizontal.FACING; public static final PropertyBool BURNING = PropertyBool.create("burning"); private static Logger logger = Logger.getLogger(Reference.MOD_ID); public BlastFurnace(String name) { super(name, Material.IRON); setSoundType(SoundType.ANVIL); this.setDefaultState( this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH).withProperty(BURNING, false)); } @Override public Item getItemDropped(IBlockState state, Random rand, int fortune) { return Item.getItemFromBlock(ModBlocks.BLAST_FURNACE); } @Override public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { return new ItemStack(ModBlocks.BLAST_FURNACE); } @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (!worldIn.isRemote) { playerIn.openGui(Main.instance, Reference.GUI_BLAST_FURNACE, worldIn, pos.getX(), pos.getY(), pos.getZ()); } logger.info("Tried to open GUI"); return true; } @Override public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { // TODO Auto-generated method stub if (!worldIn.isRemote) { IBlockState north = worldIn.getBlockState(pos.north()); IBlockState south = worldIn.getBlockState(pos.south()); IBlockState west = worldIn.getBlockState(pos.west()); IBlockState east = worldIn.getBlockState(pos.east()); EnumFacing face = (EnumFacing) state.getValue(FACING); if (face == EnumFacing.NORTH) face = EnumFacing.SOUTH; if (face == EnumFacing.SOUTH) face = EnumFacing.NORTH; if (face == EnumFacing.WEST) face = EnumFacing.EAST; if (face == EnumFacing.EAST) face = EnumFacing.WEST; worldIn.setBlockState(pos, state.withProperty(FACING, face), 2); } } public static void setState(boolean active, World worldIn, BlockPos pos) { IBlockState state = worldIn.getBlockState(pos); TileEntity tileentity = worldIn.getTileEntity(pos); if (active) worldIn.setBlockState(pos, ModBlocks.BLAST_FURNACE.getDefaultState() .withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, true), 1 | 2); else worldIn.setBlockState(pos, ModBlocks.BLAST_FURNACE.getDefaultState() .withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, false), 1 | 2); if (tileentity != null) { tileentity.validate(); worldIn.setTileEntity(pos, tileentity); } } @Override public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { // TODO Auto-generated method stub return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { // TODO Auto-generated method stub worldIn.setBlockState(pos, this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()), 2); } @Override public EnumBlockRenderType getRenderType(IBlockState state) { // TODO Auto-generated method stub return EnumBlockRenderType.MODEL; } @Override public IBlockState withRotation(IBlockState state, Rotation rot) { // TODO Auto-generated method stub return state.withProperty(FACING, rot.rotate((EnumFacing) state.getValue(FACING))); } @Override public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { // TODO Auto-generated method stub return state.withRotation(mirrorIn.toRotation((EnumFacing) state.getValue(FACING))); } @Override protected BlockStateContainer createBlockState() { // TODO Auto-generated method stub return new BlockStateContainer(this, new IProperty[] { BURNING, FACING }); } @Override public IBlockState getStateFromMeta(int meta) { // TODO Auto-generated method stub EnumFacing facing = EnumFacing.getFront(meta); if (facing.getAxis() == EnumFacing.Axis.Y) facing = EnumFacing.NORTH; return this.getDefaultState().withProperty(FACING, facing); } @Override public int getMetaFromState(IBlockState state) { // TODO Auto-generated method stub return ((EnumFacing) state.getValue(FACING)).getIndex(); } @Override public TileEntity createNewTileEntity(World worldIn, int meta) { // TODO Auto-generated method stub return new TileEntityBlastFurnace(); } } TileEntity Class Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.init.ModItems; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class TileEntityBlastFurnace extends TileEntity implements ITickable { private ItemStackHandler inventory = new ItemStackHandler(4); private String customname; private ItemStack smelting = ItemStack.EMPTY; private int burnTime = 0; private int currentBurnTime = 0; private int cookTime = 0; private int totalCookTime = 600; @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { // TODO Auto-generated method stub if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true; else return false; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { // TODO Auto-generated method stub if (hasCapability(capability, null)) return (T) this.inventory; return super.getCapability(capability, facing); } public boolean hasCustomName() { return customname != null && !customname.isEmpty(); } public void setCustomName(String customname) { this.customname = customname; } @Override public ITextComponent getDisplayName() { return this.hasCustomName() ? new TextComponentString(this.customname) : new TextComponentTranslation("container.blast_furnace"); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.inventory.deserializeNBT(compound.getCompoundTag("Inventory")); burnTime = compound.getInteger("BurnTime"); cookTime = compound.getInteger("CookTime"); totalCookTime = compound.getInteger("CookTimeTotal"); currentBurnTime = getItemBurnTime((ItemStack) inventory.getStackInSlot(1)); if (compound.hasKey("CustomName", 8)) setCustomName(compound.getString("CustomName")); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger("BurnTime", (short) burnTime); compound.setInteger("CookTime", (short) cookTime); compound.setInteger("CookTimeTotal", (short) totalCookTime); compound.setTag("inventory", this.inventory.serializeNBT()); if (hasCustomName()) compound.setString("CustomName", customname); return compound; } public boolean isBurning() { return burnTime > 0; } @SideOnly(Side.CLIENT) public static boolean isBurning(TileEntityBlastFurnace te) { return te.getField(0) > 0; } @Override public void update() { if (isBurning()) { --burnTime; BlastFurnace.setState(true, world, pos); } ItemStack fuel = (ItemStack) inventory.getStackInSlot(1); if (isBurning() || !fuel.isEmpty() && !inventory.getStackInSlot(0).isEmpty()) { if (!isBurning() && canSmelt()) { burnTime = getItemBurnTime(fuel); currentBurnTime = burnTime; if (isBurning() && !fuel.isEmpty()) { Item item = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { ItemStack item1 = item.getContainerItem(fuel); inventory.setStackInSlot(1, item1); } } } if (isBurning() && canSmelt() && cookTime > 0) { cookTime++; if (cookTime == totalCookTime) { if (inventory.getStackInSlot(2).getCount() > 0) { inventory.getStackInSlot(2).grow(1); } else { inventory.insertItem(2, smelting, false); } if (inventory.getStackInSlot(3).getCount() > 0) { inventory.getStackInSlot(3).grow(1); } else { inventory.insertItem(3, new ItemStack(ModItems.SLUG, 1), false); } } smelting = ItemStack.EMPTY; cookTime = 0; return; } // } else if (!isBurning() && cookTime > 0) { // if (cookTime > getCookTime(inventory.getStackInSlot(1)) / 3) // cookTime = MathHelper.clamp(cookTime - 3, 0, totalCookTime); // else // MathHelper.clamp(cookTime - 2, 0, totalCookTime); else { if (this.canSmelt() && this.isBurning()) { ItemStack output = BlastFurnaceRecipes.getInstance().getResult(inventory.getStackInSlot(0)); if (!output.isEmpty()) { smelting = output; cookTime++; inventory.getStackInSlot(0).shrink(1); } } } } // if (flag != isBurning()) { // flag1 = true; // BlastFurnace.setState(isBurning(), world, pos); // } // } // if (flag1) { // markDirty(); // } } private boolean canSmelt() { if (((ItemStack) inventory.getStackInSlot(0)).isEmpty()) return false; else { ItemStack result = BlastFurnaceRecipes.getInstance().getResult((ItemStack) inventory.getStackInSlot(0)); if (result.isEmpty()) return false; else { ItemStack output = (ItemStack) inventory.getStackInSlot(2); ItemStack slug = (ItemStack) inventory.getStackInSlot(3); if (output.isEmpty()) return true; if (!output.isItemEqual(result)) return false; int res1 = output.getCount() + result.getCount(); int res2 = slug.getCount() + 1; return (res1 <= 64 && res1 <= output.getMaxStackSize()) || (res2 <= 64 && res2 <= slug.getMaxStackSize()); } } } public static int getItemBurnTime(ItemStack fuel) { if (fuel.isEmpty()) return 0; else { Item item = fuel.getItem(); if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.AIR) { Block block = Block.getBlockFromItem(item); if (block == Blocks.WOODEN_SLAB) return 100; if (block == Blocks.ACACIA_STAIRS || block == Blocks.OAK_STAIRS || block == Blocks.JUNGLE_STAIRS || block == Blocks.BIRCH_STAIRS || block == Blocks.DARK_OAK_STAIRS || block == Blocks.SPRUCE_STAIRS) return 150; if (block.getDefaultState().getMaterial() == Material.WOOD) return 200; if (block == Blocks.COAL_BLOCK) return 14400; } if (item instanceof ItemTool && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemSword && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemHoe && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item == Items.STICK) return 50; if (item == Items.COAL) return 1600; if (item == Items.LAVA_BUCKET) return 20000; if (item == Item.getItemFromBlock(Blocks.SAPLING)) return 70; if (item == Items.BLAZE_ROD) return 1600; return ForgeEventFactory.getItemBurnTime(fuel); } } public static boolean isItemFuel(ItemStack fuel) { return getItemBurnTime(fuel) > 0; } public boolean isUsableByPlayer(EntityPlayer player) { return world.getTileEntity(pos) != this ? false : player.getDistanceSq((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D) <= 64.0D; } public boolean isItemValidForSlot(int index, ItemStack stack) { if (index == 2 || index == 3) return false; if (index != 1) return true; else { return isItemFuel(stack); } } public int getField(int id) { switch (id) { case 0: return burnTime; case 1: return currentBurnTime; case 2: return cookTime; case 3: return totalCookTime; default: return 0; } } public void setField(int id, int value) { switch (id) { case 0: burnTime = value; break; case 1: currentBurnTime = value; break; case 2: cookTime = value; break; case 3: totalCookTime = value; } } } Container class Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.blocks.machines.blastfurnace.slots.SlotBlastFurnaceFuel; import com.hyper1423.somestuff.blocks.machines.blastfurnace.slots.SlotBlastFurnaceOutput; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IContainerListener; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; public class ContainerBlastFurnace extends Container { private final TileEntityBlastFurnace tileentity; private int cookTime, totalCookTime, burnTime, currentBurnTime; public ContainerBlastFurnace(InventoryPlayer player, TileEntityBlastFurnace tileentity) { this.tileentity = tileentity; IItemHandler inventory = tileentity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); this.addSlotToContainer(new SlotItemHandler(inventory, 0, 35, 17)); this.addSlotToContainer(new SlotBlastFurnaceFuel(inventory, 1, 35, 53)); this.addSlotToContainer(new SlotBlastFurnaceOutput(player.player, inventory, 2, 95, 35)); this.addSlotToContainer(new SlotBlastFurnaceOutput(player.player, inventory, 3, 143, 53)); for (int y = 0; y < 3; y++) { for (int x = 0; x < 9; x++) { this.addSlotToContainer(new Slot(player, x + y * 9 + 9, 8 + x * 18, 84 + y * 18)); } } for (int x = 0; x < 9; x++) { this.addSlotToContainer(new Slot(player, x, 8 + x * 18, 142)); } } @Override public void detectAndSendChanges() { // TODO Auto-generated method stub super.detectAndSendChanges(); for (int i = 0; i < this.listeners.size(); ++i) { IContainerListener listener = (IContainerListener) this.listeners.get(i); if (this.burnTime != this.tileentity.getField(0)) listener.sendWindowProperty(this, 0, this.tileentity.getField(0)); if (this.currentBurnTime != this.tileentity.getField(1)) listener.sendWindowProperty(this, 1, this.tileentity.getField(1)); if (this.cookTime != this.tileentity.getField(2)) listener.sendWindowProperty(this, 2, this.tileentity.getField(2)); if (this.totalCookTime != this.tileentity.getField(3)) listener.sendWindowProperty(this, 3, this.tileentity.getField(3)); } this.burnTime = this.tileentity.getField(0); this.currentBurnTime = this.tileentity.getField(1); this.cookTime = this.tileentity.getField(2); this.totalCookTime = this.tileentity.getField(3); } @Override @SideOnly(Side.CLIENT) public void updateProgressBar(int id, int data) { // TODO Auto-generated method stub this.tileentity.setField(id, data); } @Override public boolean canInteractWith(EntityPlayer playerIn) { // TODO Auto-generated method stub return this.tileentity.isUsableByPlayer(playerIn); } @Override public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack stack = ItemStack.EMPTY; Slot slot = (Slot) this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack stack1 = slot.getStack(); stack = stack1.copy(); if (index == 2 || index == 3) { if (!this.mergeItemStack(stack1, 4, 40, true)) return ItemStack.EMPTY; slot.onSlotChange(stack1, stack); } else if (index != 1 && index != 0) { if (!BlastFurnaceRecipes.getInstance().getResult(stack1).isEmpty()) { if (!this.mergeItemStack(stack1, 0, 1, false)) { return ItemStack.EMPTY; } else if (TileEntityBlastFurnace.isItemFuel(stack1)) { if (!this.mergeItemStack(stack1, 1, 2, false)) return ItemStack.EMPTY; } else if (TileEntityBlastFurnace.isItemFuel(stack1)) { if (!this.mergeItemStack(stack1, 1, 2, false)) return ItemStack.EMPTY; } else if (TileEntityBlastFurnace.isItemFuel(stack1)) { if (!this.mergeItemStack(stack1, 1, 2, false)) return ItemStack.EMPTY; } else if (index >= 4 && index < 31) { if (!this.mergeItemStack(stack1, 31, 40, false)) return ItemStack.EMPTY; } else if (index >= 31 && index < 40 && !this.mergeItemStack(stack1, 4, 31, false)) { return ItemStack.EMPTY; } } } else if (!this.mergeItemStack(stack1, 4, 40, false)) { return ItemStack.EMPTY; } if (stack1.isEmpty()) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } if (stack1.getCount() == stack.getCount()) return ItemStack.EMPTY; slot.onTake(playerIn, stack1); } return stack; } } Fuel Slot class: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace.slots; import com.hyper1423.somestuff.blocks.machines.blastfurnace.TileEntityBlastFurnace; import net.minecraft.item.ItemStack; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; public class SlotBlastFurnaceFuel extends SlotItemHandler { public SlotBlastFurnaceFuel(IItemHandler inventory, int index, int x, int y) { super(inventory, index, x, y); // TODO Auto-generated constructor stub } @Override public boolean isItemValid(ItemStack stack) { // TODO Auto-generated method stub return TileEntityBlastFurnace.isItemFuel(stack); } @Override public int getItemStackLimit(ItemStack stack) { // TODO Auto-generated method stub return super.getItemStackLimit(stack); } } Output Slot class: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace.slots; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; public class SlotBlastFurnaceOutput extends SlotItemHandler { private final EntityPlayer player; private int removeCount; public SlotBlastFurnaceOutput(EntityPlayer player, IItemHandler inventory, int index, int x, int y) { super(inventory, index, x, y); this.player = player; // TODO Auto-generated constructor stub } @Override public boolean isItemValid(ItemStack stack) { return false; } @Override public ItemStack onTake(EntityPlayer thePlayer, ItemStack stack) { // TODO Auto-generated method stub this.onCrafting(stack); super.onTake(thePlayer, stack); return stack; } @Override public ItemStack decrStackSize(int amount) { // TODO Auto-generated method stub if(this.getHasStack()) this.removeCount += Math.min(amount, this.getStack().getCount()); return super.decrStackSize(amount); } } GUI class Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.util.Reference; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.util.ResourceLocation; public class GuiBlastFurnace extends GuiContainer { private static final ResourceLocation TEXTURES = new ResourceLocation(Reference.MOD_ID, "textures/gui/blast_furnace.png"); private final InventoryPlayer player; private final TileEntityBlastFurnace tileentity; public GuiBlastFurnace(InventoryPlayer player, TileEntityBlastFurnace tileentity) { super(new ContainerBlastFurnace(player, tileentity)); this.player = player; this.tileentity = tileentity; // TODO Auto-generated constructor stub } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { // TODO Auto-generated method stub if (this.tileentity.getDisplayName() != null) { String tileName = this.tileentity.getDisplayName().getUnformattedText(); this.fontRenderer.drawString(tileName, (this.xSize / 2 - this.fontRenderer.getStringWidth(tileName) / 2) + 3, 8, 0x404040); this.fontRenderer.drawString(this.player.getDisplayName().getUnformattedText(), 8, this.ySize - 96 + 2, 0x404040); } } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f); this.mc.getTextureManager().bindTexture(TEXTURES); this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); if (TileEntityBlastFurnace.isBurning(tileentity)) { int k = this.getBurnLeftScaled(13); this.drawTexturedModalRect(this.guiLeft + 36, this.guiTop + 37 + 12 - k, 176, 12 - k, 14, k + 1); } int l = this.getCookProgressScaled(24); this.drawTexturedModalRect(this.guiLeft + 58, this.guiTop + 35, 176, 14, l + 1, 16); } private int getBurnLeftScaled(int pixels) { int i = this.tileentity.getField(1); int j = this.tileentity.getField(0); if (i == 0) i = 200; return j * pixels / i; } private int getCookProgressScaled(int pixels) { int i = this.tileentity.getField(2); int j = this.tileentity.getField(3); return j != 0 && i != 0 ? i * pixels / j : 0; } } Recipe class Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import java.util.Map; import java.util.Map.Entry; import com.google.common.collect.Maps; import com.hyper1423.somestuff.init.ModItems; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; public class BlastFurnaceRecipes { private static final BlastFurnaceRecipes INSTANCE = new BlastFurnaceRecipes(); private final Map<ItemStack, ItemStack> smeltingList = Maps.<ItemStack, ItemStack>newHashMap(); private final Map<ItemStack, Float> experienceList = Maps.<ItemStack, Float>newHashMap(); public static BlastFurnaceRecipes getInstance() { return INSTANCE; } private BlastFurnaceRecipes() { addRecipe(new ItemStack(Blocks.ACACIA_FENCE), new ItemStack(ModItems.SLUG), 5.0F); } public void addRecipe(ItemStack input, ItemStack result, float experience) { if (getResult(input) != ItemStack.EMPTY) return; this.smeltingList.put(input, result); this.experienceList.put(result, Float.valueOf(experience)); } public ItemStack getResult(ItemStack input) { for (Entry<ItemStack, ItemStack> entry : this.smeltingList.entrySet()) { if (this.compareItemStacks(input, (ItemStack) entry.getKey())) { return (ItemStack) entry.getValue(); } } return ItemStack.EMPTY; } private boolean compareItemStacks(ItemStack stack1, ItemStack stack2) { return stack2.getItem() == stack1.getItem() && (stack2.getMetadata() == 32767 || stack2.getMetadata() == stack1.getMetadata()); } public Map<ItemStack, ItemStack> getDualSmeltingList() { return this.smeltingList; } public float getResultExperience(ItemStack stack) { for (Entry<ItemStack, Float> entry : this.experienceList.entrySet()) { if (this.compareItemStacks(stack, (ItemStack) entry.getKey())) { return ((Float) entry.getValue()).floatValue(); } } return 0.0F; } } Sorry for my bad english Edited June 30, 2019 by hyper1423 Solved Quote
hyper1423 Posted June 23, 2019 Author Posted June 23, 2019 (edited) 12 hours ago, diesieben07 said: Code style, issue 4. Problematic code, issue 4, 9 (BlastFurnace#currentFuel). This is why you use constants instead of hard-coding strings everywhere. Quote 4. Do not use ITileEntityProvider or BlockContainer. These classes are legacy vanilla code. To add a TileEntity to your Block, override hasTileEntity and createTileEntity in your Block class. Should I override it like this? Spoiler @Override public boolean hasTileEntity() { // TODO Auto-generated method stub return super.hasTileEntity(this.getDefaultState()); } @Override public TileEntity createTileEntity(World world, IBlockState state) { // TODO Auto-generated method stub return super.createTileEntity(world, state); } Quote 9. Any IForgeRegistryEntry (commonly items and blocks) is singleton-like. That means that there is only once instance of your block class. There is not a new Block instance for every position in the world and there is not a new Item instance for every ItemStack. This means that you cannot store position-related things as instance fields in your block class, etc. You must use a TileEntity resp. the NBT data on ItemStack. Are you saying to remove BlastFurnace.currentFuel? Quote 4. Do not abuse inheritance for code-reuse. This often manifests in classes like ItemBase, BaseItem or ItemExampleMod. Using this pattern prevents you from extending other essential classes, such as ItemFood and in that case requires code duplication. Prefer composition or utility methods instead to reuse code. What do you mean? Should I remove BlockBase class and add methods in the BlockBase class in each block classes? 12 hours ago, diesieben07 said: This is why you use constants instead of hard-coding strings everywhere. I changed TileEntity Like This: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.init.ModItems; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class TileEntityBlastFurnace extends TileEntity implements ITickable { private ItemStackHandler inventory = new ItemStackHandler(4); private String customname; private ItemStack smelting = ItemStack.EMPTY; private final String[] nbtTags = { "BurnTime", "CookTime", "CookTimeTotal" }; private final String inventoryKey = "inventory"; private int burnTime = 0; private int currentBurnTime = 0; private int cookTime = 0; private int totalCookTime = 600; @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { // TODO Auto-generated method stub if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true; else return false; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { // TODO Auto-generated method stub if (hasCapability(capability, null)) return (T) this.inventory; return super.getCapability(capability, facing); } public boolean hasCustomName() { return customname != null && !customname.isEmpty(); } public void setCustomName(String customname) { this.customname = customname; } @Override public ITextComponent getDisplayName() { return this.hasCustomName() ? new TextComponentString(this.customname) : new TextComponentTranslation("container.blast_furnace"); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.inventory.deserializeNBT(compound.getCompoundTag(inventoryKey)); burnTime = compound.getInteger(nbtTags[0]); cookTime = compound.getInteger(nbtTags[1]); totalCookTime = compound.getInteger(nbtTags[2]); currentBurnTime = getItemBurnTime((ItemStack) inventory.getStackInSlot(1)); if (compound.hasKey("CustomName", 8)) setCustomName(compound.getString("CustomName")); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger(nbtTags[0], (short) burnTime); compound.setInteger(nbtTags[1], (short) cookTime); compound.setInteger(nbtTags[2], (short) totalCookTime); compound.setTag(inventoryKey, this.inventory.serializeNBT()); if (hasCustomName()) compound.setString("CustomName", customname); return compound; } public boolean isBurning() { return burnTime > 0; } @SideOnly(Side.CLIENT) public static boolean isBurning(TileEntityBlastFurnace te) { return te.getField(0) > 0; } @Override public void update() { if (isBurning()) { --burnTime; BlastFurnace.setState(true, world, pos); } ItemStack fuel = (ItemStack) inventory.getStackInSlot(1); if (isBurning() || !fuel.isEmpty() && !inventory.getStackInSlot(0).isEmpty()) { if (!isBurning() && canSmelt()) { burnTime = getItemBurnTime(fuel); currentBurnTime = burnTime; if (isBurning() && !fuel.isEmpty()) { Item item = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { ItemStack item1 = item.getContainerItem(fuel); inventory.setStackInSlot(1, item1); } } } if (isBurning() && canSmelt() && cookTime > 0) { cookTime++; if (cookTime == totalCookTime) { if (inventory.getStackInSlot(2).getCount() > 0) { inventory.getStackInSlot(2).grow(1); } else { inventory.insertItem(2, smelting, false); } if (inventory.getStackInSlot(3).getCount() > 0) { inventory.getStackInSlot(3).grow(1); } else { inventory.insertItem(3, new ItemStack(ModItems.SLUG, 1), false); } } smelting = ItemStack.EMPTY; cookTime = 0; return; } // } else if (!isBurning() && cookTime > 0) { // if (cookTime > getCookTime(inventory.getStackInSlot(1)) / 3) // cookTime = MathHelper.clamp(cookTime - 3, 0, totalCookTime); // else // MathHelper.clamp(cookTime - 2, 0, totalCookTime); else { if (this.canSmelt() && this.isBurning()) { ItemStack output = BlastFurnaceRecipes.getInstance().getResult(inventory.getStackInSlot(0)); if (!output.isEmpty()) { smelting = output; cookTime++; inventory.getStackInSlot(0).shrink(1); } } } } // if (flag != isBurning()) { // flag1 = true; // BlastFurnace.setState(isBurning(), world, pos); // } // } // if (flag1) { // markDirty(); // } } private boolean canSmelt() { if (((ItemStack) inventory.getStackInSlot(0)).isEmpty()) return false; else { ItemStack result = BlastFurnaceRecipes.getInstance().getResult((ItemStack) inventory.getStackInSlot(0)); if (result.isEmpty()) return false; else { ItemStack output = (ItemStack) inventory.getStackInSlot(2); ItemStack slug = (ItemStack) inventory.getStackInSlot(3); if (output.isEmpty()) return true; if (!output.isItemEqual(result)) return false; int res1 = output.getCount() + result.getCount(); int res2 = slug.getCount() + 1; return (res1 <= 64 && res1 <= output.getMaxStackSize()) || (res2 <= 64 && res2 <= slug.getMaxStackSize()); } } } public static int getItemBurnTime(ItemStack fuel) { if (fuel.isEmpty()) return 0; else { Item item = fuel.getItem(); if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.AIR) { Block block = Block.getBlockFromItem(item); if (block == Blocks.WOODEN_SLAB) return 100; if (block == Blocks.ACACIA_STAIRS || block == Blocks.OAK_STAIRS || block == Blocks.JUNGLE_STAIRS || block == Blocks.BIRCH_STAIRS || block == Blocks.DARK_OAK_STAIRS || block == Blocks.SPRUCE_STAIRS) return 150; if (block.getDefaultState().getMaterial() == Material.WOOD) return 200; if (block == Blocks.COAL_BLOCK) return 14400; } if (item instanceof ItemTool && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemSword && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemHoe && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item == Items.STICK) return 50; if (item == Items.COAL) return 1600; if (item == Items.LAVA_BUCKET) return 20000; if (item == Item.getItemFromBlock(Blocks.SAPLING)) return 70; if (item == Items.BLAZE_ROD) return 1600; return ForgeEventFactory.getItemBurnTime(fuel); } } public static boolean isItemFuel(ItemStack fuel) { return getItemBurnTime(fuel) > 0; } public boolean isUsableByPlayer(EntityPlayer player) { return world.getTileEntity(pos) != this ? false : player.getDistanceSq((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D) <= 64.0D; } public boolean isItemValidForSlot(int index, ItemStack stack) { if (index == 2 || index == 3) return false; if (index != 1) return true; else { return isItemFuel(stack); } } public int getField(int id) { switch (id) { case 0: return burnTime; case 1: return currentBurnTime; case 2: return cookTime; case 3: return totalCookTime; default: return 0; } } public void setField(int id, int value) { switch (id) { case 0: burnTime = value; break; case 1: currentBurnTime = value; break; case 2: cookTime = value; break; case 3: totalCookTime = value; } } } I made constants and removed hard-coding on readFromNBT and writeToNBT. Edited June 23, 2019 by hyper1423 Quote
DavidM Posted June 23, 2019 Posted June 23, 2019 It seems like you are following HarryTalks’ tutorials. Stop. His tutorials are terrible as they use outdated code and promote bad practices. Quote Some tips: Spoiler Modder Support: Spoiler 1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code. 2. Always post your code. 3. Never copy and paste code. You won't learn anything from doing that. 4. Quote Programming via Eclipse's hotfixes will get you nowhere 5. Learn to use your IDE, especially the debugger. 6. Quote The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it. Support & Bug Reports: Spoiler 1. Read the EAQ before asking for help. Remember to provide the appropriate log(s). 2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.
hyper1423 Posted June 23, 2019 Author Posted June 23, 2019 4 minutes ago, DavidM said: It seems like you are following HarryTalks’ tutorials. Stop. His tutorials are terrible as they use outdated code and promote bad practices. Should I rewrite the whole code? Quote
Draco18s Posted June 23, 2019 Posted June 23, 2019 (edited) 1 hour ago, hyper1423 said: Should I override it like this? Reveal hidden contents @Override public boolean hasTileEntity() { // TODO Auto-generated method stub return super.hasTileEntity(this.getDefaultState()); } @Override public TileEntity createTileEntity(World world, IBlockState state) { // TODO Auto-generated method stub return super.createTileEntity(world, state); } No, because the super class does not return useful values. You need to return the correct values. Quote Are you saying to remove BlastFurnace.currentFuel? Yes. Blocks cannot store data. Block classes are singleton instances, meaning that the data is shared across all blocks of that type. That's why you have a TileEntity for per-location specific data. Quote What do you mean? Should I remove BlockBase class and add methods in the BlockBase class in each block classes? Yes, essentially. There is already a "base block class" its called Block. Quote I changed TileEntity Like This: Reveal hidden contents package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.init.ModItems; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class TileEntityBlastFurnace extends TileEntity implements ITickable { private ItemStackHandler inventory = new ItemStackHandler(4); private String customname; private ItemStack smelting = ItemStack.EMPTY; private final String[] nbtTags = { "BurnTime", "CookTime", "CookTimeTotal" }; private final String inventoryKey = "inventory"; private int burnTime = 0; private int currentBurnTime = 0; private int cookTime = 0; private int totalCookTime = 600; @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { // TODO Auto-generated method stub if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true; else return false; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { // TODO Auto-generated method stub if (hasCapability(capability, null)) return (T) this.inventory; return super.getCapability(capability, facing); } public boolean hasCustomName() { return customname != null && !customname.isEmpty(); } public void setCustomName(String customname) { this.customname = customname; } @Override public ITextComponent getDisplayName() { return this.hasCustomName() ? new TextComponentString(this.customname) : new TextComponentTranslation("container.blast_furnace"); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.inventory.deserializeNBT(compound.getCompoundTag(inventoryKey)); burnTime = compound.getInteger(nbtTags[0]); cookTime = compound.getInteger(nbtTags[1]); totalCookTime = compound.getInteger(nbtTags[2]); currentBurnTime = getItemBurnTime((ItemStack) inventory.getStackInSlot(1)); if (compound.hasKey("CustomName", 8)) setCustomName(compound.getString("CustomName")); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger(nbtTags[0], (short) burnTime); compound.setInteger(nbtTags[1], (short) cookTime); compound.setInteger(nbtTags[2], (short) totalCookTime); compound.setTag(inventoryKey, this.inventory.serializeNBT()); if (hasCustomName()) compound.setString("CustomName", customname); return compound; } public boolean isBurning() { return burnTime > 0; } @SideOnly(Side.CLIENT) public static boolean isBurning(TileEntityBlastFurnace te) { return te.getField(0) > 0; } @Override public void update() { if (isBurning()) { --burnTime; BlastFurnace.setState(true, world, pos); } ItemStack fuel = (ItemStack) inventory.getStackInSlot(1); if (isBurning() || !fuel.isEmpty() && !inventory.getStackInSlot(0).isEmpty()) { if (!isBurning() && canSmelt()) { burnTime = getItemBurnTime(fuel); currentBurnTime = burnTime; if (isBurning() && !fuel.isEmpty()) { Item item = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { ItemStack item1 = item.getContainerItem(fuel); inventory.setStackInSlot(1, item1); } } } if (isBurning() && canSmelt() && cookTime > 0) { cookTime++; if (cookTime == totalCookTime) { if (inventory.getStackInSlot(2).getCount() > 0) { inventory.getStackInSlot(2).grow(1); } else { inventory.insertItem(2, smelting, false); } if (inventory.getStackInSlot(3).getCount() > 0) { inventory.getStackInSlot(3).grow(1); } else { inventory.insertItem(3, new ItemStack(ModItems.SLUG, 1), false); } } smelting = ItemStack.EMPTY; cookTime = 0; return; } // } else if (!isBurning() && cookTime > 0) { // if (cookTime > getCookTime(inventory.getStackInSlot(1)) / 3) // cookTime = MathHelper.clamp(cookTime - 3, 0, totalCookTime); // else // MathHelper.clamp(cookTime - 2, 0, totalCookTime); else { if (this.canSmelt() && this.isBurning()) { ItemStack output = BlastFurnaceRecipes.getInstance().getResult(inventory.getStackInSlot(0)); if (!output.isEmpty()) { smelting = output; cookTime++; inventory.getStackInSlot(0).shrink(1); } } } } // if (flag != isBurning()) { // flag1 = true; // BlastFurnace.setState(isBurning(), world, pos); // } // } // if (flag1) { // markDirty(); // } } private boolean canSmelt() { if (((ItemStack) inventory.getStackInSlot(0)).isEmpty()) return false; else { ItemStack result = BlastFurnaceRecipes.getInstance().getResult((ItemStack) inventory.getStackInSlot(0)); if (result.isEmpty()) return false; else { ItemStack output = (ItemStack) inventory.getStackInSlot(2); ItemStack slug = (ItemStack) inventory.getStackInSlot(3); if (output.isEmpty()) return true; if (!output.isItemEqual(result)) return false; int res1 = output.getCount() + result.getCount(); int res2 = slug.getCount() + 1; return (res1 <= 64 && res1 <= output.getMaxStackSize()) || (res2 <= 64 && res2 <= slug.getMaxStackSize()); } } } public static int getItemBurnTime(ItemStack fuel) { if (fuel.isEmpty()) return 0; else { Item item = fuel.getItem(); if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.AIR) { Block block = Block.getBlockFromItem(item); if (block == Blocks.WOODEN_SLAB) return 100; if (block == Blocks.ACACIA_STAIRS || block == Blocks.OAK_STAIRS || block == Blocks.JUNGLE_STAIRS || block == Blocks.BIRCH_STAIRS || block == Blocks.DARK_OAK_STAIRS || block == Blocks.SPRUCE_STAIRS) return 150; if (block.getDefaultState().getMaterial() == Material.WOOD) return 200; if (block == Blocks.COAL_BLOCK) return 14400; } if (item instanceof ItemTool && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemSword && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemHoe && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item == Items.STICK) return 50; if (item == Items.COAL) return 1600; if (item == Items.LAVA_BUCKET) return 20000; if (item == Item.getItemFromBlock(Blocks.SAPLING)) return 70; if (item == Items.BLAZE_ROD) return 1600; return ForgeEventFactory.getItemBurnTime(fuel); } } public static boolean isItemFuel(ItemStack fuel) { return getItemBurnTime(fuel) > 0; } public boolean isUsableByPlayer(EntityPlayer player) { return world.getTileEntity(pos) != this ? false : player.getDistanceSq((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D) <= 64.0D; } public boolean isItemValidForSlot(int index, ItemStack stack) { if (index == 2 || index == 3) return false; if (index != 1) return true; else { return isItemFuel(stack); } } public int getField(int id) { switch (id) { case 0: return burnTime; case 1: return currentBurnTime; case 2: return cookTime; case 3: return totalCookTime; default: return 0; } } public void setField(int id, int value) { switch (id) { case 0: burnTime = value; break; case 1: currentBurnTime = value; break; case 2: cookTime = value; break; case 3: totalCookTime = value; } } } I made constants and removed hard-coding on readFromNBT and writeToNBT. "CustomName" is still a hard-coded string. And also a bad name. Edited June 23, 2019 by Draco18s 1 Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
hyper1423 Posted June 23, 2019 Author Posted June 23, 2019 7 minutes ago, Draco18s said: "CustomName" is still a hard-coded string. And also a bad name. Could you say some examples of better name? Quote
DavidM Posted June 23, 2019 Posted June 23, 2019 2 hours ago, hyper1423 said: Should I rewrite the whole code? Personally, I would say yes. i.e. All the custom name part are completely not necessary, and the getField/setField with an id is pointless. use normal getters and setters instead. Quote Some tips: Spoiler Modder Support: Spoiler 1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code. 2. Always post your code. 3. Never copy and paste code. You won't learn anything from doing that. 4. Quote Programming via Eclipse's hotfixes will get you nowhere 5. Learn to use your IDE, especially the debugger. 6. Quote The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it. Support & Bug Reports: Spoiler 1. Read the EAQ before asking for help. Remember to provide the appropriate log(s). 2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.
hyper1423 Posted June 23, 2019 Author Posted June 23, 2019 Changing code caused another problem. It does not open GUI. Spoiler [17:26:59] [Server thread/FATAL] [minecraft/MinecraftServer]: Error executing task java.util.concurrent.ExecutionException: java.lang.NullPointerException at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_172] at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_172] at net.minecraft.util.Util.runTask(Util.java:54) [Util.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:798) [MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:743) [MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192) [IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:592) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_172] Caused by: java.lang.NullPointerException at com.hyper1423.somestuff.blocks.machines.blastfurnace.ContainerBlastFurnace.<init>(ContainerBlastFurnace.java:25) ~[ContainerBlastFurnace.class:?] at com.hyper1423.somestuff.util.handlers.GuiHandler.getServerGuiElement(GuiHandler.java:20) ~[GuiHandler.class:?] at net.minecraftforge.fml.common.network.NetworkRegistry.getRemoteGuiContainer(NetworkRegistry.java:253) ~[NetworkRegistry.class:?] at net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:88) ~[FMLNetworkHandler.class:?] at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2809) ~[EntityPlayer.class:?] at com.hyper1423.somestuff.blocks.machines.blastfurnace.BlastFurnace.onBlockActivated(BlastFurnace.java:87) ~[BlastFurnace.class:?] at net.minecraft.server.management.PlayerInteractionManager.processRightClickBlock(PlayerInteractionManager.java:475) ~[PlayerInteractionManager.class:?] at net.minecraft.network.NetHandlerPlayServer.processTryUseItemOnBlock(NetHandlerPlayServer.java:769) ~[NetHandlerPlayServer.class:?] at net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock.processPacket(CPacketPlayerTryUseItemOnBlock.java:68) ~[CPacketPlayerTryUseItemOnBlock.class:?] at net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock.processPacket(CPacketPlayerTryUseItemOnBlock.java:13) ~[CPacketPlayerTryUseItemOnBlock.class:?] at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?] at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_172] at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_172] at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?] ... 5 more These are the codes: Block class: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import java.util.Random; import com.hyper1423.somestuff.Main; import com.hyper1423.somestuff.init.ModBlocks; import com.hyper1423.somestuff.init.ModItems; import com.hyper1423.somestuff.util.IHasModel; import com.hyper1423.somestuff.util.Reference; import net.minecraft.block.Block; import net.minecraft.block.BlockHorizontal; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyDirection; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class BlastFurnace extends Block implements IHasModel { public static final PropertyDirection FACING = BlockHorizontal.FACING; public static final PropertyBool BURNING = PropertyBool.create("burning"); public BlastFurnace(String name, Material material) { this(name, material, Main.someStuff); } public BlastFurnace(String name, Material material, CreativeTabs creativeTab) { super(material); setUnlocalizedName(name); setRegistryName(name); setCreativeTab(creativeTab); setSoundType(SoundType.ANVIL); setHardness(5.0f); setResistance(5.0f); setHarvestLevel("pickaxe", 1); setLightLevel(0.0f); // setLightOpacity(1); // setBlockUnbreakable(); this.setDefaultState( this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH).withProperty(BURNING, false)); ModBlocks.BLOCKS.add(this); ModItems.ITEMS.add(new ItemBlock(this).setRegistryName(this.getRegistryName())); } @Override public void registerModels() { Main.proxy.registerItemRenderer(Item.getItemFromBlock(this), 0, "inventory"); } @Override public Item getItemDropped(IBlockState state, Random rand, int fortune) { return Item.getItemFromBlock(ModBlocks.BLAST_FURNACE); } @Override public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { return new ItemStack(ModBlocks.BLAST_FURNACE); } @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (!worldIn.isRemote) { playerIn.openGui(Main.instance, Reference.GUI_BLAST_FURNACE, worldIn, pos.getX(), pos.getY(), pos.getZ()); } return true; } @Override public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { // TODO Auto-generated method stub if (!worldIn.isRemote) { IBlockState north = worldIn.getBlockState(pos.north()); IBlockState south = worldIn.getBlockState(pos.south()); IBlockState west = worldIn.getBlockState(pos.west()); IBlockState east = worldIn.getBlockState(pos.east()); EnumFacing face = (EnumFacing) state.getValue(FACING); if (face == EnumFacing.NORTH) face = EnumFacing.SOUTH; if (face == EnumFacing.SOUTH) face = EnumFacing.NORTH; if (face == EnumFacing.WEST) face = EnumFacing.EAST; if (face == EnumFacing.EAST) face = EnumFacing.WEST; worldIn.setBlockState(pos, state.withProperty(FACING, face), 2); } } public static void setState(boolean active, World worldIn, BlockPos pos) { IBlockState state = worldIn.getBlockState(pos); TileEntity tileentity = worldIn.getTileEntity(pos); if (active) worldIn.setBlockState(pos, ModBlocks.BLAST_FURNACE.getDefaultState() .withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, true), 1 | 2); else worldIn.setBlockState(pos, ModBlocks.BLAST_FURNACE.getDefaultState() .withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, false), 1 | 2); if (tileentity != null) { tileentity.validate(); worldIn.setTileEntity(pos, tileentity); } } @Override public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { // TODO Auto-generated method stub return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { // TODO Auto-generated method stub worldIn.setBlockState(pos, this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()), 2); } @Override public EnumBlockRenderType getRenderType(IBlockState state) { // TODO Auto-generated method stub return EnumBlockRenderType.MODEL; } @Override public IBlockState withRotation(IBlockState state, Rotation rot) { // TODO Auto-generated method stub return state.withProperty(FACING, rot.rotate((EnumFacing) state.getValue(FACING))); } @Override public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { // TODO Auto-generated method stub return state.withRotation(mirrorIn.toRotation((EnumFacing) state.getValue(FACING))); } @Override protected BlockStateContainer createBlockState() { // TODO Auto-generated method stub return new BlockStateContainer(this, new IProperty[] { BURNING, FACING }); } @Override public IBlockState getStateFromMeta(int meta) { // TODO Auto-generated method stub EnumFacing facing = EnumFacing.getFront(meta); if (facing.getAxis() == EnumFacing.Axis.Y) facing = EnumFacing.NORTH; return this.getDefaultState().withProperty(FACING, facing); } @Override public int getMetaFromState(IBlockState state) { // TODO Auto-generated method stub return ((EnumFacing) state.getValue(FACING)).getIndex(); } @Override public boolean hasTileEntity() { // TODO Auto-generated method stub return this.hasTileEntity; } @Override public TileEntity createTileEntity(World world, IBlockState state) { // TODO Auto-generated method stub return new TileEntityBlastFurnace(); } } TileEntity class: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import javax.annotation.Nullable; import com.hyper1423.somestuff.init.ModItems; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class TileEntityBlastFurnace extends TileEntity implements ITickable { private ItemStackHandler inventory = new ItemStackHandler(4); private String customName; private ItemStack smelting = ItemStack.EMPTY; private final String[] nbtTags = { "BurnTime", "CookTime", "CookTimeTotal" }; private final String inventoryKey = "inventory"; private final String customNameKey = "CustomName"; public int burnTime = 0; public int currentBurnTime = 0; public int cookTime = 0; public int totalCookTime = 600; public boolean hasCustomName() { return customName != null && !customName.isEmpty(); } public void setCustomName(String customname) { this.customName = customname; } @Override public ITextComponent getDisplayName() { return this.hasCustomName() ? new TextComponentString(this.customName) : new TextComponentTranslation("container.blast_furnace"); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.inventory.deserializeNBT(compound.getCompoundTag(inventoryKey)); burnTime = compound.getInteger(nbtTags[0]); cookTime = compound.getInteger(nbtTags[1]); totalCookTime = compound.getInteger(nbtTags[2]); currentBurnTime = getItemBurnTime((ItemStack) inventory.getStackInSlot(1)); if (compound.hasKey(customNameKey, 8)) setCustomName(compound.getString(customNameKey)); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger(nbtTags[0], (short) burnTime); compound.setInteger(nbtTags[1], (short) cookTime); compound.setInteger(nbtTags[2], (short) totalCookTime); compound.setTag(inventoryKey, this.inventory.serializeNBT()); if (hasCustomName()) compound.setString(customNameKey, customName); return compound; } public boolean isBurning() { return burnTime > 0; } @SideOnly(Side.CLIENT) public static boolean isBurning(TileEntityBlastFurnace te) { return te.burnTime > 0; } @Override public void update() { if (isBurning()) { --burnTime; BlastFurnace.setState(true, world, pos); } ItemStack fuel = (ItemStack) inventory.getStackInSlot(1); if (isBurning() || !fuel.isEmpty() && !inventory.getStackInSlot(0).isEmpty()) { if (!isBurning() && canSmelt()) { burnTime = getItemBurnTime(fuel); currentBurnTime = burnTime; if (isBurning() && !fuel.isEmpty()) { Item item = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { ItemStack item1 = item.getContainerItem(fuel); inventory.setStackInSlot(1, item1); } } } if (isBurning() && canSmelt() && cookTime > 0) { cookTime++; if (cookTime == totalCookTime) { if (inventory.getStackInSlot(2).getCount() > 0) { inventory.getStackInSlot(2).grow(1); } else { inventory.insertItem(2, smelting, false); } if (inventory.getStackInSlot(3).getCount() > 0) { inventory.getStackInSlot(3).grow(1); } else { inventory.insertItem(3, new ItemStack(ModItems.SLUG, 1), false); } } smelting = ItemStack.EMPTY; cookTime = 0; return; } // } else if (!isBurning() && cookTime > 0) { // if (cookTime > getCookTime(inventory.getStackInSlot(1)) / 3) // cookTime = MathHelper.clamp(cookTime - 3, 0, totalCookTime); // else // MathHelper.clamp(cookTime - 2, 0, totalCookTime); else { if (this.canSmelt() && this.isBurning()) { ItemStack output = BlastFurnaceRecipes.getInstance().getResult(inventory.getStackInSlot(0)); if (!output.isEmpty()) { smelting = output; cookTime++; inventory.getStackInSlot(0).shrink(1); } } } } // if (flag != isBurning()) { // flag1 = true; // BlastFurnace.setState(isBurning(), world, pos); // } // } // if (flag1) { // markDirty(); // } } private boolean canSmelt() { if (((ItemStack) inventory.getStackInSlot(0)).isEmpty()) return false; else { ItemStack result = BlastFurnaceRecipes.getInstance().getResult((ItemStack) inventory.getStackInSlot(0)); if (result.isEmpty()) return false; else { ItemStack output = (ItemStack) inventory.getStackInSlot(2); ItemStack slug = (ItemStack) inventory.getStackInSlot(3); if (output.isEmpty()) return true; if (!output.isItemEqual(result)) return false; int res1 = output.getCount() + result.getCount(); int res2 = slug.getCount() + 1; return (res1 <= 64 && res1 <= output.getMaxStackSize()) || (res2 <= 64 && res2 <= slug.getMaxStackSize()); } } } public static int getItemBurnTime(ItemStack fuel) { if (fuel.isEmpty()) return 0; else { Item item = fuel.getItem(); if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.AIR) { Block block = Block.getBlockFromItem(item); if (block == Blocks.WOODEN_SLAB) return 100; if (block == Blocks.ACACIA_STAIRS || block == Blocks.OAK_STAIRS || block == Blocks.JUNGLE_STAIRS || block == Blocks.BIRCH_STAIRS || block == Blocks.DARK_OAK_STAIRS || block == Blocks.SPRUCE_STAIRS) return 150; if (block.getDefaultState().getMaterial() == Material.WOOD) return 200; if (block == Blocks.COAL_BLOCK) return 14400; } if (item instanceof ItemTool && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemSword && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemHoe && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item == Items.STICK) return 50; if (item == Items.COAL) return 1600; if (item == Items.LAVA_BUCKET) return 20000; if (item == Item.getItemFromBlock(Blocks.SAPLING)) return 70; if (item == Items.BLAZE_ROD) return 1600; return ForgeEventFactory.getItemBurnTime(fuel); } } public static boolean isItemFuel(ItemStack fuel) { return getItemBurnTime(fuel) > 0; } public boolean isUsableByPlayer(EntityPlayer player) { return world.getTileEntity(pos) != this ? false : player.getDistanceSq((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D) <= 64.0D; } public boolean isItemValidForSlot(int index, ItemStack stack) { if (index == 2 || index == 3) return false; if (index != 1) return true; else { return isItemFuel(stack); } } } Recipe class: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import java.util.Map; import java.util.Map.Entry; import com.google.common.collect.Maps; import com.hyper1423.somestuff.init.ModItems; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; public class BlastFurnaceRecipes { private static final BlastFurnaceRecipes INSTANCE = new BlastFurnaceRecipes(); private final Map<ItemStack, ItemStack> smeltingList = Maps.<ItemStack, ItemStack>newHashMap(); private final Map<ItemStack, Float> experienceList = Maps.<ItemStack, Float>newHashMap(); public static BlastFurnaceRecipes getInstance() { return INSTANCE; } private BlastFurnaceRecipes() { addRecipe(new ItemStack(Blocks.ACACIA_FENCE), new ItemStack(ModItems.SLUG), 5.0F); } public void addRecipe(ItemStack input, ItemStack result, float experience) { if (getResult(input) != ItemStack.EMPTY) return; this.smeltingList.put(input, result); this.experienceList.put(result, Float.valueOf(experience)); } public ItemStack getResult(ItemStack input) { for (Entry<ItemStack, ItemStack> entry : this.smeltingList.entrySet()) { if (this.compareItemStacks(input, (ItemStack) entry.getKey())) { return (ItemStack) entry.getValue(); } } return ItemStack.EMPTY; } private boolean compareItemStacks(ItemStack stack1, ItemStack stack2) { return stack2.getItem() == stack1.getItem() && (stack2.getMetadata() == 32767 || stack2.getMetadata() == stack1.getMetadata()); } public Map<ItemStack, ItemStack> getDualSmeltingList() { return this.smeltingList; } public float getResultExperience(ItemStack stack) { for (Entry<ItemStack, Float> entry : this.experienceList.entrySet()) { if (this.compareItemStacks(stack, (ItemStack) entry.getKey())) { return ((Float) entry.getValue()).floatValue(); } } return 0.0F; } } GUI class: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.util.Reference; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.util.ResourceLocation; public class GuiBlastFurnace extends GuiContainer { private static final ResourceLocation TEXTURES = new ResourceLocation(Reference.MOD_ID, "textures/gui/blast_furnace.png"); private final InventoryPlayer player; private final TileEntityBlastFurnace tileentity; public GuiBlastFurnace(InventoryPlayer player, TileEntityBlastFurnace tileentity) { super(new ContainerBlastFurnace(player, tileentity)); this.player = player; this.tileentity = tileentity; // TODO Auto-generated constructor stub } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { // TODO Auto-generated method stub if (this.tileentity.getDisplayName() != null) { String tileName = this.tileentity.getDisplayName().getUnformattedText(); this.fontRenderer.drawString(tileName, (this.xSize / 2 - this.fontRenderer.getStringWidth(tileName) / 2) + 3, 8, 0x404040); this.fontRenderer.drawString(this.player.getDisplayName().getUnformattedText(), 8, this.ySize - 96 + 2, 0x404040); } } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f); this.mc.getTextureManager().bindTexture(TEXTURES); this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); if (TileEntityBlastFurnace.isBurning(tileentity)) { int k = this.getBurnLeftScaled(13); this.drawTexturedModalRect(this.guiLeft + 36, this.guiTop + 37 + 12 - k, 176, 12 - k, 14, k + 1); } int l = this.getCookProgressScaled(24); this.drawTexturedModalRect(this.guiLeft + 58, this.guiTop + 35, 176, 14, l + 1, 16); } private int getBurnLeftScaled(int pixels) { int i = this.tileentity.currentBurnTime; int j = this.tileentity.burnTime; if (i == 0) i = 200; return j * pixels / i; } private int getCookProgressScaled(int pixels) { int i = this.tileentity.cookTime; int j = this.tileentity.totalCookTime; return j != 0 && i != 0 ? i * pixels / j : 0; } } And container class: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.blocks.machines.blastfurnace.slots.SlotBlastFurnaceFuel; import com.hyper1423.somestuff.blocks.machines.blastfurnace.slots.SlotBlastFurnaceOutput; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IContainerListener; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; public class ContainerBlastFurnace extends Container { private final TileEntityBlastFurnace tileentity; private int cookTime, totalCookTime, burnTime, currentBurnTime; public ContainerBlastFurnace(InventoryPlayer player, TileEntityBlastFurnace tileentity) { this.tileentity = tileentity; IItemHandler inventory = tileentity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); this.addSlotToContainer(new SlotItemHandler(inventory, 0, 35, 17)); this.addSlotToContainer(new SlotBlastFurnaceFuel(inventory, 1, 35, 53)); this.addSlotToContainer(new SlotBlastFurnaceOutput(player.player, inventory, 2, 95, 35)); this.addSlotToContainer(new SlotBlastFurnaceOutput(player.player, inventory, 3, 143, 53)); for (int y = 0; y < 3; y++) { for (int x = 0; x < 9; x++) { this.addSlotToContainer(new Slot(player, x + y * 9 + 9, 8 + x * 18, 84 + y * 18)); } } for (int x = 0; x < 9; x++) { this.addSlotToContainer(new Slot(player, x, 8 + x * 18, 142)); } } @Override public void detectAndSendChanges() { // TODO Auto-generated method stub super.detectAndSendChanges(); for (int i = 0; i < this.listeners.size(); ++i) { IContainerListener listener = (IContainerListener) this.listeners.get(i); if (this.burnTime != this.tileentity.burnTime) listener.sendWindowProperty(this, 0, this.tileentity.burnTime); if (this.currentBurnTime != this.tileentity.currentBurnTime) listener.sendWindowProperty(this, 1, this.tileentity.currentBurnTime); if (this.cookTime != this.tileentity.cookTime) listener.sendWindowProperty(this, 2, this.tileentity.cookTime); if (this.totalCookTime != this.tileentity.totalCookTime) listener.sendWindowProperty(this, 3, this.tileentity.totalCookTime); } this.burnTime = this.tileentity.burnTime; this.currentBurnTime = this.tileentity.currentBurnTime; this.cookTime = this.tileentity.cookTime; this.totalCookTime = this.tileentity.totalCookTime; } @Override @SideOnly(Side.CLIENT) public void updateProgressBar(int id, int data) { // TODO Auto-generated method stub switch (id) { case 0: this.tileentity.burnTime = data; break; case 1: this.tileentity.currentBurnTime = data; break; case 2: this.tileentity.cookTime = data; break; case 3: this.tileentity.totalCookTime = data; break; } } @Override public boolean canInteractWith(EntityPlayer playerIn) { // TODO Auto-generated method stub return this.tileentity.isUsableByPlayer(playerIn); } @Override public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack stack = ItemStack.EMPTY; Slot slot = (Slot) this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack stack1 = slot.getStack(); stack = stack1.copy(); if (index == 2 || index == 3) { if (!this.mergeItemStack(stack1, 4, 40, true)) return ItemStack.EMPTY; slot.onSlotChange(stack1, stack); } else if (index != 1 && index != 0) { if (!BlastFurnaceRecipes.getInstance().getResult(stack1).isEmpty()) { if (!this.mergeItemStack(stack1, 0, 1, false)) { return ItemStack.EMPTY; } else if (TileEntityBlastFurnace.isItemFuel(stack1)) { if (!this.mergeItemStack(stack1, 1, 2, false)) return ItemStack.EMPTY; } else if (TileEntityBlastFurnace.isItemFuel(stack1)) { if (!this.mergeItemStack(stack1, 1, 2, false)) return ItemStack.EMPTY; } else if (TileEntityBlastFurnace.isItemFuel(stack1)) { if (!this.mergeItemStack(stack1, 1, 2, false)) return ItemStack.EMPTY; } else if (index >= 4 && index < 31) { if (!this.mergeItemStack(stack1, 31, 40, false)) return ItemStack.EMPTY; } else if (index >= 31 && index < 40 && !this.mergeItemStack(stack1, 4, 31, false)) { return ItemStack.EMPTY; } } } else if (!this.mergeItemStack(stack1, 4, 40, false)) { return ItemStack.EMPTY; } if (stack1.isEmpty()) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } if (stack1.getCount() == stack.getCount()) return ItemStack.EMPTY; slot.onTake(playerIn, stack1); } return stack; } } Slots are not changed. Also, when I shift-rightclick on the blast furnace, it just change its direction and no block is added. Spoiler I placed blast furnace blocks.I shift-right-clicked the block with a blast furnace item. It changes its direction. Quote
hyper1423 Posted June 27, 2019 Author Posted June 27, 2019 (edited) On 6/23/2019 at 8:51 PM, diesieben07 said: This will always return null, since your TE does not expose the ITEM_HANDLER_CAPABILITY. How do I expose ITEM_HANDLER_CAPABILITY? I tried to expose it as the way in the official forge tutorial, but it doesn't work. TileEntity: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import com.hyper1423.somestuff.init.ModItems; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.NonNullList; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class TileEntityBlastFurnace extends TileEntity implements ITickable { private ItemStackHandler inventory = new ItemStackHandler(NonNullList.withSize(4, ItemStack.EMPTY)); private String customName; private ItemStack smelting = ItemStack.EMPTY; private static final String BURNTIME_KEY = "BurnTime"; private static final String COOKTIME_KEY = "CookTime"; private static final String COOKTIMETOTAL_KEY = "CookTimeTotal"; private static final String INVENTORY_KEY = "inventory"; private static final String CUSTOMNAME_KEY = "CustomName"; public int burnTime = 0; public int currentBurnTime = 0; public int cookTime = 0; public int totalCookTime = 600; @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { // TODO Auto-generated method stub if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true; return super.hasCapability(capability, facing); } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { // TODO Auto-generated method stub if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T) this.inventory; return super.getCapability(capability, facing); } public boolean hasCustomName() { return customName != null && !customName.isEmpty(); } public void setCustomName(String customname) { this.customName = customname; } @Override public ITextComponent getDisplayName() { return this.hasCustomName() ? new TextComponentString(this.customName) : new TextComponentTranslation("container.blast_furnace"); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.inventory.deserializeNBT(compound.getCompoundTag(INVENTORY_KEY)); burnTime = compound.getInteger(BURNTIME_KEY); cookTime = compound.getInteger(COOKTIME_KEY); totalCookTime = compound.getInteger(COOKTIMETOTAL_KEY); currentBurnTime = getItemBurnTime((ItemStack) inventory.getStackInSlot(1)); if (compound.hasKey(CUSTOMNAME_KEY, 8)) setCustomName(compound.getString(CUSTOMNAME_KEY)); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger(BURNTIME_KEY, (short) burnTime); compound.setInteger(COOKTIME_KEY, (short) cookTime); compound.setInteger(COOKTIMETOTAL_KEY, (short) totalCookTime); compound.setTag(INVENTORY_KEY, this.inventory.serializeNBT()); if (hasCustomName()) compound.setString(CUSTOMNAME_KEY, customName); return compound; } public boolean isBurning() { return burnTime > 0; } @SideOnly(Side.CLIENT) public static boolean isBurning(TileEntityBlastFurnace te) { return te.burnTime > 0; } @Override public void update() { if (isBurning()) { --burnTime; BlastFurnace.setState(true, world, pos); } ItemStack fuel = (ItemStack) inventory.getStackInSlot(1); if (isBurning() || !fuel.isEmpty() && !inventory.getStackInSlot(0).isEmpty()) { if (!isBurning() && canSmelt()) { burnTime = getItemBurnTime(fuel); currentBurnTime = burnTime; if (isBurning() && !fuel.isEmpty()) { Item item = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { ItemStack item1 = item.getContainerItem(fuel); inventory.setStackInSlot(1, item1); } } } if (isBurning() && canSmelt() && cookTime > 0) { cookTime++; if (cookTime == totalCookTime) { if (inventory.getStackInSlot(2).getCount() > 0) { inventory.getStackInSlot(2).grow(1); } else { inventory.insertItem(2, smelting, false); } if (inventory.getStackInSlot(3).getCount() > 0) { inventory.getStackInSlot(3).grow(1); } else { inventory.insertItem(3, new ItemStack(ModItems.SLUG, 1), false); } } smelting = ItemStack.EMPTY; cookTime = 0; return; } // } else if (!isBurning() && cookTime > 0) { // if (cookTime > getCookTime(inventory.getStackInSlot(1)) / 3) // cookTime = MathHelper.clamp(cookTime - 3, 0, totalCookTime); // else // MathHelper.clamp(cookTime - 2, 0, totalCookTime); else { if (this.canSmelt() && this.isBurning()) { ItemStack output = BlastFurnaceRecipes.getInstance().getResult(inventory.getStackInSlot(0)); if (!output.isEmpty()) { smelting = output; cookTime++; inventory.getStackInSlot(0).shrink(1); } } } } // if (flag != isBurning()) { // flag1 = true; // BlastFurnace.setState(isBurning(), world, pos); // } // } // if (flag1) { // markDirty(); // } } private boolean canSmelt() { if (((ItemStack) inventory.getStackInSlot(0)).isEmpty()) return false; else { ItemStack result = BlastFurnaceRecipes.getInstance().getResult((ItemStack) inventory.getStackInSlot(0)); if (result.isEmpty()) return false; else { ItemStack output = (ItemStack) inventory.getStackInSlot(2); ItemStack slug = (ItemStack) inventory.getStackInSlot(3); if (output.isEmpty()) return true; if (!output.isItemEqual(result)) return false; int res1 = output.getCount() + result.getCount(); int res2 = slug.getCount() + 1; return (res1 <= 64 && res1 <= output.getMaxStackSize()) || (res2 <= 64 && res2 <= slug.getMaxStackSize()); } } } public static int getItemBurnTime(ItemStack fuel) { if (fuel.isEmpty()) return 0; else { Item item = fuel.getItem(); if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.AIR) { Block block = Block.getBlockFromItem(item); if (block == Blocks.WOODEN_SLAB) return 100; if (block == Blocks.ACACIA_STAIRS || block == Blocks.OAK_STAIRS || block == Blocks.JUNGLE_STAIRS || block == Blocks.BIRCH_STAIRS || block == Blocks.DARK_OAK_STAIRS || block == Blocks.SPRUCE_STAIRS) return 150; if (block.getDefaultState().getMaterial() == Material.WOOD) return 200; if (block == Blocks.COAL_BLOCK) return 14400; } if (item instanceof ItemTool && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemSword && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item instanceof ItemHoe && "WOOD".contentEquals(((ItemTool) item).getToolMaterialName())) return 180; if (item == Items.STICK) return 50; if (item == Items.COAL) return 1600; if (item == Items.LAVA_BUCKET) return 20000; if (item == Item.getItemFromBlock(Blocks.SAPLING)) return 70; if (item == Items.BLAZE_ROD) return 1600; return ForgeEventFactory.getItemBurnTime(fuel); } } public static boolean isItemFuel(ItemStack fuel) { return getItemBurnTime(fuel) > 0; } public boolean isUsableByPlayer(EntityPlayer player) { return world.getTileEntity(pos) != this ? false : player.getDistanceSq((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D) <= 64.0D; } public boolean isItemValidForSlot(int index, ItemStack stack) { if (index == 2 || index == 3) return false; if (index != 1) return true; else { return isItemFuel(stack); } } } Block: Spoiler package com.hyper1423.somestuff.blocks.machines.blastfurnace; import java.util.Random; import com.hyper1423.somestuff.Main; import com.hyper1423.somestuff.init.ModBlocks; import com.hyper1423.somestuff.init.ModItems; import com.hyper1423.somestuff.util.Reference; import net.minecraft.block.Block; import net.minecraft.block.BlockHorizontal; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyDirection; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class BlastFurnace extends Block { public static final PropertyDirection FACING = BlockHorizontal.FACING; public static final PropertyBool BURNING = PropertyBool.create("burning"); public BlastFurnace(String name, Material material) { this(name, material, Main.someStuff); } public BlastFurnace(String name, Material material, CreativeTabs creativeTab) { super(material); setUnlocalizedName(name); setRegistryName(name); setCreativeTab(creativeTab); setSoundType(SoundType.ANVIL); setHardness(5.0f); setResistance(5.0f); setHarvestLevel("pickaxe", 1); setLightLevel(0.0f); // setLightOpacity(1); // setBlockUnbreakable(); this.setDefaultState( this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH).withProperty(BURNING, false)); ModBlocks.BLOCKS.add(this); ModItems.ITEMS.add(new ItemBlock(this).setRegistryName(this.getRegistryName())); } public void registerModels() { Main.proxy.registerItemRenderer(Item.getItemFromBlock(this), 0, "inventory"); } @Override public Item getItemDropped(IBlockState state, Random rand, int fortune) { return Item.getItemFromBlock(ModBlocks.BLAST_FURNACE); } @Override public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { return new ItemStack(ModBlocks.BLAST_FURNACE); } @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (!worldIn.isRemote) { playerIn.openGui(Main.instance, Reference.GUI_BLAST_FURNACE, worldIn, pos.getX(), pos.getY(), pos.getZ()); } return true; } @Override public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { // TODO Auto-generated method stub if (!worldIn.isRemote) { IBlockState north = worldIn.getBlockState(pos.north()); IBlockState south = worldIn.getBlockState(pos.south()); IBlockState west = worldIn.getBlockState(pos.west()); IBlockState east = worldIn.getBlockState(pos.east()); EnumFacing face = (EnumFacing) state.getValue(FACING); if (face == EnumFacing.NORTH) face = EnumFacing.SOUTH; if (face == EnumFacing.SOUTH) face = EnumFacing.NORTH; if (face == EnumFacing.WEST) face = EnumFacing.EAST; if (face == EnumFacing.EAST) face = EnumFacing.WEST; worldIn.setBlockState(pos, state.withProperty(FACING, face), 2); } } public static void setState(boolean active, World worldIn, BlockPos pos) { IBlockState state = worldIn.getBlockState(pos); TileEntity tileentity = worldIn.getTileEntity(pos); if (active) worldIn.setBlockState(pos, ModBlocks.BLAST_FURNACE.getDefaultState() .withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, true), 1 | 2); else worldIn.setBlockState(pos, ModBlocks.BLAST_FURNACE.getDefaultState() .withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, false), 1 | 2); if (tileentity != null) { tileentity.validate(); worldIn.setTileEntity(pos, tileentity); } } @Override public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { // TODO Auto-generated method stub return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { // TODO Auto-generated method stub worldIn.setBlockState(pos, this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()), 2); } @Override public EnumBlockRenderType getRenderType(IBlockState state) { // TODO Auto-generated method stub return EnumBlockRenderType.MODEL; } @Override public IBlockState withRotation(IBlockState state, Rotation rot) { // TODO Auto-generated method stub return state.withProperty(FACING, rot.rotate((EnumFacing) state.getValue(FACING))); } @Override public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { // TODO Auto-generated method stub return state.withRotation(mirrorIn.toRotation((EnumFacing) state.getValue(FACING))); } @Override protected BlockStateContainer createBlockState() { // TODO Auto-generated method stub return new BlockStateContainer(this, new IProperty[] { BURNING, FACING }); } @Override public IBlockState getStateFromMeta(int meta) { // TODO Auto-generated method stub EnumFacing facing = EnumFacing.getFront(meta); if (facing.getAxis() == EnumFacing.Axis.Y) facing = EnumFacing.NORTH; return this.getDefaultState().withProperty(FACING, facing); } @Override public int getMetaFromState(IBlockState state) { // TODO Auto-generated method stub return ((EnumFacing) state.getValue(FACING)).getIndex(); } @Override public boolean hasTileEntity() { // TODO Auto-generated method stub return this.hasTileEntity; } @Override public TileEntity createTileEntity(World world, IBlockState state) { // TODO Auto-generated method stub return new TileEntityBlastFurnace(); } } Other classes are not changed. Edited June 27, 2019 by hyper1423 Quote
hyper1423 Posted June 27, 2019 Author Posted June 27, 2019 (edited) 22 minutes ago, diesieben07 said: Define "does not work". GUI does not open and occurs a NullPointerException. Edited June 27, 2019 by hyper1423 Quote
hyper1423 Posted June 27, 2019 Author Posted June 27, 2019 (edited) Spoiler [17:46:00] [Server thread/FATAL] [minecraft/MinecraftServer]: Error executing task java.util.concurrent.ExecutionException: java.lang.NullPointerException at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_172] at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_172] at net.minecraft.util.Util.runTask(Util.java:54) [Util.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:798) [MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:743) [MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192) [IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:592) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_172] Caused by: java.lang.NullPointerException at com.hyper1423.somestuff.blocks.machines.blastfurnace.ContainerBlastFurnace.<init>(ContainerBlastFurnace.java:25) ~[ContainerBlastFurnace.class:?] at com.hyper1423.somestuff.util.handlers.GuiHandler.getServerGuiElement(GuiHandler.java:20) ~[GuiHandler.class:?] at net.minecraftforge.fml.common.network.NetworkRegistry.getRemoteGuiContainer(NetworkRegistry.java:253) ~[NetworkRegistry.class:?] at net.minecraftforge.fml.common.network.internal.FMLNetworkHandler.openGui(FMLNetworkHandler.java:88) ~[FMLNetworkHandler.class:?] at net.minecraft.entity.player.EntityPlayer.openGui(EntityPlayer.java:2809) ~[EntityPlayer.class:?] at com.hyper1423.somestuff.blocks.machines.blastfurnace.BlastFurnace.onBlockActivated(BlastFurnace.java:85) ~[BlastFurnace.class:?] at net.minecraft.server.management.PlayerInteractionManager.processRightClickBlock(PlayerInteractionManager.java:475) ~[PlayerInteractionManager.class:?] at net.minecraft.network.NetHandlerPlayServer.processTryUseItemOnBlock(NetHandlerPlayServer.java:769) ~[NetHandlerPlayServer.class:?] at net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock.processPacket(CPacketPlayerTryUseItemOnBlock.java:68) ~[CPacketPlayerTryUseItemOnBlock.class:?] at net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock.processPacket(CPacketPlayerTryUseItemOnBlock.java:13) ~[CPacketPlayerTryUseItemOnBlock.class:?] at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:21) ~[PacketThreadUtil$1.class:?] at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_172] at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_172] at net.minecraft.util.Util.runTask(Util.java:53) ~[Util.class:?] ... 5 more Here it is. Edited June 27, 2019 by hyper1423 Quote
hyper1423 Posted June 27, 2019 Author Posted June 27, 2019 I think the TileEntity instance is null, but I can't find why it is null and how to fix it. Quote
hyper1423 Posted June 27, 2019 Author Posted June 27, 2019 Spoiler package com.hyper1423.somestuff.util.handlers; import java.util.logging.Logger; import com.hyper1423.somestuff.blocks.machines.blastfurnace.ContainerBlastFurnace; import com.hyper1423.somestuff.blocks.machines.blastfurnace.GuiBlastFurnace; import com.hyper1423.somestuff.blocks.machines.blastfurnace.TileEntityBlastFurnace; import com.hyper1423.somestuff.util.Reference; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.network.IGuiHandler; public class GuiHandler implements IGuiHandler { @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { // TODO Auto-generated method stub if(ID == Reference.GUI_BLAST_FURNACE) return new ContainerBlastFurnace(player.inventory, (TileEntityBlastFurnace)world.getTileEntity(new BlockPos(x, y, z))); return null; } @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { // TODO Auto-generated method stub if(ID == Reference.GUI_BLAST_FURNACE) return new GuiBlastFurnace(player.inventory, (TileEntityBlastFurnace)world.getTileEntity(new BlockPos(x, y, z))); return null; } } Quote
hyper1423 Posted June 29, 2019 Author Posted June 29, 2019 (edited) 13 minutes ago, diesieben07 said: The version of hasTileEntity you are using is deprecated. Do not just ignore deprecations. Which hasTileEntity do you mean? Ok, I changed hasTileEntity to the version that is not deprecated. EDIT: It still doesn't open. Edited June 29, 2019 by hyper1423 Quote
hyper1423 Posted June 29, 2019 Author Posted June 29, 2019 (edited) I found that BlastFurnace.hasTileEntity is false and Minecraft does not call BlastFurnace.createTileEntity(World world, IBlockState state). I guess my TileEntity isn't registered correctly. Edited June 29, 2019 by hyper1423 Quote
DavidM Posted June 29, 2019 Posted June 29, 2019 You are supposed to override Block#hasTIleEntity. 1 Quote Some tips: Spoiler Modder Support: Spoiler 1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code. 2. Always post your code. 3. Never copy and paste code. You won't learn anything from doing that. 4. Quote Programming via Eclipse's hotfixes will get you nowhere 5. Learn to use your IDE, especially the debugger. 6. Quote The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it. Support & Bug Reports: Spoiler 1. Read the EAQ before asking for help. Remember to provide the appropriate log(s). 2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.
hyper1423 Posted June 29, 2019 Author Posted June 29, 2019 2 minutes ago, DavidM said: You are supposed to override Block#hasTIleEntity. I overrided it correctly. Quote
hyper1423 Posted June 30, 2019 Author Posted June 30, 2019 (edited) Thank you!!!!!!! It works!!! But it still does not cook item, and use an item in a tick. EDIT: I fixed it. I changed the code like this: Spoiler @Override public void update() { if (isBurning()) { --burnTime; BlastFurnace.setState(true, world, pos); } ItemStack fuel = (ItemStack) inventory.getStackInSlot(1); if (isBurning() || !fuel.isEmpty() && !inventory.getStackInSlot(0).isEmpty()) { if (!isBurning() && canSmelt()) { burnTime = getItemBurnTime(fuel); currentBurnTime = burnTime; if (isBurning() && !fuel.isEmpty()) { Item item = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { ItemStack item1 = item.getContainerItem(fuel); inventory.setStackInSlot(1, item1); } } } if (isBurning() && canSmelt() && cookTime > 0) { cookTime++; if (cookTime == totalCookTime) { if (inventory.getStackInSlot(2).getCount() > 0) { inventory.getStackInSlot(2).grow(1); } else { inventory.insertItem(2, smelting, false); } if (inventory.getStackInSlot(3).getCount() > 0) { inventory.getStackInSlot(3).grow(1); } else { inventory.insertItem(3, new ItemStack(ModItems.SLUG, 1), false); } smelting = ItemStack.EMPTY; cookTime = 0; } return; } // } else if (!isBurning() && cookTime > 0) { // if (cookTime > getCookTime(inventory.getStackInSlot(1)) / 3) // cookTime = MathHelper.clamp(cookTime - 3, 0, totalCookTime); // else // MathHelper.clamp(cookTime - 2, 0, totalCookTime); else { if (this.canSmelt() && this.isBurning()) { ItemStack output = BlastFurnaceRecipes.getInstance().getResult(inventory.getStackInSlot(0)); if (!output.isEmpty()) { smelting = output; cookTime++; inventory.getStackInSlot(0).shrink(1); } } } } // if (flag != isBurning()) { // flag1 = true; // BlastFurnace.setState(isBurning(), world, pos); // } // } // if (flag1) { // markDirty(); // } } and it works. Thanks to everyone who helped me. Edited June 30, 2019 by hyper1423 Quote
Recommended Posts
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.