Jump to content

[1.14.4] Single Block type in Chunk


Simon_kungen

Recommended Posts

Hi

 

This is a little over the place, but I'm going to try and summarize to the best of my ability:

 

I have a block which affects a whole chunk (a Chunkloader to be exact), and I have made so additional Chunkloaders placed in the same chunk will simply "turn off".

 

Spoiler

BlockChunkloader.java


public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack)
{

    if (!worldIn.isRemote) {


        BlockPos dub = getDuplicate(worldIn,pos);

        if (dub != null) {
            placer.sendMessage(new TranslationTextComponent("chunkloading.intercraftcore.dublicate",dub.getX(),dub.getY(),dub.getZ()));
            worldIn.setBlockState(pos,state.with(BlockProperties.ACTIVE,false));

            TileEntity tile = worldIn.getTileEntity(pos);

            if (tile instanceof ChunkLoaderBaseTileEntity) {
                ((ChunkLoaderBaseTileEntity)tile).setCanLoad(false);
            } else if (tile instanceof ChunkLoaderTimerTileEntity) {
                ((ChunkLoaderTimerTileEntity)tile).setCanLoad(false);
            }


        }
    }

    super.onBlockPlacedBy(worldIn,pos,state,placer,stack);

}



public static BlockPos[] scanForLoaders(World worldIn, BlockPos pos)
{
    List<BlockPos> positions = new ArrayList<>();

    for (BlockPos tePos : worldIn.getChunk(pos).getTileEntitiesPos()) {
        if (worldIn.getTileEntity(pos) instanceof ChunkLoaderBaseTileEntity || worldIn.getTileEntity(pos) instanceof ChunkLoaderTimerTileEntity)
            positions.add(tePos);
    }

    return positions.toArray(new BlockPos[positions.size()]);

}



public static BlockPos getDuplicate(World worldIn, BlockPos pos)
{
    for (BlockPos tePos : scanForLoaders(worldIn,pos)) {

        if (pos.getX() == tePos.getX() && pos.getY() == tePos.getY() && pos.getZ() == tePos.getZ()) continue;

        TileEntity tile = worldIn.getTileEntity(tePos);
        if (tile == null) continue;
        return tePos;
    }
    return null;
}

 

 

ChunkLoaderBaseTileEntity.java


public class ChunkLoaderBaseTileEntity extends TileEntity implements ITickableTileEntity
{

    private boolean canLoad = true;


    public ChunkLoaderBaseTileEntity()
    {
        super(IntercraftTileEntities.CHUNKLOADER);
    }



    @Override
    public void tick()
    {

        if (canLoad) {

            if (world.isRemote) return;

            BlockState state = getBlockState();
            if (!state.get(BlockProperties.ACTIVE)) return;

            Chunk chunk = world.getChunkAt(pos);

            // Should do the chunkloading here..



        } else {
            if (getBlockState().get(BlockProperties.ACTIVE))
                world.setBlockState(pos, getBlockState().with(BlockProperties.ACTIVE, false));

        }

    }


    public boolean getCanLoad()
    {
        return canLoad;
    }


    public void setCanLoad(boolean value)
    {
        canLoad = value;
        markDirty();
    }


    @Override
    public CompoundNBT write(CompoundNBT compound)
    {

        compound.putBoolean("can_load",canLoad);

        return super.write(compound);
    }

    @Override
    public void read(CompoundNBT compound)
    {
        super.read(compound);

        canLoad = compound.getBoolean("can_load");
    }
}

 

ChunkLoaderTimerTileEntity.java

Spoiler


public class ChunkLoaderTimerTileEntity extends TileEntity implements ITickableTileEntity
{

    private boolean canLoad = true;

    private long duration;

    private int seconds = 0;
    private int minutes = 30;
    private int hours = 0;
    private int days = 0;

    public ChunkLoaderTimerTileEntity()
    {
        super(IntercraftTileEntities.CHUNKLOADER_TIMER);
        duration = getResetTime();
    }




    @Override
    public void tick()
    {

        if (canLoad) {

            if (getWorld().isRemote) return;

            BlockState state = getBlockState();
            if (!state.get(BlockProperties.ACTIVE)) return;

            if (duration > 0) {


                // Should do the chunkloading here..

                Chunk chunk = world.getChunkAt(pos);

                setDuration(duration-1);
            } else {
                world.setBlockState(pos,getBlockState().with(BlockProperties.ACTIVE,false));
                setDuration(getResetTime());
            }

        } else {
            if (getBlockState().get(BlockProperties.ACTIVE))
                world.setBlockState(pos, getBlockState().with(BlockProperties.ACTIVE, false));
        }
    }


    private int mult(int value, int multi)
    {
        if (value <= 1)
            return 1;
        else
            return value*multi;

    }

    public boolean getCanLoad()
    {
        return canLoad;
    }

    public long getResetTime()
    {
        return mult(days,24) * mult(hours,60) * mult(minutes,60) * mult(minutes,60) * mult(seconds,20);
    }


