diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 9a18713..393fa13 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -31,15 +31,13 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; * TODO add screwdriver ( iterate over theme states ) ? * TODO add blueprint for survival friendly copy paste of a theme. -> for v1.5.5 * TODO add minecraft models like wall fence etc -> for v1.6 - * TODO ( + half stair + layers ) -> priority for v1.5 - * TODO put more coherence in the double theme orders / directions -> maybe v1.6 ? * TODO better connected textures -> maybe v1.6 ? */ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; public static final ArrayList BLOCKS = new ArrayList<>(); - public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, STAIRS_CUBE, SLAB, SLABS_CUBE, STEP, STEPS_SLAB; + public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, HALF_STAIR, STAIRS_CUBE, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, SLAB, SLABS_CUBE, STEP, STEPS_SLAB, LAYER; public static ItemGroup ITEM_GROUP; public static BlockEntityType REFRAMED_BLOCK_ENTITY; @@ -54,10 +52,10 @@ public class ReFramed implements ModInitializer { SMALL_CUBES_STEP = registerReFramed("small_cubes_step" , new ReFramedSmallCubesStepBlock(cp(Blocks.OAK_PLANKS))); STAIR = registerReFramed("stair" , new ReFramedStairBlock(cp(Blocks.OAK_STAIRS))); STAIRS_CUBE = registerReFramed("stairs_cube" , new ReFramedStairsCubeBlock(cp(Blocks.OAK_STAIRS))); -// CUBE = registerReFramed("half_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO -// CUBE = registerReFramed("half_stairs_stair" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO -// CUBE = registerReFramed("half_stairs_slab" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO -// CUBE = registerReFramed("layer" , new ReFramedBlock(cp(Blocks.OAK_SLAB))); // TODO + HALF_STAIR = registerReFramed("half_stair" , new ReFramedHalfStairBlock(cp(Blocks.OAK_STAIRS))); + HALF_STAIRS_SLAB = registerReFramed("half_stairs_slab" , new ReFramedHalfStairsSlabBlock(cp(Blocks.OAK_STAIRS))); + HALF_STAIRS_STAIR = registerReFramed("half_stairs_stair" , new ReFramedHalfStairsStairBlock(cp(Blocks.OAK_STAIRS))); + LAYER = registerReFramed("layer" , new ReFramedLayerBlock(cp(Blocks.OAK_SLAB))); SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB))); SLABS_CUBE = registerReFramed("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB))); STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairBlock.java new file mode 100644 index 0000000..cb1ca8a --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairBlock.java @@ -0,0 +1,194 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.VoxelHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.function.BooleanBiFunction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE; +import static fr.adrien1106.reframed.util.blocks.Corner.*; +import static net.minecraft.data.client.VariantSettings.Rotation.*; + +public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock implements BlockStateProvider { + + public static final VoxelShape[] HALF_STAIR_VOXELS; + + private record ModelCacheKey(Corner corner, int face) {} + + public ReFramedHalfStairBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE)); + } + + @Override + public int getModelStateCount() { + return 24; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(CORNER,CORNER_FACE)); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + Corner corner = BlockHelper.getPlacementCorner(ctx); + return super.getPlacementState(ctx) + .with(CORNER, corner) + .with(CORNER_FACE, corner.getDirectionIndex(ctx.getSide().getOpposite())); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return HALF_STAIR_VOXELS[state.get(CORNER_FACE) + state.get(CORNER).getID() * 3]; + } + + @Override + public BlockStateSupplier getMultipart() { + return getHalfStairMultipart( + this, + ReFramed.id("half_stair_down_special"), + ReFramed.id("half_stair_side_special") + ); + } + + public static BlockStateSupplier getHalfStairMultipart(Block block, Identifier model_down, Identifier model_side) { + return MultipartBlockStateSupplier.create(block) + .with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R0)) + .with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R270)) + .with(GBlockstate.when(CORNER, NORTH_EAST_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R0)) + + .with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R90)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R0)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R90)) + + .with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R180)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R90)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R180)) + + .with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R0, R270)) + .with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R90, R180)) + .with(GBlockstate.when(CORNER, WEST_NORTH_DOWN, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R0, R270)) + + .with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R0)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R90)) + .with(GBlockstate.when(CORNER, EAST_SOUTH_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R0)) + + .with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R90)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R180)) + .with(GBlockstate.when(CORNER, SOUTH_WEST_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R90)) + + .with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R180)) + .with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R270)) + .with(GBlockstate.when(CORNER, WEST_NORTH_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R180)) + + .with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 0), + GBlockstate.variant(model_side, true, R180, R270)) + .with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 1), + GBlockstate.variant(model_side, true, R270, R0)) + .with(GBlockstate.when(CORNER, NORTH_EAST_UP, CORNER_FACE, 2), + GBlockstate.variant(model_down, true, R180, R270)); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2); + ShapedRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this, 4) + .pattern("I ") + .pattern("II ") + .input('I', ReFramed.CUBE) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } + + static { + final VoxelShape HALF_STAIR = VoxelShapes.combineAndSimplify( + createCuboidShape(8, 0, 0, 16, 16, 8), + createCuboidShape(0, 0, 0, 8, 8, 8), + BooleanBiFunction.OR + ); + HALF_STAIR_VOXELS = VoxelListBuilder.create(HALF_STAIR, 24) + .add(0 , VoxelHelper::rotateY, VoxelHelper::mirrorZ) + .add(0 , VoxelHelper::rotateCX, VoxelHelper::mirrorZ) + + .add(0 , VoxelHelper::rotateY) + .add(1 , VoxelHelper::rotateY) + .add(2 , VoxelHelper::rotateY) + + .add(3 , VoxelHelper::rotateY) + .add(4 , VoxelHelper::rotateY) + .add(5 , VoxelHelper::rotateY) + + .add(6 , VoxelHelper::rotateY) + .add(7 , VoxelHelper::rotateY) + .add(8 , VoxelHelper::rotateY) + + .add(0 , VoxelHelper::mirrorY) + .add(1 , VoxelHelper::mirrorY) + .add(2 , VoxelHelper::mirrorY) + + .add(12, VoxelHelper::rotateY) + .add(13, VoxelHelper::rotateY) + .add(14, VoxelHelper::rotateY) + + .add(15, VoxelHelper::rotateY) + .add(16, VoxelHelper::rotateY) + .add(17, VoxelHelper::rotateY) + + .add(18, VoxelHelper::rotateY) + .add(19, VoxelHelper::rotateY) + .add(20, VoxelHelper::rotateY) + .build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsSlabBlock.java new file mode 100644 index 0000000..e0c6c41 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsSlabBlock.java @@ -0,0 +1,103 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairMultipart; +import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape; +import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE; +import static fr.adrien1106.reframed.util.blocks.Corner.NORTH_EAST_DOWN; +import static net.minecraft.util.shape.VoxelShapes.empty; + +public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { + + private record ModelCacheKey(Corner corner, int face) {} + + public ReFramedHalfStairsSlabBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE)); + } + + @Override + public int getModelStateCount() { + return 24; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(CORNER,CORNER_FACE)); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + Corner corner = BlockHelper.getPlacementCorner(ctx); + return super.getPlacementState(ctx) + .with(CORNER, corner) + .with(CORNER_FACE, corner.getDirectionIndex(ctx.getSide().getOpposite())); + } + + @Override + public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) { + return isGhost(view, pos) ? empty(): getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE))); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE))); + } + + @Override + public VoxelShape getShape(BlockState state, int i) { + Corner corner = state.get(CORNER); + int face = state.get(CORNER_FACE); + return i == 2 + ? SMALL_CUBE_VOXELS[corner.getOpposite(face).getID()] + : HALF_STAIR_VOXELS[face + corner.getID() * 3]; + } + + @Override + public BlockStateSupplier getMultipart() { + return getHalfStairMultipart( + this, + ReFramed.id("half_stairs_slab_down_special"), + ReFramed.id("half_stairs_slab_side_special") + ); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this) + .input(ReFramed.HALF_STAIR) + .input(ReFramed.SMALL_CUBE) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsStairBlock.java new file mode 100644 index 0000000..d645df0 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfStairsStairBlock.java @@ -0,0 +1,138 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.Edge; +import fr.adrien1106.reframed.util.blocks.StairShape; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; +import static fr.adrien1106.reframed.util.blocks.Edge.*; +import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.util.shape.VoxelShapes.empty; + +public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { + public ReFramedHalfStairsStairBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(EDGE, NORTH_DOWN)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(EDGE); + } + + @Override + public int getModelStateCount() { + return 12; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(EDGE)); + } + + @Nullable + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx)); + } + + @Override + public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) { + return isGhost(view, pos) ? empty(): getStairShape(state.get(EDGE), StairShape.STRAIGHT); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getStairShape(state.get(EDGE), StairShape.STRAIGHT); + } + + @Override + public VoxelShape getShape(BlockState state, int i) { + Edge edge = state.get(EDGE); + Direction side = i == 1 + ? edge.getRightDirection() + : edge.getLeftDirection(); + Corner corner = Corner.getByDirections( + edge.getFirstDirection(), + edge.getSecondDirection(), + side + + ); + return HALF_STAIR_VOXELS[corner.getID() * 3 + corner.getDirectionIndex(side)]; + } + + @Override + public int getTopThemeIndex(BlockState state) { + return 2; + } + + @Override + public BlockStateSupplier getMultipart() { + Identifier model_id = ReFramed.id("half_stairs_stair_down_special"); + Identifier side_model_id = ReFramed.id("half_stairs_stair_side_special"); + Identifier reverse_model_id = ReFramed.id("half_stairs_stair_reverse_special"); + return MultipartBlockStateSupplier.create(this) + /* X AXIS */ + .with(GBlockstate.when(EDGE, NORTH_DOWN), + GBlockstate.variant(side_model_id, true, R90, R180)) + .with(GBlockstate.when(EDGE, DOWN_SOUTH), + GBlockstate.variant(side_model_id, true, R0, R180)) + .with(GBlockstate.when(EDGE, SOUTH_UP), + GBlockstate.variant(side_model_id, true, R270, R180)) + .with(GBlockstate.when(EDGE, UP_NORTH), + GBlockstate.variant(side_model_id, true, R180, R180)) + /* Y AXIS */ + .with(GBlockstate.when(EDGE, NORTH_EAST), + GBlockstate.variant(model_id, true, R0, R0)) + .with(GBlockstate.when(EDGE, EAST_SOUTH), + GBlockstate.variant(model_id, true, R0, R90)) + .with(GBlockstate.when(EDGE, SOUTH_WEST), + GBlockstate.variant(model_id, true, R0, R180)) + .with(GBlockstate.when(EDGE, WEST_NORTH), + GBlockstate.variant(model_id, true, R0, R270)) + /* Z AXIS */ + .with(GBlockstate.when(EDGE, DOWN_EAST), + GBlockstate.variant(side_model_id, true, R0, R90)) + .with(GBlockstate.when(EDGE, EAST_UP), + GBlockstate.variant(reverse_model_id, true, R180, R270)) + .with(GBlockstate.when(EDGE, UP_WEST), + GBlockstate.variant(side_model_id, true, R180, R90)) + .with(GBlockstate.when(EDGE, WEST_DOWN), + GBlockstate.variant(reverse_model_id, true, R0, R270)); + } + + @Override + public void setRecipe(RecipeExporter exporter) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 2); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, this) + .input(ReFramed.HALF_STAIR, 2) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) + .offerTo(exporter); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedLayerBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedLayerBlock.java new file mode 100644 index 0000000..e7e8be5 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedLayerBlock.java @@ -0,0 +1,117 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.GBlockstate; +import fr.adrien1106.reframed.util.VoxelHelper; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.state.StateManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; +import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.state.property.Properties.FACING; +import static net.minecraft.state.property.Properties.LAYERS; + +public class ReFramedLayerBlock extends ReFramedSlabBlock { + + public static final VoxelShape[] LAYER_VOXELS; + private record ModelCacheKey(Direction face, int layer) {} + + public ReFramedLayerBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(LAYERS, 1)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(FACING), state.get(LAYERS)); + } + + @Override + public int getModelStateCount() { + return 48; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(LAYERS)); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return LAYER_VOXELS[state.get(FACING).getId() * 8 + state.get(LAYERS) - 1]; + } + + @Override + public boolean canReplace(BlockState state, ItemPlacementContext ctx) { + return !(!state.isOf(this) || ctx.getPlayer().isSneaking() || state.get(LAYERS) == 8); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos()); + if (!previous.isOf(this)) return super.getPlacementState(ctx); + return previous.with(LAYERS, previous.get(LAYERS) + 1); + } + + @Override + public MultipartBlockStateSupplier getMultipart() { + String model_pattern = "layer_x_special"; + MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(this); + for (int i = 1; i <= 8; i++) { + Identifier model = ReFramed.id(model_pattern.replace("x", i + "")); + supplier + .with(GBlockstate.when(FACING, Direction.DOWN, LAYERS, i), + GBlockstate.variant(model, true, R0, R0)) + .with(GBlockstate.when(FACING, Direction.SOUTH, LAYERS, i), + GBlockstate.variant(model, true, R90, R0)) + .with(GBlockstate.when(FACING, Direction.UP, LAYERS, i), + GBlockstate.variant(model, true, R180, R0)) + .with(GBlockstate.when(FACING, Direction.NORTH, LAYERS, i), + GBlockstate.variant(model, true, R270, R0)) + .with(GBlockstate.when(FACING, Direction.WEST, LAYERS, i), + GBlockstate.variant(model, true, R90, R90)) + .with(GBlockstate.when(FACING, Direction.EAST, LAYERS, i), + GBlockstate.variant(model, true, R90, R270)); + } + return supplier; + } + + static { + VoxelListBuilder builder = VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 2, 16), 48) + .add(createCuboidShape(0, 0, 0, 16, 4, 16)) + .add(createCuboidShape(0, 0, 0, 16, 6, 16)) + .add(createCuboidShape(0, 0, 0, 16, 8, 16)) + .add(createCuboidShape(0, 0, 0, 16, 10, 16)) + .add(createCuboidShape(0, 0, 0, 16, 12, 16)) + .add(createCuboidShape(0, 0, 0, 16, 14, 16)) + .add(createCuboidShape(0, 0, 0, 16, 16, 16)); + + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::mirrorY); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateX); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateCX); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateCZ); + } + for (int i = 0; i < 8; i++) { + builder.add(i, VoxelHelper::rotateZ); + } + + LAYER_VOXELS = builder.build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java index 1e43fa0..bce79f6 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubeBlock.java @@ -19,22 +19,19 @@ import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; import net.minecraft.util.Identifier; 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; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; import static fr.adrien1106.reframed.util.blocks.Corner.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implements BlockStateProvider { - public static final List SMALL_CUBE_VOXELS = new ArrayList<>(8); + public static final VoxelShape[] SMALL_CUBE_VOXELS; public ReFramedSmallCubeBlock(Settings settings) { super(settings); @@ -63,16 +60,7 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implement @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return switch (state.get(CORNER)) { - case NORTH_EAST_DOWN -> SMALL_CUBE_VOXELS.get(0); - case EAST_SOUTH_DOWN -> SMALL_CUBE_VOXELS.get(1); - case SOUTH_WEST_DOWN -> SMALL_CUBE_VOXELS.get(2); - case WEST_NORTH_DOWN -> SMALL_CUBE_VOXELS.get(3); - case NORTH_EAST_UP -> SMALL_CUBE_VOXELS.get(4); - case EAST_SOUTH_UP -> SMALL_CUBE_VOXELS.get(5); - case SOUTH_WEST_UP -> SMALL_CUBE_VOXELS.get(6); - case WEST_NORTH_UP -> SMALL_CUBE_VOXELS.get(7); - }; + return SMALL_CUBE_VOXELS[state.get(CORNER).getID()]; } @Override @@ -111,14 +99,15 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock implement static { final VoxelShape SMALL_CUBE = VoxelShapes.cuboid(.5f, 0f, 0f, 1f, .5f, .5f); - SMALL_CUBE_VOXELS.add(SMALL_CUBE); - SMALL_CUBE_VOXELS.add(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.rotateCounterClockwise(SMALL_CUBE, Direction.Axis.Y)); + SMALL_CUBE_VOXELS = VoxelListBuilder.create(SMALL_CUBE, 8) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(SMALL_CUBE, Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y), Direction.Axis.Y)); - SMALL_CUBE_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(SMALL_CUBE, Direction.Axis.Y), Direction.Axis.Y)); + .add(SMALL_CUBE, VoxelHelper::mirrorY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .build(); } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java index 7a50811..cf663bd 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSmallCubesStepBlock.java @@ -4,6 +4,7 @@ import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; import fr.adrien1106.reframed.util.blocks.Edge; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; @@ -13,7 +14,7 @@ import net.minecraft.data.client.BlockStateSupplier; import net.minecraft.data.client.MultipartBlockStateSupplier; import net.minecraft.data.server.recipe.RecipeExporter; import net.minecraft.data.server.recipe.RecipeProvider; -import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.ItemPlacementContext; import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; @@ -70,20 +71,14 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc @Override public VoxelShape getShape(BlockState state, int i) { - return switch (state.get(EDGE)) { - case NORTH_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 3 : 0); - case DOWN_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 2); - case SOUTH_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 6 : 5); - case UP_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 4 : 7); - case WEST_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 2 : 3); - case DOWN_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 1); - case EAST_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 5 : 4); - case UP_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 7 : 6); - case WEST_NORTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 3 : 7); - case NORTH_EAST -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 4); - case EAST_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 5); - case SOUTH_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 2 : 6); - }; + Edge edge = state.get(EDGE); + return SMALL_CUBE_VOXELS[Corner.getByDirections( + edge.getFirstDirection(), + edge.getSecondDirection(), + i == 1 + ? edge.getRightDirection() + : edge.getLeftDirection() + ).getID()]; } @Override @@ -93,44 +88,44 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc @Override public BlockStateSupplier getMultipart() { - Identifier small_cube_id = ReFramed.id("double_small_cube_special"); + Identifier model_id = ReFramed.id("small_cubes_step_special"); + Identifier reverse_model_id = ReFramed.id("small_cubes_step_reverse_special"); return MultipartBlockStateSupplier.create(this) /* X AXIS */ .with(GBlockstate.when(EDGE, DOWN_EAST), - GBlockstate.variant(small_cube_id, true, R0, R0)) + GBlockstate.variant(reverse_model_id, true, R0, R0)) .with(GBlockstate.when(EDGE, EAST_UP), - GBlockstate.variant(small_cube_id, true, R180, R0)) + GBlockstate.variant(model_id, true, R180, R0)) .with(GBlockstate.when(EDGE, UP_WEST), - GBlockstate.variant(small_cube_id, true, R180, R180)) + GBlockstate.variant(reverse_model_id, true, R180, R180)) .with(GBlockstate.when(EDGE, WEST_DOWN), - GBlockstate.variant(small_cube_id, true, R0, R180)) + GBlockstate.variant(model_id, true, R0, R180)) /* Y AXIS */ .with(GBlockstate.when(EDGE, EAST_SOUTH), - GBlockstate.variant(small_cube_id, true, R90, R0)) + GBlockstate.variant(model_id, true, R90, R0)) .with(GBlockstate.when(EDGE, SOUTH_WEST), - GBlockstate.variant(small_cube_id, true, R90, R90)) + GBlockstate.variant(model_id, true, R90, R90)) .with(GBlockstate.when(EDGE, WEST_NORTH), - GBlockstate.variant(small_cube_id, true, R90, R180)) + GBlockstate.variant(model_id, true, R90, R180)) .with(GBlockstate.when(EDGE, NORTH_EAST), - GBlockstate.variant(small_cube_id, true, R90, R270)) + GBlockstate.variant(model_id, true, R90, R270)) /* Z AXIS */ .with(GBlockstate.when(EDGE, DOWN_SOUTH), - GBlockstate.variant(small_cube_id, true, R0, R90)) + GBlockstate.variant(reverse_model_id, true, R0, R90)) .with(GBlockstate.when(EDGE, NORTH_DOWN), - GBlockstate.variant(small_cube_id, true, R0, R270)) + GBlockstate.variant(model_id, true, R0, R270)) .with(GBlockstate.when(EDGE, UP_NORTH), - GBlockstate.variant(small_cube_id, true, R180, R270)) + GBlockstate.variant(reverse_model_id, true, R180, R270)) .with(GBlockstate.when(EDGE, SOUTH_UP), - GBlockstate.variant(small_cube_id, true, R180, R90)); + GBlockstate.variant(model_id, true, R180, R90)); } @Override public void setRecipe(RecipeExporter exporter) { RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 4); - ShapedRecipeJsonBuilder + ShapelessRecipeJsonBuilder .create(RecipeCategory.BUILDING_BLOCKS, this) - .pattern("II") - .input('I', ReFramed.SMALL_CUBE) + .input(ReFramed.SMALL_CUBE, 2) .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) .offerTo(exporter); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java index a4386c8..452fe21 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairBlock.java @@ -1,17 +1,18 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.VoxelHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.blocks.Edge; import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; -import net.minecraft.data.client.*; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.client.When; import net.minecraft.data.server.recipe.RecipeExporter; import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; @@ -22,7 +23,6 @@ import net.minecraft.util.Identifier; import net.minecraft.util.function.BooleanBiFunction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Direction.Axis; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; @@ -30,18 +30,17 @@ import net.minecraft.world.World; import net.minecraft.world.WorldAccess; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; import java.util.stream.Stream; -import static fr.adrien1106.reframed.util.blocks.BlockProperties.*; +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; +import static fr.adrien1106.reframed.util.blocks.Edge.*; import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; -import static fr.adrien1106.reframed.util.blocks.Edge.*; public class ReFramedStairBlock extends WaterloggableReFramedBlock implements BlockStateProvider { - - public static final List VOXEL_LIST = new ArrayList<>(52); + public static final VoxelShape[] STAIR_VOXELS; private record ModelCacheKey(Edge edge, StairShape shape) {} public ReFramedStairBlock(Settings settings) { @@ -85,124 +84,13 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos); } - /* ---------------------------------- DON'T GO FURTHER IF YOU LIKE HAVING EYES ---------------------------------- */ @Override public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return getOutline(state); + return getStairShape(state.get(EDGE), state.get(STAIR_SHAPE)); } - public static VoxelShape getOutline(BlockState state) { - StairShape shape = state.get(STAIR_SHAPE); - Edge direction = state.get(EDGE); - return switch (shape) { - case STRAIGHT -> - switch (direction) { - case DOWN_SOUTH -> VOXEL_LIST.get(0); - case NORTH_DOWN -> VOXEL_LIST.get(1); - case UP_NORTH -> VOXEL_LIST.get(2); - case SOUTH_UP -> VOXEL_LIST.get(3); - case DOWN_EAST -> VOXEL_LIST.get(4); - case WEST_DOWN -> VOXEL_LIST.get(5); - case UP_WEST -> VOXEL_LIST.get(6); - case EAST_UP -> VOXEL_LIST.get(7); - case NORTH_EAST -> VOXEL_LIST.get(8); - case EAST_SOUTH -> VOXEL_LIST.get(9); - case SOUTH_WEST -> VOXEL_LIST.get(10); - case WEST_NORTH -> VOXEL_LIST.get(11); - }; - case INNER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(44); - case DOWN_EAST -> VOXEL_LIST.get(45); - case DOWN_SOUTH -> VOXEL_LIST.get(47); - case UP_WEST, UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(48); - case EAST_UP, NORTH_EAST -> VOXEL_LIST.get(49); - case EAST_SOUTH -> VOXEL_LIST.get(50); - case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(51); - }; - case INNER_RIGHT -> - switch (direction) { - case WEST_NORTH -> VOXEL_LIST.get(44); - case NORTH_DOWN, NORTH_EAST -> VOXEL_LIST.get(45); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(46); - case WEST_DOWN, SOUTH_WEST -> VOXEL_LIST.get(47); - case UP_NORTH -> VOXEL_LIST.get(49); - case EAST_UP, SOUTH_UP -> VOXEL_LIST.get(50); - case UP_WEST -> VOXEL_LIST.get(51); - }; - case OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> VOXEL_LIST.get(43); - case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(42); - case DOWN_SOUTH -> VOXEL_LIST.get(41); - case EAST_UP, NORTH_EAST -> VOXEL_LIST.get(39); - case UP_WEST, UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(38); - case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(37); - case EAST_SOUTH -> VOXEL_LIST.get(36); - }; - case OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN, NORTH_EAST -> VOXEL_LIST.get(43); - case WEST_NORTH -> VOXEL_LIST.get(42); - case WEST_DOWN, SOUTH_WEST -> VOXEL_LIST.get(41); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(40); - case UP_NORTH -> VOXEL_LIST.get(39); - case UP_WEST -> VOXEL_LIST.get(37); - case EAST_UP, SOUTH_UP -> VOXEL_LIST.get(36); - }; - case FIRST_OUTER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(14); - case SOUTH_UP -> VOXEL_LIST.get(17); - case EAST_UP -> VOXEL_LIST.get(19); - case EAST_SOUTH -> VOXEL_LIST.get(20); - case DOWN_SOUTH -> VOXEL_LIST.get(22); - case UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(25); - case SOUTH_WEST -> VOXEL_LIST.get(28); - case UP_WEST -> VOXEL_LIST.get(31); - case DOWN_EAST -> VOXEL_LIST.get(34); - case NORTH_EAST -> VOXEL_LIST.get(35); - }; - case FIRST_OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN -> VOXEL_LIST.get(15); - case SOUTH_UP, EAST_UP -> VOXEL_LIST.get(16); - case WEST_DOWN -> VOXEL_LIST.get(13); - case DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(23); - case UP_NORTH -> VOXEL_LIST.get(24); - case WEST_NORTH -> VOXEL_LIST.get(26); - case UP_WEST -> VOXEL_LIST.get(28); - case SOUTH_WEST -> VOXEL_LIST.get(29); - case DOWN_EAST -> VOXEL_LIST.get(33); - case NORTH_EAST -> VOXEL_LIST.get(34); - }; - case SECOND_OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> VOXEL_LIST.get(15); - case DOWN_SOUTH -> VOXEL_LIST.get(13); - case UP_WEST, UP_NORTH -> VOXEL_LIST.get(18); - case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(21); - case NORTH_EAST -> VOXEL_LIST.get(24); - case NORTH_DOWN -> VOXEL_LIST.get(26); - case WEST_DOWN -> VOXEL_LIST.get(30); - case WEST_NORTH -> VOXEL_LIST.get(31); - case EAST_SOUTH -> VOXEL_LIST.get(32); - case EAST_UP -> VOXEL_LIST.get(35); - }; - case SECOND_OUTER_RIGHT -> - switch (direction) { - case DOWN_SOUTH, DOWN_EAST -> VOXEL_LIST.get(12); - case UP_WEST -> VOXEL_LIST.get(17); - case UP_NORTH -> VOXEL_LIST.get(19); - case SOUTH_UP -> VOXEL_LIST.get(20); - case SOUTH_WEST -> VOXEL_LIST.get(22); - case NORTH_EAST, NORTH_DOWN -> VOXEL_LIST.get(27); - case WEST_DOWN -> VOXEL_LIST.get(29); - case WEST_NORTH -> VOXEL_LIST.get(30); - case EAST_UP -> VOXEL_LIST.get(32); - case EAST_SOUTH -> VOXEL_LIST.get(33); - }; - }; + public static VoxelShape getStairShape(Edge edge, StairShape shape) { + return STAIR_VOXELS[edge.getID() * 9 + shape.getID()]; } @Override @@ -211,12 +99,12 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl } public static MultipartBlockStateSupplier getStairMultipart(Block block, boolean is_double) { - String prefix = is_double ? "double_" : ""; - Identifier straight_id = ReFramed.id(prefix + "stairs_special"); - Identifier double_outer_id = ReFramed.id(prefix + "outers_stairs_special"); - Identifier inner_id = ReFramed.id(prefix + "inner_stairs_special"); - Identifier outer_id = ReFramed.id(prefix + "outer_stairs_special"); - Identifier outer_side_id = ReFramed.id(prefix + "outer_side_stairs_special"); + String infix = is_double ? "s_cube" : ""; + Identifier straight_id = ReFramed.id("stair" + infix + "_special"); + Identifier double_outer_id = ReFramed.id("outers_stair" + infix + "_special"); + Identifier inner_id = ReFramed.id("inner_stair" + infix + "_special"); + Identifier outer_id = ReFramed.id("outer_stair" + infix + "_special"); + Identifier outer_side_id = ReFramed.id("outer_side_stair" + infix + "_special"); return MultipartBlockStateSupplier.create(block) /* STRAIGHT X AXIS */ .with(GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, STRAIGHT), @@ -247,22 +135,22 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl GBlockstate.variant(straight_id, true, R180, R90)) /* INNER BOTTOM */ .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R0, R270)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R0, R90)) @@ -270,55 +158,55 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl .with(When.anyOf( GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R180, R0)) .with(When.anyOf( GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT), - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.variant(inner_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.variant(inner_id, true, R180, R270)) /* OUTER BOTTOM */ .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R0, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R0, R270)) /* OUTER TOP */ .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_id, true, R180, R270)) /* OUTER EAST */ @@ -341,19 +229,19 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl /* OUTER SOUTH */ .with(When.anyOf( GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R0, R90)) .with(When.anyOf( GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R90, R90)) .with(When.anyOf( GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R180, R90)) .with(When.anyOf( GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R270, R90)) /* OUTER WEST */ .with(When.anyOf( @@ -375,59 +263,59 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl /* OUTER NORTH */ .with(When.anyOf( GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT), - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R0, R270)) .with(When.anyOf( GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT), - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.variant(outer_side_id, true, R90, R270)) .with(When.anyOf( GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT), - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R180, R270)) .with(When.anyOf( GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.variant(outer_side_id, true, R270, R270)) /* OUTER BOTTOM */ .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.variant(double_outer_id, true, R0, R270)) /* OUTER TOP */ .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R0)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R90)) .with(When.anyOf( - GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R180)) .with(When.anyOf( - GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT), + GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.variant(double_outer_id, true, R180, R270)); @@ -448,89 +336,98 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock implements Bl } static { - final VoxelShape STRAIGHT = Stream.of( - VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f), - VoxelShapes.cuboid(0.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); - final VoxelShape JUNCTION = Stream.of( - VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); - final VoxelShape OUTER = Stream.of( - VoxelShapes.cuboid(0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f), - VoxelShapes.cuboid(0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.0f, 0.5f, 1.0f, 0.5f, 1.0f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); + final VoxelShape STRAIGHT = VoxelShapes.combineAndSimplify( + createCuboidShape(0, 8, 0, 16, 16, 8), + createCuboidShape(0, 0, 0, 16, 8, 16), + BooleanBiFunction.OR + ); final VoxelShape INNER = Stream.of( - VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f), - VoxelShapes.cuboid(0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f), - VoxelShapes.cuboid(0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f) - ).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get(); + createCuboidShape(0, 8, 0, 16, 16, 8), + createCuboidShape(0, 8, 8, 8, 16, 16), + createCuboidShape(0, 0, 0, 16, 8, 16) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, BooleanBiFunction.OR)).get(); + final VoxelShape OUTER = Stream.of( + createCuboidShape(0, 8, 0, 8, 16, 8), + createCuboidShape(8, 0, 0, 16, 8, 8), + createCuboidShape(0, 0, 0, 8, 8, 16) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, BooleanBiFunction.OR)).get(); + final VoxelShape JUNCTION = VoxelShapes.combineAndSimplify( + createCuboidShape(0, 8, 0, 8, 16, 8), + createCuboidShape(0, 0, 0, 16, 8, 16), + BooleanBiFunction.OR + ); - VOXEL_LIST.add(STRAIGHT); - VOXEL_LIST.add(VoxelHelper.mirror(STRAIGHT, Axis.Z)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.X), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.X)); - - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.X)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.Z), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.Z)); - - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y), Axis.Z)); - - VOXEL_LIST.add(JUNCTION); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(JUNCTION, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(JUNCTION, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.mirror(JUNCTION, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z)); - - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z), Axis.Z)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z)); - - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X)); - - VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X), Axis.X)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X)); - - VOXEL_LIST.add(OUTER); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(OUTER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(OUTER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(OUTER, Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.mirror(OUTER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y)); - - VOXEL_LIST.add(INNER); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(INNER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(INNER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(INNER, Axis.Y)); - - VOXEL_LIST.add(VoxelHelper.mirror(INNER, Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y), Axis.Y)); - VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y)); + STAIR_VOXELS = VoxelListBuilder.create(STRAIGHT, 108) + .add(INNER).add(VoxelHelper::rotateY) + .add(OUTER).add(VoxelHelper::rotateY) + .add(JUNCTION).add(VoxelHelper::rotateY) + .add(JUNCTION, VoxelHelper::rotateX, VoxelHelper::rotateZ).add(VoxelHelper::rotateZ) + // DOWN_SOUTH + .add(0, VoxelHelper::rotateCX) + .add(1, VoxelHelper::rotateCX).add(2, VoxelHelper::rotateCX) + .add(3, VoxelHelper::rotateCX).add(4, VoxelHelper::rotateCX) + .add(5, VoxelHelper::rotateCX).add(6, VoxelHelper::rotateCX) + .add(7, VoxelHelper::rotateCX).add(8, VoxelHelper::rotateCX) + // SOUTH_UP + .add(9, VoxelHelper::rotateCX) + .add(10, VoxelHelper::rotateCX).add(11, VoxelHelper::rotateCX) + .add(12, VoxelHelper::rotateCX).add(13, VoxelHelper::rotateCX) + .add(14, VoxelHelper::rotateCX).add(15, VoxelHelper::rotateCX) + .add(16, VoxelHelper::rotateCX).add(17, VoxelHelper::rotateCX) + // UP_NORTH + .add(18, VoxelHelper::rotateCX) + .add(19, VoxelHelper::rotateCX).add(20, VoxelHelper::rotateCX) + .add(21, VoxelHelper::rotateCX).add(22, VoxelHelper::rotateCX) + .add(23, VoxelHelper::rotateCX).add(24, VoxelHelper::rotateCX) + .add(25, VoxelHelper::rotateCX).add(26, VoxelHelper::rotateCX) + // WEST_DOWN + .add(0, VoxelHelper::rotateCY) + .add(10).add(1) + .add(12).add(3) + .add(16).add(5) + .add(7, VoxelHelper::rotateCY).add(8, VoxelHelper::rotateCY) + // DOWN_EAST + .add(36, VoxelHelper::rotateZ) + .add(11).add(2) + .add(13).add(4) + .add(41, VoxelHelper::rotateZ).add(42, VoxelHelper::rotateZ) + .add(17).add(6) + // EAST_UP + .add(45, VoxelHelper::rotateZ) + .add(20).add(29) + .add(22).add(31) + .add(24).add(35) + .add(52, VoxelHelper::rotateZ).add(53, VoxelHelper::rotateZ) + // UP_WEST + .add(54, VoxelHelper::rotateZ) + .add(19).add(28) + .add(21).add(30) + .add(59, VoxelHelper::rotateZ).add(60, VoxelHelper::rotateZ) + .add(23).add(34) + // WEST_NORTH + .add(0, VoxelHelper::rotateCZ) + .add(1).add(28) + .add(3).add(30) + .add(7).add(32) + .add(44).add(69) + // NORTH_EAST + .add(72, VoxelHelper::rotateY) + .add(2).add(29) + .add(4).add(31) + .add(51).add(62) + .add(8).add(33) + // EAST_SOUTH + .add(81, VoxelHelper::rotateY) + .add(11).add(20) + .add(13).add(22) + .add(15).add(26) + .add(50).add(61) + // SOUTH_WEST + .add(90, VoxelHelper::rotateY) + .add(10).add(19) + .add(12).add(21) + .add(43).add(68) + .add(14).add(25) + .build(); } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java index 8af13f1..60b44f9 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsCubeBlock.java @@ -15,25 +15,21 @@ import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.ItemPlacementContext; import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; -import net.minecraft.util.function.BooleanBiFunction; 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.World; import net.minecraft.world.WorldAccess; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - import static fr.adrien1106.reframed.block.ReFramedStairBlock.*; +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements BlockStateProvider { - private static final List COMPLEMENT_LIST = new ArrayList<>(52); + private static final VoxelShape[] STAIRS_CUBE_VOXELS = VoxelListBuilder.buildFrom(STAIR_VOXELS); private record ModelCacheKey(Edge edge, StairShape shape) {} public ReFramedStairsCubeBlock(Settings settings) { @@ -80,121 +76,9 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc @Override public VoxelShape getShape(BlockState state, int i) { - return i == 2 ? getComplementOutline(state) : getOutline(state); - } - - private VoxelShape getComplementOutline(BlockState state) { + Edge edge = state.get(EDGE); StairShape shape = state.get(STAIR_SHAPE); - Edge direction = state.get(EDGE); - return switch (shape) { - case STRAIGHT -> - switch (direction) { - case DOWN_SOUTH -> COMPLEMENT_LIST.get(0); - case NORTH_DOWN -> COMPLEMENT_LIST.get(1); - case UP_NORTH -> COMPLEMENT_LIST.get(2); - case SOUTH_UP -> COMPLEMENT_LIST.get(3); - case DOWN_EAST -> COMPLEMENT_LIST.get(4); - case WEST_DOWN -> COMPLEMENT_LIST.get(5); - case UP_WEST -> COMPLEMENT_LIST.get(6); - case EAST_UP -> COMPLEMENT_LIST.get(7); - case NORTH_EAST -> COMPLEMENT_LIST.get(8); - case EAST_SOUTH -> COMPLEMENT_LIST.get(9); - case SOUTH_WEST -> COMPLEMENT_LIST.get(10); - case WEST_NORTH -> COMPLEMENT_LIST.get(11); - }; - case INNER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> COMPLEMENT_LIST.get(44); - case DOWN_EAST -> COMPLEMENT_LIST.get(45); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(47); - case UP_WEST, UP_NORTH, WEST_NORTH -> COMPLEMENT_LIST.get(48); - case EAST_UP, NORTH_EAST -> COMPLEMENT_LIST.get(49); - case EAST_SOUTH -> COMPLEMENT_LIST.get(50); - case SOUTH_UP, SOUTH_WEST -> COMPLEMENT_LIST.get(51); - }; - case INNER_RIGHT -> - switch (direction) { - case WEST_NORTH -> COMPLEMENT_LIST.get(44); - case NORTH_DOWN, NORTH_EAST -> COMPLEMENT_LIST.get(45); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> COMPLEMENT_LIST.get(46); - case WEST_DOWN, SOUTH_WEST -> COMPLEMENT_LIST.get(47); - case UP_NORTH -> COMPLEMENT_LIST.get(49); - case EAST_UP, SOUTH_UP -> COMPLEMENT_LIST.get(50); - case UP_WEST -> COMPLEMENT_LIST.get(51); - }; - case OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> COMPLEMENT_LIST.get(43); - case WEST_DOWN, NORTH_DOWN -> COMPLEMENT_LIST.get(42); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(41); - case EAST_UP, NORTH_EAST -> COMPLEMENT_LIST.get(39); - case UP_WEST, UP_NORTH, WEST_NORTH -> COMPLEMENT_LIST.get(38); - case SOUTH_UP, SOUTH_WEST -> COMPLEMENT_LIST.get(37); - case EAST_SOUTH -> COMPLEMENT_LIST.get(36); - }; - case OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN, NORTH_EAST -> COMPLEMENT_LIST.get(43); - case WEST_NORTH -> COMPLEMENT_LIST.get(42); - case WEST_DOWN, SOUTH_WEST -> COMPLEMENT_LIST.get(41); - case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> COMPLEMENT_LIST.get(40); - case UP_NORTH -> COMPLEMENT_LIST.get(39); - case UP_WEST -> COMPLEMENT_LIST.get(37); - case EAST_UP, SOUTH_UP -> COMPLEMENT_LIST.get(36); - }; - case FIRST_OUTER_LEFT -> - switch (direction) { - case WEST_DOWN, NORTH_DOWN -> COMPLEMENT_LIST.get(14); - case SOUTH_UP -> COMPLEMENT_LIST.get(17); - case EAST_UP -> COMPLEMENT_LIST.get(19); - case EAST_SOUTH -> COMPLEMENT_LIST.get(20); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(22); - case UP_NORTH, WEST_NORTH -> COMPLEMENT_LIST.get(25); - case SOUTH_WEST -> COMPLEMENT_LIST.get(28); - case UP_WEST -> COMPLEMENT_LIST.get(31); - case DOWN_EAST -> COMPLEMENT_LIST.get(34); - case NORTH_EAST -> COMPLEMENT_LIST.get(35); - }; - case FIRST_OUTER_RIGHT -> - switch (direction) { - case NORTH_DOWN -> COMPLEMENT_LIST.get(15); - case SOUTH_UP, EAST_UP -> COMPLEMENT_LIST.get(16); - case WEST_DOWN -> COMPLEMENT_LIST.get(13); - case DOWN_SOUTH, EAST_SOUTH -> COMPLEMENT_LIST.get(23); - case UP_NORTH -> COMPLEMENT_LIST.get(24); - case WEST_NORTH -> COMPLEMENT_LIST.get(26); - case UP_WEST -> COMPLEMENT_LIST.get(28); - case SOUTH_WEST -> COMPLEMENT_LIST.get(29); - case DOWN_EAST -> COMPLEMENT_LIST.get(33); - case NORTH_EAST -> COMPLEMENT_LIST.get(34); - }; - case SECOND_OUTER_LEFT -> - switch (direction) { - case DOWN_EAST -> COMPLEMENT_LIST.get(15); - case DOWN_SOUTH -> COMPLEMENT_LIST.get(13); - case UP_WEST, UP_NORTH -> COMPLEMENT_LIST.get(18); - case SOUTH_UP, SOUTH_WEST -> COMPLEMENT_LIST.get(21); - case NORTH_EAST -> COMPLEMENT_LIST.get(24); - case NORTH_DOWN -> COMPLEMENT_LIST.get(26); - case WEST_DOWN -> COMPLEMENT_LIST.get(30); - case WEST_NORTH -> COMPLEMENT_LIST.get(31); - case EAST_SOUTH -> COMPLEMENT_LIST.get(32); - case EAST_UP -> COMPLEMENT_LIST.get(35); - }; - case SECOND_OUTER_RIGHT -> - switch (direction) { - case DOWN_SOUTH, DOWN_EAST -> COMPLEMENT_LIST.get(12); - case UP_WEST -> COMPLEMENT_LIST.get(17); - case UP_NORTH -> COMPLEMENT_LIST.get(19); - case SOUTH_UP -> COMPLEMENT_LIST.get(20); - case SOUTH_WEST -> COMPLEMENT_LIST.get(22); - case NORTH_EAST, NORTH_DOWN -> COMPLEMENT_LIST.get(27); - case WEST_DOWN -> COMPLEMENT_LIST.get(29); - case WEST_NORTH -> COMPLEMENT_LIST.get(30); - case EAST_UP -> COMPLEMENT_LIST.get(32); - case EAST_SOUTH -> COMPLEMENT_LIST.get(33); - }; - }; + return i == 2 ? STAIRS_CUBE_VOXELS[edge.getID() * 9 + shape.getID()] : getStairShape(edge, shape); } @Override @@ -213,8 +97,4 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock implements Bloc .criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this)) .offerTo(exporter); } - - static { - VOXEL_LIST.forEach(shape -> COMPLEMENT_LIST.add(VoxelShapes.combineAndSimplify(VoxelShapes.fullCube(), shape, BooleanBiFunction.ONLY_FIRST))); - } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java index 3df062c..fa7f969 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java @@ -1,15 +1,16 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.VoxelHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.blocks.Edge; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; +import net.minecraft.data.client.BlockStateSupplier; import net.minecraft.data.client.MultipartBlockStateSupplier; import net.minecraft.data.server.recipe.RecipeExporter; import net.minecraft.data.server.recipe.RecipeProvider; @@ -19,22 +20,18 @@ import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.state.StateManager; import net.minecraft.util.Identifier; 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; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - +import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.Edge.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider { - public static final List STEP_VOXELS = new ArrayList<>(12); + public static final VoxelShape[] STEP_VOXELS; public ReFramedStepBlock(Settings settings) { super(settings); @@ -68,53 +65,40 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo } public static VoxelShape getStepShape(Edge edge) { - return switch (edge) { - case DOWN_SOUTH -> STEP_VOXELS.get(0); - case NORTH_DOWN -> STEP_VOXELS.get(1); - case UP_NORTH -> STEP_VOXELS.get(2); - case SOUTH_UP -> STEP_VOXELS.get(3); - case DOWN_EAST -> STEP_VOXELS.get(4); - case WEST_DOWN -> STEP_VOXELS.get(5); - case UP_WEST -> STEP_VOXELS.get(6); - case EAST_UP -> STEP_VOXELS.get(7); - case NORTH_EAST -> STEP_VOXELS.get(8); - case EAST_SOUTH -> STEP_VOXELS.get(9); - case SOUTH_WEST -> STEP_VOXELS.get(10); - case WEST_NORTH -> STEP_VOXELS.get(11); - }; + return STEP_VOXELS[edge.getID()]; } @Override - public MultipartBlockStateSupplier getMultipart() { - Identifier step_id = ReFramed.id("step_special"); + public BlockStateSupplier getMultipart() { + Identifier model_id = ReFramed.id("step_special"); return MultipartBlockStateSupplier.create(this) /* X AXIS */ .with(GBlockstate.when(EDGE, DOWN_EAST), - GBlockstate.variant(step_id, true, R0, R0)) + GBlockstate.variant(model_id, true, R0, R0)) .with(GBlockstate.when(EDGE, EAST_UP), - GBlockstate.variant(step_id, true, R180, R0)) + GBlockstate.variant(model_id, true, R180, R0)) .with(GBlockstate.when(EDGE, UP_WEST), - GBlockstate.variant(step_id, true, R180, R180)) + GBlockstate.variant(model_id, true, R180, R180)) .with(GBlockstate.when(EDGE, WEST_DOWN), - GBlockstate.variant(step_id, true, R0, R180)) + GBlockstate.variant(model_id, true, R0, R180)) /* Y AXIS */ .with(GBlockstate.when(EDGE, EAST_SOUTH), - GBlockstate.variant(step_id, true, R90, R0)) + GBlockstate.variant(model_id, true, R90, R0)) .with(GBlockstate.when(EDGE, SOUTH_WEST), - GBlockstate.variant(step_id, true, R90, R90)) + GBlockstate.variant(model_id, true, R90, R90)) .with(GBlockstate.when(EDGE, WEST_NORTH), - GBlockstate.variant(step_id, true, R90, R180)) + GBlockstate.variant(model_id, true, R90, R180)) .with(GBlockstate.when(EDGE, NORTH_EAST), - GBlockstate.variant(step_id, true, R90, R270)) + GBlockstate.variant(model_id, true, R90, R270)) /* Z AXIS */ .with(GBlockstate.when(EDGE, DOWN_SOUTH), - GBlockstate.variant(step_id, true, R0, R90)) + GBlockstate.variant(model_id, true, R0, R90)) .with(GBlockstate.when(EDGE, NORTH_DOWN), - GBlockstate.variant(step_id, true, R0, R270)) + GBlockstate.variant(model_id, true, R0, R270)) .with(GBlockstate.when(EDGE, UP_NORTH), - GBlockstate.variant(step_id, true, R180, R270)) + GBlockstate.variant(model_id, true, R180, R270)) .with(GBlockstate.when(EDGE, SOUTH_UP), - GBlockstate.variant(step_id, true, R180, R90)); + GBlockstate.variant(model_id, true, R180, R90)); } @Override @@ -130,21 +114,22 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo } static { - final VoxelShape STEP = VoxelShapes.cuboid(0f, 0f, .5f, 1f, .5f, 1f); + final VoxelShape STEP = createCuboidShape(0, 0, 0, 16, 8, 8); - STEP_VOXELS.add(STEP); - STEP_VOXELS.add(VoxelHelper.mirror(STEP, Direction.Axis.Z)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.X), Direction.Axis.Z)); - STEP_VOXELS.add(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.X)); + STEP_VOXELS = VoxelListBuilder.create(STEP, 12) + .add(VoxelHelper::rotateCX) + .add(VoxelHelper::rotateCX) + .add(VoxelHelper::rotateCX) - STEP_VOXELS.add(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y), Direction.Axis.X)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y), Direction.Axis.Z), Direction.Axis.X)); - STEP_VOXELS.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STEP, Direction.Axis.Y), Direction.Axis.Z)); + .add(STEP, VoxelHelper::rotateCY) + .add(VoxelHelper::rotateZ) + .add(VoxelHelper::rotateZ) + .add(VoxelHelper::rotateZ) - STEP_VOXELS.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z), Direction.Axis.Y)); - STEP_VOXELS.add(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z)); - STEP_VOXELS.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z), Direction.Axis.Y)); - STEP_VOXELS.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STEP, Direction.Axis.Z), Direction.Axis.Y), Direction.Axis.Z)); + .add(STEP, VoxelHelper::rotateCZ) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::rotateY) + .build(); } } diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java index 3b65d2f..c86688e 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepsSlabBlock.java @@ -4,6 +4,7 @@ import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Edge; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -25,7 +26,7 @@ import net.minecraft.world.BlockView; import org.jetbrains.annotations.Nullable; import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape; -import static fr.adrien1106.reframed.block.ReFramedStepBlock.STEP_VOXELS; +import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape; import static net.minecraft.data.client.VariantSettings.Rotation.*; import static net.minecraft.state.property.Properties.AXIS; import static net.minecraft.state.property.Properties.FACING; @@ -75,14 +76,14 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock imp @Override public VoxelShape getShape(BlockState state, int i) { Axis axis = state.get(AXIS); - return STEP_VOXELS.get(switch (state.get(FACING)) { - case DOWN -> axis == Axis.Z ? (i == 1 ? 0 : 1): (i == 1 ? 4 : 5 ); - case UP -> axis == Axis.Z ? (i == 1 ? 3 : 2): (i == 1 ? 7 : 6 ); - case NORTH -> axis == Axis.Y ? (i == 1 ? 1 : 2): (i == 1 ? 11 : 8 ); - case SOUTH -> axis == Axis.Y ? (i == 1 ? 0 : 3): (i == 1 ? 9 : 10); - case EAST -> axis == Axis.Y ? (i == 1 ? 4 : 7): (i == 1 ? 8 : 9 ); - case WEST -> axis == Axis.Y ? (i == 1 ? 5 : 6): (i == 1 ? 10 : 11); - }); + return getStepShape(Edge.getByDirections( + state.get(FACING), + switch (axis) { + case X -> i == 1 ? Direction.WEST : Direction.EAST; + case Y -> i == 1 ? Direction.DOWN : Direction.UP; + case Z -> i == 1 ? Direction.SOUTH : Direction.NORTH; + } + )); } @Override @@ -92,24 +93,24 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock imp @Override public MultipartBlockStateSupplier getMultipart() { - Identifier step_id = ReFramed.id("double_step_special"); - Identifier step_side_id = ReFramed.id("double_step_side_special"); + Identifier step_id = ReFramed.id("steps_slab_special"); + Identifier step_side_id = ReFramed.id("steps_slab_side_special"); return MultipartBlockStateSupplier.create(this) .with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Axis.X), - GBlockstate.variant(step_id, true, R0, R0)) + GBlockstate.variant(step_id, true, R0, R180)) .with(GBlockstate.when(FACING, Direction.DOWN, AXIS, Axis.Z), GBlockstate.variant(step_id, true, R0, R90)) .with(GBlockstate.when(FACING, Direction.UP, AXIS, Axis.X), - GBlockstate.variant(step_id, true, R180, R0)) + GBlockstate.variant(step_id, true, R180, R180)) .with(GBlockstate.when(FACING, Direction.UP, AXIS, Axis.Z), GBlockstate.variant(step_id, true, R180, R90)) .with(GBlockstate.when(FACING, Direction.EAST, AXIS, Axis.Z), - GBlockstate.variant(step_side_id, true, R0, R0)) + GBlockstate.variant(step_side_id, true, R180, R0)) .with(GBlockstate.when(FACING, Direction.EAST, AXIS, Axis.Y), GBlockstate.variant(step_side_id, true, R90, R0)) .with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Axis.X), - GBlockstate.variant(step_side_id, true, R0, R90)) + GBlockstate.variant(step_side_id, true, R180, R90)) .with(GBlockstate.when(FACING, Direction.SOUTH, AXIS, Axis.Y), GBlockstate.variant(step_side_id, true, R90, R90)) .with(GBlockstate.when(FACING, Direction.WEST, AXIS, Axis.Z), diff --git a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java index 329cde9..59e08fb 100644 --- a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java +++ b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java @@ -26,35 +26,68 @@ public class ReFramedClient implements ClientModInitializer { //all frames mustn't be on the SOLID layer because they are not opaque! BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0])); - HELPER.addReFramedModel("cube_special" , HELPER.auto(new Identifier("block/cube"))); - HELPER.addReFramedModel("small_cube_special" , HELPER.auto(ReFramed.id("block/small_cube"))); - HELPER.addReFramedModel("double_small_cube_special" , HELPER.autoDouble(ReFramed.id("block/small_cube"), ReFramed.id("block/small_cube_complement"))); - HELPER.addReFramedModel("slab_special" , HELPER.auto(new Identifier("block/slab"))); - HELPER.addReFramedModel("double_slab_special" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"))); - HELPER.addReFramedModel("stairs_special" , HELPER.auto(ReFramed.id("block/stairs"))); - HELPER.addReFramedModel("outers_stairs_special" , HELPER.auto(ReFramed.id("block/double_outer_stairs"))); - HELPER.addReFramedModel("inner_stairs_special" , HELPER.auto(ReFramed.id("block/inner_stairs"))); - HELPER.addReFramedModel("outer_stairs_special" , HELPER.auto(ReFramed.id("block/outer_stairs"))); - HELPER.addReFramedModel("outer_side_stairs_special" , HELPER.auto(ReFramed.id("block/outer_side_stairs"))); - HELPER.addReFramedModel("double_stairs_special" , HELPER.autoDouble(ReFramed.id("block/stairs"), ReFramed.id("block/stairs_complement"))); - HELPER.addReFramedModel("double_outers_stairs_special" , HELPER.autoDouble(ReFramed.id("block/double_outer_stairs"), ReFramed.id("block/double_outer_stairs_complement"))); - HELPER.addReFramedModel("double_inner_stairs_special" , HELPER.autoDouble(ReFramed.id("block/inner_stairs"), ReFramed.id("block/inner_stairs_complement"))); - HELPER.addReFramedModel("double_outer_stairs_special" , HELPER.autoDouble(ReFramed.id("block/outer_stairs"), ReFramed.id("block/outer_stairs_complement"))); - HELPER.addReFramedModel("double_outer_side_stairs_special", HELPER.autoDouble(ReFramed.id("block/outer_side_stairs"), ReFramed.id("block/outer_side_stairs_complement"))); - HELPER.addReFramedModel("step_special" , HELPER.auto(ReFramed.id("block/step"))); - HELPER.addReFramedModel("double_step_special" , HELPER.autoDouble(ReFramed.id("block/step"), ReFramed.id("block/step_complement_slab"))); - HELPER.addReFramedModel("double_step_side_special" , HELPER.autoDouble(ReFramed.id("block/step_side"), ReFramed.id("block/step_side_complement_slab"))); + // CUBE + HELPER.addReFramedModel("cube_special" , HELPER.auto(new Identifier("block/cube"))); + // SMALL_CUBE + HELPER.addReFramedModel("small_cube_special" , HELPER.auto(ReFramed.id("block/small_cube/base"))); + // SMALL_CUBES_STEP + HELPER.addReFramedModel("small_cubes_step_special" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base"))); + HELPER.addReFramedModel("small_cubes_step_reverse_special" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base"))); + // SLAB + HELPER.addReFramedModel("slab_special" , HELPER.auto(new Identifier("block/slab"))); + // SLAB_CUBE + HELPER.addReFramedModel("double_slab_special" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"))); + // STAIR + HELPER.addReFramedModel("stair_special" , HELPER.auto(ReFramed.id("block/stair/straight"))); + HELPER.addReFramedModel("outers_stair_special" , HELPER.auto(ReFramed.id("block/stair/double_outer"))); + HELPER.addReFramedModel("inner_stair_special" , HELPER.auto(ReFramed.id("block/stair/inner"))); + HELPER.addReFramedModel("outer_stair_special" , HELPER.auto(ReFramed.id("block/stair/outer"))); + HELPER.addReFramedModel("outer_side_stair_special" , HELPER.auto(ReFramed.id("block/stair/outer_side"))); + // STAIRS_CUBE + HELPER.addReFramedModel("stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight"))); + HELPER.addReFramedModel("outers_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer"))); + HELPER.addReFramedModel("inner_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner"))); + HELPER.addReFramedModel("outer_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer"))); + HELPER.addReFramedModel("outer_side_stairs_cube_special" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side"))); + // HALF_STAIR + HELPER.addReFramedModel("half_stair_down_special" , HELPER.auto(ReFramed.id("block/half_stair/down"))); + HELPER.addReFramedModel("half_stair_side_special" , HELPER.auto(ReFramed.id("block/half_stair/side"))); + // HALF_STAIRS_SLAB + HELPER.addReFramedModel("half_stairs_slab_down_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down"))); + HELPER.addReFramedModel("half_stairs_slab_side_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side"))); + // HALF_STAIRS_STAIR + HELPER.addReFramedModel("half_stairs_stair_down_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down"))); + HELPER.addReFramedModel("half_stairs_stair_side_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side"))); + HELPER.addReFramedModel("half_stairs_stair_reverse_special" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side"))); + // STEP + HELPER.addReFramedModel("step_special" , HELPER.auto(ReFramed.id("block/step/down"))); + // STEPS_SLAB + HELPER.addReFramedModel("steps_slab_special" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down"))); + HELPER.addReFramedModel("steps_slab_side_special" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side"))); + // LAYER + HELPER.addReFramedModel("layer_1_special" , HELPER.auto(new Identifier("block/snow_height2"))); + HELPER.addReFramedModel("layer_2_special" , HELPER.auto(new Identifier("block/snow_height4"))); + HELPER.addReFramedModel("layer_3_special" , HELPER.auto(new Identifier("block/snow_height6"))); + HELPER.addReFramedModel("layer_4_special" , HELPER.auto(new Identifier("block/snow_height8"))); + HELPER.addReFramedModel("layer_5_special" , HELPER.auto(new Identifier("block/snow_height10"))); + HELPER.addReFramedModel("layer_6_special" , HELPER.auto(new Identifier("block/snow_height12"))); + HELPER.addReFramedModel("layer_7_special" , HELPER.auto(new Identifier("block/snow_height14"))); + HELPER.addReFramedModel("layer_8_special" , HELPER.auto(new Identifier("block/cube"))); //item model assignments (in lieu of models/item/___.json) HELPER.assignItemModel("cube_special" , ReFramed.CUBE); HELPER.assignItemModel("small_cube_special" , ReFramed.SMALL_CUBE); - HELPER.assignItemModel("double_small_cube_special" , ReFramed.SMALL_CUBES_STEP); + HELPER.assignItemModel("small_cubes_step_special" , ReFramed.SMALL_CUBES_STEP); HELPER.assignItemModel("slab_special" , ReFramed.SLAB); HELPER.assignItemModel("double_slab_special" , ReFramed.SLABS_CUBE); - HELPER.assignItemModel("stairs_special" , ReFramed.STAIR); - HELPER.assignItemModel("double_stairs_special" , ReFramed.STAIRS_CUBE); + HELPER.assignItemModel("stair_special" , ReFramed.STAIR); + HELPER.assignItemModel("stairs_cube_special" , ReFramed.STAIRS_CUBE); + HELPER.assignItemModel("half_stair_down_special" , ReFramed.HALF_STAIR); + HELPER.assignItemModel("half_stairs_slab_down_special" , ReFramed.HALF_STAIRS_SLAB); + HELPER.assignItemModel("half_stairs_stair_down_special", ReFramed.HALF_STAIRS_STAIR); HELPER.assignItemModel("step_special" , ReFramed.STEP); - HELPER.assignItemModel("double_step_special" , ReFramed.STEPS_SLAB); + HELPER.assignItemModel("steps_slab_special" , ReFramed.STEPS_SLAB); + HELPER.assignItemModel("layer_1_special" , ReFramed.LAYER); } private void privateInit() { diff --git a/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java b/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java index 885e552..ba4d0d8 100644 --- a/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/VoxelHelper.java @@ -5,68 +5,201 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +import static net.minecraft.util.shape.VoxelShapes.*; + public class VoxelHelper { + + /* ---------------------------------------- Methods for VoxelListBuilder ---------------------------------------- */ + public static VoxelShape rotateX(VoxelShape shape) { + return rotateClockwise(shape, Direction.Axis.X); + } + + public static VoxelShape rotateY(VoxelShape shape) { + return rotateClockwise(shape, Direction.Axis.Y); + } + public static VoxelShape rotateZ(VoxelShape shape) { + return rotateClockwise(shape, Direction.Axis.Z); + } + + public static VoxelShape rotateCX(VoxelShape shape) { + return rotateCounterClockwise(shape, Direction.Axis.X); + } + + public static VoxelShape rotateCY(VoxelShape shape) { + return rotateCounterClockwise(shape, Direction.Axis.Y); + } + public static VoxelShape rotateCZ(VoxelShape shape) { + return rotateCounterClockwise(shape, Direction.Axis.Z); + } + + public static VoxelShape mirrorX(VoxelShape shape) { + return mirror(shape, Direction.Axis.X); + } + + public static VoxelShape mirrorY(VoxelShape shape) { + return mirror(shape, Direction.Axis.Y); + } + public static VoxelShape mirrorZ(VoxelShape shape) { + return mirror(shape, Direction.Axis.Z); + } + public static VoxelShape rotateClockwise(VoxelShape shape, Direction.Axis axis) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxZ, minY, minX, 1 - minZ, maxY, maxX), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, 1 - maxZ, minY, maxX, 1 - minZ, maxY), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxY, minX, minZ, 1 - minY, maxX, maxZ), BooleanBiFunction.OR)); - break; - } - return buffer[1]; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(1 - maxZ, minY, minX, 1 - minZ, maxY, maxX); + case X -> cuboid(minX, 1 - maxZ, minY, maxX, 1 - minZ, maxY); + case Z -> cuboid(1 - maxY, minX, minZ, 1 - minY, maxX, maxZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); } public static VoxelShape rotateCounterClockwise(VoxelShape shape, Direction.Axis axis) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minZ, minY, 1 - maxX, maxZ, maxY, 1 - minX), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minZ, 1 - maxY, maxX, maxZ, 1 - minY), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minY, 1 - maxX, minZ, maxY, 1 - minX, maxZ), BooleanBiFunction.OR)); - break; - } - return buffer[1]; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(minZ, minY, 1 - maxX, maxZ, maxY, 1 - minX); + case X -> cuboid(minX, minZ, 1 - maxY, maxX, maxZ, 1 - minY); + case Z -> cuboid(minY, 1 - maxX, minZ, maxY, 1 - minX, maxZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); } public static VoxelShape mirror(VoxelShape shape, Direction.Axis axis) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, 1 - maxY, minZ, maxX, 1 - minY, maxZ), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxX, minY, minZ, 1 - minX, maxY, maxZ), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minY, 1 - maxZ, maxX, maxY, 1 - minZ), BooleanBiFunction.OR)); - break; - } - return buffer[1]; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(minX, 1 - maxY, minZ, maxX, 1 - minY, maxZ); + case X -> cuboid(1 - maxX, minY, minZ, 1 - minX, maxY, maxZ); + case Z -> cuboid(minX, minY, 1 - maxZ, maxX, maxY, 1 - minZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); } public static VoxelShape offset(VoxelShape shape, Direction.Axis axis, float offset) { - VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() }; - switch (axis) { - case Y: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, offset + minY, minZ, maxX, offset + maxY, maxZ), BooleanBiFunction.OR)); - break; - case X: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( offset + minX, minY, minZ, offset + maxX, maxY, maxZ), BooleanBiFunction.OR)); - break; - case Z: - buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minY, offset + minZ, maxX, maxY, offset + maxZ), BooleanBiFunction.OR)); - break; + AtomicReference new_shape = new AtomicReference<>(empty()); + shape.forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> + new_shape.getAndUpdate(s -> + combineAndSimplify( + s, + switch (axis) { + case Y -> cuboid(minX, offset + minY, minZ, maxX, offset + maxY, maxZ); + case X -> cuboid(offset + minX, minY, minZ, offset + maxX, maxY, maxZ); + case Z -> cuboid(minX, minY, offset + minZ, maxX, maxY, offset + maxZ); + }, + BooleanBiFunction.OR + ) + ) + ); + return new_shape.get(); + } + + public static class VoxelListBuilder { + private final List voxels; + + /** + * A simple class that helps to get cleaner shape list generation (Hopefully) + * @param base_shape - the shape to start with + * @param size - the amount of shapes expected + */ + private VoxelListBuilder(VoxelShape base_shape, int size) { + voxels = new ArrayList<>(size); + voxels.add(base_shape); + } + + public static VoxelListBuilder create(VoxelShape base_shape, int size) { + return new VoxelListBuilder(base_shape, size); + } + + /** + * Add shape by applying modification to previous shape + * @param modifications - the modifications to apply @See {@link VoxelHelper} methods + * @return this instance + */ + @SafeVarargs + public final VoxelListBuilder add(Function... modifications) { + return add(voxels.size() - 1, modifications); + } + + /** + * Add shape by applying modifications to given shape + * @param ref - the index of the reference shape + * @param modifications - the modifications to apply @See {@link VoxelHelper} methods + * @return this instance + */ + @SafeVarargs + public final VoxelListBuilder add(int ref, Function... modifications) { + return add(voxels.get(ref), modifications); + } + + /** + * Add shape by applying modifications to given shape + * @param ref - the shape you want to add and apply modifications if present + * @param modifications - the modifications to apply @See {@link VoxelHelper} methods + * @return this instance + */ + @SafeVarargs + public final VoxelListBuilder add(VoxelShape ref, Function... modifications) { + for(Function modif: modifications) { + ref = modif.apply(ref); + } + voxels.add(ref); + return this; + } + + /** + * @return the final array of voxel shapes + */ + public VoxelShape[] build() { + return voxels.toArray(new VoxelShape[0]); + } + + /** + * build a new set of voxels based on th negation of the references and a full cube + * @param ref_voxels - the reference to subtract from the wanted shape + * @return the array of complementary voxels + */ + public static VoxelShape[] buildFrom(VoxelShape[] ref_voxels) { + return buildFrom(VoxelShapes.fullCube(), ref_voxels); + } + + /** + * build a new set of voxels based on th negation of the references and a wanted_shape + * @param ref_voxels - the reference to subtract from the wanted shape + * @return the array of complementary voxels + */ + public static VoxelShape[] buildFrom(VoxelShape wanted_shape, VoxelShape[] ref_voxels) { + VoxelShape[] shapes = new VoxelShape[ref_voxels.length]; + for (int i = 0; i < shapes.length; i++) { + shapes[i] = VoxelShapes.combineAndSimplify(wanted_shape, ref_voxels[i], BooleanBiFunction.ONLY_FIRST); + } + return shapes; } - return buffer[1]; } } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java index c8a9296..a53ea94 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java @@ -2,10 +2,12 @@ package fr.adrien1106.reframed.util.blocks; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.EnumProperty; +import net.minecraft.state.property.IntProperty; public class BlockProperties { public static final BooleanProperty LIGHT = BooleanProperty.of("emits_light"); public static final EnumProperty EDGE = EnumProperty.of("edge", Edge.class); public static final EnumProperty CORNER = EnumProperty.of("corner", Corner.class); + public static final IntProperty CORNER_FACE = IntProperty.of("face", 0, 2); public static final EnumProperty STAIR_SHAPE = EnumProperty.of("shape", StairShape.class); } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java index bfa0801..1b16ea4 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java @@ -64,4 +64,34 @@ public enum Corner implements StringIdentifiable { .filter(value -> value.name().equals(name)) .findFirst().orElse(Corner.NORTH_EAST_DOWN); } + + public int getDirectionIndex(Direction side) { + return side == second_direction ? 1 : side == third_direction ? 2 : 0; + } + + public Direction getDirection(int index) { + return index == 1 ? second_direction : index == 2 ? third_direction : first_direction; + } + + public Corner getOpposite() { + return getByDirections(first_direction.getOpposite(), second_direction.getOpposite(), third_direction.getOpposite()); + } + + /** + * @param index - an index of the direction to keep and use as reference + * @return the opposite corner on same direction plane + */ + public Corner getOpposite(int index) { + return getOpposite(getDirection(index)); + } + + /** + * @param direction - a direction to keep and use as reference + * @return the opposite corner on same direction plane + */ + public Corner getOpposite(Direction direction) { + Direction other_1 = first_direction == direction ? second_direction : first_direction; + Direction other_2 = second_direction == direction || first_direction == direction ? third_direction : second_direction; + return getByDirections(direction, other_1.getOpposite(), other_2.getOpposite()); + } } diff --git a/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java index f7df0af..3b23296 100644 --- a/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Edge.java @@ -6,32 +6,30 @@ import net.minecraft.util.math.Direction; import java.util.Arrays; public enum Edge implements StringIdentifiable { - NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.EAST, 0), - DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.EAST, 1), - SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.EAST, 2), - UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.EAST, 3), - WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.SOUTH, 4), - DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.SOUTH, 5), - EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.SOUTH, 6), - UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.SOUTH, 7), - WEST_NORTH("west_north", Direction.WEST, Direction.NORTH, Direction.DOWN, 8), - NORTH_EAST("north_east", Direction.NORTH, Direction.EAST, Direction.DOWN, 9), - EAST_SOUTH("east_south", Direction.EAST, Direction.SOUTH, Direction.DOWN, 10), - SOUTH_WEST("south_west", Direction.SOUTH, Direction.WEST, Direction.DOWN, 11); + NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.Axis.X, 0), + DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.Axis.X, 1), + SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.Axis.X, 2), + UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.Axis.X, 3), + WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.Axis.Z, 4), + DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.Axis.Z, 5), + EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.Axis.Z, 6), + UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.Axis.Z, 7), + WEST_NORTH("west_north", Direction.WEST, Direction.NORTH, Direction.Axis.Y, 8), + NORTH_EAST("north_east", Direction.NORTH, Direction.EAST, Direction.Axis.Y, 9), + EAST_SOUTH("east_south", Direction.EAST, Direction.SOUTH, Direction.Axis.Y, 10), + SOUTH_WEST("south_west", Direction.SOUTH, Direction.WEST, Direction.Axis.Y, 11); private final String name; private final Direction first_direction; private final Direction second_direction; - private final Direction right_direction; - private final Direction left_direction; + private final Direction.Axis axis; private final int ID; - Edge(String name, Direction first_direction, Direction second_direction, Direction right_direction, int id) { + Edge(String name, Direction first_direction, Direction second_direction, Direction.Axis axis, int id) { this.name = name; this.first_direction = first_direction; this.second_direction = second_direction; - this.right_direction = right_direction; - this.left_direction = right_direction.getOpposite(); + this.axis = axis; this.ID = id; } @@ -51,10 +49,18 @@ public enum Edge implements StringIdentifiable { return second_direction; } public Direction getRightDirection() { - return right_direction; + return switch (axis) { + case X -> Direction.WEST; + case Y -> Direction.DOWN; + case Z -> Direction.SOUTH; + }; } public Direction getLeftDirection() { - return left_direction; + return switch (axis) { + case X -> Direction.EAST; + case Y -> Direction.UP; + case Z -> Direction.NORTH; + }; } public boolean hasDirection(Direction direction) { diff --git a/src/main/resources/assets/reframed/models/block/half_stair/down.json b/src/main/resources/assets/reframed/models/block/half_stair/down.json new file mode 100644 index 0000000..2df9bc2 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/down.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 0, 8], + "to": [16, 8, 16], + "faces": { + "east": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [8, 0, 0], + "to": [16, 8, 8], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "east"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [0, 0, 0], + "to": [8, 8, 8], + "faces": { + "north": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "north"}, + "south": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#top"}, + "down": {"uv": [0, 8, 8, 16], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/side.json b/src/main/resources/assets/reframed/models/block/half_stair/side.json new file mode 100644 index 0000000..039ea0d --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/side.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 8, 0], + "to": [16, 16, 8], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top", "cullface": "up"} + } + }, + { + "from": [8, 0, 0], + "to": [16, 8, 8], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "east"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [8, 0, 8], + "to": [16, 8, 16], + "faces": { + "east": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/slab/down.json b/src/main/resources/assets/reframed/models/block/half_stair/slab/down.json new file mode 100644 index 0000000..b56aa5e --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/slab/down.json @@ -0,0 +1,35 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [0, 0, 8], + "to": [8, 8, 16], + "faces": { + "north": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "east": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "south": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 8, 8, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 8, 8], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/slab/side.json b/src/main/resources/assets/reframed/models/block/half_stair/slab/side.json new file mode 100644 index 0000000..ca813e3 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/slab/side.json @@ -0,0 +1,35 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 8, 8], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "east": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top", "cullface": "up"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/stair/down.json b/src/main/resources/assets/reframed/models/block/half_stair/stair/down.json new file mode 100644 index 0000000..adba846 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/stair/down.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [8, 8, 8], + "to": [16, 16, 16], + "faces": { + "east": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "east"}, + "south": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "up": {"uv": [8, 8, 16, 16], "texture": "#top", "cullface": "up"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#bottom"} + } + }, + { + "from": [8, 8, 0], + "to": [16, 16, 8], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "east"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#top", "cullface": "up"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#bottom"} + } + }, + { + "from": [0, 8, 0], + "to": [8, 16, 8], + "faces": { + "north": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "north"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#top", "cullface": "up"}, + "down": {"uv": [0, 8, 8, 16], "texture": "#bottom"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_stair/stair/side.json b/src/main/resources/assets/reframed/models/block/half_stair/stair/side.json new file mode 100644 index 0000000..f917223 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_stair/stair/side.json @@ -0,0 +1,55 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [0, 8, 0], + "to": [8, 16, 8], + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 0, 16, 8], "texture": "#side"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#side"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#top", "cullface": "up"} + } + }, + { + "from": [0, 0, 0], + "to": [8, 8, 8], + "faces": { + "north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [8, 8, 16, 16], "texture": "#side"}, + "west": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "west"}, + "down": {"uv": [0, 8, 8, 16], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [0, 0, 8], + "to": [8, 8, 16], + "faces": { + "east": {"uv": [0, 8, 8, 16], "texture": "#side"}, + "south": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 8, 8, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 8, 8], "texture": "#bottom", "cullface": "down"} + } + } + ], + "display": { + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "gui": { + "rotation": [30, 135, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, -90, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/small_cube.json b/src/main/resources/assets/reframed/models/block/small_cube/base.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/small_cube.json rename to src/main/resources/assets/reframed/models/block/small_cube/base.json diff --git a/src/main/resources/assets/reframed/models/block/small_cube_complement.json b/src/main/resources/assets/reframed/models/block/small_cube/step/base.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/small_cube_complement.json rename to src/main/resources/assets/reframed/models/block/small_cube/step/base.json diff --git a/src/main/resources/assets/reframed/models/block/double_outer_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/double_outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/double_outer_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/double_outer.json diff --git a/src/main/resources/assets/reframed/models/block/inner_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/inner.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/inner_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/inner.json diff --git a/src/main/resources/assets/reframed/models/block/outer_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/outer.json diff --git a/src/main/resources/assets/reframed/models/block/outer_side_stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/outer_side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_side_stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/outer_side.json diff --git a/src/main/resources/assets/reframed/models/block/stairs_complement.json b/src/main/resources/assets/reframed/models/block/stair/cube/straight.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/stairs_complement.json rename to src/main/resources/assets/reframed/models/block/stair/cube/straight.json diff --git a/src/main/resources/assets/reframed/models/block/double_outer_stairs.json b/src/main/resources/assets/reframed/models/block/stair/double_outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/double_outer_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/double_outer.json diff --git a/src/main/resources/assets/reframed/models/block/inner_stairs.json b/src/main/resources/assets/reframed/models/block/stair/inner.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/inner_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/inner.json diff --git a/src/main/resources/assets/reframed/models/block/outer_stairs.json b/src/main/resources/assets/reframed/models/block/stair/outer.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/outer.json diff --git a/src/main/resources/assets/reframed/models/block/outer_side_stairs.json b/src/main/resources/assets/reframed/models/block/stair/outer_side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/outer_side_stairs.json rename to src/main/resources/assets/reframed/models/block/stair/outer_side.json diff --git a/src/main/resources/assets/reframed/models/block/stairs.json b/src/main/resources/assets/reframed/models/block/stair/straight.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/stairs.json rename to src/main/resources/assets/reframed/models/block/stair/straight.json diff --git a/src/main/resources/assets/reframed/models/block/step.json b/src/main/resources/assets/reframed/models/block/step/down.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step.json rename to src/main/resources/assets/reframed/models/block/step/down.json diff --git a/src/main/resources/assets/reframed/models/block/step_side.json b/src/main/resources/assets/reframed/models/block/step/side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step_side.json rename to src/main/resources/assets/reframed/models/block/step/side.json diff --git a/src/main/resources/assets/reframed/models/block/step_complement_slab.json b/src/main/resources/assets/reframed/models/block/step/slab/down.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step_complement_slab.json rename to src/main/resources/assets/reframed/models/block/step/slab/down.json diff --git a/src/main/resources/assets/reframed/models/block/step_side_complement_slab.json b/src/main/resources/assets/reframed/models/block/step/slab/side.json similarity index 100% rename from src/main/resources/assets/reframed/models/block/step_side_complement_slab.json rename to src/main/resources/assets/reframed/models/block/step/slab/side.json