started new stairs reimplementation shapes are not all there for generation and inner shapes are badly oriented
This commit is contained in:
parent
a788176ffc
commit
7b4c465c66
@ -31,16 +31,12 @@ import java.util.stream.Collectors;
|
|||||||
public class Templates implements ModInitializer {
|
public class Templates implements ModInitializer {
|
||||||
public static final String MODID = "reframedtemplates";
|
public static final String MODID = "reframedtemplates";
|
||||||
|
|
||||||
//addon devs: *Don't* add your blocks to this collection, it's just for my registration convenience since Templates adds a lot of blocks...
|
protected static final ArrayList<Block> INTERNAL_TEMPLATES = new ArrayList<>();
|
||||||
@ApiStatus.Internal static final ArrayList<Block> INTERNAL_TEMPLATES = new ArrayList<>();
|
public static Block CUBE, STAIRS, SLAB, POST, FENCE, FENCE_GATE, DOOR, TRAPDOOR, IRON_DOOR, IRON_TRAPDOOR, PRESSURE_PLATE, BUTTON, LEVER, WALL, CARPET, PANE, CANDLE;
|
||||||
@ApiStatus.Internal static Block CUBE, STAIRS, SLAB, POST, FENCE, FENCE_GATE, DOOR, TRAPDOOR, IRON_DOOR, IRON_TRAPDOOR, PRESSURE_PLATE, BUTTON, LEVER, WALL, CARPET, PANE, CANDLE;
|
|
||||||
|
|
||||||
//For addon devs: Please don't stuff more blocks into this BlockEntityType, and register your own.
|
public static BlockEntityType<FramedEntity> TEMPLATE_BLOCK_ENTITY;
|
||||||
//You can even re-register the same TemplateEntity class under your own ID if you like. (It's an extensible block entity.)
|
|
||||||
@ApiStatus.Internal public static BlockEntityType<TemplateEntity> TEMPLATE_BLOCK_ENTITY;
|
|
||||||
|
|
||||||
//Changed in TemplatesClient (which is safe since client initializers load after common initializers)
|
public static BiConsumer<World, BlockPos> chunkRerenderProxy = (world, pos) -> {};
|
||||||
@ApiStatus.Internal public static BiConsumer<World, BlockPos> chunkRerenderProxy = (world, pos) -> {};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
@ -69,7 +65,7 @@ public class Templates implements ModInitializer {
|
|||||||
|
|
||||||
//The block entity is still called templates:slope; this is a bit of a legacy mistake.
|
//The block entity is still called templates:slope; this is a bit of a legacy mistake.
|
||||||
TEMPLATE_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("slope"),
|
TEMPLATE_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("slope"),
|
||||||
FabricBlockEntityTypeBuilder.create((pos, state) -> new TemplateEntity(TEMPLATE_BLOCK_ENTITY, pos, state), INTERNAL_TEMPLATES.toArray(new Block[0])).build(null)
|
FabricBlockEntityTypeBuilder.create((pos, state) -> new FramedEntity(TEMPLATE_BLOCK_ENTITY, pos, state), INTERNAL_TEMPLATES.toArray(new Block[0])).build(null)
|
||||||
);
|
);
|
||||||
|
|
||||||
Registry.register(Registries.ITEM_GROUP, id("tab"), FabricItemGroup.builder()
|
Registry.register(Registries.ITEM_GROUP, id("tab"), FabricItemGroup.builder()
|
||||||
@ -79,7 +75,6 @@ public class Templates implements ModInitializer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//purely to shorten this call :p
|
|
||||||
private static AbstractBlock.Settings cp(Block base) {
|
private static AbstractBlock.Settings cp(Block base) {
|
||||||
return TemplateInteractionUtil.configureSettings(AbstractBlock.Settings.copy(base));
|
return TemplateInteractionUtil.configureSettings(AbstractBlock.Settings.copy(base));
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ public class TemplatesClient implements ClientModInitializer {
|
|||||||
api.addTemplateModel(Templates.id("pressure_plate_down_special") , api.auto(new Identifier("block/pressure_plate_down")));
|
api.addTemplateModel(Templates.id("pressure_plate_down_special") , api.auto(new Identifier("block/pressure_plate_down")));
|
||||||
api.addTemplateModel(Templates.id("slab_special") , api.auto(new Identifier("block/slab")));
|
api.addTemplateModel(Templates.id("slab_special") , api.auto(new Identifier("block/slab")));
|
||||||
api.addTemplateModel(Templates.id("stairs_special") , api.auto(new Identifier("block/stairs")));
|
api.addTemplateModel(Templates.id("stairs_special") , api.auto(new Identifier("block/stairs")));
|
||||||
|
api.addTemplateModel(Templates.id("double_outer_stairs_special") , api.auto(Templates.id("block/double_outer_stairs")));
|
||||||
api.addTemplateModel(Templates.id("inner_stairs_special") , api.auto(new Identifier("block/inner_stairs")));
|
api.addTemplateModel(Templates.id("inner_stairs_special") , api.auto(new Identifier("block/inner_stairs")));
|
||||||
api.addTemplateModel(Templates.id("outer_stairs_special") , api.auto(new Identifier("block/outer_stairs")));
|
api.addTemplateModel(Templates.id("outer_stairs_special") , api.auto(new Identifier("block/outer_stairs")));
|
||||||
api.addTemplateModel(Templates.id("trapdoor_bottom_special") , api.auto(new Identifier("block/template_trapdoor_bottom")));
|
api.addTemplateModel(Templates.id("trapdoor_bottom_special") , api.auto(new Identifier("block/template_trapdoor_bottom")));
|
||||||
@ -92,7 +93,7 @@ public class TemplatesClient implements ClientModInitializer {
|
|||||||
api.assignItemModel(Templates.id("trapdoor_bottom_special") , Templates.IRON_TRAPDOOR);
|
api.assignItemModel(Templates.id("trapdoor_bottom_special") , Templates.IRON_TRAPDOOR);
|
||||||
api.assignItemModel(Templates.id("fence_post_inventory_special") , Templates.POST);
|
api.assignItemModel(Templates.id("fence_post_inventory_special") , Templates.POST);
|
||||||
api.assignItemModel(Templates.id("pressure_plate_up_special") , Templates.PRESSURE_PLATE);
|
api.assignItemModel(Templates.id("pressure_plate_up_special") , Templates.PRESSURE_PLATE);
|
||||||
api.assignItemModel(Templates.id("slab_bottom_special") , Templates.SLAB);
|
api.assignItemModel(Templates.id("slab_special") , Templates.SLAB);
|
||||||
api.assignItemModel(Templates.id("stairs_special") , Templates.STAIRS);
|
api.assignItemModel(Templates.id("stairs_special") , Templates.STAIRS);
|
||||||
api.assignItemModel(Templates.id("trapdoor_bottom_special") , Templates.TRAPDOOR);
|
api.assignItemModel(Templates.id("trapdoor_bottom_special") , Templates.TRAPDOOR);
|
||||||
api.assignItemModel(Templates.id("wall_inventory_special") , Templates.WALL);
|
api.assignItemModel(Templates.id("wall_inventory_special") , Templates.WALL);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package fr.adrien1106.reframedtemplates.api;
|
package fr.adrien1106.reframedtemplates.api;
|
||||||
|
|
||||||
import fr.adrien1106.reframedtemplates.block.TemplateEntity;
|
import fr.adrien1106.reframedtemplates.block.FramedEntity;
|
||||||
import net.minecraft.block.AbstractBlock;
|
import net.minecraft.block.AbstractBlock;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockEntityProvider;
|
import net.minecraft.block.BlockEntityProvider;
|
||||||
@ -61,11 +61,11 @@ public class TemplateInteractionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable BlockState modifyPlacementState(@Nullable BlockState in, ItemPlacementContext ctx) {
|
public static @Nullable BlockState modifyPlacementState(@Nullable BlockState in, ItemPlacementContext ctx) {
|
||||||
return TemplateEntity.weirdNbtLightLevelStuff(in, ctx.getStack());
|
return FramedEntity.weirdNbtLightLevelStuff(in, ctx.getStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
public static ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||||
if(!(world.getBlockEntity(pos) instanceof TemplateEntity be)) return ActionResult.PASS;
|
if(!(world.getBlockEntity(pos) instanceof FramedEntity be)) return ActionResult.PASS;
|
||||||
if(!player.canModifyBlocks() || !world.canPlayerModifyAt(player, pos)) return ActionResult.PASS;
|
if(!player.canModifyBlocks() || !world.canPlayerModifyAt(player, pos)) return ActionResult.PASS;
|
||||||
|
|
||||||
ItemStack held = player.getStackInHand(hand);
|
ItemStack held = player.getStackInHand(hand);
|
||||||
@ -132,7 +132,7 @@ public class TemplateInteractionUtil {
|
|||||||
//Maybe an odd spot to put this logic but it's consistent w/ vanilla chests, barrels, etc
|
//Maybe an odd spot to put this logic but it's consistent w/ vanilla chests, barrels, etc
|
||||||
public static void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
public static void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
if(!state.isOf(newState.getBlock()) &&
|
if(!state.isOf(newState.getBlock()) &&
|
||||||
world.getBlockEntity(pos) instanceof TemplateEntity template &&
|
world.getBlockEntity(pos) instanceof FramedEntity template &&
|
||||||
world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)
|
world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)
|
||||||
) {
|
) {
|
||||||
DefaultedList<ItemStack> drops = DefaultedList.of();
|
DefaultedList<ItemStack> drops = DefaultedList.of();
|
||||||
@ -152,7 +152,7 @@ public class TemplateInteractionUtil {
|
|||||||
public static void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
public static void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||||
//Load the BlockEntityTag clientside, which fixes the template briefly showing its default state when placing it.
|
//Load the BlockEntityTag clientside, which fixes the template briefly showing its default state when placing it.
|
||||||
//I'm surprised this doesn't happen by default; the BlockEntityTag stuff is only done serverside.
|
//I'm surprised this doesn't happen by default; the BlockEntityTag stuff is only done serverside.
|
||||||
if(world.isClient && world.getBlockEntity(pos) instanceof TemplateEntity be) {
|
if(world.isClient && world.getBlockEntity(pos) instanceof FramedEntity be) {
|
||||||
NbtCompound tag = BlockItem.getBlockEntityNbt(stack);
|
NbtCompound tag = BlockItem.getBlockEntityNbt(stack);
|
||||||
if(tag != null) be.readNbt(tag);
|
if(tag != null) be.readNbt(tag);
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ public class TemplateInteractionUtil {
|
|||||||
|
|
||||||
//Returns "null" to signal "no opinion". Imagine it like an InteractionResult.PASS.
|
//Returns "null" to signal "no opinion". Imagine it like an InteractionResult.PASS.
|
||||||
public static @Nullable VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
public static @Nullable VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
||||||
return view.getBlockEntity(pos) instanceof TemplateEntity be && !be.isSolid() ? VoxelShapes.empty() : null;
|
return view.getBlockEntity(pos) instanceof FramedEntity be && !be.isSolid() ? VoxelShapes.empty() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean emitsRedstonePower(BlockState state) {
|
public static boolean emitsRedstonePower(BlockState state) {
|
||||||
@ -169,11 +169,11 @@ public class TemplateInteractionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
public static int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
||||||
return view.getBlockEntity(pos) instanceof TemplateEntity be && be.emitsRedstone() ? 15 : 0;
|
return view.getBlockEntity(pos) instanceof FramedEntity be && be.emitsRedstone() ? 15 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
public static int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
||||||
return view.getBlockEntity(pos) instanceof TemplateEntity be && be.emitsRedstone() ? 15 : 0;
|
return view.getBlockEntity(pos) instanceof FramedEntity be && be.emitsRedstone() ? 15 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int luminance(BlockState state) {
|
public static int luminance(BlockState state) {
|
||||||
|
@ -26,7 +26,7 @@ import java.util.Objects;
|
|||||||
//Keeping the weight of this block entity down, both in terms of memory consumption and NBT sync traffic,
|
//Keeping the weight of this block entity down, both in terms of memory consumption and NBT sync traffic,
|
||||||
//is pretty important since players might place a lot of them. There were tons and tons of these at Blanketcon.
|
//is pretty important since players might place a lot of them. There were tons and tons of these at Blanketcon.
|
||||||
//To that end, most of the state has been crammed into a bitfield.
|
//To that end, most of the state has been crammed into a bitfield.
|
||||||
public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity {
|
public class FramedEntity extends BlockEntity implements ThemeableBlockEntity {
|
||||||
protected BlockState renderedState = Blocks.AIR.getDefaultState();
|
protected BlockState renderedState = Blocks.AIR.getDefaultState();
|
||||||
protected byte bitfield = DEFAULT_BITFIELD;
|
protected byte bitfield = DEFAULT_BITFIELD;
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ public class TemplateEntity extends BlockEntity implements ThemeableBlockEntity
|
|||||||
protected static final String BLOCKSTATE_KEY = "s";
|
protected static final String BLOCKSTATE_KEY = "s";
|
||||||
protected static final String BITFIELD_KEY = "b";
|
protected static final String BITFIELD_KEY = "b";
|
||||||
|
|
||||||
public TemplateEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public FramedEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
}
|
}
|
||||||
|
|
@ -1,96 +1,393 @@
|
|||||||
package fr.adrien1106.reframedtemplates.block;
|
package fr.adrien1106.reframedtemplates.block;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
|
||||||
import fr.adrien1106.reframedtemplates.Templates;
|
import fr.adrien1106.reframedtemplates.Templates;
|
||||||
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
|
import fr.adrien1106.reframedtemplates.generator.GBlockstate;
|
||||||
|
import fr.adrien1106.reframedtemplates.generator.MultipartBlockStateProvider;
|
||||||
|
import fr.adrien1106.reframedtemplates.util.VoxelHelper;
|
||||||
|
import fr.adrien1106.reframedtemplates.util.property.StairDirection;
|
||||||
|
import fr.adrien1106.reframedtemplates.util.property.StairShape;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockEntityProvider;
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.ShapeContext;
|
import net.minecraft.block.ShapeContext;
|
||||||
import net.minecraft.block.StairsBlock;
|
import net.minecraft.data.client.*;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.state.StateManager;
|
import net.minecraft.state.StateManager;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.state.property.EnumProperty;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.function.BooleanBiFunction;
|
||||||
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.Direction.Axis;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
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 org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class TemplateStairsBlock extends StairsBlock implements BlockEntityProvider {
|
import java.util.ArrayList;
|
||||||
public TemplateStairsBlock(BlockState blockState, Settings settings) {
|
import java.util.List;
|
||||||
super(blockState, settings);
|
import java.util.stream.Stream;
|
||||||
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
|
|
||||||
}
|
import static fr.adrien1106.reframedtemplates.util.property.StairShape.*;
|
||||||
|
import static net.minecraft.data.client.VariantSettings.Rotation.*;
|
||||||
|
import static fr.adrien1106.reframedtemplates.util.property.StairDirection.*;
|
||||||
|
|
||||||
|
public class TemplateStairsBlock extends WaterloggableTemplateBlock implements MultipartBlockStateProvider {
|
||||||
|
|
||||||
|
public static final EnumProperty<StairDirection> FACING = EnumProperty.of("facing", StairDirection.class);
|
||||||
|
public static final EnumProperty<StairShape> SHAPE = EnumProperty.of("shape", StairShape.class);
|
||||||
|
private static final List<VoxelShape> VOXEL_LIST= new ArrayList<>();
|
||||||
|
|
||||||
public TemplateStairsBlock(Settings settings) {
|
public TemplateStairsBlock(Settings settings) {
|
||||||
this(Blocks.OAK_PLANKS.getDefaultState(), settings);
|
super(settings);
|
||||||
}
|
setDefaultState(getDefaultState().with(FACING, StairDirection.NORTH_DOWN).with(SHAPE, STRAIGHT));
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
|
||||||
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
|
super.appendProperties(builder.add(FACING).add(SHAPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighbor_state, WorldAccess world, BlockPos pos, BlockPos moved) {
|
||||||
|
return super.getStateForNeighborUpdate(state, direction, neighbor_state, world, pos, moved)
|
||||||
|
.with(SHAPE, getPlacementShape(state.get(FACING), world, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override // Pretty happy of how clean it is (also got it on first try :) )
|
||||||
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
public BlockState getPlacementState(ItemPlacementContext ctx) {
|
||||||
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
|
BlockState state = super.getPlacementState(ctx);
|
||||||
}
|
Direction side = ctx.getSide().getOpposite();
|
||||||
|
BlockPos block_pos = ctx.getBlockPos();
|
||||||
|
Vec3d hit_pos = ctx.getHitPos();
|
||||||
|
Vec3d pos = new Vec3d(
|
||||||
|
hit_pos.getX() - block_pos.getX() - .5d,
|
||||||
|
hit_pos.getY() - block_pos.getY() - .5d,
|
||||||
|
hit_pos.getZ() - block_pos.getZ() - .5d
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
Stream<Axis> axes = Stream.of(Axis.values()).filter(axis -> !axis.equals(side.getAxis()));
|
||||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
Axis axis = axes.reduce((axis_1, axis_2) ->
|
||||||
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
|
Math.abs(axis_1.choose(pos.x, pos.y, pos.z)) > Math.abs(axis_2.choose(pos.x, pos.y, pos.z))
|
||||||
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
|
? axis_1
|
||||||
return r;
|
: axis_2
|
||||||
|
).get();
|
||||||
|
|
||||||
|
Direction part_direction = Direction.from(
|
||||||
|
axis,
|
||||||
|
axis.choose(pos.x, pos.y, pos.z) > 0
|
||||||
|
? Direction.AxisDirection.POSITIVE
|
||||||
|
: Direction.AxisDirection.NEGATIVE
|
||||||
|
);
|
||||||
|
|
||||||
|
return state.with(FACING, StairDirection.getByDirections(side, part_direction));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||||
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
|
|
||||||
super.onStateReplaced(state, world, pos, newState, moved);
|
super.onStateReplaced(state, world, pos, newState, moved);
|
||||||
|
|
||||||
//StairsBlock onStateReplaced is Weird! it doesn't delegate to regular block onStateReplaced!
|
//StairsBlock onStateReplaced is Weird! it doesn't delegate to regular block onStateReplaced!
|
||||||
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
if(!state.isOf(newState.getBlock())) world.removeBlockEntity(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------- DON'T GO FURTHER IF YOU LIKE HAVING EYES ---------------------------------- */
|
||||||
@Override
|
@Override
|
||||||
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||||
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
|
StairShape shape = state.get(SHAPE);
|
||||||
super.onPlaced(world, pos, state, placer, stack);
|
StairDirection direction = state.get(FACING);
|
||||||
|
return switch (shape) {
|
||||||
|
case STRAIGHT ->
|
||||||
|
switch (direction) {
|
||||||
|
case DOWN_SOUTH -> VOXEL_LIST.get(0);
|
||||||
|
case NORTH_DOWN -> VOXEL_LIST.get(1);
|
||||||
|
case UP_NORTH -> VOXEL_LIST.get(2);
|
||||||
|
case SOUTH_UP -> VOXEL_LIST.get(3);
|
||||||
|
case DOWN_EAST -> VOXEL_LIST.get(4);
|
||||||
|
case WEST_DOWN -> VOXEL_LIST.get(5);
|
||||||
|
case UP_WEST -> VOXEL_LIST.get(6);
|
||||||
|
case EAST_UP -> VOXEL_LIST.get(7);
|
||||||
|
case NORTH_EAST -> VOXEL_LIST.get(8);
|
||||||
|
case EAST_SOUTH -> VOXEL_LIST.get(9);
|
||||||
|
case SOUTH_WEST -> VOXEL_LIST.get(10);
|
||||||
|
case WEST_NORTH -> VOXEL_LIST.get(11);
|
||||||
|
};
|
||||||
|
case INNER_LEFT ->
|
||||||
|
switch (direction) {
|
||||||
|
case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(44);
|
||||||
|
case DOWN_EAST -> VOXEL_LIST.get(45);
|
||||||
|
case DOWN_SOUTH -> VOXEL_LIST.get(47);
|
||||||
|
case UP_WEST, UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(48);
|
||||||
|
case EAST_UP, NORTH_EAST -> VOXEL_LIST.get(49);
|
||||||
|
case EAST_SOUTH -> VOXEL_LIST.get(50);
|
||||||
|
case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(51);
|
||||||
|
};
|
||||||
|
case INNER_RIGHT ->
|
||||||
|
switch (direction) {
|
||||||
|
case WEST_NORTH -> VOXEL_LIST.get(44);
|
||||||
|
case NORTH_DOWN, NORTH_EAST -> VOXEL_LIST.get(45);
|
||||||
|
case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(46);
|
||||||
|
case WEST_DOWN, SOUTH_WEST -> VOXEL_LIST.get(47);
|
||||||
|
case UP_NORTH -> VOXEL_LIST.get(49);
|
||||||
|
case EAST_UP, SOUTH_UP -> VOXEL_LIST.get(50);
|
||||||
|
case UP_WEST -> VOXEL_LIST.get(51);
|
||||||
|
};
|
||||||
|
case OUTER_LEFT ->
|
||||||
|
switch (direction) {
|
||||||
|
case DOWN_EAST -> VOXEL_LIST.get(43);
|
||||||
|
case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(42);
|
||||||
|
case DOWN_SOUTH -> VOXEL_LIST.get(41);
|
||||||
|
case EAST_UP, NORTH_EAST -> VOXEL_LIST.get(39);
|
||||||
|
case UP_WEST, UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(38);
|
||||||
|
case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(37);
|
||||||
|
case EAST_SOUTH -> VOXEL_LIST.get(36);
|
||||||
|
};
|
||||||
|
case OUTER_RIGHT ->
|
||||||
|
switch (direction) {
|
||||||
|
case NORTH_DOWN, NORTH_EAST -> VOXEL_LIST.get(43);
|
||||||
|
case WEST_NORTH -> VOXEL_LIST.get(42);
|
||||||
|
case WEST_DOWN, SOUTH_WEST -> VOXEL_LIST.get(41);
|
||||||
|
case DOWN_EAST, DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(40);
|
||||||
|
case UP_NORTH -> VOXEL_LIST.get(39);
|
||||||
|
case UP_WEST -> VOXEL_LIST.get(37);
|
||||||
|
case EAST_UP, SOUTH_UP -> VOXEL_LIST.get(36);
|
||||||
|
};
|
||||||
|
case FIRST_OUTER_LEFT ->
|
||||||
|
switch (direction) {
|
||||||
|
case WEST_DOWN, NORTH_DOWN -> VOXEL_LIST.get(14);
|
||||||
|
case SOUTH_UP -> VOXEL_LIST.get(17);
|
||||||
|
case EAST_UP -> VOXEL_LIST.get(19);
|
||||||
|
case EAST_SOUTH -> VOXEL_LIST.get(20);
|
||||||
|
case DOWN_SOUTH -> VOXEL_LIST.get(22);
|
||||||
|
case UP_NORTH, WEST_NORTH -> VOXEL_LIST.get(25);
|
||||||
|
case SOUTH_WEST -> VOXEL_LIST.get(28);
|
||||||
|
case UP_WEST -> VOXEL_LIST.get(31);
|
||||||
|
case DOWN_EAST -> VOXEL_LIST.get(34);
|
||||||
|
case NORTH_EAST -> VOXEL_LIST.get(35);
|
||||||
|
};
|
||||||
|
case FIRST_OUTER_RIGHT ->
|
||||||
|
switch (direction) {
|
||||||
|
case NORTH_DOWN -> VOXEL_LIST.get(15);
|
||||||
|
case SOUTH_UP, EAST_UP -> VOXEL_LIST.get(16);
|
||||||
|
case WEST_DOWN -> VOXEL_LIST.get(13);
|
||||||
|
case DOWN_SOUTH, EAST_SOUTH -> VOXEL_LIST.get(23);
|
||||||
|
case UP_NORTH -> VOXEL_LIST.get(24);
|
||||||
|
case WEST_NORTH -> VOXEL_LIST.get(26);
|
||||||
|
case UP_WEST -> VOXEL_LIST.get(28);
|
||||||
|
case SOUTH_WEST -> VOXEL_LIST.get(29);
|
||||||
|
case DOWN_EAST -> VOXEL_LIST.get(33);
|
||||||
|
case NORTH_EAST -> VOXEL_LIST.get(34);
|
||||||
|
};
|
||||||
|
case SECOND_OUTER_LEFT ->
|
||||||
|
switch (direction) {
|
||||||
|
case DOWN_EAST -> VOXEL_LIST.get(15);
|
||||||
|
case DOWN_SOUTH -> VOXEL_LIST.get(13);
|
||||||
|
case UP_WEST, UP_NORTH -> VOXEL_LIST.get(18);
|
||||||
|
case SOUTH_UP, SOUTH_WEST -> VOXEL_LIST.get(21);
|
||||||
|
case NORTH_EAST -> VOXEL_LIST.get(24);
|
||||||
|
case NORTH_DOWN -> VOXEL_LIST.get(26);
|
||||||
|
case WEST_DOWN -> VOXEL_LIST.get(30);
|
||||||
|
case WEST_NORTH -> VOXEL_LIST.get(31);
|
||||||
|
case EAST_SOUTH -> VOXEL_LIST.get(32);
|
||||||
|
case EAST_UP -> VOXEL_LIST.get(35);
|
||||||
|
};
|
||||||
|
case SECOND_OUTER_RIGHT ->
|
||||||
|
switch (direction) {
|
||||||
|
case DOWN_SOUTH, DOWN_EAST -> VOXEL_LIST.get(12);
|
||||||
|
case UP_WEST -> VOXEL_LIST.get(17);
|
||||||
|
case UP_NORTH -> VOXEL_LIST.get(19);
|
||||||
|
case SOUTH_UP -> VOXEL_LIST.get(20);
|
||||||
|
case SOUTH_WEST -> VOXEL_LIST.get(22);
|
||||||
|
case NORTH_EAST, NORTH_DOWN -> VOXEL_LIST.get(27);
|
||||||
|
case WEST_DOWN -> VOXEL_LIST.get(29);
|
||||||
|
case WEST_NORTH -> VOXEL_LIST.get(30);
|
||||||
|
case EAST_UP -> VOXEL_LIST.get(32);
|
||||||
|
case EAST_SOUTH -> VOXEL_LIST.get(33);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getNeighborPos(StairDirection face, Direction direction, Boolean reverse, Direction reference, BlockView world, BlockPos pos) {
|
||||||
|
BlockState block_state = world.getBlockState(
|
||||||
|
pos.offset(reverse ? direction.getOpposite() : direction)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (block_state.getBlock() instanceof TemplateStairsBlock && block_state.get(FACING).hasDirection(reference)) {
|
||||||
|
if (block_state.get(FACING).hasDirection(face.getLeftDirection())) return "left";
|
||||||
|
else if (block_state.get(FACING).hasDirection(face.getRightDirection())) return "right";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StairShape getPlacementShape(StairDirection face, BlockView world, BlockPos pos) {
|
||||||
|
StairShape shape = STRAIGHT;
|
||||||
|
|
||||||
|
String sol = getNeighborPos(face, face.getFirstDirection(), true, face.getSecondDirection(), world, pos);
|
||||||
|
switch (sol) {
|
||||||
|
case "right": return INNER_RIGHT;
|
||||||
|
case "left": return INNER_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol = getNeighborPos(face, face.getSecondDirection(), true, face.getFirstDirection(), world, pos);
|
||||||
|
switch (sol) {
|
||||||
|
case "right": return INNER_RIGHT;
|
||||||
|
case "left": return INNER_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol = getNeighborPos(face, face.getFirstDirection(), false, face.getSecondDirection(), world, pos);
|
||||||
|
switch (sol) {
|
||||||
|
case "right" -> shape = FIRST_OUTER_RIGHT;
|
||||||
|
case "left" -> shape = FIRST_OUTER_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol = getNeighborPos(face, face.getSecondDirection(), false, face.getFirstDirection(), world, pos);
|
||||||
|
switch (sol) {
|
||||||
|
case "right" -> {
|
||||||
|
if (shape.equals(STRAIGHT)) shape = SECOND_OUTER_RIGHT;
|
||||||
|
else if (shape.equals(FIRST_OUTER_RIGHT)) shape = OUTER_RIGHT;
|
||||||
|
}
|
||||||
|
case "left" -> {
|
||||||
|
if (shape.equals(STRAIGHT)) shape = SECOND_OUTER_LEFT;
|
||||||
|
else if (shape.equals(FIRST_OUTER_LEFT)) shape = OUTER_LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
|
public MultipartBlockStateSupplier getMultipart() {
|
||||||
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
|
Identifier straight_id = Templates.id("stairs_special");
|
||||||
|
Identifier double_outer_id = Templates.id("double_outer_stairs_special");
|
||||||
|
Identifier inner_id = Templates.id("inner_stairs_special");
|
||||||
|
Identifier outer_id = Templates.id("outer_stairs_special");
|
||||||
|
return MultipartBlockStateSupplier.create(this)
|
||||||
|
/* STRAIGHT X AXIS */
|
||||||
|
.with(GBlockstate.when(FACING, DOWN_EAST, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R0, R0))
|
||||||
|
.with(GBlockstate.when(FACING, EAST_UP, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R180, R0))
|
||||||
|
.with(GBlockstate.when(FACING, UP_WEST, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R180, R180))
|
||||||
|
.with(GBlockstate.when(FACING, WEST_DOWN, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R0, R180))
|
||||||
|
/* STRAIGHT Y AXIS */
|
||||||
|
.with(GBlockstate.when(FACING, EAST_SOUTH, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R90, R0))
|
||||||
|
.with(GBlockstate.when(FACING, SOUTH_WEST, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R90, R90))
|
||||||
|
.with(GBlockstate.when(FACING, WEST_NORTH, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R90, R180))
|
||||||
|
.with(GBlockstate.when(FACING, NORTH_EAST, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R90, R270))
|
||||||
|
/* STRAIGHT Z AXIS */
|
||||||
|
.with(GBlockstate.when(FACING, DOWN_SOUTH, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R0, R90))
|
||||||
|
.with(GBlockstate.when(FACING, NORTH_DOWN, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R0, R270))
|
||||||
|
.with(GBlockstate.when(FACING, UP_NORTH, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R180, R270))
|
||||||
|
.with(GBlockstate.when(FACING, SOUTH_UP, SHAPE, STRAIGHT),
|
||||||
|
GBlockstate.variant(straight_id, true, R180, R90))
|
||||||
|
/* OUTER X AXIS */
|
||||||
|
.with(GBlockstate.when(FACING, DOWN_EAST, SHAPE, FIRST_OUTER_RIGHT),
|
||||||
|
GBlockstate.variant(outer_id, true, R0, R0))
|
||||||
|
.with(GBlockstate.when(FACING, DOWN_EAST, SHAPE, INNER_LEFT),
|
||||||
|
GBlockstate.variant(inner_id, true, R0, R270))
|
||||||
|
/* OUTER DOUBLE */
|
||||||
|
.with(GBlockstate.when(FACING, NORTH_DOWN, SHAPE, OUTER_LEFT),
|
||||||
|
GBlockstate.variant(double_outer_id, true, R0, R180))
|
||||||
|
.with(GBlockstate.when(FACING, NORTH_DOWN, SHAPE, OUTER_RIGHT),
|
||||||
|
GBlockstate.variant(double_outer_id, true, R0, R270));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
static {
|
||||||
public boolean emitsRedstonePower(BlockState state) {
|
final VoxelShape STRAIGHT = Stream.of(
|
||||||
return TemplateInteractionUtil.emitsRedstonePower(state);
|
VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f),
|
||||||
}
|
VoxelShapes.cuboid(0.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f)
|
||||||
|
).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get();
|
||||||
|
final VoxelShape JUNCTION = Stream.of(
|
||||||
|
VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f),
|
||||||
|
VoxelShapes.cuboid(0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f)
|
||||||
|
).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get();
|
||||||
|
final VoxelShape INNER = Stream.of(
|
||||||
|
VoxelShapes.cuboid(0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f),
|
||||||
|
VoxelShapes.cuboid(0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f),
|
||||||
|
VoxelShapes.cuboid(0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f),
|
||||||
|
VoxelShapes.cuboid(0.5f, 0.0f, 0.5f, 1.0f, 0.5f, 1.0f)
|
||||||
|
).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get();
|
||||||
|
final VoxelShape OUTER = Stream.of(
|
||||||
|
VoxelShapes.cuboid(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f),
|
||||||
|
VoxelShapes.cuboid(0.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f),
|
||||||
|
VoxelShapes.cuboid(0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.5f)
|
||||||
|
).reduce((previous, current) -> VoxelShapes.combineAndSimplify(previous, current, BooleanBiFunction.OR)).get();
|
||||||
|
|
||||||
@Override
|
VOXEL_LIST.add(STRAIGHT);
|
||||||
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
VOXEL_LIST.add(VoxelHelper.mirror(STRAIGHT, Axis.Z));
|
||||||
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
|
VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.X), Axis.Z));
|
||||||
}
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.X));
|
||||||
|
|
||||||
@Override
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y));
|
||||||
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
|
VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.X));
|
||||||
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
|
VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.Z), Axis.X));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(STRAIGHT, Axis.Y), Axis.Z));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(STRAIGHT, Axis.Z), Axis.Y), Axis.Z));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(JUNCTION);
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(JUNCTION, Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(JUNCTION, Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.Y));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.mirror(JUNCTION, Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(JUNCTION, Axis.Y), Axis.Y));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z), Axis.Z));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Z), Axis.Z));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.rotateClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X), Axis.X));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(VoxelHelper.rotateClockwise(VoxelHelper.rotateCounterClockwise(JUNCTION, Axis.X), Axis.Y), Axis.X), Axis.X));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(INNER);
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(INNER, Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(INNER, Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(INNER, Axis.Y));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.mirror(INNER, Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(INNER, Axis.Y), Axis.Y));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(OUTER);
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(OUTER, Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(OUTER, Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(OUTER, Axis.Y));
|
||||||
|
|
||||||
|
VOXEL_LIST.add(VoxelHelper.mirror(OUTER, Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y), Axis.Y));
|
||||||
|
VOXEL_LIST.add(VoxelHelper.rotateCounterClockwise(VoxelHelper.mirror(OUTER, Axis.Y), Axis.Y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package fr.adrien1106.reframedtemplates.model;
|
package fr.adrien1106.reframedtemplates.model;
|
||||||
|
|
||||||
import fr.adrien1106.reframedtemplates.block.TemplateEntity;
|
import fr.adrien1106.reframedtemplates.block.FramedEntity;
|
||||||
import fr.adrien1106.reframedtemplates.mixin.MinecraftAccessor;
|
import fr.adrien1106.reframedtemplates.mixin.MinecraftAccessor;
|
||||||
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearance;
|
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearance;
|
||||||
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearanceManager;
|
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearanceManager;
|
||||||
@ -100,7 +100,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
//none of this is accessible unless you're in creative mode doing ctrl-pick btw
|
//none of this is accessible unless you're in creative mode doing ctrl-pick btw
|
||||||
TemplateAppearance nbtAppearance;
|
TemplateAppearance nbtAppearance;
|
||||||
int tint;
|
int tint;
|
||||||
BlockState theme = TemplateEntity.readStateFromItem(stack);
|
BlockState theme = FramedEntity.readStateFromItem(stack);
|
||||||
if(!theme.isAir()) {
|
if(!theme.isAir()) {
|
||||||
nbtAppearance = tam.getTemplateAppearance(theme);
|
nbtAppearance = tam.getTemplateAppearance(theme);
|
||||||
tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).templates$getItemColors().getColor(new ItemStack(theme.getBlock()), 0);
|
tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).templates$getItemColors().getColor(new ItemStack(theme.getBlock()), 0);
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
package fr.adrien1106.reframedtemplates.util;
|
||||||
|
|
||||||
|
import net.minecraft.util.function.BooleanBiFunction;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
|
||||||
|
public class VoxelHelper {
|
||||||
|
public static VoxelShape rotateClockwise(VoxelShape shape, Direction.Axis axis) {
|
||||||
|
VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() };
|
||||||
|
switch (axis) {
|
||||||
|
case Y:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxZ, minY, minX, 1 - minZ, maxY, maxX), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, 1 - maxZ, minY, maxX, 1 - minZ, maxY), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxY, minX, minZ, 1 - minY, maxX, maxZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return buffer[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VoxelShape rotateCounterClockwise(VoxelShape shape, Direction.Axis axis) {
|
||||||
|
VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() };
|
||||||
|
switch (axis) {
|
||||||
|
case Y:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minZ, minY, 1 - maxX, maxZ, maxY, 1 - minX), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minZ, 1 - maxY, maxX, maxZ, 1 - minY), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minY, 1 - maxX, minZ, maxY, 1 - minX, maxZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return buffer[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VoxelShape mirror(VoxelShape shape, Direction.Axis axis) {
|
||||||
|
VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() };
|
||||||
|
switch (axis) {
|
||||||
|
case Y:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, 1 - maxY, minZ, maxX, 1 - minY, maxZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( 1 - maxX, minY, minZ, 1 - minX, maxY, maxZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minY, 1 - maxZ, maxX, maxY, 1 - minZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return buffer[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VoxelShape offset(VoxelShape shape, Direction.Axis axis, float offset) {
|
||||||
|
VoxelShape[] buffer = new VoxelShape[]{ shape, VoxelShapes.empty() };
|
||||||
|
switch (axis) {
|
||||||
|
case Y:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, offset + minY, minZ, maxX, offset + maxY, maxZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( offset + minX, minY, minZ, offset + maxX, maxY, maxZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
buffer[0].forEachBox((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = VoxelShapes.combineAndSimplify( buffer[1], VoxelShapes.cuboid( minX, minY, offset + minZ, maxX, maxY, offset + maxZ), BooleanBiFunction.OR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return buffer[1];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package fr.adrien1106.reframedtemplates.util.property;
|
||||||
|
|
||||||
|
import net.minecraft.util.StringIdentifiable;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum StairDirection implements StringIdentifiable {
|
||||||
|
NORTH_DOWN("north_down", Direction.NORTH, Direction.DOWN, Direction.EAST, 0),
|
||||||
|
DOWN_SOUTH("down_south", Direction.DOWN, Direction.SOUTH, Direction.EAST, 1),
|
||||||
|
SOUTH_UP("south_up", Direction.SOUTH, Direction.UP, Direction.EAST, 2),
|
||||||
|
UP_NORTH("up_north", Direction.UP, Direction.NORTH, Direction.EAST, 3),
|
||||||
|
WEST_DOWN("west_down", Direction.WEST, Direction.DOWN, Direction.SOUTH, 4),
|
||||||
|
DOWN_EAST("down_east", Direction.DOWN, Direction.EAST, Direction.SOUTH, 5),
|
||||||
|
EAST_UP("east_up", Direction.EAST, Direction.UP, Direction.SOUTH, 6),
|
||||||
|
UP_WEST("up_west", Direction.UP, Direction.WEST, Direction.SOUTH, 7),
|
||||||
|
WEST_NORTH("west_north", Direction.WEST, Direction.NORTH, Direction.DOWN, 8),
|
||||||
|
NORTH_EAST("north_east", Direction.NORTH, Direction.EAST, Direction.DOWN, 9),
|
||||||
|
EAST_SOUTH("east_south", Direction.EAST, Direction.SOUTH, Direction.DOWN, 10),
|
||||||
|
SOUTH_WEST("south_west", Direction.SOUTH, Direction.WEST, Direction.DOWN, 11);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Direction first_direction;
|
||||||
|
private final Direction second_direction;
|
||||||
|
private final Direction right_direction;
|
||||||
|
private final Direction left_direction;
|
||||||
|
private final int ID;
|
||||||
|
|
||||||
|
StairDirection(String name, Direction first_direction, Direction second_direction, Direction right_direction, int id) {
|
||||||
|
this.name = name;
|
||||||
|
this.first_direction = first_direction;
|
||||||
|
this.second_direction = second_direction;
|
||||||
|
this.right_direction = right_direction;
|
||||||
|
this.left_direction = right_direction.getOpposite();
|
||||||
|
this.ID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String asString() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getFirstDirection() {
|
||||||
|
return first_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getSecondDirection() {
|
||||||
|
return second_direction;
|
||||||
|
}
|
||||||
|
public Direction getRightDirection() {
|
||||||
|
return right_direction;
|
||||||
|
}
|
||||||
|
public Direction getLeftDirection() {
|
||||||
|
return left_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDirection(Direction direction) {
|
||||||
|
return this.first_direction.equals(direction)
|
||||||
|
|| this.second_direction.equals(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getID() {
|
||||||
|
return this.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StairDirection getByDirections(Direction direction_1, Direction direction_2) {
|
||||||
|
return Arrays.stream(StairDirection.values())
|
||||||
|
.filter(value -> value.hasDirection(direction_1) && value.hasDirection(direction_2))
|
||||||
|
.findFirst().orElse(StairDirection.NORTH_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StairDirection fromId(int id) {
|
||||||
|
return Arrays.stream(StairDirection.values())
|
||||||
|
.filter(value -> value.getID() == id)
|
||||||
|
.findFirst().orElse(StairDirection.NORTH_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StairDirection fromName(String name) {
|
||||||
|
return Arrays.stream(StairDirection.values())
|
||||||
|
.filter(value -> value.name().equals(name))
|
||||||
|
.findFirst().orElse(StairDirection.NORTH_DOWN);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package fr.adrien1106.reframedtemplates.util.property;
|
||||||
|
|
||||||
|
import net.minecraft.util.StringIdentifiable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public enum StairShape implements StringIdentifiable {
|
||||||
|
STRAIGHT("straight", 0),
|
||||||
|
INNER_RIGHT("inner_right", 1),
|
||||||
|
INNER_LEFT("inner_left", 2),
|
||||||
|
OUTER_RIGHT("outer_right", 3),
|
||||||
|
OUTER_LEFT("outer_left", 4),
|
||||||
|
FIRST_OUTER_RIGHT("first_outer_right", 5),
|
||||||
|
FIRST_OUTER_LEFT("first_outer_left", 6),
|
||||||
|
SECOND_OUTER_RIGHT("second_outer_right", 7),
|
||||||
|
SECOND_OUTER_LEFT("second_outer_left", 8);
|
||||||
|
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final int ID;
|
||||||
|
|
||||||
|
StairShape(String name, int id) {
|
||||||
|
this.name = name;
|
||||||
|
this.ID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String asString() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getID() {
|
||||||
|
return this.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StairShape fromId(int id) {
|
||||||
|
return Arrays.stream(StairShape.values())
|
||||||
|
.filter(value -> value.getID() == id)
|
||||||
|
.findFirst().orElse(StairShape.STRAIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StairShape fromName(String name) {
|
||||||
|
return Arrays.stream(StairShape.values())
|
||||||
|
.filter(value -> value.name().equals(name))
|
||||||
|
.findFirst().orElse(StairShape.STRAIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"parent": "minecraft:block/block",
|
||||||
|
"textures": {
|
||||||
|
"particle": "#side"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [0, 0, 0],
|
||||||
|
"to": [16, 8, 16],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "north"},
|
||||||
|
"east": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "east"},
|
||||||
|
"south": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "south"},
|
||||||
|
"west": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "west"},
|
||||||
|
"up": {"uv": [0, 0, 16, 16], "texture": "#top"},
|
||||||
|
"down": {"uv": [0, 0, 16, 16], "texture": "#bottom", "cullface": "down"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [8, 0, 0],
|
||||||
|
"to": [16, 8, 16],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "north"},
|
||||||
|
"east": {"uv": [0, 8, 16, 16], "texture": "#side", "cullface": "east"},
|
||||||
|
"south": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "south"},
|
||||||
|
"west": {"uv": [0, 8, 16, 16], "texture": "#side"},
|
||||||
|
"up": {"uv": [8, 0, 16, 16], "texture": "#top", "cullface": "up"},
|
||||||
|
"down": {"uv": [8, 0, 16, 16], "texture": "#bottom"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [8, 8, 8],
|
||||||
|
"to": [16, 16, 16],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [0, 0, 8, 8], "texture": "#side"},
|
||||||
|
"east": {"uv": [0, 0, 8, 8], "texture": "#side"},
|
||||||
|
"south": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "south"},
|
||||||
|
"west": {"uv": [8, 0, 16, 8], "texture": "#side", "cullface": "west"},
|
||||||
|
"up": {"uv": [8, 8, 16, 16], "texture": "#top", "cullface": "up"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [0, 0, 8],
|
||||||
|
"to": [8, 8, 16],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [8, 8, 16, 16], "texture": "#side"},
|
||||||
|
"south": {"uv": [0, 8, 8, 16], "texture": "#side", "cullface": "south"},
|
||||||
|
"west": {"uv": [8, 8, 16, 16], "texture": "#side", "cullface": "west"},
|
||||||
|
"up": {"uv": [0, 8, 8, 16], "texture": "#top", "cullface": "up"},
|
||||||
|
"down": {"uv": [0, 0, 8, 8], "texture": "#bottom"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user