new block and better additivity #24

Merged
Adrien1106 merged 6 commits from dev into master 2024-07-01 23:32:01 +02:00
20 changed files with 398 additions and 100 deletions

View File

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

View File

@ -41,7 +41,7 @@ public class ReFramed implements ModInitializer {
SMALL_CUBE, SMALL_CUBES_STEP, SMALL_CUBE, SMALL_CUBES_STEP,
STAIR, STAIRS_CUBE, STAIR, STAIRS_CUBE,
HALF_STAIR, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, HALF_STAIRS_CUBE_STAIR, HALF_STAIRS_STEP_STAIR, HALF_STAIR, HALF_STAIRS_SLAB, HALF_STAIRS_STAIR, HALF_STAIRS_CUBE_STAIR, HALF_STAIRS_STEP_STAIR,
SLAB, SLABS_CUBE, SLABS_STAIR, SLABS_OUTER_STAIR, SLABS_INNER_STAIR, SLABS_HALF_LAYER, SLAB, SLABS_CUBE, SLABS_STAIR, SLABS_OUTER_STAIR, SLABS_INNER_STAIR, SLABS_HALF_LAYER, SLABS_LAYER,
HALF_SLAB, HALF_SLABS_SLAB, HALF_SLAB, HALF_SLABS_SLAB,
STEP, STEPS_SLAB, STEPS_CROSS, STEPS_HALF_LAYER, STEP, STEPS_SLAB, STEPS_CROSS, STEPS_HALF_LAYER,
LAYER, HALF_LAYER, LAYER, HALF_LAYER,
@ -80,6 +80,7 @@ public class ReFramed implements ModInitializer {
SLABS_OUTER_STAIR = registerBlock("slabs_outer_stair" , new ReFramedSlabsOuterStairBlock(cp(Blocks.OAK_STAIRS))); SLABS_OUTER_STAIR = registerBlock("slabs_outer_stair" , new ReFramedSlabsOuterStairBlock(cp(Blocks.OAK_STAIRS)));
SLABS_INNER_STAIR = registerBlock("slabs_inner_stair" , new ReFramedSlabsInnerStairBlock(cp(Blocks.OAK_STAIRS))); SLABS_INNER_STAIR = registerBlock("slabs_inner_stair" , new ReFramedSlabsInnerStairBlock(cp(Blocks.OAK_STAIRS)));
SLABS_HALF_LAYER = registerBlock("slabs_half_layer" , new ReFramedSlabsHalfLayerBlock(cp(Blocks.OAK_SLAB))); SLABS_HALF_LAYER = registerBlock("slabs_half_layer" , new ReFramedSlabsHalfLayerBlock(cp(Blocks.OAK_SLAB)));
SLABS_LAYER = registerBlock("slabs_layer" , new ReFramedSlabsLayerBlock(cp(Blocks.OAK_SLAB)));
HALF_SLAB = registerBlock("half_slab" , new ReFramedHalfSlabBlock(cp(Blocks.OAK_SLAB))); HALF_SLAB = registerBlock("half_slab" , new ReFramedHalfSlabBlock(cp(Blocks.OAK_SLAB)));
HALF_SLABS_SLAB = registerBlock("half_slabs_slab" , new ReFramedHalfSlabsSlabBlock(cp(Blocks.OAK_SLAB))); HALF_SLABS_SLAB = registerBlock("half_slabs_slab" , new ReFramedHalfSlabsSlabBlock(cp(Blocks.OAK_SLAB)));
STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB))); STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB)));

View File

@ -48,8 +48,9 @@ public abstract class CornerDoubleReFramedBlock extends WaterloggableReFramedDou
public BlockState rotate(BlockState state, BlockRotation rotation) { public BlockState rotate(BlockState state, BlockRotation rotation) {
Corner corner = state.get(CORNER); Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE)); Direction face = corner.getDirection(state.get(CORNER_FACE));
corner = corner.rotate(rotation);
return state return state
.with(CORNER, corner.rotate(rotation)) .with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(rotation.rotate(face))); .with(CORNER_FACE, corner.getDirectionIndex(rotation.rotate(face)));
} }
@ -58,8 +59,9 @@ public abstract class CornerDoubleReFramedBlock extends WaterloggableReFramedDou
public BlockState mirror(BlockState state, BlockMirror mirror) { public BlockState mirror(BlockState state, BlockMirror mirror) {
Corner corner = state.get(CORNER); Corner corner = state.get(CORNER);
Direction face = corner.getDirection(state.get(CORNER_FACE)); Direction face = corner.getDirection(state.get(CORNER_FACE));
corner = corner.mirror(mirror);
return state return state
.with(CORNER, corner.mirror(mirror)) .with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(mirror.apply(face))); .with(CORNER_FACE, corner.getDirectionIndex(mirror.apply(face)));
} }

