23 Commits

Author SHA1 Message Date
e0b04f0efd feat: added complex shape raycasting 2024-07-22 18:54:46 +02:00
e592db1ea2 feat: updated version 2024-07-01 23:31:09 +02:00
1fa55064c7 feat: added slabs layer block 2024-07-01 23:29:18 +02:00
e8c06a7fb3 feat: better additivity support 2024-07-01 22:31:52 +02:00
d7ae1f646f fix: bad rotating / mirroring logic on corner double frame 2024-07-01 15:16:50 +02:00
e3dac8a77f fix: wrong Step Cross shape 2024-07-01 02:19:34 +02:00
5281f84a2a fix: useAO out of bounds because not using model id 2024-07-01 02:11:49 +02:00
eac948bf5d feat: updated version 2024-06-19 14:36:00 +02:00
12924579a5 feat: added half slab and half slabs slab 2024-06-19 14:26:43 +02:00
48c7c4e538 fix: made frames properly update on every client when using blueprint/screwdriver/hammer 2024-06-19 13:20:12 +02:00
d325e3c5a5 feat: added 3 blocks and some refactoring 2024-06-19 02:42:03 +02:00
4d353bab27 refactor: changed method to non depreciated version 2024-06-18 15:23:59 +02:00
6f8304d638 feat: added HalfStairsCubeStair and HalfStairsStepStair 2024-06-18 14:56:46 +02:00
3bf9fc2268 feat: added StepCross 2024-06-17 21:10:57 +02:00
5812812bd9 feat: added missing models 2024-06-17 19:19:36 +02:00
1e6cab04cc feat: added SlabsInnerStair and SlabsOuterStair with additive logic + depreciation warning suppressing on AbstractBlock Methods 2024-06-17 19:19:13 +02:00
d7ad6ed0c1 feat: added and improved logic to merge step with slabs 2024-06-17 10:52:21 +02:00
8a9fbd9109 feat: added SlabsStair block 2024-06-16 18:17:04 +02:00
a76714d54d fix: render issue with items in axiom 2024-06-16 15:17:48 +02:00
b99f315c6f docs: updated objectives for publish 2024-06-14 17:46:47 +02:00
7df46a4b76 fix: more checks on ThemedEntity Class 2024-06-14 17:16:53 +02:00
42049047f7 fix: more injection fix + bad culling 2024-06-14 16:51:25 +02:00
ddffd45a44 fix: injection remapping issues fixed + additional check 2024-06-14 00:35:13 +02:00
152 changed files with 5312 additions and 524 deletions

View File

@@ -22,8 +22,6 @@ or based on preferences add the person(s) to the project
### What Shapes are planed to be added
Currently, the list of shapes to be added is pretty simple as the mod is still under development:
- Pressure Plate
- Carpet (maybe redundant with Layer)
- Half Slab (maybe redundant with Layer)
- Slabs Stair (a stair with one end being of a second theme, might be done in multiple blocks)
Any Ideas feel free to make a suggestion [here](https://github.com/DriHut/ReFramed/issues).

View File

@@ -44,6 +44,7 @@ sourceSets {
}
loom {
accessWidenerPath = file("src/main/resources/reframed.accesswidener")
runs {
// This adds a new gradle task that runs the datagen API: "gradlew runDatagen"
datagen {
@@ -122,7 +123,7 @@ dependencies {
modRuntimeOnly "earth.terrarium.chipped:Chipped-fabric-${project.minecraft_version}:3.1.2"
// Axiom for blueprint support
modCompileOnly "maven.modrinth:N6n5dqoA:nvx3oDkz"
modCompileOnly "maven.modrinth:N6n5dqoA:YxeYxQyz"
modCompileOnly "com.github.moulberry:AxiomClientAPI:1.0.5.3"
// Fabric API.

View File

@@ -9,7 +9,7 @@ loader_version=0.15.11
# Mod Properties
modrinth_id = jCpoCBpn
mod_version = 1.6
mod_version = 1.6.6
maven_group = fr.adrien1106
archives_base_name = ReFramed
mod_id = reframed

View File

@@ -7,7 +7,6 @@ import fr.adrien1106.reframed.item.ReFramedBlueprintWrittenItem;
import fr.adrien1106.reframed.item.ReFramedScrewdriverItem;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
@@ -28,23 +27,24 @@ import java.util.stream.Stream;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
/**
* TODO Dynamic Ambient Occlusion -> for v1.6
* TODO add minecraft models like wall fence etc -> for v1.6
* TODO better connected textures -> maybe v1.6 ?
* TODO Dynamic Ambient Occlusion -> not scheduled
* TODO better connected textures -> not scheduled
* TODO support continuity overlays -> not scheduled
* TODO slopes -> thinking about it
*/
public class ReFramed implements ModInitializer {
public static final String MODID = "reframed";
public static final ArrayList<Block> BLOCKS = new ArrayList<>();
public static Block
public static ReFramedBlock
CUBE,
SMALL_CUBE, SMALL_CUBES_STEP,
STAIR, STAIRS_CUBE,
HALF_STAIR, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR,
SLAB, SLABS_CUBE,
STEP, STEPS_SLAB,
LAYER,
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, SLABS_LAYER,
HALF_SLAB, HALF_SLABS_SLAB,
STEP, STEPS_SLAB, STEPS_CROSS, STEPS_HALF_LAYER,
LAYER, HALF_LAYER,
PILLAR, PILLARS_WALL, WALL,
PANE, TRAPDOOR, DOOR,
BUTTON,
@@ -62,37 +62,51 @@ public class ReFramed implements ModInitializer {
@Override
public void onInitialize() {
CUBE = registerBlock("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS)));
SMALL_CUBE = registerBlock("small_cube" , new ReFramedSmallCubeBlock(cp(Blocks.OAK_PLANKS)));
SMALL_CUBES_STEP = registerBlock("small_cubes_step" , new ReFramedSmallCubesStepBlock(cp(Blocks.OAK_PLANKS)));
STAIR = registerBlock("stair" , new ReFramedStairBlock(cp(Blocks.OAK_STAIRS)));
STAIRS_CUBE = registerBlock("stairs_cube" , new ReFramedStairsCubeBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIR = registerBlock("half_stair" , new ReFramedHalfStairBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIRS_SLAB = registerBlock("half_stairs_slab" , new ReFramedHalfStairsSlabBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIRS_STAIR = registerBlock("half_stairs_stair" , new ReFramedHalfStairsStairBlock(cp(Blocks.OAK_STAIRS)));
LAYER = registerBlock("layer" , new ReFramedLayerBlock(cp(Blocks.OAK_SLAB)));
SLAB = registerBlock("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB)));
SLABS_CUBE = registerBlock("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB)));
STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB)));
STEPS_SLAB = registerBlock("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB)));
PILLAR = registerBlock("pillar" , new ReFramedPillarBlock(cp(Blocks.OAK_FENCE)));
PILLARS_WALL = registerBlock("pillars_wall" , new ReFramedPillarsWallBlock(cp(Blocks.OAK_FENCE)));
WALL = registerBlock("wall" , new ReFramedWallBlock(cp(Blocks.OAK_FENCE)));
PANE = registerBlock("pane" , new ReFramedPaneBlock(cp(Blocks.OAK_FENCE)));
TRAPDOOR = registerBlock("trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR)));
DOOR = registerBlock("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR)));
BUTTON = registerBlock("button" , new ReFramedButtonBlock(cp(Blocks.OAK_BUTTON)));
POST = registerBlock("post" , new ReFramedPostBlock(cp(Blocks.OAK_FENCE)));
FENCE = registerBlock("fence" , new ReFramedFenceBlock(cp(Blocks.OAK_FENCE)));
POST_FENCE = registerBlock("post_fence" , new ReFramedPostFenceBlock(cp(Blocks.OAK_FENCE)));
CUBE = registerBlock("cube" , new ReFramedBlock(cp(Blocks.OAK_PLANKS)));
SMALL_CUBE = registerBlock("small_cube" , new ReFramedSmallCubeBlock(cp(Blocks.OAK_PLANKS)));
SMALL_CUBES_STEP = registerBlock("small_cubes_step" , new ReFramedSmallCubesStepBlock(cp(Blocks.OAK_PLANKS)));
STAIR = registerBlock("stair" , new ReFramedStairBlock(cp(Blocks.OAK_STAIRS)));
STAIRS_CUBE = registerBlock("stairs_cube" , new ReFramedStairsCubeBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIR = registerBlock("half_stair" , new ReFramedHalfStairBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIRS_SLAB = registerBlock("half_stairs_slab" , new ReFramedHalfStairsSlabBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIRS_STAIR = registerBlock("half_stairs_stair" , new ReFramedHalfStairsStairBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIRS_CUBE_STAIR = registerBlock("half_stairs_cube_stair" , new ReFramedHalfStairsCubeStairBlock(cp(Blocks.OAK_STAIRS)));
HALF_STAIRS_STEP_STAIR = registerBlock("half_stairs_step_stair" , new ReFramedHalfStairsStepStairBlock(cp(Blocks.OAK_STAIRS)));
LAYER = registerBlock("layer" , new ReFramedLayerBlock(cp(Blocks.OAK_SLAB)));
HALF_LAYER = registerBlock("half_layer" , new ReFramedHalfLayerBlock(cp(Blocks.OAK_SLAB)));
SLAB = registerBlock("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB)));
SLABS_CUBE = registerBlock("slabs_cube" , new ReFramedSlabsCubeBlock(cp(Blocks.OAK_SLAB)));
SLABS_STAIR = registerBlock("slabs_stair" , new ReFramedSlabsStairBlock(cp(Blocks.OAK_STAIRS)));
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)));
STEPS_SLAB = registerBlock("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB)));
STEPS_CROSS = registerBlock("steps_cross" , new ReFramedStepsCrossBlock(cp(Blocks.OAK_SLAB)));
STEPS_HALF_LAYER = registerBlock("steps_half_layer" , new ReFramedStepsHalfLayerBlock(cp(Blocks.OAK_SLAB)));
PILLAR = registerBlock("pillar" , new ReFramedPillarBlock(cp(Blocks.OAK_FENCE)));
PILLARS_WALL = registerBlock("pillars_wall" , new ReFramedPillarsWallBlock(cp(Blocks.OAK_FENCE)));
WALL = registerBlock("wall" , new ReFramedWallBlock(cp(Blocks.OAK_FENCE)));
PANE = registerBlock("pane" , new ReFramedPaneBlock(cp(Blocks.OAK_FENCE)));
TRAPDOOR = registerBlock("trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR)));
DOOR = registerBlock("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR)));
BUTTON = registerBlock("button" , new ReFramedButtonBlock(cp(Blocks.OAK_BUTTON)));
POST = registerBlock("post" , new ReFramedPostBlock(cp(Blocks.OAK_FENCE)));
FENCE = registerBlock("fence" , new ReFramedFenceBlock(cp(Blocks.OAK_FENCE)));
POST_FENCE = registerBlock("post_fence" , new ReFramedPostFenceBlock(cp(Blocks.OAK_FENCE)));
HAMMER = registerItem("hammer" , new ReFramedHammerItem(new Item.Settings().maxCount(1)));
SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1)));
BLUEPRINT = registerItem("blueprint" , new ReFramedBlueprintItem(new Item.Settings()));
BLUEPRINT_WRITTEN = registerItem("blueprint_written" , new ReFramedBlueprintWrittenItem(new Item.Settings().maxCount(1)));
HAMMER = registerItem("hammer" , new ReFramedHammerItem(new Item.Settings().maxCount(1)));
SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1)));
BLUEPRINT = registerItem("blueprint" , new ReFramedBlueprintItem(new Item.Settings()));
BLUEPRINT_WRITTEN = registerItem("blueprint_written" , new ReFramedBlueprintWrittenItem(new Item.Settings().maxCount(1)));
registerBlock("test", new TestBlock(cp(Blocks.OAK_PLANKS).nonOpaque())); // TODO remove
REFRAMED_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("camo"),
FabricBlockEntityTypeBuilder.create(
BlockEntityType.Builder.create(
(pos, state) -> new ReFramedEntity(REFRAMED_BLOCK_ENTITY, pos, state),
BLOCKS.stream()
.filter(block -> !(block instanceof ReFramedDoubleBlock))
@@ -100,7 +114,7 @@ public class ReFramed implements ModInitializer {
);
REFRAMED_DOUBLE_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("double_camo"),
FabricBlockEntityTypeBuilder.create(
BlockEntityType.Builder.create(
(pos, state) -> new ReFramedDoubleEntity(REFRAMED_DOUBLE_BLOCK_ENTITY, pos, state),
BLOCKS.stream()
.filter(block -> block instanceof ReFramedDoubleBlock)

View File

@@ -55,13 +55,7 @@ public abstract class ConnectingReFramedBlock extends WaterloggableReFramedBlock
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getConnectionProperty(rotation.rotate(dir)), state.get(getConnectionProperty(dir)))
@@ -69,6 +63,7 @@ public abstract class ConnectingReFramedBlock extends WaterloggableReFramedBlock
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getConnectionProperty(mirror.apply(dir)), state.get(getConnectionProperty(dir)))
@@ -78,6 +73,7 @@ public abstract class ConnectingReFramedBlock extends WaterloggableReFramedBlock
protected abstract boolean connectsTo(BlockState state, boolean fs, Direction dir);
@Override
@SuppressWarnings("deprecation")
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
public static BooleanProperty getConnectionProperty(Direction dir) {

View File

@@ -0,0 +1,70 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
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.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
public abstract class CornerDoubleReFramedBlock extends WaterloggableReFramedDoubleBlock {
public CornerDoubleReFramedBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_EAST_DOWN).with(CORNER_FACE, 0));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER,CORNER_FACE));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
Corner corner = BlockHelper.getPlacementCorner(ctx);
return super.getPlacementState(ctx)
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(ctx.getSide().getOpposite()));
}
@Override
@SuppressWarnings("deprecation")
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
corner = corner.rotate(rotation);
return state
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(rotation.rotate(face)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
corner = corner.mirror(mirror);
return state
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(mirror.apply(face)));
}
@Override
public abstract VoxelShape getShape(BlockState state, int i);
}

View File

@@ -0,0 +1,64 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Edge;
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.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
public abstract class EdgeDoubleReFramedBlock extends WaterloggableReFramedDoubleBlock {
public EdgeDoubleReFramedBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(EDGE_FACE, 0));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE, EDGE_FACE));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
Edge edge = BlockHelper.getPlacementEdge(ctx);
return super.getPlacementState(ctx)
.with(EDGE, edge)
.with(EDGE_FACE, edge.getDirectionIndex(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) {
Edge edge = state.get(EDGE).rotate(rotation);
Direction face = state.get(EDGE).getDirection(state.get(EDGE_FACE));
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(rotation.rotate(face)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
Edge edge = state.get(EDGE).mirror(mirror);
Direction face = state.get(EDGE).getDirection(state.get(EDGE_FACE));
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(mirror.apply(face)));
}
@Override
public abstract VoxelShape getShape(BlockState state, int i);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,46 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
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 java.util.List;
import static net.minecraft.state.property.Properties.LAYERS;
public abstract class HalfLayerDoubleReFramedBlock extends EdgeDoubleReFramedBlock {
public HalfLayerDoubleReFramedBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(LAYERS, 1));
}
@Override
@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;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(LAYERS));
}
@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.HALF_LAYER && state.get(LAYERS) < 8;
}
}

View File

@@ -0,0 +1,64 @@
package fr.adrien1106.reframed.block;
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.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import static net.minecraft.state.property.Properties.LAYERS;
public abstract class LayeredReFramedBlock extends WaterloggableReFramedBlock {
public LayeredReFramedBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(LAYERS, 1));
}
@Override
@SuppressWarnings("deprecation")
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
List<ItemStack> drops = super.getDroppedStacks(state, builder);
drops.forEach((stack) -> {
if (stack.getItem() instanceof BlockItem bi && bi.getBlock() instanceof LayeredReFramedBlock)
stack.setCount(state.get(LAYERS));
});
return drops;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(LAYERS));
}
@Override
@SuppressWarnings("deprecation")
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
@Override
@SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false;
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(block_item.getBlock() == this && state.get(LAYERS) < 8)
);
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
if (!previous.isOf(this)) return super.getPlacementState(ctx);
return previous.with(LAYERS, previous.get(LAYERS) + 1);
}
}

View File

