feat: added slabs layer block
This commit is contained in:
parent
e8c06a7fb3
commit
1fa55064c7
@ -41,7 +41,7 @@ public class ReFramed implements ModInitializer {
|
||||
SMALL_CUBE, SMALL_CUBES_STEP,
|
||||
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,
|
||||
SLAB, SLABS_CUBE, SLABS_STAIR, SLABS_OUTER_STAIR, SLABS_INNER_STAIR, SLABS_HALF_LAYER, SLABS_LAYER,
|
||||
HALF_SLAB, HALF_SLABS_SLAB,
|
||||
STEP, STEPS_SLAB, STEPS_CROSS, STEPS_HALF_LAYER,
|
||||
LAYER, HALF_LAYER,
|
||||
@ -80,6 +80,7 @@ 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)));
|
||||
SLABS_LAYER = registerBlock("slabs_layer" , new ReFramedSlabsLayerBlock(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)));
|
||||
|
@ -0,0 +1,57 @@
|
||||
package fr.adrien1106.reframed.block;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
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 net.minecraft.state.property.Properties.FACING;
|
||||
|
||||
public abstract class FacingDoubleReFramedBlock extends WaterloggableReFramedDoubleBlock {
|
||||
|
||||
public FacingDoubleReFramedBlock(AbstractBlock.Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder< Block, BlockState > 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 abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
|
||||
|
||||
@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 abstract VoxelShape getShape(BlockState state, int i);
|
||||
|
||||
}
|
@ -24,6 +24,7 @@ public abstract class HalfLayerDoubleReFramedBlock extends EdgeDoubleReFramedBlo
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
|
||||
List<ItemStack> drops = super.getDroppedStacks(state, builder);
|
||||
if (state.get(LAYERS) > 1)
|
||||
drops.add(new ItemStack(ReFramed.HALF_LAYER, state.get(LAYERS)-1));
|
||||
return drops;
|
||||
}
|
||||
|
@ -1,62 +1,30 @@
|
||||
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 class ReFramedHalfSlabsSlabBlock extends FacingDoubleReFramedBlock {
|
||||
|
||||
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<Block, BlockState> 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);
|
||||
|
@ -1,5 +1,6 @@
|
||||
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;
|
||||
@ -15,8 +16,8 @@ import net.minecraft.world.BlockView;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
import static net.minecraft.state.property.Properties.LAYERS;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
|
||||
import static net.minecraft.state.property.Properties.*;
|
||||
|
||||
public class ReFramedLayerBlock extends LayeredReFramedBlock {
|
||||
|
||||
@ -34,7 +35,11 @@ public class ReFramedLayerBlock extends LayeredReFramedBlock {
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return LAYER_VOXELS[state.get(FACING).getId() * 8 + state.get(LAYERS) - 1];
|
||||
return getLayerShape(state.get(FACING), state.get(LAYERS));
|
||||
}
|
||||
|
||||
public static VoxelShape getLayerShape(Direction facing, int layers) {
|
||||
return LAYER_VOXELS[facing.getId() * 8 + layers - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,6 +47,15 @@ public class ReFramedLayerBlock extends LayeredReFramedBlock {
|
||||
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
|
||||
BlockState state = super.getPlacementState(ctx);
|
||||
if (previous.isOf(this)) return state;
|
||||
|
||||
if (previous.isOf(ReFramed.SLAB))
|
||||
return ReFramed.SLABS_LAYER.getDefaultState()
|
||||
.with(FACING, previous.get(FACING))
|
||||
.with(WATERLOGGED, previous.get(WATERLOGGED));
|
||||
|
||||
if (previous.isOf(ReFramed.SLABS_LAYER))
|
||||
return previous.with(HALF_LAYERS, previous.get(HALF_LAYERS) + 1);
|
||||
|
||||
return state.with(FACING, ctx.getSide().getOpposite());
|
||||
}
|
||||
|
||||
|
@ -58,15 +58,14 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
|
||||
&& block != ReFramed.SMALL_CUBE
|
||||
&& block != ReFramed.HALF_STAIR
|
||||
&& block != ReFramed.HALF_LAYER
|
||||
&& block != ReFramed.LAYER
|
||||
) return false;
|
||||
|
||||
// check if the player is clicking on the inner part of the block
|
||||
return ReFramed.SLABS_CUBE
|
||||
.matchesShape(
|
||||
return matchesShape(
|
||||
context.getHitPos(),
|
||||
context.getBlockPos(),
|
||||
ReFramed.SLABS_CUBE.getDefaultState().with(AXIS, state.get(FACING).getAxis()),
|
||||
state.get(FACING).getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
|
||||
state.with(FACING, state.get(FACING).getOpposite())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
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.item.ItemStack;
|
||||
import net.minecraft.loot.context.LootContextParameterSet;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.adrien1106.reframed.block.ReFramedLayerBlock.getLayerShape;
|
||||
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
|
||||
public class ReFramedSlabsLayerBlock extends FacingDoubleReFramedBlock {
|
||||
|
||||
public static VoxelShape[] HALF_LAYER_SHAPES;
|
||||
|
||||
public ReFramedSlabsLayerBlock(Settings settings) {
|
||||
super(settings);
|
||||
setDefaultState(getDefaultState().with(HALF_LAYERS, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
|
||||
List<ItemStack> drops = super.getDroppedStacks(state, builder);
|
||||
if (state.get(HALF_LAYERS) > 1)
|
||||
drops.add(new ItemStack(ReFramed.LAYER, state.get(HALF_LAYERS)-1));
|
||||
return drops;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean canReplace(BlockState state, ItemPlacementContext context) {
|
||||
if (context.getPlayer() == null
|
||||
|| context.getPlayer().isSneaking()
|
||||
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|
||||
) return false;
|
||||
|
||||
return block_item.getBlock() == ReFramed.LAYER && state.get(HALF_LAYERS) < 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder.add(HALF_LAYERS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return getLayerShape(state.get(FACING), state.get(HALF_LAYERS) + 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, int i) {
|
||||
Direction face = state.get(FACING);
|
||||
return i == 2
|
||||
? HALF_LAYER_SHAPES[face.getId() * 4 + state.get(HALF_LAYERS)-1]
|
||||
: getSlabShape(face);
|
||||
}
|
||||
|
||||
static {
|
||||
VoxelHelper.VoxelListBuilder builder = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 8, 0, 16, 10, 16), 24)
|
||||
.add(createCuboidShape(0, 8, 0, 16, 12, 16))
|
||||
.add(createCuboidShape(0, 8, 0, 16, 14, 16))
|
||||
.add(createCuboidShape(0, 8, 0, 16, 16, 16));
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::mirrorY);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateX);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateCX);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateCZ);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
builder.add(i, VoxelHelper::rotateZ);
|
||||
}
|
||||
|
||||
HALF_LAYER_SHAPES = builder.build();
|
||||
}
|
||||
}
|
@ -208,6 +208,12 @@ public class ReFramedClient implements ClientModInitializer {
|
||||
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")));
|
||||
// SLABS LAYER
|
||||
HELPER.addReFramedModel("slabs_layer_2" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_2")));
|
||||
HELPER.addReFramedModel("slabs_layer_4" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_4")));
|
||||
HELPER.addReFramedModel("slabs_layer_6" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_6")));
|
||||
HELPER.addReFramedModel("slabs_layer_8" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_8")));
|
||||
|
||||
|
||||
|
||||
// item model assignments (in lieu of models/item/___.json)
|
||||
@ -245,6 +251,7 @@ public class ReFramedClient implements ClientModInitializer {
|
||||
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);
|
||||
HELPER.assignItemModel("slabs_layer_2" , ReFramed.SLABS_LAYER);
|
||||
}
|
||||
|
||||
private void privateInit() {
|
||||
|
@ -33,6 +33,7 @@ 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(ReFramedSlabsLayerBlock.class, new SlabsLayer());
|
||||
providers.put(ReFramedHalfSlabBlock.class, new HalfSlab());
|
||||
providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab());
|
||||
providers.put(ReFramedSmallCubeBlock.class, new SmallCube());
|
||||
|
@ -35,6 +35,7 @@ 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(ReFramedSlabsLayerBlock.class, new SlabsLayer());
|
||||
providers.put(ReFramedHalfSlabBlock.class, new HalfSlab());
|
||||
providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab());
|
||||
providers.put(ReFramedSmallCubeBlock.class, new SmallCube());
|
||||
|
@ -0,0 +1,58 @@
|
||||
package fr.adrien1106.reframed.generator.block;
|
||||
|
||||
import fr.adrien1106.reframed.ReFramed;
|
||||
import fr.adrien1106.reframed.generator.BlockStateProvider;
|
||||
import fr.adrien1106.reframed.generator.GBlockstate;
|
||||
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;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
|
||||
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||
import static net.minecraft.state.property.Properties.FACING;
|
||||
|
||||
public class SlabsLayer 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.SLAB)
|
||||
.input(ReFramed.LAYER)
|
||||
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
|
||||
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
|
||||
.offerTo(exporter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultipartBlockStateSupplier getMultipart(Block block) {
|
||||
String model_pattern = "slabs_layer_x_special";
|
||||
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(block);
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
Identifier model = ReFramed.id(model_pattern.replace("x", i * 2 + ""));
|
||||
supplier
|
||||
.with(GBlockstate.when(FACING, Direction.DOWN, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R0, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.SOUTH, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R90, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.UP, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R180, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.NORTH, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R270, R0))
|
||||
.with(GBlockstate.when(FACING, Direction.WEST, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R90, R90))
|
||||
.with(GBlockstate.when(FACING, Direction.EAST, HALF_LAYERS, i),
|
||||
GBlockstate.variant(model, true, R90, R270));
|
||||
}
|
||||
return supplier;
|
||||
}
|
||||
}
|
@ -12,4 +12,6 @@ public class BlockProperties {
|
||||
public static final IntProperty CORNER_FACE = IntProperty.of("face", 0, 2);
|
||||
public static final IntProperty CORNER_FEATURE = IntProperty.of("corner_feature", 0, 1);
|
||||
public static final EnumProperty<StairShape> STAIR_SHAPE = EnumProperty.of("shape", StairShape.class);
|
||||
public static final IntProperty HALF_LAYERS = IntProperty.of("layers", 1, 4);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user