Posted February 14, 201411 yr Hi, i have a registered tile entity and stuff, everything works fine except for when i reload my world the items inside the arent there. I added system.out.println() codes and the writeToNBT gets called but not readFromNBT! Is it just me being stupid? Thanks in advance! nbt code (It wont let me add a spoiler for some reason -.-): @Override public void writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); NBTTagList items = new NBTTagList(); for(int i=0;i<getSizeInventory();i++) { ItemStack stack = getStackInSlot(i); if(stack != null) { NBTTagCompound item = new NBTTagCompound(); item.setByte("Slot", (byte)i); stack.writeToNBT(compound); items.appendTag(item); System.out.println("Storing Stack "+i); } } compound.setTag("Items", items); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); NBTTagList items = compound.getTagList("Items", compound.getId()); for (int i = 0; i < items.tagCount(); ++i) { NBTTagCompound item = items.getCompoundTagAt(i); byte slot = item.getByte("Slot"); if (slot >= 0 && slot < getSizeInventory()) { setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(item)); System.out.println("Storing Stack "+i); } } }
February 14, 201411 yr Author I didn't call the write method and that still works. I use the markDirty() method though.
February 15, 201411 yr Try overriding the getDescriptionPacket() method: @Override public Packet getDescriptionPacket() { NBTTagCompound tag = new NBTTagCompound(); this.writeToNBT(tag); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tag); } http://i.imgur.com/NdrFdld.png[/img]
February 15, 201411 yr NBT works fine, just add in different print checks to see which parts are being called. Most likely one of your if statements is returning false and you don't realize it. If you really want help, give that modder a thank you. Modders LOVE thank yous.
February 15, 201411 yr Did you ever call the readFromNBT method? You (the programmer) don't have to. That's the point of overriding existing functions: they're called by Minecraft's internals automagically. 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.
February 15, 201411 yr Author @coolAlias: Thanks, do i just copy that? I'm not very good with packet handlers!
February 15, 201411 yr @coolAlias: Thanks, do i just copy that? I'm not very good with packet handlers! That function, yes, and another. public void onDataPacket(INetworkManager net, S35PacketUpdateTileEntity packet) { readFromNBT(packet.data); } (alert: this code was for 1.6.4, I just updating the packet class type, there MAY be other differences for 1.7) They're both called automatically. 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.
February 15, 201411 yr Author I copied it in and changed it for 1.7.2 (after a few minutes of google searching) but it still doesnt work!! If you need more code im happy to show it.
February 15, 201411 yr Yes, just copy and paste this into your TileEntity: @Override public Packet getDescriptionPacket() { NBTTagCompound tag = new NBTTagCompound(); this.writeToNBT(tag); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tag); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) { readFromNBT(packet.func_148857_g()); } If that's not working for you, did you update your IInventory code to use markDirty() now that onInventoryChanged() has been removed from that interface? You need to use it to ensure the inventory changes are recorded, as far as I can tell. http://i.imgur.com/NdrFdld.png[/img]
February 16, 201411 yr Author It still doesn't work! Maybe im being stupid somewhere else in my tile entity: package com.ljcoding.robotmod.robotworkshop; 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.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; public class TileEntityWorkshop extends TileEntity implements IInventory { private ItemStack[] items; public TileEntityWorkshop() { items = new ItemStack[12]; } @Override public void closeInventory() {} @Override public void openInventory() {} @Override public ItemStack decrStackSize(int i, int count) { ItemStack itemstack = getStackInSlot(i); if(itemstack != null) { if(itemstack.stackSize <= count) { setInventorySlotContents(i, null); } else { itemstack = itemstack.splitStack(count); markDirty(); } } return itemstack; } @Override public String getInventoryName() { return "RobotWorkshop"; } @Override public int getInventoryStackLimit() { return 64; } @Override public int getSizeInventory() { return items.length; } @Override public ItemStack getStackInSlot(int i) { return items[i]; } @Override public ItemStack getStackInSlotOnClosing(int i) { ItemStack item = getStackInSlot(i); setInventorySlotContents(i, null); return item; } @Override public boolean hasCustomInventoryName() { return true; } @Override public boolean isItemValidForSlot(int i, ItemStack itemstack) { return false; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return player.getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) <= 64; } @Override public void setInventorySlotContents(int i, ItemStack itemstack) { items[i] = itemstack; if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) { itemstack.stackSize = getInventoryStackLimit(); } markDirty(); } @Override public void writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); NBTTagList items = new NBTTagList(); for(int i=0;i<getSizeInventory();i++) { ItemStack stack = getStackInSlot(i); if(stack != null) { NBTTagCompound item = new NBTTagCompound(); item.setByte("Slot", (byte)i); stack.writeToNBT(compound); items.appendTag(item); System.out.println("Storing Stack "+i); } } compound.setTag("Items", items); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); NBTTagList items = compound.getTagList("Items", compound.getId()); for (int i = 0; i < items.tagCount(); ++i) { NBTTagCompound item = items.getCompoundTagAt(i); byte slot = item.getByte("Slot"); if (slot >= 0 && slot < getSizeInventory()) { setInventorySlotContents(slot, ItemStack.loadItemStackFromNBT(item)); System.out.println("Storing Stack "+i); } } } @Override public Packet getDescriptionPacket() { NBTTagCompound tag = new NBTTagCompound(); this.writeToNBT(tag); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tag); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) { readFromNBT(packet.func_148857_g()); } }
February 16, 201411 yr Show us your main class and your onBlockActivated in your block too. If you really want help, give that modder a thank you. Modders LOVE thank yous.
February 16, 201411 yr Author Main Class: package com.ljcoding.robotmod; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Items; import net.minecraft.item.Item; import com.ljcoding.robotmod.robotworkshop.BlockWorkshop; import com.ljcoding.robotmod.robotworkshop.GuiHandler; import com.ljcoding.robotmod.robotworkshop.TileEntityWorkshop; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.GameRegistry; @Mod(modid = RobotMod.MODID, version = RobotMod.VERSION) public class RobotMod { public static final String MODID = "RobotMod"; public static final String VERSION = "0.0.1"; @Instance(value = MODID) public static RobotMod instance; //Creative Tabs public static CreativeTabs robotTab = new CreativeTabs("robotTab") { @Override public Item getTabIconItem() { return Items.paper; } }; //Blocks public static final Block workshop = new BlockWorkshop(1000, Material.iron); @EventHandler public void preInit(FMLPreInitializationEvent event) { GameRegistry.registerBlock(workshop, "Robot Workshop"); } @EventHandler public void init(FMLInitializationEvent event) { new GuiHandler(); GameRegistry.registerTileEntity(TileEntityWorkshop.class, "tileentityworkshop"); } } Block Class: package com.ljcoding.robotmod.robotworkshop; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.World; import com.ljcoding.robotmod.RobotMod; import cpw.mods.fml.common.network.internal.FMLNetworkHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class BlockWorkshop extends BlockContainer { private IIcon icon; public BlockWorkshop(int i, Material mat) { super(mat); this.setCreativeTab(RobotMod.robotTab); this.setStepSound(soundTypeMetal); this.setHardness(8f); this.setResistance(10f); this.setLightLevel(0.2f); this.setBlockName("Robot Workshop"); } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { if(!world.isRemote) { FMLNetworkHandler.openGui(player, RobotMod.instance, 0, world, x, y, z); } return false; } @Override public TileEntity createNewTileEntity(World var1, int var2) { return new TileEntityWorkshop(); } @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { icon = iconRegister.registerIcon("robot:block_workshop"); } @SideOnly(Side.CLIENT) @Override public IIcon getIcon(int i, int j) { return icon; } }
February 17, 201411 yr Author Ok, so i changed some stuff around and the readFromNBT is only called when there isnt anything in the inventory! Anyone know why?
June 8, 201411 yr The problem is that you are writing the ItemStack to compound, but adding item to the tag list. When you are reading from nbt, you are reading the contents of the tag list, which doesn't contain any of the ItemStacks. Changing stack.writeToNBT(compound); into stack.writeToNBT(item); in writeToNBT should fix this problem.
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.