Posted January 7, 201510 yr Hello, I am just learning how to create blocks which hold an inventory, and I finally finished the code. I can right-click the block to open its inventory, and the items from my inventory appear properly in the bottom. But when I attempt to pick up an item from my inventory, it seems to pick up for a moment, then immediately returns to it's original spot, preventing me from doing anything. I have no idea what I did wrong, so I'm going to post the full source code for all associated classes. I hope someone can help me, thanks! Source Code: Main mod class BetterHealthRegen.java: package me.snap64.betterhealthregen; import me.snap64.betterhealthregen.blocks.BlockTypes; import me.snap64.betterhealthregen.gui.GuiHandler; import me.snap64.betterhealthregen.items.ItemTypes; import me.snap64.betterhealthregen.lib.Constants; import me.snap64.betterhealthregen.proxy.CommonProxy; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.network.NetworkRegistry; @Mod(modid = Constants.MODID, name = Constants.NAME, version = Constants.VERSION) public class BetterHealthRegen { @Mod.Instance(Constants.MODID) public static BetterHealthRegen instance; @SidedProxy(clientSide = Constants.CLIENT_PROXY_CLASS, serverSide = Constants.SERVER_PROXY_CLASS) public static CommonProxy proxy; @Mod.EventHandler public void preInit(FMLPreInitializationEvent event){ BlockTypes.init(); ItemTypes.init(); } @Mod.EventHandler public void init(FMLInitializationEvent event){ proxy.registerTileEntities(); NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler()); } @Mod.EventHandler public void postInit(FMLPostInitializationEvent event){ } } BlockTypes.java: package me.snap64.betterhealthregen.blocks; import net.minecraft.block.Block; public final class BlockTypes { public static Block dryingPress; public static void init(){ dryingPress = new DryingPress(); } } DryingPress.java: package me.snap64.betterhealthregen.blocks; import cpw.mods.fml.common.registry.GameRegistry; import me.snap64.betterhealthregen.BetterHealthRegen; import me.snap64.betterhealthregen.lib.Constants; import me.snap64.betterhealthregen.tileentity.TileEntityDryingPress; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.World; public class DryingPress extends BlockContainer { private String name = "dryingPress"; protected DryingPress() { super(Material.rock); this.setCreativeTab(CreativeTabs.tabBlock); this.setBlockName(Constants.MODID+"_"+name); this.setBlockTextureName(Constants.MODID+":"+name); GameRegistry.registerBlock(this, name); GameRegistry.addRecipe(new ItemStack(this), "SSS", "III", "RCR", 'S', new ItemStack(Blocks.stone_slab), 'I', new ItemStack(Items.iron_ingot), 'C', new ItemStack(Blocks.coal_block), 'R', new ItemStack(Blocks.stone)); } private IIcon top; private IIcon bottom; private IIcon sides; @Override public void registerBlockIcons(IIconRegister iconRegister){ top = iconRegister.registerIcon(Constants.MODID+":"+name+"_top"); bottom = iconRegister.registerIcon(Constants.MODID+":"+name+"_bottom"); sides = iconRegister.registerIcon(Constants.MODID+":"+name+"_sides"); } @Override public IIcon getIcon(int side, int meta){ switch(side){ case 0: return bottom; case 1: return top; } return sides; } @Override public TileEntity createNewTileEntity(World world, int meta) { return new TileEntityDryingPress(); } @Override public boolean hasTileEntity(int meta){ return true; } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int meta, float hitX, float hitY, float hitZ){ if(world.isRemote){ if(world.getTileEntity(x, y, z) != null){ player.openGui(BetterHealthRegen.instance, 0, world, x, y, z); } } return true; } } TileEntityDryingPress.java: package me.snap64.betterhealthregen.tileentity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; public class TileEntityDryingPress extends TileEntity implements IInventory{ public static final String tileEntityName = "tileEntityDryingPress"; private String inventoryName = "inventoryDryingPress"; private ItemStack[] inv; public TileEntityDryingPress(){ inv = new ItemStack[3]; } @Override public int getSizeInventory() { return inv.length; } @Override public ItemStack getStackInSlot(int slot) { return inv[slot]; } @Override public void setInventorySlotContents(int slot, ItemStack stack) { if(stack != null && stack.stackSize > getInventoryStackLimit()){ stack.stackSize = this.getInventoryStackLimit(); } inv[slot] = stack; } @Override public ItemStack decrStackSize(int slot, int amount) { ItemStack stack = this.getStackInSlot(slot); if(stack != null){ if(stack.stackSize <= amount){ this.setInventorySlotContents(slot, null); }else{ stack = stack.splitStack(amount); } } return stack; } @Override public ItemStack getStackInSlotOnClosing(int slot) { ItemStack stack = this.getStackInSlot(slot); if(stack != null){ this.setInventorySlotContents(slot, null); } return stack; } @Override public String getInventoryName() { return inventoryName; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return worldObj.getTileEntity(xCoord, yCoord, zCoord) == this && player.getDistanceSq(xCoord+0.5, yCoord+0.5, zCoord+0.5) < 64; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int slot, ItemStack stack) { return true; } @Override public void writeToNBT(NBTTagCompound compound){ super.writeToNBT(compound); NBTTagList itemList = new NBTTagList(); for(int i = 0; i < inv.length; i++){ ItemStack stack = inv[i]; if(stack != null){ NBTTagCompound itemTag = new NBTTagCompound(); itemTag.setByte("Slot", (byte) i); stack.writeToNBT(itemTag); itemList.appendTag(itemTag); } } compound.setTag("Inventory", itemList); } @Override public void readFromNBT(NBTTagCompound compound){ super.readFromNBT(compound); NBTTagList itemList = compound.getTagList("Inventory", 10);//NBT_TagCompound ID is 10 from minecraft wiki for(int i = 0; i < itemList.tagCount(); i++){ NBTTagCompound itemTag = itemList.getCompoundTagAt(i); byte slot = itemTag.getByte("Slot"); if(slot > 0 && slot < inv.length){ inv[slot] = ItemStack.loadItemStackFromNBT(itemTag); } } } } ContainerDryingPress.java: package me.snap64.betterhealthregen.inventory; import me.snap64.betterhealthregen.tileentity.TileEntityDryingPress; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; public class ContainerDryingPress extends Container { private TileEntityDryingPress tileEntity; public ContainerDryingPress(InventoryPlayer invPlayer, TileEntityDryingPress tileEntity){ this.tileEntity = tileEntity; Slot top = new Slot(tileEntity, 0, 56, 17); Slot bottom = new Slot(tileEntity, 1, 56, 53); Slot result = new Slot(tileEntity, 2, 116, 35); addSlotToContainer(top); addSlotToContainer(bottom); addSlotToContainer(result); bindPlayerInventory(invPlayer); } private static final int GUI_HEIGHT = 84; protected void bindPlayerInventory(InventoryPlayer invPlayer){ //First we add the main inventory //Cycle through x and y coordinates for(int y = 0; y < 3; y++){ for(int x = 0; x < 9; x++){ //Calculate real slot number, based on x and y, add 9 for hot bar int slot = x + y * 9 + 9; //Calculate x coordinate: //inv grid starts 8 from the side //each item slot is 16x16 with one padding on either side to make 18x18 int realX = 8 + x * 18; //Add the top padding for the current gui, then each square is 18x18 int realY = GUI_HEIGHT + y * 18; //Then finally add the slot addSlotToContainer(new Slot(invPlayer, slot, realX, realY)); } } //Then we add the hotbar slots //These need to be separate due to the seperated y position for(int i = 0; i < 9; i++){ //X coordinate same as before int x = 8 + i * 18; //all y coords are the same: GUI_HEIGHT + 58 addSlotToContainer(new Slot(invPlayer, i, x, GUI_HEIGHT + 58)); } } @Override public ItemStack transferStackInSlot(EntityPlayer player, int slot){ ItemStack stack = null; Slot slotObject = (Slot) inventorySlots.get(slot); //make sure the slot is valid and has an item that can stack if(slotObject != null && slotObject.getHasStack()){ ItemStack stackInSlot = slotObject.getStack(); stack = stackInSlot.copy(); int tileInvSize = tileEntity.getSizeInventory(); if(slot < tileInvSize){ if(!this.mergeItemStack(stackInSlot, 0, 35, true)){ return null; } }else if(!this.mergeItemStack(stackInSlot, 0, tileInvSize, false)){ return null; } if(stackInSlot.stackSize == 0){ slotObject.putStack(null); }else{ slotObject.onSlotChanged(); } if(stackInSlot.stackSize == stack.stackSize){ return null; } slotObject.onPickupFromSlot(player, stackInSlot); } return stack; } @Override public boolean canInteractWith(EntityPlayer player) { return tileEntity.isUseableByPlayer(player); } } GuiHandler.java: package me.snap64.betterhealthregen.gui; import me.snap64.betterhealthregen.inventory.ContainerDryingPress; import me.snap64.betterhealthregen.tileentity.TileEntityDryingPress; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import cpw.mods.fml.common.network.IGuiHandler; public class GuiHandler implements IGuiHandler { public static final int ID_DRYING_PRESS = 0; @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { TileEntity tileEntity = world.getTileEntity(x, y, z); if(tileEntity instanceof TileEntityDryingPress){ return new ContainerDryingPress(player.inventory, (TileEntityDryingPress) tileEntity); } return null; } @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { TileEntity tileEntity = world.getTileEntity(x, y, z); if(tileEntity instanceof TileEntityDryingPress){ return new GuiDryingPress(player.inventory, (TileEntityDryingPress) tileEntity); } return null; } } GuiDryingPress.java: package me.snap64.betterhealthregen.gui; import me.snap64.betterhealthregen.inventory.ContainerDryingPress; import me.snap64.betterhealthregen.lib.Constants; import me.snap64.betterhealthregen.tileentity.TileEntityDryingPress; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.ResourceLocation; public class GuiDryingPress extends GuiContainer { public GuiDryingPress(InventoryPlayer invPlayer, TileEntityDryingPress tileEntity) { super(new ContainerDryingPress(invPlayer, tileEntity)); } @Override protected void drawGuiContainerForegroundLayer(int par2, int par3) { //TODO add title //fontRenderer.drawString("Tiny", 8, 6, 4210752); } private ResourceLocation backgroundTexture = new ResourceLocation(Constants.MODID+":"+"textures/client/gui/guiDryingPress.png"); @Override protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { this.mc.getTextureManager().bindTexture(backgroundTexture); int x = (this.width - xSize) / 2; int y = (this.height - ySize) / 2; this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize); } @Override public boolean doesGuiPauseGame(){ return false; } } CommonProxy.java: package me.snap64.betterhealthregen.proxy; import me.snap64.betterhealthregen.tileentity.TileEntityDryingPress; import cpw.mods.fml.common.registry.GameRegistry; public class CommonProxy { public void registerTileEntities(){ GameRegistry.registerTileEntity(TileEntityDryingPress.class, TileEntityDryingPress.tileEntityName); } }
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.