@@ -32,14 +32,17 @@ public abstract class PillarReFramedBlock extends WaterloggableReFramedBlock {
}
@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(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(AXIS, mirror.apply(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
}

View File

@@ -20,6 +20,7 @@ import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
@@ -59,6 +60,7 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
}
@Override
@SuppressWarnings("deprecation")
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!canUse(world, pos, player)) return ActionResult.PASS;
ActionResult result = BlockHelper.useUpgrade(state, world, pos, player, hand);
@@ -72,7 +74,10 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
}
@Override
@SuppressWarnings("deprecation")
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
if (!new_state.isOf(state.getBlock())) world.removeBlockEntity(pos);
if(!(new_state.getBlock() instanceof ReFramedBlock) &&
world.getBlockEntity(pos) instanceof ReFramedEntity frame_entity &&
world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)
@@ -135,8 +140,22 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
}
onPlaced(world, pos, state, placer, stack);
}
public boolean matchesShape(Vec3d hit, BlockPos pos, BlockState state) {
return matchesShape(hit, pos, state, 0);
}
public boolean matchesShape(Vec3d hit, BlockPos pos, BlockState state, int i) {
Vec3d rel = BlockHelper.getRelativePos(hit, pos);
return matchesShape(rel, getShape(state, i));
}
public boolean matchesShape(Vec3d rel_hit, VoxelShape shape) {
return BlockHelper.cursorMatchesFace(shape, rel_hit);
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return isGhost(view, pos)
? VoxelShapes.empty()
@@ -144,12 +163,14 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
return isGhost(view, pos)
? VoxelShapes.empty()
: super.getCullingShape(state, view, pos);
}
@SuppressWarnings("deprecation")
public VoxelShape getShape(BlockState state, int i) {
// assuming the shape don't need the world and position
return getOutlineShape(state, null, null, null);
@@ -160,11 +181,13 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
}
@Override
@SuppressWarnings("deprecation")
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return view.getBlockEntity(pos) instanceof ReFramedEntity be && be.emitsRedstone() ? 15 : 0;
}
@Override
@SuppressWarnings("deprecation")
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return getWeakRedstonePower(state, view, pos, dir);
}

View File

@@ -51,6 +51,7 @@ public class ReFramedButtonBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
return canPlaceAt(world, pos, getDirection(state).getOpposite());
}
@@ -96,6 +97,7 @@ public class ReFramedButtonBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stackMerger) {
if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK && !world.isClient() && !(Boolean)state.get(POWERED)) {
powerOn(state, world, pos);
@@ -120,6 +122,7 @@ public class ReFramedButtonBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return BUTTON_VOXELS[
(state.get(POWERED) ? 12 : 0) +
@@ -129,11 +132,13 @@ public class ReFramedButtonBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING)));
}
@@ -144,7 +149,6 @@ public class ReFramedButtonBlock extends WaterloggableReFramedBlock {
if(!state.isOf(new_state.getBlock())) {
if (!moved && state.get(POWERED)) updateNeighbors(state, world, pos);
world.removeBlockEntity(pos);
}
}
@@ -159,16 +163,19 @@ public class ReFramedButtonBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean emitsRedstonePower(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (state.get(POWERED)) tryPowerWithProjectiles(state, world, pos);
}
@Override
@SuppressWarnings("deprecation")
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
if (!world.isClient && !state.get(POWERED)) tryPowerWithProjectiles(state, world, pos);
}

View File

@@ -57,6 +57,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
BlockPos pos_down = pos.down();
BlockState state_down = world.getBlockState(pos_down);
@@ -64,6 +65,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block source, BlockPos sourcePos, boolean notify) {
if (world.isClient) return;
boolean powered = world.isReceivingRedstonePower(pos)
@@ -126,13 +128,6 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
return super.onBreak(world, pos, state, player);
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState other, WorldAccess world, BlockPos pos, BlockPos moved) {
if (direction.getAxis() == Direction.Axis.Y
@@ -162,6 +157,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
return switch (type) {
case LAND, AIR -> state.get(OPEN);
@@ -170,6 +166,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stack_merger) {
if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK
&& !world.isClient()
@@ -192,6 +189,7 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
Direction direction = state.get(HORIZONTAL_FACING);
if (state.get(OPEN)) direction = switch (state.get(DOOR_HINGE)) {
@@ -202,16 +200,19 @@ public class ReFramedDoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return mirror == BlockMirror.NONE ? state : state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING))).cycle(DOOR_HINGE);
}
@Override
@SuppressWarnings("deprecation")
public long getRenderingSeed(BlockState state, BlockPos pos) {
return MathHelper.hashCode(pos.getX(), pos.down(state.get(DOUBLE_BLOCK_HALF) == DoubleBlockHalf.LOWER ? 0 : 1).getY(), pos.getZ());
}

View File

@@ -19,7 +19,6 @@ import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import static net.minecraft.util.shape.VoxelShapes.empty;
import static net.minecraft.util.shape.VoxelShapes.fullCube;
public abstract class ReFramedDoubleBlock extends ReFramedBlock {
public ReFramedDoubleBlock(Settings settings) {
@@ -49,14 +48,6 @@ public abstract class ReFramedDoubleBlock extends ReFramedBlock {
return 0;
}
public boolean matchesShape(Vec3d hit, BlockPos pos, BlockState state, int i) {
Vec3d rel = BlockHelper.getRelativePos(hit, pos);
return BlockHelper.cursorMatchesFace(
getShape(state, i),
rel
);
}
@Override
public boolean isTransparent(BlockState state, BlockView world, BlockPos pos) {
return world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity
@@ -69,7 +60,7 @@ public abstract class ReFramedDoubleBlock extends ReFramedBlock {
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return isGhost(view, pos) ? empty() : fullCube();
return isGhost(view, pos) ? empty() : getOutlineShape(state, view, pos, ctx);
}
@Override

View File

@@ -57,6 +57,6 @@ public class ReFramedDoubleEntity extends ReFramedEntity {
public void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
if(second_state != Blocks.AIR.getDefaultState()) nbt.put(BLOCKSTATE_KEY + 2, NbtHelper.fromBlockState(second_state));
nbt.put(BLOCKSTATE_KEY + 2, NbtHelper.fromBlockState(second_state));
}
}

View File

@@ -52,16 +52,15 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
if (nbt.contains(BITFIELD_KEY)) bit_field = nbt.getByte(BITFIELD_KEY);
// Force a chunk remesh on the client if the displayed blockstate has changed
if(world != null && world.isClient && !Objects.equals(rendered_state, first_state)) {
if(world != null && world.isClient && !Objects.equals(rendered_state, first_state))
ReFramed.chunkRerenderProxy.accept(world, pos);
}
}
@Override
public void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
if(first_state != Blocks.AIR.getDefaultState()) nbt.put(BLOCKSTATE_KEY + 1, NbtHelper.fromBlockState(first_state));
nbt.put(BLOCKSTATE_KEY + 1, NbtHelper.fromBlockState(first_state));
if(bit_field != SOLIDITY_MASK) nbt.putByte(BITFIELD_KEY, bit_field);
}
@@ -113,7 +112,7 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity
}
public void setTheme(BlockState new_state, int i) {
if(!Objects.equals(first_state, new_state)) {
if(!Objects.equals(first_state, new_state) && i == 1) {
first_state = new_state;
markDirtyAndDispatch();
}

View File

@@ -56,6 +56,7 @@ public class ReFramedFenceBlock extends ConnectingReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getCameraCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getOutlineShape(state, world, pos, context);
}
@@ -66,10 +67,12 @@ public class ReFramedFenceBlock extends ConnectingReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
return false;
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult result = super.onUse(state, world, pos, player, hand, hit);
if (result.isAccepted()) return result;

View File

@@ -0,0 +1,188 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Edge;
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.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 java.util.Map;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
import static net.minecraft.state.property.Properties.*;
public class ReFramedHalfLayerBlock extends LayeredReFramedBlock {
public static final VoxelShape[] HALF_LAYER_VOXELS;
public ReFramedHalfLayerBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(EDGE_FACE, 0));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE, EDGE_FACE));
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (super.canReplace(state, context)) return true;
if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
) return false;
Edge edge = state.get(EDGE);
Direction face = edge.getDirection(state.get(EDGE_FACE));
if (block_item.getBlock() == ReFramed.SLAB)
return ReFramed.SLAB
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SLAB.getDefaultState().with(FACING, edge.getOtherDirection(face).getOpposite())
);
if (block_item.getBlock() == ReFramed.STEP)
return ReFramed.STEP
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STEP.getDefaultState().with(EDGE, edge.getOpposite(face))
);
return false;
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getHalfLayerShape(
state.get(EDGE),
state.get(EDGE_FACE),
state.get(LAYERS)
);
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
BlockState state = super.getPlacementState(ctx);
if (previous.isOf(this))
return state;
if (previous.isOf(ReFramed.SLABS_HALF_LAYER) || previous.isOf(ReFramed.STEPS_HALF_LAYER))
return previous.with(LAYERS, Math.min(8, previous.get(LAYERS) + 1));
if (previous.isOf(ReFramed.SLAB)) {
Direction face = previous.get(FACING);
Edge edge;
if (face.getAxis() == ctx.getSide().getAxis()) {
edge = BlockHelper.getPlacementEdge(ctx);
if (face == ctx.getSide()) edge = edge.getOpposite(edge.getOtherDirection(ctx.getSide()));
} else edge = Edge.getByDirections(face, ctx.getSide().getOpposite());
return ReFramed.SLABS_HALF_LAYER.getDefaultState()
.with(EDGE, edge)
.with(EDGE_FACE, edge.getDirectionIndex(face))
.with(WATERLOGGED, previous.get(WATERLOGGED));
}
if (previous.isOf(ReFramed.STEP)) {
int face_index = 0;
Edge edge = previous.get(EDGE);
if (!ReFramed.STEP.matchesShape(
ctx.getHitPos(),
ctx.getBlockPos(),
ReFramed.STEP.getDefaultState().with(EDGE, edge.getOpposite(1))
)) face_index = 1;
return ReFramed.STEPS_HALF_LAYER.getDefaultState()
.with(EDGE, edge)
.with(EDGE_FACE, face_index)
.with(WATERLOGGED, previous.get(WATERLOGGED));
}
Edge edge = BlockHelper.getPlacementEdge(ctx);
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(ctx.getSide().getOpposite()));
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
Edge edge = state.get(EDGE);
Direction face = rotation.rotate(edge.getDirection(state.get(EDGE_FACE)));
edge = edge.rotate(rotation);
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(face));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
Edge edge = state.get(EDGE);
Direction face = mirror.apply(edge.getDirection(state.get(EDGE_FACE)));
edge = edge.mirror(mirror);
return state.with(EDGE, edge).with(EDGE_FACE, edge.getDirectionIndex(face));
}
@Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.SLABS_HALF_LAYER)
|| new_state.isOf(ReFramed.STEPS_HALF_LAYER)
) return Map.of(1, 2);
return super.getThemeMap(state, new_state);
}
public static VoxelShape getHalfLayerShape(Edge edge, int face, int layer) {
return HALF_LAYER_VOXELS[edge.ordinal() * 16 + face * 8 + layer - 1];
}
static {
VoxelListBuilder builder = VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 8, 2), 192)
.add(createCuboidShape(0, 0, 0, 16, 8, 4))
.add(createCuboidShape(0, 0, 0, 16, 8, 6))
.add(createCuboidShape(0, 0, 0, 16, 8, 8))
.add(createCuboidShape(0, 0, 0, 16, 8, 10))
.add(createCuboidShape(0, 0, 0, 16, 8, 12))
.add(createCuboidShape(0, 0, 0, 16, 8, 14))
.add(createCuboidShape(0, 0, 0, 16, 8, 16));
for (int i = 0; i < 8; i++) {
builder.add(i, VoxelHelper::rotateCX, VoxelHelper::mirrorZ);
}
for (int i = 0; i < 48; i++) {
builder.add(i, VoxelHelper::rotateCX);
}
for (int i = 0; i < 64; i++) {
builder.add(i, VoxelHelper::rotateCY);
}
for (int i = 64; i < 80; i++) {
builder.add(i, VoxelHelper::rotateX);
}
for (int i = 80; i < 96; i++) {
builder.add(i, VoxelHelper::rotateX);
}
for (int i = 96; i < 112; i++) {
builder.add(i, VoxelHelper::rotateX);
}
for (int i = 112; i < 128; i++) {
builder.add(i, VoxelHelper::rotateX);
}
HALF_LAYER_VOXELS = builder.build();
}
}

View File

@@ -0,0 +1,86 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import static net.minecraft.state.property.Properties.*;
public class ReFramedHalfSlabBlock extends ReFramedSlabBlock {
public static VoxelShape[] HALF_SLAB_SHAPES;
public ReFramedHalfSlabBlock(Settings settings) {
super(settings);
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
) return false;
// allow replacing with slab, step, small cube and half stair
Block block = block_item.getBlock();
if (block != this) return false;
// check if the player is clicking on the inner part of the block
return ReFramed.HALF_SLABS_SLAB
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.HALF_SLABS_SLAB.getDefaultState().with(FACING, state.get(FACING)),
2
);
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState current_state = ctx.getWorld().getBlockState(ctx.getBlockPos());
if (current_state.isOf(this))
return ReFramed.HALF_SLABS_SLAB.getDefaultState()
.with(FACING, current_state.get(FACING))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
return super.getPlacementState(ctx).with(FACING, ctx.getSide().getOpposite());
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getHalfSlabShape(state.get(FACING));
}
public static VoxelShape getHalfSlabShape(Direction direction) {
return HALF_SLAB_SHAPES[direction.getId()];
}
@Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.HALF_SLABS_SLAB)) return Map.of(1, 1);
return super.getThemeMap(state, new_state);
}
static {
HALF_SLAB_SHAPES = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 0, 0, 16, 4, 16),6)
.add(createCuboidShape(0, 12, 0, 16, 16, 16))
.add(createCuboidShape(0, 0, 0, 16, 16, 4))
.add(createCuboidShape(0, 0, 12, 16, 16, 16))
.add(createCuboidShape(0, 0, 0, 4, 16, 16))
.add(createCuboidShape(12, 0, 0, 16, 16, 16))
.build();
}
}

View File

@@ -0,0 +1,45 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
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 FacingDoubleReFramedBlock {
public static VoxelShape[] HALF_SLAB_COMP_SHAPES;
public ReFramedHalfSlabsSlabBlock(Settings settings) {
super(settings);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getSlabShape(state.get(FACING));
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Direction face = state.get(FACING);
return i == 2
? HALF_SLAB_COMP_SHAPES[face.getId()]
: getHalfSlabShape(face);
}
static {
HALF_SLAB_COMP_SHAPES = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 4, 0, 16, 8, 16),6)
.add(createCuboidShape(0, 8, 0, 16, 12, 16))
.add(createCuboidShape(0, 0, 4, 16, 16, 8))
.add(createCuboidShape(0, 0, 8, 16, 16, 12))
.add(createCuboidShape(4, 0, 0, 8, 16, 16))
.add(createCuboidShape(8, 0, 0, 12, 16, 16))
.build();
}
}

View File

