Jump to content

TileEntity read/write not working properly


Jipthechip

Recommended Posts

Here is my TileEntity class:

import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IStringSerializable;

import java.util.Arrays;

public class MasherBowlTileEntity extends TileEntity {

    public enum FoodType implements IStringSerializable {
        apple,
        baked_potato,
        beetroot,
        bread,
        carrot,
        chorus_fruit,
        dried_kelp,
        kelp,
        honey_bottle,
        melon_slice,
        potato,
        poisonous_potato,
        pumpkin,
        sweet_berries,
        nothing;

        @Override
        public String getName() {
            return this.name();
        }
    }

    private FoodType[] ingredients = new FoodType[4];

    public MasherBowlTileEntity(){
        super(TileEntitiesList.masher_bowl);
        clearFoods();
    }

    @Override
    public void read(CompoundNBT compound) {
        super.read(compound);
        int [] arr = compound.getIntArray("ingredients");
        System.out.print("reading ingredients: "+ arr[0] + "," + arr[1]+ "," + arr[2]+ "," + arr[3]+ "\n");
        for(int i = 0; i < arr.length; i++){
            ingredients[i] = FoodType.values()[arr[i]];
        }
    }

    private int[] foodToIntArray(FoodType[] arr){
        int[] result = new int[arr.length];
        for(int i = 0; i < arr.length; i++){
            result[i] = arr[i].ordinal();
        }
        return result;
    }

    @Override
    public CompoundNBT write(CompoundNBT compound) {
        super.write(compound);
        int [] arr = foodToIntArray(ingredients);
        compound.putIntArray("ingredients", arr);
        System.out.print("writing ingredients: "+ arr[0] + "," + arr[1]+ "," + arr[2]+ "," + arr[3]+ "\n");
        return compound;
    }

    public boolean addFood(FoodType food){
        for(int i = 0; i < ingredients.length; i++){
            if(ingredients[i] == FoodType.nothing){
                markDirty();
                ingredients[i] = food;
                return true;
            }
        }
        return false;
    }

    public void clearFoods(){
        markDirty();
        Arrays.fill(ingredients, FoodType.nothing);
    }

    public FoodType getIngredient(int index) {
        return ingredients[index];
    }
}

 

I'm having 2 issues:

 

1. I can only get write() to be called by pausing the game, despite me calling markDirty() whenever data is updated.

 

2. Even if write() was called beforehand, the array gotten in read() is of length 0, which I assume means it couldn't find an NBT matching the key. I know that the array write() is attempting to write has the correct information because the System.out.print call prints the correct information, and the key is correct.

 

Edited by Jipthechip
Link to comment
Share on other sites

7 hours ago, diesieben07 said:

That is normal. If the game were to save the chunk to disk every time a tile entity said "my data changed" then it would have to save to disk whenever you moved something around in a chest. That is not feasible. markDirty simply tells the game "next time you get around to saving, I need saving".

Oh ok, that makes sense. I was just concerned because I noticed that it wasn't calling my write function before the chunk was unloaded, and then I'd reload the chunk and my data would be gone. But now I think this is simply due to the fact that my write function isn't properly writing data to the NBT, or I'm not properly reading somehow.

7 hours ago, diesieben07 said:

When overriding TileEntity#write you must call super first and put your data in the resulting CompoundNBT. Otherwise your tile entity will not save its ID and position and cannot be loaded back in.

I added the super call to my read and write and the problem persists. Looking at some other TileEntities, I assume you need to add the super call to TileEntity#read as well? I updated my code at the top.

7 hours ago, diesieben07 said:

Also I would recommend saving your enum by name instead of by ordinal, because if you use the ordinal that means you can never change the order of entries in that enum.

I could just remember to add new entries to the end, but if I'm gonna be adding a lot, which I may have to if I want to integrate with other mods, that might get messy. But it may be worth it because it's reading/writing less data.

Edited by Jipthechip
Link to comment
Share on other sites

2 hours ago, diesieben07 said:

Show your block class and where you register your TileEntityType.