View File

@ -0,0 +1,57 @@
package fr.adrien1106.reframed.block;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager;
import net.minecraft.util.BlockMirror;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
import static net.minecraft.state.property.Properties.FACING;
public abstract class FacingDoubleReFramedBlock extends WaterloggableReFramedDoubleBlock {
public FacingDoubleReFramedBlock(AbstractBlock.Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
}
@Override
protected void appendProperties(StateManager.Builder< Block, BlockState > builder) {
super.appendProperties(builder.add(FACING));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
return super.getPlacementState(ctx)
.with(FACING, ctx.getSide().getOpposite());
}
@Override
@SuppressWarnings("deprecation")
public abstract VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context);
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state
.with(FACING, rotation.rotate(state.get(FACING)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(FACING, mirror.apply(state.get(FACING)));
}
@Override
public abstract VoxelShape getShape(BlockState state, int i);
}

View File

@ -24,7 +24,8 @@ public abstract class HalfLayerDoubleReFramedBlock extends EdgeDoubleReFramedBlo
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) { public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
List<ItemStack> drops = super.getDroppedStacks(state, builder); List<ItemStack> drops = super.getDroppedStacks(state, builder);
drops.add(new ItemStack(ReFramed.HALF_LAYER, state.get(LAYERS)-1)); if (state.get(LAYERS) > 1)
drops.add(new ItemStack(ReFramed.HALF_LAYER, state.get(LAYERS)-1));
return drops; return drops;
} }

View File

