v1.5 new shapes + self culling + caching + coding tools/cleanup #10

Merged
Adrien1106 merged 11 commits from dev into master 2024-03-14 22:30:30 +01:00
20 changed files with 637 additions and 224 deletions
Showing only changes of commit 96f08bdd3e - Show all commits

View File

@ -1,7 +1,6 @@
package fr.adrien1106.reframed; package fr.adrien1106.reframed;
import fr.adrien1106.reframed.block.*; import fr.adrien1106.reframed.block.*;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
@ -25,16 +24,22 @@ import java.util.ArrayList;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
/** /**
* TODO self culling * TODO add Hammer from framed ( removes theme ) for sure
* TODO fix other models * TODO add screwdriver ( iterate over theme states ) ?
* TODO add blueprint for survival friendly copy paste of a theme.
* TODO fix other models ( + half stair )
* TODO get better naming for the shapes (will break a lot of already placed blocks)
* TODO put more coherence in the double theme orders / directions
* TODO better connected textures * TODO better connected textures
*/ */
public class ReFramed implements ModInitializer { public class ReFramed implements ModInitializer {
public static final String MODID = "reframed"; public static final String MODID = "reframed";
public static final ArrayList<Block> BLOCKS = new ArrayList<>(); public static final ArrayList<Block> BLOCKS = new ArrayList<>();
public static Block CUBE, STAIRS, DOUBLE_STAIRS, SLAB, DOUBLE_SLAB, STEP, DOUBLE_STEP; public static Block CUBE, SMALL_CUBE, DOUBLE_SMALL_CUBE, STAIRS, DOUBLE_STAIRS, SLAB, DOUBLE_SLAB, STEP, DOUBLE_STEP;
public static ItemGroup ITEM_GROUP; public static ItemGroup ITEM_GROUP;
public static BlockEntityType<ReFramedEntity> REFRAMED_BLOCK_ENTITY; public static BlockEntityType<ReFramedEntity> REFRAMED_BLOCK_ENTITY;
@ -44,14 +49,13 @@ public class ReFramed implements ModInitializer {
@Override @Override
public void onInitialize() { public void onInitialize() {
//registerReFramed mutates FRAMES as a side effect, which is a List, so order is preserved
//the ordering is used in the creative tab, so they're roughly sorted by encounter order of the
//corresponding vanilla block in the "search" creative tab... with the non-vanilla "post" and
//"vertical slab" inserted where they fit ...and i moved the lever way up next to the pressureplate
//and button, because they're redstoney... hopefully this ordering makes sense lol
CUBE = registerReFramed("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS))); CUBE = registerReFramed("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS)));
SMALL_CUBE = registerReFramed("small_cube" , new ReFramedSmallBlock(cp(Blocks.OAK_PLANKS)));
DOUBLE_SMALL_CUBE = registerReFramed("double_small_cube" , new ReFramedDoubleSmallBlock(cp(Blocks.OAK_PLANKS)));
STAIRS = registerReFramed("stairs" , new ReFramedStairsBlock(cp(Blocks.OAK_STAIRS))); STAIRS = registerReFramed("stairs" , new ReFramedStairsBlock(cp(Blocks.OAK_STAIRS)));
DOUBLE_STAIRS = registerReFramed("double_stairs" , new ReFramedDoubleStairsBlock(cp(Blocks.OAK_STAIRS))); DOUBLE_STAIRS = registerReFramed("double_stairs" , new ReFramedDoubleStairsBlock(cp(Blocks.OAK_STAIRS)));
// CUBE = registerReFramed("half_stairs" , new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO
// CUBE = registerReFramed("double_half_stairs", new ReFramedBlock(cp(Blocks.OAK_STAIRS))); // TODO
SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB))); SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB)));
DOUBLE_SLAB = registerReFramed("double_slab" , new ReFramedDoubleSlabBlock(cp(Blocks.OAK_SLAB))); DOUBLE_SLAB = registerReFramed("double_slab" , new ReFramedDoubleSlabBlock(cp(Blocks.OAK_SLAB)));
STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); STEP = registerReFramed("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB)));
@ -82,7 +86,7 @@ public class ReFramed implements ModInitializer {
private static AbstractBlock.Settings cp(Block base) { private static AbstractBlock.Settings cp(Block base) {
return AbstractBlock.Settings.copy(base) return AbstractBlock.Settings.copy(base)
.luminance(BlockHelper::luminance) .luminance(state -> state.contains(LIGHT) && state.get(LIGHT) ? 15 : 0)
.nonOpaque() .nonOpaque()
.sounds(BlockSoundGroup.WOOD) .sounds(BlockSoundGroup.WOOD)
.hardness(0.2f) .hardness(0.2f)

View File

@ -0,0 +1,132 @@
package fr.adrien1106.reframed;
import fr.adrien1106.reframed.block.WaterloggableReFramedDoubleBlock;
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;
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.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedSmallBlock.SMALL_CUBE_VOXELS;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
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 ReFramedDoubleSmallBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider {
public ReFramedDoubleSmallBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(EDGE, 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<Block, BlockState> 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 getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getStepShape(state.get(EDGE));
}
@Override // TODO
public VoxelShape getShape(BlockState state, int i) {
return switch (state.get(EDGE)) {
case NORTH_DOWN -> SMALL_CUBE_VOXELS.get(i == 1 ? 0 : 3);
case DOWN_SOUTH -> SMALL_CUBE_VOXELS.get(i == 1 ? 1 : 2);
case SOUTH_UP -> SMALL_CUBE_VOXELS.get(i == 1 ? 5 : 6);
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 ? 4 : 5);
case UP_WEST -> SMALL_CUBE_VOXELS.get(i == 1 ? 6 : 7);
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);
};
}
@Override
public int getTopThemeIndex(BlockState state) {
return super.getTopThemeIndex(state); // TODO
}
@Override // TODO
public BlockStateSupplier getMultipart() {
Identifier small_cube_id = ReFramed.id("double_small_cube_special");
return MultipartBlockStateSupplier.create(this)
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(small_cube_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(small_cube_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(small_cube_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(small_cube_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(small_cube_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(small_cube_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(small_cube_id, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(small_cube_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(small_cube_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(small_cube_id, true, R180, R90));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 4);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this)
.pattern("II")
.input('I', ReFramed.SMALL_CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
}

View File

@ -3,7 +3,7 @@ package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.util.blocks.BlockHelper; 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 fr.adrien1106.reframed.util.blocks.StairShape;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -28,22 +28,22 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import static fr.adrien1106.reframed.block.ReFramedStairsBlock.*; import static fr.adrien1106.reframed.block.ReFramedStairsBlock.*;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; 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.BlockProperties.STAIR_SHAPE;
public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements BlockStateProvider { public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements BlockStateProvider {
private static final List<VoxelShape> COMPLEMENT_LIST = new ArrayList<>(52); private static final List<VoxelShape> COMPLEMENT_LIST = new ArrayList<>(52);
private record ModelCacheKey(Corner corner, StairShape shape) {} private record ModelCacheKey(Edge edge, StairShape shape) {}
public ReFramedDoubleStairsBlock(Settings settings) { public ReFramedDoubleStairsBlock(Settings settings) {
super(settings); super(settings);
setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT)); setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT));
} }
@Override @Override
public Object getModelCacheKey(BlockState state) { public Object getModelCacheKey(BlockState state) {
return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
} }
@Override @Override
@ -53,22 +53,22 @@ public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements Bl
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER, STAIR_SHAPE)); super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
} }
@Override @Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) { public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) {
return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved) return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved)
.with(STAIR_SHAPE, BlockHelper.getStairsShape(this, state.get(CORNER), world, pos)); .with(STAIR_SHAPE, BlockHelper.getStairsShape(this, state.get(EDGE), world, pos));
} }
@Nullable @Nullable
@Override @Override
public BlockState getPlacementState(ItemPlacementContext ctx) { public BlockState getPlacementState(ItemPlacementContext ctx) {
Corner face = BlockHelper.getPlacementCorner(ctx); Edge face = BlockHelper.getPlacementEdge(ctx);
StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos()); StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos());
return super.getPlacementState(ctx).with(CORNER, face).with(STAIR_SHAPE, shape); return super.getPlacementState(ctx).with(EDGE, face).with(STAIR_SHAPE, shape);
} }
@Override @Override
@ -85,7 +85,7 @@ public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements Bl
private VoxelShape getComplementOutline(BlockState state) { private VoxelShape getComplementOutline(BlockState state) {
StairShape shape = state.get(STAIR_SHAPE); StairShape shape = state.get(STAIR_SHAPE);
Corner direction = state.get(CORNER); Edge direction = state.get(EDGE);
return switch (shape) { return switch (shape) {
case STRAIGHT -> case STRAIGHT ->
switch (direction) { switch (direction) {

View File

@ -85,6 +85,11 @@ public class ReFramedDoubleStepBlock extends WaterloggableReFramedDoubleBlock im
}); });
} }
@Override
public int getTopThemeIndex(BlockState state) {
return 2;
}
@Override @Override
public MultipartBlockStateSupplier getMultipart() { public MultipartBlockStateSupplier getMultipart() {
Identifier step_id = ReFramed.id("double_step_special"); Identifier step_id = ReFramed.id("double_step_special");

View File

@ -0,0 +1,124 @@
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 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.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.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class ReFramedSmallBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
public static final List<VoxelShape> SMALL_CUBE_VOXELS = new ArrayList<>(8);
public ReFramedSmallBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN));
}
@Override
public Object getModelCacheKey(BlockState state) {
return state.get(CORNER);
}
@Override
public int getModelStateCount() {
return 8;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
return super.getPlacementState(ctx).with(CORNER, BlockHelper.getPlacementCorner(ctx));
}
@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);
};
}
@Override
public BlockStateSupplier getMultipart() {
Identifier small_cube_id = ReFramed.id("small_cube_special");
return MultipartBlockStateSupplier.create(this)
.with(GBlockstate.when(CORNER, NORTH_EAST_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R0))
.with(GBlockstate.when(CORNER, EAST_SOUTH_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R90))
.with(GBlockstate.when(CORNER, SOUTH_WEST_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R180))
.with(GBlockstate.when(CORNER, WEST_NORTH_DOWN),
GBlockstate.variant(small_cube_id, true, R0, R270))
.with(GBlockstate.when(CORNER, EAST_SOUTH_UP),
GBlockstate.variant(small_cube_id, true, R180, R0))
.with(GBlockstate.when(CORNER, SOUTH_WEST_UP),
GBlockstate.variant(small_cube_id, true, R180, R90))
.with(GBlockstate.when(CORNER, WEST_NORTH_UP),
GBlockstate.variant(small_cube_id, true, R180, R180))
.with(GBlockstate.when(CORNER, NORTH_EAST_UP),
GBlockstate.variant(small_cube_id, true, R180, R270));
}
@Override
public void setRecipe(RecipeExporter exporter) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, this, ReFramed.CUBE, 8);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, this, 8)
.input(ReFramed.CUBE)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(this), FabricRecipeProvider.conditionsFromItem(this))
.offerTo(exporter);
}
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.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));
}
}

