Jump to content

Recommended Posts

Posted

So I'm trying to make a furnace, and I got everything set up but I'm having one problem, when I try and smelt items, I put some cobblestone/raw porkchop in and the smelting result is 1 item, 4 items, 16 items, 32 items, then 64 items. (Instead of 1 item, 2 items, 3 items, 4 items, etc. as it should be.) So that makes it when you put 5 items in it smelts them all into a stack of whatever the result is.

Another problem is a lot of times if I try and pull it out before it is a full stack, the items will disappear.

Last problem is after it smelts the first stack(Or I pull items out early) it won't put ANY more items into the result slot, it just uses up the input without putting anything into the output.

 

Now I have narrowed it down to this one function I have.

public static ItemStack getSmeltingResultForItem(ItemStack stack)
	{
		else return FurnaceRecipes.instance().getSmeltingResult(stack);
	}

That is returning the crazy doubling numbers I'm seeing. Even more so, when I replace the above code with this.

public static ItemStack getSmeltingResultForItem(ItemStack stack)
	{
		if(stack.getItem()==Item.getItemFromBlock(Blocks.COBBLESTONE))
		{
			return new ItemStack(Item.getItemFromBlock(Blocks.STONE), 1);
		}
		else return FurnaceRecipes.instance().getSmeltingResult(stack);
	}

It works perfect for cobblestone, but then has the same problem with raw pork-chop or anything else I put in.

For a better view of my code I will put all related classes in

KSTileEntityBlessedFurnace

Spoiler

import java.util.HashSet;

import com.theundertaker11.kitchensink.tileentity.TileEntityContainerBase;

import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;

public class KSTileEntityBlessedFurnace extends TileEntityContainerBase{
    
    private int ticksCooking;
    private static final int TICKS_NEEDED = 40;
    public KSTileEntityBlessedFurnace(){super();}

    @Override
    public void update()
    {
        if (canSmelt()) 
        {
            ticksCooking++;
            int lavacount = getLavaCount(this.getPos());
            if(ticksCooking>=((double)TICKS_NEEDED/(double)(2^lavacount-1)))
            {
                ticksCooking=0;
                smeltItem();
            }
        }
        else{ticksCooking=0;}
    }
    
    public int getLavaCount(BlockPos pos)
    {
        int count = 0;
        HashSet<IBlockState> set = new HashSet<IBlockState>();
        set.add(this.getWorld().getBlockState(new BlockPos(this.getPos().getX(),this.getPos().getY()+1,this.getPos().getZ())));
        set.add(this.getWorld().getBlockState(new BlockPos(this.getPos().getX(),this.getPos().getY()-1,this.getPos().getZ())));
        set.add(this.getWorld().getBlockState(new BlockPos(this.getPos().getX()+1,this.getPos().getY(),this.getPos().getZ())));
        set.add(this.getWorld().getBlockState(new BlockPos(this.getPos().getX()-1,this.getPos().getY(),this.getPos().getZ())));
        set.add(this.getWorld().getBlockState(new BlockPos(this.getPos().getX(),this.getPos().getY(),this.getPos().getZ()+1)));
        set.add(this.getWorld().getBlockState(new BlockPos(this.getPos().getX(),this.getPos().getY(),this.getPos().getZ()-1)));
        for(IBlockState state:set)
        {
            if(state!=null&&state.getBlock()==Blocks.LAVA) count++;
        }
        return count;
    }
    public static ItemStack getSmeltingResultForItem(ItemStack stack)
    {
        if(stack.getItem()==Item.getItemFromBlock(Blocks.COBBLESTONE))
        {
            return new ItemStack(Item.getItemFromBlock(Blocks.STONE), 1);
        }
        else return FurnaceRecipes.instance().getSmeltingResult(stack);
    }
    
    private boolean canSmelt() {return smeltItem(false);}

    private void smeltItem() {smeltItem(true);}
    
    private boolean smeltItem(boolean performSmelt)
    {
        IItemHandler inventory = this.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
        IItemHandler inventoryoutput = this.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN);

