Posted April 20, 201411 yr Files: BlockBookshelf.java ModelBookshelf.java TileEntityBookshelfRenderer.java ContainerBookshelf.java TileEntityBookshelf.java What is supposed to happen: After loading a world, already existing (custom) bookshelves should display a book model for each book already in the container. What happens: After loading a world, all bookshelves appear to be empty. If the player opens a bookshelf's GUI/inventory, that certain bookshelf begins to display the models properly.
April 20, 201411 yr Hi It sounds to me like either (1) you're not restoring the state from the NBT properly (looking at your code, it seems ok to me), or (2) there is a client server mismatch which gets resolved when you open the GUI, i.e. the server loads the NBT properly but the client doesn't get a copy of the information. To be honest I can't recall if this is supposed to happen automatically or not. It should be pretty easy to tell the difference if you add a few System.out.println to the appropriate parts of your code eg System.out.println( (FMLCommonHandler. getEffectiveSide() == CLIENT) ? "[Client]" : "[server]" + "inv[] = " + inv.toString()); -TGG
April 20, 201411 yr Author Based on the results of my testing, it's #2. The test code: public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int idk, float what, float these, float are) { TileEntity entity = world.getTileEntity(x, y, z); if (entity != null && entity instanceof TileEntityBookshelf) { for (int i = 0; i < bookshelf.getSizeInventory(); i++) if (bookshelf.getStackInSlot(i) != null) System.out.println((FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) ? "[Client]" : "[server]" + "inv[" + i + "] = " + bookshelf.getStackInSlot(i).toString()); } } Output in console: [server]inv[0] = 1xitem.book@0 [server]inv[1] = 1xitem.book@0 [server]inv[2] = 1xitem.book@0 [server]inv[3] = 1xitem.book@0 [server]inv[4] = 1xitem.book@0 [server]inv[5] = 1xitem.book@0 [server]inv[6] = 1xitem.book@0 [server]inv[7] = 1xitem.book@0 [server]inv[0] = 1xitem.book@0 [server]inv[1] = 1xitem.book@0 [server]inv[2] = 1xitem.book@0 [server]inv[3] = 1xitem.book@0 [server]inv[4] = 1xitem.book@0 [server]inv[5] = 1xitem.book@0 [server]inv[6] = 1xitem.book@0 [server]inv[0] = 1xitem.book@0 [server]inv[1] = 1xitem.book@0 [server]inv[2] = 1xitem.book@0 [server]inv[3] = 1xitem.book@0 [server]inv[4] = 1xitem.book@0 [server]inv[5] = 1xitem.book@0 [server]inv[6] = 1xitem.book@0 [server]inv[7] = 1xitem.book@0
April 21, 201411 yr Hi try overriding TileEntity:: public Packet getDescriptionPacket() eg for 1.6.4 @Override public Packet getDescriptionPacket() { NBTTagCompound nbttagcompound = new NBTTagCompound(); this.writeToNBT(nbttagcompound); return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 3, nbttagcompound); } for 1.7.2: @Override public Packet getDescriptionPacket() { NBTTagCompound nbttagcompound = new NBTTagCompound(); this.writeToNBT(nbttagcompound); return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 3, nbttagcompound); } -TGG
April 21, 201411 yr Author It seems that doesn't work. I forgot to mention that the output from my previous post was from right-clicking the "empty" bookshelves. This is what is outputted when the bookshelves aren't "empty": [server]inv[0] = 1xitem.book@0 [server]inv[1] = 1xitem.book@0 [server]inv[2] = 1xitem.book@0 [server]inv[3] = 1xitem.book@0 [server]inv[4] = 1xitem.book@0 [server]inv[5] = 1xitem.book@0 [server]inv[6] = 1xitem.book@0 [server]inv[7] = 1xitem.book@0 [Client] [Client] [Client] [Client] [Client] [Client] [Client] Thank you for the help
April 21, 201411 yr drat Yeah it looks very much like a client-server synchronisation problem. I had high hopes that getDescriptionPacket would fix it, since that appears to be what the vanilla uses to transmit most NBT information for TileEntities. Perhaps try putting the System.out.println code in a couple of extra places in TileEntityBookshelf, eg at the end of readFromNBT in your getDescriptionPacket in the constructor in setInventorySlotContents I suggest changing the println to (eg) System.out.println( (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) ? "[Client]" : "[server]" + "readFromNBT() inv[0] = " + (inv == null || inv[0] == null) ? "null" : "filled"); Let me know if that doesn't give you any more insight, and I can see if I can download your GitHub to test it directly (is the rest of it compilable?) -TGG
April 21, 201411 yr Author I've got to go to bed, so I'll probably have time to do that in ~20 hrs (sleep, school & homework). As the current commit doesn't seem to be compilable, download the previous one. Don't worry, the current commit didn't make any changes to bookshelves.
April 21, 201411 yr Hi Ah- I just realised- in order for your client to process the description packet you will need to override TileEntity:: /** * Called when you receive a TileEntityData packet for the location this * TileEntity is currently in. On the client, the NetworkManager will always * be the remote server. On the server, it will be whomever is responsible for * sending the packet. * * @param net The NetworkManager the packet originated from * @param pkt The data packet */ public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { } The S35PacketUpdateTileEntity will contain some NBT data, you should call your TileEntity.readFromNBT() on that NBT data. -TGG
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.