@@ -25,6 +25,7 @@ import java.util.Map;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static net.minecraft.state.property.Properties.FACING;
import static net.minecraft.state.property.Properties.WATERLOGGED;
public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
@@ -42,39 +43,44 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false;
Direction dir = state.get(CORNER).getDirection(state.get(CORNER_FACE));
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| (
!(
block_item.getBlock() == this
&& ((ReFramedHalfStairsStairBlock) ReFramed.HALF_STAIRS_STAIR)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.HALF_STAIRS_STAIR.getDefaultState()
.with(EDGE, state.get(CORNER).getEdge(dir)),
dir.getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
&& !(
block_item.getBlock() == ReFramed.SMALL_CUBE
&& BlockHelper.cursorMatchesFace(
ReFramed.SMALL_CUBE.getOutlineShape(
ReFramed.SMALL_CUBE.getDefaultState()
.with(CORNER, state.get(CORNER).getOpposite(state.get(CORNER_FACE))),
context.getWorld(),
context.getBlockPos(),
ShapeContext.absent()
),
BlockHelper.getRelativePos(context.getHitPos(), context.getBlockPos())
)
)
)
);
if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
) return false;
// allow replacing with slab, step, small cube and half stair
Block block = block_item.getBlock();
Corner corner = state.get(CORNER);
Direction dir = corner.getDirection(state.get(CORNER_FACE));
if (block == this || block == ReFramed.STEP)
return ReFramed.HALF_STAIRS_STAIR.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.HALF_STAIRS_STAIR.getDefaultState().with(EDGE, corner.getEdge(dir)),
dir.getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
);
if (block == ReFramed.SMALL_CUBE)
return ReFramed.SMALL_CUBE.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBE.getDefaultState().with(CORNER, corner.change(dir))
) || ReFramed.SMALL_CUBE.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBE.getDefaultState().with(CORNER, corner.getOpposite(dir))
);
if (block == ReFramed.SLAB)
return ReFramed.SLAB.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SLAB.getDefaultState().with(FACING, dir.getOpposite())
);
return false;
}
@Override
@@ -92,6 +98,15 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
return ReFramed.HALF_STAIRS_STAIR.getDefaultState()
.with(EDGE, current_state.get(CORNER).getEdge(current_state.get(CORNER).getDirection(current_state.get(CORNER_FACE))))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
if (current_state.isOf(ReFramed.SLAB)) {
Corner corner = BlockHelper.getPlacementCorner(ctx);
Direction face = current_state.get(FACING);
if (!corner.hasDirection(face)) corner = corner.change(face.getOpposite());
return ReFramed.SLABS_INNER_STAIR.getDefaultState()
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(face))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
Corner corner = BlockHelper.getPlacementCorner(ctx);
return super.getPlacementState(ctx)
@@ -100,11 +115,13 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return HALF_STAIR_VOXELS[state.get(CORNER_FACE) + state.get(CORNER).getID() * 3];
return getHalfStairShape(state.get(CORNER), state.get(CORNER_FACE));
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
Corner corner = state.get(CORNER).rotate(rotation);
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
@@ -112,6 +129,7 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
Corner corner = state.get(CORNER).mirror(mirror);
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
@@ -120,7 +138,11 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
@Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)) return Map.of(1, 1);
if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)
|| new_state.isOf(ReFramed.HALF_STAIRS_CUBE_STAIR)
|| new_state.isOf(ReFramed.HALF_STAIRS_STEP_STAIR)
) return Map.of(1, 1);
if (new_state.isOf(ReFramed.SLABS_INNER_STAIR)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.HALF_STAIRS_STAIR))
return Map.of(
1,
@@ -131,6 +153,10 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
return super.getThemeMap(state, new_state);
}
public static VoxelShape getHalfStairShape(Corner corner, int face) {
return HALF_STAIR_VOXELS[face + corner.getID() * 3];
}
static {
final VoxelShape HALF_STAIR = VoxelShapes.combineAndSimplify(
createCuboidShape(8, 0, 0, 16, 16, 8),

View File

@@ -0,0 +1,48 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.getSmallCubeShape;
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
public class ReFramedHalfStairsCubeStairBlock extends CornerDoubleReFramedBlock {
public ReFramedHalfStairsCubeStairBlock(Settings settings) {
super(settings);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
Edge edge = corner.getEdge(face);
return getStairShape(
edge,
face.getDirection() == Direction.AxisDirection.POSITIVE
? StairShape.OUTER_LEFT
: StairShape.OUTER_RIGHT
);
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
if (i == 2) corner = corner.change(face);
return i == 2
? getSmallCubeShape(corner)
: getHalfStairShape(corner, state.get(CORNER_FACE));
}
}

View File

@@ -15,13 +15,12 @@ import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOXELS;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS;
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.getSmallCubeShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
import static fr.adrien1106.reframed.util.blocks.Corner.NORTH_EAST_DOWN;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock {
@@ -44,16 +43,13 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return isGhost(view, pos) ? empty(): getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE)));
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
Corner corner = state.get(CORNER).rotate(rotation);
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
@@ -61,6 +57,7 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
Corner corner = state.get(CORNER).mirror(mirror);
Direction face = state.get(CORNER).getDirection(state.get(CORNER_FACE));
@@ -72,7 +69,7 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
Corner corner = state.get(CORNER);
int face = state.get(CORNER_FACE);
return i == 2
? SMALL_CUBE_VOXELS[corner.getOpposite(face).getID()]
: HALF_STAIR_VOXELS[face + corner.getID() * 3];
? getSmallCubeShape(corner.getOpposite(face))
: getHalfStairShape(corner, face);
}
}

View File

@@ -17,11 +17,10 @@ import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.HALF_STAIR_VOXELS;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlock {
public ReFramedHalfStairsStairBlock(Settings settings) {
@@ -41,21 +40,19 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return isGhost(view, pos) ? empty(): getStairShape(state.get(EDGE), StairShape.STRAIGHT);
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getStairShape(state.get(EDGE), StairShape.STRAIGHT);
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(EDGE, state.get(EDGE).rotate(rotation));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(EDGE, state.get(EDGE).mirror(mirror));
}
@@ -72,7 +69,7 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
side
);
return HALF_STAIR_VOXELS[corner.getID() * 3 + corner.getDirectionIndex(side)];
return getHalfStairShape(corner, corner.getDirectionIndex(side));
}
@Override

View File

@@ -0,0 +1,76 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.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.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
public class ReFramedHalfStairsStepStairBlock extends CornerDoubleReFramedBlock {
public ReFramedHalfStairsStepStairBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(CORNER_FEATURE, 0));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER_FEATURE));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState state = super.getPlacementState(ctx);
Corner corner = state.get(CORNER);
int face_index = state.get(CORNER_FACE);
Direction face = corner.getDirection(face_index);
face = BlockHelper.getPlacementEdge(ctx).getOtherDirection(face);
int feature_index = corner.getDirectionIndex(face);
return state.with(CORNER_FEATURE, feature_index > face_index ? feature_index - 1 : feature_index);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
Corner corner = state.get(CORNER);
int feature_index = state.get(CORNER_FEATURE), face_index = state.get(CORNER_FACE);
Direction feature_face = corner.getDirection(feature_index >= face_index ? feature_index + 1 : feature_index);
Direction face = corner.getDirection(face_index);
Edge edge = Edge.getByDirections(feature_face, face);
return getStairShape(
edge,
corner.getOtherDirection(edge).getDirection() == Direction.AxisDirection.POSITIVE
? edge.getDirectionIndex(face) == 0
? StairShape.FIRST_OUTER_LEFT
: StairShape.SECOND_OUTER_LEFT
: edge.getDirectionIndex(face) == 0
? StairShape.FIRST_OUTER_RIGHT
: StairShape.SECOND_OUTER_RIGHT
);
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Corner corner = state.get(CORNER);
int feature_index = state.get(CORNER_FEATURE), face_index = state.get(CORNER_FACE);
Direction feature_face = corner.getDirection(feature_index >= face_index ? feature_index + 1 : feature_index);
Direction face = corner.getDirection(face_index);
return i == 2
? getStepShape(Edge.getByDirections(face.getOpposite(), feature_face))
: getHalfStairShape(corner, face_index);
}
}

View File

@@ -1,79 +1,72 @@
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.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 java.util.List;
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 ReFramedSlabBlock {
public class ReFramedLayerBlock extends LayeredReFramedBlock {
public static final VoxelShape[] LAYER_VOXELS;
public ReFramedLayerBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(LAYERS, 1));
}
@Override
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
List<ItemStack> drops = super.getDroppedStacks(state, builder);
drops.forEach((stack) -> {
if (stack.getItem() instanceof BlockItem bi && bi.getBlock() instanceof ReFramedLayerBlock)
stack.setCount(state.get(LAYERS));
});
return drops;
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(LAYERS));
super.appendProperties(builder.add(FACING));
}
@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));
}
@Override
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false;
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(block_item.getBlock() == this && state.get(LAYERS) < 8)
);
public static VoxelShape getLayerShape(Direction facing, int layers) {
return LAYER_VOXELS[facing.getId() * 8 + layers - 1];
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
if (!previous.isOf(this)) return super.getPlacementState(ctx);
return previous.with(LAYERS, previous.get(LAYERS) + 1);
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());
}
@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)));
}

View File

@@ -71,13 +71,6 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
return getWallState(state, top_state, neighbors, top_shape, fs, world, pos);
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
if (isGhost(view, pos)) return empty();
@@ -95,6 +88,7 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
VoxelShape shape = WALL_VOXELS[0];
for (Direction dir: Direction.Type.HORIZONTAL) {
@@ -106,6 +100,7 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getWallShape(rotation.rotate(dir)), state.get(getWallShape(dir)))
@@ -113,6 +108,7 @@ public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getWallShape(mirror.apply(dir)), state.get(getWallShape(dir)))

View File

@@ -49,13 +49,6 @@ public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock {
super.appendProperties(builder.add(EAST, NORTH, SOUTH, WEST));
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction dir, BlockState other_state, WorldAccess world, BlockPos pos, BlockPos moved) {
BlockState new_state = super.getStateForNeighborUpdate(state, dir, other_state, world, pos, moved);
@@ -74,6 +67,7 @@ public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getConnectionProperty(rotation.rotate(dir)), state.get(getConnectionProperty(dir)))
@@ -81,6 +75,7 @@ public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getConnectionProperty(mirror.apply(dir)), state.get(getConnectionProperty(dir)))
@@ -104,6 +99,7 @@ public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
VoxelShape shape = FENCE_VOXELS[0];
for (Direction dir: Direction.Type.HORIZONTAL) {
@@ -124,6 +120,7 @@ public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getCameraCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getOutlineShape(state, world, pos, context);
}
@@ -134,6 +131,7 @@ public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
return false;
}

View File

@@ -1,6 +1,9 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
@@ -18,8 +21,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.Map;
import static net.minecraft.state.property.Properties.AXIS;
import static net.minecraft.state.property.Properties.FACING;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static net.minecraft.state.property.Properties.*;
public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
@@ -41,46 +44,134 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false;
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(
block_item.getBlock() == this
&& ((ReFramedSlabsCubeBlock) ReFramed.SLABS_CUBE)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SLABS_CUBE.getDefaultState().with(AXIS, state.get(FACING).getAxis()),
state.get(FACING).getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
);
if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
) return false;
// allow replacing with slab, step, small cube and half stair
Block block = block_item.getBlock();
if (block != this
&& block != ReFramed.STEP
&& 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 matchesShape(
context.getHitPos(),
context.getBlockPos(),
state.with(FACING, state.get(FACING).getOpposite())
);
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockState current_state = ctx.getWorld().getBlockState(ctx.getBlockPos());
if (current_state.isOf(this))
return ReFramed.SLABS_CUBE.getDefaultState()
.with(AXIS, current_state.get(FACING).getAxis());
if (current_state.isOf(ReFramed.HALF_LAYER)) {
Edge edge = current_state.get(EDGE);
Direction face = edge.getDirection(current_state.get(EDGE_FACE));
edge = edge.getOpposite(face);
return ReFramed.SLABS_HALF_LAYER.getDefaultState()
.with(EDGE, edge)
.with(EDGE_FACE, edge.getDirectionIndex(edge.getOtherDirection(face)))
.with(LAYERS, current_state.get(LAYERS))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(ReFramed.HALF_STAIR)) {
Corner corner = current_state.get(CORNER);
Direction face = corner.getDirection(current_state.get(CORNER_FACE));
corner = corner.change(face);
return ReFramed.SLABS_INNER_STAIR.getDefaultState()
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(face.getOpposite()))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(ReFramed.STEP)) {
Edge edge = current_state.get(EDGE),
placed = BlockHelper.getPlacementEdge(ctx),
new_edge;
Direction face = edge.getFirstDirection(),
other = edge.getSecondDirection().getOpposite();
if (!ReFramed.STEP.matchesShape(
ctx.getHitPos(),
ctx.getBlockPos(),
current_state.with(EDGE, new_edge = edge.getOpposite(face))
)
&& ctx.getSide() != other.getOpposite()
&& (placed.getAxis() == edge.getAxis()
|| ctx.getSide() == other
|| !placed.hasDirection(other))
) {
new_edge = edge.getOpposite(edge.getSecondDirection());
other = edge.getFirstDirection().getOpposite();
}
return ReFramed.SLABS_STAIR.getDefaultState()
.with(EDGE, new_edge)
.with(EDGE_FACE, new_edge.getDirectionIndex(other))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(ReFramed.SMALL_CUBE)) {
Corner corner = current_state.get(CORNER);
Edge placed = BlockHelper.getPlacementEdge(ctx);
Direction face;
Corner new_corner;
if (!corner.hasDirection(face = ctx.getSide())) {
int i = 0;
do {
face = corner.getDirection(i);
new_corner = corner.change(face);
} while (!ReFramed.SMALL_CUBE.matchesShape(
ctx.getHitPos(),
ctx.getBlockPos(),
current_state.with(CORNER, new_corner)
) && ++i < 3);
if (i == 3) {
face = placed.getOtherDirection(corner.getMatchingDirection(placed)).getOpposite();
new_corner = corner.change(face);
}
} else new_corner = corner.change(face);
return ReFramed.SLABS_OUTER_STAIR.getDefaultState()
.with(CORNER, new_corner)
.with(CORNER_FACE, new_corner.getDirectionIndex(face.getOpposite()))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
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)));
}
@@ -98,6 +189,11 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
@Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.SLABS_STAIR)
|| new_state.isOf(ReFramed.SLABS_OUTER_STAIR)
|| new_state.isOf(ReFramed.SLABS_INNER_STAIR)
|| new_state.isOf(ReFramed.SLABS_HALF_LAYER)
) return Map.of(1, 1);
if (new_state.isOf(ReFramed.SLABS_CUBE)) return Map.of(1, state.get(FACING).getDirection() == Direction.AxisDirection.POSITIVE ? 2 : 1);
return super.getThemeMap(state, new_state);
}

View File