    public long getDuration()
    {
        return duration;
    }

    public int getSeconds()
    {
        return seconds;
    }

    public int getMinutes()
    {
        return minutes;
    }

    public int getHours()
    {
        return hours;
    }

    public int getDays()
    {
        return days;
    }


    public void setCanLoad(boolean value)
    {
        canLoad = value;
        markDirty();
    }

    public void setDuration(long value)
    {
        duration = value;
        markDirty();
    }

    public void setSeconds(int value)
    {
        seconds = value;
        markDirty();
    }

    public void setMinutes(int value)
    {
        minutes = value;
        markDirty();
    }

    public void setHours(int value)
    {
        hours = value;
        markDirty();
    }

    public void setDays(int value)
    {
        days = value;
        markDirty();
    }



    @Override
    public CompoundNBT write(CompoundNBT compound)
    {

        compound.putBoolean("can_load",canLoad);
        compound.putLong("duration",duration);
        compound.putInt("sec",seconds);
        compound.putInt("min",minutes);
        compound.putInt("hour",hours);
        compound.putInt("day",days);

        return super.write(compound);
    }

    @Override
    public void read(CompoundNBT compound)
    {
        super.read(compound);

        canLoad = compound.getBoolean("can_load");
        duration = compound.getLong("duration");
        seconds = compound.getInt("sec");
        minutes = compound.getInt("min");
        hours = compound.getInt("hour");
        days = compound.getInt("day");
    }
}

 

 

 

 

 

The TileEntities tick, and should only do the stuff if the canLoad variable is true. So if I place a second Chunkloader in the same chunk it will make it disabled. I want when it has one of the other Chunkloaders removed it should check if it is the last one there, and if it is disabled it should be allowed to be turned back on:

 

BlockChunkloader.java

Spoiler

 


public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player)
{
    if (!worldIn.isRemote) {

        BlockPos[] blockPos = scanForLoaders(worldIn,pos);


        if (blockPos.length-1 < 2 && blockPos.length-1 > 0) {
            System.out.println("There is one left in this chunk!");

            TileEntity tile = worldIn.getTileEntity(blockPos[0]);

            for (int i=0;i<blockPos.length;i++) {
                if (!(pos.getX() == blockPos[i].getX() &&pos.getY() == blockPos[i].getY() &&pos.getZ() == blockPos[i].getZ())) {
                    tile = worldIn.getTileEntity(blockPos[i]);
                    break;
                }
            }

            if (tile instanceof ChunkLoaderBaseTileEntity) {
                ((ChunkLoaderBaseTileEntity)tile).setCanLoad(true);
                if (autoActivate())
                    worldIn.setBlockState(pos,state.with(BlockProperties.ACTIVE,true));
            } else if (tile instanceof ChunkLoaderTimerTileEntity) {
                ((ChunkLoaderTimerTileEntity)tile).setCanLoad(true);
                if (autoActivate())
                    worldIn.setBlockState(pos,state.with(BlockProperties.ACTIVE,true));
            }
        }

    }

    super.onBlockHarvested(worldIn,pos,state,player);

}

 

 

 

The strange part is that when I do this the first time it works fine, but after I've reloaded the game the canLoad variable has reverted back being disabled and doesn't seem to be affected by having a new Chunkloader placed in the chunk and then removed. The only way of fixing it is to remove the block and place a new one. Which doesn't make any sense. Not sure if it's a logic error I've missed or some other thing.

Link to comment
Share on other sites

47 minutes ago, Simon_kungen said:

but after I've reloaded the game the canLoad variable has reverted back being disabled

How did you test this? Could it have been a client server desync? Have you tried stepping through the debugger in the read and write methods along with your onBlockPlacedBy and onHarvestBlock? I'd not do so find out how the code is executing.

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.

Link to comment
Share on other sites

2 minutes ago, Animefan8888 said:

How did you test this? Could it have been a client server desync? Have you tried stepping through the debugger in the read and write methods along with your onBlockPlacedBy and onHarvestBlock? I'd not do so find out how the code is executing.

I have a visual blockstate changing whenever it is on or not. Then I have the variable whenever it CAN load that chunk in the TileEntity.

Link to comment
Share on other sites

1 minute ago, Simon_kungen said:

Using things such as the Debug Stick to change the blockstate imminently changes it back again.

I wasnt talking about the debug stick I was talking about the debugger in your IDE that allows you to step through the code.

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.

Link to comment
Share on other sites

3 minutes ago, Animefan8888 said:

I wasnt talking about the debug stick I was talking about the debugger in your IDE that allows you to step through the code.

Umm, I haven't used that before. I tried the "Debug" button instead of the "Run" button in IntelliJ idea and didn't see any differences between that and the regular run mode.

Link to comment
Share on other sites

4 minutes ago, Simon_kungen said:

differences between that and the regular run mode.

You need to setup breakpoints to tell intellij where you want it to stop. Look up how to use the debugger in intellij for more information.

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.

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



×
×
  • Create New...

Important Information

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