Compare commits
3 Commits
fa44408836
...
d5369823d9
Author | SHA1 | Date | |
---|---|---|---|
d5369823d9 | |||
c6f2244826 | |||
72c9c3511b |
@ -4,7 +4,7 @@ import fr.altarik.CreateTag
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "com.modrinth.minotaur" version "2.+"
|
id "com.modrinth.minotaur" version "2.+"
|
||||||
id 'fabric-loom' version '1.5-SNAPSHOT'
|
id 'fabric-loom' version '1.6-SNAPSHOT'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
# check these on https://modmuss50.me/fabric.html
|
# check these on https://modmuss50.me/fabric.html
|
||||||
minecraft_version=1.20.4
|
minecraft_version=1.20.4
|
||||||
yarn_mappings=1.20.4+build.3
|
yarn_mappings=1.20.4+build.3
|
||||||
loader_version=0.15.6
|
loader_version=0.15.10
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
modrinth_id = jCpoCBpn
|
modrinth_id = jCpoCBpn
|
||||||
@ -16,7 +16,7 @@ mod_id = reframed
|
|||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
# check this on https://modmuss50.me/fabric.html
|
# check this on https://modmuss50.me/fabric.html
|
||||||
fabric_version=0.95.4+1.20.4
|
fabric_version=0.97.0+1.20.4
|
||||||
|
|
||||||
git_owner=Altarik
|
git_owner=Altarik
|
||||||
git_repo=ReFramed
|
git_repo=ReFramed
|
||||||
|
@ -37,7 +37,7 @@ 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, WALL;
|
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;
|
||||||
|
|
||||||
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;
|
||||||
@ -65,7 +65,8 @@ public class ReFramed implements ModInitializer {
|
|||||||
STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB)));
|
STEP = registerBlock("step" , new ReFramedStepBlock(cp(Blocks.OAK_SLAB)));
|
||||||
STEPS_SLAB = registerBlock("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB)));
|
STEPS_SLAB = registerBlock("steps_slab" , new ReFramedStepsSlabBlock(cp(Blocks.OAK_SLAB)));
|
||||||
PILLAR = registerBlock("pillar" , new ReFramedPillarBlock(cp(Blocks.OAK_FENCE)));
|
PILLAR = registerBlock("pillar" , new ReFramedPillarBlock(cp(Blocks.OAK_FENCE)));
|
||||||
WALL = registerBlock("wall" , new ReframedWallBlock(cp(Blocks.OAK_FENCE)));
|
PILLARS_WALL = registerBlock("pillars_wall" , new ReFramedPillarsWallBlock(cp(Blocks.OAK_FENCE)));
|
||||||
|
WALL = registerBlock("wall" , new ReFramedWallBlock(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)));
|
||||||
|
@ -43,16 +43,6 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
|
|||||||
setDefaultState(getDefaultState().with(LIGHT, false));
|
setDefaultState(getDefaultState().with(LIGHT, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a record for the key so that it replaces the blockstate
|
|
||||||
* which may have states that returns same models
|
|
||||||
* @param state - the state_key to generate the key from
|
|
||||||
* @return a cache key with only relevant properties
|
|
||||||
*/
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
//For addon devs: override this so your blocks don't end up trying to place my block entity, my BlockEntityType only handles blocks internal to the mod
|
//For addon devs: override this so your blocks don't end up trying to place my block entity, my BlockEntityType only handles blocks internal to the mod
|
||||||
//Just make your own BlockEntityType, it's fine, you can even use the same ReFramedEntity class
|
//Just make your own BlockEntityType, it's fine, you can even use the same ReFramedEntity class
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,12 +69,12 @@ public abstract class ReFramedDoubleBlock extends ReFramedBlock {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||||
return getCullingShape(state, view, pos);
|
return isGhost(view, pos) ? empty() : fullCube();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
||||||
return isGhost(view, pos) ? empty() : fullCube();
|
return getCollisionShape(state, view, pos, ShapeContext.absent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,18 +29,11 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
|
|||||||
|
|
||||||
public static final VoxelShape[] HALF_STAIR_VOXELS;
|
public static final VoxelShape[] HALF_STAIR_VOXELS;
|
||||||
|
|
||||||
private record ModelCacheKey(Corner corner, int face) {}
|
|
||||||
|
|
||||||
public ReFramedHalfStairBlock(Settings settings) {
|
public ReFramedHalfStairBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0));
|
setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(CORNER,CORNER_FACE));
|
super.appendProperties(builder.add(CORNER,CORNER_FACE));
|
||||||
|
@ -22,18 +22,11 @@ import static net.minecraft.util.shape.VoxelShapes.empty;
|
|||||||
|
|
||||||
public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
||||||
|
|
||||||
private record ModelCacheKey(Corner corner, int face) {}
|
|
||||||
|
|
||||||
public ReFramedHalfStairsSlabBlock(Settings settings) {
|
public ReFramedHalfStairsSlabBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0));
|
setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN).with(CORNER_FACE, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(CORNER,CORNER_FACE));
|
super.appendProperties(builder.add(CORNER,CORNER_FACE));
|
||||||
@ -48,7 +41,7 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||||
return isGhost(view, pos) ? empty(): getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE)));
|
return isGhost(view, pos) ? empty(): getSlabShape(state.get(CORNER).getDirection(state.get(CORNER_FACE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,11 +27,6 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
|
|||||||
setDefaultState(getDefaultState().with(EDGE, NORTH_DOWN));
|
setDefaultState(getDefaultState().with(EDGE, NORTH_DOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return state.get(EDGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(EDGE));
|
super.appendProperties(builder.add(EDGE));
|
||||||
@ -44,7 +39,7 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||||
return isGhost(view, pos) ? empty(): getStairShape(state.get(EDGE), StairShape.STRAIGHT);
|
return isGhost(view, pos) ? empty(): getStairShape(state.get(EDGE), StairShape.STRAIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import net.minecraft.item.BlockItem;
|
|||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
import net.minecraft.state.StateManager;
|
import net.minecraft.state.StateManager;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
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 org.jetbrains.annotations.Nullable;
|
||||||
@ -20,18 +19,12 @@ import static net.minecraft.state.property.Properties.LAYERS;
|
|||||||
public class ReFramedLayerBlock extends ReFramedSlabBlock {
|
public class ReFramedLayerBlock extends ReFramedSlabBlock {
|
||||||
|
|
||||||
public static final VoxelShape[] LAYER_VOXELS;
|
public static final VoxelShape[] LAYER_VOXELS;
|
||||||
private record ModelCacheKey(Direction face, int layer) {}
|
|
||||||
|
|
||||||
public ReFramedLayerBlock(Settings settings) {
|
public ReFramedLayerBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
setDefaultState(getDefaultState().with(LAYERS, 1));
|
setDefaultState(getDefaultState().with(LAYERS, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return new ModelCacheKey(state.get(FACING), state.get(LAYERS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(LAYERS));
|
super.appendProperties(builder.add(LAYERS));
|
||||||
|
@ -26,11 +26,6 @@ public class ReFramedPillarBlock extends WaterloggableReFramedBlock {
|
|||||||
setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y));
|
setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return state.get(AXIS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(AXIS));
|
super.appendProperties(builder.add(AXIS));
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
package fr.adrien1106.reframed.block;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.ShapeContext;
|
||||||
|
import net.minecraft.block.enums.WallShape;
|
||||||
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
|
import net.minecraft.state.StateManager;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldAccess;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static fr.adrien1106.reframed.block.ReFramedWallBlock.*;
|
||||||
|
import static net.minecraft.state.property.Properties.*;
|
||||||
|
import static net.minecraft.util.shape.VoxelShapes.empty;
|
||||||
|
|
||||||
|
public class ReFramedPillarsWallBlock extends WaterloggableReFramedDoubleBlock {
|
||||||
|
|
||||||
|
public ReFramedPillarsWallBlock(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
setDefaultState(getDefaultState()
|
||||||
|
.with(EAST_WALL_SHAPE, WallShape.NONE)
|
||||||
|
.with(NORTH_WALL_SHAPE, WallShape.NONE)
|
||||||
|
.with(WEST_WALL_SHAPE, WallShape.NONE)
|
||||||
|
.with(SOUTH_WALL_SHAPE, WallShape.NONE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
|
super.appendProperties(builder.add(EAST_WALL_SHAPE, NORTH_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
BlockState top_state = dir == Direction.UP? other_state: world.getBlockState(pos.up());
|
||||||
|
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
|
||||||
|
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
|
||||||
|
Map<Direction, BlockState> neighbors = Direction.Type.HORIZONTAL.stream()
|
||||||
|
.collect(Collectors.toMap(d -> d, d -> {
|
||||||
|
if (d == dir) return other_state;
|
||||||
|
return world.getBlockState(pos.offset(d));
|
||||||
|
}));
|
||||||
|
return getWallState(new_state, top_state, neighbors, top_shape, fs, world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||||
|
BlockState state = super.getPlacementState(ctx);
|
||||||
|
World world = ctx.getWorld();
|
||||||
|
BlockPos pos = ctx.getBlockPos();
|
||||||
|
|
||||||
|
BlockState top_state = world.getBlockState(pos.up());
|
||||||
|
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
|
||||||
|
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
|
||||||
|
|
||||||
|
Map<Direction, BlockState> neighbors = Direction.Type.HORIZONTAL.stream()
|
||||||
|
.collect(Collectors.toMap(d -> d, d -> world.getBlockState(pos.offset(d))));
|
||||||
|
return getWallState(state, top_state, neighbors, top_shape, fs, world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
|
||||||
|
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||||
|
if (isGhost(view, pos)) return empty();
|
||||||
|
VoxelShape shape = WALL_VOXELS[9];
|
||||||
|
for (Direction dir : Direction.Type.HORIZONTAL) {
|
||||||
|
if (state.get(getWallShape(dir)) != WallShape.NONE)
|
||||||
|
shape = VoxelShapes.union(shape, WALL_VOXELS[8 + dir.ordinal()]);
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
||||||
|
return isGhost(view, pos) ? empty(): getOutlineShape(state, view, pos, ShapeContext.absent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||||
|
VoxelShape shape = WALL_VOXELS[0];
|
||||||
|
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||||
|
WallShape wall_shape = state.get(getWallShape(dir));
|
||||||
|
if (wall_shape != WallShape.NONE)
|
||||||
|
shape = VoxelShapes.union(shape, WALL_VOXELS[1 + (wall_shape.ordinal()-1) * 4 + (dir.ordinal() - 2)]);
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VoxelShape getShape(BlockState state, int i) {
|
||||||
|
if (i == 1) return WALL_VOXELS[0];
|
||||||
|
VoxelShape shape = VoxelShapes.empty();
|
||||||
|
for (Direction dir: Direction.Type.HORIZONTAL) {
|
||||||
|
WallShape wall_shape = state.get(getWallShape(dir));
|
||||||
|
if (wall_shape != WallShape.NONE)
|
||||||
|
shape = VoxelShapes.union(shape, WALL_VOXELS[1 + (wall_shape.ordinal()-1) * 4 + (dir.ordinal() - 2)]);
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
}
|
@ -33,11 +33,6 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
|
|||||||
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
|
setDefaultState(getDefaultState().with(FACING, Direction.DOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return state.get(FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(FACING));
|
super.appendProperties(builder.add(FACING));
|
||||||
|
@ -18,11 +18,6 @@ public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock {
|
|||||||
setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y));
|
setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return state.get(AXIS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(AXIS));
|
super.appendProperties(builder.add(AXIS));
|
||||||
|
@ -34,11 +34,6 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
|
|||||||
setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN));
|
setDefaultState(getDefaultState().with(CORNER, NORTH_EAST_DOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return state.get(CORNER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(CORNER));
|
super.appendProperties(builder.add(CORNER));
|
||||||
|
@ -25,11 +25,6 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc
|
|||||||
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN));
|
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return state.get(EDGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(EDGE));
|
super.appendProperties(builder.add(EDGE));
|
||||||
@ -42,7 +37,7 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||||
return isGhost(view, pos) ? empty(): getStepShape(state.get(EDGE));
|
return isGhost(view, pos) ? empty(): getStepShape(state.get(EDGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,18 +31,12 @@ import static fr.adrien1106.reframed.util.blocks.StairShape.*;
|
|||||||
|
|
||||||
public class ReFramedStairBlock extends WaterloggableReFramedBlock {
|
public class ReFramedStairBlock extends WaterloggableReFramedBlock {
|
||||||
public static final VoxelShape[] STAIR_VOXELS;
|
public static final VoxelShape[] STAIR_VOXELS;
|
||||||
private record ModelCacheKey(Edge edge, StairShape shape) {}
|
|
||||||
|
|
||||||
public ReFramedStairBlock(Settings settings) {
|
public ReFramedStairBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT));
|
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
|
super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
|
||||||
|
@ -22,18 +22,12 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
|
|||||||
public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
|
public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
|
||||||
|
|
||||||
private static final VoxelShape[] STAIRS_CUBE_VOXELS = VoxelListBuilder.buildFrom(STAIR_VOXELS);
|
private static final VoxelShape[] STAIRS_CUBE_VOXELS = VoxelListBuilder.buildFrom(STAIR_VOXELS);
|
||||||
private record ModelCacheKey(Edge edge, StairShape shape) {}
|
|
||||||
|
|
||||||
public ReFramedStairsCubeBlock(Settings settings) {
|
public ReFramedStairsCubeBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT));
|
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
|
super.appendProperties(builder.add(EDGE, STAIR_SHAPE));
|
||||||
|
@ -34,11 +34,6 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
|
|||||||
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN));
|
setDefaultState(getDefaultState().with(EDGE, Edge.NORTH_DOWN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return state.get(EDGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(EDGE));
|
super.appendProperties(builder.add(EDGE));
|
||||||
|
@ -22,18 +22,12 @@ import static net.minecraft.state.property.Properties.FACING;
|
|||||||
import static net.minecraft.util.shape.VoxelShapes.empty;
|
import static net.minecraft.util.shape.VoxelShapes.empty;
|
||||||
|
|
||||||
public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
||||||
private record ModelCacheKey(Direction facing, Axis axis) {}
|
|
||||||
|
|
||||||
public ReFramedStepsSlabBlock(Settings settings) {
|
public ReFramedStepsSlabBlock(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
setDefaultState(getDefaultState().with(FACING, Direction.DOWN).with(AXIS, Axis.X));
|
setDefaultState(getDefaultState().with(FACING, Direction.DOWN).with(AXIS, Axis.X));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return new ModelCacheKey(state.get(FACING), state.get(AXIS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(FACING, AXIS));
|
super.appendProperties(builder.add(FACING, AXIS));
|
||||||
@ -48,7 +42,7 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
|
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||||
return isGhost(view, pos) ? empty() : getSlabShape(state.get(FACING));
|
return isGhost(view, pos) ? empty() : getSlabShape(state.get(FACING));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,19 +15,20 @@ 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.World;
|
||||||
import net.minecraft.world.WorldAccess;
|
import net.minecraft.world.WorldAccess;
|
||||||
|
import net.minecraft.world.WorldView;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static net.minecraft.state.property.Properties.*;
|
import static net.minecraft.state.property.Properties.*;
|
||||||
|
|
||||||
public class ReframedWallBlock extends WaterloggableReFramedBlock {
|
public class ReFramedWallBlock extends WaterloggableReFramedBlock {
|
||||||
|
|
||||||
public static final VoxelShape[] WALL_VOXELS;
|
public static final VoxelShape[] WALL_VOXELS;
|
||||||
|
|
||||||
private record ModelCacheKey(boolean up, WallShape east, WallShape north, WallShape west, WallShape south) {}
|
public ReFramedWallBlock(Settings settings) {
|
||||||
|
|
||||||
public ReframedWallBlock(Settings settings) {
|
|
||||||
super(settings);
|
super(settings);
|
||||||
setDefaultState(getDefaultState()
|
setDefaultState(getDefaultState()
|
||||||
.with(UP, true)
|
.with(UP, true)
|
||||||
@ -38,17 +39,6 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getModelCacheKey(BlockState state) {
|
|
||||||
return new ModelCacheKey(
|
|
||||||
state.get(UP),
|
|
||||||
state.get(EAST_WALL_SHAPE),
|
|
||||||
state.get(NORTH_WALL_SHAPE),
|
|
||||||
state.get(WEST_WALL_SHAPE),
|
|
||||||
state.get(SOUTH_WALL_SHAPE)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(builder.add(UP, EAST_WALL_SHAPE, NORTH_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
super.appendProperties(builder.add(UP, EAST_WALL_SHAPE, NORTH_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
||||||
@ -61,34 +51,13 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
|
|||||||
BlockState top_state = dir == Direction.UP? other_state: world.getBlockState(pos.up());
|
BlockState top_state = dir == Direction.UP? other_state: world.getBlockState(pos.up());
|
||||||
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
|
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
|
||||||
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
|
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
|
||||||
if (dir == Direction.UP) {
|
|
||||||
for (Direction d : Direction.Type.HORIZONTAL) {
|
|
||||||
Property<WallShape> wall_shape = getWallShape(d);
|
|
||||||
if (state.get(wall_shape) == WallShape.NONE) continue;
|
|
||||||
new_state = new_state.with(
|
|
||||||
wall_shape,
|
|
||||||
fs
|
|
||||||
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|
|
||||||
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
|
|
||||||
? WallShape.TALL
|
|
||||||
: WallShape.LOW
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return new_state.with(UP, shouldHavePost(new_state, top_state, top_shape));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean side_full = other_state.isSideSolidFullSquare(world, moved, dir.getOpposite());
|
Map<Direction, BlockState> neighbors = Direction.Type.HORIZONTAL.stream()
|
||||||
if (shouldConnectTo(other_state, side_full, dir.getOpposite())) {
|
.collect(Collectors.toMap(d -> d, d -> {
|
||||||
Property<WallShape> wall_shape = getWallShape(dir);
|
if (d == dir) return other_state;
|
||||||
new_state = new_state.with(
|
return world.getBlockState(pos.offset(d));
|
||||||
wall_shape,
|
}));
|
||||||
fs
|
new_state = getWallState(new_state, top_state, neighbors, top_shape, fs, world, pos);
|
||||||
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|
|
||||||
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
|
|
||||||
? WallShape.TALL
|
|
||||||
: WallShape.LOW
|
|
||||||
);
|
|
||||||
} else new_state = new_state.with(getWallShape(dir), WallShape.NONE);
|
|
||||||
return new_state.with(UP, shouldHavePost(new_state, top_state, top_shape));
|
return new_state.with(UP, shouldHavePost(new_state, top_state, top_shape));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,25 +66,14 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
|
|||||||
BlockState state = super.getPlacementState(ctx);
|
BlockState state = super.getPlacementState(ctx);
|
||||||
World world = ctx.getWorld();
|
World world = ctx.getWorld();
|
||||||
BlockPos pos = ctx.getBlockPos();
|
BlockPos pos = ctx.getBlockPos();
|
||||||
|
|
||||||
BlockState top_state = world.getBlockState(pos.up());
|
BlockState top_state = world.getBlockState(pos.up());
|
||||||
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
|
boolean fs = top_state.isSideSolidFullSquare(world, pos.up(), Direction.DOWN);
|
||||||
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
|
VoxelShape top_shape = fs ? null : top_state.getCollisionShape(world, pos.up()).getFace(Direction.DOWN);
|
||||||
for (Direction dir : Direction.Type.HORIZONTAL) {
|
|
||||||
BlockPos offset = pos.offset(dir);
|
Map<Direction, BlockState> neighbors = Direction.Type.HORIZONTAL.stream()
|
||||||
BlockState neighbor = world.getBlockState(offset);
|
.collect(Collectors.toMap(d -> d, d -> world.getBlockState(pos.offset(d))));
|
||||||
boolean side_full = neighbor.isSideSolidFullSquare(world, offset, dir.getOpposite());
|
state = getWallState(state, top_state, neighbors, top_shape, fs, world, pos);
|
||||||
if (shouldConnectTo(neighbor, side_full, dir.getOpposite())) {
|
|
||||||
Property<WallShape> wall_shape = getWallShape(dir);
|
|
||||||
state = state.with(
|
|
||||||
wall_shape,
|
|
||||||
fs
|
|
||||||
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|
|
||||||
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
|
|
||||||
? WallShape.TALL
|
|
||||||
: WallShape.LOW
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state.with(UP, shouldHavePost(state, top_state, top_shape));
|
return state.with(UP, shouldHavePost(state, top_state, top_shape));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,9 +106,29 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
|
|||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldHavePost(BlockState state, BlockState top_state, VoxelShape top_shape) {
|
public static BlockState getWallState(BlockState state, BlockState top_state, Map<Direction, BlockState> neighbors, VoxelShape top_shape, boolean fs, WorldView world, BlockPos pos) {
|
||||||
|
for (Direction dir : Direction.Type.HORIZONTAL) {
|
||||||
|
BlockPos offset = pos.offset(dir);
|
||||||
|
BlockState neighbor = neighbors.get(dir);
|
||||||
|
boolean side_full = neighbor.isSideSolidFullSquare(world, offset, dir.getOpposite());
|
||||||
|
Property<WallShape> wall_shape = getWallShape(dir);
|
||||||
|
if (shouldConnectTo(neighbor, side_full, dir.getOpposite())) {
|
||||||
|
state = state.with(
|
||||||
|
wall_shape,
|
||||||
|
fs
|
||||||
|
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|
||||||
|
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
|
||||||
|
? WallShape.TALL
|
||||||
|
: WallShape.LOW
|
||||||
|
);
|
||||||
|
} else state = state.with(wall_shape, WallShape.NONE);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldHavePost(BlockState state, BlockState top_state, VoxelShape top_shape) {
|
||||||
// above has post
|
// above has post
|
||||||
if (top_state.contains(NORTH_WALL_SHAPE) && top_state.get(UP)) return true;
|
if ((top_state.contains(UP) && top_state.get(UP)) || (!top_state.contains(UP) && top_state.contains(NORTH_WALL_SHAPE))) return true;
|
||||||
|
|
||||||
if (Stream.of(Direction.SOUTH, Direction.EAST) // Opposites are different
|
if (Stream.of(Direction.SOUTH, Direction.EAST) // Opposites are different
|
||||||
.anyMatch(dir -> state.get(getWallShape(dir)) != state.get(getWallShape(dir.getOpposite())))
|
.anyMatch(dir -> state.get(getWallShape(dir)) != state.get(getWallShape(dir.getOpposite())))
|
||||||
@ -160,23 +138,22 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
|
|||||||
if (Direction.Type.HORIZONTAL.stream().allMatch(dir -> state.get(getWallShape(dir)) == WallShape.NONE))
|
if (Direction.Type.HORIZONTAL.stream().allMatch(dir -> state.get(getWallShape(dir)) == WallShape.NONE))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// tall Matching sides
|
// Matching sides
|
||||||
if (Stream.of(Direction.SOUTH, Direction.EAST)
|
if (Stream.of(Direction.SOUTH, Direction.EAST)
|
||||||
.anyMatch(dir ->
|
.anyMatch(dir ->
|
||||||
state.get(getWallShape(dir)) == WallShape.TALL
|
state.get(getWallShape(dir)) == state.get(getWallShape(dir.getOpposite()))
|
||||||
&& state.get(getWallShape(dir.getOpposite())) == WallShape.TALL
|
|
||||||
)) return false;
|
)) return false;
|
||||||
|
|
||||||
return top_state.isIn(BlockTags.WALL_POST_OVERRIDE) || top_shape == null || shouldUseTall(WALL_VOXELS[0], top_shape);
|
return top_state.isIn(BlockTags.WALL_POST_OVERRIDE) || top_shape == null || shouldUseTall(WALL_VOXELS[0], top_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldConnectTo(BlockState state, boolean side_full, Direction side) {
|
public static boolean shouldConnectTo(BlockState state, boolean side_full, Direction side) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
boolean bl = block instanceof FenceGateBlock && FenceGateBlock.canWallConnect(state, side);
|
boolean bl = block instanceof FenceGateBlock && FenceGateBlock.canWallConnect(state, side);
|
||||||
return state.isIn(BlockTags.WALLS) || !WallBlock.cannotConnect(state) && side_full || block instanceof PaneBlock || bl;
|
return state.isIn(BlockTags.WALLS) || !WallBlock.cannotConnect(state) && side_full || block instanceof PaneBlock || bl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldUseTall(VoxelShape self_shape, VoxelShape other_shape) {
|
public static boolean shouldUseTall(VoxelShape self_shape, VoxelShape other_shape) {
|
||||||
return !VoxelShapes.matchesAnywhere(
|
return !VoxelShapes.matchesAnywhere(
|
||||||
self_shape,
|
self_shape,
|
||||||
other_shape,
|
other_shape,
|
||||||
@ -184,7 +161,7 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Property<WallShape> getWallShape(Direction dir) {
|
public static Property<WallShape> getWallShape(Direction dir) {
|
||||||
return switch (dir) {
|
return switch (dir) {
|
||||||
case EAST -> EAST_WALL_SHAPE;
|
case EAST -> EAST_WALL_SHAPE;
|
||||||
case NORTH -> NORTH_WALL_SHAPE;
|
case NORTH -> NORTH_WALL_SHAPE;
|
@ -14,10 +14,6 @@ import net.minecraft.resource.ResourceType;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.ChunkSectionPos;
|
import net.minecraft.util.math.ChunkSectionPos;
|
||||||
|
|
||||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
|
|
||||||
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
|
|
||||||
import static net.minecraft.state.property.Properties.*;
|
|
||||||
|
|
||||||
public class ReFramedClient implements ClientModInitializer {
|
public class ReFramedClient implements ClientModInitializer {
|
||||||
public static final ReFramedModelProvider PROVIDER = new ReFramedModelProvider();
|
public static final ReFramedModelProvider PROVIDER = new ReFramedModelProvider();
|
||||||
|
|
||||||
@ -31,92 +27,96 @@ public class ReFramedClient implements ClientModInitializer {
|
|||||||
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
|
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
|
||||||
|
|
||||||
// CUBE
|
// CUBE
|
||||||
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube"), 2));
|
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube")));
|
||||||
// SMALL_CUBE
|
// SMALL_CUBE
|
||||||
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base"), 9, CORNER));
|
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base")));
|
||||||
// SMALL_CUBES_STEP
|
// SMALL_CUBES_STEP
|
||||||
HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base"), 9, EDGE));
|
HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base")));
|
||||||
HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base"), 4, EDGE));
|
HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base")));
|
||||||
// SLAB
|
// SLAB
|
||||||
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab"), 7, FACING));
|
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab")));
|
||||||
// SLAB_CUBE
|
// SLAB_CUBE
|
||||||
HELPER.addReFramedModel("double_slab" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"), 4, AXIS));
|
HELPER.addReFramedModel("double_slab" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top")));
|
||||||
// STAIR
|
// STAIR
|
||||||
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight"), 13, EDGE));
|
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight")));
|
||||||
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer"), 24, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer")));
|
||||||
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner"), 24, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner")));
|
||||||
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer"), 16, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer")));
|
||||||
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side"), 32, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side")));
|
||||||
// STAIRS_CUBE
|
// STAIRS_CUBE
|
||||||
HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight"), 13, EDGE));
|
HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight")));
|
||||||
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer"), 24, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer")));
|
||||||
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner"), 24, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner")));
|
||||||
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer"), 16, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer")));
|
||||||
HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side"), 32, EDGE, STAIR_SHAPE));
|
HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side")));
|
||||||
// HALF_STAIR
|
// HALF_STAIR
|
||||||
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down"), 9, CORNER, CORNER_FACE));
|
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down")));
|
||||||
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side"), 16, CORNER, CORNER_FACE));
|
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side")));
|
||||||
// HALF_STAIRS_SLAB
|
// HALF_STAIRS_SLAB
|
||||||
HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down"), 9, CORNER, CORNER_FACE));
|
HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down")));
|
||||||
HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side"), 16, CORNER, CORNER_FACE));
|
HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side")));
|
||||||
// HALF_STAIRS_STAIR
|
// HALF_STAIRS_STAIR
|
||||||
HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down"), 5, EDGE));
|
HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down")));
|
||||||
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side"), 6, EDGE));
|
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side")));
|
||||||
HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side"), 2, EDGE));
|
HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side")));
|
||||||
// STEP
|
// STEP
|
||||||
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down"), 13, EDGE));
|
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down")));
|
||||||
// STEPS_SLAB
|
// STEPS_SLAB
|
||||||
HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down"), 5, FACING, AXIS));
|
HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down")));
|
||||||
HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side"), 8, FACING, AXIS));
|
HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side")));
|
||||||
// LAYER
|
// LAYER
|
||||||
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2"), 7, FACING));
|
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2")));
|
||||||
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4"), 6, FACING));
|
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4")));
|
||||||
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6"), 6, FACING));
|
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6")));
|
||||||
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8"), 6, FACING));
|
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8")));
|
||||||
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10"), 6, FACING));
|
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10")));
|
||||||
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12"), 6, FACING));
|
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12")));
|
||||||
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14"), 6, FACING));
|
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14")));
|
||||||
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube"), 1));
|
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube")));
|
||||||
// PILLAR
|
// PILLAR
|
||||||
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar"), 4, AXIS));
|
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar")));
|
||||||
// WALL
|
// WALL
|
||||||
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default"), 1));
|
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default")));
|
||||||
// --------------------- pillar
|
// --------------------- pillar
|
||||||
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core"), 1, UP));
|
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core")));
|
||||||
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low")));
|
||||||
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall")));
|
||||||
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none")));
|
||||||
// --------------------- side
|
// --------------------- side
|
||||||
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low"), 92, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low")));
|
||||||
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall"), 92, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall")));
|
||||||
// --------------------- junction
|
// --------------------- junction
|
||||||
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low")));
|
||||||
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall")));
|
||||||
// --------------------- junction_i
|
// --------------------- junction_i
|
||||||
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i")));
|
||||||
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i")));
|
||||||
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i")));
|
||||||
// --------------------- junction_c
|
// --------------------- junction_c
|
||||||
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c")));
|
||||||
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c")));
|
||||||
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c")));
|
||||||
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c")));
|
||||||
// --------------------- junction_t
|
// --------------------- junction_t
|
||||||
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t")));
|
||||||
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t")));
|
||||||
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t")));
|
||||||
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t")));
|
||||||
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t")));
|
||||||
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t")));
|
||||||
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t")));
|
||||||
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t")));
|
||||||
// --------------------- junction_x
|
// --------------------- junction_x
|
||||||
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x")));
|
||||||
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x")));
|
||||||
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x")));
|
||||||
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x")));
|
||||||
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x")));
|
||||||
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
|
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x")));
|
||||||
|
// PILLAR WALL
|
||||||
|
HELPER.addReFramedModel("pillars_wall_inventory" , HELPER.autoDouble(ReFramed.id("block/pillar"), ReFramed.id("block/wall/full/inventory/sides")));
|
||||||
|
HELPER.addReFramedModel("pillars_wall_low" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/low"), ReFramed.id("block/wall/full/side/low")));
|
||||||
|
HELPER.addReFramedModel("pillars_wall_tall" , HELPER.autoDouble(ReFramed.id("block/wall/full/pillar/tall"), ReFramed.id("block/wall/full/side/tall")));
|
||||||
|
|
||||||
|
|
||||||
//item model assignments (in lieu of models/item/___.json)
|
//item model assignments (in lieu of models/item/___.json)
|
||||||
@ -134,6 +134,7 @@ public class ReFramedClient implements ClientModInitializer {
|
|||||||
HELPER.assignItemModel("steps_slab" , ReFramed.STEPS_SLAB);
|
HELPER.assignItemModel("steps_slab" , ReFramed.STEPS_SLAB);
|
||||||
HELPER.assignItemModel("layer_1" , ReFramed.LAYER);
|
HELPER.assignItemModel("layer_1" , ReFramed.LAYER);
|
||||||
HELPER.assignItemModel("pillar" , ReFramed.PILLAR);
|
HELPER.assignItemModel("pillar" , ReFramed.PILLAR);
|
||||||
|
HELPER.assignItemModel("pillars_wall_inventory", ReFramed.PILLARS_WALL);
|
||||||
HELPER.assignItemModel("wall_inventory" , ReFramed.WALL);
|
HELPER.assignItemModel("wall_inventory" , ReFramed.WALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ import net.minecraft.client.render.model.UnbakedModel;
|
|||||||
import net.minecraft.client.texture.Sprite;
|
import net.minecraft.client.texture.Sprite;
|
||||||
import net.minecraft.client.util.SpriteIdentifier;
|
import net.minecraft.client.util.SpriteIdentifier;
|
||||||
import net.minecraft.item.ItemConvertible;
|
import net.minecraft.item.ItemConvertible;
|
||||||
import net.minecraft.state.property.Property;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -28,18 +27,18 @@ public class ReFramedClientHelper {
|
|||||||
private final ReFramedModelProvider prov;
|
private final ReFramedModelProvider prov;
|
||||||
|
|
||||||
|
|
||||||
public UnbakedRetexturedModel auto(Identifier parent, int model_count, Property<?>... properties) {
|
public UnbakedRetexturedModel auto(Identifier parent) {
|
||||||
return new UnbakedAutoRetexturedModel(parent, model_count, properties);
|
return new UnbakedAutoRetexturedModel(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnbakedRetexturedModel json(Identifier parent, int model_count, Property<?>... properties) {
|
public UnbakedRetexturedModel json(Identifier parent) {
|
||||||
return new UnbakedJsonRetexturedModel(parent, model_count, properties);
|
return new UnbakedJsonRetexturedModel(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnbakedModel autoDouble(Identifier first, Identifier second, int model_count, Property<?>... properties) {
|
public UnbakedModel autoDouble(Identifier first, Identifier second) {
|
||||||
return new UnbakedDoubleRetexturedModel(
|
return new UnbakedDoubleRetexturedModel(
|
||||||
auto(first, model_count, properties),
|
auto(first),
|
||||||
auto(second, model_count, properties)
|
auto(second)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ import java.util.function.Supplier;
|
|||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class DoubleRetexturingBakedModel extends ForwardingBakedModel implements MultiRetexturableModel {
|
public class DoubleRetexturingBakedModel extends ForwardingBakedModel implements MultiRetexturableModel {
|
||||||
|
|
||||||
private final ForwardingBakedModel model_1, model_2;
|
private final RetexturingBakedModel model_1, model_2;
|
||||||
public DoubleRetexturingBakedModel(ForwardingBakedModel model_1, ForwardingBakedModel model_2) {
|
public DoubleRetexturingBakedModel(RetexturingBakedModel model_1, RetexturingBakedModel model_2) {
|
||||||
this.wrapped = model_1.getWrappedModel();
|
this.wrapped = model_1.getWrappedModel();
|
||||||
this.model_1 = model_1;
|
this.model_1 = model_1;
|
||||||
this.model_2 = model_2;
|
this.model_2 = model_2;
|
||||||
@ -44,7 +44,7 @@ public class DoubleRetexturingBakedModel extends ForwardingBakedModel implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ForwardingBakedModel> models() {
|
public List<RetexturingBakedModel> models() {
|
||||||
return List.of(model_1, model_2);
|
return List.of(model_1, model_2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package fr.adrien1106.reframed.client.model;
|
package fr.adrien1106.reframed.client.model;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface MultiRetexturableModel {
|
public interface MultiRetexturableModel {
|
||||||
|
|
||||||
List<ForwardingBakedModel> models();
|
List<RetexturingBakedModel> models();
|
||||||
}
|
}
|
||||||
|
@ -20,38 +20,28 @@ import net.minecraft.client.render.model.BakedModel;
|
|||||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||||
import net.minecraft.client.texture.Sprite;
|
import net.minecraft.client.texture.Sprite;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.state.property.Property;
|
|
||||||
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.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
import net.minecraft.world.BlockRenderView;
|
import net.minecraft.world.BlockRenderView;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||||
public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state, int model_count, Property<?>... properties) {
|
public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state) {
|
||||||
this.wrapped = base_model; //field from the superclass; vanilla getQuads etc. will delegate through to this
|
this.wrapped = base_model; //field from the superclass; vanilla getQuads etc. will delegate through to this
|
||||||
|
|
||||||
this.appearance_manager = tam;
|
this.appearance_manager = tam;
|
||||||
this.theme_index = theme_index;
|
this.theme_index = theme_index;
|
||||||
this.uv_lock = settings.isUvLocked();
|
this.uv_lock = settings.isUvLocked();
|
||||||
this.item_state = item_state;
|
this.item_state = item_state;
|
||||||
this.properties = properties;
|
|
||||||
|
|
||||||
BASE_MESH_CACHE = new Object2ObjectLinkedOpenHashMap<>(model_count, 0.25f) {
|
|
||||||
@Override
|
|
||||||
protected void rehash(int v) {}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final CamoAppearanceManager appearance_manager;
|
protected final CamoAppearanceManager appearance_manager;
|
||||||
protected final int theme_index;
|
protected final int theme_index;
|
||||||
protected final boolean uv_lock;
|
protected final boolean uv_lock;
|
||||||
protected final BlockState item_state;
|
protected final BlockState item_state;
|
||||||
protected final Property<?>[] properties;
|
|
||||||
|
|
||||||
protected record MeshCacheKey(Object state_key, CamoAppearance appearance, int model_id) {}
|
protected record MeshCacheKey(Object state_key, CamoAppearance appearance, int model_id) {}
|
||||||
/** cache that store retextured models */
|
/** cache that store retextured models */
|
||||||
@ -59,7 +49,11 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
protected final Cache<MeshCacheKey, Mesh> RETEXTURED_MESH_CACHE = CacheBuilder.newBuilder().maximumSize(256).build();
|
protected final Cache<MeshCacheKey, Mesh> RETEXTURED_MESH_CACHE = CacheBuilder.newBuilder().maximumSize(256).build();
|
||||||
|
|
||||||
/** cache that stores the base meshes which has the size of the amount of models */
|
/** cache that stores the base meshes which has the size of the amount of models */
|
||||||
protected final Object2ObjectLinkedOpenHashMap<Object, Mesh> BASE_MESH_CACHE;
|
protected final Object2ObjectLinkedOpenHashMap<Object, Mesh> BASE_MESH_CACHE =
|
||||||
|
new Object2ObjectLinkedOpenHashMap<>(2, 0.25f) {
|
||||||
|
@Override
|
||||||
|
protected void rehash(int v) {}
|
||||||
|
};
|
||||||
|
|
||||||
protected static final Direction[] DIRECTIONS_AND_NULL;
|
protected static final Direction[] DIRECTIONS_AND_NULL;
|
||||||
static {
|
static {
|
||||||
@ -88,15 +82,18 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
return appearance_manager.getDefaultAppearance(theme_index).getSprites(Direction.UP, 0).get(0).sprite();
|
return appearance_manager.getDefaultAppearance(theme_index).getSprites(Direction.UP, 0).get(0).sprite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getThemeIndex() {
|
||||||
|
return theme_index;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||||
BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null;
|
BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null;
|
||||||
QuadEmitter quad_emitter = context.getEmitter();
|
QuadEmitter quad_emitter = context.getEmitter();
|
||||||
List<?> model_key = Stream.of(properties).map(state::get).toList();
|
|
||||||
if(theme == null || theme.isAir()) {
|
if(theme == null || theme.isAir()) {
|
||||||
getRetexturedMesh(
|
getRetexturedMesh(
|
||||||
new MeshCacheKey(
|
new MeshCacheKey(
|
||||||
model_key,
|
hashCode(),
|
||||||
appearance_manager.getDefaultAppearance(theme_index),
|
appearance_manager.getDefaultAppearance(theme_index),
|
||||||
0
|
0
|
||||||
),
|
),
|
||||||
@ -112,7 +109,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
|
if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
|
||||||
|
|
||||||
int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, world, pos, 0);
|
int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, world, pos, 0);
|
||||||
MeshCacheKey key = new MeshCacheKey(model_key, camo, model_id);
|
MeshCacheKey key = new MeshCacheKey(hashCode(), camo, model_id);
|
||||||
// do not clutter the cache with single-use meshes
|
// do not clutter the cache with single-use meshes
|
||||||
Mesh untintedMesh = camo.hashCode() == -1 ? transformMesh(key, state) : getRetexturedMesh(key, state);
|
Mesh untintedMesh = camo.hashCode() == -1 ? transformMesh(key, state) : getRetexturedMesh(key, state);
|
||||||
|
|
||||||
@ -154,6 +151,13 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean useAmbientOcclusion(BlockRenderView view, BlockPos pos) {
|
||||||
|
if (!(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity)) return false;
|
||||||
|
CamoAppearance appearance = appearance_manager
|
||||||
|
.getCamoAppearance(view, frame_entity.getTheme(theme_index), pos, theme_index, false);
|
||||||
|
return appearance.getAO(theme_index);
|
||||||
|
}
|
||||||
|
|
||||||
protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) {
|
protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) {
|
||||||
if (RETEXTURED_MESH_CACHE.asMap().containsKey(key)) return RETEXTURED_MESH_CACHE.getIfPresent(key);
|
if (RETEXTURED_MESH_CACHE.asMap().containsKey(key)) return RETEXTURED_MESH_CACHE.getIfPresent(key);
|
||||||
Mesh mesh = transformMesh(key, state);
|
Mesh mesh = transformMesh(key, state);
|
||||||
|
@ -14,7 +14,6 @@ import net.minecraft.client.render.model.Baker;
|
|||||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||||
import net.minecraft.client.texture.Sprite;
|
import net.minecraft.client.texture.Sprite;
|
||||||
import net.minecraft.client.util.SpriteIdentifier;
|
import net.minecraft.client.util.SpriteIdentifier;
|
||||||
import net.minecraft.state.property.Property;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
@ -24,8 +23,8 @@ import java.util.function.Function;
|
|||||||
|
|
||||||
public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel {
|
public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel {
|
||||||
|
|
||||||
public UnbakedAutoRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
|
public UnbakedAutoRetexturedModel(Identifier parent) {
|
||||||
super(parent, state_count, properties);
|
super(parent);
|
||||||
item_state = Blocks.AIR.getDefaultState();
|
item_state = Blocks.AIR.getDefaultState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,9 +36,7 @@ public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel {
|
|||||||
ReFramedClient.HELPER.getCamoAppearanceManager(texture_getter),
|
ReFramedClient.HELPER.getCamoAppearanceManager(texture_getter),
|
||||||
theme_index,
|
theme_index,
|
||||||
bake_settings,
|
bake_settings,
|
||||||
item_state,
|
item_state
|
||||||
state_count,
|
|
||||||
properties
|
|
||||||
) {
|
) {
|
||||||
protected Mesh convertModel(BlockState state) {
|
protected Mesh convertModel(BlockState state) {
|
||||||
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
|
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package fr.adrien1106.reframed.client.model;
|
package fr.adrien1106.reframed.client.model;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.render.model.Baker;
|
import net.minecraft.client.render.model.Baker;
|
||||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||||
@ -41,8 +40,8 @@ public class UnbakedDoubleRetexturedModel implements UnbakedModel {
|
|||||||
@Override
|
@Override
|
||||||
public BakedModel bake(Baker baker, Function<SpriteIdentifier, Sprite> texture_getter, ModelBakeSettings model_bake_settings, Identifier identifier) {
|
public BakedModel bake(Baker baker, Function<SpriteIdentifier, Sprite> texture_getter, ModelBakeSettings model_bake_settings, Identifier identifier) {
|
||||||
return new DoubleRetexturingBakedModel(
|
return new DoubleRetexturingBakedModel(
|
||||||
(ForwardingBakedModel) model_1.bake(baker, texture_getter, model_bake_settings, identifier),
|
(RetexturingBakedModel) model_1.bake(baker, texture_getter, model_bake_settings, identifier),
|
||||||
(ForwardingBakedModel) model_2.bake(baker, texture_getter, model_bake_settings, identifier)
|
(RetexturingBakedModel) model_2.bake(baker, texture_getter, model_bake_settings, identifier)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ import net.minecraft.client.render.model.ModelBakeSettings;
|
|||||||
import net.minecraft.client.texture.Sprite;
|
import net.minecraft.client.texture.Sprite;
|
||||||
import net.minecraft.client.util.SpriteIdentifier;
|
import net.minecraft.client.util.SpriteIdentifier;
|
||||||
import net.minecraft.screen.PlayerScreenHandler;
|
import net.minecraft.screen.PlayerScreenHandler;
|
||||||
import net.minecraft.state.property.Property;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
@ -25,8 +24,8 @@ import java.util.Objects;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel {
|
public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel {
|
||||||
public UnbakedJsonRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
|
public UnbakedJsonRetexturedModel(Identifier parent) {
|
||||||
super(parent, state_count, properties);
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -45,9 +44,7 @@ public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel {
|
|||||||
ReFramedClient.HELPER.getCamoAppearanceManager(spriteLookup),
|
ReFramedClient.HELPER.getCamoAppearanceManager(spriteLookup),
|
||||||
theme_index,
|
theme_index,
|
||||||
bake_settings,
|
bake_settings,
|
||||||
item_state,
|
item_state
|
||||||
state_count,
|
|
||||||
properties
|
|
||||||
) {
|
) {
|
||||||
protected Mesh convertModel(BlockState state) {
|
protected Mesh convertModel(BlockState state) {
|
||||||
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
|
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
|
||||||
|
@ -2,7 +2,6 @@ package fr.adrien1106.reframed.client.model;
|
|||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.render.model.UnbakedModel;
|
import net.minecraft.client.render.model.UnbakedModel;
|
||||||
import net.minecraft.state.property.Property;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -15,13 +14,9 @@ public abstract class UnbakedRetexturedModel implements UnbakedModel {
|
|||||||
|
|
||||||
protected int theme_index = 1;
|
protected int theme_index = 1;
|
||||||
protected BlockState item_state;
|
protected BlockState item_state;
|
||||||
protected final int state_count;
|
|
||||||
protected final Property<?>[] properties;
|
|
||||||
|
|
||||||
public UnbakedRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
|
public UnbakedRetexturedModel(Identifier parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.state_count = state_count;
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnbakedRetexturedModel setThemeIndex(int theme_index) {
|
public UnbakedRetexturedModel setThemeIndex(int theme_index) {
|
||||||
|
@ -5,6 +5,7 @@ import com.google.common.cache.CacheBuilder;
|
|||||||
import fr.adrien1106.reframed.block.ReFramedBlock;
|
import fr.adrien1106.reframed.block.ReFramedBlock;
|
||||||
import fr.adrien1106.reframed.client.ReFramedClient;
|
import fr.adrien1106.reframed.client.ReFramedClient;
|
||||||
import fr.adrien1106.reframed.client.model.QuadPosBounds;
|
import fr.adrien1106.reframed.client.model.QuadPosBounds;
|
||||||
|
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
@ -32,18 +33,18 @@ import static net.minecraft.util.shape.VoxelShapes.combine;
|
|||||||
public class RenderHelper {
|
public class RenderHelper {
|
||||||
|
|
||||||
// self culling cache of the models not made thread local so that it is only computed once
|
// self culling cache of the models not made thread local so that it is only computed once
|
||||||
private static final Cache<CullElement, Integer[]> INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build();
|
private static final Cache<CullElement, Integer[]> INNER_CULL_MAP = CacheBuilder.newBuilder().build();
|
||||||
private record CullElement(Block block, Object state_key, int model) {}
|
private record CullElement(Block block, Object state_key, int model) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compute which quad might cull with another model quad
|
* compute which quad might cull with another model quad
|
||||||
* @param state - the state of the model
|
* @param state - the state of the model
|
||||||
* @param models - list of models on the same block
|
* @param models - list of models on the same block
|
||||||
|
* @param hash - the hash of main model
|
||||||
*/
|
*/
|
||||||
public static void computeInnerCull(BlockState state, List<ForwardingBakedModel> models) {
|
public static void computeInnerCull(BlockState state, List<RetexturingBakedModel> models, int hash) {
|
||||||
if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return;
|
if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return;
|
||||||
Object key = frame_block.getModelCacheKey(state);
|
if (INNER_CULL_MAP.asMap().containsKey(new CullElement(frame_block, hash, 1))) return;
|
||||||
if (INNER_CULL_MAP.asMap().containsKey(new CullElement(frame_block, key, 1))) return;
|
|
||||||
|
|
||||||
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
|
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
|
||||||
QuadEmitter quad_emitter = r.meshBuilder().getEmitter();
|
QuadEmitter quad_emitter = r.meshBuilder().getEmitter();
|
||||||
@ -60,12 +61,12 @@ public class RenderHelper {
|
|||||||
}).toList()).toList();
|
}).toList()).toList();
|
||||||
|
|
||||||
Integer[] cull_array;
|
Integer[] cull_array;
|
||||||
for(int self_id = 1; self_id <= model_bounds.size(); self_id++) {
|
for (int self_id = 1; self_id <= model_bounds.size(); self_id++) {
|
||||||
List<QuadPosBounds> self_bounds = model_bounds.get(self_id - 1);
|
List<QuadPosBounds> self_bounds = model_bounds.get(self_id - 1);
|
||||||
cull_array = new Integer[self_bounds.size()];
|
cull_array = new Integer[self_bounds.size()];
|
||||||
for (int self_quad = 0; self_quad < cull_array.length; self_quad++) {
|
for (int self_quad = 0; self_quad < cull_array.length; self_quad++) {
|
||||||
QuadPosBounds self_bound = self_bounds.get(self_quad);
|
QuadPosBounds self_bound = self_bounds.get(self_quad);
|
||||||
for(int other_id = 1; other_id <= model_bounds.size(); other_id++) {
|
for (int other_id = 1; other_id <= model_bounds.size(); other_id++) {
|
||||||
if (other_id == self_id) continue;
|
if (other_id == self_id) continue;
|
||||||
if (model_bounds.get(other_id - 1).stream().anyMatch(other_bound -> other_bound.equals(self_bound))) {
|
if (model_bounds.get(other_id - 1).stream().anyMatch(other_bound -> other_bound.equals(self_bound))) {
|
||||||
cull_array[self_quad] = other_id;
|
cull_array[self_quad] = other_id;
|
||||||
@ -73,15 +74,15 @@ public class RenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INNER_CULL_MAP.put(new CullElement(frame_block, key, self_id), cull_array);
|
INNER_CULL_MAP.put(new CullElement(frame_block, hash, self_id), cull_array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean shouldDrawInnerFace(BlockState state, BlockRenderView view, BlockPos pos, int quad_index, int theme_index) {
|
public static boolean shouldDrawInnerFace(BlockState state, BlockRenderView view, BlockPos pos, int quad_index, int theme_index, int hash) {
|
||||||
if ( !(state.getBlock() instanceof ReFramedBlock frame_block)
|
if (!(state.getBlock() instanceof ReFramedBlock frame_block)
|
||||||
|| !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity)
|
|| !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity)
|
||||||
) return true;
|
) return true;
|
||||||
CullElement key = new CullElement(frame_block, frame_block.getModelCacheKey(state), theme_index);
|
CullElement key = new CullElement(frame_block, hash, theme_index);
|
||||||
if (!INNER_CULL_MAP.asMap().containsKey(key)) return true;
|
if (!INNER_CULL_MAP.asMap().containsKey(key)) return true;
|
||||||
|
|
||||||
// needs to be Integer object because array is initialized with null not 0
|
// needs to be Integer object because array is initialized with null not 0
|
||||||
|
@ -14,9 +14,11 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class RebakedModel implements BakedModel {
|
public class RebakedModel implements BakedModel {
|
||||||
protected final Map<Direction, List<BakedQuad>> face_quads;
|
protected final Map<Direction, List<BakedQuad>> face_quads;
|
||||||
|
protected boolean ambient_occlusion;
|
||||||
|
|
||||||
public RebakedModel(Map<Direction, List<BakedQuad>> face_quads) {
|
public RebakedModel(Map<Direction, List<BakedQuad>> face_quads, boolean ambient_occlusion) {
|
||||||
this.face_quads = face_quads;
|
this.face_quads = face_quads;
|
||||||
|
this.ambient_occlusion = ambient_occlusion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -26,7 +28,7 @@ public class RebakedModel implements BakedModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useAmbientOcclusion() {
|
public boolean useAmbientOcclusion() {
|
||||||
return true;
|
return ambient_occlusion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,7 +16,8 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
public class GBlockTag extends BlockTagProvider {
|
public class GBlockTag extends BlockTagProvider {
|
||||||
private static final Map<Class<? extends Block>, TagGetter> providers = new HashMap<>();
|
private static final Map<Class<? extends Block>, TagGetter> providers = new HashMap<>();
|
||||||
static {
|
static {
|
||||||
providers.put(ReframedWallBlock.class, new Wall());
|
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
|
||||||
|
providers.put(ReFramedWallBlock.class, new Wall());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBlockTag(FabricDataOutput output, CompletableFuture<WrapperLookup> registries) {
|
public GBlockTag(FabricDataOutput output, CompletableFuture<WrapperLookup> registries) {
|
||||||
|
@ -32,7 +32,8 @@ public class GBlockstate extends FabricModelProvider {
|
|||||||
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
|
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
|
||||||
providers.put(ReFramedStepBlock.class, new Step());
|
providers.put(ReFramedStepBlock.class, new Step());
|
||||||
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
|
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
|
||||||
providers.put(ReframedWallBlock.class, new Wall());
|
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
|
||||||
|
providers.put(ReFramedWallBlock.class, new Wall());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBlockstate(FabricDataOutput output) {
|
public GBlockstate(FabricDataOutput output) {
|
||||||
|
@ -34,7 +34,8 @@ public class GRecipe extends FabricRecipeProvider {
|
|||||||
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
|
providers.put(ReFramedStairsCubeBlock.class, new StairsCube());
|
||||||
providers.put(ReFramedStepBlock.class, new Step());
|
providers.put(ReFramedStepBlock.class, new Step());
|
||||||
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
|
providers.put(ReFramedStepsSlabBlock.class, new StepsSlab());
|
||||||
providers.put(ReframedWallBlock.class, new Wall());
|
providers.put(ReFramedPillarsWallBlock.class, new PillarsWall());
|
||||||
|
providers.put(ReFramedWallBlock.class, new Wall());
|
||||||
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());
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
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.block.enums.WallShape.*;
|
||||||
|
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||||
|
import static net.minecraft.state.property.Properties.*;
|
||||||
|
|
||||||
|
public class PillarsWall implements RecipeSetter, TagGetter, BlockStateProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRecipe(RecipeExporter exporter, ItemConvertible convertible) {
|
||||||
|
RecipeProvider.offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, convertible, ReFramed.CUBE, 1);
|
||||||
|
ShapelessRecipeJsonBuilder
|
||||||
|
.create(RecipeCategory.BUILDING_BLOCKS, convertible, 2)
|
||||||
|
.input(ReFramed.WALL, 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.WALLS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockStateSupplier getMultipart(Block block) {
|
||||||
|
Identifier
|
||||||
|
low = ReFramed.id("pillars_wall_low_special"),
|
||||||
|
tall = ReFramed.id("pillars_wall_tall_special"),
|
||||||
|
none = ReFramed.id("wall_pillar_none_special");
|
||||||
|
return MultipartBlockStateSupplier.create(block)
|
||||||
|
// PILLAR CORE
|
||||||
|
.with(GBlockstate.variant(ReFramed.id("wall_core_special"), true, R0, R0))
|
||||||
|
// LOW
|
||||||
|
.with(GBlockstate.when(NORTH_WALL_SHAPE, LOW),
|
||||||
|
GBlockstate.variant(low, true, R0, R0))
|
||||||
|
.with(GBlockstate.when(EAST_WALL_SHAPE, LOW),
|
||||||
|
GBlockstate.variant(low, true, R0, R90))
|
||||||
|
.with(GBlockstate.when(SOUTH_WALL_SHAPE, LOW),
|
||||||
|
GBlockstate.variant(low, true, R0, R180))
|
||||||
|
.with(GBlockstate.when(WEST_WALL_SHAPE, LOW),
|
||||||
|
GBlockstate.variant(low, true, R0, R270))
|
||||||
|
// TALL
|
||||||
|
.with(GBlockstate.when(NORTH_WALL_SHAPE, TALL),
|
||||||
|
GBlockstate.variant(tall, true, R0, R0))
|
||||||
|
.with(GBlockstate.when(EAST_WALL_SHAPE, TALL),
|
||||||
|
GBlockstate.variant(tall, true, R0, R90))
|
||||||
|
.with(GBlockstate.when(SOUTH_WALL_SHAPE, TALL),
|
||||||
|
GBlockstate.variant(tall, true, R0, R180))
|
||||||
|
.with(GBlockstate.when(WEST_WALL_SHAPE, TALL),
|
||||||
|
GBlockstate.variant(tall, true, R0, R270))
|
||||||
|
// PILLAR NONE
|
||||||
|
.with(GBlockstate.when(NORTH_WALL_SHAPE, NONE),
|
||||||
|
GBlockstate.variant(none, true, R0, R0))
|
||||||
|
.with(GBlockstate.when(EAST_WALL_SHAPE, NONE),
|
||||||
|
GBlockstate.variant(none, true, R0, R90))
|
||||||
|
.with(GBlockstate.when(SOUTH_WALL_SHAPE, NONE),
|
||||||
|
GBlockstate.variant(none, true, R0, R180))
|
||||||
|
.with(GBlockstate.when(WEST_WALL_SHAPE, NONE),
|
||||||
|
GBlockstate.variant(none, true, R0, R270));
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,8 @@ public abstract class AthenaBakedModelMixin implements DynamicBakedModel, BakedM
|
|||||||
|
|
||||||
@Shadow(remap = false) @Final private Int2ObjectMap<Sprite> textures;
|
@Shadow(remap = false) @Final private Int2ObjectMap<Sprite> textures;
|
||||||
|
|
||||||
|
@Shadow public abstract boolean useAmbientOcclusion();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reuses the emitQuad method to compute the quads to be used by the frame
|
* Reuses the emitQuad method to compute the quads to be used by the frame
|
||||||
*
|
*
|
||||||
@ -77,6 +79,6 @@ public abstract class AthenaBakedModelMixin implements DynamicBakedModel, BakedM
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
return new RebakedModel(face_quads);
|
return new RebakedModel(face_quads, useAmbientOcclusion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,6 @@ public abstract class ContinuityCTMBakedModelMixin extends ForwardingBakedModel
|
|||||||
transform.getProcessingContext().reset(); // reset instead of outputting to emitter
|
transform.getProcessingContext().reset(); // reset instead of outputting to emitter
|
||||||
transform.invokeReset();
|
transform.invokeReset();
|
||||||
|
|
||||||
return new RebakedModel(face_quads);
|
return new RebakedModel(face_quads, useAmbientOcclusion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,6 @@ public abstract class IndiumAbstractBlockRenderContextMixin {
|
|||||||
private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) {
|
private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) {
|
||||||
if (face != null || quad.tag() == 0 || !(blockInfo instanceof IBlockRenderInfoMixin info) || info.getThemeIndex() == 0) return isFaceCulled(face);
|
if (face != null || quad.tag() == 0 || !(blockInfo instanceof IBlockRenderInfoMixin info) || info.getThemeIndex() == 0) return isFaceCulled(face);
|
||||||
|
|
||||||
return !RenderHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex());
|
return !RenderHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex(), info.getModelHash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo implements IBlockRenderInfoMixin {
|
public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo implements IBlockRenderInfoMixin {
|
||||||
|
|
||||||
@Unique private int theme_index = 0;
|
@Unique private int theme_index = 0;
|
||||||
|
@Unique private int model_hash = 0;
|
||||||
|
|
||||||
@Redirect(
|
@Redirect(
|
||||||
method = "shouldDrawFaceInner",
|
method = "shouldDrawFaceInner",
|
||||||
@ -36,8 +37,9 @@ public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo, int theme_index) {
|
public void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo, int theme_index, int model_hash) {
|
||||||
this.theme_index = theme_index;
|
this.theme_index = theme_index;
|
||||||
|
this.model_hash = model_hash;
|
||||||
prepareForBlock(blockState, blockPos, seed, modelAo);
|
prepareForBlock(blockState, blockPos, seed, modelAo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,4 +47,9 @@ public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo
|
|||||||
public int getThemeIndex() {
|
public int getThemeIndex() {
|
||||||
return theme_index;
|
return theme_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getModelHash() {
|
||||||
|
return model_hash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
package fr.adrien1106.reframed.mixin.compat;
|
package fr.adrien1106.reframed.mixin.compat;
|
||||||
|
|
||||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||||
|
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||||
|
import link.infra.indium.renderer.aocalc.AoCalculator;
|
||||||
import link.infra.indium.renderer.render.AbstractBlockRenderContext;
|
import link.infra.indium.renderer.render.AbstractBlockRenderContext;
|
||||||
|
import link.infra.indium.renderer.render.BlockRenderInfo;
|
||||||
import link.infra.indium.renderer.render.TerrainRenderContext;
|
import link.infra.indium.renderer.render.TerrainRenderContext;
|
||||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderContext;
|
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderContext;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@ -28,18 +32,34 @@ public abstract class IndiumTerrainRenderContextMixin extends AbstractBlockRende
|
|||||||
), remap = false,
|
), remap = false,
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderMultipleModels(BlockRenderContext ctx, CallbackInfo ci) {
|
private void renderMultipleModels(BlockRenderContext ctx, CallbackInfo ci) {
|
||||||
if (!(ctx.model() instanceof IMultipartBakedModelMixin wrapped)
|
if (!(ctx.model() instanceof IMultipartBakedModelMixin wrapped)) return;
|
||||||
|| !(wrapped.getModel(ctx.state()) instanceof MultiRetexturableModel retexturing_model)) return;
|
List<BakedModel> models = wrapped.getModels(ctx.state());
|
||||||
|
if (models.stream().noneMatch(bakedModel ->
|
||||||
|
bakedModel instanceof MultiRetexturableModel
|
||||||
|
|| bakedModel instanceof RetexturingBakedModel
|
||||||
|
)) return;
|
||||||
|
|
||||||
List<ForwardingBakedModel> models = retexturing_model.models();
|
models.forEach(model -> {
|
||||||
RenderHelper.computeInnerCull(ctx.state(), models);
|
if (model instanceof MultiRetexturableModel multi_model) {
|
||||||
int i = 0;
|
RenderHelper.computeInnerCull(ctx.state(), multi_model.models(), model.hashCode());
|
||||||
for (BakedModel model : models) {
|
multi_model.models().forEach(rexteruable_model ->
|
||||||
i++;
|
renderModel(ctx, rexteruable_model, aoCalc, blockInfo, this, model.hashCode())
|
||||||
aoCalc.clear();
|
);
|
||||||
((IBlockRenderInfoMixin) blockInfo).prepareForBlock(ctx.state(), ctx.pos(), ctx.seed(), model.useAmbientOcclusion(), i);
|
} else if (model instanceof RetexturingBakedModel rexteruable_model)
|
||||||
model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
|
renderModel(ctx, rexteruable_model, aoCalc, blockInfo, this, model.hashCode());
|
||||||
}
|
else model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
|
||||||
|
});
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static void renderModel(BlockRenderContext ctx, RetexturingBakedModel model, AoCalculator aoCalc, BlockRenderInfo block_info, RenderContext context, int model_hash) {
|
||||||
|
aoCalc.clear();
|
||||||
|
((IBlockRenderInfoMixin) block_info).prepareForBlock(
|
||||||
|
ctx.state(), ctx.pos(), ctx.seed(),
|
||||||
|
model.useAmbientOcclusion(block_info.blockView, ctx.pos()),
|
||||||
|
model.getThemeIndex(), model_hash
|
||||||
|
);
|
||||||
|
model.emitBlockQuads(block_info.blockView, block_info.blockState, block_info.blockPos, block_info.randomSupplier, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,12 @@ public abstract class AbstractBlockRenderContextMixin {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) {
|
private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) {
|
||||||
if (face != null || quad.tag() == 0 || !(blockInfo instanceof IBlockRenderInfoMixin info) || info.getThemeIndex() == 0) return isFaceCulled(face);
|
if (face != null
|
||||||
|
|| quad.tag() == 0
|
||||||
|
|| !(blockInfo instanceof IBlockRenderInfoMixin info)
|
||||||
|
|| info.getThemeIndex() == 0
|
||||||
|
) return isFaceCulled(face);
|
||||||
|
|
||||||
return !RenderHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex());
|
return !RenderHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex(), info.getModelHash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ public abstract class BlockRenderInfoMixin implements IBlockRenderInfoMixin {
|
|||||||
|
|
||||||
@Shadow public BlockRenderView blockView;
|
@Shadow public BlockRenderView blockView;
|
||||||
@Unique private int theme_index = 0;
|
@Unique private int theme_index = 0;
|
||||||
|
@Unique private int model_hash = 0;
|
||||||
|
|
||||||
@ModifyArg(method = "prepareForBlock",
|
@ModifyArg(method = "prepareForBlock",
|
||||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/RenderLayers;" +
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/RenderLayers;" +
|
||||||
@ -42,8 +43,9 @@ public abstract class BlockRenderInfoMixin implements IBlockRenderInfoMixin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Unique
|
@Unique
|
||||||
public void prepareForBlock(BlockState state, BlockPos pos, boolean ao, int theme_index) {
|
public void prepareForBlock(BlockState state, BlockPos pos, boolean ao, int theme_index, int model_hash) {
|
||||||
this.theme_index = theme_index;
|
this.theme_index = theme_index;
|
||||||
|
this.model_hash = model_hash;
|
||||||
prepareForBlock(state, pos, ao);
|
prepareForBlock(state, pos, ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,4 +53,9 @@ public abstract class BlockRenderInfoMixin implements IBlockRenderInfoMixin {
|
|||||||
public int getThemeIndex() {
|
public int getThemeIndex() {
|
||||||
return theme_index;
|
return theme_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getModelHash() {
|
||||||
|
return model_hash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ public class MultipartBakedModelMixin implements IMultipartBakedModelMixin {
|
|||||||
@Shadow @Final private List<Pair<Predicate<BlockState>, BakedModel>> components;
|
@Shadow @Final private List<Pair<Predicate<BlockState>, BakedModel>> components;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BakedModel getModel(BlockState state) {
|
public List<BakedModel> getModels(BlockState state) {
|
||||||
return components.stream().map(pair -> pair.getLeft().test(state) ? pair.getRight(): null).filter(Objects::nonNull).findAny().orElse(null);
|
return components.stream().map(pair -> pair.getLeft().test(state) ? pair.getRight(): null).filter(Objects::nonNull).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
package fr.adrien1106.reframed.mixin.render;
|
package fr.adrien1106.reframed.mixin.render;
|
||||||
|
|
||||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||||
|
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||||
|
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator;
|
||||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext;
|
import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext;
|
||||||
|
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo;
|
||||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderContext;
|
import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderContext;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@ -27,18 +31,34 @@ public abstract class TerrainRenderContextMixin extends AbstractBlockRenderConte
|
|||||||
), remap = false,
|
), remap = false,
|
||||||
cancellable = true)
|
cancellable = true)
|
||||||
private void renderMultipleModels(BlockState state, BlockPos pos, BakedModel wrapper, MatrixStack matrixStack, CallbackInfo ci) {
|
private void renderMultipleModels(BlockState state, BlockPos pos, BakedModel wrapper, MatrixStack matrixStack, CallbackInfo ci) {
|
||||||
if (!(wrapper instanceof IMultipartBakedModelMixin wrapped)
|
if (!(wrapper instanceof IMultipartBakedModelMixin wrapped)) return;
|
||||||
|| !(wrapped.getModel(state) instanceof MultiRetexturableModel retexturing_model)) return;
|
List<BakedModel> models = wrapped.getModels(state);
|
||||||
|
if (models.stream().noneMatch(bakedModel ->
|
||||||
|
bakedModel instanceof MultiRetexturableModel
|
||||||
|
|| bakedModel instanceof RetexturingBakedModel
|
||||||
|
)) return;
|
||||||
|
|
||||||
List<ForwardingBakedModel> models = retexturing_model.models();
|
models.forEach(model -> {
|
||||||
RenderHelper.computeInnerCull(state, models);
|
if (model instanceof MultiRetexturableModel multi_model) {
|
||||||
int i = 0;
|
RenderHelper.computeInnerCull(state, multi_model.models(), model.hashCode());
|
||||||
for (BakedModel model : models) {
|
multi_model.models().forEach(retexturable_model ->
|
||||||
i++;
|
renderModel(state, retexturable_model, pos, aoCalc, blockInfo, this, model.hashCode())
|
||||||
aoCalc.clear();
|
);
|
||||||
((IBlockRenderInfoMixin) blockInfo).prepareForBlock(state, pos, model.useAmbientOcclusion(), i);
|
} else if (model instanceof RetexturingBakedModel retexturable_model)
|
||||||
model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
|
renderModel(state, retexturable_model, pos, aoCalc, blockInfo, this, model.hashCode());
|
||||||
}
|
else model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
|
||||||
|
});
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static void renderModel(BlockState state, RetexturingBakedModel model, BlockPos pos, AoCalculator aoCalc, BlockRenderInfo block_info, RenderContext context, int model_hash) {
|
||||||
|
aoCalc.clear();
|
||||||
|
((IBlockRenderInfoMixin) block_info).prepareForBlock(
|
||||||
|
state, pos,
|
||||||
|
model.useAmbientOcclusion(block_info.blockView, pos),
|
||||||
|
model.getThemeIndex(), model_hash
|
||||||
|
);
|
||||||
|
model.emitBlockQuads(block_info.blockView, block_info.blockState, block_info.blockPos, block_info.randomSupplier, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,11 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
|
|
||||||
public interface IBlockRenderInfoMixin {
|
public interface IBlockRenderInfoMixin {
|
||||||
|
|
||||||
void prepareForBlock(BlockState state, BlockPos pos, boolean ao, int theme_index);
|
void prepareForBlock(BlockState state, BlockPos pos, boolean ao, int theme_index, int model_hash);
|
||||||
|
|
||||||
void prepareForBlock(BlockState state, BlockPos pos, long seed, boolean ao, int theme_index);
|
void prepareForBlock(BlockState state, BlockPos pos, long seed, boolean ao, int theme_index, int model_hash);
|
||||||
|
|
||||||
int getThemeIndex();
|
int getThemeIndex();
|
||||||
|
|
||||||
|
int getModelHash();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,9 @@ package fr.adrien1106.reframed.util.mixin;
|
|||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.render.model.BakedModel;
|
import net.minecraft.client.render.model.BakedModel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface IMultipartBakedModelMixin {
|
public interface IMultipartBakedModelMixin {
|
||||||
|
|
||||||
BakedModel getModel(BlockState state);
|
List<BakedModel> getModels(BlockState state);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"credit": "Made with Blockbench",
|
||||||
|
"parent": "block/block",
|
||||||
|
"textures": {
|
||||||
|
"particle": "#side"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [5, 0, 0],
|
||||||
|
"to": [11, 14, 4],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [5, 2, 11, 16], "texture": "#side", "cullface": "north"},
|
||||||
|
"east": {"uv": [12, 2, 16, 16], "texture": "#side"},
|
||||||
|
"south": {"uv": [5, 2, 11, 16], "texture": "#side"},
|
||||||
|
"west": {"uv": [0, 2, 4, 16], "texture": "#side"},
|
||||||
|
"up": {"uv": [5, 0, 11, 4], "texture": "#top"},
|
||||||
|
"down": {"uv": [5, 12, 11, 16], "texture": "#bottom"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [5, 0, 12],
|
||||||
|
"to": [11, 14, 16],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [5, 2, 11, 16], "texture": "#side"},
|
||||||
|
"east": {"uv": [0, 2, 4, 16], "texture": "#side"},
|
||||||
|
"south": {"uv": [5, 2, 11, 16], "texture": "#side", "cullface": "south"},
|
||||||
|
"west": {"uv": [12, 2, 16, 16], "texture": "#side"},
|
||||||
|
"up": {"uv": [5, 12, 11, 16], "texture": "#top"},
|
||||||
|
"down": {"uv": [5, 0, 11, 4], "texture": "#bottom"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user