@@ -11,7 +11,6 @@ import net.minecraft.util.shape.VoxelShape;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.*;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static net.minecraft.state.property.Properties.AXIS;
public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock {
@@ -33,11 +32,13 @@ public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(AXIS, mirror.apply(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis());
}

View File

@@ -0,0 +1,62 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.Edge;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import static fr.adrien1106.reframed.block.ReFramedHalfLayerBlock.getHalfLayerShape;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
import static net.minecraft.state.property.Properties.LAYERS;
public class ReFramedSlabsHalfLayerBlock extends HalfLayerDoubleReFramedBlock {
private static final VoxelShape[] SLABS_HALF_LAYER_VOXELS = new VoxelShape[196];
public ReFramedSlabsHalfLayerBlock(Settings settings) {
super(settings);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getSlabsHalfLayerShape(state.get(EDGE), state.get(EDGE_FACE), state.get(LAYERS));
}
public static VoxelShape getSlabsHalfLayerShape(Edge edge, int face, int layers) {
int i = edge.ordinal() * 16 + face * 8 + layers - 1;
VoxelShape shape = SLABS_HALF_LAYER_VOXELS[i];
if (shape == null) {
shape = VoxelShapes.combineAndSimplify(
getShape(edge, edge.getDirection(face), layers, 1),
getShape(edge, edge.getDirection(face), layers, 2),
BooleanBiFunction.OR
);
SLABS_HALF_LAYER_VOXELS[i] = shape;
}
return shape;
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Edge edge = state.get(EDGE);
Direction face = edge.getDirection(state.get(EDGE_FACE));
return getShape(edge, face, state.get(LAYERS), i);
}
private static VoxelShape getShape(Edge edge, Direction face, int layers, int i) {
if (i == 2) {
face = edge.getOtherDirection(face);
edge = edge.getOpposite(face);
}
return i == 2
? getHalfLayerShape(edge, edge.getDirectionIndex(face), layers)
: getSlabShape(face);
}
}

View File

@@ -0,0 +1,48 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import static fr.adrien1106.reframed.block.ReFramedHalfStairBlock.getHalfStairShape;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
public class ReFramedSlabsInnerStairBlock extends CornerDoubleReFramedBlock {
public ReFramedSlabsInnerStairBlock(Settings settings) {
super(settings);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
Edge edge = corner.getEdge(face);
return getStairShape(
edge,
face.getDirection() == Direction.AxisDirection.POSITIVE
? StairShape.INNER_LEFT
: StairShape.INNER_RIGHT
);
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
if (i == 2) corner = corner.change(face);
return i == 2
? getHalfStairShape(corner, corner.getDirectionIndex(face.getOpposite()))
: getSlabShape(face);
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,51 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.getSmallCubeShape;
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
public class ReFramedSlabsOuterStairBlock extends CornerDoubleReFramedBlock {
public ReFramedSlabsOuterStairBlock(Settings settings) {
super(settings);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
Edge edge = corner.getEdgeWith(face);
return getStairShape(
edge,
corner.getOtherDirection(edge).getDirection() == Direction.AxisDirection.POSITIVE
? edge.getDirectionIndex(face) == 1
? StairShape.FIRST_OUTER_LEFT
: StairShape.SECOND_OUTER_LEFT
: edge.getDirectionIndex(face) == 1
? StairShape.FIRST_OUTER_RIGHT
: StairShape.SECOND_OUTER_RIGHT
);
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE));
return i == 2
? getSmallCubeShape(corner.change(face))
: getSlabShape(face);
}
}

View File

@@ -0,0 +1,37 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.block.ReFramedStairBlock.getStairShape;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
public class ReFramedSlabsStairBlock extends EdgeDoubleReFramedBlock {
public ReFramedSlabsStairBlock(Settings settings) {
super(settings);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getStairShape(state.get(EDGE), StairShape.STRAIGHT);
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Edge edge = state.get(EDGE);
Direction face = edge.getDirection(state.get(EDGE_FACE));
return i == 2
? getStepShape(edge.getOpposite(edge.getOtherDirection(face)))
: getSlabShape(face);
}
}

View File

@@ -4,6 +4,8 @@ import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
@@ -25,6 +27,7 @@ import java.util.Map;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.Corner.*;
import static net.minecraft.state.property.Properties.FACING;
import static net.minecraft.state.property.Properties.WATERLOGGED;
public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
@@ -42,64 +45,73 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false;
if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
) return false;
Block block = block_item.getBlock();
Corner corner = state.get(CORNER);
return !(
context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| (
!(
block_item.getBlock() == ReFramed.HALF_STAIR
&& !(corner.hasDirection(context.getSide())
|| (corner.hasDirection(context.getSide().getOpposite())
&& BlockHelper.cursorMatchesFace(
getOutlineShape(state, context.getWorld(), context.getBlockPos(), null),
BlockHelper.getRelativePos(context.getHitPos(), context.getBlockPos())
)
)
)
if (block == this)
return matchesShape(
context.getHitPos(),
context.getBlockPos(),
getDefaultState().with(CORNER, corner.change(corner.getFirstDirection()))
) || matchesShape(
context.getHitPos(),
context.getBlockPos(),
getDefaultState().with(CORNER, corner.change(corner.getSecondDirection()))
) || matchesShape(
context.getHitPos(),
context.getBlockPos(),
getDefaultState().with(CORNER, corner.change(corner.getThirdDirection()))
);
if (block == ReFramed.HALF_STAIR || block == ReFramed.SLAB) {
corner = corner.getOpposite();
Direction face = corner.getFirstDirection();
Edge edge = corner.getEdge(face);
if (ReFramed.STAIR.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STAIR.getDefaultState()
.with(EDGE, edge)
.with(
STAIR_SHAPE,
face.getDirection() == Direction.AxisDirection.POSITIVE
? StairShape.INNER_LEFT
: StairShape.INNER_RIGHT
)
&& !(
block_item.getBlock() == this
&& (
((ReFramedSmallCubesStepBlock) ReFramed.SMALL_CUBES_STEP)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getFirstDirection())),
corner.getFirstDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ((ReFramedSmallCubesStepBlock) ReFramed.SMALL_CUBES_STEP)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getSecondDirection())),
corner.getSecondDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ((ReFramedSmallCubesStepBlock) ReFramed.SMALL_CUBES_STEP)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getThirdDirection())),
corner.getThirdDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
)
)
);
)) return block == ReFramed.SLAB || !matchesShape(
context.getHitPos(),
context.getBlockPos(),
getDefaultState().with(CORNER, corner)
);
}
return false;
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
BlockPos pos = ctx.getBlockPos();
BlockState current_state = ctx.getWorld().getBlockState(pos);
if (current_state.isOf(ReFramed.HALF_STAIR))
return ReFramed.HALF_STAIRS_SLAB.getDefaultState()
if (current_state.isOf(ReFramed.HALF_STAIR)) {
BlockState new_state;
Direction face = current_state.get(CORNER).getDirection(current_state.get(CORNER_FACE));
if (matchesShape(
ctx.getHitPos(), pos,
getDefaultState().with(CORNER, current_state.get(CORNER).change(face))
)) new_state = ReFramed.HALF_STAIRS_CUBE_STAIR.getDefaultState();
else new_state = ReFramed.HALF_STAIRS_SLAB.getDefaultState();
return new_state
.with(CORNER, current_state.get(CORNER))
.with(CORNER_FACE, current_state.get(CORNER_FACE))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(this)) {
Vec3d hit = ctx.getHitPos();
@@ -120,27 +132,42 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
return state.with(EDGE, corner.getEdge(corner.getThirdDirection()));
}
if (current_state.isOf(ReFramed.SLAB)) {
Corner corner = BlockHelper.getPlacementCorner(ctx);
Direction face = current_state.get(FACING);
if (!corner.hasDirection(face)) corner = corner.change(face.getOpposite());
return ReFramed.SLABS_OUTER_STAIR.getDefaultState()
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(face))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
return super.getPlacementState(ctx).with(CORNER, BlockHelper.getPlacementCorner(ctx));
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SMALL_CUBE_VOXELS[state.get(CORNER).getID()];
return getSmallCubeShape(state.get(CORNER));
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(CORNER, state.get(CORNER).rotate(rotation));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(CORNER, state.get(CORNER).mirror(mirror));
}
@Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)
|| new_state.isOf(ReFramed.SLABS_OUTER_STAIR)
) return Map.of(1, 2);
if (new_state.isOf(ReFramed.SMALL_CUBES_STEP))
return Map.of(
1,
@@ -151,6 +178,10 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
return super.getThemeMap(state, new_state);
}
public static VoxelShape getSmallCubeShape(Corner corner) {
return SMALL_CUBE_VOXELS[corner.getID()];
}
static {
final VoxelShape SMALL_CUBE = VoxelShapes.cuboid(.5f, 0f, 0f, 1f, .5f, .5f);

View File

@@ -18,7 +18,6 @@ import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedSmallCubeBlock.SMALL_CUBE_VOXELS;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBlock {
@@ -39,21 +38,19 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return isGhost(view, pos) ? empty(): getStepShape(state.get(EDGE));
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getStepShape(state.get(EDGE));
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(EDGE, state.get(EDGE).rotate(rotation));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(EDGE, state.get(EDGE).mirror(mirror));
}

View File

@@ -19,7 +19,6 @@ import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import org.jetbrains.annotations.Nullable;
@@ -45,6 +44,7 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false;
return !(
@@ -52,7 +52,7 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| !(
block_item.getBlock() == ReFramed.STEP
&& ((ReFramedStairsCubeBlock) ReFramed.STAIRS_CUBE)
&& ReFramed.STAIRS_CUBE
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
@@ -87,18 +87,13 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getStairShape(state.get(EDGE), state.get(STAIR_SHAPE));
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
Edge prev_edge = state.get(EDGE);
Edge edge = prev_edge.rotate(rotation);
@@ -115,6 +110,7 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
Edge prev_edge = state.get(EDGE);
Edge edge = prev_edge.mirror(mirror);

View File

@@ -12,7 +12,6 @@ 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.World;
import net.minecraft.world.WorldAccess;
import org.jetbrains.annotations.Nullable;
@@ -36,6 +35,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
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)
.with(STAIR_SHAPE, BlockHelper.getStairsShape(state.get(EDGE), world, pos));
@@ -52,6 +52,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
Edge prev_edge = state.get(EDGE);
Edge edge = prev_edge.rotate(rotation);
@@ -68,6 +69,7 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
Edge prev_edge = state.get(EDGE);
Edge edge = prev_edge.mirror(mirror);
@@ -76,13 +78,6 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
.with(EDGE, edge);
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Edge edge = state.get(EDGE);

View File

@@ -3,6 +3,7 @@ package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -22,10 +23,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.Map;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
import static net.minecraft.state.property.Properties.*;
import static net.minecraft.state.property.Properties.WATERLOGGED;
public class ReFramedStepBlock extends WaterloggableReFramedBlock {
@@ -42,49 +42,38 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false;
Edge edge = state.get(EDGE);
return !(
context.getPlayer().isSneaking()
if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
|| (
!(
block_item.getBlock() == ReFramed.STAIR
&& ((ReFramedStairsCubeBlock) ReFramed.STAIRS_CUBE)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STAIRS_CUBE.getDefaultState().with(EDGE, edge.opposite()),
1
)
) return false;
)
&& !(
block_item.getBlock() == this
&& (
((ReFramedStepsSlabBlock) ReFramed.STEPS_SLAB)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STEPS_SLAB.getDefaultState()
.with(FACING, edge.getFirstDirection())
.with(AXIS, edge.getSecondDirection().getAxis()),
edge.getSecondDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ((ReFramedStepsSlabBlock) ReFramed.STEPS_SLAB)
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STEPS_SLAB.getDefaultState()
.with(FACING, edge.getSecondDirection())
.with(AXIS, edge.getFirstDirection().getAxis()),
edge.getFirstDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
)
)
);
Block block = block_item.getBlock();
Edge edge = state.get(EDGE);
if (block == ReFramed.HALF_LAYER)
return matchesShape(
context.getHitPos(),
context.getBlockPos(),
getDefaultState().with(EDGE, edge.getOpposite(edge.getFirstDirection()))
) || matchesShape(
context.getHitPos(),
context.getBlockPos(),
getDefaultState().with(EDGE, edge.getOpposite(edge.getSecondDirection()))
);
// allow replacing with stair
if (block != this
&& block != ReFramed.STAIR
&& block != ReFramed.SLAB
) return false;
return ReFramed.STAIR
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STAIRS_CUBE.getDefaultState().with(EDGE, edge.opposite())
);
}
@Nullable
@@ -92,6 +81,7 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
public BlockState getPlacementState(ItemPlacementContext ctx) {
BlockPos pos = ctx.getBlockPos();
BlockState current_state = ctx.getWorld().getBlockState(pos);
if (current_state.isOf(ReFramed.STAIR))
return ReFramed.STAIRS_CUBE.getDefaultState()
.with(EDGE, current_state.get(EDGE))
@@ -101,39 +91,91 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
if (current_state.isOf(this)) {
Vec3d hit = ctx.getHitPos();
Edge edge = current_state.get(EDGE);
Direction dir = edge.getFirstDirection();
ReFramedStepsSlabBlock block = ((ReFramedStepsSlabBlock) ReFramed.STEPS_SLAB);
BlockState state = block.getDefaultState()
.with(FACING, dir)
.with(AXIS, edge.getOtherDirection(dir).getAxis())
// Steps Slab
if (matchesShape(hit, pos,
current_state.with(EDGE, edge.getOpposite(edge.getFirstDirection()))
)) return ReFramed.STEPS_SLAB.getDefaultState()
.with(FACING, edge.getFirstDirection())
.with(AXIS, edge.getSecondDirection().getAxis())
.with(WATERLOGGED, current_state.get(WATERLOGGED));
else if (matchesShape(hit, pos,
current_state.with(EDGE, edge.getOpposite(edge.getSecondDirection()))
)) return ReFramed.STEPS_SLAB.getDefaultState()
.with(FACING, edge.getSecondDirection())
.with(AXIS, edge.getFirstDirection().getAxis())
.with(WATERLOGGED, current_state.get(WATERLOGGED));
// Steps Cross
return ReFramed.STEPS_CROSS.getDefaultState()
.with(EDGE, edge)
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(ReFramed.SLAB)) {
Direction facing = current_state.get(FACING);
Edge edge;
// Slabs Stair
if (ctx.getSide() == facing || ctx.getSide() == facing.getOpposite())
edge = BlockHelper.getPlacementEdge(ctx);
else
edge = Edge.getByDirections(facing, ctx.getSide().getOpposite());
return ReFramed.SLABS_STAIR.getDefaultState()
.with(EDGE, edge)
.with(EDGE_FACE, edge.getDirectionIndex(facing));
}
if (current_state.isOf(ReFramed.HALF_STAIR)) {
Corner corner = current_state.get(CORNER);
int face_index = current_state.get(CORNER_FACE), feature_index;
Direction face = corner.getDirection(current_state.get(CORNER_FACE));
Direction side = ctx.getSide().getOpposite();
if (side.getAxis() == face.getAxis())
side = BlockHelper.getPlacementEdge(ctx).getOtherDirection(face == side ? face : face.getOpposite());
if (side.getAxis() != face.getAxis() && !corner.hasDirection(side))
side = corner.getOtherDirection(Edge.getByDirections(face, side.getOpposite()));
feature_index = corner.getDirectionIndex(side);
return ReFramed.HALF_STAIRS_STEP_STAIR.getDefaultState()
.with(CORNER, corner)
.with(CORNER_FACE, face_index)
.with(CORNER_FEATURE, feature_index > face_index ? feature_index - 1 : feature_index)
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(ReFramed.HALF_LAYER)) {
Edge edge = current_state.get(EDGE);
Direction face = edge.getDirection(current_state.get(EDGE_FACE));
edge = edge.getOpposite(face);
return ReFramed.STEPS_HALF_LAYER.getDefaultState()
.with(EDGE, edge)
.with(EDGE_FACE, edge.getDirectionIndex(edge.getOtherDirection(face)))
.with(LAYERS, current_state.get(LAYERS))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
if (!block.matchesShape(
hit, pos,
state,
edge.getOtherDirection(dir).getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)) {
dir = edge.getSecondDirection();
state = state
.with(FACING, dir)
.with(AXIS, edge.getOtherDirection(dir).getAxis());
}
return state;
}
return super.getPlacementState(ctx).with(EDGE, BlockHelper.getPlacementEdge(ctx));
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getStepShape(state.get(EDGE));
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(EDGE, state.get(EDGE).rotate(rotation));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(EDGE, state.get(EDGE).mirror(mirror));
}
@@ -144,7 +186,11 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
@Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.STAIRS_CUBE)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.STEPS_CROSS)
|| new_state.isOf(ReFramed.STEPS_HALF_LAYER)
) return Map.of(1, 1);
if (new_state.isOf(ReFramed.STAIRS_CUBE)
|| new_state.isOf(ReFramed.SLABS_STAIR)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.STEPS_SLAB))
return Map.of(
1,

View File

@@ -0,0 +1,86 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Edge;
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.function.BooleanBiFunction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
public class ReFramedStepsCrossBlock extends WaterloggableReFramedDoubleBlock {
public static VoxelShape[] STEP_CROSS_VOXELS;
public ReFramedStepsCrossBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
Edge edge = BlockHelper.getPlacementCorner(ctx).getEdge(ctx.getSide().getOpposite());
return super.getPlacementState(ctx).with(EDGE, edge);
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return STEP_CROSS_VOXELS[state.get(EDGE).ordinal()];
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(EDGE, state.get(EDGE).rotate(rotation));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(EDGE, state.get(EDGE).mirror(mirror));
}
@Override
public VoxelShape getShape(BlockState state, int i) {
return getStepShape(i == 1 ? state.get(EDGE): state.get(EDGE).opposite());
}
static {
VoxelShape STEP_CROSS = VoxelShapes.combineAndSimplify(
getStepShape(Edge.NORTH_DOWN),
getStepShape(Edge.SOUTH_UP),
BooleanBiFunction.OR
);
STEP_CROSS_VOXELS = VoxelHelper.VoxelListBuilder.create(STEP_CROSS, 12)
.add(VoxelHelper::rotateX)
.add(VoxelHelper::rotateX)
.add(VoxelHelper::rotateX)
.add(0, VoxelHelper::rotateCY)
.add(VoxelHelper::rotateZ)
.add(VoxelHelper::rotateZ)
.add(VoxelHelper::rotateZ)
.add(0, VoxelHelper::rotateCZ)
.add(VoxelHelper::rotateY)
.add(VoxelHelper::rotateY)
.add(VoxelHelper::rotateY)
.build();
}
}

View File

@@ -0,0 +1,62 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.blocks.Edge;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import static fr.adrien1106.reframed.block.ReFramedHalfLayerBlock.getHalfLayerShape;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
import static net.minecraft.state.property.Properties.LAYERS;
public class ReFramedStepsHalfLayerBlock extends HalfLayerDoubleReFramedBlock {
private static final VoxelShape[] SLABS_HALF_LAYER_VOXELS = new VoxelShape[196];
public ReFramedStepsHalfLayerBlock(Settings settings) {
super(settings);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getStepsHalfLayerShape(state.get(EDGE), state.get(EDGE_FACE), state.get(LAYERS));
}
public static VoxelShape getStepsHalfLayerShape(Edge edge, int face, int layers) {
int i = edge.ordinal() * 16 + face * 8 + layers - 1;
VoxelShape shape = SLABS_HALF_LAYER_VOXELS[i];
if (shape == null) {
shape = VoxelShapes.combineAndSimplify(
getShape(edge, edge.getDirection(face), layers, 1),
getShape(edge, edge.getDirection(face), layers, 2),
BooleanBiFunction.OR
);
SLABS_HALF_LAYER_VOXELS[i] = shape;
}
return shape;
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Edge edge = state.get(EDGE);
Direction face = edge.getDirection(state.get(EDGE_FACE));
return getShape(edge, face, state.get(LAYERS), i);
}
private static VoxelShape getShape(Edge edge, Direction face, int layers, int i) {
if (i == 2) {
face = edge.getOtherDirection(face);
edge = edge.getOpposite(face);
}
return i == 2
? getHalfLayerShape(edge, edge.getDirectionIndex(face), layers)
: getStepShape(edge);
}
}

View File

@@ -21,7 +21,6 @@ import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.block.ReFramedStepBlock.getStepShape;
import static net.minecraft.state.property.Properties.AXIS;
import static net.minecraft.state.property.Properties.FACING;
import static net.minecraft.util.shape.VoxelShapes.empty;
public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
@@ -44,16 +43,13 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return isGhost(view, pos) ? empty() : getSlabShape(state.get(FACING));
}
@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(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis())
@@ -61,6 +57,7 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
if (state.get(FACING).getAxis() != Axis.Y)
return state.with(FACING, mirror.apply(state.get(FACING)));

