Jump to content

Recommended Posts

Posted

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.

Posted

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

Posted

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.

Posted

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;
    }
}

 

Posted

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.

Posted

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.

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.