View File

@ -5,7 +5,7 @@ import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.VoxelHelper; import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.Corner; import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape; import fr.adrien1106.reframed.util.blocks.StairShape;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -37,21 +37,21 @@ import java.util.stream.Stream;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*; import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static fr.adrien1106.reframed.util.blocks.StairShape.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*; import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static fr.adrien1106.reframed.util.blocks.Corner.*; import static fr.adrien1106.reframed.util.blocks.Edge.*;
public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements BlockStateProvider { public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
public static final List<VoxelShape> VOXEL_LIST = new ArrayList<>(52); public static final List<VoxelShape> VOXEL_LIST = new ArrayList<>(52);
private record ModelCacheKey(Corner corner, StairShape shape) {} private record ModelCacheKey(Edge edge, StairShape shape) {}
public ReFramedStairsBlock(Settings settings) { public ReFramedStairsBlock(Settings settings) {
super(settings); super(settings);
setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT));
} }
@Override @Override
public Object getModelCacheKey(BlockState state) { public Object getModelCacheKey(BlockState state) {
return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
} }
@Override @Override
@ -61,21 +61,21 @@ public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements B
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER, STAIR_SHAPE)); super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
} }
@Override @Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) { public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) {
return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved) return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved)
.with(STAIR_SHAPE, BlockHelper.getStairsShape(state.getBlock(), state.get(CORNER), world, pos)); .with(STAIR_SHAPE, BlockHelper.getStairsShape(state.getBlock(), state.get(EDGE), world, pos));
} }
@Nullable @Nullable
@Override // Pretty happy of how clean it is (also got it on first try :) ) @Override // Pretty happy of how clean it is (also got it on first try :) )
public BlockState getPlacementState(ItemPlacementContext ctx) { public BlockState getPlacementState(ItemPlacementContext ctx) {
Corner face = BlockHelper.getPlacementCorner(ctx); Edge face = BlockHelper.getPlacementEdge(ctx);
StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos()); StairShape shape = BlockHelper.getStairsShape(this, face, ctx.getWorld(), ctx.getBlockPos());
return super.getPlacementState(ctx).with(CORNER, face).with(STAIR_SHAPE, shape); return super.getPlacementState(ctx).with(EDGE, face).with(STAIR_SHAPE, shape);
} }
@Override @Override
@ -93,7 +93,7 @@ public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements B
public static VoxelShape getOutline(BlockState state) { public static VoxelShape getOutline(BlockState state) {
StairShape shape = state.get(STAIR_SHAPE); StairShape shape = state.get(STAIR_SHAPE);
Corner direction = state.get(CORNER); Edge direction = state.get(EDGE);
return switch (shape) { return switch (shape) {
case STRAIGHT -> case STRAIGHT ->
switch (direction) { switch (direction) {
@ -219,217 +219,217 @@ public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements B
Identifier outer_side_id = ReFramed.id(prefix + "outer_side_stairs_special"); Identifier outer_side_id = ReFramed.id(prefix + "outer_side_stairs_special");
return MultipartBlockStateSupplier.create(block) return MultipartBlockStateSupplier.create(block)
/* STRAIGHT X AXIS */ /* STRAIGHT X AXIS */
.with(GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R0)) GBlockstate.variant(straight_id, true, R0, R0))
.with(GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R0)) GBlockstate.variant(straight_id, true, R180, R0))
.with(GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R180)) GBlockstate.variant(straight_id, true, R180, R180))
.with(GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R180)) GBlockstate.variant(straight_id, true, R0, R180))
/* STRAIGHT Y AXIS */ /* STRAIGHT Y AXIS */
.with(GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R0)) GBlockstate.variant(straight_id, true, R90, R0))
.with(GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R90)) GBlockstate.variant(straight_id, true, R90, R90))
.with(GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R180)) GBlockstate.variant(straight_id, true, R90, R180))
.with(GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R90, R270)) GBlockstate.variant(straight_id, true, R90, R270))
/* STRAIGHT Z AXIS */ /* STRAIGHT Z AXIS */
.with(GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R90)) GBlockstate.variant(straight_id, true, R0, R90))
.with(GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R0, R270)) GBlockstate.variant(straight_id, true, R0, R270))
.with(GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R270)) GBlockstate.variant(straight_id, true, R180, R270))
.with(GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, STRAIGHT), .with(GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, STRAIGHT),
GBlockstate.variant(straight_id, true, R180, R90)) GBlockstate.variant(straight_id, true, R180, R90))
/* INNER BOTTOM */ /* INNER BOTTOM */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R0, R180)) GBlockstate.variant(inner_id, true, R0, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R0, R270)) GBlockstate.variant(inner_id, true, R0, R270))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R0, R0)) GBlockstate.variant(inner_id, true, R0, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R0, R90)) GBlockstate.variant(inner_id, true, R0, R90))
/* INNER TOP */ /* INNER TOP */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R180, R0)) GBlockstate.variant(inner_id, true, R180, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, INNER_RIGHT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, INNER_RIGHT),
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R180, R90)) GBlockstate.variant(inner_id, true, R180, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, INNER_RIGHT)), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_RIGHT)),
GBlockstate.variant(inner_id, true, R180, R180)) GBlockstate.variant(inner_id, true, R180, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, INNER_LEFT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, INNER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, INNER_LEFT)), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, INNER_LEFT)),
GBlockstate.variant(inner_id, true, R180, R270)) GBlockstate.variant(inner_id, true, R180, R270))
/* OUTER BOTTOM */ /* OUTER BOTTOM */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R0, R0)) GBlockstate.variant(outer_id, true, R0, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R0, R90)) GBlockstate.variant(outer_id, true, R0, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R0, R180)) GBlockstate.variant(outer_id, true, R0, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R0, R270)) GBlockstate.variant(outer_id, true, R0, R270))
/* OUTER TOP */ /* OUTER TOP */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R180, R0)) GBlockstate.variant(outer_id, true, R180, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R180, R90)) GBlockstate.variant(outer_id, true, R180, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_id, true, R180, R180)) GBlockstate.variant(outer_id, true, R180, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_id, true, R180, R270)) GBlockstate.variant(outer_id, true, R180, R270))
/* OUTER EAST */ /* OUTER EAST */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R0, R0)) GBlockstate.variant(outer_side_id, true, R0, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R90, R0)) GBlockstate.variant(outer_side_id, true, R90, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R180, R0)) GBlockstate.variant(outer_side_id, true, R180, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R270, R0)) GBlockstate.variant(outer_side_id, true, R270, R0))
/* OUTER SOUTH */ /* OUTER SOUTH */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R0, R90)) GBlockstate.variant(outer_side_id, true, R0, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R90, R90)) GBlockstate.variant(outer_side_id, true, R90, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R180, R90)) GBlockstate.variant(outer_side_id, true, R180, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R270, R90)) GBlockstate.variant(outer_side_id, true, R270, R90))
/* OUTER WEST */ /* OUTER WEST */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R0, R180)) GBlockstate.variant(outer_side_id, true, R0, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R90, R180)) GBlockstate.variant(outer_side_id, true, R90, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R180, R180)) GBlockstate.variant(outer_side_id, true, R180, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R270, R180)) GBlockstate.variant(outer_side_id, true, R270, R180))
/* OUTER NORTH */ /* OUTER NORTH */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_RIGHT),
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R0, R270)) GBlockstate.variant(outer_side_id, true, R0, R270))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, SECOND_OUTER_LEFT),
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT)),
GBlockstate.variant(outer_side_id, true, R90, R270)) GBlockstate.variant(outer_side_id, true, R90, R270))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT),
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, FIRST_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R180, R270)) GBlockstate.variant(outer_side_id, true, R180, R270))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, FIRST_OUTER_RIGHT),
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, SECOND_OUTER_LEFT)),
GBlockstate.variant(outer_side_id, true, R270, R270)) GBlockstate.variant(outer_side_id, true, R270, R270))
/* OUTER BOTTOM */ /* OUTER BOTTOM */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R0)) GBlockstate.variant(double_outer_id, true, R0, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, DOWN_SOUTH, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R90)) GBlockstate.variant(double_outer_id, true, R0, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, WEST_DOWN, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R180)) GBlockstate.variant(double_outer_id, true, R0, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, NORTH_DOWN, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, DOWN_EAST, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_RIGHT)),
GBlockstate.variant(double_outer_id, true, R0, R270)) GBlockstate.variant(double_outer_id, true, R0, R270))
/* OUTER TOP */ /* OUTER TOP */
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.when(EDGE, NORTH_EAST, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R0)) GBlockstate.variant(double_outer_id, true, R180, R0))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, EAST_UP, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, EAST_UP, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.when(EDGE, EAST_SOUTH, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R90)) GBlockstate.variant(double_outer_id, true, R180, R90))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, SOUTH_UP, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, OUTER_RIGHT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_RIGHT),
GBlockstate.when(CORNER, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.when(EDGE, SOUTH_WEST, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R180)) GBlockstate.variant(double_outer_id, true, R180, R180))
.with(When.anyOf( .with(When.anyOf(
GBlockstate.when(CORNER, UP_NORTH, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, UP_NORTH, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, UP_WEST, STAIR_SHAPE, OUTER_LEFT), GBlockstate.when(EDGE, UP_WEST, STAIR_SHAPE, OUTER_LEFT),
GBlockstate.when(CORNER, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)), GBlockstate.when(EDGE, WEST_NORTH, STAIR_SHAPE, OUTER_LEFT)),
GBlockstate.variant(double_outer_id, true, R180, R270)); GBlockstate.variant(double_outer_id, true, R180, R270));
} }