View File

@@ -48,6 +48,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block source, BlockPos sourcePos, boolean notify) {
if (world.isClient) return;
boolean powered = world.isReceivingRedstonePower(pos);
@@ -83,13 +84,6 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
return state;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult result = super.onUse(state, world, pos, player, hand, hit);
@@ -99,6 +93,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
return switch (type) {
case LAND, AIR -> state.get(OPEN);
@@ -107,6 +102,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stack_merger) {
if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK
&& !world.isClient()
@@ -129,6 +125,7 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
int index;
if (!state.get(OPEN)) index = state.get(BLOCK_HALF) == BlockHalf.BOTTOM ? 0 : 1;
@@ -137,11 +134,13 @@ public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING)));
}

View File

@@ -80,13 +80,7 @@ public class ReFramedWallBlock extends WaterloggableReFramedBlock {
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState new_state, boolean moved) {
super.onStateReplaced(state, world, pos, new_state, moved);
if(!state.isOf(new_state.getBlock())) world.removeBlockEntity(pos);
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
VoxelShape shape = state.get(UP) ? WALL_VOXELS[0]: VoxelShapes.empty();
for (Direction dir : Direction.Type.HORIZONTAL) {
@@ -109,6 +103,7 @@ public class ReFramedWallBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getWallShape(rotation.rotate(dir)), state.get(getWallShape(dir)))
@@ -116,6 +111,7 @@ public class ReFramedWallBlock extends WaterloggableReFramedBlock {
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) ->
s.with(getWallShape(mirror.apply(dir)), state.get(getWallShape(dir)))

View File

@@ -0,0 +1,36 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.client.voxel.MorphVoxel;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
public class TestBlock extends Block {
public static MorphVoxel voxel = new MorphVoxel(createCuboidShape(1, 1, 1, 15, 15, 15),
new Vec3d[] {
new Vec3d(0, 0, 0),
new Vec3d(1, 0, 0),
new Vec3d(1, 1, 1),
new Vec3d(0, 1, 1),
new Vec3d(0, 1, 1),
new Vec3d(1, 1, 1),
new Vec3d(1, 0, 1),
new Vec3d(0, 0, 1)
});
public TestBlock(Settings settings) {
super(settings);
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return voxel;
}
}

View File

@@ -33,10 +33,13 @@ public class WaterloggableReFramedBlock extends ReFramedBlock implements Waterlo
}
@Override
@SuppressWarnings("deprecation")
public FluidState getFluidState(BlockState state) {
return state.get(Properties.WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
}
@Override
@SuppressWarnings("deprecation")
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState otherState, WorldAccess world, BlockPos pos, BlockPos moved) {
if(state.get(Properties.WATERLOGGED)) world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
return super.getStateForNeighborUpdate(state, direction, otherState, world, pos, moved);

View File

@@ -33,10 +33,13 @@ public class WaterloggableReFramedDoubleBlock extends ReFramedDoubleBlock implem
}
@Override
@SuppressWarnings("deprecation")
public FluidState getFluidState(BlockState state) {
return state.get(Properties.WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
}
@Override
@SuppressWarnings("deprecation")
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState otherState, WorldAccess world, BlockPos pos, BlockPos moved) {
if(state.get(Properties.WATERLOGGED)) world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
return super.getStateForNeighborUpdate(state, direction, otherState, world, pos, moved);

View File

@@ -27,149 +27,231 @@ public class ReFramedClient implements ClientModInitializer {
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
// CUBE
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube")));
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube")));
// SMALL_CUBE
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base")));
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base")));
// SMALL_CUBES_STEP
HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base")));
HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base")));
HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base")));
HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base")));
// SLAB
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab")));
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab")));
// SLAB_CUBE
HELPER.addReFramedModel("double_slab" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top")));
HELPER.addReFramedModel("double_slab" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top")));
// STAIR
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight")));
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer")));
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner")));
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer")));
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side")));
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight")));
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer")));
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner")));
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer")));
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side")));
// STAIRS_CUBE
HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight")));
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer")));
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner")));
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer")));
HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side")));
HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight")));
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer")));
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner")));
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer")));
HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side")));
// HALF_STAIR
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down")));
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side")));
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down")));
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side")));
// HALF_STAIRS_SLAB
HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down")));
HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side")));
HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down")));
HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side")));
// HALF_STAIRS_STAIR
HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down")));
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side")));
HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side")));
HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down")));
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side")));
HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side")));
// STEP
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down")));
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down")));
// STEPS_SLAB
HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down")));
HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side")));
HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down")));
HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side")));
// LAYER
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2")));
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4")));
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6")));
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8")));
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10")));
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12")));
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14")));
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube")));
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2")));
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4")));
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6")));
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8")));
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10")));
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12")));
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14")));
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube")));
// PILLAR
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar")));
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar")));
// WALL
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default")));
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default")));
// --------------------- pillar
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core")));
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low")));
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall")));
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none")));
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core")));
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low")));
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall")));
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none")));
// --------------------- side
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low")));
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall")));
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low")));
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall")));
// --------------------- junction
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low")));
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall")));
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low")));
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall")));
// --------------------- junction_i
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i")));
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i")));
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i")));
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i")));
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i")));
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i")));
// --------------------- junction_c
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c")));
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c")));
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c")));
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c")));
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c")));
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c")));
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c")));
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c")));
// --------------------- junction_t
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t")));
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t")));
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t")));
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t")));
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t")));
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t")));
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t")));
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t")));
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t")));
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t")));
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t")));
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t")));
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t")));
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t")));
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t")));
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t")));
// --------------------- junction_x
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x")));
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x")));
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x")));
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x")));
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x")));
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x")));
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x")));
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x")));
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x")));
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x")));
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x")));
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x")));
// PILLAR WALL
HELPER.addReFramedModel("pillars_wall_inventory" , HELPER.autoDouble(ReFramed.id("block/pillar"), ReFramed.id("block/wall/full/inventory/sides")));
HELPER.addReFramedModel("pillars_wall_low" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/low"), ReFramed.id("block/wall/full/side/low")));
HELPER.addReFramedModel("pillars_wall_tall" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/tall"), ReFramed.id("block/wall/full/side/tall")));
HELPER.addReFramedModel("pillars_wall_inventory" , HELPER.autoDouble(ReFramed.id("block/pillar"), ReFramed.id("block/wall/full/inventory/sides")));
HELPER.addReFramedModel("pillars_wall_low" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/low"), ReFramed.id("block/wall/full/side/low")));
HELPER.addReFramedModel("pillars_wall_tall" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/tall"), ReFramed.id("block/wall/full/side/tall")));
// PANE
HELPER.addReFramedModel("pane_inventory" , HELPER.auto(ReFramed.id("block/pane")));
HELPER.addReFramedModel("pane_post" , HELPER.auto(new Identifier("block/glass_pane_post")));
HELPER.addReFramedModel("pane_side" , HELPER.auto(new Identifier("block/glass_pane_side")));
HELPER.addReFramedModel("pane_side_alt" , HELPER.auto(new Identifier("block/glass_pane_side_alt")));
HELPER.addReFramedModel("pane_noside" , HELPER.auto(new Identifier("block/glass_pane_noside")));
HELPER.addReFramedModel("pane_noside_alt" , HELPER.auto(new Identifier("block/glass_pane_noside_alt")));
HELPER.addReFramedModel("pane_inventory" , HELPER.auto(ReFramed.id("block/pane")));
HELPER.addReFramedModel("pane_post" , HELPER.auto(new Identifier("block/glass_pane_post")));
HELPER.addReFramedModel("pane_side" , HELPER.auto(new Identifier("block/glass_pane_side")));
HELPER.addReFramedModel("pane_side_alt" , HELPER.auto(new Identifier("block/glass_pane_side_alt")));
HELPER.addReFramedModel("pane_noside" , HELPER.auto(new Identifier("block/glass_pane_noside")));
HELPER.addReFramedModel("pane_noside_alt" , HELPER.auto(new Identifier("block/glass_pane_noside_alt")));
// TRAPDOOR
HELPER.addReFramedModel("trapdoor_open" , HELPER.auto(new Identifier("block/oak_trapdoor_open")));
HELPER.addReFramedModel("trapdoor_bottom" , HELPER.auto(new Identifier("block/oak_trapdoor_bottom")));
HELPER.addReFramedModel("trapdoor_top" , HELPER.auto(new Identifier("block/oak_trapdoor_top")));
HELPER.addReFramedModel("trapdoor_open" , HELPER.auto(new Identifier("block/oak_trapdoor_open")));
HELPER.addReFramedModel("trapdoor_bottom" , HELPER.auto(new Identifier("block/oak_trapdoor_bottom")));
HELPER.addReFramedModel("trapdoor_top" , HELPER.auto(new Identifier("block/oak_trapdoor_top")));
// DOOR
HELPER.addReFramedModel("door_inventory" , HELPER.auto(ReFramed.id("block/door")));
HELPER.addReFramedModel("door_inventory" , HELPER.auto(ReFramed.id("block/door")));
// BUTTON
HELPER.addReFramedModel("button_inventory" , HELPER.auto(new Identifier("block/button_inventory")));
HELPER.addReFramedModel("button" , HELPER.auto(new Identifier("block/button")));
HELPER.addReFramedModel("button_pressed" , HELPER.auto(new Identifier("block/button_pressed")));
HELPER.addReFramedModel("button_inventory" , HELPER.auto(new Identifier("block/button_inventory")));
HELPER.addReFramedModel("button" , HELPER.auto(new Identifier("block/button")));
HELPER.addReFramedModel("button_pressed" , HELPER.auto(new Identifier("block/button_pressed")));
// POST
HELPER.addReFramedModel("post" , HELPER.auto(ReFramed.id("block/post")));
HELPER.addReFramedModel("post" , HELPER.auto(ReFramed.id("block/post")));
// FENCE
HELPER.addReFramedModel("fence_inventory" , HELPER.auto(ReFramed.id("block/fence/inventory")));
HELPER.addReFramedModel("fence_core" , HELPER.auto(ReFramed.id("block/fence/core")));
HELPER.addReFramedModel("fence_side_off" , HELPER.auto(ReFramed.id("block/fence/side_off")));
HELPER.addReFramedModel("fence_side_on" , HELPER.auto(ReFramed.id("block/fence/side_on")));
HELPER.addReFramedModel("fence_inventory" , HELPER.auto(ReFramed.id("block/fence/inventory")));
HELPER.addReFramedModel("fence_core" , HELPER.auto(ReFramed.id("block/fence/core")));
HELPER.addReFramedModel("fence_side_off" , HELPER.auto(ReFramed.id("block/fence/side_off")));
HELPER.addReFramedModel("fence_side_on" , HELPER.auto(ReFramed.id("block/fence/side_on")));
// POST FENCE
HELPER.addReFramedModel("post_fence_inventory" , HELPER.autoDouble(ReFramed.id("block/post"), ReFramed.id("block/fence/full/inventory")));
HELPER.addReFramedModel("post_fence_side" , HELPER.autoDouble(ReFramed.id("block/fence/full/side_core"), ReFramed.id("block/fence/full/side_bars")));
HELPER.addReFramedModel("post_fence_inventory" , HELPER.autoDouble(ReFramed.id("block/post"), ReFramed.id("block/fence/full/inventory")));
HELPER.addReFramedModel("post_fence_side" , HELPER.autoDouble(ReFramed.id("block/fence/full/side_core"), ReFramed.id("block/fence/full/side_bars")));
// SLABS STAIR
HELPER.addReFramedModel("slabs_stair" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/slab"), ReFramed.id("block/slabs_stair/step")));
HELPER.addReFramedModel("slabs_stair_side" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/side/slab"), ReFramed.id("block/slabs_stair/side/step")));
// SLABS OUTER STAIR
HELPER.addReFramedModel("slabs_outer_stair" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/outer/slab"), ReFramed.id("block/slabs_stair/outer/cube")));
HELPER.addReFramedModel("slabs_outer_stair_side" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/outer/side/slab"), ReFramed.id("block/slabs_stair/outer/side/cube")));
// SLABS OUTER STAIR
HELPER.addReFramedModel("slabs_inner_stair" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/inner/slab"), ReFramed.id("block/slabs_stair/inner/half_stair")));
HELPER.addReFramedModel("slabs_inner_stair_side" , HELPER.autoDouble(ReFramed.id("block/slabs_stair/inner/side/slab"), ReFramed.id("block/slabs_stair/inner/side/half_stair")));
// SLABS OUTER STAIR
HELPER.addReFramedModel("steps_cross" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/cross")));
// HALF STAIRS CUBE STAIR
HELPER.addReFramedModel("half_stairs_cube_stair" , HELPER.autoDouble(ReFramed.id("block/half_stair/base"), ReFramed.id("block/half_stair/stair/cube")));
HELPER.addReFramedModel("half_stairs_cube_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/base_side"), ReFramed.id("block/half_stair/stair/cube_side")));
// HALF STAIRS STEP STAIR
HELPER.addReFramedModel("half_stairs_step_stair_1" , HELPER.autoDouble(ReFramed.id("block/half_stair/base"), ReFramed.id("block/half_stair/stair/step_1")));
HELPER.addReFramedModel("half_stairs_step_stair_side_1", HELPER.autoDouble(ReFramed.id("block/half_stair/base_side"), ReFramed.id("block/half_stair/stair/step_side_1")));
HELPER.addReFramedModel("half_stairs_step_stair_2" , HELPER.autoDouble(ReFramed.id("block/half_stair/base"), ReFramed.id("block/half_stair/stair/step_2")));
HELPER.addReFramedModel("half_stairs_step_stair_side_2", HELPER.autoDouble(ReFramed.id("block/half_stair/base_side"), ReFramed.id("block/half_stair/stair/step_side_2")));
// HALF LAYER
// --------------------- east
HELPER.addReFramedModel("half_layer_2" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_2")));
HELPER.addReFramedModel("half_layer_4" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_4")));
HELPER.addReFramedModel("half_layer_6" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_6")));
HELPER.addReFramedModel("half_layer_8" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_8")));
HELPER.addReFramedModel("half_layer_10" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_10")));
HELPER.addReFramedModel("half_layer_12" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_12")));
HELPER.addReFramedModel("half_layer_14" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_14")));
HELPER.addReFramedModel("half_layer_16" , HELPER.auto(ReFramed.id("block/half_layer/east/layer_16")));
// --------------------- side
HELPER.addReFramedModel("half_layer_side_2" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_2")));
HELPER.addReFramedModel("half_layer_side_4" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_4")));
HELPER.addReFramedModel("half_layer_side_6" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_6")));
HELPER.addReFramedModel("half_layer_side_8" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_8")));
HELPER.addReFramedModel("half_layer_side_10" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_10")));
HELPER.addReFramedModel("half_layer_side_12" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_12")));
HELPER.addReFramedModel("half_layer_side_14" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_14")));
HELPER.addReFramedModel("half_layer_side_16" , HELPER.auto(ReFramed.id("block/half_layer/side/layer_16")));
// SLAB HALF LAYER
HELPER.addReFramedModel("slabs_half_inventory" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/half_layer/slab/east/layer_4")));
// STEP HALF LAYER
HELPER.addReFramedModel("steps_half_inventory" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/half_layer/slab/east/layer_4")));
// --------------------- east
HELPER.addReFramedModel("second_half_layer_2" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_2")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_4" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_4")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_6" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_6")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_8" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_8")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_10" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_10")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_12" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_12")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_14" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_14")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_16" , HELPER.auto(ReFramed.id("block/half_layer/slab/east/layer_16")).setThemeIndex(2));
// --------------------- side
HELPER.addReFramedModel("second_half_layer_side_2" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_2")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_side_4" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_4")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_side_6" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_6")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_side_8" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_8")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_side_10" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_10")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_side_12" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_12")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_side_14" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_14")).setThemeIndex(2));
HELPER.addReFramedModel("second_half_layer_side_16" , HELPER.auto(ReFramed.id("block/half_layer/slab/side/layer_16")).setThemeIndex(2));
// HALF SLAB
HELPER.addReFramedModel("half_slab" , HELPER.auto(ReFramed.id("block/half_slab/default")));
// HALF SLABS SLAB
HELPER.addReFramedModel("half_slabs_slab" , HELPER.autoDouble(ReFramed.id("block/half_slab/default"), ReFramed.id("block/half_slab/complement")));
// 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)
HELPER.assignItemModel("cube" , ReFramed.CUBE);
HELPER.assignItemModel("small_cube" , ReFramed.SMALL_CUBE);
HELPER.assignItemModel("small_cubes_step" , ReFramed.SMALL_CUBES_STEP);
HELPER.assignItemModel("slab" , ReFramed.SLAB);
HELPER.assignItemModel("double_slab" , ReFramed.SLABS_CUBE);
HELPER.assignItemModel("stair" , ReFramed.STAIR);
HELPER.assignItemModel("stairs_cube" , ReFramed.STAIRS_CUBE);
HELPER.assignItemModel("half_stair_down" , ReFramed.HALF_STAIR);
HELPER.assignItemModel("half_stairs_slab_down" , ReFramed.HALF_STAIRS_SLAB);
HELPER.assignItemModel("half_stairs_stair_down", ReFramed.HALF_STAIRS_STAIR);
HELPER.assignItemModel("step" , ReFramed.STEP);
HELPER.assignItemModel("steps_slab" , ReFramed.STEPS_SLAB);
HELPER.assignItemModel("layer_1" , ReFramed.LAYER);
HELPER.assignItemModel("pillar" , ReFramed.PILLAR);
HELPER.assignItemModel("pillars_wall_inventory", ReFramed.PILLARS_WALL);
HELPER.assignItemModel("wall_inventory" , ReFramed.WALL);
HELPER.assignItemModel("pane_inventory" , ReFramed.PANE);
HELPER.assignItemModel("trapdoor_bottom" , ReFramed.TRAPDOOR);
HELPER.assignItemModel("door_inventory" , ReFramed.DOOR);
HELPER.assignItemModel("button_inventory" , ReFramed.BUTTON);
HELPER.assignItemModel("post" , ReFramed.POST);
HELPER.assignItemModel("fence_inventory" , ReFramed.FENCE);
HELPER.assignItemModel("post_fence_inventory" , ReFramed.POST_FENCE);
// item model assignments (in lieu of models/item/___.json)
HELPER.assignItemModel("cube" , ReFramed.CUBE);
HELPER.assignItemModel("small_cube" , ReFramed.SMALL_CUBE);
HELPER.assignItemModel("small_cubes_step" , ReFramed.SMALL_CUBES_STEP);
HELPER.assignItemModel("slab" , ReFramed.SLAB);
HELPER.assignItemModel("double_slab" , ReFramed.SLABS_CUBE);
HELPER.assignItemModel("stair" , ReFramed.STAIR);
HELPER.assignItemModel("stairs_cube" , ReFramed.STAIRS_CUBE);
HELPER.assignItemModel("half_stair_down" , ReFramed.HALF_STAIR);
HELPER.assignItemModel("half_stairs_slab_down" , ReFramed.HALF_STAIRS_SLAB);
HELPER.assignItemModel("half_stairs_stair_down" , ReFramed.HALF_STAIRS_STAIR);
HELPER.assignItemModel("step" , ReFramed.STEP);
HELPER.assignItemModel("steps_slab" , ReFramed.STEPS_SLAB);
HELPER.assignItemModel("layer_1" , ReFramed.LAYER);
HELPER.assignItemModel("pillar" , ReFramed.PILLAR);
HELPER.assignItemModel("pillars_wall_inventory" , ReFramed.PILLARS_WALL);
HELPER.assignItemModel("wall_inventory" , ReFramed.WALL);
HELPER.assignItemModel("pane_inventory" , ReFramed.PANE);
HELPER.assignItemModel("trapdoor_bottom" , ReFramed.TRAPDOOR);
HELPER.assignItemModel("door_inventory" , ReFramed.DOOR);
HELPER.assignItemModel("button_inventory" , ReFramed.BUTTON);
HELPER.assignItemModel("post" , ReFramed.POST);
HELPER.assignItemModel("fence_inventory" , ReFramed.FENCE);
HELPER.assignItemModel("post_fence_inventory" , ReFramed.POST_FENCE);
HELPER.assignItemModel("slabs_stair" , ReFramed.SLABS_STAIR);
HELPER.assignItemModel("slabs_outer_stair" , ReFramed.SLABS_OUTER_STAIR);
HELPER.assignItemModel("slabs_inner_stair" , ReFramed.SLABS_INNER_STAIR);
HELPER.assignItemModel("steps_cross" , ReFramed.STEPS_CROSS);
HELPER.assignItemModel("half_stairs_cube_stair" , ReFramed.HALF_STAIRS_CUBE_STAIR);
HELPER.assignItemModel("half_stairs_step_stair_1", ReFramed.HALF_STAIRS_STEP_STAIR);
HELPER.assignItemModel("half_layer_2" , ReFramed.HALF_LAYER);
HELPER.assignItemModel("slabs_half_inventory" , ReFramed.SLABS_HALF_LAYER);
HELPER.assignItemModel("steps_half_inventory" , ReFramed.STEPS_HALF_LAYER);
HELPER.assignItemModel("half_slab" , ReFramed.HALF_SLAB);
HELPER.assignItemModel("half_slabs_slab" , ReFramed.HALF_SLABS_SLAB);
HELPER.assignItemModel("slabs_layer_2" , ReFramed.SLABS_LAYER);
}
private void privateInit() {

View File

@@ -85,7 +85,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
appearance_manager.getDefaultAppearance(theme_index),
0
),
state
state == null ? item_state : state
)
);
}
@@ -190,9 +190,14 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
public boolean useAmbientOcclusion(BlockRenderView view, BlockPos pos) {
if (!(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity)) return false;
BlockState theme = frame_entity.getTheme(theme_index);
CamoAppearance appearance = appearance_manager
.getCamoAppearance(view, frame_entity.getTheme(theme_index), pos, theme_index, false);
return appearance.getAO(theme_index);
.getCamoAppearance(view, theme, pos, theme_index, false);
long seed = theme.getRenderingSeed(pos);
int model_id = 0;
if (appearance instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
return appearance.getAO(model_id);
}
protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) {

View File

@@ -0,0 +1,7 @@
package fr.adrien1106.reframed.client.util;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
public record RaycastResult(Vec3d pos, Direction face, boolean inside) {
}

View File

@@ -0,0 +1,42 @@
package fr.adrien1106.reframed.client.voxel;
import fr.adrien1106.reframed.client.util.RaycastResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import java.util.List;
import java.util.Objects;
public class MorphBox extends Box {
protected List<Triangle> triangles;
public MorphBox(List<Triangle> triangles) {
super(new BlockPos(0, 0, 0));
this.triangles = triangles;
}
public RaycastResult triangleRaycast(Vec3d min, Vec3d max) {
return triangles.stream()
.map(triangle -> {
Vec3d inter = triangle.intersection(min, max);
if (inter == null) return null;
return new RaycastResult(
inter,
triangle.face(),
false
);
})
.filter(Objects::nonNull)
.findFirst()
.orElseGet(() -> isInside(min) ? new RaycastResult(
min,
triangles.get(0).face(),
true
) : null);
}
public boolean isInside(Vec3d point) {
return triangles.stream().allMatch(triangle -> triangle.after(point));
}
}

View File

@@ -0,0 +1,100 @@
package fr.adrien1106.reframed.client.voxel;
import fr.adrien1106.reframed.client.util.RaycastResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.*;
import net.minecraft.util.shape.SimpleVoxelShape;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* Represents a VoxelShape that can be morphed using its 8 vertices.
* the vertices are distributed as follows:
* <pre><code>
* E--------F ABCD -> NORTH
* ^ /| /| EFGH -> SOUTH
* |/ | / | AHED -> EAST
* D--------C | BCGF -> WEST
* | |/ | | ABGH -> DOWN
* | H-----|--G CDFE -> UP
* | / | /
* |/ |/
* A--------B->
* </code></pre>
*/
public class MorphVoxel extends SimpleVoxelShape {
private static final int[][] EDGE_INDICES = {
{0, 1},
{1, 2},
{2, 3},
{3, 0},
{0, 7},
{1, 6},
{2, 5},
{3, 4},
{4, 5},
{5, 6},
{6, 7},
{7, 4}
};
private static final int[][] FACE_INDICES = {
{7, 6, 1, 0},
{5, 4, 3, 2},
{0, 1, 2, 3},
{4, 5, 6, 7},
{0, 3, 4, 7},
{6, 5, 2, 1}
};
protected final Vec3d[] v;
MorphBox box;
public MorphVoxel(VoxelShape wrapper, Vec3d[] vertices) {
super(wrapper.voxels);
List<Triangle> triangles = new ArrayList<>();
Stream.of(Direction.values()).forEach(dir -> {
int i = dir.ordinal();
List<Vec3d> v = IntStream.range(0, 4).mapToObj(j -> { // remove matching vertices
if (vertices[FACE_INDICES[i][j]].equals(vertices[FACE_INDICES[i][(j+1)%4]])) return null;
return vertices[FACE_INDICES[i][j]];
}).filter(Objects::nonNull).toList();
if (v.size() < 3) return; // skip if there are less than 3 vertices (e.g. a line/dot)
triangles.add(Triangle.of(dir,v));
});
box = new MorphBox(triangles);
v = vertices;
}
@Nullable
@Override
public BlockHitResult raycast(Vec3d start, Vec3d end, BlockPos pos) {
RaycastResult result = box.triangleRaycast(start.subtract(pos.getX(), pos.getY(), pos.getZ()), end.subtract(pos.getX(), pos.getY(), pos.getZ()));
return result == null
? null
: new BlockHitResult(
result.pos().add(pos.getX(), pos.getY(), pos.getZ()),
result.face(),
pos,
result.inside()
);
}
@Override
public void forEachEdge(VoxelShapes.BoxConsumer consumer) {
IntStream.range(0, 12).forEach(i -> {
Vec3d a = v[EDGE_INDICES[i][0]];
Vec3d b = v[EDGE_INDICES[i][1]];
consumer.consume(a.x, a.y, a.z, b.x, b.y, b.z);
});
}
}

View File

@@ -0,0 +1,78 @@
package fr.adrien1106.reframed.client.voxel;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import java.util.List;
import java.util.stream.IntStream;
/**
* Represents a Face of a MorphVoxel.
* @param v - list of vertices on the same plane
* @param e - list of the outer edges
* @param n - normal of the face
* @param face - the direction of the face
*/
public record Triangle(Vec3d[] v, Vec3d[] e, Vec3d n, Direction face) {
/**
* Creates a Triangle from a list of vertices.
* @param face - the direction of the face
* @param vertices - list of vertices on the same plane
* @return the Triangle
*/
public static Triangle of(Direction face, List<Vec3d> vertices) {
assert vertices.size() >= 3;
Vec3d[] v = vertices.toArray(new Vec3d[0]);
// compute the edges
Vec3d[] e = new Vec3d[v.length];
IntStream.range(0, v.length).forEach(i -> e[i] = v[(i + 1) % v.length].subtract(v[i]));
// compute the normal
Vec3d n = v[1].subtract(v[0]).crossProduct(v[2].subtract(v[0])).normalize();
return new Triangle(v, e, n, face);
}
/**
* Computes the intersection of a ray with the triangle.
* @param start - the start of the ray
* @param end - the end of the ray
* @return the intersection point or null if there is no intersection
*/
public Vec3d intersection(Vec3d start, Vec3d end) {
Vec3d start_v0 = start.subtract(v[0]);
Vec3d end_v1 = end.subtract(v[1]);
// check if the ray intersects the plane
if (n.dotProduct(start_v0) * n.dotProduct(end_v1) >= 0) return null;
Vec3d ray = end.subtract(start);
double direction = n.dotProduct(ray);
// plane normal is facing away from the ray
if (direction < 0) return null;
// get Intersection point
double t = -n.dotProduct(start_v0) / direction;
Vec3d intersection = start.add(ray.multiply(t));
// check if the intersection is inside the triangle
for (int i = 0; i < v.length; i++) {
Vec3d edge = e[i];
Vec3d edge_intersection = intersection.subtract(v[i]);
if (edge_intersection.length() < 1e-6) break; // intersection is on the vertex
double a = n.dotProduct(edge.crossProduct(edge_intersection));
if (a <= 0) return null; // intersection is outside the triangle
if (a <= edge.length() * 1e-6) break; // intersection is on the edge
}
return intersection;
}
public boolean after(Vec3d point) {
return n.dotProduct(point.subtract(v[0])) > 0;
}
}

View File

@@ -22,16 +22,28 @@ public class GBlockstate extends FabricModelProvider {
providers.put(ReFramedHalfStairBlock.class, new HalfStair());
providers.put(ReFramedHalfStairsSlabBlock.class, new HalfStairsSlab());
providers.put(ReFramedHalfStairsStairBlock.class, new HalfStairsStair());
providers.put(ReFramedHalfStairsCubeStairBlock.class, new HalfStairsCubeStair());
providers.put(ReFramedHalfStairsStepStairBlock.class, new HalfStairsStepStair());
providers.put(ReFramedLayerBlock.class, new Layer());
providers.put(ReFramedHalfLayerBlock.class, new HalfLayer());
providers.put(ReFramedPillarBlock.class, new Pillar());
providers.put(ReFramedSlabBlock.class, new Slab());
providers.put(ReFramedSlabsCubeBlock.class, new SlabsCube());
providers.put(ReFramedSlabsStairBlock.class, new SlabsStair());
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());
providers.put(ReFramedSmallCubesStepBlock.class, new SmallCubesStep());
providers.put(ReFramedStairBlock.class, new Stair());
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
providers.put(ReFramedStepBlock.class, new Step());
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
providers.put(ReFramedStepsCrossBlock.class, new StepsCross());
providers.put(ReFramedStepsHalfLayerBlock.class, new StepsHalfLayer());
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
providers.put(ReFramedWallBlock.class, new Wall());
providers.put(ReFramedPaneBlock.class, new Pane());
@@ -41,6 +53,8 @@ public class GBlockstate extends FabricModelProvider {
providers.put(ReFramedPostBlock.class, new Post());
providers.put(ReFramedFenceBlock.class, new Fence());
providers.put(ReFramedPostFenceBlock.class, new PostFence());
providers.put(TestBlock.class, new Test());
}
public GBlockstate(FabricDataOutput output) {

View File

@@ -24,16 +24,28 @@ public class GRecipe extends FabricRecipeProvider {
providers.put(ReFramedHalfStairBlock.class, new HalfStair());
providers.put(ReFramedHalfStairsSlabBlock.class, new HalfStairsSlab());
providers.put(ReFramedHalfStairsStairBlock.class, new HalfStairsStair());
providers.put(ReFramedHalfStairsCubeStairBlock.class, new HalfStairsCubeStair());
providers.put(ReFramedHalfStairsStepStairBlock.class, new HalfStairsStepStair());
providers.put(ReFramedLayerBlock.class, new Layer());
providers.put(ReFramedHalfLayerBlock.class, new HalfLayer());
providers.put(ReFramedPillarBlock.class, new Pillar());
providers.put(ReFramedSlabBlock.class, new Slab());
providers.put(ReFramedSlabsCubeBlock.class, new SlabsCube());
providers.put(ReFramedSlabsStairBlock.class, new SlabsStair());
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());
providers.put(ReFramedSmallCubesStepBlock.class, new SmallCubesStep());
providers.put(ReFramedStairBlock.class, new Stair());
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
providers.put(ReFramedStepBlock.class, new Step());
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
providers.put(ReFramedStepsCrossBlock.class, new StepsCross());
providers.put(ReFramedStepsHalfLayerBlock.class, new StepsHalfLayer());
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
providers.put(ReFramedWallBlock.class, new Wall());
providers.put(ReFramedPaneBlock.class, new Pane());

View File

@@ -0,0 +1,77 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.util.blocks.Corner;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER_FACE;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class CornerDouble {
public static MultipartBlockStateSupplier getMultipart(Block block, String model_name) {
Identifier model_id = ReFramed.id(model_name + "_special");
Identifier side_id = ReFramed.id(model_name + "_side_special");
return MultipartBlockStateSupplier.create(block)
// BOTTOM
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R0, R90))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R0, R180))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R0, R270))
// TOP
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R180, R0))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R180, R90))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R180, R180))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 2),
GBlockstate.variant(model_id, true, R180, R270))
// EAST
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R0, R0))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R90, R0))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R180, R0))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R270, R0))
// SOUTH
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R0, R90))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R90, R90))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R180, R90))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R270, R90))
// WEST
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R0, R180))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R90, R180))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R180, R180))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R270, R180))
// NORTH
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R0, R270))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 0),
GBlockstate.variant(side_id, true, R90, R270))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R180, R270))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 1),
GBlockstate.variant(side_id, true, R270, R270))
;
}
}