        if(getLavaCount(this.getPos())>0)
        {
            if (inventory != null&&inventory.getStackInSlot(0)!=null) 
            {
                ItemStack inputSlotStack = inventory.getStackInSlot(0);
                ItemStack result = getSmeltingResultForItem(inputSlotStack);
                if (result != null)
                {
                    ItemStack outputSlotStack = inventoryoutput.getStackInSlot(0);
                    if (outputSlotStack == null)
                    {
                        if(inventoryoutput.insertItem(0, result, !performSmelt)==null)
                        {
                            inventory.extractItem(0, 1, !performSmelt);
                            markDirty();
                            return true;
                        }
                    }else{
                        if(inventoryoutput.insertItem(0, result, true)!=null)
                        {
                            return false;
                        }
                        else
                        {
                            inventoryoutput.insertItem(0, result, !performSmelt);
                            inventory.extractItem(0, 1, !performSmelt);
                            markDirty();
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    public double percComplete()
    {
        return (double)this.ticksCooking/(double)((double)TICKS_NEEDED/(double)(2^getLavaCount(this.getPos())-1));
    }
    
    private static final byte TICKS_COOKING_FIELD_ID = 0;
    
    private static final byte NUMBER_OF_FIELDS = 1;

    public int getField(int id) {
        if (id == TICKS_COOKING_FIELD_ID) return ticksCooking;
        System.err.println("Invalid field ID in GRTileEntity.getField:" + id);
        return 0;
    }

    public void setField(int id, int value)
    {
        if (id == TICKS_COOKING_FIELD_ID) {
            ticksCooking = (short)value;
        }
    }
    public int getFieldCount(){
        return NUMBER_OF_FIELDS;
    }
}

TileEntityContainerBase

Spoiler

import javax.annotation.Nullable;

import com.theundertaker11.kitchensink.ksblocks.StorageBlockBase;

import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumFacing.Axis;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;

public class TileEntityContainerBase extends TileEntity implements ITickable{

    public TileEntityContainerBase(){super();}

    @Override
    public void update(){}
    
    public boolean isUseableByPlayer(EntityPlayer playerIn) {
        // If we are too far away from this tile entity you cannot use it
        return !isInvalid() && playerIn.getDistanceSq(pos.add(0.5D, 0.5D, 0.5D)) <= 64D;
    }
    
    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound)
    {
        super.writeToNBT(compound);
        compound.setTag("inputitem", itemStackHandler.serializeNBT());
        compound.setTag("outputitem", itemStackHandlerOutput.serializeNBT());
        return compound;
    }
    
    @Override
    public void readFromNBT(NBTTagCompound compound)
    {
        super.readFromNBT(compound);
        if (compound.hasKey("inputitem")){
            itemStackHandler.deserializeNBT((NBTTagCompound) compound.getTag("inputitem"));
        }
        if (compound.hasKey("outputitem")){
            itemStackHandlerOutput.deserializeNBT((NBTTagCompound) compound.getTag("outputitem"));
        }
    }
    private ItemStackHandler itemStackHandler = 
            new ItemStackHandler(1){
        @Override
        protected void onContentsChanged(int slot){
            markDirty();
        }
    };
    private ItemStackHandler itemStackHandlerOutput = 
            new ItemStackHandler(1){
        @Override
        protected void onContentsChanged(int slot){
            markDirty();
        }
    };
    
    @Override
    public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
            return true;
        }
        return super.hasCapability(capability, facing);
    }

    @Override
    public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
        if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY&&this.getWorld().getBlockState(this.pos).getBlock() instanceof StorageBlockBase) {
            EnumFacing rightSide = this.getWorld().getBlockState(this.pos).getValue(StorageBlockBase.FACING).rotateAround(Axis.Y).getOpposite();
            if(facing==EnumFacing.DOWN||facing==rightSide) return (T)itemStackHandlerOutput;
            else return (T) itemStackHandler;
        }
        return super.getCapability(capability, facing);
    }
    
    @Override
    @Nullable
    public SPacketUpdateTileEntity getUpdatePacket()
    {
      NBTTagCompound updateTagDescribingTileEntityState = getUpdateTag();
      final int METADATA = 0;
      return new SPacketUpdateTileEntity(this.pos, METADATA, updateTagDescribingTileEntityState);
    }

    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
      NBTTagCompound updateTagDescribingTileEntityState = pkt.getNbtCompound();
      handleUpdateTag(updateTagDescribingTileEntityState);
    }

    /* Creates a tag containing the TileEntity information, used by vanilla to transmit from server to client
       Warning - although our getUpdatePacket() uses this method, vanilla also calls it directly, so don't remove it.
     */
    @Override
    public NBTTagCompound getUpdateTag()
    {
          NBTTagCompound nbtTagCompound = new NBTTagCompound();
          writeToNBT(nbtTagCompound);
      return nbtTagCompound;
    }

    /* Populates this TileEntity with information from the tag, used by vanilla to transmit from server to client
     Warning - although our onDataPacket() uses this method, vanilla also calls it directly, so don't remove it.
   */
    @Override
    public void handleUpdateTag(NBTTagCompound tag)
    {
      this.readFromNBT(tag);
    }
    
    @Override
    public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate)
    {
        return (oldState.getBlock() != newSate.getBlock());
    }
}

ContainerBlessedFurnace