View File

@ -5,7 +5,7 @@ import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.BlockStateProvider; import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.VoxelHelper; import fr.adrien1106.reframed.util.VoxelHelper;
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.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -28,8 +28,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Corner.*; import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*; import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider { public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider {
@ -38,12 +38,12 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo
public ReFramedStepBlock(Settings settings) { public ReFramedStepBlock(Settings settings) {
super(settings); super(settings);
setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN)); setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN));
} }
@Override @Override
public Object getModelCacheKey(BlockState state) { public Object getModelCacheKey(BlockState state) {
return state.get(CORNER); return state.get(EDGE);
} }
@Override @Override
@ -53,18 +53,22 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER)); super.appendProperties(builder.add(EDGE));
} }
@Nullable @Nullable
@Override @Override
public BlockState getPlacementState(ItemPlacementContext ctx) { public BlockState getPlacementState(ItemPlacementContext ctx) {
return super.getPlacementState(ctx).with(CORNER, BlockHelper.getPlacementCorner(ctx)); return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx));
} }
@Override @Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return switch (state.get(CORNER)) { return getStepShape(state.get(EDGE));
}
public static VoxelShape getStepShape(Edge edge) {
return switch (edge) {
case DOWN_SOUTH -> STEP_VOXELS.get(0); case DOWN_SOUTH -> STEP_VOXELS.get(0);
case NORTH_DOWN -> STEP_VOXELS.get(1); case NORTH_DOWN -> STEP_VOXELS.get(1);
case UP_NORTH -> STEP_VOXELS.get(2); case UP_NORTH -> STEP_VOXELS.get(2);
@ -85,31 +89,31 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo
Identifier step_id = ReFramed.id("step_special"); Identifier step_id = ReFramed.id("step_special");
return MultipartBlockStateSupplier.create(this) return MultipartBlockStateSupplier.create(this)
/* X AXIS */ /* X AXIS */
.with(GBlockstate.when(CORNER, DOWN_EAST), .with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(step_id, true, R0, R0)) GBlockstate.variant(step_id, true, R0, R0))
.with(GBlockstate.when(CORNER, EAST_UP), .with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(step_id, true, R180, R0)) GBlockstate.variant(step_id, true, R180, R0))
.with(GBlockstate.when(CORNER, UP_WEST), .with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(step_id, true, R180, R180)) GBlockstate.variant(step_id, true, R180, R180))
.with(GBlockstate.when(CORNER, WEST_DOWN), .with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(step_id, true, R0, R180)) GBlockstate.variant(step_id, true, R0, R180))
/* Y AXIS */ /* Y AXIS */
.with(GBlockstate.when(CORNER, EAST_SOUTH), .with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(step_id, true, R90, R0)) GBlockstate.variant(step_id, true, R90, R0))
.with(GBlockstate.when(CORNER, SOUTH_WEST), .with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(step_id, true, R90, R90)) GBlockstate.variant(step_id, true, R90, R90))
.with(GBlockstate.when(CORNER, WEST_NORTH), .with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(step_id, true, R90, R180)) GBlockstate.variant(step_id, true, R90, R180))
.with(GBlockstate.when(CORNER, NORTH_EAST), .with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(step_id, true, R90, R270)) GBlockstate.variant(step_id, true, R90, R270))
/* Z AXIS */ /* Z AXIS */
.with(GBlockstate.when(CORNER, DOWN_SOUTH), .with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(step_id, true, R0, R90)) GBlockstate.variant(step_id, true, R0, R90))
.with(GBlockstate.when(CORNER, NORTH_DOWN), .with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(step_id, true, R0, R270)) GBlockstate.variant(step_id, true, R0, R270))
.with(GBlockstate.when(CORNER, UP_NORTH), .with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(step_id, true, R180, R270)) GBlockstate.variant(step_id, true, R180, R270))
.with(GBlockstate.when(CORNER, SOUTH_UP), .with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(step_id, true, R180, R90)); GBlockstate.variant(step_id, true, R180, R90));
} }

