Расположить упавшее дерево такой же длины как и стоячее

Версия Minecraft
1.12.2
5,024
47
784
Чет посидел и появилось настроение покодить. Короче, запилил что то такое - падающее дерево после срубки.
Чет никак не могу приложить ума, как бы мне чекать высоту ствола и спавнить рядом такой же длины?
Java:
boolean check;

    public void updateTick(World world, BlockPos pos, IBlockState state, Random rand)
    {

        if (!world.isRemote)
        {
            this.onBlockDestroyedByPlayer(world, pos, state);
        }
    }
    int checker;
    public int highTree;
    private void checkBackBone(World world, BlockPos pos) {
        int x = pos.getX();
        int y = pos.getY();
        int z = pos.getZ();

        for(int i = 0; i < 10; i++) {
            checker++;
            if(world.getBlockState(new BlockPos(x,y - i,z)) != RegBlocks.test_falling_log.getDefaultState()) {           
                break;   
            }
                
        }

    }

  public void onBlockDestroyedByPlayer(World world, BlockPos pos, IBlockState state)
    {
          this.checkBackBone(world, pos);
        this.checkFallableDown(world, pos);
        this.checkFallableLogSouth1St(world, pos);
        this.checkFallableLogSouth2St(world, pos);
    }

    private boolean checkFallableLogSouth1St(World world, BlockPos pos)
    {
        IBlockState state = world.getBlockState(pos);
        

        
        if (world.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32)))
        {
            if(!world.isRemote) {
                if(world.isAirBlock(pos.down())){
                    return false;
                }
                if(world.isAirBlock(pos.south())){
                    EntityFallingBlock efb = new EntityFallingBlock(world, (double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, world.getBlockState(pos.south()));
                    this.onStartFalling(efb);
                    world.spawnEntity(efb);
                }
                if( world.isAirBlock(new BlockPos(pos.getX(),pos.getY() - 1,pos.getZ() + 1))) {

                    world.setBlockState(new BlockPos(pos.getX(),pos.getY(),pos.getZ() + 1), state.withProperty(AXIS, EnumFacing.Axis.Z));
                    world.setBlockToAir(pos);
                }
            }
        }
        return check;

    }

    private void checkFallableDown(World world, BlockPos pos)
    {   
        IBlockState state = world.getBlockState(pos);

        if (world.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32)))
        {
            if(!world.isRemote) {
                if(world.isAirBlock(pos.down())) {
                    EntityFallingBlock efb = new EntityFallingBlock(world, (double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, world.getBlockState(pos));
                    this.onStartFalling(efb);
                    world.spawnEntity(efb);
                }
            }
        }
    }
    private void checkFallableLogSouth2St(World world, BlockPos pos)
    {
        if(!check) {
            IBlockState state = world.getBlockState(pos);
        
        
            int x = pos.getX();
            int y = pos.getY();
            int z = pos.getZ();
            if (world.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32)))
            {
                if(!world.isRemote) {
                    if(world.isAirBlock(pos.down())){
                        return;
                    }
                    if(world.isAirBlock(pos.south())){
                        EntityFallingBlock efb = new EntityFallingBlock(world, (double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, world.getBlockState(new BlockPos(x,y,z + 1)));
                    //    EntityFallingBlock efb2 = new EntityFallingBlock(world, (double)pos.getX() + 0.5D, (double)pos.getY(), (double)pos.getZ() + 0.5D, world.getBlockState(new BlockPos(x,y,z + 2)));
                        this.onStartFalling(efb);
                        world.spawnEntity(efb);
                    //    world.spawnEntity(efb2);
                    }
                    if( world.getBlockState(new BlockPos(pos.getX(),pos.getY() - 1,pos.getZ() + 1)).getBlock() == RegBlocks.test_falling_log) {

                        world.setBlockState(new BlockPos(x,y,z + 2), state.withProperty(AXIS, EnumFacing.Axis.Z));
                        world.setBlockToAir(pos);
                    }
                }
            }
        }
    }
Это работает вот так.
 
Решение
Для тебя напишу)
Java:
int lenght(BlockPos pos, World world){
    return lenght(pos,world,0);
}

int lenght(BlockPos pos, World world, int curLen){
    if(world.getBlock(pos)==Blocks.oak_log)//условие для 1.12.2 возможно, не покатит(там же стейты и все такое)
        return lenght(pos.add(0,1,0),world,curLen+1);
    else return curLen;
}
7,099
324
1,510
Проверь, выполняется ли это условие для произвольного блока в мире(не твоего)?
world.getBlockState(pos) == RegBlocks.test_falling_log.getDefaultState()
 
