Posted January 1, 201510 yr I'm having troubles with my NBT data being lost when I close the window. I have a packet handler set up for my tile, and it will save the data after exiting and reentering the world, but if I close Minecraft and reopen it, the data is lost. Did I set up the packet handler wrong? PacketHandler: public class PacketHandler { public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(reference.MOD_ID.toLowerCase()); public static void init() { INSTANCE.registerMessage(MessageCells.class, MessageCells.class, 0, Side.CLIENT); } } MessageCells: public class MessageCells implements IMessage, IMessageHandler<MessageCells, IMessage> { public int x, y, z, power; public int[] conf = new int[6]; public MessageCells(){ } public MessageCells(BaseCellTE baseCellTE){ x = baseCellTE.xCoord; y = baseCellTE.yCoord; z = baseCellTE.zCoord; power = baseCellTE.getEnergyStored(); for(int i = 0; i<6; i++){ try { conf[i] = baseCellTE.getSendRecv(i); } catch (Exception e){ LogHelper.info(e); } } } @Override public void fromBytes(ByteBuf buf) { this.x = buf.readInt(); this.y = buf.readInt(); this.z = buf.readInt(); this.power = buf.readInt(); for(int i = 0; i<6; i++){ conf[i] = buf.readInt(); } } @Override public void toBytes(ByteBuf buf) { buf.writeInt(x); buf.writeInt(y); buf.writeInt(z); buf.writeInt(power); for(int i = 0; i<6; i++){ buf.writeInt(conf[i]); } } @Override public IMessage onMessage(MessageCells message, MessageContext ctx) { TileEntity TE = FMLClientHandler.instance().getWorldClient().getTileEntity(message.x, message.y, message.z); if(TE instanceof BaseCellTE) { ((BaseCellTE) TE).setEnergyStored(message.power); ((BaseCellTE) TE).setSendRecv(message.conf); } return null; } @Override public String toString() { return String.format("MessageCells - x:%s, y:%s, z:%s, energy:%s, conf:%s,%s,%s,%s,%s,%s", x, y, z, power, conf[0], conf[1], conf[2], conf[3], conf[4], conf[5]); } } TileEntity: public class BaseCellTE extends TileEntity implements IEnergyHandler, ISidedTexture { protected EnergyStorage storage; private int[] SendRecv = {0,0,0,0,0,0}; static { addMapping(TileRedCell.class, "Red Cell"); addMapping(TileGreenCell.class, "Green Cell"); addMapping(TileBlueCell.class, "Blue Cell"); addMapping(TilePurpleCell.class, "Purple Cell"); } public int getEnergyStored() { return this.storage.getEnergyStored(); } public void setEnergyStored(int amount) { this.storage.setEnergyStored(amount); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); storage.writeToNBT(nbt); nbt.setIntArray("SendRecv", SendRecv); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); SendRecv = nbt.getIntArray("SendRecv"); storage.readFromNBT(nbt); } public void changeSide(int side) { if(SendRecv[side] < 2) SendRecv[side] += 1; else SendRecv[side] = 0; this.markDirty(); } public int getSendRecv(int side) { return SendRecv[side]; } public void setSendRecv(int[] conf) {SendRecv = conf;} //Network @Override public Packet getDescriptionPacket() { return PacketHandler.INSTANCE.getPacketFrom(new MessageCells(this)); } /* IEnergyHandler */ @Override public boolean canConnectEnergy(ForgeDirection from) { return true; } @Override public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) { return storage.receiveEnergy(maxReceive, simulate); } @Override public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate) { return storage.extractEnergy(maxExtract, simulate); } @Override public int getEnergyStored(ForgeDirection from) { return storage.getEnergyStored(); } @Override public int getMaxEnergyStored(ForgeDirection from) { return storage.getMaxEnergyStored(); } public IIcon getTexture(int side, int pass) { return null; } } I will note the packethandler is being initialized in preInit.
January 1, 201510 yr You're using the wrong kind of packets. You need to use the S35PacketUpdateTileEntity ones (getDescriptionPacket and onDataPacket). Keep in mind that you put this in your TileEntity and you don't need the other classes. The proud(ish) developer of Ancients
January 1, 201510 yr Author Is the data only displayed in the Gui? Then the description packet is not the right thing to use. Synchronize the data via your container, ContainerFurnace has an example. I use the SendRecv in for changing the texture of my block.
January 2, 201510 yr Author You need to call markBlockForUpdate on the World object to send the description packet. Yes, I do. Even with using the S35PacketUpdateTileEntity, the data is not being save on closing the window. Updated Tile: public class BaseCellTE extends TileEntity implements IEnergyHandler, ISidedTexture { protected EnergyStorage storage; private int[] SendRecv = {0,0,0,0,0,0}; static { addMapping(TileRedCell.class, "Red Cell"); addMapping(TileGreenCell.class, "Green Cell"); addMapping(TileBlueCell.class, "Blue Cell"); addMapping(TilePurpleCell.class, "Purple Cell"); } public int getEnergyStored() { return this.storage.getEnergyStored(); } public void setEnergyStored(int amount) { this.storage.setEnergyStored(amount); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); storage.writeToNBT(nbt); nbt.setIntArray("SendRecv", SendRecv); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); SendRecv = nbt.getIntArray("SendRecv"); storage.readFromNBT(nbt); } public void changeSide(int side) { if(SendRecv[side] < 2) SendRecv[side] += 1; else SendRecv[side] = 0; this.markDirty(); } public int getSendRecv(int side) { return SendRecv[side]; } public void setSendRecv(int[] conf) {SendRecv = conf;} //Network @Override public Packet getDescriptionPacket() { NBTTagCompound nbt = new NBTTagCompound(); nbt.setIntArray("SendRecv", SendRecv); return new S35PacketUpdateTileEntity(xCoord,yCoord,zCoord,1,nbt); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) { this.SendRecv = packet.func_148857_g().getIntArray("SendRecv"); this.getWorldObj().markBlockForUpdate(xCoord,yCoord,zCoord); } /* IEnergyHandler */ @Override public boolean canConnectEnergy(ForgeDirection from) { return true; } @Override public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) { return storage.receiveEnergy(maxReceive, simulate); } @Override public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate) { return storage.extractEnergy(maxExtract, simulate); } @Override public int getEnergyStored(ForgeDirection from) { return storage.getEnergyStored(); } @Override public int getMaxEnergyStored(ForgeDirection from) { return storage.getMaxEnergyStored(); } public IIcon getTexture(int side, int pass) { return null; } }
January 2, 201510 yr Author Ok, you do realize that you cannot modify the data from a Gui, right? If you do that, you need a different kind of packet that is sent from the GUI. There is no gui to the block as of yet. I'm changing the data on server side from onBlockActivated.
January 2, 201510 yr Author Ok, the last thing I can think of is that you register your TE in it's static initializer. That probably won't work, because at the point where the game needs to load your TE from disk, the TE class might not be initialized yet. You need to do that in preInit. That did it! Thank you.
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.