Jump to content

Recommended Posts

Posted

Hello,

 

Recently I've been developing a framework for my mod to be built around, however, when added a 'test' tile entity with an inventory, I get an issue with the item in the slot not saving when leaving and rejoining.

Here are the snippets of code of the TE's NBT:

Spoiler

    public static void saveSlotsToNBT(IItemHandler slots, NBTTagCompound compound) {
        if (slots != null && slots.getSlots() > 0) {
            NBTTagList tagList = new NBTTagList();
            for (int i = 0; i < slots.getSlots(); i++) {
                ItemStack slot = slots.getStackInSlot(i);
                NBTTagCompound tagCompound = new NBTTagCompound();
                if (ItemUtil.isValid(slot)) {
                    slot.writeToNBT(tagCompound);
                }
                tagList.appendTag(tagCompound);
            }
            compound.setTag("Items", tagList);
        }
    }

    public static void loadSlotsFromNBT(IItemHandlerModifiable slots, NBTTagCompound compound) {
        if (slots != null && slots.getSlots() > 0) {
            NBTTagList tagList = compound.getTagList("Items", 10);
            for (int i = 0; i < slots.getSlots(); i++) {
                NBTTagCompound tagCompound = tagList.getCompoundTagAt(i);
                slots.setStackInSlot(i, tagCompound != null && tagCompound.hasKey("id") ? new ItemStack(tagCompound) : ItemUtil.getEmpty());
            }
        }
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        super.writeToNBT(compound);
        saveSlotsToNBT(this.inv, compound);

        return compound;
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        super.readFromNBT(compound);
        loadSlotsFromNBT(this.inv, compound);
    }

 

 

 

If you'd like to view the whole class or other classes, you can find it on my github: https://github.com/unassignedxd/plentifulutils

 

Thanks.

Posted

I believe you need to add this to your class:

public NBTTagCompound getUpdateTag()
{
  return writeToNBT(super.getUpdateTag());
}

@Nullable
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
	return new SPacketUpdateTileEntity(getPos(), getBlockMetadata(), writeToNBT(new NBTTagCompound()));
}

@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
	readFromNBT(pkt.getNbtCompound());
}

 

Posted
54 minutes ago, unassigned said:

I get an issue with the item in the slot not saving when leaving and rejoining.

How do you know that it isnt saving, this could be a desync issue.

  • Like 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)
2 hours ago, D4RSORC said:

I believe you need to add this to your class:


public NBTTagCompound getUpdateTag()
{
  return writeToNBT(super.getUpdateTag());
}

@Nullable
@Override
public SPacketUpdateTileEntity getUpdatePacket() {
	return new SPacketUpdateTileEntity(getPos(), getBlockMetadata(), writeToNBT(new NBTTagCompound()));
}

@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
	readFromNBT(pkt.getNbtCompound());
}

 

I do have this in the TileEntityBase that I'm extending.

 

2 hours ago, Animefan8888 said:

 How do you know that it isnt saving, this could be a desync issue.

I believe it is not a desync issue as, in the tile that has the inventory, I have:

Spoiler

@Override
public void update() {
    if(this.inv.getStackInSlot(0) != ItemUtil.getEmpty())
    {
        System.out.println("client? " + world.isRemote + " - item: " + this.inv.getStackInSlot(0).getItem().getUnlocalizedName());
    }
}
 

which prints the item properly - and displays correctly when opened and closed, however, once restarted, the client prints: 

[14:59:46] [main/INFO] [STDOUT]: [unassigned.plentifulutilities.tile.TileEntityVoidAccumulator:update:25]: client? true - item: tile.air

while the server does not print anything; probably because the itemstack is considered empty.

 

Here is all of the TileEntityBase code for sending packets and saving other NBT data:

Spoiler

@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
    compound.setBoolean("DropInv", this.dropInv);
    compound.setInteger("TicksAlive", this.ticksAlive);

    return compound;
}

@Override
public void readFromNBT(NBTTagCompound compound) {
    this.dropInv = compound.getBoolean("DropInv");
    this.ticksAlive = compound.getInteger("TicksAlive");
}

@Override
public SPacketUpdateTileEntity getUpdatePacket() {
    NBTTagCompound compound = new NBTTagCompound();
    this.writeToNBT(compound);
    return new SPacketUpdateTileEntity(this.getPos(), -1, compound);
}