My registration class:

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class RegisterBlocks {
    @SubscribeEvent
    public static void registerBlocks(final RegistryEvent.Register<Block> event){
        event.getRegistry().registerAll(
            BlocksList.masher_bowl = new MasherBowlBlock(Block.Properties.create(Material.IRON))
            .setRegistryName(new ResourceLocation(MOD_ID, "masher_bowl"))
    }
    @SubscribeEvent
    public static void registerTE(RegistryEvent.Register<TileEntityType<?>> event) {

        event.getRegistry().registerAll(
                TileEntitiesList.masher_bowl =
                TileEntityType.Builder.create(MasherBowlTileEntity::new, BlocksList.masher_bowl).build(null)
                .setRegistryName(MOD_ID, "masher_bowl")
        );
    }
}

My Block class:

public class MasherBowlBlock extends Block {

    public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
    public static final BooleanProperty CONTAINS_ROD = BooleanProperty.create("contains_rod");
    public static final DirectionProperty ROD_FACING = DirectionProperty.create("rod_facing", Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
    public static final BooleanProperty CONTAINS_WATER = BooleanProperty.create("contains_water");
    public static final IntegerProperty STIR_PROGRESS = IntegerProperty.create("stir_progress", 0,10);


    public MasherBowlBlock(Properties properties) {
        super(properties.notSolid());
        this.setDefaultState(this.getStateContainer().getBaseState()
                .with(FACING, Direction.NORTH)
                .with(CONTAINS_ROD, false)
                .with(ROD_FACING, Direction.NORTH)
                .with(CONTAINS_WATER, false)
                .with(STIR_PROGRESS, 0)
        );
    }

    @Override
    public BlockState getStateForPlacement(BlockItemUseContext context){

        return this.getDefaultState()
                .with(FACING, context.getPlacementHorizontalFacing().getOpposite())
                .with(CONTAINS_ROD, false)
                .with(ROD_FACING, context.getPlacementHorizontalFacing().getOpposite())
                .with(CONTAINS_WATER, false)
                .with(STIR_PROGRESS, 0);
    }

    @Override
    protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
        builder.add(FACING, CONTAINS_ROD, ROD_FACING, CONTAINS_WATER, STIR_PROGRESS);
    }

    @Override
    public boolean hasTileEntity(BlockState state) {
        return true;
    }

    @Nullable
    @Override
    public TileEntity createTileEntity(BlockState state, IBlockReader world) {
        return new MasherBowlTileEntity();
    }

    @Override
    public BlockState rotate(BlockState state, Rotation rot) {
        return state.with(FACING, rot.rotate(state.get(FACING)));
    }

    @Override
    public BlockState mirror(BlockState state, Mirror mirrorIn) {
        return state.rotate(mirrorIn.toRotation(state.get(FACING)));
    }

    @Override
    public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {

        ItemStack heldItem = player.getHeldItem(handIn);
        String itemRegistryName = Objects.requireNonNull(heldItem.getItem().getRegistryName()).toString();

        System.out.println(itemRegistryName);

        switch(itemRegistryName){
            case MOD_ID+":masher_rod_item":
                if(!player.isCreative()) {
                    heldItem.setCount(heldItem.getCount() - 1);
                }
                player.sendBreakAnimation(handIn);
                worldIn.setBlockState(pos, state.with(CONTAINS_ROD, true));
                return ActionResultType.SUCCESS;

            case "minecraft:water_bucket":
                if(!state.get(CONTAINS_WATER)){
                    if(!player.isCreative()){
                        ItemStack bucket = new ItemStack(Items.BUCKET);
                        player.setHeldItem(handIn, bucket);
                    }
                    worldIn.playSound(player, pos, SoundEvents.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 10.0f, 1.0f);
                    worldIn.setBlockState(pos, state.with(CONTAINS_WATER, true));
                    return ActionResultType.SUCCESS;
                }
                break;

            case "minecraft:bucket":
                if(state.get(CONTAINS_WATER)){
                    if(!player.isCreative()){
                        ItemStack water_bucket = new ItemStack(Items.WATER_BUCKET);
                        player.setHeldItem(handIn, water_bucket);
                    }
                    worldIn.playSound(player, pos, SoundEvents.ITEM_BUCKET_FILL, SoundCategory.BLOCKS, 10.0f, 1.0f);
                    worldIn.setBlockState(pos, state.with(CONTAINS_WATER, false)
                                                    .with(STIR_PROGRESS, 0));
                    return ActionResultType.SUCCESS;
                }
                break;
        }

        // check if the item is one of the valid foods
        String path = itemRegistryName.split(":")[1];

        if(EnumUtils.isValidEnum(FoodType.class, path) && state.get(CONTAINS_WATER)) {
            FoodType food = EnumUtils.getEnum(FoodType.class, path);
            MasherBowlTileEntity tileEntity = (MasherBowlTileEntity)worldIn.getTileEntity(pos);
            assert tileEntity != null;

            if(tileEntity.addFood(food)) {
                return ActionResultType.SUCCESS;
            }
        }

        return ActionResultType.PASS;
    }
}

I also have 2 classes that store registered blocks and tile entities:

public class TileEntitiesList {
    public static TileEntityType<?> masher_bowl;
}

public class BlocksList {
    public static Block masher_bowl;
}

 

Link to comment
Share on other sites

2 hours ago, Jipthechip said:

build(null)

I am almost certain that this is wrong.

 

2 hours ago, Jipthechip said:

BlocksList.masher_bowl =

Don't set this field yourself, use @ObjectHolder annotations.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

6 minutes ago, Draco18s said:

I am almost certain that this is wrong.

That's just for the data fixer type, which as far as I understand is unnecessary.

(To be honest I've never been able to figure out data fixers in the first place...)

I'm eager to learn and am prone to mistakes. Don't hesitate to tell me how I can improve.

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

    • I didn't. The quotation marks are still around the file path first part. & tried with quotation marks both jdk-17 & -17.0.9. Just double-checked.  
    • https://www.dropbox.com/scl/fi/r92sbb0ywoc6d0wwzx8wj/crash-2023-08-17_11.43.40-server.txt?rlkey=do2x4ategaht2czeezi39v7cx&dl=0 Is there a way to fix it without my world crashing
    • DAFTAR KLIK DISINI DAFTAR KLIK DISINI Prediksi HK merupakan salah satu metode meracik angka yang sangat dibutuhkan para pecinta togel Hongkong untuk mendapatkan angka jitu. Prediksi Hongkong akan memberikan anda racikan yang sudah dibuat oleh para master angka togel dan akan dibagikan melalui situs Prediksi HK ini. Namun sebelum itu kami menegaskan yang namanya prediksi tidak ada yang sempurna, karena yang sempurna hanya milik Tuhan saja. Kami juga tidak mengatakan bahwa prediksi yang kami berikan itu asal dan tidak berdasar. Kami memberikan Bocoran HK malam ini pastinya melalui berbagai macam rumus dan dibantu oleh peracik angka togel handal. Jadi anda tidak ada salahnya juga jika menggunakan Prediksi Bocoran Togel Hongkong yang akan kami berikan disitus ini. Selaku situs Prediksi Hongkong jitu malam ini, kami juga memberikan saran kepada anda jika ingin mencari prediksi togel HK yang bagus jangan asal memilih. Karena banyak situs palsu yang tersebar di internet dan hanya memberikan angka prediksi Hk asal dan tidak berdasar. Maka kami sarankan anda bisa menggunakan Bocoran Togel Hongkong di situs kami ini sebagai acuan memilih angka yang ingin dipasang. Bocoran HK Paling Jitu Malam Ini Bocoran Hk Malam Ini tentu saja sangat membantu untuk para member yang kesulitan untuk mendapatkan angka racikan togel HK malam ini. Tapi tenang saja kami disini akan memberikan Prediksi Bocoran HK Jitu secara gratis untuk anda, sehingga anda tidak perlu lagi khawatir jika ingin mencari situs prediksi togel HK yang akurat dan gratis. Tetapi kami juga mengingatkan untuk anda jika sering mendapatkan jackpot dari bocoran togel hongkong malam ini yang ada di situs ini, kami berharap anda dapat membagikannya juga kepada kerabat dan teman anda yang memiliki hobi yang sama yaitu bermain togel online. Dengan saling berbagi tidak ada ruginya bahkan kita bisa mengalahkan bandot togel bersama-sama. Forum Master Prediksi Hongkong Malam Ini Terpercaya Apakah anda sedang mencari Master Prediksi HK yang akan memberikan racikan atau bocoran togel khususnya pasaran Hongkong? Maka disini adalah tempat yang tepat jika anda mencari racikan Prediksi Hongkong dari master togel terpercaya. Pada kesempatan hari ini Master Prediksi Togel Hongkong telah memberikan racikannya yang dapat anda lihat dalam tabel bocoran HK di atas. Kami sangat senang jika anda selalu mengunjungi forum atau situs prediksi HK kami ini. Seluruh Bocoran HK yang telah kami berikan tentu saja gratis dan tanpa dipungut biaya apapun. Karena kami membuat situs prediksi ini murni demi membantu para pemain togel yang bingung untuk mencari angka kuat untuk dipasangkan dalam pasaran togel Hongkong Malam Ini. Manfaat Prediksi Togel Hongkong Untuk Para Togelers Prediksi Togel Hongkong tentu saja sangat bermanfaat bagi setiap pemain togel online yang menggunakannya. Manfaat yang paling menonjol yaitu anda bisa mencocokkan angka anda sendiri dengan angka yang telah diracik oleh para master togel jitu. Selain itu apabila anda tidak memiliki angka sama sekali yang ingin dipasangkan, anda dapat menggunakan hasil racikan Bocoran HK dalam situs ini untuk dijadikan angka taruhan. Jadi jangan sampai kelewatan segala jenis prediksi togel hongkong yang sudah kami bagikan pada hari ini sehingga anda mendapatkan angka jitu yang ingin digunakan. Sekali lagi kami ingatkan bahwa setiap prediksi yang diberikan tidak kami jamin 100% akan tembus, tetapi setidaknya menambah peluang kemenangan. Sekian pembahasan kami dan kami harapkan anda puas dengan prediksi hk yang sudah kami berikan di situs ini. Semoga kalian jackpot dan salam togel mania. Angka Main: 5746 Angka Ikut: 8463 Colok Bebas: 6 Kepala: 5 7 | Ekor: 8 3 Twin: 44 / 66 ANGKA JITU 2D 57*54*56*58*53*75*74*76* 78*73*45*47*46*48*43*65* SHIO: KAMBING Angka Main: 4092 Angka Ikut: 6410 Colok Bebas: 4 Kepala: 6 9 | Ekor: 1 2 Twin: 44 / 00 ANGKA JITU 2D 40*49*42*46*41*04*09*02* 06*01*94*90*92*96*91*24* SHIO: TIKUS Angka Main: 6128 Angka Ikut: 4368 Colok Bebas: 8 Kepala: 1 4 | Ekor: 3 2 Twin: 66 / 88 ANGKA JITU 2D 61*62*68*64*63*16*12*18* 14*13*26*21*28*24*23*86* SHIO: HARIMAU Angka Main: 1495 Angka Ikut: 5871 Colok Bebas: 5 Kepala: 8 9 | Ekor: 7 4 Twin: 11 / 55 ANGKA JITU 2D 14*19*15*18*17*41*49*45* 48*47*91*94*95*98*97*51* SHIO: AYAM Angka Main: 9124 Angka Ikut: 4859 Colok Bebas: 9 Kepala: 5 1 | Ekor: 2 8 Twin: 99 / 44 ANGKA JITU 2D 91*92*94*98*95*19*12*14* 18*15*29*21*24*28*25*49* SHIO: KERBAU Angka Main: 2095 Angka Ikut: 8152 Colok Bebas: 2 Kepala: 1 0 | Ekor: 9 8 Twin: 22 / 55 ANGKA JITU 2D 20*29*25*28*21*02*09*05* 08*01*92*90*95*98*91*52* SHIO: KUDA
    • Hm. I did try adding that in the user_jvm_args.txt but I get this:  Error: Could not find or load main class C:Program FilesJavajdk-17.0.9binjavaw.exe Caused by: java.lang.ClassNotFoundException: C:Program FilesJavajdk-17.0.9binjavaw.exe Press any key to continue . . . I tried both with "\jdk-17\" (as it appears in the program files) as well as "\jdk-17.0.9\"  No luck. am I placing it in the wrong file? Could the second part be incorrect? 
  • Topics

×
×
  • Create New...

Important Information

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