Jump to content

[1.11.2] [Resolved] TileEntity without Fuel Issue


coolsim

Recommended Posts

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 by coolsim
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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;
    }

}

 

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.