Keep data after breaking Block (possibly stored into BlockItem)

Started by GaussianWonder on Fri, 01/01/2021 - 01:22

Topic category: Help with modding (Java Edition)

Last seen on 21:07, 21. Jan 2021
Joined Jan 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
Keep data after breaking Block (possibly stored into BlockItem)
Fri, 01/01/2021 - 01:22

So I have this MatterStorage Capablity that is applied on a block tile, and it is working fine when it comes to chunk loading/unloading I can successfully get & retrieve data after leaving chunks and disconnecting to the server. BUT I CAN'T FOR THE LOVE OF GOD figure out how to make it copy the CompoundNBT tag from the Block to the BlockItem before breaking it.

 

I want a way to keep data after breaking a block

 

I thought I could overwrite Block.getDrops:

@SuppressWarnings("deprecation")
@Override // inside class MatterRecyclerBlock extends Block 
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
    TileEntity tileEntity = builder.get(LootParameters.BLOCK_ENTITY);
    if(tileEntity instanceof MatterRecyclerTitle) {
        final List<ItemStack> drops = new ArrayList<>();

        ItemStack stack = ItemHandlerHelper.copyStackWithSize(new ItemStack(this), 1);
        CompoundNBT tag = new CompoundNBT();
        tag = ((MatterRecyclerTitle)tileEntity).write(tag); // something might be redundant here
        stack.setTag(tag);

        drops.add(stack);

        System.out.println("I'm just about to give custom tag to this mother chucker!");
        return drops;
    }
    else {
        return super.getDrops(state, builder);
    }
}
@Override // inside MatterRecyclerTitle extends TileEntity implements ITickableTileEntity
public CompoundNBT write(CompoundNBT tag) {
    tag.put("inv", itemHandler.serializeNBT());
    tag.put("matter", matterStorage.serializeNBT());

    tag.putInt("cooldown", cooldown);
    tag.putInt("efficiency", efficiency);
    return super.write(tag);
}

I am kinda new to modding and the documentation kinda sucks.

Last seen on 21:07, 21. Jan 2021
Joined Jan 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
I am sorry for the weird…
Fri, 01/01/2021 - 01:25

I am sorry for the weird missing punctuation marks and other formatting issues... this is the first time I am posting on this forum and I had no idea how this would've rendered on the page :(

Interesting, this looks ok…
Fri, 01/01/2021 - 10:18

Interesting, this looks ok at a first glance. Did you check what tags does returned stack has on server and on client side, maybe it is just not synced properly to the client side?

Last seen on 21:07, 21. Jan 2021
Joined Jan 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
I added this into getDrops()…
Fri, 01/01/2021 - 11:54

I added this into getDrops() after the tag write and the tag seems to be just fine. It prints only once, so that must be only a server thing.

 

System.out.println(tag.getInt("efficiency"));

 

I checked the data of the block after replacing (for both cliend and server). Both the server and the client ignore the tags written at getDrops() :)))

 

My only guess right now is that I also have to overwrite some placeBlock() method (which I don't know about yet). If it can't keep tags when breaking a block, why would it push tags when placing?

 

Also I think I have to mention that the Capability is used only for the tile entity, I didn't do anything with the MatterRecyclerBlockItem, it is still just a plain BlockItem.

 

I think I should also mention that packets of relevant data are sent to the client whenever data is modified on the BlockTile. No networking for the BlockItem (if that's even a thing).

 

Working with mc 1.16

Last seen on 21:07, 21. Jan 2021
Joined Jan 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
I finally made it work, it…
Fri, 01/01/2021 - 12:52

I finally made it work, it seems that it has to do with yet another shady undocumented thing.

 

Apparently minecraft does automatically save tags to the block when they are placed, but there are a handful of problems along the way:

 

1) I don't think you know 100% if the ItemStack has an NBT tag of its own

2) If it does, it looks at the "BlockEntityTag" tag it will read from there whatever it is to be copied.

 

    @SuppressWarnings("deprecation")
    @Override
    public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
        TileEntity tileEntity = builder.get(LootParameters.BLOCK_ENTITY);
        if(tileEntity instanceof MatterRecyclerTitle) {
            final List<ItemStack> drops = new ArrayList<>();
            ItemStack stack = new ItemStack(this);

            CompoundNBT tag = new CompoundNBT();
            ((MatterRecyclerTitle)tileEntity).write(tag);

            stack.setTagInfo("BlockEntityTag", tag);
            drops.add(stack);

            return drops;
        }
        else {
            return super.getDrops(state, builder);
        }
    }

 

This is what I currently have and it works

 

Please correct any wrong thing that I mention, I'm still learning and this might be a good topic for newcomers

It could be that data is…
Fri, 01/01/2021 - 16:55

It could be that data is synced to the client side when this tag is present.

The thing is, NBT needs to be sent to the client-side to work properly.

Last seen on 21:07, 21. Jan 2021
Joined Jan 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
Yes, there is a method in…
Tue, 01/05/2021 - 01:11

Yes, there is a method in BlockItem that you can overwrite called shouldSyncTag. It defaults to true, so it seems that it does that automatically