@ -1,62 +1,30 @@
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 fr.adrien1106.reframed.block.ReFramedHalfSlabBlock.getHalfSlabShape; import static fr.adrien1106.reframed.block.ReFramedHalfSlabBlock.getHalfSlabShape;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape; import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static net.minecraft.state.property.Properties.FACING; import static net.minecraft.state.property.Properties.FACING;
public class ReFramedHalfSlabsSlabBlock extends WaterloggableReFramedDoubleBlock { public class ReFramedHalfSlabsSlabBlock extends FacingDoubleReFramedBlock {
public static VoxelShape[] HALF_SLAB_COMP_SHAPES; public static VoxelShape[] HALF_SLAB_COMP_SHAPES;
public ReFramedHalfSlabsSlabBlock(Settings settings) { public ReFramedHalfSlabsSlabBlock(Settings settings) {
super(settings); super(settings);
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
} }
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(FACING));
}
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
return super.getPlacementState(ctx)
.with(FACING, ctx.getSide().getOpposite());
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getSlabShape(state.get(FACING)); return getSlabShape(state.get(FACING));
} }
@Override
@SuppressWarnings("deprecation")
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state
.with(FACING, rotation.rotate(state.get(FACING)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.with(FACING, mirror.apply(state.get(FACING)));
}
@Override @Override
public VoxelShape getShape(BlockState state, int i) { public VoxelShape getShape(BlockState state, int i) {
Direction face = state.get(FACING); Direction face = state.get(FACING);

View File

@ -73,6 +73,13 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
ReFramed.SMALL_CUBE.getDefaultState().with(CORNER, corner.getOpposite(dir)) ReFramed.SMALL_CUBE.getDefaultState().with(CORNER, corner.getOpposite(dir))
); );
if (block == ReFramed.SLAB)
return ReFramed.SLAB.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SLAB.getDefaultState().with(FACING, dir.getOpposite())
);
return false; return false;
} }
@ -135,6 +142,7 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|| new_state.isOf(ReFramed.HALF_STAIRS_CUBE_STAIR) || new_state.isOf(ReFramed.HALF_STAIRS_CUBE_STAIR)
|| new_state.isOf(ReFramed.HALF_STAIRS_STEP_STAIR) || new_state.isOf(ReFramed.HALF_STAIRS_STEP_STAIR)
) return Map.of(1, 1); ) return Map.of(1, 1);
if (new_state.isOf(ReFramed.SLABS_INNER_STAIR)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.HALF_STAIRS_STAIR)) if (new_state.isOf(ReFramed.HALF_STAIRS_STAIR))
return Map.of( return Map.of(
1, 1,

View File

@ -1,5 +1,6 @@
package fr.adrien1106.reframed.block; package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.VoxelHelper; import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -15,8 +16,8 @@ import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder; import static fr.adrien1106.reframed.util.VoxelHelper.VoxelListBuilder;
import static net.minecraft.state.property.Properties.FACING; import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
import static net.minecraft.state.property.Properties.LAYERS; import static net.minecraft.state.property.Properties.*;
public class ReFramedLayerBlock extends LayeredReFramedBlock { public class ReFramedLayerBlock extends LayeredReFramedBlock {
@ -34,7 +35,11 @@ public class ReFramedLayerBlock extends LayeredReFramedBlock {
@Override @Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return LAYER_VOXELS[state.get(FACING).getId() * 8 + state.get(LAYERS) - 1]; return getLayerShape(state.get(FACING), state.get(LAYERS));
}
public static VoxelShape getLayerShape(Direction facing, int layers) {
return LAYER_VOXELS[facing.getId() * 8 + layers - 1];
} }
@Override @Override
@ -42,6 +47,15 @@ public class ReFramedLayerBlock extends LayeredReFramedBlock {
BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos()); BlockState previous = ctx.getWorld().getBlockState(ctx.getBlockPos());
BlockState state = super.getPlacementState(ctx); BlockState state = super.getPlacementState(ctx);
if (previous.isOf(this)) return state; if (previous.isOf(this)) return state;
if (previous.isOf(ReFramed.SLAB))
return ReFramed.SLABS_LAYER.getDefaultState()
.with(FACING, previous.get(FACING))
.with(WATERLOGGED, previous.get(WATERLOGGED));
if (previous.isOf(ReFramed.SLABS_LAYER))
return previous.with(HALF_LAYERS, previous.get(HALF_LAYERS) + 1);
return state.with(FACING, ctx.getSide().getOpposite()); return state.with(FACING, ctx.getSide().getOpposite());
} }

View File

@ -1,6 +1,8 @@
package fr.adrien1106.reframed.block; package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge; import fr.adrien1106.reframed.util.blocks.Edge;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -19,8 +21,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Map; import java.util.Map;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE; import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.EDGE_FACE;
import static net.minecraft.state.property.Properties.*; import static net.minecraft.state.property.Properties.*;
public class ReFramedSlabBlock extends WaterloggableReFramedBlock { public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
@ -57,16 +58,15 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
&& block != ReFramed.SMALL_CUBE && block != ReFramed.SMALL_CUBE
&& block != ReFramed.HALF_STAIR && block != ReFramed.HALF_STAIR
&& block != ReFramed.HALF_LAYER && block != ReFramed.HALF_LAYER
&& block != ReFramed.LAYER
) return false; ) return false;
// check if the player is clicking on the inner part of the block // check if the player is clicking on the inner part of the block
return ReFramed.SLABS_CUBE return matchesShape(
.matchesShape( context.getHitPos(),
context.getHitPos(), context.getBlockPos(),
context.getBlockPos(), state.with(FACING, state.get(FACING).getOpposite())
ReFramed.SLABS_CUBE.getDefaultState().with(AXIS, state.get(FACING).getAxis()), );
state.get(FACING).getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
);
} }
@Nullable @Nullable
@ -89,6 +89,72 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
.with(WATERLOGGED, current_state.get(WATERLOGGED)); .with(WATERLOGGED, current_state.get(WATERLOGGED));
} }
if (current_state.isOf(ReFramed.HALF_STAIR)) {
Corner corner = current_state.get(CORNER);
Direction face = corner.getDirection(current_state.get(CORNER_FACE));
corner = corner.change(face);
return ReFramed.SLABS_INNER_STAIR.getDefaultState()
.with(CORNER, corner)
.with(CORNER_FACE, corner.getDirectionIndex(face.getOpposite()))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(ReFramed.STEP)) {
Edge edge = current_state.get(EDGE),
placed = BlockHelper.getPlacementEdge(ctx),
new_edge;
Direction face = edge.getFirstDirection(),
other = edge.getSecondDirection().getOpposite();
if (!ReFramed.STEP.matchesShape(
ctx.getHitPos(),
ctx.getBlockPos(),
current_state.with(EDGE, new_edge = edge.getOpposite(face))
)
&& ctx.getSide() != other.getOpposite()
&& (placed.getAxis() == edge.getAxis()
|| ctx.getSide() == other
|| !placed.hasDirection(other))
) {
new_edge = edge.getOpposite(edge.getSecondDirection());
other = edge.getFirstDirection().getOpposite();
}
return ReFramed.SLABS_STAIR.getDefaultState()
.with(EDGE, new_edge)
.with(EDGE_FACE, new_edge.getDirectionIndex(other))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
if (current_state.isOf(ReFramed.SMALL_CUBE)) {
Corner corner = current_state.get(CORNER);
Edge placed = BlockHelper.getPlacementEdge(ctx);
Direction face;
Corner new_corner;
if (!corner.hasDirection(face = ctx.getSide())) {
int i = 0;
do {
face = corner.getDirection(i);
new_corner = corner.change(face);
} while (!ReFramed.SMALL_CUBE.matchesShape(
ctx.getHitPos(),
ctx.getBlockPos(),
current_state.with(CORNER, new_corner)
) && ++i < 3);
if (i == 3) {
face = placed.getOtherDirection(corner.getMatchingDirection(placed)).getOpposite();
new_corner = corner.change(face);
}
} else new_corner = corner.change(face);
return ReFramed.SLABS_OUTER_STAIR.getDefaultState()
.with(CORNER, new_corner)
.with(CORNER_FACE, new_corner.getDirectionIndex(face.getOpposite()))
.with(WATERLOGGED, current_state.get(WATERLOGGED));
}
return super.getPlacementState(ctx).with(FACING, ctx.getSide().getOpposite()); return super.getPlacementState(ctx).with(FACING, ctx.getSide().getOpposite());
} }

