From 12924579a5cd999c2a6f1a6a3cc18451af505342 Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Wed, 19 Jun 2024 14:26:43 +0200 Subject: [PATCH] feat: added half slab and half slabs slab --- .../java/fr/adrien1106/reframed/ReFramed.java | 3 + .../reframed/block/ReFramedHalfSlabBlock.java | 86 +++++++++++++++++++ .../block/ReFramedHalfSlabsSlabBlock.java | 77 +++++++++++++++++ .../reframed/client/ReFramedClient.java | 6 ++ .../reframed/generator/GBlockstate.java | 2 + .../reframed/generator/GRecipe.java | 2 + .../reframed/generator/block/HalfSlab.java | 34 ++++++++ .../generator/block/HalfSlabsSlab.java | 34 ++++++++ .../reframed/generator/block/Slab.java | 8 +- .../models/block/half_slab/complement.json | 22 +++++ .../models/block/half_slab/default.json | 22 +++++ 11 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabBlock.java create mode 100644 src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabsSlabBlock.java create mode 100644 src/main/java/fr/adrien1106/reframed/generator/block/HalfSlab.java create mode 100644 src/main/java/fr/adrien1106/reframed/generator/block/HalfSlabsSlab.java create mode 100644 src/main/resources/assets/reframed/models/block/half_slab/complement.json create mode 100644 src/main/resources/assets/reframed/models/block/half_slab/default.json diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index 60fefd8..1d42145 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -42,6 +42,7 @@ public class ReFramed implements ModInitializer { STAIR, STAIRS_CUBE, HALF_STAIR, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, HALF_STAIRS_CUBE_STAIR, HALF_STAIRS_STEP_STAIR, SLAB, SLABS_CUBE, SLABS_STAIR, SLABS_OUTER_STAIR, SLABS_INNER_STAIR, SLABS_HALF_LAYER, + HALF_SLAB, HALF_SLABS_SLAB, STEP, STEPS_SLAB, STEPS_CROSS, STEPS_HALF_LAYER, LAYER, HALF_LAYER, PILLAR, PILLARS_WALL, WALL, @@ -79,6 +80,8 @@ public class ReFramed implements ModInitializer { SLABS_OUTER_STAIR = registerBlock("slabs_outer_stair" , new ReFramedSlabsOuterStairBlock(cp(Blocks.OAK_STAIRS))); SLABS_INNER_STAIR = registerBlock("slabs_inner_stair" , new ReFramedSlabsInnerStairBlock(cp(Blocks.OAK_STAIRS))); SLABS_HALF_LAYER = registerBlock("slabs_half_layer" , new ReFramedSlabsHalfLayerBlock(cp(Blocks.OAK_SLAB))); + HALF_SLAB = registerBlock("half_slab" , new ReFramedHalfSlabBlock(cp(Blocks.OAK_SLAB))); + HALF_SLABS_SLAB = registerBlock("half_slabs_slab" , new ReFramedHalfSlabsSlabBlock(cp(Blocks.OAK_SLAB))); STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); STEPS_SLAB = registerBlock("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB))); STEPS_CROSS = registerBlock("steps_cross" , new ReFramedStepsCrossBlock(cp(Blocks.OAK_SLAB))); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabBlock.java new file mode 100644 index 0000000..7ed0afa --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabBlock.java @@ -0,0 +1,86 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.util.VoxelHelper; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemPlacementContext; +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 java.util.Map; + +import static net.minecraft.state.property.Properties.*; + +public class ReFramedHalfSlabBlock extends ReFramedSlabBlock { + + public static VoxelShape[] HALF_SLAB_SHAPES; + + public ReFramedHalfSlabBlock(Settings settings) { + super(settings); + } + + @Override + public boolean canReplace(BlockState state, ItemPlacementContext context) { + if (context.getPlayer() == null + || context.getPlayer().isSneaking() + || !(context.getStack().getItem() instanceof BlockItem block_item) + ) return false; + + // allow replacing with slab, step, small cube and half stair + Block block = block_item.getBlock(); + if (block != this) return false; + + // check if the player is clicking on the inner part of the block + return ReFramed.HALF_SLABS_SLAB + .matchesShape( + context.getHitPos(), + context.getBlockPos(), + ReFramed.HALF_SLABS_SLAB.getDefaultState().with(FACING, state.get(FACING)), + 2 + ); + } + + @Nullable + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + BlockState current_state = ctx.getWorld().getBlockState(ctx.getBlockPos()); + + if (current_state.isOf(this)) + return ReFramed.HALF_SLABS_SLAB.getDefaultState() + .with(FACING, current_state.get(FACING)) + .with(WATERLOGGED, current_state.get(WATERLOGGED)); + + return super.getPlacementState(ctx).with(FACING, ctx.getSide().getOpposite()); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getHalfSlabShape(state.get(FACING)); + } + + public static VoxelShape getHalfSlabShape(Direction direction) { + return HALF_SLAB_SHAPES[direction.getId()]; + } + + @Override + public Map getThemeMap(BlockState state, BlockState new_state) { + if (new_state.isOf(ReFramed.HALF_SLABS_SLAB)) return Map.of(1, 1); + return super.getThemeMap(state, new_state); + } + + static { + HALF_SLAB_SHAPES = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 4, 16),6) + .add(createCuboidShape(0, 12, 0, 16, 16, 16)) + .add(createCuboidShape(0, 0, 0, 16, 16, 4)) + .add(createCuboidShape(0, 0, 12, 16, 16, 16)) + .add(createCuboidShape(0, 0, 0, 4, 16, 16)) + .add(createCuboidShape(12, 0, 0, 16, 16, 16)) + .build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabsSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabsSlabBlock.java new file mode 100644 index 0000000..35ba851 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedHalfSlabsSlabBlock.java @@ -0,0 +1,77 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.util.VoxelHelper; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.state.StateManager; +import net.minecraft.util.BlockMirror; +import net.minecraft.util.BlockRotation; +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.ReFramedHalfSlabBlock.getHalfSlabShape; +import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape; +import static net.minecraft.state.property.Properties.FACING; + +public class ReFramedHalfSlabsSlabBlock extends WaterloggableReFramedDoubleBlock { + + public static VoxelShape[] HALF_SLAB_COMP_SHAPES; + + public ReFramedHalfSlabsSlabBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(FACING, Direction.DOWN)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(FACING)); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + return super.getPlacementState(ctx) + .with(FACING, ctx.getSide().getOpposite()); + } + + @Override + @SuppressWarnings("deprecation") + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getSlabShape(state.get(FACING)); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState rotate(BlockState state, BlockRotation rotation) { + return state + .with(FACING, rotation.rotate(state.get(FACING))); + } + + @Override + @SuppressWarnings("deprecation") + public BlockState mirror(BlockState state, BlockMirror mirror) { + return state.with(FACING, mirror.apply(state.get(FACING))); + } + + @Override + public VoxelShape getShape(BlockState state, int i) { + Direction face = state.get(FACING); + return i == 2 + ? HALF_SLAB_COMP_SHAPES[face.getId()] + : getHalfSlabShape(face); + } + + static { + HALF_SLAB_COMP_SHAPES = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 4, 0, 16, 8, 16),6) + .add(createCuboidShape(0, 8, 0, 16, 12, 16)) + .add(createCuboidShape(0, 0, 4, 16, 16, 8)) + .add(createCuboidShape(0, 0, 8, 16, 16, 12)) + .add(createCuboidShape(4, 0, 0, 8, 16, 16)) + .add(createCuboidShape(8, 0, 0, 12, 16, 16)) + .build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java index b7d237e..0a4b99f 100644 --- a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java +++ b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java @@ -204,6 +204,10 @@ public class ReFramedClient implements ClientModInitializer { HELPER.addReFramedModel("second_half_layer_side_12" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_12")).setThemeIndex(2)); HELPER.addReFramedModel("second_half_layer_side_14" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_14")).setThemeIndex(2)); HELPER.addReFramedModel("second_half_layer_side_16" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_16")).setThemeIndex(2)); + // HALF SLAB + HELPER.addReFramedModel("half_slab" , HELPER.auto(ReFramed.id("block/half_slab/default"))); + // HALF SLABS SLAB + HELPER.addReFramedModel("half_slabs_slab" , HELPER.autoDouble(ReFramed.id("block/half_slab/default"), ReFramed.id("block/half_slab/complement"))); // item model assignments (in lieu of models/item/___.json) @@ -239,6 +243,8 @@ public class ReFramedClient implements ClientModInitializer { HELPER.assignItemModel("half_layer_2" , ReFramed.HALF_LAYER); HELPER.assignItemModel("slabs_half_inventory" , ReFramed.SLABS_HALF_LAYER); HELPER.assignItemModel("steps_half_inventory" , ReFramed.STEPS_HALF_LAYER); + HELPER.assignItemModel("half_slab" , ReFramed.HALF_SLAB); + HELPER.assignItemModel("half_slabs_slab" , ReFramed.HALF_SLABS_SLAB); } private void privateInit() { diff --git a/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java b/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java index 8e251a6..63a2790 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java @@ -33,6 +33,8 @@ public class GBlockstate extends FabricModelProvider { providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair()); providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair()); providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer()); + providers.put(ReFramedHalfSlabBlock.class, new HalfSlab()); + providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab()); providers.put(ReFramedSmallCubeBlock.class, new SmallCube()); providers.put(ReFramedSmallCubesStepBlock.class, new SmallCubesStep()); providers.put(ReFramedStairBlock.class, new Stair()); diff --git a/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java b/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java index f898727..5cb9e8c 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java @@ -35,6 +35,8 @@ public class GRecipe extends FabricRecipeProvider { providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair()); providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair()); providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer()); + providers.put(ReFramedHalfSlabBlock.class, new HalfSlab()); + providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab()); providers.put(ReFramedSmallCubeBlock.class, new SmallCube()); providers.put(ReFramedSmallCubesStepBlock.class, new SmallCubesStep()); providers.put(ReFramedStairBlock.class, new Stair()); diff --git a/src/main/java/fr/adrien1106/reframed/generator/block/HalfSlab.java b/src/main/java/fr/adrien1106/reframed/generator/block/HalfSlab.java new file mode 100644 index 0000000..cec246c --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/generator/block/HalfSlab.java @@ -0,0 +1,34 @@ +package fr.adrien1106.reframed.generator.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.RecipeSetter; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +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.ItemConvertible; +import net.minecraft.recipe.book.RecipeCategory; + +public class HalfSlab implements RecipeSetter, BlockStateProvider { + + @Override + public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 4); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, convertible, 2) + .input(ReFramed.SLAB) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible)) + .offerTo(exporter); + } + + @Override + public MultipartBlockStateSupplier getMultipart(Block block) { + return Slab.getMultipart(block, "half_slab"); + } + + +} diff --git a/src/main/java/fr/adrien1106/reframed/generator/block/HalfSlabsSlab.java b/src/main/java/fr/adrien1106/reframed/generator/block/HalfSlabsSlab.java new file mode 100644 index 0000000..5b1484a --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/generator/block/HalfSlabsSlab.java @@ -0,0 +1,34 @@ +package fr.adrien1106.reframed.generator.block; + +import fr.adrien1106.reframed.ReFramed; +import fr.adrien1106.reframed.generator.BlockStateProvider; +import fr.adrien1106.reframed.generator.RecipeSetter; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +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.ItemConvertible; +import net.minecraft.recipe.book.RecipeCategory; + +public class HalfSlabsSlab implements RecipeSetter, BlockStateProvider { + + @Override + public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, convertible, 1) + .input(ReFramed.HALF_SLAB, 2) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible)) + .offerTo(exporter); + } + + @Override + public MultipartBlockStateSupplier getMultipart(Block block) { + return Slab.getMultipart(block, "half_slabs_slab"); + } + + +} diff --git a/src/main/java/fr/adrien1106/reframed/generator/block/Slab.java b/src/main/java/fr/adrien1106/reframed/generator/block/Slab.java index 4f8bcdb..e4fffb4 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/block/Slab.java +++ b/src/main/java/fr/adrien1106/reframed/generator/block/Slab.java @@ -34,7 +34,11 @@ public class Slab implements RecipeSetter, BlockStateProvider { @Override public MultipartBlockStateSupplier getMultipart(Block block) { - Identifier model_id = ReFramed.id("slab_special"); + return getMultipart(block, "slab"); + } + + public static MultipartBlockStateSupplier getMultipart(Block block, String model_name) { + Identifier model_id = ReFramed.id(model_name + "_special"); return MultipartBlockStateSupplier.create(block) .with(GBlockstate.when(FACING, Direction.DOWN), GBlockstate.variant(model_id, true, R0, R0)) @@ -49,4 +53,6 @@ public class Slab implements RecipeSetter, BlockStateProvider { .with(GBlockstate.when(FACING, Direction.EAST), GBlockstate.variant(model_id, true, R90, R270)); } + + } diff --git a/src/main/resources/assets/reframed/models/block/half_slab/complement.json b/src/main/resources/assets/reframed/models/block/half_slab/complement.json new file mode 100644 index 0000000..b1c12b4 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_slab/complement.json @@ -0,0 +1,22 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [0, 4, 0], + "to": [16, 8, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 12, 0]}, + "faces": { + "north": {"uv": [0, 8, 16, 12], "texture": "#side", "cullface": "north"}, + "east": {"uv": [0, 8, 16, 12], "texture": "#side", "cullface": "east"}, + "south": {"uv": [0, 8, 16, 12], "texture": "#side", "cullface": "south"}, + "west": {"uv": [0, 8, 16, 12], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#bottom"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/half_slab/default.json b/src/main/resources/assets/reframed/models/block/half_slab/default.json new file mode 100644 index 0000000..fcf0358 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/half_slab/default.json @@ -0,0 +1,22 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 4, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]}, + "faces": { + "north": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "north"}, + "east": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "east"}, + "south": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "west"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"} + } + } + ] +} \ No newline at end of file