Spoiler

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
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.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
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 ContainerBlessedFurnace extends Container {

    private KSTileEntityBlessedFurnace tileInventory;

    private int cachedTicksCooking;

    private final int HOTBAR_SLOT_COUNT = 9;
    private final int PLAYER_INVENTORY_ROW_COUNT = 3;
    private final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
    private final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
    private final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;

    public final int INPUT_SLOTS_COUNT = 1;
    public final int OUTPUT_SLOTS_COUNT = 1;
    public final int TOTAL_SLOTS_COUNT = INPUT_SLOTS_COUNT + OUTPUT_SLOTS_COUNT;

    private final int VANILLA_FIRST_SLOT_INDEX = 0;
    private final int INPUT_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
    private final int OUTPUT_SLOT_INDEX = INPUT_SLOT_INDEX + INPUT_SLOTS_COUNT;

    private final int INPUT_SLOT_NUMBER = 0;
    private final int OUTPUT_SLOT_NUMBER = 0;

    public ContainerBlessedFurnace(InventoryPlayer invPlayer, KSTileEntityBlessedFurnace tileInventory){
        this.tileInventory = tileInventory;

        final int SLOT_X_SPACING = 18;
        final int SLOT_Y_SPACING = 18;
        final int HOTBAR_XPOS = 8;
        final int HOTBAR_YPOS = 183;
        // Add the players hotbar to the gui - the [xpos, ypos] location of each item
        for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) {
            int slotNumber = x;
            addSlotToContainer(new Slot(invPlayer, slotNumber, HOTBAR_XPOS + SLOT_X_SPACING * x, HOTBAR_YPOS));
        }

        final int PLAYER_INVENTORY_XPOS = 8;
        final int PLAYER_INVENTORY_YPOS = 125;
        // Add the rest of the players inventory to the gui
        for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) {
            for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) {
                int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x;
                int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_X_SPACING;
                int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_Y_SPACING;
                addSlotToContainer(new Slot(invPlayer, slotNumber,  xpos, ypos));
            }
        }
        
        IItemHandler itemhandlerinput = tileInventory.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
        IItemHandler itemhandleroutput = tileInventory.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN);
        final int INPUT_SLOTS_XPOS = 26;
        final int INPUT_SLOTS_YPOS = 24;
        // Add the tile input slots
        int slotNumberInput = 2 + INPUT_SLOT_NUMBER;
        addSlotToContainer(new SlotSmeltableInput(itemhandlerinput, INPUT_SLOT_NUMBER, INPUT_SLOTS_XPOS, INPUT_SLOTS_YPOS+ SLOT_Y_SPACING * 2));
        

        final int OUTPUT_SLOTS_XPOS = 134;
        final int OUTPUT_SLOTS_YPOS = 24;
        // Add the tile output slots
        int slotNumber = 2 + OUTPUT_SLOT_NUMBER;
        addSlotToContainer(new SlotOutput(itemhandleroutput, OUTPUT_SLOT_NUMBER, OUTPUT_SLOTS_XPOS, OUTPUT_SLOTS_YPOS + SLOT_Y_SPACING * 2));
    }

    // Checks each tick to make sure the player is still able to access the inventory and if not closes the gui
    @Override
    public boolean canInteractWith(EntityPlayer player)
    {
        return tileInventory.isUseableByPlayer(player);
    }

    //Always make sure it returns null if nothing should happen, and after stuff has happened make it return a copy
    //of the stack
    @Override
    public ItemStack transferStackInSlot(EntityPlayer player, int sourceSlotIndex)
    {
        ItemStack itemstack = null;
        Slot slot = (Slot)this.inventorySlots.get(sourceSlotIndex);
        if(slot == null || !slot.getHasStack()) return null;
        if(tileInventory.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP)==null) return null;
        IItemHandler input = tileInventory.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
        
        ItemStack sourceStack = slot.getStack();
        ItemStack copyOfStack = sourceStack.copy();
        
        //If it is player's inventory do these things.
        if (sourceSlotIndex >= VANILLA_FIRST_SLOT_INDEX && sourceSlotIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT)
        {
            if(KSTileEntityBlessedFurnace.getSmeltingResultForItem(sourceStack)!=null)
            {
                if(input.insertItem(0, sourceStack, true)==null)
                {
                    input.insertItem(0, sourceStack, false);
                    player.inventory.setInventorySlotContents(sourceSlotIndex, null);
                }
                else if (input.insertItem(0, sourceStack, true).stackSize==sourceStack.stackSize){
                    return null;
                }
                else
                {
                    player.inventory.setInventorySlotContents(sourceSlotIndex, input.insertItem(0, sourceStack, false));
                }
            }
            else return null;
        }
        else if(sourceSlotIndex==INPUT_SLOT_INDEX||sourceSlotIndex==OUTPUT_SLOT_INDEX)
        {
            if (!this.mergeItemStack(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)){
                return null;
            }
        }else return null;
        return copyOfStack;
    }    
    

    /* Client Synchronization */
    @Override
    public void detectAndSendChanges()
    {
        super.detectAndSendChanges();

        boolean fieldHasChanged = false;
        boolean overclockersChanged = false;
        if (cachedTicksCooking != tileInventory.getField(0))
        {
            this.cachedTicksCooking = tileInventory.getField(0);
            fieldHasChanged = true;
        }

        // go through the list of listeners (players using this container) and update them if necessary
        for (IContainerListener listener : this.listeners)
        {
            if (fieldHasChanged)
            {
                // Note that although sendProgressBarUpdate takes 2 ints on a server these are truncated to shorts
                listener.sendProgressBarUpdate(this, 0, this.cachedTicksCooking);
            }
        }
    }

    @SideOnly(Side.CLIENT)
    @Override
    public void updateProgressBar(int id, int data)
    {
        tileInventory.setField(id, data);
    }

    // SlotSmeltableInput is a slot for input items
    public class SlotSmeltableInput extends SlotItemHandler
    {
        public SlotSmeltableInput(IItemHandler inventoryIn, int index, int xPosition, int yPosition) {
            super(inventoryIn, index, xPosition, yPosition);
        }

        // if this function returns false, the player won't be able to insert the given item into this slot
        @Override
        public boolean isItemValid(ItemStack stack) {
            return (KSTileEntityBlessedFurnace.getSmeltingResultForItem(stack)!=null);
        }
    }

    public class SlotOutput extends SlotItemHandler
    {
        public SlotOutput(IItemHandler inventoryIn, int index, int xPosition, int yPosition) {
            super(inventoryIn, index, xPosition, yPosition);
        }

        @Override
        public boolean isItemValid(ItemStack stack) {
            return false;
        }
    }
}

