diff --git a/README.md b/README.md index 3ddd190..2aa9500 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,8 @@ 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: -- Fence - Pressure Plate - Carpet (maybe redundant with Layer) -- Post - Half Slab (maybe redundant with Layer) - Slabs Stair (a stair with one end being of a second theme, might be done in multiple blocks) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index f3dca2c..211cf8a 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -37,7 +37,18 @@ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; public static final ArrayList BLOCKS = new ArrayList<>(); - public static Block CUBE, SMALL_CUBE, SMALL_CUBES_STEP, STAIR, HALF_STAIR, STAIRS_CUBE, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, SLAB, SLABS_CUBE, STEP, STEPS_SLAB, LAYER, PILLAR, PILLARS_WALL, WALL, PANE, TRAPDOOR, DOOR, BUTTON; + public static Block + CUBE, + SMALL_CUBE, SMALL_CUBES_STEP, + STAIR, STAIRS_CUBE, + HALF_STAIR, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, + SLAB, SLABS_CUBE, + STEP, STEPS_SLAB, + LAYER, + PILLAR, PILLARS_WALL, WALL, + PANE, TRAPDOOR, DOOR, + BUTTON, + POST, POST_FENCE, FENCE; public static final ArrayList ITEMS = new ArrayList<>(); public static Item HAMMER, SCREWDRIVER, BLUEPRINT, BLUEPRINT_WRITTEN; @@ -71,6 +82,9 @@ public class ReFramed implements ModInitializer { 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))); diff --git a/src/main/java/fr/adrien1106/reframed/block/ConnectingReFramedBlock.java b/src/main/java/fr/adrien1106/reframed/block/ConnectingReFramedBlock.java new file mode 100644 index 0000000..5b63d7a --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ConnectingReFramedBlock.java @@ -0,0 +1,104 @@ +package fr.adrien1106.reframed.block; + +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.state.property.BooleanProperty; +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 net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import org.apache.commons.lang3.function.TriFunction; +import org.jetbrains.annotations.Nullable; + +import static net.minecraft.state.property.Properties.*; +import static net.minecraft.state.property.Properties.SOUTH; + +public abstract class ConnectingReFramedBlock extends WaterloggableReFramedBlock { + + public ConnectingReFramedBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState() + .with(EAST, false) + .with(NORTH, false) + .with(WEST, false) + .with(SOUTH, false) + ); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder.add(EAST, NORTH, SOUTH, WEST)); + } + + @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); + if (dir == Direction.DOWN) return new_state; + + return placementState(new_state, world, pos, this::connectsTo); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + BlockState state = super.getPlacementState(ctx); + World world = ctx.getWorld(); + BlockPos pos = ctx.getBlockPos(); + + return placementState(state, world, pos, this::connectsTo); + } + + @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 rotate(BlockState state, BlockRotation rotation) { + return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) -> + s.with(getConnectionProperty(rotation.rotate(dir)), state.get(getConnectionProperty(dir))) + , (prev, next) -> next); + } + + @Override + 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))) + , (prev, next) -> next); + } + + protected abstract boolean connectsTo(BlockState state, boolean fs, Direction dir); + + @Override + public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context); + + public static BooleanProperty getConnectionProperty(Direction dir) { + return switch (dir) { + case NORTH -> NORTH; + case EAST -> EAST; + case SOUTH -> SOUTH; + case WEST -> WEST; + default -> null; + }; + } + + public static BlockState placementState(BlockState state, BlockView world, BlockPos pos, TriFunction connectsTo) { + for (Direction dir: Direction.Type.HORIZONTAL) { + BlockState neighbor = world.getBlockState(pos.offset(dir)); + state = state.with(getConnectionProperty(dir), connectsTo.apply( + neighbor, + neighbor.isSideSolidFullSquare(world, pos.offset(dir), dir.getOpposite()), + dir + )); + } + return state; + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/PillarReFramedBlock.java b/src/main/java/fr/adrien1106/reframed/block/PillarReFramedBlock.java new file mode 100644 index 0000000..1360d9e --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/PillarReFramedBlock.java @@ -0,0 +1,46 @@ +package fr.adrien1106.reframed.block; + +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.AXIS; + +public abstract class PillarReFramedBlock extends WaterloggableReFramedBlock { + public PillarReFramedBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y)); + } + + @Override + protected void appendProperties(StateManager.Builder< Block, BlockState > builder) { + super.appendProperties(builder.add(AXIS)); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + return super.getPlacementState(ctx).with(AXIS, ctx.getSide().getAxis()); + } + + @Override + public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context); + + @Override + public BlockState rotate(BlockState state, BlockRotation rotation) { + return state.with(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis()); + } + + @Override + public BlockState mirror(BlockState state, BlockMirror mirror) { + return state.with(AXIS, mirror.apply(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis()); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedFenceBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedFenceBlock.java new file mode 100644 index 0000000..d34b717 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedFenceBlock.java @@ -0,0 +1,105 @@ +package fr.adrien1106.reframed.block; + +import fr.adrien1106.reframed.util.VoxelHelper; +import net.minecraft.block.BlockState; +import net.minecraft.block.FenceGateBlock; +import net.minecraft.block.ShapeContext; +import net.minecraft.entity.ai.pathing.NavigationType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.item.LeadItem; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.function.BooleanBiFunction; +import net.minecraft.util.hit.BlockHitResult; +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 net.minecraft.world.World; + +public class ReFramedFenceBlock extends ConnectingReFramedBlock { + + public static final VoxelShape[] FENCE_VOXELS; + + public ReFramedFenceBlock(Settings settings) { + super(settings); + } + + @Override + protected boolean connectsTo(BlockState state, boolean fs, Direction dir) { + return fs || state.isIn(BlockTags.FENCES) + || (state.getBlock() instanceof FenceGateBlock && FenceGateBlock.canWallConnect(state, dir)); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + VoxelShape shape = FENCE_VOXELS[0]; + for (Direction dir: Direction.Type.HORIZONTAL) { + if (state.get(getConnectionProperty(dir))) + shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() - 1]); + } + return shape; + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { + VoxelShape shape = FENCE_VOXELS[5]; + for (Direction dir: Direction.Type.HORIZONTAL) { + if (state.get(getConnectionProperty(dir))) + shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() + 4]); + } + return shape; + } + + @Override + public VoxelShape getCameraCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getOutlineShape(state, world, pos, context); + } + + @Override + public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) { + return getOutlineShape(state, view, pos, ShapeContext.absent()); + } + + @Override + public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { + return false; + } + + 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; + if (world.isClient) { + ItemStack itemStack = player.getStackInHand(hand); + return itemStack.isOf(Items.LEAD) ? ActionResult.SUCCESS : ActionResult.PASS; + } else { + return LeadItem.attachHeldMobsToBlock(player, world, pos); + } + } + + static { + VoxelShape POST = createCuboidShape(6, 0, 6, 10, 16, 10); + VoxelShape POST_COLLISION = createCuboidShape(6, 0, 6, 10, 24, 10); + VoxelShape SIDE = VoxelShapes.combineAndSimplify( + createCuboidShape(7, 12, 0, 9, 15, 6), + createCuboidShape(7, 6, 0, 9, 9, 6), + BooleanBiFunction.OR + ); + VoxelShape SIDE_COLLISION = createCuboidShape(7, 0, 0, 9, 24, 6); + FENCE_VOXELS = VoxelHelper.VoxelListBuilder.create(POST, 5) + .add(SIDE) + .add(VoxelHelper::mirrorZ) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::mirrorX) + .add(POST_COLLISION) + .add(SIDE_COLLISION) + .add(VoxelHelper::mirrorZ) + .add(VoxelHelper::rotateY) + .add(VoxelHelper::mirrorX) + .build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java index 6ea5dd2..34d10c1 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedPaneBlock.java @@ -1,122 +1,39 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.util.VoxelHelper; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.PaneBlock; import net.minecraft.block.ShapeContext; -import net.minecraft.item.ItemPlacementContext; import net.minecraft.registry.tag.BlockTags; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.BooleanProperty; -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.util.shape.VoxelShapes; import net.minecraft.world.BlockView; -import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; -import org.jetbrains.annotations.Nullable; -import static net.minecraft.state.property.Properties.*; - -public class ReFramedPaneBlock extends WaterloggableReFramedBlock { +public class ReFramedPaneBlock extends ConnectingReFramedBlock { public static final VoxelShape[] PANE_VOXELS; public ReFramedPaneBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState() - .with(EAST, false) - .with(NORTH, false) - .with(WEST, false) - .with(SOUTH, false) - ); - } - - @Override - protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder.add(EAST, NORTH, SOUTH, WEST)); - } - - @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); - if (dir == Direction.DOWN) return new_state; - - for (Direction side: Direction.Type.HORIZONTAL) { - BlockState neighbor = world.getBlockState(pos.offset(side)); - new_state = new_state.with(getPaneProperty(side), connectsTo( - neighbor, - neighbor.isSideSolidFullSquare(world, pos.offset(side), side.getOpposite()) - )); - } - return new_state; - } - - @Override - public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { - BlockState state = super.getPlacementState(ctx); - World world = ctx.getWorld(); - BlockPos pos = ctx.getBlockPos(); - - for (Direction dir: Direction.Type.HORIZONTAL) { - BlockState neighbor = world.getBlockState(pos.offset(dir)); - state = state.with(getPaneProperty(dir), connectsTo( - neighbor, - neighbor.isSideSolidFullSquare(world, pos.offset(dir), dir.getOpposite()) - )); - } - 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 VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { VoxelShape shape = PANE_VOXELS[0]; for (Direction dir: Direction.Type.HORIZONTAL) { - if (state.get(getPaneProperty(dir))) + if (state.get(getConnectionProperty(dir))) shape = VoxelShapes.union(shape, PANE_VOXELS[dir.ordinal() - 1]); } return shape; } @Override - public BlockState rotate(BlockState state, BlockRotation rotation) { - return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) -> - s.with(getPaneProperty(rotation.rotate(dir)), state.get(getPaneProperty(dir))) - , (prev, next) -> next); - } - - @Override - public BlockState mirror(BlockState state, BlockMirror mirror) { - return Direction.Type.HORIZONTAL.stream().reduce(state, (s, dir) -> - s.with(getPaneProperty(mirror.apply(dir)), state.get(getPaneProperty(dir))) - , (prev, next) -> next); - } - - public static boolean connectsTo(BlockState state, boolean fs) { + protected boolean connectsTo(BlockState state, boolean fs, Direction dir) { return !cannotConnect(state) && fs || state.getBlock() instanceof PaneBlock || state.isIn(BlockTags.WALLS); } - public static BooleanProperty getPaneProperty(Direction dir) { - return switch (dir) { - case NORTH -> NORTH; - case EAST -> EAST; - case SOUTH -> SOUTH; - case WEST -> WEST; - default -> null; - }; - } - static { VoxelShape POST = createCuboidShape(7, 0, 7, 9, 16, 9); VoxelShape SIDE = createCuboidShape(7, 0, 0, 9, 16, 7); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarBlock.java index 9b9a379..ed520c3 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedPillarBlock.java @@ -1,38 +1,21 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.util.VoxelHelper; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; -import net.minecraft.item.ItemPlacementContext; -import net.minecraft.state.StateManager; -import net.minecraft.util.BlockMirror; -import net.minecraft.util.BlockRotation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.BlockView; -import org.jetbrains.annotations.Nullable; import static net.minecraft.state.property.Properties.AXIS; -public class ReFramedPillarBlock extends WaterloggableReFramedBlock { +public class ReFramedPillarBlock extends PillarReFramedBlock { public static final VoxelShape[] PILLAR_VOXELS; public ReFramedPillarBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y)); - } - - @Override - protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder.add(AXIS)); - } - - @Override - public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { - return super.getPlacementState(ctx).with(AXIS, ctx.getSide().getAxis()); } @Override @@ -44,16 +27,6 @@ public class ReFramedPillarBlock extends WaterloggableReFramedBlock { return PILLAR_VOXELS[axis.ordinal()]; } - @Override - public BlockState rotate(BlockState state, BlockRotation rotation) { - return state.with(AXIS, rotation.rotate(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis()); - } - - @Override - public BlockState mirror(BlockState state, BlockMirror mirror) { - return state.with(AXIS, mirror.apply(Direction.get(Direction.AxisDirection.POSITIVE, state.get(AXIS))).getAxis()); - } - static { final VoxelShape PILLAR = createCuboidShape(0, 4, 4, 16, 12, 12); PILLAR_VOXELS = VoxelHelper.VoxelListBuilder.create(PILLAR, 3) diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedPostBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedPostBlock.java new file mode 100644 index 0000000..14c053f --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedPostBlock.java @@ -0,0 +1,37 @@ +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 net.minecraft.state.property.Properties.AXIS; + +public class ReFramedPostBlock extends PillarReFramedBlock { + + public static final VoxelShape[] POST_VOXELS; + + public ReFramedPostBlock(Settings settings) { + super(settings); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getPillarShape(state.get(AXIS)); + } + + public static VoxelShape getPillarShape(Direction.Axis axis) { + return POST_VOXELS[axis.ordinal()]; + } + + static { + final VoxelShape POST = createCuboidShape(0, 6, 6, 16, 10, 10); + POST_VOXELS = VoxelHelper.VoxelListBuilder.create(POST, 3) + .add(VoxelHelper::rotateZ) + .add(VoxelHelper::rotateX) + .build(); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedPostFenceBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedPostFenceBlock.java new file mode 100644 index 0000000..a90423d --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedPostFenceBlock.java @@ -0,0 +1,152 @@ +package fr.adrien1106.reframed.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.FenceGateBlock; +import net.minecraft.block.ShapeContext; +import net.minecraft.entity.ai.pathing.NavigationType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.item.LeadItem; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.state.StateManager; +import net.minecraft.util.ActionResult; +import net.minecraft.util.BlockMirror; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +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 net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import org.jetbrains.annotations.Nullable; + +import static fr.adrien1106.reframed.block.ConnectingReFramedBlock.getConnectionProperty; +import static fr.adrien1106.reframed.block.ConnectingReFramedBlock.placementState; +import static fr.adrien1106.reframed.block.ReFramedFenceBlock.FENCE_VOXELS; +import static net.minecraft.state.property.Properties.*; +import static net.minecraft.state.property.Properties.WEST; + +public class ReFramedPostFenceBlock extends WaterloggableReFramedDoubleBlock { + + public ReFramedPostFenceBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState() + .with(EAST, false) + .with(NORTH, false) + .with(WEST, false) + .with(SOUTH, false) + ); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + 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); + if (dir == Direction.DOWN) return new_state; + + return placementState(new_state, world, pos, this::connectsTo); + } + + @Override + public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) { + BlockState state = super.getPlacementState(ctx); + World world = ctx.getWorld(); + BlockPos pos = ctx.getBlockPos(); + + return placementState(state, world, pos, this::connectsTo); + } + + @Override + 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))) + , (prev, next) -> next); + } + + @Override + 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))) + , (prev, next) -> next); + } + + private boolean connectsTo(BlockState state, boolean fs, Direction dir) { + return fs || state.isIn(BlockTags.FENCES) + || (state.getBlock() instanceof FenceGateBlock && FenceGateBlock.canWallConnect(state, dir)); + } + + @Override + public VoxelShape getShape(BlockState state, int i) { + if (i == 1) return FENCE_VOXELS[0]; + VoxelShape shape = VoxelShapes.empty(); + for (Direction dir: Direction.Type.HORIZONTAL) { + if (state.get(getConnectionProperty(dir))) + shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() - 1]); + } + return shape; + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + VoxelShape shape = FENCE_VOXELS[0]; + for (Direction dir: Direction.Type.HORIZONTAL) { + if (state.get(getConnectionProperty(dir))) + shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() - 1]); + } + return shape; + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { + VoxelShape shape = FENCE_VOXELS[5]; + for (Direction dir: Direction.Type.HORIZONTAL) { + if (state.get(getConnectionProperty(dir))) + shape = VoxelShapes.union(shape, FENCE_VOXELS[dir.ordinal() + 4]); + } + return shape; + } + + @Override + public VoxelShape getCameraCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return getOutlineShape(state, world, pos, context); + } + + @Override + public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) { + return getOutlineShape(state, view, pos, ShapeContext.absent()); + } + + @Override + public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { + return false; + } + + 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; + if (world.isClient) { + ItemStack itemStack = player.getStackInHand(hand); + return itemStack.isOf(Items.LEAD) ? ActionResult.SUCCESS : ActionResult.PASS; + } else { + return LeadItem.attachHeldMobsToBlock(player, world, pos); + } + } + +} diff --git a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java index 6aed4ed..4bb9123 100644 --- a/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java +++ b/src/main/java/fr/adrien1106/reframed/client/ReFramedClient.java @@ -134,6 +134,16 @@ public class ReFramedClient implements ClientModInitializer { 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"))); + // 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"))); + // 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"))); //item model assignments (in lieu of models/item/___.json) @@ -157,6 +167,9 @@ public class ReFramedClient implements ClientModInitializer { 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); } private void privateInit() { diff --git a/src/main/java/fr/adrien1106/reframed/generator/GBlockTag.java b/src/main/java/fr/adrien1106/reframed/generator/GBlockTag.java index cae2d8e..0d017e2 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GBlockTag.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GBlockTag.java @@ -19,6 +19,8 @@ public class GBlockTag extends BlockTagProvider { providers.put(ReFramedPillarsWallBlock.class, new PillarsWall()); providers.put(ReFramedWallBlock.class, new Wall()); providers.put(ReFramedPaneBlock.class, new Pane()); + providers.put(ReFramedFenceBlock.class, new Fence()); + providers.put(ReFramedPostFenceBlock.class, new PostFence()); } public GBlockTag(FabricDataOutput output, CompletableFuture registries) { diff --git a/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java b/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java index 4b0c049..84b5862 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GBlockstate.java @@ -38,6 +38,9 @@ public class GBlockstate extends FabricModelProvider { providers.put(ReFramedTrapdoorBlock.class, new Trapdoor()); providers.put(ReFramedDoorBlock.class, new Door()); providers.put(ReFramedButtonBlock.class, new Button()); + providers.put(ReFramedPostBlock.class, new Post()); + providers.put(ReFramedFenceBlock.class, new Fence()); + providers.put(ReFramedPostFenceBlock.class, new PostFence()); } public GBlockstate(FabricDataOutput output) { diff --git a/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java b/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java index ed156b1..650fe86 100644 --- a/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java +++ b/src/main/java/fr/adrien1106/reframed/generator/GRecipe.java @@ -40,6 +40,9 @@ public class GRecipe extends FabricRecipeProvider { providers.put(ReFramedTrapdoorBlock.class, new Trapdoor()); providers.put(ReFramedDoorBlock.class, new Door()); providers.put(ReFramedButtonBlock.class, new Button()); + providers.put(ReFramedPostBlock.class, new Post()); + providers.put(ReFramedFenceBlock.class, new Fence()); + providers.put(ReFramedPostFenceBlock.class, new PostFence()); providers.put(ReFramedBlueprintItem.class, new Blueprint()); providers.put(ReFramedHammerItem.class, new Hammer()); providers.put(ReFramedScrewdriverItem.class, new Screwdriver()); diff --git a/src/main/java/fr/adrien1106/reframed/generator/block/Fence.java b/src/main/java/fr/adrien1106/reframed/generator/block/Fence.java new file mode 100644 index 0000000..fea8a79 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/generator/block/Fence.java @@ -0,0 +1,73 @@ +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.generator.TagGetter; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.data.client.BlockStateSupplier; +import net.minecraft.data.client.MultipartBlockStateSupplier; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +import java.util.List; + +import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.state.property.Properties.*; + +public class Fence implements RecipeSetter, TagGetter, BlockStateProvider { + + @Override + public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 4); + ShapedRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, convertible, 4) + .pattern("I-I") + .pattern("I-I") + .input('I', ReFramed.CUBE) + .input('-', Blocks.BAMBOO) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible)) + .offerTo(exporter); + } + + @Override + public List> getTags() { + return List.of(BlockTags.FENCES, BlockTags.WOODEN_FENCES); + } + + @Override + public BlockStateSupplier getMultipart(Block block) { + Identifier side_on = ReFramed.id("fence_side_on_special"); + Identifier side_off = ReFramed.id("fence_side_off_special"); + return MultipartBlockStateSupplier.create(block) + .with(GBlockstate.variant(ReFramed.id("fence_core_special"), true, R0, R0)) + // SIDE ON + .with(GBlockstate.when(NORTH, true), + GBlockstate.variant(side_on, true, R0, R0)) + .with(GBlockstate.when(EAST, true), + GBlockstate.variant(side_on, true, R0, R90)) + .with(GBlockstate.when(SOUTH, true), + GBlockstate.variant(side_on, true, R0, R180)) + .with(GBlockstate.when(WEST, true), + GBlockstate.variant(side_on, true, R0, R270)) + // SIDE OFF + .with(GBlockstate.when(NORTH, false), + GBlockstate.variant(side_off, true, R0, R0)) + .with(GBlockstate.when(EAST, false), + GBlockstate.variant(side_off, true, R0, R90)) + .with(GBlockstate.when(SOUTH, false), + GBlockstate.variant(side_off, true, R0, R180)) + .with(GBlockstate.when(WEST, false), + GBlockstate.variant(side_off, true, R0, R270)); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/generator/block/Post.java b/src/main/java/fr/adrien1106/reframed/generator/block/Post.java new file mode 100644 index 0000000..e7cb465 --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/generator/block/Post.java @@ -0,0 +1,50 @@ +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.ShapedRecipeJsonBuilder; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.Direction; + +import static net.minecraft.data.client.VariantSettings.Rotation.R0; +import static net.minecraft.data.client.VariantSettings.Rotation.R90; +import static net.minecraft.state.property.Properties.AXIS; + +public class Post implements RecipeSetter, BlockStateProvider { + + @Override + public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 6); + ShapedRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, convertible, 12) + .pattern("I") + .pattern("I") + .pattern("I") + .input('I', ReFramed.CUBE) + .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 model_id = ReFramed.id("post_special"); + return MultipartBlockStateSupplier.create(block) + .with(GBlockstate.when(AXIS, Direction.Axis.X), + GBlockstate.variant(model_id, true, R90, R90)) + .with(GBlockstate.when(AXIS, Direction.Axis.Y), + GBlockstate.variant(model_id, true, R0, R0)) + .with(GBlockstate.when(AXIS, Direction.Axis.Z), + GBlockstate.variant(model_id, true, R90, R0)); + } +} diff --git a/src/main/java/fr/adrien1106/reframed/generator/block/PostFence.java b/src/main/java/fr/adrien1106/reframed/generator/block/PostFence.java new file mode 100644 index 0000000..97747ea --- /dev/null +++ b/src/main/java/fr/adrien1106/reframed/generator/block/PostFence.java @@ -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 fr.adrien1106.reframed.generator.TagGetter; +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.registry.tag.BlockTags; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +import java.util.List; + +import static net.minecraft.data.client.VariantSettings.Rotation.*; +import static net.minecraft.state.property.Properties.*; + +public class PostFence implements RecipeSetter, TagGetter, BlockStateProvider { + + @Override + public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) { + RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.FENCE, 1); + ShapelessRecipeJsonBuilder + .create(RecipeCategory.BUILDING_BLOCKS, convertible, 2) + .input(ReFramed.FENCE, 2) + .criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE)) + .criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible)) + .offerTo(exporter); + } + + @Override + public List> getTags() { + return List.of(BlockTags.FENCES, BlockTags.WOODEN_FENCES); + } + + @Override + public BlockStateSupplier getMultipart(Block block) { + Identifier side_on = ReFramed.id("post_fence_side_special"); + Identifier side_off = ReFramed.id("fence_side_off_special"); + return MultipartBlockStateSupplier.create(block) + .with(GBlockstate.variant(ReFramed.id("fence_core_special"), true, R0, R0)) + // SIDE ON + .with(GBlockstate.when(NORTH, true), + GBlockstate.variant(side_on, true, R0, R0)) + .with(GBlockstate.when(EAST, true), + GBlockstate.variant(side_on, true, R0, R90)) + .with(GBlockstate.when(SOUTH, true), + GBlockstate.variant(side_on, true, R0, R180)) + .with(GBlockstate.when(WEST, true), + GBlockstate.variant(side_on, true, R0, R270)) + // SIDE OFF + .with(GBlockstate.when(NORTH, false), + GBlockstate.variant(side_off, true, R0, R0)) + .with(GBlockstate.when(EAST, false), + GBlockstate.variant(side_off, true, R0, R90)) + .with(GBlockstate.when(SOUTH, false), + GBlockstate.variant(side_off, true, R0, R180)) + .with(GBlockstate.when(WEST, false), + GBlockstate.variant(side_off, true, R0, R270)); + } +} diff --git a/src/main/resources/assets/reframed/models/block/fence/core.json b/src/main/resources/assets/reframed/models/block/fence/core.json new file mode 100644 index 0000000..c1fc907 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/fence/core.json @@ -0,0 +1,17 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [7, 0, 7], + "to": [9, 16, 9], + "faces": { + "up": {"uv": [7, 7, 9, 9], "texture": "#top", "cullface": "up"}, + "down": {"uv": [7, 7, 9, 9], "texture": "#bottom", "cullface": "down"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/fence/full/inventory.json b/src/main/resources/assets/reframed/models/block/fence/full/inventory.json new file mode 100644 index 0000000..9ca0508 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/fence/full/inventory.json @@ -0,0 +1,60 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [7, 12, 0], + "to": [9, 15, 6], + "faces": { + "north": {"uv": [7, 1, 9, 4], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 1, 16, 4], "texture": "#side"}, + "south": {"uv": [7, 1, 9, 4], "texture": "#side"}, + "west": {"uv": [0, 1, 6, 4], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [7, 6, 10], + "to": [9, 9, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -5, 0]}, + "faces": { + "north": {"uv": [7, 7, 9, 10], "texture": "#side", "cullface": "south"}, + "east": {"uv": [10, 7, 16, 10], "texture": "#side"}, + "south": {"uv": [7, 7, 9, 10], "texture": "#side", "cullface": "south"}, + "west": {"uv": [0, 7, 6, 10], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [7, 12, 10], + "to": [9, 15, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 10]}, + "faces": { + "north": {"uv": [7, 1, 9, 4], "texture": "#side"}, + "east": {"uv": [10, 1, 16, 4], "texture": "#side"}, + "south": {"uv": [7, 1, 9, 4], "texture": "#side", "cullface": "south"}, + "west": {"uv": [0, 1, 6, 4], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [7, 6, 0], + "to": [9, 9, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -5, -10]}, + "faces": { + "north": {"uv": [7, 7, 9, 10], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 7, 16, 10], "texture": "#side"}, + "south": {"uv": [7, 7, 9, 10], "texture": "#side"}, + "west": {"uv": [0, 7, 6, 10], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/fence/full/side_bars.json b/src/main/resources/assets/reframed/models/block/fence/full/side_bars.json new file mode 100644 index 0000000..020fa7c --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/fence/full/side_bars.json @@ -0,0 +1,34 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [7, 12, 0], + "to": [9, 15, 6], + "faces": { + "north": {"uv": [7, 1, 9, 4], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 1, 16, 4], "texture": "#side"}, + "south": {"uv": [7, 1, 9, 4], "texture": "#side"}, + "west": {"uv": [0, 1, 6, 4], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [7, 6, 0], + "to": [9, 9, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -5, -10]}, + "faces": { + "north": {"uv": [7, 7, 9, 10], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 7, 16, 10], "texture": "#side"}, + "south": {"uv": [7, 7, 9, 10], "texture": "#side"}, + "west": {"uv": [0, 7, 6, 10], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/fence/full/side_core.json b/src/main/resources/assets/reframed/models/block/fence/full/side_core.json new file mode 100644 index 0000000..8dc1b0d --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/fence/full/side_core.json @@ -0,0 +1,62 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [6, 0, 6], + "to": [7, 16, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, -1]}, + "faces": { + "north": {"uv": [9, 0, 10, 16], "texture": "#side"}, + "west": {"uv": [6, 0, 7, 16], "texture": "#side"}, + "up": {"uv": [6, 6, 7, 7], "texture": "#top", "cullface": "up"}, + "down": {"uv": [6, 9, 7, 10], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [7, 0, 6], + "to": [9, 6, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 0, -1]}, + "faces": { + "north": {"uv": [7, 10, 9, 16], "texture": "#side"}, + "down": {"uv": [7, 9, 9, 10], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [7, 9, 6], + "to": [9, 12, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 6, -1]}, + "faces": { + "north": {"uv": [7, 4, 9, 7], "texture": "#side"} + } + }, + { + "from": [7, 12, 6], + "to": [9, 15, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 9, -1]}, + "faces": { + "north": {"uv": [7, 1, 9, 4], "texture": "#side"} + } + }, + { + "from": [7, 6, 6], + "to": [9, 9, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 3, -1]}, + "faces": { + "north": {"uv": [7, 7, 9, 10], "texture": "#side"} + } + }, + { + "from": [7, 15, 6], + "to": [9, 16, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 10, -1]}, + "faces": { + "north": {"uv": [7, 0, 9, 1], "texture": "#side"}, + "up": {"uv": [7, 6, 9, 7], "texture": "#top", "cullface": "up"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/fence/inventory.json b/src/main/resources/assets/reframed/models/block/fence/inventory.json new file mode 100644 index 0000000..3fd2053 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/fence/inventory.json @@ -0,0 +1,68 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [7, 12, 10], + "to": [9, 15, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 1, 0]}, + "faces": { + "east": {"uv": [0, 1, 6, 4], "texture": "#side"}, + "south": {"uv": [7, 1, 9, 4], "texture": "#side", "cullface": "south"}, + "west": {"uv": [10, 1, 16, 4], "texture": "#side"}, + "up": {"uv": [7, 10, 9, 16], "texture": "#top"}, + "down": {"uv": [7, 0, 9, 6], "texture": "#bottom"} + } + }, + { + "from": [7, 6, 10], + "to": [9, 9, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -5, 0]}, + "faces": { + "east": {"uv": [0, 7, 6, 10], "texture": "#side"}, + "south": {"uv": [7, 2, 9, 5], "texture": "#side", "cullface": "south"}, + "west": {"uv": [10, 7, 16, 10], "texture": "#side"}, + "up": {"uv": [7, 10, 9, 16], "texture": "#top"}, + "down": {"uv": [7, 0, 9, 6], "texture": "#bottom"} + } + }, + { + "from": [7, 12, 0], + "to": [9, 15, 6], + "faces": { + "north": {"uv": [7, 1, 9, 4], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 1, 16, 4], "texture": "#side"}, + "west": {"uv": [0, 1, 6, 4], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [7, 6, 0], + "to": [9, 9, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -5, -10]}, + "faces": { + "north": {"uv": [7, 7, 9, 10], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 7, 16, 10], "texture": "#side"}, + "west": {"uv": [0, 7, 6, 10], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [6, 0, 6], + "to": [10, 16, 10], + "faces": { + "north": {"uv": [6, 0, 10, 16], "texture": "#side"}, + "east": {"uv": [6, 0, 10, 16], "texture": "#side"}, + "south": {"uv": [6, 0, 10, 16], "texture": "#side", "cullface": "south"}, + "west": {"uv": [6, 0, 10, 16], "texture": "#side"}, + "up": {"uv": [6, 6, 10, 10], "texture": "#top"}, + "down": {"uv": [6, 6, 10, 10], "texture": "#bottom"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/fence/side_off.json b/src/main/resources/assets/reframed/models/block/fence/side_off.json new file mode 100644 index 0000000..1c71bbe --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/fence/side_off.json @@ -0,0 +1,20 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [6, 0, 6], + "to": [9, 16, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, -1]}, + "faces": { + "north": {"uv": [7, 0, 10, 16], "texture": "#side"}, + "west": {"uv": [6, 0, 7, 16], "texture": "#side"}, + "up": {"uv": [6, 6, 9, 7], "texture": "#top", "cullface": "up"}, + "down": {"uv": [6, 9, 9, 10], "texture": "#bottom", "cullface": "down"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/fence/side_on.json b/src/main/resources/assets/reframed/models/block/fence/side_on.json new file mode 100644 index 0000000..aac6165 --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/fence/side_on.json @@ -0,0 +1,69 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [7, 12, 0], + "to": [9, 15, 6], + "faces": { + "north": {"uv": [7, 1, 9, 4], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 1, 16, 4], "texture": "#side"}, + "west": {"uv": [0, 1, 6, 4], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [7, 6, 0], + "to": [9, 9, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [0, -5, -10]}, + "faces": { + "north": {"uv": [7, 7, 9, 10], "texture": "#side", "cullface": "north"}, + "east": {"uv": [10, 7, 16, 10], "texture": "#side"}, + "west": {"uv": [0, 7, 6, 10], "texture": "#side"}, + "up": {"uv": [7, 0, 9, 6], "texture": "#top"}, + "down": {"uv": [7, 10, 9, 16], "texture": "#bottom"} + } + }, + { + "from": [6, 0, 6], + "to": [7, 16, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [-1, 0, -1]}, + "faces": { + "north": {"uv": [9, 0, 10, 16], "texture": "#side"}, + "west": {"uv": [6, 0, 7, 16], "texture": "#side"}, + "up": {"uv": [6, 6, 7, 7], "texture": "#top", "cullface": "up"}, + "down": {"uv": [6, 9, 7, 10], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [7, 0, 6], + "to": [9, 6, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 0, -1]}, + "faces": { + "north": {"uv": [7, 10, 9, 16], "texture": "#side"}, + "down": {"uv": [7, 9, 9, 10], "texture": "#bottom", "cullface": "down"} + } + }, + { + "from": [7, 9, 6], + "to": [9, 12, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 6, -1]}, + "faces": { + "north": {"uv": [7, 4, 9, 7], "texture": "#side"} + } + }, + { + "from": [7, 15, 6], + "to": [9, 16, 7], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 10, -1]}, + "faces": { + "north": {"uv": [7, 0, 9, 1], "texture": "#side"}, + "up": {"uv": [7, 6, 9, 7], "texture": "#top", "cullface": "up"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/reframed/models/block/post.json b/src/main/resources/assets/reframed/models/block/post.json new file mode 100644 index 0000000..82ad85e --- /dev/null +++ b/src/main/resources/assets/reframed/models/block/post.json @@ -0,0 +1,21 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [6, 0, 6], + "to": [10, 16, 10], + "faces": { + "north": {"uv": [6, 0, 10, 16], "texture": "#side"}, + "east": {"uv": [4, 0, 10, 16], "texture": "#side"}, + "south": {"uv": [6, 0, 10, 16], "texture": "#side"}, + "west": {"uv": [6, 0, 10, 16], "texture": "#side"}, + "up": {"uv": [6, 6, 10, 10], "texture": "#top", "cullface": "up"}, + "down": {"uv": [6, 6, 10, 10], "texture": "#bottom", "cullface": "down"} + } + } + ] +} \ No newline at end of file