View File

@ -0,0 +1,96 @@
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.VoxelHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.context.LootContextParameterSet;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import java.util.List;
import static fr.adrien1106.reframed.block.ReFramedLayerBlock.getLayerShape;
import static fr.adrien1106.reframed.block.ReFramedSlabBlock.getSlabShape;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
import static net.minecraft.state.property.Properties.FACING;
public class ReFramedSlabsLayerBlock extends FacingDoubleReFramedBlock {
public static VoxelShape[] HALF_LAYER_SHAPES;
public ReFramedSlabsLayerBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(HALF_LAYERS, 1));
}
@Override
@SuppressWarnings("deprecation")
public List<ItemStack> getDroppedStacks(BlockState state, LootContextParameterSet.Builder builder) {
List<ItemStack> drops = super.getDroppedStacks(state, builder);
if (state.get(HALF_LAYERS) > 1)
drops.add(new ItemStack(ReFramed.LAYER, state.get(HALF_LAYERS)-1));
return drops;
}
@Override
@SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
) return false;
return block_item.getBlock() == ReFramed.LAYER && state.get(HALF_LAYERS) < 4;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(HALF_LAYERS));
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getLayerShape(state.get(FACING), state.get(HALF_LAYERS) + 4);
}
@Override
public VoxelShape getShape(BlockState state, int i) {
Direction face = state.get(FACING);
return i == 2
? HALF_LAYER_SHAPES[face.getId() * 4 + state.get(HALF_LAYERS)-1]
: getSlabShape(face);
}
static {
VoxelHelper.VoxelListBuilder builder = VoxelHelper.VoxelListBuilder.create(createCuboidShape(0, 8, 0, 16, 10, 16), 24)
.add(createCuboidShape(0, 8, 0, 16, 12, 16))
.add(createCuboidShape(0, 8, 0, 16, 14, 16))
.add(createCuboidShape(0, 8, 0, 16, 16, 16));
for (int i = 0; i < 4; i++) {
builder.add(i, VoxelHelper::mirrorY);
}
for (int i = 0; i < 4; i++) {
builder.add(i, VoxelHelper::rotateX);
}
for (int i = 0; i < 4; i++) {
builder.add(i, VoxelHelper::rotateCX);
}
for (int i = 0; i < 4; i++) {
builder.add(i, VoxelHelper::rotateCZ);
}
for (int i = 0; i < 4; i++) {
builder.add(i, VoxelHelper::rotateZ);
}
HALF_LAYER_SHAPES = builder.build();
}
}

