feat: added post fence and postfence frames

This commit is contained in:
Adrien1106 2024-06-13 01:28:28 +02:00
parent 1061431af7
commit 535fd6151e
24 changed files with 1027 additions and 117 deletions

View File

@ -21,10 +21,8 @@ or based on preferences add the person(s) to the project
### What Shapes are planed to be added ### 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: Currently, the list of shapes to be added is pretty simple as the mod is still under development:
- Fence
- Pressure Plate - Pressure Plate
- Carpet (maybe redundant with Layer) - Carpet (maybe redundant with Layer)
- Post
- Half Slab (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) - Slabs Stair (a stair with one end being of a second theme, might be done in multiple blocks)

View File

@ -37,7 +37,18 @@ public class ReFramed implements ModInitializer {
public static final String MODID = "reframed"; public static final String MODID = "reframed";
public static final ArrayList<Block> BLOCKS = new ArrayList<>(); public static final ArrayList<Block> BLOCKS = new ArrayList<>();
public static Block CUBE, 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<Item> ITEMS = new ArrayList<>(); public static final ArrayList<Item> ITEMS = new ArrayList<>();
public static Item HAMMER, SCREWDRIVER, BLUEPRINT, BLUEPRINT_WRITTEN; 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))); TRAPDOOR = registerBlock("trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR)));
DOOR = registerBlock("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR))); DOOR = registerBlock("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR)));
BUTTON = registerBlock("button" , new ReFramedButtonBlock(cp(Blocks.OAK_BUTTON))); 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))); HAMMER = registerItem("hammer" , new ReFramedHammerItem(new Item.Settings().maxCount(1)));
SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1))); SCREWDRIVER = registerItem("screwdriver" , new ReFramedScrewdriverItem(new Item.Settings().maxCount(1)));

View File

@ -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<Block, BlockState> 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<BlockState, Boolean, Direction, Boolean> 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;
}
}

View File

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

View File

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

View File

