package com.minelittlepony.unicopia.block; import java.util.Arrays; import com.minelittlepony.unicopia.util.PosHelper; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; public interface SegmentedBlock { double[] STAGE_SIZES = new double[] {3.2, 6.4, 9.6, 12.8, 16}; VoxelShape[] STAGE_SHAPES = Arrays.stream(STAGE_SIZES).mapToObj(height -> { return Block.createCuboidShape(0, 0, 0, 16, height, 16); }).toArray(VoxelShape[]::new); static VoxelShape getShape(int age) { if (age < 0 || age >= STAGE_SHAPES.length) { return VoxelShapes.fullCube(); } return STAGE_SHAPES[age]; } static double getHeight(int age) { if (age < 0 || age >= STAGE_SHAPES.length) { return 16; } return STAGE_SIZES[age]; } static VoxelShape[] computeShapes(int maxHeight) { VoxelShape[] shapes = new VoxelShape[STAGE_SIZES.length * maxHeight]; for (int i = 0; i < maxHeight; i++) { for (int j = 0; j < STAGE_SIZES.length; j++) { shapes[j + (i * STAGE_SIZES.length)] = Block.createCuboidShape(0, 0, 0, 16, STAGE_SIZES[j] + (i * 16), 16); } } return shapes; } boolean isBase(BlockState state); boolean isNext(BlockState state); default BlockPos getTip(BlockView world, BlockPos startingPos) { return PosHelper.traverseChain(world, startingPos, Direction.UP, this::isNext); } default BlockPos getRoot(BlockView world, BlockPos startingPos) { return PosHelper.traverseChain(world, startingPos, Direction.DOWN, this::isBase); } }