5,024
47
784
Не думаю что это сильно поменяет дело.
up: это не будет вообще работать, так как метод lenght вызывается в onDestroedBlockPlayer.
Т.е сломать надо именно этот блок.
 
7,099
324
1,510
Мне кажется, оно всегда истинно и рекурсия поэтому не заканчивается
 
5,024
47
784
Смотри че происходит.
Если поставить мой блок снизу ломаемого то
вот это
Java:
    int lenght(World world, BlockPos pos,int curLen){
        if(world.getBlockState(pos) != RegBlocks.test_falling_log.getDefaultState())
        {   
            System.out.println("YES");
            return lenght(world, pos.add(0,1,0),curLen+1);
        }
        else
        {
            System.out.println("NOO");
            return curLen;
        }
    }

дает такой результат:

Код:
[19:25:12] [main/INFO] [STDOUT]: [ru.legendgamer.Realism.API.BasicBlock.BasicFallingLog:lenght:202]: YES
[19:25:12] [main/INFO] [STDOUT]: [ru.legendgamer.Realism.API.BasicBlock.BasicFallingLog:lenght:207]: NOO
[19:25:12] [Server thread/INFO] [STDOUT]: [ru.legendgamer.Realism.API.BasicBlock.BasicFallingLog:lenght:202]: YES
[19:25:12] [Server thread/INFO] [STDOUT]: [ru.legendgamer.Realism.API.BasicBlock.BasicFallingLog:lenght:207]: NOO

В любом другом случае - только NOO Т.е в нужном мне случае выполняются оба условия
 
7,099
324
1,510
В любом случае NOO напечатается.
YES напечатается хотя бы один раз, если дерево существует
 
3,005
192
592
5,024
47
784
Меняется. Но уже потом, после того как пройдет проверка(ну точнее, так изначально было задумано(а как щас работает хрен знает):) - сначала идет проверка какой высоты дерево, а потом только оно падает и меняются стейты)
 
5,024
47
784
решил проблему короче. три часа мне понадобилось, чтобы понять что к чему и как это сделать. При больших деревьях подлагивает, возможно это есть детектор говнокода, но
Java:
    int lenght(World world, BlockPos pos) {
        return lenght(world, pos,0);
    }

    int lenght(World world, BlockPos pos,int curLen){
        if(world.getBlockState(pos.up()) == RegBlocks.test_falling_log.getDefaultState())
        {  

            return lenght(world, pos.add(0,1,0),curLen + 1);
        }
        else
        {
            return curLen;
        }
    }
    @Override
    public void onBlockDestroyedByPlayer(World world, BlockPos pos, IBlockState state)
    {
        this.lenght(world, pos);
        int highTree = this.lenght(world, pos) + 1;
        for(int i = 1; i < highTree; i++) {
            world.setBlockState(new BlockPos(pos.getX(),pos.getY() + i,pos.getZ() + i), state.withProperty(AXIS, EnumFacing.Axis.Z));
            world.setBlockState((pos), Blocks.AIR.getDefaultState());
            world.setBlockState(new BlockPos(pos.getX(),pos.getY() + i,pos.getZ()), Blocks.AIR.getDefaultState());
        }
    }
Это выглядит вот так. Какие варики по оптимизации?
 
7,099
324
1,510

Icosider

Kotliner
Администратор
3,603
99
664
Мда...
Java:
for(int i = 1; i < highTree; i++) {
            world.setBlockState(new BlockPos(pos.getX(),pos.getY() + i,pos.getZ() + i), state.withProperty(AXIS, EnumFacing.Axis.Z));
            world.setBlockState((pos), Blocks.AIR.getDefaultState());
            world.setBlockState(new BlockPos(pos.getX(),pos.getY() + i,pos.getZ()), Blocks.AIR.getDefaultState());
        }
 
5,024
47
784
это первый код который я писал, потому напихал все-все-все в кучу, чтобы уж точно заработало. Потом оптимизировал
 
476
9
39
Кстати это уже реализовали в одном моде. Можешь поискать на minecraft.curseforge.com
 
5,024
47
784
Я видел. И даже исходники видел. Но я настолько ленив, что мне лень разбираться в чужих исходниках - пишу свое всегда.
пусть говно, зато свое
 
5,024
47
784
В смысле? Я вообще хоть когда нибудь воровал код из модов? Максимум что было из грехов - выпрашивал готовый кусочек кода для конкретной цели своей
 
Сверху