@ -1,122 +1,39 @@
package fr.adrien1106.reframed.block; package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.VoxelHelper; import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.PaneBlock; import net.minecraft.block.PaneBlock;
import net.minecraft.block.ShapeContext; import net.minecraft.block.ShapeContext;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.registry.tag.BlockTags; 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.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes; import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView; 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 ConnectingReFramedBlock {
public class ReFramedPaneBlock extends WaterloggableReFramedBlock {
public static final VoxelShape[] PANE_VOXELS; public static final VoxelShape[] PANE_VOXELS;
public ReFramedPaneBlock(Settings settings) { public ReFramedPaneBlock(Settings settings) {
super(settings); super(settings);
setDefaultState(getDefaultState()
.with(EAST, false)
.with(NORTH, false)
.with(WEST, false)
.with(SOUTH, false)
);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> 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 @Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
VoxelShape shape = PANE_VOXELS[0]; VoxelShape shape = PANE_VOXELS[0];
for (Direction dir: Direction.Type.HORIZONTAL) { 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]); shape = VoxelShapes.union(shape, PANE_VOXELS[dir.ordinal() - 1]);
} }
return shape; return shape;
} }
@Override @Override
public BlockState rotate(BlockState state, BlockRotation rotation) { protected boolean connectsTo(BlockState state, boolean fs, Direction dir) {
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) {
return !cannotConnect(state) && fs || state.getBlock() instanceof PaneBlock || state.isIn(BlockTags.WALLS); 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 { static {
VoxelShape POST = createCuboidShape(7, 0, 7, 9, 16, 9); VoxelShape POST = createCuboidShape(7, 0, 7, 9, 16, 9);
VoxelShape SIDE = createCuboidShape(7, 0, 0, 9, 16, 7); VoxelShape SIDE = createCuboidShape(7, 0, 0, 9, 16, 7);

View File

@ -1,38 +1,21 @@
package fr.adrien1106.reframed.block; package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.util.VoxelHelper; import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext; 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.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static net.minecraft.state.property.Properties.AXIS; 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 static final VoxelShape[] PILLAR_VOXELS;
public ReFramedPillarBlock(Settings settings) { public ReFramedPillarBlock(Settings settings) {
super(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 @Override
@ -44,16 +27,6 @@ public class ReFramedPillarBlock extends WaterloggableReFramedBlock {
return PILLAR_VOXELS[axis.ordinal()]; 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 { static {
final VoxelShape PILLAR = createCuboidShape(0, 4, 4, 16, 12, 12); final VoxelShape PILLAR = createCuboidShape(0, 4, 4, 16, 12, 12);
PILLAR_VOXELS = VoxelHelper.VoxelListBuilder.create(PILLAR, 3) PILLAR_VOXELS = VoxelHelper.VoxelListBuilder.create(PILLAR, 3)

View File

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

View File

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

View File

@ -134,6 +134,16 @@ public class ReFramedClient implements ClientModInitializer {
HELPER.addReFramedModel("button_inventory" , HELPER.auto(new Identifier("block/button_inventory"))); HELPER.addReFramedModel("button_inventory" , HELPER.auto(new Identifier("block/button_inventory")));
HELPER.addReFramedModel("button" , HELPER.auto(new Identifier("block/button"))); HELPER.addReFramedModel("button" , HELPER.auto(new Identifier("block/button")));
HELPER.addReFramedModel("button_pressed" , HELPER.auto(new Identifier("block/button_pressed"))); 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) //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("trapdoor_bottom" , ReFramed.TRAPDOOR);
HELPER.assignItemModel("door_inventory" , ReFramed.DOOR); HELPER.assignItemModel("door_inventory" , ReFramed.DOOR);
HELPER.assignItemModel("button_inventory" , ReFramed.BUTTON); 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() { private void privateInit() {

View File

@ -19,6 +19,8 @@ public class GBlockTag extends BlockTagProvider {
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall()); providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
providers.put(ReFramedWallBlock.class, new Wall()); providers.put(ReFramedWallBlock.class, new Wall());
providers.put(ReFramedPaneBlock.class, new Pane()); providers.put(ReFramedPaneBlock.class, new Pane());
providers.put(ReFramedFenceBlock.class, new Fence());
providers.put(ReFramedPostFenceBlock.class, new PostFence());
} }
public GBlockTag(FabricDataOutput output, CompletableFuture<WrapperLookup> registries) { public GBlockTag(FabricDataOutput output, CompletableFuture<WrapperLookup> registries) {

View File

@ -38,6 +38,9 @@ public class GBlockstate extends FabricModelProvider {
providers.put(ReFramedTrapdoorBlock.class, new Trapdoor()); providers.put(ReFramedTrapdoorBlock.class, new Trapdoor());
providers.put(ReFramedDoorBlock.class, new Door()); providers.put(ReFramedDoorBlock.class, new Door());
providers.put(ReFramedButtonBlock.class, new Button()); 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) { public GBlockstate(FabricDataOutput output) {

View File

@ -40,6 +40,9 @@ public class GRecipe extends FabricRecipeProvider {
providers.put(ReFramedTrapdoorBlock.class, new Trapdoor()); providers.put(ReFramedTrapdoorBlock.class, new Trapdoor());
providers.put(ReFramedDoorBlock.class, new Door()); providers.put(ReFramedDoorBlock.class, new Door());
providers.put(ReFramedButtonBlock.class, new Button()); 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(ReFramedBlueprintItem.class, new Blueprint());
providers.put(ReFramedHammerItem.class, new Hammer()); providers.put(ReFramedHammerItem.class, new Hammer());
providers.put(ReFramedScrewdriverItem.class, new Screwdriver()); providers.put(ReFramedScrewdriverItem.class, new Screwdriver());

View File

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

View File

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

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 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<TagKey<Block>> 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));
}
}

View File

@ -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"}
}
}
]
}

View File

@ -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"}
}
}
]
}

View File

@ -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"}
}
}
]
}

View File

@ -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"}
}
}
]
}

View File

@ -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"}
}
}
]
}

View File

@ -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"}
}
}
]
}

View File

@ -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"}
}
}
]
}

View File

@ -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"}
}
}
]
}