package net.minecraft.world.level.block; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.mojang.serialization.MapCodec; import java.util.Map; import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; public abstract class PipeBlock extends Block { private static final Direction[] DIRECTIONS = Direction.values(); public static final BooleanProperty NORTH = BlockStateProperties.NORTH; public static final BooleanProperty EAST = BlockStateProperties.EAST; public static final BooleanProperty SOUTH = BlockStateProperties.SOUTH; public static final BooleanProperty WEST = BlockStateProperties.WEST; public static final BooleanProperty UP = BlockStateProperties.UP; public static final BooleanProperty DOWN = BlockStateProperties.DOWN; public static final Map PROPERTY_BY_DIRECTION = ImmutableMap.copyOf(Util.make(Maps.newEnumMap(Direction.class), enumMap -> { enumMap.put(Direction.NORTH, NORTH); enumMap.put(Direction.EAST, EAST); enumMap.put(Direction.SOUTH, SOUTH); enumMap.put(Direction.WEST, WEST); enumMap.put(Direction.UP, UP); enumMap.put(Direction.DOWN, DOWN); })); protected final VoxelShape[] shapeByIndex; protected PipeBlock(float apothem, BlockBehaviour.Properties properties) { super(properties); this.shapeByIndex = this.makeShapes(apothem); } @Override protected abstract MapCodec codec(); private VoxelShape[] makeShapes(float apothem) { float f = 0.5F - apothem; float g = 0.5F + apothem; VoxelShape voxelShape = Block.box(f * 16.0F, f * 16.0F, f * 16.0F, g * 16.0F, g * 16.0F, g * 16.0F); VoxelShape[] voxelShapes = new VoxelShape[DIRECTIONS.length]; for (int i = 0; i < DIRECTIONS.length; i++) { Direction direction = DIRECTIONS[i]; voxelShapes[i] = Shapes.box( 0.5 + Math.min(-apothem, direction.getStepX() * 0.5), 0.5 + Math.min(-apothem, direction.getStepY() * 0.5), 0.5 + Math.min(-apothem, direction.getStepZ() * 0.5), 0.5 + Math.max(apothem, direction.getStepX() * 0.5), 0.5 + Math.max(apothem, direction.getStepY() * 0.5), 0.5 + Math.max(apothem, direction.getStepZ() * 0.5) ); } VoxelShape[] voxelShapes2 = new VoxelShape[64]; for (int j = 0; j < 64; j++) { VoxelShape voxelShape2 = voxelShape; for (int k = 0; k < DIRECTIONS.length; k++) { if ((j & 1 << k) != 0) { voxelShape2 = Shapes.or(voxelShape2, voxelShapes[k]); } } voxelShapes2[j] = voxelShape2; } return voxelShapes2; } @Override protected boolean propagatesSkylightDown(BlockState blockState) { return false; } @Override protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { return this.shapeByIndex[this.getAABBIndex(state)]; } protected int getAABBIndex(BlockState state) { int i = 0; for (int j = 0; j < DIRECTIONS.length; j++) { if ((Boolean)state.getValue((Property)PROPERTY_BY_DIRECTION.get(DIRECTIONS[j]))) { i |= 1 << j; } } return i; } }