@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) {
    this.readFromNBT(pkt.getNbtCompound());
}

@Override
public NBTTagCompound getUpdateTag() {
    NBTTagCompound compound = new NBTTagCompound();
    this.writeToNBT(compound);
    return compound;
}

@Override
public void handleUpdateTag(NBTTagCompound tag) {
    this.readFromNBT(tag);
}

@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) {
    return !oldState.getBlock().isAssociatedBlock(newState.getBlock());
}
 

 

Thanks.

Edited by unassigned
Posted

This may not be related, but I’ve noticed your not calling super in a lot of methods, your not implementing has/getCapability and your manually implementing the saving functionality of ItemStackHander (it has a public method to write its contents to NBT).

You should also be using @ObjectHolder for your items and blocks (what if another mod overrides one of your items? currently your references will still point to an item that doesn’t exist anymore and will crash the game if used)

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Posted
5 minutes ago, Cadiboo said:

This may not be related, but I’ve noticed your not calling super in a lot of methods, your not implementing has/getCapability

2

Okay, I've added supers to methods that need it, and I do believe that I am implementing the capabilites via TileEntityBase class:

Spoiler

  @Override
    public boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing) {
        return this.getCapability(capability, facing) != null;
    }

    @Nullable
    @Override
    public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing) {
        if(capability == CapabilityEnergy.ENERGY)
        {
            IEnergyStorage storage = this.getEnergyStorage(facing);
            if(storage == null)
            {
                return (T)storage;
            }
        }
        else if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
        {
            IItemHandler iHandler = this.getItemHandler(facing);
            if(iHandler == null)
            {
                return (T)iHandler;
            }
        }
        return super.getCapability(capability, facing);
    }

    public IEnergyStorage getEnergyStorage(EnumFacing facing){ return null; }
    public IItemHandler getItemHandler(EnumFacing facing){ return null; }

 

 

If a TE needs an energy/item capability, you just set the getEnergyStorage/getItemHandler within the class, which reduces the amount of code per TE - which I do within the TE I'm testing (TileEntityVoidAccumulator)

 

10 minutes ago, Cadiboo said:

and your manually implementing the saving functionality of ItemStackHander (it has a public method to write its contents to NBT).

I was not aware of the existence of this, so I'd just throw 

this.inv.deserializeNBT(compound);

within the writeNBT; and would I use the serialize method to read or would I need to keep the functionality I have currently.

 

13 minutes ago, Cadiboo said:

You should also be using @ObjectHolder for your items and blocks (what if another mod overrides one of your items? currently your references will still point to an item that doesn’t exist anymore and will crash the game if used)

This must somewhat new, as I was not aware of this annotation (most of my modding knowledge is from 1.7.10/1.11). Would this just lead a class, or would this go where it is initialized?

 

Thanks.

 

Posted
29 minutes ago, unassigned said:

This must somewhat new, as I was not aware of this annotation (most of my modding knowledge is from 1.7.10/1.11). Would this just lead a class, or would this go where it is initialized?

Im not sure when it was added. It allows mods to override other mods items and puts in place base functionality to allow forge (in the future) to dynamically load and unload mods ingame.

You can see examples of it here

https://github.com/Cadiboo/Example-Mod/blob/master/src/main/java/cadiboo/examplemod/init/ModBlocks.java (References)

and here

https://github.com/Cadiboo/Example-Mod/blob/6a1ba1042d63b80fb6e6676a0d04018e0bc1f3ae/src/main/java/cadiboo/examplemod/EventSubscriber.java#L28-L43 (initialisation and registry)

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Posted
3 minutes ago, Cadiboo said:

 Im not sure when it was added. It allows mods to override other mods items and puts in place base functionality to allow forge (in the future) to dynamically load and unload mods ingame.

You can see examples of it here

https://github.com/Cadiboo/Example-Mod/blob/master/src/main/java/cadiboo/examplemod/init/ModBlocks.java (References)

and here

 https://github.com/Cadiboo/Example-Mod/blob/6a1ba1042d63b80fb6e6676a0d04018e0bc1f3ae/src/main/java/cadiboo/examplemod/EventSubscriber.java#L28-L43 (initialisation and registry)

Alright, I have added that to my holders, thanks!

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.