View File

@@ -0,0 +1,171 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.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.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import java.util.Map;
import static fr.adrien1106.reframed.generator.GBlockstate.variant;
import static fr.adrien1106.reframed.generator.GBlockstate.when;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.state.property.Properties.LAYERS;
public class HalfLayer implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 16);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 2)
.input(ReFramed.LAYER)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
return getMultipart(block, "half_layer");
}
public static MultipartBlockStateSupplier getMultipart(Block block, String layer) {
Map<Integer, Identifier> layer_model = Map.of(
1, ReFramed.id(layer + "_2_special"),
2, ReFramed.id(layer + "_4_special"),
3, ReFramed.id(layer + "_6_special"),
4, ReFramed.id(layer + "_8_special"),
5, ReFramed.id(layer + "_10_special"),
6, ReFramed.id(layer + "_12_special"),
7, ReFramed.id(layer + "_14_special"),
8, ReFramed.id(layer + "_16_special")
);
Map<Integer, Identifier> layer_side = Map.of(
1, ReFramed.id(layer + "_side_2_special"),
2, ReFramed.id(layer + "_side_4_special"),
3, ReFramed.id(layer + "_side_6_special"),
4, ReFramed.id(layer + "_side_8_special"),
5, ReFramed.id(layer + "_side_10_special"),
6, ReFramed.id(layer + "_side_12_special"),
7, ReFramed.id(layer + "_side_14_special"),
8, ReFramed.id(layer + "_side_16_special")
);
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(block);
// DOWN
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, DOWN_EAST, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R0, R0))
);
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, DOWN_SOUTH, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R0, R90))
);
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, WEST_DOWN, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R0, R180))
);
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, NORTH_DOWN, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R0, R270))
);
// UP
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, EAST_UP, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R180, R0))
);
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, SOUTH_UP, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R180, R90))
);
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, UP_WEST, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R180, R180))
);
layer_model.forEach((i, model) ->
supplier.with(when(EDGE, UP_NORTH, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R180, R270))
);
// EAST
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, EAST_SOUTH, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R0, R0))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, EAST_UP, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R90, R0))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, NORTH_EAST, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R180, R0))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, DOWN_EAST, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R270, R0))
);
// SOUTH
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, SOUTH_WEST, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R0, R90))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, SOUTH_UP, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R90, R90))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, EAST_SOUTH, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R180, R90))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, DOWN_SOUTH, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R270, R90))
);
// WEST
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, WEST_NORTH, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R0, R180))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, UP_WEST, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R90, R180))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, SOUTH_WEST, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R180, R180))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, WEST_DOWN, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R270, R180))
);
// NORTH
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, NORTH_EAST, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R0, R270))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, UP_NORTH, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R90, R270))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, WEST_NORTH, EDGE_FACE, 1, LAYERS, i),
variant(model, true, R180, R270))
);
layer_side.forEach((i, model) ->
supplier.with(when(EDGE, NORTH_DOWN, EDGE_FACE, 0, LAYERS, i),
variant(model, true, R270, R270))
);
return supplier;
}
}

