Posted January 8, 20187 yr Greetings all! I am creating my first TileEntity which is basically a furnace that only cooks food and requires no fuel. It's like the oven in MrCrayfish's Furniture Mod, only with one input. When I place the item into the input it doubles and once clicked on vanishes. I have tried several times to rewrite the code from scratch but end up with similar results. Link to a short clip of the issue Main TileEntity Class: public class TileEntityCampfire extends TileEntity implements ITickable, ISidedInventory { private static final int[] SLOTS_TOP = new int[] {0}; private static final int[] SLOTS_BOTTOM = new int[] {2}; private static NonNullList<ItemStack> inventory = NonNullList.<ItemStack>withSize(2, ItemStack.EMPTY); private String customName; private int furnaceBurnTime; private int cookTime; private int totalCookTime; @Override public int getSizeInventory() { return this.inventory.size(); } public String getGuiID() { return Reference.MOD_ID + ":campfire"; } @Override public boolean isEmpty() { for(ItemStack stack : this.inventory) if(!stack.isEmpty()) return false; return true; } @Override public ItemStack getStackInSlot(int index) { return this.inventory.get(index); } @Override public ItemStack decrStackSize(int index, int count) { return ItemStackHelper.getAndSplit(this.inventory, index, count); } @Override public ItemStack removeStackFromSlot(int index) { return ItemStackHelper.getAndRemove(this.inventory, index); } @Override public void setInventorySlotContents(int index, ItemStack stack) { ItemStack itemstack = (ItemStack)this.inventory.get(index); boolean flag = !stack.isEmpty() && stack.isItemEqual(itemstack) && ItemStack.areItemStackTagsEqual(stack, itemstack); this.inventory.set(index, stack); if (stack.getCount() > this.getInventoryStackLimit()) { stack.setCount(this.getInventoryStackLimit()); } if(index == 0 && !flag) { this.totalCookTime = this.getCookTime(stack); this.cookTime = 0; this.markDirty(); } } @Override public int getInventoryStackLimit() { return 64; } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.inventory = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY); ItemStackHelper.loadAllItems(compound, this.inventory); this.furnaceBurnTime = compound.getInteger("BurnTime"); this.cookTime = compound.getInteger("CookTime"); this.totalCookTime = compound.getInteger("CookTimeTotal"); if (compound.hasKey("CustomName", 8)) { this.customName = compound.getString("CustomName"); } } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger("BurnTime", (short)this.furnaceBurnTime); compound.setInteger("CookTime", (short)this.cookTime); compound.setInteger("CookTimeTotal", (short)this.totalCookTime); ItemStackHelper.saveAllItems(compound, this.inventory); if (this.hasCustomName()) { compound.setString("CustomName", this.customName); } return compound; } public int getCookTime(ItemStack stack) { return 100; } @Override public boolean isUsableByPlayer(EntityPlayer player) { return this.world.getTileEntity(this.pos) != this ? false : player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; } @Override public void openInventory(EntityPlayer player) { } @Override public void closeInventory(EntityPlayer player) { } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { if (index == 1) { return false; } else// if (index != 1) { return true; } } @Override public int getField(int id) { switch(id) { case 0: return this.furnaceBurnTime; case 1: return this.cookTime; case 2: return this.totalCookTime; default: return 0; } } @Override public void setField(int id, int value) { switch (id) { case 0: this.furnaceBurnTime = value; break; case 1: this.cookTime = value; break; case 2: this.totalCookTime = value; break; } } @Override public int getFieldCount() { return 2; } @Override public void clear() { this.inventory.clear(); } @Override public String getName() { return this.hasCustomName() ? this.customName : "container.campfire"; } @Override public boolean hasCustomName() { return this.customName != null && !this.customName.isEmpty(); } @Override public int[] getSlotsForFace(EnumFacing side) { return side == EnumFacing.DOWN ? SLOTS_BOTTOM : (side == EnumFacing.UP ? SLOTS_TOP : SLOTS_BOTTOM); } @Override public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction) { return this.isItemValidForSlot(index, itemStackIn); } @Override public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) { return true; } public boolean isBurning() { return this.furnaceBurnTime > 0; } @SideOnly(Side.CLIENT) public static boolean isBurning(IInventory inventory) { return inventory.getField(0) > 0; } @Override public void update() { boolean flag = this.isBurning(); boolean flag1 = false; if (this.isBurning()) { --this.furnaceBurnTime; } if (!this.world.isRemote) { if (this.isBurning() && this.canSmelt()) { ++this.cookTime; if (this.cookTime == this.totalCookTime) { this.cookTime = 0; this.totalCookTime = this.getCookTime((ItemStack)this.inventory.get(0)); this.smeltItem(); flag1 = true; } } else { this.cookTime = 0; } } else if (!this.isBurning() && this.cookTime > 0) { this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.totalCookTime); } if (flag != this.isBurning()) { flag1 = true; BlockFurnace.setState(this.isBurning(), this.world, this.pos); } if (flag1) { this.markDirty(); } } private boolean canSmelt() { if (((ItemStack)this.inventory.get(0)).isEmpty()) { return false; } else { ItemStack itemstack = CampfireRecipes.instance().getCampfireSmeltingResult((ItemStack)this.inventory.get(0)); if (itemstack.isEmpty()) { return false; } else { ItemStack itemstack1 = (ItemStack)this.inventory.get(1); if (itemstack1.isEmpty()) return true; if (!itemstack1.isItemEqual(itemstack)) return false; int result = itemstack1.getCount() + itemstack.getCount(); return result <= getInventoryStackLimit() && result <= itemstack1.getMaxStackSize(); // Forge fix: make furnace respect stack sizes in furnace recipes } } } public void smeltItem() { if (this.canSmelt()) { ItemStack itemstack = (ItemStack)this.inventory.get(0); ItemStack itemstack1 = CampfireRecipes.instance().getCampfireSmeltingResult(itemstack); ItemStack itemstack2 = (ItemStack)this.inventory.get(1); if (itemstack2.isEmpty()) { this.inventory.set(1, itemstack1.copy()); } else if (itemstack2.getItem() == itemstack1.getItem()) { itemstack2.grow(itemstack1.getCount()); } itemstack.shrink(1); } } } TileEntity Recipe Class: public class CampfireRecipes { private static final CampfireRecipes SMELTING_BASE = new CampfireRecipes(); private final Map<ItemStack, ItemStack> smeltingList = Maps.<ItemStack, ItemStack>newHashMap(); private final Map<ItemStack, Float> experienceList = Maps.<ItemStack, Float>newHashMap(); /** * Returns an instance of CampfireRecipes. */ public static CampfireRecipes instance() { return SMELTING_BASE; } private CampfireRecipes() { this.addCampfireSmelting(Items.PORKCHOP, new ItemStack(Items.COOKED_PORKCHOP), 0.35F); this.addCampfireSmelting(Items.BEEF, new ItemStack(Items.COOKED_BEEF), 0.35F); this.addCampfireSmelting(Items.CHICKEN, new ItemStack(Items.COOKED_CHICKEN), 0.35F); this.addCampfireSmelting(Items.RABBIT, new ItemStack(Items.COOKED_RABBIT), 0.35F); this.addCampfireSmelting(Items.MUTTON, new ItemStack(Items.COOKED_MUTTON), 0.35F); this.addCampfireSmelting(Items.CLAY_BALL, new ItemStack(Items.BRICK), 0.3F); this.addCampfireSmeltingRecipeForBlock(Blocks.LOG, new ItemStack(Items.COAL, 1, 1), 0.15F); this.addCampfireSmeltingRecipeForBlock(Blocks.LOG2, new ItemStack(Items.COAL, 1, 1), 0.15F); this.addCampfireSmelting(Items.POTATO, new ItemStack(Items.BAKED_POTATO), 0.35F); this.addCampfireSmeltingRecipe(new ItemStack(Blocks.SPONGE, 1, 1), new ItemStack(Blocks.SPONGE, 1, 0), 0.15F); this.addCampfireSmelting(Items.CHORUS_FRUIT, new ItemStack(Items.CHORUS_FRUIT_POPPED), 0.1F); for (ItemFishFood.FishType itemfishfood$fishtype : ItemFishFood.FishType.values()) { if (itemfishfood$fishtype.canCook()) { this.addCampfireSmeltingRecipe(new ItemStack(Items.FISH, 1, itemfishfood$fishtype.getMetadata()), new ItemStack(Items.COOKED_FISH, 1, itemfishfood$fishtype.getMetadata()), 0.35F); } } } /** * Adds a smelting recipe, where the input item is an instance of Block. */ public void addCampfireSmeltingRecipeForBlock(Block input, ItemStack stack, float experience) { this.addCampfireSmelting(Item.getItemFromBlock(input), stack, experience); } /** * Adds a roasting recipe using an Item as the input item. */ public void addCampfireSmelting(Item input, ItemStack stack, float experience) { this.addCampfireSmeltingRecipe(new ItemStack(input, 1, 32767), stack, experience); } /** * Adds a smelting recipe using an ItemStack as the input for the recipe. */ public void addCampfireSmeltingRecipe(ItemStack input, ItemStack stack, float experience) { if (getCampfireSmeltingResult(input) != null) { net.minecraftforge.fml.common.FMLLog.info("Ignored campfire recipe with conflicting input: " + input + " = " + stack); return; } this.smeltingList.put(input, stack); this.experienceList.put(stack, Float.valueOf(experience)); } /** * Returns the smelting result of an item. */ @Nullable public ItemStack getCampfireSmeltingResult(ItemStack stack) { for (Entry<ItemStack, ItemStack> entry : this.smeltingList.entrySet()) { if (this.compareItemStacks(stack, (ItemStack)entry.getKey())) { return (ItemStack)entry.getValue(); } } return null; } /** * Compares two itemstacks to ensure that they are the same. This checks both the item and the metadata of the item. */ private boolean compareItemStacks(ItemStack stack1, ItemStack stack2) { return stack2.getItem() == stack1.getItem() && (stack2.getMetadata() == 32767 || stack2.getMetadata() == stack1.getMetadata()); } public Map<ItemStack, ItemStack> getSmeltingList() { return this.smeltingList; } public float getCampfireSmeltingExperience(ItemStack stack) { float ret = stack.getItem().getSmeltingExperience(stack); if (ret != -1) return ret; for (Entry<ItemStack, Float> entry : this.experienceList.entrySet()) { if (this.compareItemStacks(stack, (ItemStack)entry.getKey())) { return ((Float)entry.getValue()).floatValue(); } } return 0.0F; } } Any help would be appreciated as this issue is holding up the development of my mod. Edited February 5, 20187 yr by coolsim
January 8, 20187 yr Problematic code, #5. Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support. 1.12 -> 1.13 primer by williewillus. 1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support. http://www.howoldisminecraft1710.today/
January 8, 20187 yr Also whenever you get ghost items, either you are not copying/cloning the itemstack properly, or you are using them only in clientside without syncing them. New Channel: https://www.youtube.com/theawesomegemily'>https://www.youtube.com/theawesomegemily My Group: https://www.youtube.com/officialpixelgem Old Channel: https://www.youtube.com/theawesomegem
January 8, 20187 yr You also need to show your Container and GuiContainer classes. 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.
January 8, 20187 yr Author I will look at changing isBurning in my main TileEntity class so that it doesn't use IInventory. Here are the other classes. Container: public class ContainerCampfire extends Container{ private final TileEntityCampfire tileentity; private int furnaceBurnTime; private int cookTime; private int totalCookTime; public ContainerCampfire(InventoryPlayer player, TileEntityCampfire tileentity) { this.tileentity = tileentity; this.addSlotToContainer(new Slot(tileentity, 0, 56, 35)); this.addSlotToContainer(new SlotFurnaceOutput(player.player, tileentity, 1, 116, 35)); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 9; ++j) { this.addSlotToContainer(new Slot(player, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); } } for (int k = 0; k < 9; ++k) { this.addSlotToContainer(new Slot(player, k, 8 + k * 18, 142)); } } @Override public void addListener(IContainerListener listener) { super.addListener(listener); listener.sendAllWindowProperties(this, this.tileentity); } @Override public void detectAndSendChanges() { super.detectAndSendChanges(); for (int i = 0; i < this.listeners.size(); ++i) { IContainerListener icontainerlistener = (IContainerListener)this.listeners.get(i); if (this.cookTime != this.tileentity.getField(1)) { icontainerlistener.sendProgressBarUpdate(this, 1, this.tileentity.getField(1)); } if (this.furnaceBurnTime != this.tileentity.getField(0)) { icontainerlistener.sendProgressBarUpdate(this, 0, this.tileentity.getField(0)); } if (this.totalCookTime != this.tileentity.getField(2)) { icontainerlistener.sendProgressBarUpdate(this, 2, this.tileentity.getField(2)); } } this.cookTime = this.tileentity.getField(1); this.furnaceBurnTime = this.tileentity.getField(0); this.totalCookTime = this.tileentity.getField(2); } @Override @SideOnly(Side.CLIENT) public void updateProgressBar(int id, int data) { this.tileentity.setField(id, data); } @Override public boolean canInteractWith(EntityPlayer playerIn) { return this.tileentity.isUsableByPlayer(playerIn); } @Override public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack itemstack = ItemStack.EMPTY; Slot slot = (Slot)this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index == 1) { if (!this.mergeItemStack(itemstack1, 2, 39, true)) { return ItemStack.EMPTY; } slot.onSlotChange(itemstack1, itemstack); } else if (index != 0) { if (!CampfireRecipes.instance().getCampfireSmeltingResult(itemstack1).isEmpty()) { if (!this.mergeItemStack(itemstack1, 0, 1, false)) { return ItemStack.EMPTY; } } else if (TileEntityFurnace.isItemFuel(itemstack1)) { if (!this.mergeItemStack(itemstack1, 1, 2, false)) { return ItemStack.EMPTY; } } else if (index >= 3 && index < 30) { if (!this.mergeItemStack(itemstack1, 30, 39, false)) { return ItemStack.EMPTY; } } else if (index >= 30 && index < 39 && !this.mergeItemStack(itemstack1, 3, 30, false)) { return ItemStack.EMPTY; } } else if (!this.mergeItemStack(itemstack1, 3, 39, false)) { return ItemStack.EMPTY; } if (itemstack1.isEmpty()) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } if (itemstack1.getCount() == itemstack.getCount()) { return ItemStack.EMPTY; } slot.onTake(playerIn, itemstack1); } return itemstack; } @Override public void onContainerClosed(EntityPlayer player) { super.onContainerClosed(player); this.tileentity.closeInventory(player); } } GuiContainer: public class GuiCampfire extends GuiContainer{ private static final ResourceLocation CAMPFIRE_GUI_TEXTURE = new ResourceLocation(Reference.MOD_ID + ":" + "textures/gui/container/campfire.png"); private final InventoryPlayer player; private final TileEntityCampfire tileentity; public GuiCampfire(InventoryPlayer player, TileEntityCampfire tileentity) { super(new ContainerCampfire(player, tileentity)); this.player = player; this.tileentity = tileentity; } /** * Draw the foreground layer for the GuiContainer (everything in front of the items) */ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { String s = this.tileentity.hasCustomName() ? this.tileentity.getName() : I18n.format(this.tileentity.getName(), new Object[0]); this.fontRendererObj.drawString(s, this.xSize / 2 - this.fontRendererObj.getStringWidth(s) / 2, 6, 0xFFFFFF); this.fontRendererObj.drawString(this.player.getDisplayName().getUnformattedText(), 8, this.ySize - 96 + 2, 0xFFFFFF); } /** * Draws the background layer of this container (behind the items). */ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.mc.getTextureManager().bindTexture(CAMPFIRE_GUI_TEXTURE); int i = (this.width - this.xSize) / 2; int j = (this.height - this.ySize) / 2; this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize); int l = this.getCookProgressScaled(24); this.drawTexturedModalRect(i + 79, j + 34, 176, 14, l + 1, 16); } private int getCookProgressScaled(int pixels) { int i = this.tileentity.getField(1); int j = this.tileentity.getField(0); return j != 0 && i != 0 ? i * pixels / j : 0; } }
February 5, 20187 yr Author After writing my code a couple more times, I decided to make my campfire use sticks as fuel. I have labeled this as resolved as I no longer need assistance.
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.