BlockBlessedFurnace

Spoiler

import javax.annotation.Nullable;

import com.theundertaker11.kitchensink.KitchenSink;
import com.theundertaker11.kitchensink.gui.GuiHelper;
import com.theundertaker11.kitchensink.ksblocks.StorageBlockBase;

import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;

public class BlockBlessedFurnace extends StorageBlockBase{

    public BlockBlessedFurnace(String name){
        super(name);
    }
    
    @Override
    public TileEntity createTileEntity(World world, IBlockState state)
    {
        return new KSTileEntityBlessedFurnace();
    }

    @Override
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
        if(worldIn.isRemote) return true;
        TileEntity tEntity = worldIn.getTileEntity(pos);
        
        if(tEntity!=null&&tEntity instanceof KSTileEntityBlessedFurnace&&hand==EnumHand.MAIN_HAND)
        {
            playerIn.openGui(KitchenSink.instance, GuiHelper.BlessedFurnaceGui, worldIn, pos.getX(), pos.getY(), pos.getZ());
        }
        return true;
    }
    
    @Override
    public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
    {
        TileEntity tile = worldIn.getTileEntity(pos);
        //All the null checks are just in case and probably not actually needed
        if (tile!=null&&tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP)!=null&&tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN)!=null
            &&tile instanceof KSTileEntityBlessedFurnace)
        {
            KSTileEntityBlessedFurnace tileentity = (KSTileEntityBlessedFurnace)tile;
            IItemHandler input = tileentity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP);
            IItemHandler output = tileentity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN);
            if(input.getStackInSlot(0)!=null)
            {
                ItemStack inputstack = input.getStackInSlot(0);
                EntityItem entityinput = new EntityItem(tileentity.getWorld(), tileentity.getPos().getX(), tileentity.getPos().getY(), tileentity.getPos().getZ(), inputstack);
                tileentity.getWorld().spawnEntityInWorld(entityinput);
            }
            if(output.getStackInSlot(0)!=null)
            {
                ItemStack outputstack = output.getStackInSlot(0);
                EntityItem entityoutput = new EntityItem(tileentity.getWorld(), tileentity.getPos().getX(), tileentity.getPos().getY(), tileentity.getPos().getZ(), outputstack);
                tileentity.getWorld().spawnEntityInWorld(entityoutput);
            }
        }
        super.breakBlock(worldIn, pos, state);
    }
}

I wouldn't think you would need all this code to figure out the problem, but just in case I put it all there. (It also has a gui I just didn't put that here)

My IGN is TheUnderTaker11, but when I tried to sign up for this site it would not send the email... So yea now I have to use this account.

Posted

Because you're modifying the recipe stack. You need to clone it before adding it to the output slot.

  • Like 1

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.

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.