View File

@ -27,6 +27,8 @@ public class ReFramedClient implements ClientModInitializer {
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0])); BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
HELPER.addReFramedModel("cube_special" , HELPER.auto(new Identifier("block/cube"))); 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("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("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("stairs_special" , HELPER.auto(ReFramed.id("block/stairs")));
@ -45,6 +47,8 @@ public class ReFramedClient implements ClientModInitializer {
//item model assignments (in lieu of models/item/___.json) //item model assignments (in lieu of models/item/___.json)
HELPER.assignItemModel("cube_special" , ReFramed.CUBE); HELPER.assignItemModel("cube_special" , ReFramed.CUBE);
HELPER.assignItemModel("small_cube_special" , ReFramed.SMALL_CUBE);
HELPER.assignItemModel("double_small_cube_special" , ReFramed.DOUBLE_SMALL_CUBE);
HELPER.assignItemModel("slab_special" , ReFramed.SLAB); HELPER.assignItemModel("slab_special" , ReFramed.SLAB);
HELPER.assignItemModel("double_slab_special" , ReFramed.DOUBLE_SLAB); HELPER.assignItemModel("double_slab_special" , ReFramed.DOUBLE_SLAB);
HELPER.assignItemModel("stairs_special" , ReFramed.STAIRS); HELPER.assignItemModel("stairs_special" , ReFramed.STAIRS);

View File

@ -1,11 +1,14 @@
package fr.adrien1106.reframed.client.model; package fr.adrien1106.reframed.client.model;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.joml.Vector3f; import org.joml.Vector3f;
@Environment(EnvType.CLIENT)
public record QuadPosBounds(float min_x, float max_x, float min_y, float max_y, float min_z, float max_z) { public record QuadPosBounds(float min_x, float max_x, float min_y, float max_y, float min_z, float max_z) {
public static QuadPosBounds read(QuadView quad) { public static QuadPosBounds read(QuadView quad) {

View File

@ -1,10 +1,13 @@
package fr.adrien1106.reframed.client.model; package fr.adrien1106.reframed.client.model;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@Environment(EnvType.CLIENT)
public record QuadUvBounds(float minU, float maxU, float minV, float maxV) { public record QuadUvBounds(float minU, float maxU, float minV, float maxV) {
public static QuadUvBounds read(QuadView quad) { public static QuadUvBounds read(QuadView quad) {
float u0 = quad.u(0), u1 = quad.u(1), u2 = quad.u(2), u3 = quad.u(3); float u0 = quad.u(0), u1 = quad.u(1), u2 = quad.u(2), u3 = quad.u(3);

View File

@ -1,6 +1,8 @@
package fr.adrien1106.reframed.client.model.apperance; package fr.adrien1106.reframed.client.model.apperance;
import fr.adrien1106.reframed.client.model.QuadPosBounds; import fr.adrien1106.reframed.client.model.QuadPosBounds;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
@ -9,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
@Environment(EnvType.CLIENT)
public abstract class CamoAppearance { public abstract class CamoAppearance {
protected final int id; protected final int id;
protected final RenderMaterial ao_material; protected final RenderMaterial ao_material;

View File

@ -6,6 +6,8 @@ import fr.adrien1106.reframed.client.model.DynamicBakedModel;
import fr.adrien1106.reframed.client.model.QuadPosBounds; import fr.adrien1106.reframed.client.model.QuadPosBounds;
import fr.adrien1106.reframed.mixin.model.WeightedBakedModelAccessor; import fr.adrien1106.reframed.mixin.model.WeightedBakedModelAccessor;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
@ -33,6 +35,7 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function; import java.util.function.Function;
@Environment(EnvType.CLIENT)
public class CamoAppearanceManager { public class CamoAppearanceManager {
public CamoAppearanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) { public CamoAppearanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {

View File

@ -1,11 +1,14 @@
package fr.adrien1106.reframed.client.model.apperance; package fr.adrien1106.reframed.client.model.apperance;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
@Environment(EnvType.CLIENT)
public class ComputedAppearance extends CamoAppearance { public class ComputedAppearance extends CamoAppearance {
private final Appearance appearance; private final Appearance appearance;

View File

@ -1,5 +1,7 @@
package fr.adrien1106.reframed.client.model.apperance; package fr.adrien1106.reframed.client.model.apperance;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
@ -7,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
@Environment(EnvType.CLIENT)
public class SingleSpriteAppearance extends CamoAppearance { public class SingleSpriteAppearance extends CamoAppearance {
private final @NotNull Sprite defaultSprite; private final @NotNull Sprite defaultSprite;

View File

@ -1,5 +1,7 @@
package fr.adrien1106.reframed.client.model.apperance; package fr.adrien1106.reframed.client.model.apperance;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.minecraft.util.collection.Weighted; import net.minecraft.util.collection.Weighted;
import net.minecraft.util.collection.Weighting; import net.minecraft.util.collection.Weighting;
@ -9,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
@Environment(EnvType.CLIENT)
public class WeightedComputedAppearance extends CamoAppearance { public class WeightedComputedAppearance extends CamoAppearance {
private final List<Weighted.Present<Appearance>> appearances; private final List<Weighted.Present<Appearance>> appearances;
private final int total_weight; private final int total_weight;

View File

@ -6,6 +6,8 @@ import fr.adrien1106.reframed.block.ReFramedBlock;
import fr.adrien1106.reframed.block.ReFramedEntity; import fr.adrien1106.reframed.block.ReFramedEntity;
import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.ReFramedClient;
import fr.adrien1106.reframed.client.model.QuadPosBounds; import fr.adrien1106.reframed.client.model.QuadPosBounds;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
@ -20,6 +22,7 @@ import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Pair;
import net.minecraft.util.function.BooleanBiFunction; import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -32,14 +35,11 @@ import net.minecraft.world.BlockRenderView;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.Arrays; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static fr.adrien1106.reframed.util.blocks.StairShape.*;
import static net.minecraft.util.shape.VoxelShapes.combine; import static net.minecraft.util.shape.VoxelShapes.combine;
@ -48,22 +48,30 @@ public class BlockHelper {
// self culling cache of the models not made thread local so that it is only computed once // self culling cache of the models not made thread local so that it is only computed once
private static final Cache<CullElement, Integer[]> INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build(); private static final Cache<CullElement, Integer[]> INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build();
private record CullElement(Object state_key, int model) {} private record CullElement(Object state_key, int model) {}
public static Corner getPlacementCorner(ItemPlacementContext ctx) { public static Corner getPlacementCorner(ItemPlacementContext ctx) {
Direction side = ctx.getSide().getOpposite();
Vec3d pos = getHitPos(ctx.getHitPos(), ctx.getBlockPos());
Pair<Direction, Direction> sides = getHitSides(pos, side);
return Corner.getByDirections(side, sides.getLeft(), sides.getRight());
}
private static Pair<Direction, Direction> getHitSides(Vec3d pos, Direction side) {
Iterator<Direction.Axis> axes = Stream.of(Direction.Axis.values())
.filter(axis -> !axis.equals(side.getAxis())).iterator();
return new Pair<>(getHitDirection(axes.next(), pos), getHitDirection(axes.next(), pos));
}
public static Edge getPlacementEdge(ItemPlacementContext ctx) {
Direction side = ctx.getSide().getOpposite(); Direction side = ctx.getSide().getOpposite();
Vec3d pos = getHitPos(ctx.getHitPos(), ctx.getBlockPos()); Vec3d pos = getHitPos(ctx.getHitPos(), ctx.getBlockPos());
Direction.Axis axis = getHitAxis(pos, side); Direction.Axis axis = getHitAxis(pos, side);
Direction part_direction = Direction.from( Direction part_direction = getHitDirection(axis, pos);
axis,
axis.choose(pos.x, pos.y, pos.z) > 0
? Direction.AxisDirection.POSITIVE
: Direction.AxisDirection.NEGATIVE
);
return Corner.getByDirections(side, part_direction); return Edge.getByDirections(side, part_direction);
} }
public static Direction.Axis getHitAxis(Vec3d pos, Direction side) { public static Direction.Axis getHitAxis(Vec3d pos, Direction side) {
@ -75,6 +83,15 @@ public class BlockHelper {
).orElse(null); ).orElse(null);
} }
public static Direction getHitDirection(Direction.Axis axis, Vec3d pos) {
return Direction.from(
axis,
axis.choose(pos.x, pos.y, pos.z) > 0
? Direction.AxisDirection.POSITIVE
: Direction.AxisDirection.NEGATIVE
);
}
public static Vec3d getRelativePos(Vec3d pos, BlockPos block_pos) { public static Vec3d getRelativePos(Vec3d pos, BlockPos block_pos) {
return new Vec3d( return new Vec3d(
pos.getX() - block_pos.getX(), pos.getX() - block_pos.getX(),
@ -92,7 +109,7 @@ public class BlockHelper {
); );
} }
public static StairShape getStairsShape(Block block, Corner face, BlockView world, BlockPos pos) { public static StairShape getStairsShape(Block block, Edge face, BlockView world, BlockPos pos) {
StairShape shape = STRAIGHT; StairShape shape = STRAIGHT;
String sol = getNeighborPos(face, face.getFirstDirection(), true, face.getSecondDirection(), world, pos, block); String sol = getNeighborPos(face, face.getFirstDirection(), true, face.getSecondDirection(), world, pos, block);
@ -128,14 +145,14 @@ public class BlockHelper {
return shape; return shape;
} }
public static String getNeighborPos(Corner face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos, Block block) { public static String getNeighborPos(Edge face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos, Block block) {
BlockState block_state = world.getBlockState( BlockState block_state = world.getBlockState(
pos.offset(reverse ? direction.getOpposite() : direction) pos.offset(reverse ? direction.getOpposite() : direction)
); );
if (block_state.isOf(block) && block_state.get(CORNER).hasDirection(reference)) { if (block_state.isOf(block) && block_state.get(EDGE).hasDirection(reference)) {
if (block_state.get(CORNER).hasDirection(face.getLeftDirection())) return "left"; if (block_state.get(EDGE).hasDirection(face.getLeftDirection())) return "left";
else if (block_state.get(CORNER).hasDirection(face.getRightDirection())) return "right"; else if (block_state.get(EDGE).hasDirection(face.getRightDirection())) return "right";
} }
return ""; return "";
} }
@ -224,6 +241,7 @@ public class BlockHelper {
* @param state - the state of the model * @param state - the state of the model
* @param models - list of models on the same block * @param models - list of models on the same block
*/ */
@Environment(EnvType.CLIENT)
public static void computeInnerCull(BlockState state, List<ForwardingBakedModel> models) { public static void computeInnerCull(BlockState state, List<ForwardingBakedModel> models) {
if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return; if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return;
Object key = frame_block.getModelCacheKey(state); Object key = frame_block.getModelCacheKey(state);
@ -261,6 +279,7 @@ public class BlockHelper {
} }
} }
@Environment(EnvType.CLIENT)
public static boolean shouldDrawInnerFace(BlockState state, BlockRenderView view, BlockPos pos, int quad_index, int theme_index) { public static boolean shouldDrawInnerFace(BlockState state, BlockRenderView view, BlockPos pos, int quad_index, int theme_index) {
if ( !(state.getBlock() instanceof ReFramedBlock frame_block) if ( !(state.getBlock() instanceof ReFramedBlock frame_block)
|| !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity) || !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity)
@ -280,6 +299,7 @@ public class BlockHelper {
} }
// Doing this method from scratch as it is simpler to do than injecting everywhere // Doing this method from scratch as it is simpler to do than injecting everywhere
@Environment(EnvType.CLIENT)
public static boolean shouldDrawSide(BlockState self_state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, int theme_index) { public static boolean shouldDrawSide(BlockState self_state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, int theme_index) {
ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e ? e : null; ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e ? e : null;
ThemeableBlockEntity other = world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity e ? e : null; ThemeableBlockEntity other = world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity e ? e : null;
@ -372,8 +392,4 @@ public class BlockHelper {
.reduce((prev, current) -> prev && current).orElse(false) .reduce((prev, current) -> prev && current).orElse(false)
); );
} }
public static int luminance(BlockState state) {
return state.contains(LIGHT) && state.get(LIGHT) ? 15 : 0;
}
} }

View File

@ -5,6 +5,7 @@ import net.minecraft.state.property.EnumProperty;
public class BlockProperties { public class BlockProperties {
public static final BooleanProperty LIGHT = BooleanProperty.of("emits_light"); public static final BooleanProperty LIGHT = BooleanProperty.of("emits_light");
public static final EnumProperty<Edge> EDGE = EnumProperty.of("edge", Edge.class);
public static final EnumProperty<Corner> CORNER = EnumProperty.of("corner", Corner.class); public static final EnumProperty<Corner> CORNER = EnumProperty.of("corner", Corner.class);
public static final EnumProperty<StairShape> STAIR_SHAPE = EnumProperty.of("shape", StairShape.class); public static final EnumProperty<StairShape> STAIR_SHAPE = EnumProperty.of("shape", StairShape.class);
} }

View File

@ -6,32 +6,26 @@ import net.minecraft.util.math.Direction;
import java.util.Arrays; import java.util.Arrays;
public enum Corner implements StringIdentifiable { public enum Corner implements StringIdentifiable {
NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.EAST, 0), NORTH_EAST_DOWN("north_east_down", Direction.NORTH, Direction.EAST, Direction.DOWN, 0),
DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.EAST, 1), EAST_SOUTH_DOWN("east_south_down", Direction.EAST, Direction.SOUTH, Direction.DOWN, 1),
SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.EAST, 2), SOUTH_WEST_DOWN("south_west_down", Direction.SOUTH, Direction.WEST, Direction.DOWN, 2),
UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.EAST, 3), WEST_NORTH_DOWN("west_north_down", Direction.WEST, Direction.NORTH, Direction.DOWN, 3),
WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.SOUTH, 4), NORTH_EAST_UP("north_east_up", Direction.NORTH, Direction.EAST, Direction.UP, 4),
DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.SOUTH, 5), EAST_SOUTH_UP("east_south_up", Direction.EAST, Direction.SOUTH, Direction.UP, 5),
EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.SOUTH, 6), SOUTH_WEST_UP("south_west_up", Direction.SOUTH, Direction.WEST, Direction.UP, 6),
UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.SOUTH, 7), WEST_NORTH_UP("west_north_up", Direction.WEST, Direction.NORTH, Direction.UP, 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);
private final String name; private final String name;
private final Direction first_direction; private final Direction first_direction;
private final Direction second_direction; private final Direction second_direction;
private final Direction right_direction; private final Direction third_direction;
private final Direction left_direction;
private final int ID; private final int ID;
Corner(String name, Direction first_direction, Direction second_direction, Direction right_direction, int id) { Corner(String name, Direction first_direction, Direction second_direction, Direction third_direction, int id) {
this.name = name; this.name = name;
this.first_direction = first_direction; this.first_direction = first_direction;
this.second_direction = second_direction; this.second_direction = second_direction;
this.right_direction = right_direction; this.third_direction = third_direction;
this.left_direction = right_direction.getOpposite();
this.ID = id; this.ID = id;
} }
@ -43,44 +37,31 @@ public enum Corner implements StringIdentifiable {
return asString(); return asString();
} }
public Direction getFirstDirection() {
return first_direction;
}
public Direction getSecondDirection() {
return second_direction;
}
public Direction getRightDirection() {
return right_direction;
}
public Direction getLeftDirection() {
return left_direction;
}
public boolean hasDirection(Direction direction) { public boolean hasDirection(Direction direction) {
return this.first_direction.equals(direction) return this.first_direction.equals(direction)
|| this.second_direction.equals(direction); || this.second_direction.equals(direction)
|| this.third_direction.equals(direction);
} }
public int getID() { public int getID() {
return this.ID; return this.ID;
} }
public static Corner getByDirections(Direction direction_1, Direction direction_2) { public static Corner getByDirections(Direction direction_1, Direction direction_2, Direction direction_3) {
return Arrays.stream(Corner.values()) return Arrays.stream(Corner.values())
.filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2)) .filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2) && value.hasDirection(direction_3))
.findFirst().orElse(Corner.NORTH_DOWN); .findFirst().orElse(Corner.NORTH_EAST_DOWN);
} }
public static Corner fromId(int id) { public static Corner fromId(int id) {
return Arrays.stream(Corner.values()) return Arrays.stream(Corner.values())
.filter(value -> value.getID() == id) .filter(value -> value.getID() == id)
.findFirst().orElse(Corner.NORTH_DOWN); .findFirst().orElse(Corner.NORTH_EAST_DOWN);
} }
public static Corner fromName(String name) { public static Corner fromName(String name) {
return Arrays.stream(Corner.values()) return Arrays.stream(Corner.values())
.filter(value -> value.name().equals(name)) .filter(value -> value.name().equals(name))
.findFirst().orElse(Corner.NORTH_DOWN); .findFirst().orElse(Corner.NORTH_EAST_DOWN);
} }
} }

View File

@ -0,0 +1,86 @@
package fr.adrien1106.reframed.util.blocks;
import net.minecraft.util.StringIdentifiable;
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);
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 int ID;
Edge(String name, Direction first_direction, Direction second_direction, Direction right_direction, 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.ID = id;
}
public String asString() {
return this.name;
}
public String toString() {
return asString();
}
public Direction getFirstDirection() {
return first_direction;
}
public Direction getSecondDirection() {
return second_direction;
}
public Direction getRightDirection() {
return right_direction;
}
public Direction getLeftDirection() {
return left_direction;
}
public boolean hasDirection(Direction direction) {
return this.first_direction.equals(direction)
|| this.second_direction.equals(direction);
}
public int getID() {
return this.ID;
}
public static Edge getByDirections(Direction direction_1, Direction direction_2) {
return Arrays.stream(Edge.values())
.filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2))
.findFirst().orElse(Edge.NORTH_DOWN);
}
public static Edge fromId(int id) {
return Arrays.stream(Edge.values())
.filter(value -> value.getID() == id)
.findFirst().orElse(Edge.NORTH_DOWN);
}
public static Edge fromName(String name) {
return Arrays.stream(Edge.values())
.filter(value -> value.name().equals(name))
.findFirst().orElse(Edge.NORTH_DOWN);
}
}

View File

@ -0,0 +1,35 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"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"},
"south": {"uv": [8, 8, 16, 16], "texture": "#side"},
"west": {"uv": [0, 8, 8, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 8], "texture": "#top"},
"down": {"uv": [8, 8, 16, 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]
}
}
}