Posted March 27, 20241 yr good days this is a kind of cursed block intended to to be set in some dungeons and give lot as a chest The problem is it saves the items only when it feels like the gold and the emeralds just get loss after reload the world the block entity just goes back to the last saved state data the one whit the carbono armor item in the chest slot i made some experiments i made a custome itemhandler whit system outs to see whats happening Spoiler package mercmod.capabity; //import mercmod.capabity.briefcase_handler; import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraftforge.items.ItemStackHandler; import org.jetbrains.annotations.NotNull; public class briefcase_be_handler extends ItemStackHandler { //private final BasketBlock.BasketSize basketSize; BlockEntity container = null; public int comment = 0; public byte pulling = 0; private Long t0 = 0L; private Long t1 = 0L; private int t = 0; public long start_time = 0L; public int time = 0; public int limit = 60; public Byte action = 0; // ########## ########## ########## ########## // public briefcase_be_handler(BlockEntity blkent, int size) { super(size); this.container = blkent; } // ########## ########## ########## ########## // @Override public int getSlotLimit(int slot) { return 64; } // ########## ########## ########## ########## // @Override public boolean isItemValid(int slot, @NotNull ItemStack stack) { if ( stack == null || stack.isEmpty() ) //|| stack.getItem() instanceof BasketBlockItem { return false; } else { return super.isItemValid(slot, stack); } } // ########## ########## ########## ########## public void start_time() { this.start_time = System.currentTimeMillis(); save(); } // ########## ########## ########## ########## public void stop_time() { this.start_time = 0L; this.time = 0; save(); } // ########## ########## ########## ########## public void print(Level warudo) { System.out.println("<!-- -->"); //<!-- --> System.out.println("world => " + ((warudo.isClientSide) ? "Mundo Local" : "Mundo Servidor")); print(); } public void print() { //System.out.println("this.id = " + this.id); System.out.println("pulling = " + this.pulling); ItemStack dstack = ItemStack.EMPTY; for (int index = 0; index < this.getSlots(); index++) { dstack = getStackInSlot(index); System.out.println( "[" + index + "] (" + dstack.getCount() + "), " + dstack.getDisplayName().getString() ); } System.out.println("\n"); //<!-- --> } // ########## ########## ########## ########## public void save() { if (this.container == null) { System.out.println("\n#this.container is Null at save()#\n"); } if (this.container != null) { Level warudo = this.container.getLevel(); if(!warudo.isClientSide()) { System.out.println("\n#this.container is saving()#\n"); CompoundTag nbt = this.container.serializeNBT(); nbt.put("inventory", this.serializeNBT()); this.container.load(nbt); warudo.setBlockEntity(this.container); } return; } //this.container.saveAdditional( this.serializeNBT() ); } @Override public void setStackInSlot(int slot, @NotNull ItemStack stack) { //System.out.println("\n >>> briefcase_be_handler().setStackInSlot(" + slot + ")"); validateSlotIndex(slot); this.stacks.set(slot, stack); onContentsChanged(slot); save(); //start_time(); } @Override @NotNull public ItemStack getStackInSlot(int slot) { //System.out.println("\n <<< briefcase_be_handler().getStackInSlot(" + slot + ")"); validateSlotIndex(slot); return this.stacks.get(slot); } // ########## ########## ########## ########## // @Override public static NonNullList<ItemStack> read_items_from(ItemStack itemstack) { NonNullList<ItemStack> contained_items = NonNullList.withSize(9, ItemStack.EMPTY);// this.getContainerSize() if (itemstack.hasTag()) { CompoundTag compoundtag = itemstack.getTag(); ListTag listtag = null; int size = 0; if (compoundtag.contains("Items")) { // ListTag listtag = new ListTag(); listtag = compoundtag.getList("Items", 10); size = listtag.size(); // contained_items = NonNullList.withSize(size, ItemStack.EMPTY); for (int i = 0; i < listtag.size(); ++i) { CompoundTag itemstacktag = listtag.getCompound(i); int j = compoundtag.getByte("Slot") & 255; if (j >= 0 && j < contained_items.size()) { contained_items.set(j, ItemStack.of(itemstacktag)); } } } } return contained_items; } // ########## ########## ########## ########## // @Override public void write_item_to_slot(ItemStack container, int slot, @NotNull ItemStack stack) { //, NonNullList<ItemStack> contained_items CompoundTag compoundtag = null; if (container.hasTag()) { compoundtag = container.getTag(); } else { compoundtag = new CompoundTag(); } ListTag listtag = null; if (compoundtag.contains("Items")) { listtag = compoundtag.getList("Items", 10); }else { listtag = new ListTag(); } CompoundTag itemstacktag = null; if(slot < listtag.size() ) { itemstacktag = listtag.getCompound(slot); } else { itemstacktag = new CompoundTag(); } itemstacktag.putByte("Slot", (byte) slot); stack.save(itemstacktag); listtag.add(itemstacktag); //aqui tengi una duda, se sobreescrive o crea otra ?? compoundtag.put("Items", listtag); container.setTag(compoundtag); } // ########## ########## ########## ########## // @Override public CompoundTag serializeNBT() { //System.out.println("serializeNBT()"); ListTag nbtTagList = new ListTag(); for (int i = 0; i < stacks.size(); i++) { if (!stacks.get(i).isEmpty()) { CompoundTag itemTag = new CompoundTag(); itemTag.putInt("Slot", i); stacks.get(i).save(itemTag); nbtTagList.add(itemTag); } } CompoundTag nbt = new CompoundTag(); nbt.put("Items", nbtTagList); nbt.putInt("Size", stacks.size()); nbt.putByte("pulling", pulling); nbt.putInt("comment", comment ); if (this.start_time > 0L) { this.t1 = System.currentTimeMillis(); if (this.t1 > this.t0) { //if it a diferent microtick // System.out.println( this.t1 + " > " + this.t0 ); this.t0 = this.t1; this.t = (int) (t1 - this.start_time) / 50; if (this.t > this.time) { //if its a diferent tick every 50ms // System.out.println( this.t + " > " + this.time + ", " + this.limit ); this.time = this.t; this.onUseTick();//only once per tick if (this.time >= this.limit) { this.time = this.limit; finishUsingItem(); this.time = 0; this.stop_time(); } } } } nbt.putLong("start_time", this.start_time); nbt.putShort("time", (short) this.time); nbt.putShort("limit", (short) this.limit); nbt.putByte("action", this.action); return nbt; } // ########## ########## ########## ########## // @Override public void deserializeNBT(CompoundTag nbt) { //System.out.println("deserializeNBT"); setSize(nbt.contains("Size", Tag.TAG_INT) ? nbt.getInt("Size") : stacks.size()); ListTag tagList = nbt.getList("Items", Tag.TAG_COMPOUND); for (int i = 0; i < tagList.size(); i++) { CompoundTag itemTags = tagList.getCompound(i); int slot = itemTags.getInt("Slot"); if (slot >= 0 && slot < stacks.size()) { stacks.set(slot, ItemStack.of(itemTags)); } } this.comment = nbt.getInt("comment" ); this.pulling = nbt.getByte("pulling"); this.start_time = nbt.getLong("start_time"); this.time = nbt.getShort("time"); this.limit = nbt.getShort("limit"); this.action = nbt.getByte("action"); onLoad(); } // ########## ########## ########## ########## public void onUseTick() { System.out.println("onUseTick = " + this.time); } // ########## ########## ########## ########## public void finishUsingItem() { System.out.println("finishUsingItem = " + this.time); save(); } } the important part is this here this system out must only print when a change afects the itemhandler in the server side and here i manually force the block entity to save that custom itemhandler to the Block entity nbt and then save the BlockEnt to the world // ########## ########## ########## ########## public void save() { if (this.container == null) { System.out.println("\n#this.container is Null at save()#\n"); } if (this.container != null) { Level warudo = this.container.getLevel(); if(!warudo.isClientSide()) { System.out.println("\n#this.container is saving()#\n"); CompoundTag nbt = this.container.serializeNBT(); nbt.put("inventory", this.serializeNBT()); this.container.load(nbt); warudo.setBlockEntity(this.container); } return; } //this.container.saveAdditional( this.serializeNBT() ); } in the console i see this every time i take or move some item from the gui #this.container is saving()# #this.container is saving()# #this.container is saving()# #this.container is saving()# #this.container is saving()# #################################################### this means the menu is working and sending the changes to the server side but this blockentity nbt data is not getting save to the world warudo.setBlockEntity(this.container); is doing nothing i have more block entities and those entities has the same problem i just no notice it until know my guest is coze this happends before in 1.19 and that time whats coze i dont register the blockentities to the bus but this time im doing it Spoiler package mercmod.blockentitys; import mercmod.blocks.BlockInit; import mercmod.mercmod; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; public class BlockEntityInit { public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, mercmod.MOD_ID); public static final RegistryObject<BlockEntityType<Panel_BlockEntity>> PANEL_BLOCKENTITY = BLOCK_ENTITIES.register( "panel_blockentity", () -> BlockEntityType.Builder.of( Panel_BlockEntity::new, BlockInit.OAK_LADDER.get() ).build(null) ); public static final RegistryObject<BlockEntityType<BlockEntityBriefcase>> BLOCKENTITYBRIEFCASE = BLOCK_ENTITIES.register( "blockentitybriefcase", () -> BlockEntityType.Builder.of( BlockEntityBriefcase::new, BlockInit.BRIEFCASE.get() ).build(null) ); public static final RegistryObject<BlockEntityType<BlockEntityHardcase>> BLOCKENTITYHARDCASE = BLOCK_ENTITIES.register( "blockentityhardcase", () -> BlockEntityType.Builder.of( BlockEntityHardcase::new, BlockInit.HARDCASE.get() ).build(null) ); public static final RegistryObject<BlockEntityType<BlockEntityBodyBlock>> BLOCKENTITYMOBBLOCK = BLOCK_ENTITIES.register( "blockentitymobblock", () -> BlockEntityType.Builder.of( BlockEntityBodyBlock::new, BlockInit.DEAD_BODY.get() ).build(null) ); public static void register(IEventBus eventBus) { BLOCK_ENTITIES.register(eventBus); } } the thing is that i think this is not valid for 1.20.4 coze i get it from a 1.20.1 tutorial an probably the way of declaring it has change again public static final RegistryObject<BlockEntityType<BlockEntityBodyBlock>> BLOCKENTITYMOBBLOCK = BLOCK_ENTITIES.register( "blockentitymobblock", () -> BlockEntityType.Builder.of( BlockEntityBodyBlock::new, BlockInit.DEAD_BODY.get() ).build(null) ); ############################################################################################ what i think i need is an example a working code gits whit block entities register soo i could fix the mines according to 1.20.4 thanks for reading the long post
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.