Jump to content

1.19.2 BlockEntity - onLoad() is called before NBT data can be copied over from BlockItem


Povstalec

Recommended Posts

I've got a BlockEntity, which can save its data to an item when broken(just like a Shulker Box). I use this to generate an "address" - When the BlockEntity is placed in the world for the first time, it will generate a new address and save the address to SavedData. When it is broken, the NBT data is saved to a BlockItem and the address is deleted from SavedData. When it is placed again, this time using the BlockItem that has data from the previous BlockEntity saved, it should copy the data and check if it has the address tag; if it does, it will save the address to SavedData again.

The last part used to work for me, but then I changed some things and forgot to make a backup, so it doesn't work properly now. What it does now is: The BlockEntity checks if there is an address tag, but there isn't one, so it generates a new address which it saves to SavedData. The address tag is then copied from the BlockItem immediately after, so when I click on it to see the address, the address is different from what is now saved in SavedData.

I'm pretty sure the problem lies in the fact that onLoad() is called before BlockItem NBT data is copied over. I'm using onLoad() to check whether or not it should generate an address and I know the BlockItem NBT data is stored correctly, because:
1. I'm saving more than just the address and everything else works perfectly and 2. the BlockEntity shows the correct address after I place it and click on it.

Is there a way to fix/work around this?

Link to comment
Share on other sites

You won't get many responses if you don't show the code (preferably by posting it to github).

Just providing a description of what you think is happening vs what your code actually does is not very useful.

 

But, you know onLoad() gets called on both the client and the server? While the drops (if you are really doing it like it the shulker box) only happens on the server.

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

From what I can tell, you won't be able to use onLoad() for this.

The issue is the block placement is done in 2 steps, see BlockItem.place()

(1) BlockItem.placeBlock() which sets the block in the world using normal logic,

(2) then it does updateBlockStateFromTag() and updateCustomBlockEntityTag() to change the state/blockentity to what is in the ItemStack. 

 

Your problem is step (1) ends up in LevelChunk.setBlockState() where it creates a default BlockEntity and then calls addAndRegisterBlockEntity() which calls onLoad()

This is before it has loaded the custom data from the ItemStack in updateCustomBlockEntityTag().

 

You either need to come up with different logic for your processing or add some code to your BlockEntity.load() to detect this happening.

 

For alternative logic, you should look at how mods like AE2, refined storage or one of the mods with pipes manage their (pipe) networks.

They probably don't store important keys/identifiers the way you are doing it?

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

Alright, thanks, that helped a lot.

It gave me the idea to extend the BlockItem class and add some stuff to updateCustomBlockEntityTag(), which now deletes the randomly generated address and replaces it with the one from the BlockItem. It's probably not the best way to go around it, but it does what I want for now. I'll probably come up with something better later down the line.

Link to comment
Share on other sites

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • They were already updated, and just to double check I even did a cleanup and fresh update from that same page. I'm quite sure drivers are not the problem here. 
    • i tried downloading the drivers but it says no AMD graphics hardware has been detected    
    • Update your AMD/ATI drivers - get the drivers from their website - do not update via system  
    • As the title says i keep on crashing on forge 1.20.1 even without any mods downloaded, i have the latest drivers (nvidia) and vanilla minecraft works perfectly fine for me logs: https://pastebin.com/5UR01yG9
    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.