View File

@@ -0,0 +1,34 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class HalfSlab implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 4);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 2)
.input(ReFramed.SLAB)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
return Slab.getMultipart(block, "half_slab");
}
}

View File

@@ -0,0 +1,34 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class HalfSlabsSlab implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 1)
.input(ReFramed.HALF_SLAB, 2)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
return Slab.getMultipart(block, "half_slabs_slab");
}
}

View File

@@ -0,0 +1,33 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class HalfStairsCubeStair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.SMALL_CUBE)
.input(ReFramed.HALF_STAIR)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
return CornerDouble.getMultipart(block, "half_stairs_cube_stair");
}
}

View File

@@ -0,0 +1,159 @@
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 fr.adrien1106.reframed.util.blocks.Corner;
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 static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.data.client.VariantSettings.Rotation.R270;
public class HalfStairsStepStair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.SMALL_CUBE)
.input(ReFramed.HALF_STAIR)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
Identifier model_1_id = ReFramed.id("half_stairs_step_stair_1_special");
Identifier side_1_id = ReFramed.id("half_stairs_step_stair_side_1_special");
Identifier model_2_id = ReFramed.id("half_stairs_step_stair_2_special");
Identifier side_2_id = ReFramed.id("half_stairs_step_stair_side_2_special");
return MultipartBlockStateSupplier.create(block)
// BOTTOM
// --- 1 ---
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_1_id, true, R0, R0))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_1_id, true, R0, R90))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_1_id, true, R0, R180))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_1_id, true, R0, R270))
// --- 2 ---
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_2_id, true, R0, R0))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_2_id, true, R0, R90))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_2_id, true, R0, R180))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_2_id, true, R0, R270))
// TOP
// --- 1 ---
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_1_id, true, R180, R0))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_1_id, true, R180, R90))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_1_id, true, R180, R180))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 1),
GBlockstate.variant(model_1_id, true, R180, R270))
// --- 2 ---
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_2_id, true, R180, R0))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_2_id, true, R180, R90))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_2_id, true, R180, R180))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 2, CORNER_FEATURE, 0),
GBlockstate.variant(model_2_id, true, R180, R270))
// EAST
// --- 1 ---
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R0, R0))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R90, R0))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R180, R0))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R270, R0))
// --- 2 ---
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R0, R0))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R90, R0))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R180, R0))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R270, R0))
// SOUTH
// --- 1 ---
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R0, R90))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R90, R90))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R180, R90))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R270, R90))
// --- 2 ---
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R0, R90))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R90, R90))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R180, R90))
.with(GBlockstate.when(CORNER, Corner.EAST_SOUTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R270, R90))
// WEST
// --- 1 ---
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R0, R180))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R90, R180))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R180, R180))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R270, R180))
// --- 2 ---
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R0, R180))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R90, R180))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R180, R180))
.with(GBlockstate.when(CORNER, Corner.SOUTH_WEST_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R270, R180))
// NORTH
// --- 1 ---
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R0, R270))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R90, R270))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_1_id, true, R180, R270))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_1_id, true, R270, R270))
// --- 2 ---
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_DOWN, CORNER_FACE, 0, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R0, R270))
.with(GBlockstate.when(CORNER, Corner.NORTH_EAST_UP, CORNER_FACE, 0, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R90, R270))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_UP, CORNER_FACE, 1, CORNER_FEATURE, 1),
GBlockstate.variant(side_2_id, true, R180, R270))
.with(GBlockstate.when(CORNER, Corner.WEST_NORTH_DOWN, CORNER_FACE, 1, CORNER_FEATURE, 0),
GBlockstate.variant(side_2_id, true, R270, R270))
;
}
}

View File

@@ -34,7 +34,11 @@ public class Slab implements RecipeSetter, BlockStateProvider {
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("slab_special");
return getMultipart(block, "slab");
}
public static MultipartBlockStateSupplier getMultipart(Block block, String model_name) {
Identifier model_id = ReFramed.id(model_name + "_special");
return MultipartBlockStateSupplier.create(block)
.with(GBlockstate.when(FACING, Direction.DOWN),
GBlockstate.variant(model_id, true, R0, R0))
@@ -49,4 +53,6 @@ public class Slab implements RecipeSetter, BlockStateProvider {
.with(GBlockstate.when(FACING, Direction.EAST),
GBlockstate.variant(model_id, true, R90, R270));
}
}

View File

@@ -0,0 +1,93 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.generator.GBlockstate.variant;
import static fr.adrien1106.reframed.generator.GBlockstate.when;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.data.client.When.anyOf;
public class SlabsHalfLayer 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)
.input(ReFramed.HALF_LAYER)
.input(ReFramed.SLAB)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier slab_model = ReFramed.id("slab_special");
return HalfLayer.getMultipart(block, "second_half_layer")
.with(
anyOf(
when(EDGE, DOWN_EAST, EDGE_FACE, 0),
when(EDGE, DOWN_SOUTH, EDGE_FACE, 0),
when(EDGE, WEST_DOWN, EDGE_FACE, 1),
when(EDGE, NORTH_DOWN, EDGE_FACE, 1)
),
variant(slab_model, true, R0, R0))
.with(
anyOf(
when(EDGE, EAST_SOUTH, EDGE_FACE, 1),
when(EDGE, DOWN_SOUTH, EDGE_FACE, 1),
when(EDGE, SOUTH_WEST, EDGE_FACE, 0),
when(EDGE, SOUTH_UP, EDGE_FACE, 0)
),
variant(slab_model, true, R90, R0))
.with(
anyOf(
when(EDGE, UP_WEST, EDGE_FACE, 0),
when(EDGE, UP_NORTH, EDGE_FACE, 0),
when(EDGE, EAST_UP, EDGE_FACE, 1),
when(EDGE, SOUTH_UP, EDGE_FACE, 1)
),
variant(slab_model, true, R180, R0))
.with(
anyOf(
when(EDGE, WEST_NORTH, EDGE_FACE, 1),
when(EDGE, UP_NORTH, EDGE_FACE, 1),
when(EDGE, NORTH_EAST, EDGE_FACE, 0),
when(EDGE, NORTH_DOWN, EDGE_FACE, 0)
),
variant(slab_model, true, R270, R0))
.with(
anyOf(
when(EDGE, SOUTH_WEST, EDGE_FACE, 1),
when(EDGE, UP_WEST, EDGE_FACE, 1),
when(EDGE, WEST_NORTH, EDGE_FACE, 0),
when(EDGE, WEST_DOWN, EDGE_FACE, 0)
),
variant(slab_model, true, R90, R90))
.with(
anyOf(
when(EDGE, NORTH_EAST, EDGE_FACE, 1),
when(EDGE, DOWN_EAST, EDGE_FACE, 1),
when(EDGE, EAST_SOUTH, EDGE_FACE, 0),
when(EDGE, EAST_UP, EDGE_FACE, 0)
),
variant(slab_model, true, R90, R270))
;
}
}

View File

@@ -0,0 +1,33 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class SlabsInnerStair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.HALF_STAIR)
.input(ReFramed.SLAB)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
return CornerDouble.getMultipart(block, "slabs_inner_stair");
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,33 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class SlabsOuterStair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.SMALL_CUBE)
.input(ReFramed.SLAB)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
return CornerDouble.getMultipart(block, "slabs_outer_stair");
}
}

View File

@@ -0,0 +1,97 @@
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 fr.adrien1106.reframed.util.blocks.Edge;
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 static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class SlabsStair implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.STEP)
.input(ReFramed.SLAB)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("slabs_stair_special");
Identifier side_id = ReFramed.id("slabs_stair_side_special");
return MultipartBlockStateSupplier.create(block)
// BOTTOM
.with(GBlockstate.when(EDGE, Edge.DOWN_EAST, EDGE_FACE, 0),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, Edge.DOWN_SOUTH, EDGE_FACE, 0),
GBlockstate.variant(model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, Edge.WEST_DOWN, EDGE_FACE, 1),
GBlockstate.variant(model_id, true, R0, R180))
.with(GBlockstate.when(EDGE, Edge.NORTH_DOWN, EDGE_FACE, 1),
GBlockstate.variant(model_id, true, R0, R270))
// TOP
.with(GBlockstate.when(EDGE, Edge.EAST_UP, EDGE_FACE, 1),
GBlockstate.variant(model_id, true, R180, R0))
.with(GBlockstate.when(EDGE, Edge.SOUTH_UP, EDGE_FACE, 1),
GBlockstate.variant(model_id, true, R180, R90))
.with(GBlockstate.when(EDGE, Edge.UP_WEST, EDGE_FACE, 0),
GBlockstate.variant(model_id, true, R180, R180))
.with(GBlockstate.when(EDGE, Edge.UP_NORTH, EDGE_FACE, 0),
GBlockstate.variant(model_id, true, R180, R270))
// EAST
.with(GBlockstate.when(EDGE, Edge.EAST_SOUTH, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R0, R0))
.with(GBlockstate.when(EDGE, Edge.EAST_UP, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R90, R0))
.with(GBlockstate.when(EDGE, Edge.NORTH_EAST, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R180, R0))
.with(GBlockstate.when(EDGE, Edge.DOWN_EAST, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R270, R0))
// SOUTH
.with(GBlockstate.when(EDGE, Edge.SOUTH_WEST, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R0, R90))
.with(GBlockstate.when(EDGE, Edge.SOUTH_UP, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R90, R90))
.with(GBlockstate.when(EDGE, Edge.EAST_SOUTH, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R180, R90))
.with(GBlockstate.when(EDGE, Edge.DOWN_SOUTH, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R270, R90))
// WEST
.with(GBlockstate.when(EDGE, Edge.WEST_NORTH, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R0, R180))
.with(GBlockstate.when(EDGE, Edge.UP_WEST, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R90, R180))
.with(GBlockstate.when(EDGE, Edge.SOUTH_WEST, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R180, R180))
.with(GBlockstate.when(EDGE, Edge.WEST_DOWN, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R270, R180))
// NORTH
.with(GBlockstate.when(EDGE, Edge.NORTH_EAST, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R0, R270))
.with(GBlockstate.when(EDGE, Edge.UP_NORTH, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R90, R270))
.with(GBlockstate.when(EDGE, Edge.WEST_NORTH, EDGE_FACE, 1),
GBlockstate.variant(side_id, true, R180, R270))
.with(GBlockstate.when(EDGE, Edge.NORTH_DOWN, EDGE_FACE, 0),
GBlockstate.variant(side_id, true, R270, R270))
;
}
}

View File

@@ -2,23 +2,15 @@ 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.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.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE;
import static fr.adrien1106.reframed.util.blocks.Edge.*;
import static fr.adrien1106.reframed.util.blocks.Edge.SOUTH_UP;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
public class SmallCubesStep implements RecipeSetter, BlockStateProvider {
@@ -35,35 +27,6 @@ public class SmallCubesStep implements RecipeSetter, BlockStateProvider {
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("small_cubes_step_special");
Identifier reverse_model_id = ReFramed.id("small_cubes_step_reverse_special");
return MultipartBlockStateSupplier.create(block)
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(reverse_model_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(model_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(reverse_model_id, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(model_id, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(model_id, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(model_id, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(reverse_model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(model_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(reverse_model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(model_id, true, R180, R90));
return Step.getMultipart(block, "small_cubes_step", "small_cubes_step_reverse");
}
}

View File

@@ -36,17 +36,26 @@ public class Step implements RecipeSetter, BlockStateProvider {
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier model_id = ReFramed.id("step_special");
return getMultipart(block, "step");
}
public static BlockStateSupplier getMultipart(Block block, String model_name) {
return getMultipart(block, model_name, model_name);
}
public static BlockStateSupplier getMultipart(Block block, String model_name, String reverse_model_name) {
Identifier model_id = ReFramed.id(model_name + "_special");
Identifier reverse_model_id = ReFramed.id(reverse_model_name + "_special");
return MultipartBlockStateSupplier.create(block)
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(model_id, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(model_id, true, R180, R0))
GBlockstate.variant(reverse_model_id, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(model_id, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(model_id, true, R0, R180))
GBlockstate.variant(reverse_model_id, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(model_id, true, R90, R0))
@@ -58,11 +67,11 @@ public class Step implements RecipeSetter, BlockStateProvider {
GBlockstate.variant(model_id, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(model_id, true, R0, R90))
GBlockstate.variant(reverse_model_id, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(model_id, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(model_id, true, R180, R270))
GBlockstate.variant(reverse_model_id, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(model_id, true, R180, R90));
}

View File

@@ -0,0 +1,34 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
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.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
public class StepsCross implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 8)
.pattern(" I")
.pattern("I ")
.input('I', ReFramed.STEP)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
return Step.getMultipart(block, "steps_cross");
}
}

View File

@@ -0,0 +1,69 @@
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.BlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
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 StepsHalfLayer implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 4);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.HALF_LAYER)
.input(ReFramed.STEP)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public BlockStateSupplier getMultipart(Block block) {
Identifier step_model = ReFramed.id("step_special");
return HalfLayer.getMultipart(block, "second_half_layer")
/* X AXIS */
.with(GBlockstate.when(EDGE, DOWN_EAST),
GBlockstate.variant(step_model, true, R0, R0))
.with(GBlockstate.when(EDGE, EAST_UP),
GBlockstate.variant(step_model, true, R180, R0))
.with(GBlockstate.when(EDGE, UP_WEST),
GBlockstate.variant(step_model, true, R180, R180))
.with(GBlockstate.when(EDGE, WEST_DOWN),
GBlockstate.variant(step_model, true, R0, R180))
/* Y AXIS */
.with(GBlockstate.when(EDGE, EAST_SOUTH),
GBlockstate.variant(step_model, true, R90, R0))
.with(GBlockstate.when(EDGE, SOUTH_WEST),
GBlockstate.variant(step_model, true, R90, R90))
.with(GBlockstate.when(EDGE, WEST_NORTH),
GBlockstate.variant(step_model, true, R90, R180))
.with(GBlockstate.when(EDGE, NORTH_EAST),
GBlockstate.variant(step_model, true, R90, R270))
/* Z AXIS */
.with(GBlockstate.when(EDGE, DOWN_SOUTH),
GBlockstate.variant(step_model, true, R0, R90))
.with(GBlockstate.when(EDGE, NORTH_DOWN),
GBlockstate.variant(step_model, true, R0, R270))
.with(GBlockstate.when(EDGE, UP_NORTH),
GBlockstate.variant(step_model, true, R180, R270))
.with(GBlockstate.when(EDGE, SOUTH_UP),
GBlockstate.variant(step_model, true, R180, R90))
;
}
}

View File

@@ -9,7 +9,7 @@ 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.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
@@ -25,9 +25,10 @@ public class StepsSlab implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
ShapedRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible)
.input(ReFramed.STEP, 2)
.pattern("II")
.input('I', ReFramed.STEP)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);

View File

@@ -0,0 +1,26 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import net.minecraft.block.Block;
import net.minecraft.data.client.BlockStateSupplier;
import net.minecraft.data.client.VariantsBlockStateSupplier;
import net.minecraft.util.Identifier;
import static net.minecraft.data.client.VariantSettings.Rotation.R0;
public class Test implements BlockStateProvider {
@Override
public BlockStateSupplier getMultipart(Block block) {
return VariantsBlockStateSupplier.create(
block,
GBlockstate.variant(
new Identifier("block/barrier"),
true,
R0, R0
)
);
}
}

View File

@@ -74,7 +74,14 @@ public class ReFramedBlueprintWrittenItem extends Item {
stacks.stream().map(inventory::getSlotWithStack).forEach(index -> inventory.removeStack(index, 1));
player.playSound(SoundEvents.ENTITY_ITEM_PICKUP, 0.5f, 0.5f);
}
frame_entity.readNbt(tag);
for (int i = 1; tag.contains(BLOCKSTATE_KEY + i); i++) {
BlockState state = NbtHelper.toBlockState(
Registries.BLOCK.getReadOnlyWrapper(),
tag.getCompound(BLOCKSTATE_KEY + i)
);
frame_entity.setTheme(state, i);
}
if (world.isClient) ReFramed.chunkRerenderProxy.accept(world, pos);
world.playSound(player, player.getBlockPos(), SoundEvents.ITEM_BOOK_PAGE_TURN, SoundCategory.PLAYERS);
return ActionResult.SUCCESS;

View File

@@ -43,7 +43,7 @@ public class ReFramedHammerItem extends Item {
world.playSound(player, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 1f, 1.1f);
}
frame_entity.setTheme(Blocks.AIR.getDefaultState(), theme_index);
ReFramed.chunkRerenderProxy.accept(world, pos);
if (world.isClient) ReFramed.chunkRerenderProxy.accept(world, pos);
return ActionResult.SUCCESS;
}
}

View File

@@ -52,7 +52,7 @@ public class ReFramedScrewdriverItem extends Item {
case Z -> Direction.Axis.X;
}
), theme_index);
ReFramed.chunkRerenderProxy.accept(world, pos);
if (world.isClient) ReFramed.chunkRerenderProxy.accept(world, pos);
return ActionResult.SUCCESS;
}
}