View File

@ -4,6 +4,8 @@ import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.VoxelHelper; import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.blocks.BlockHelper;
import fr.adrien1106.reframed.util.blocks.Corner; import fr.adrien1106.reframed.util.blocks.Corner;
import fr.adrien1106.reframed.util.blocks.Edge;
import fr.adrien1106.reframed.util.blocks.StairShape;
import net.minecraft.block.Block; 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;
@ -45,51 +47,51 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean canReplace(BlockState state, ItemPlacementContext context) { public boolean canReplace(BlockState state, ItemPlacementContext context) {
if (context.getPlayer() == null) return false; if (context.getPlayer() == null
|| context.getPlayer().isSneaking()
|| !(context.getStack().getItem() instanceof BlockItem block_item)
) return false;
Block block = block_item.getBlock();
Corner corner = state.get(CORNER); Corner corner = state.get(CORNER);
return !( if (block == this)
context.getPlayer().isSneaking() return matchesShape(
|| !(context.getStack().getItem() instanceof BlockItem block_item) context.getHitPos(),
|| ( context.getBlockPos(),
!( getDefaultState().with(CORNER, corner.change(corner.getFirstDirection()))
block_item.getBlock() == ReFramed.HALF_STAIR ) || matchesShape(
&& !(corner.hasDirection(context.getSide()) context.getHitPos(),
|| (corner.hasDirection(context.getSide().getOpposite()) context.getBlockPos(),
&& BlockHelper.cursorMatchesFace( getDefaultState().with(CORNER, corner.change(corner.getSecondDirection()))
getOutlineShape(state, context.getWorld(), context.getBlockPos(), null), ) || matchesShape(
BlockHelper.getRelativePos(context.getHitPos(), context.getBlockPos()) context.getHitPos(),
) context.getBlockPos(),
) getDefaultState().with(CORNER, corner.change(corner.getThirdDirection()))
) );
if (block == ReFramed.HALF_STAIR || block == ReFramed.SLAB) {
corner = corner.getOpposite();
Direction face = corner.getFirstDirection();
Edge edge = corner.getEdge(face);
if (ReFramed.STAIR.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.STAIR.getDefaultState()
.with(EDGE, edge)
.with(
STAIR_SHAPE,
face.getDirection() == Direction.AxisDirection.POSITIVE
? StairShape.INNER_LEFT
: StairShape.INNER_RIGHT
) )
&& !( )) return block == ReFramed.SLAB || !matchesShape(
block_item.getBlock() == this context.getHitPos(),
&& ( context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP getDefaultState().with(CORNER, corner)
.matchesShape( );
context.getHitPos(), }
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getFirstDirection())), return false;
corner.getFirstDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ReFramed.SMALL_CUBES_STEP
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getSecondDirection())),
corner.getSecondDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
|| ReFramed.SMALL_CUBES_STEP
.matchesShape(
context.getHitPos(),
context.getBlockPos(),
ReFramed.SMALL_CUBES_STEP.getDefaultState().with(EDGE, corner.getEdge(corner.getThirdDirection())),
corner.getThirdDirection().getDirection() == Direction.AxisDirection.POSITIVE ? 1 : 2
)
)
)
)
);
} }
@Override @Override
@ -163,7 +165,9 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
@Override @Override
public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) { public Map<Integer, Integer> getThemeMap(BlockState state, BlockState new_state) {
if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)) return Map.of(1, 2); if (new_state.isOf(ReFramed.HALF_STAIRS_SLAB)
|| new_state.isOf(ReFramed.SLABS_OUTER_STAIR)
) return Map.of(1, 2);
if (new_state.isOf(ReFramed.SMALL_CUBES_STEP)) if (new_state.isOf(ReFramed.SMALL_CUBES_STEP))
return Map.of( return Map.of(
1, 1,

View File

@ -63,7 +63,10 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
); );
// allow replacing with stair // allow replacing with stair
if (block != this && block != ReFramed.STAIR) return false; if (block != this
&& block != ReFramed.STAIR
&& block != ReFramed.SLAB
) return false;
return ReFramed.STAIR return ReFramed.STAIR
.matchesShape( .matchesShape(
@ -186,7 +189,8 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
if (new_state.isOf(ReFramed.STEPS_CROSS) if (new_state.isOf(ReFramed.STEPS_CROSS)
|| new_state.isOf(ReFramed.STEPS_HALF_LAYER) || new_state.isOf(ReFramed.STEPS_HALF_LAYER)
) return Map.of(1, 1); ) return Map.of(1, 1);
if (new_state.isOf(ReFramed.STAIRS_CUBE)) return Map.of(1, 2); if (new_state.isOf(ReFramed.STAIRS_CUBE)
|| new_state.isOf(ReFramed.SLABS_STAIR)) return Map.of(1, 2);
if (new_state.isOf(ReFramed.STEPS_SLAB)) if (new_state.isOf(ReFramed.STEPS_SLAB))
return Map.of( return Map.of(
1, 1,

View File

@ -60,8 +60,7 @@ public class ReFramedStepsCrossBlock extends WaterloggableReFramedDoubleBlock {
@Override @Override
public VoxelShape getShape(BlockState state, int i) { public VoxelShape getShape(BlockState state, int i) {
// return getStepShape(i == 1 ? state.get(EDGE): state.get(EDGE).opposite()); return getStepShape(i == 1 ? state.get(EDGE): state.get(EDGE).opposite());
return getOutlineShape(state, null, null, null);
} }
static { static {

View File

@ -208,6 +208,12 @@ public class ReFramedClient implements ClientModInitializer {
HELPER.addReFramedModel("half_slab" , HELPER.auto(ReFramed.id("block/half_slab/default"))); HELPER.addReFramedModel("half_slab" , HELPER.auto(ReFramed.id("block/half_slab/default")));
// HALF SLABS SLAB // HALF SLABS SLAB
HELPER.addReFramedModel("half_slabs_slab" , HELPER.autoDouble(ReFramed.id("block/half_slab/default"), ReFramed.id("block/half_slab/complement"))); HELPER.addReFramedModel("half_slabs_slab" , HELPER.autoDouble(ReFramed.id("block/half_slab/default"), ReFramed.id("block/half_slab/complement")));
// SLABS LAYER
HELPER.addReFramedModel("slabs_layer_2" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_2")));
HELPER.addReFramedModel("slabs_layer_4" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_4")));
HELPER.addReFramedModel("slabs_layer_6" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_6")));
HELPER.addReFramedModel("slabs_layer_8" , HELPER.autoDouble(new Identifier("block/slab"), ReFramed.id("block/layer_top/layer_8")));
// item model assignments (in lieu of models/item/___.json) // item model assignments (in lieu of models/item/___.json)
@ -245,6 +251,7 @@ public class ReFramedClient implements ClientModInitializer {
HELPER.assignItemModel("steps_half_inventory" , ReFramed.STEPS_HALF_LAYER); HELPER.assignItemModel("steps_half_inventory" , ReFramed.STEPS_HALF_LAYER);
HELPER.assignItemModel("half_slab" , ReFramed.HALF_SLAB); HELPER.assignItemModel("half_slab" , ReFramed.HALF_SLAB);
HELPER.assignItemModel("half_slabs_slab" , ReFramed.HALF_SLABS_SLAB); HELPER.assignItemModel("half_slabs_slab" , ReFramed.HALF_SLABS_SLAB);
HELPER.assignItemModel("slabs_layer_2" , ReFramed.SLABS_LAYER);
} }
private void privateInit() { private void privateInit() {

View File

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

View File

@ -33,6 +33,7 @@ public class GBlockstate extends FabricModelProvider {
providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair()); providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair());
providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair()); providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair());
providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer()); providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer());
providers.put(ReFramedSlabsLayerBlock.class, new SlabsLayer());
providers.put(ReFramedHalfSlabBlock.class, new HalfSlab()); providers.put(ReFramedHalfSlabBlock.class, new HalfSlab());
providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab()); providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab());
providers.put(ReFramedSmallCubeBlock.class, new SmallCube()); providers.put(ReFramedSmallCubeBlock.class, new SmallCube());

View File

@ -35,6 +35,7 @@ public class GRecipe extends FabricRecipeProvider {
providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair()); providers.put(ReFramedSlabsOuterStairBlock.class, new SlabsOuterStair());
providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair()); providers.put(ReFramedSlabsInnerStairBlock.class, new SlabsInnerStair());
providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer()); providers.put(ReFramedSlabsHalfLayerBlock.class, new SlabsHalfLayer());
providers.put(ReFramedSlabsLayerBlock.class, new SlabsLayer());
providers.put(ReFramedHalfSlabBlock.class, new HalfSlab()); providers.put(ReFramedHalfSlabBlock.class, new HalfSlab());
providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab()); providers.put(ReFramedHalfSlabsSlabBlock.class, new HalfSlabsSlab());
providers.put(ReFramedSmallCubeBlock.class, new SmallCube()); providers.put(ReFramedSmallCubeBlock.class, new SmallCube());

View File

@ -0,0 +1,58 @@
package fr.adrien1106.reframed.generator.block;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.BlockStateProvider;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.RecipeSetter;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.block.Block;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.item.ItemConvertible;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.HALF_LAYERS;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static net.minecraft.state.property.Properties.FACING;
public class SlabsLayer implements RecipeSetter, BlockStateProvider {
@Override
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 2);
ShapelessRecipeJsonBuilder
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 1)
.input(ReFramed.SLAB)
.input(ReFramed.LAYER)
.criterion(FabricRecipeProvider.hasItem(ReFramed.CUBE), FabricRecipeProvider.conditionsFromItem(ReFramed.CUBE))
.criterion(FabricRecipeProvider.hasItem(convertible), FabricRecipeProvider.conditionsFromItem(convertible))
.offerTo(exporter);
}
@Override
public MultipartBlockStateSupplier getMultipart(Block block) {
String model_pattern = "slabs_layer_x_special";
MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(block);
for (int i = 1; i <= 4; i++) {
Identifier model = ReFramed.id(model_pattern.replace("x", i * 2 + ""));
supplier
.with(GBlockstate.when(FACING, Direction.DOWN, HALF_LAYERS, i),
GBlockstate.variant(model, true, R0, R0))
.with(GBlockstate.when(FACING, Direction.SOUTH, HALF_LAYERS, i),
GBlockstate.variant(model, true, R90, R0))
.with(GBlockstate.when(FACING, Direction.UP, HALF_LAYERS, i),
GBlockstate.variant(model, true, R180, R0))
.with(GBlockstate.when(FACING, Direction.NORTH, HALF_LAYERS, i),
GBlockstate.variant(model, true, R270, R0))
.with(GBlockstate.when(FACING, Direction.WEST, HALF_LAYERS, i),
GBlockstate.variant(model, true, R90, R90))
.with(GBlockstate.when(FACING, Direction.EAST, HALF_LAYERS, i),
GBlockstate.variant(model, true, R90, R270));
}
return supplier;
}
}

View File

@ -12,4 +12,6 @@ public class BlockProperties {
public static final IntProperty CORNER_FACE = IntProperty.of("face", 0, 2); public static final IntProperty CORNER_FACE = IntProperty.of("face", 0, 2);
public static final IntProperty CORNER_FEATURE = IntProperty.of("corner_feature", 0, 1); public static final IntProperty CORNER_FEATURE = IntProperty.of("corner_feature", 0, 1);
public static final EnumProperty<StairShape> STAIR_SHAPE = EnumProperty.of("shape", StairShape.class); public static final EnumProperty<StairShape> STAIR_SHAPE = EnumProperty.of("shape", StairShape.class);
public static final IntProperty HALF_LAYERS = IntProperty.of("layers", 1, 4);
} }

View File

@ -154,4 +154,8 @@ public enum Corner implements StringIdentifiable {
third_direction == face ? opposite : third_direction third_direction == face ? opposite : third_direction
); );
} }
public Direction getMatchingDirection(Edge edge) {
return hasDirection(edge.getSecondDirection()) ? edge.getSecondDirection() : edge.getFirstDirection();
}
} }