View File

@@ -6,11 +6,13 @@ import com.moulberry.axiom.utils.IntMatrix;
import com.moulberry.axiom.world_modification.CompressedBlockEntity;
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
import fr.adrien1106.reframed.util.DefaultList;
import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
import fr.adrien1106.reframed.util.mixin.ThemedBlockEntity;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Camera;
@@ -78,15 +80,19 @@ public abstract class AxiomChunkedBlockRegionMixin implements IAxiomChunkedBlock
cancellable = true)
private static void onRenderBlock(BufferBuilder blockBuilder, BlockRenderManager renderer, BlockPos.Mutable pos, Random rand, MatrixStack matrices, BlockRenderView world, Matrix4f currentPoseMatrix, Matrix4f basePoseMatrix, int x, int y, int z, BlockState state, boolean useAmbientOcclusion, CallbackInfo ci, @Local BakedModel model) {
List<BakedModel> models;
if ((models = getModels(model, state)).isEmpty() // not a retexturable model
|| !(world.getBlockEntity(pos) instanceof ThemedBlockEntity block_entity) // not a themed block entity
) return;
if ((models = getModels(model, state)).isEmpty()) return;
DefaultList<BlockState> themes = new DefaultList<>(
Blocks.AIR.getDefaultState(),
world.getBlockEntity(pos) instanceof ThemedBlockEntity themed
? themed.getThemes()
: List.of()
);
models.stream().flatMap(m -> m instanceof MultiRetexturableModel mm
? mm.models().stream()
: Stream.of((RetexturingBakedModel)m)
).forEach(m -> {
m.setCamo(world, block_entity.getTheme(m.getThemeIndex()), pos);
m.setCamo(world, themes.get(m.getThemeIndex() - 1), pos);
if (useAmbientOcclusion && state.getLuminance() == 0 && m.useAmbientOcclusion()) renderer.getModelRenderer()
.renderSmooth(world, m, state, pos, matrices, blockBuilder, true, rand, state.getRenderingSeed(pos), OverlayTexture.DEFAULT_UV);
else renderer.getModelRenderer()
@@ -98,11 +104,10 @@ public abstract class AxiomChunkedBlockRegionMixin implements IAxiomChunkedBlock
@Inject(
method = "getBlockEntity",
at = @At("HEAD"),
remap = false,
cancellable = true
)
private void onGetBlockEntity(BlockPos pos, CallbackInfoReturnable<BlockEntity> cir) {
if (inverse_transform == null) return;
if (inverse_transform == null || block_entities == null) return;
long key = BlockPos.asLong(
inverse_transform.transformX(pos.getX(), pos.getY(), pos.getZ()),
inverse_transform.transformY(pos.getX(), pos.getY(), pos.getZ()),

View File

@@ -21,7 +21,6 @@ public class AxiomMappedBlockAndTintGetterMixin {
at = @At(
value = "RETURN"
),
remap = false,
cancellable = true
)
private void onGetBlockEntity(BlockPos pos, CallbackInfoReturnable<BlockEntity> cir) {

View File

@@ -30,8 +30,7 @@ public class AxiomPlacementMixin {
@Inject(
method = "startPlacement(Lnet/minecraft/util/math/BlockPos;Lcom/moulberry/axiom/render/regions/ChunkedBlockRegion;Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;Ljava/lang/String;)I",
at = @At("HEAD"),
remap = false
at = @At("HEAD")
)
private void onStartPlacement(BlockPos target, ChunkedBlockRegion region, Long2ObjectMap<CompressedBlockEntity> entities, String description, CallbackInfoReturnable<Integer> cir) {
((IAxiomChunkedBlockRegionMixin) region).setTransform(new IntMatrix(), entities);

View File

@@ -1,6 +1,5 @@
package fr.adrien1106.reframed.mixin.compat;
import com.llamalad7.mixinextras.sugar.Local;
import fr.adrien1106.reframed.client.util.RenderHelper;
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
@@ -24,7 +23,6 @@ public abstract class IndiumBlockRenderInfoMixin implements IBlockRenderInfoMixi
@Shadow public BlockPos blockPos;
@Shadow public BlockRenderView blockView;
@Shadow public BlockState blockState;
@Shadow(remap = false) private int cullResultFlags;
@Unique private int theme_index = 0;
@Unique private int model_hash = 0;
@@ -32,19 +30,18 @@ public abstract class IndiumBlockRenderInfoMixin implements IBlockRenderInfoMixi
@Inject(
method = "shouldDrawFace",
at = @At(
value = "INVOKE",
target = "Llink/infra/indium/renderer/render/BlockRenderInfo;shouldDrawFaceInner(Lnet/minecraft/util/math/Direction;)Z"
value = "INVOKE_ASSIGN",
target = "Lnet/minecraft/util/math/Direction;getId()I",
shift = At.Shift.AFTER
),
cancellable = true
)
private void shouldDrawInnerFace(Direction face, CallbackInfoReturnable<Boolean> cir, @Local int mask) {
private void shouldDrawInnerFace(Direction face, CallbackInfoReturnable<Boolean> cir) {
BlockPos other_pos = blockPos.offset(face);
if (!(blockView.getBlockEntity(blockPos) instanceof ThemeableBlockEntity
|| blockView.getBlockEntity(other_pos) instanceof ThemeableBlockEntity)
) return;
boolean result = RenderHelper.shouldDrawSide(blockState, blockView, blockPos, face, other_pos, theme_index);
if (result) cullResultFlags |= mask;
cir.setReturnValue(result);
cir.setReturnValue(RenderHelper.shouldDrawSide(blockState, blockView, blockPos, face, other_pos, theme_index));
}
@Override

View File

@@ -42,7 +42,6 @@ public abstract class IndiumNonTerrainBlockRenderContextMixin extends AbstractBl
target = "Llink/infra/indium/renderer/render/BlockRenderInfo;prepareForWorld(Lnet/minecraft/world/BlockRenderView;Z)V",
shift = At.Shift.AFTER
),
remap = false,
cancellable = true
)
private void renderMultipleModels(BlockRenderView blockView, BakedModel wrapper, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, boolean cull, Random random, long seed, int overlay, CallbackInfo ci) {

View File

@@ -0,0 +1,140 @@
package fr.adrien1106.reframed.util;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class DefaultList<T> implements List<T> {
protected T default_value;
protected List<T> elements;
public DefaultList(T default_value, List<T> elements) {
this.default_value = default_value;
this.elements = elements;
}
@Override
public int size() {
return elements.size();
}
@Override
public boolean isEmpty() {
return elements.isEmpty();
}
@Override
public boolean contains(Object o) {
return elements.contains(o) || default_value.equals(o);
}
@NotNull
@Override
public Iterator<T> iterator() {
return elements.iterator();
}
@NotNull
@Override
public Object[] toArray() {
return elements.toArray();
}
@NotNull
@Override
public <T1> T1[] toArray(@NotNull T1[] a) {
return elements.toArray(a);
}
@Override
public boolean add(T t) {
return elements.add(t);
}
@Override
public boolean remove(Object o) {
return elements.remove(o);
}
@Override
public boolean containsAll(@NotNull Collection<?> c) {
return elements.containsAll(c);
}
@Override
public boolean addAll(@NotNull Collection<? extends T> c) {
return elements.addAll(c);
}
@Override
public boolean addAll(int index, @NotNull Collection<? extends T> c) {
return elements.addAll(index, c);
}
@Override
public boolean removeAll(@NotNull Collection<?> c) {
return elements.removeAll(c);
}
@Override
public boolean retainAll(@NotNull Collection<?> c) {
return elements.retainAll(c);
}
@Override
public void clear() {
elements.clear();
}
@Override
public T get(int index) {
return index < elements.size() && index >= 0 ? elements.get(index) : default_value;
}
@Override
public T set(int index, T element) {
return elements.set(index, element);
}
@Override
public void add(int index, T element) {
elements.add(index, element);
}
@Override
public T remove(int index) {
return elements.remove(index);
}
@Override
public int indexOf(Object o) {
return elements.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
return elements.lastIndexOf(o);
}
@NotNull
@Override
public ListIterator<T> listIterator() {
return elements.listIterator();
}
@NotNull
@Override
public ListIterator<T> listIterator(int index) {
return elements.listIterator();
}
@NotNull
@Override
public List<T> subList(int fromIndex, int toIndex) {
return elements.subList(fromIndex, toIndex);
}
}

View File

@@ -201,5 +201,24 @@ public class VoxelHelper {
}
return shapes;
}
/**
* build a new set of voxels based on the combination of two sets of voxels
* @param long_voxels - the first set of voxels
* @param short_voxels - the second set of voxels
* @param mapping_function - the function to map the index of the first set to the index of the second set
* @return the array of added voxels
*/
public static VoxelShape[] buildFrom(VoxelShape[] long_voxels, VoxelShape[] short_voxels, Function<Integer, Integer> mapping_function) {
VoxelShape[] shapes = new VoxelShape[long_voxels.length];
for (int i = 0; i < shapes.length; i++) {
shapes[i] = VoxelShapes.combineAndSimplify(
long_voxels[i],
short_voxels[mapping_function.apply(i)],
BooleanBiFunction.OR
);
}
return shapes;
}
}
}

View File

@@ -7,7 +7,11 @@ import net.minecraft.state.property.IntProperty;
public class BlockProperties {
public static final BooleanProperty LIGHT = BooleanProperty.of("emits_light");
public static final EnumProperty<Edge> EDGE = EnumProperty.of("edge", Edge.class);
public static final IntProperty EDGE_FACE = IntProperty.of("face", 0, 1);
public static final EnumProperty<Corner> CORNER = EnumProperty.of("corner", Corner.class);
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);
}

View File

@@ -116,6 +116,14 @@ public enum Corner implements StringIdentifiable {
);
}
public Edge getEdgeWith(Direction direction) {
return Edge.getByDirections(
first_direction == direction ? first_direction : second_direction,
first_direction == direction ? second_direction : third_direction
);
}
public Direction getOtherDirection(Edge edge) {
if (edge.getFirstDirection() != second_direction && edge.getSecondDirection() != second_direction) return second_direction;
if (edge.getFirstDirection() != third_direction && edge.getSecondDirection() != third_direction) return third_direction;
@@ -137,4 +145,17 @@ public enum Corner implements StringIdentifiable {
mirror.apply(third_direction)
);
}
public Corner change(Direction face) {
Direction opposite = face.getOpposite();
return getByDirections(
first_direction == face ? opposite : first_direction,
second_direction == face ? opposite : second_direction,
third_direction == face ? opposite : third_direction
);
}
public Direction getMatchingDirection(Edge edge) {
return hasDirection(edge.getSecondDirection()) ? edge.getSecondDirection() : edge.getFirstDirection();
}
}

View File

@@ -106,6 +106,22 @@ public enum Edge implements StringIdentifiable {
.findFirst().orElse(Edge.NORTH_DOWN);
}
public Direction getDirection(int side) {
return side == 1 ? second_direction : first_direction;
}
public int getDirectionIndex(Direction direction) {
return direction == first_direction ? 0 : 1;
}
public Edge getOpposite(int index) {
return getOpposite(getDirection(index));
}
public Edge getOpposite(Direction direction) {
return getByDirections(direction, getOtherDirection(direction).getOpposite());
}
public Edge rotate(BlockRotation rotation) {
return getByDirections(
rotation.rotate(first_direction),

View File

@@ -2,6 +2,7 @@ package fr.adrien1106.reframed.util.mixin;
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtHelper;
@@ -29,12 +30,17 @@ public class ThemedBlockEntity extends BlockEntity implements ThemeableBlockEnti
@Override
public BlockState getTheme(int i) {
if (i > themes.size())
return Blocks.AIR.getDefaultState();
return themes.get(Math.max(0, i-1));
}
@Override
public void setTheme(BlockState state, int i) {
themes.set(Math.max(0, i-1), state);
if (i > themes.size())
themes.add(state);
else
themes.set(Math.max(0, i-1), state);
}
@Override

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 10, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 6, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 6, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 6, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 6, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 4, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 4, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 4, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 4, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 14, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 2, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 2, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 2, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 2, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 0, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 0, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 0, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 0, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top", "cullface": "up"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 2, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 14, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 14, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 14, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 14, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 12, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 12, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 12, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 12, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 6, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 10, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 10, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 10, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 10, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [8, 0, 0],
"to": [16, 8, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"},
"east": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [0, 8, 16, 16], "texture": "#side"},
"up": {"uv": [8, 0, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [6, 0, 8],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 0, 10, 16], "texture": "#side"},
"east": {"uv": [0, 0, 8, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [6, 0, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [8, 0, 16, 16], "texture": "#side"},
"up": {"uv": [6, 8, 16, 16], "texture": "#top", "cullface": "up"},
"down": {"uv": [6, 0, 16, 8], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [4, 0, 8],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 0, 12, 16], "texture": "#side"},
"east": {"uv": [0, 0, 8, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [4, 0, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [8, 0, 16, 16], "texture": "#side"},
"up": {"uv": [4, 8, 16, 16], "texture": "#top", "cullface": "up"},
"down": {"uv": [4, 0, 16, 8], "texture": "#bottom", "cullface": "down"}
}
}
]
}

View File

@@ -0,0 +1,22 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"elements": [
{
"from": [2, 0, 8],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [0, 8, 0]},
"faces": {
"north": {"uv": [0, 0, 14, 16], "texture": "#side"},
"east": {"uv": [0, 0, 8, 16], "texture": "#side", "cullface": "east"},
"south": {"uv": [2, 0, 16, 16], "texture": "#side", "cullface": "south"},
"west": {"uv": [8, 0, 16, 16], "texture": "#side"},
"up": {"uv": [2, 8, 16, 16], "texture": "#top", "cullface": "up"},
"down": {"uv": [2, 0, 16, 8], "texture": "#bottom", "cullface": "down"}
}
}
]
}

Some files were not shown because too many files have changed in this diff Show More