diff --git a/src/main/java/net/xevianlight/aphelion/block/custom/PipeTestBlock.java b/src/main/java/net/xevianlight/aphelion/block/custom/PipeTestBlock.java new file mode 100644 index 0000000..90bf565 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/block/custom/PipeTestBlock.java @@ -0,0 +1,125 @@ +package net.xevianlight.aphelion.block.custom; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.phys.shapes.BooleanOp; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; + +// a lot of this is ai slop so take it with a grainlet of salt +public class PipeTestBlock extends Block { + + // shortcuts for each directional property because they're pretty verbose + // t/f here means is/isn't connected outgoing in that direction + public static final BooleanProperty NORTH = BlockStateProperties.NORTH; + public static final BooleanProperty SOUTH = BlockStateProperties.SOUTH; + public static final BooleanProperty EAST = BlockStateProperties.EAST; + public static final BooleanProperty WEST = BlockStateProperties.WEST; + public static final BooleanProperty UP = BlockStateProperties.UP; + public static final BooleanProperty DOWN = BlockStateProperties.DOWN; + + // Voxel shape pieces to make the actual pipe model + private static final VoxelShape CORE = Block.box(6, 6, 6, 10, 10, 10); + private static final VoxelShape NORTH_SHAPE = Block.box(6, 6, 0, 10, 10, 6); + private static final VoxelShape SOUTH_SHAPE = Block.box(6, 6, 10, 10, 10, 16); + private static final VoxelShape EAST_SHAPE = Block.box(10, 6, 6, 16, 10, 10); + private static final VoxelShape WEST_SHAPE = Block.box(0, 6, 6, 6, 10, 10); + private static final VoxelShape UP_SHAPE = Block.box(6, 10, 6, 10, 16, 10); + private static final VoxelShape DOWN_SHAPE = Block.box(6, 0, 6, 10, 6, 10); + + // Assembles the "VoxelShape" of the block which i assume is just the collision/place/mine hitbox + // later this should be cached for each different shape that we need + @Override + public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { + VoxelShape shape = CORE; + + if (state.getValue(NORTH)) shape = Shapes.join(shape, NORTH_SHAPE, BooleanOp.OR); + if (state.getValue(SOUTH)) shape = Shapes.join(shape, SOUTH_SHAPE, BooleanOp.OR); + if (state.getValue(EAST)) shape = Shapes.join(shape, EAST_SHAPE, BooleanOp.OR); + if (state.getValue(WEST)) shape = Shapes.join(shape, WEST_SHAPE, BooleanOp.OR); + if (state.getValue(UP)) shape = Shapes.join(shape, UP_SHAPE, BooleanOp.OR); + if (state.getValue(DOWN)) shape = Shapes.join(shape, DOWN_SHAPE, BooleanOp.OR); + + return shape; + } + + public PipeTestBlock(Properties properties) { + super(properties); + this.registerDefaultState(this.stateDefinition.any() + .setValue(NORTH, false).setValue(SOUTH, false) + .setValue(EAST, false).setValue(WEST, false) + .setValue(UP, false).setValue(DOWN, false)); + } + + // This method determines the state when first placed + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + return makeConnections(context.getLevel(), context.getClickedPos()); + } + + // Updates the block when a neighbor changes + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) { + return makeConnections(level, currentPos); + } + + public static Properties getProperties() { + return Properties.of().noOcclusion(); + } + + private BlockState makeConnections(LevelAccessor level, BlockPos pos) { + return this.defaultBlockState() + .setValue(NORTH, canConnect(level, pos.north())) + .setValue(SOUTH, canConnect(level, pos.south())) + .setValue(EAST, canConnect(level, pos.east())) + .setValue(WEST, canConnect(level, pos.west())) + .setValue(UP, canConnect(level, pos.above())) + .setValue(DOWN, canConnect(level, pos.below())); + } + + private boolean canConnect(LevelAccessor level, BlockPos neighborPos) { + // Simplest logic: connect if the neighbor is also a SimplePipeBlock + return level.getBlockState(neighborPos).getBlock() == this; + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(NORTH, SOUTH, EAST, WEST, UP, DOWN); + } + + // Doesn't block sunlight +// @Override +// public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) { +// return true; +// } + + /// This function doesn't do what the AI says it does. I have no idea what it actually does, though + // 2. Prevents the "black shadows" inside or around the pipe +// @Override +// public int getLightBlock(BlockState state, BlockGetter worldIn, BlockPos pos) { +// return 0; +// } + + /// I don't know what this does, because Properties.noOcclusion() is the part that made the leaves keep + /// rendering their faces. + // 3. Tells adjacent blocks (like leaves) to keep rendering their faces +// @Override +// public boolean isOcclusionShapeFullBlock(BlockState state, BlockGetter worldIn, BlockPos pos) { +// return false; +// } + + // This bit affects how strong the ambient occlusion effect is + @Override + public float getShadeBrightness(BlockState state, BlockGetter world, BlockPos pos) { + return 1.0F; // Maintains full brightness + } +} diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java index 37e1af2..e03b33c 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModBlocks.java @@ -20,4 +20,5 @@ public class ModBlocks { public static final DeferredBlock VAF_MULTIBLOCK_DUMMY_BLOCK = BLOCKS.register("vaf_dummy_block", () -> new VAFMultiblockDummyBlock(VAFMultiblockDummyBlock.getProperties())); public static final DeferredBlock OXYGEN_TEST_BLOCK = BLOCKS.register("oxygen_test_block", () -> new OxygenTestBlock(OxygenTestBlock.getProperties())); public static final DeferredBlock ROCKET_ASSEMBLER_BLOCK = BLOCKS.register("rocket_assembler_block", () -> new RocketAssemblerBlock(RocketAssemblerBlock.getProperties())); + public static final DeferredBlock PIPE_TEST_BLOCK = BLOCKS.register("pipe", () -> new PipeTestBlock(PipeTestBlock.getProperties())); } diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java b/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java index 5a1071a..95a284b 100644 --- a/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModItems.java @@ -36,6 +36,7 @@ public static final DeferredItem MUSIC_DISC_BIT_SHIFT = ITEMS.register("mu public static final DeferredItem ARC_FURNACE_CASING_BLOCK = ITEMS.register("arc_furnace_casing", () -> new BlockItem(ModBlocks.ARC_FURNACE_CASING_BLOCK.get(), ArcFurnaceCasingBlock.getItemProperties())); public static final DeferredItem VACUUM_ARC_FURNACE_CONTROLLER = ITEMS.register("vacuum_arc_furnace_controller", () -> new BlockItem(ModBlocks.VACUUM_ARC_FURNACE_CONTROLLER.get(), VacuumArcFurnaceController.getItemProperties())); public static final DeferredItem OXYGEN_TEST_BLOCK = ITEMS.register("oxygen_test_block", () -> new BlockItem(ModBlocks.OXYGEN_TEST_BLOCK.get(), new Item.Properties())); + public static final DeferredItem PIPE_TEST_BLOCK = ITEMS.register("pipe", () -> new BlockItem(ModBlocks.PIPE_TEST_BLOCK.get(), new Item.Properties())); public static final DeferredItem LAUNCH_PAD = ITEMS.register("launch_pad", () -> new BlockItem(ModBlocks.LAUNCH_PAD.get(), LaunchPad.getItemProperties())); public static final DeferredItem ROCKET_ASSEMBLER_BLOCK = ITEMS.register("rocket_assembler_block", () -> new BlockItem(ModBlocks.ROCKET_ASSEMBLER_BLOCK.get(), RocketAssemblerBlock.getItemProperties())); // public static final DeferredItem VAF_MULTIBLOCK_DUMMY_BLOCK = ITEMS.register("vaf_multiblock_dummy_block", () -> new BlockItem(ModBlocks.VAF_MULTIBLOCK_DUMMY_BLOCK.get(), VAFMultiblockDummyBlock.getItemProperties())); diff --git a/src/main/resources/assets/aphelion/blockstates/pipe.json b/src/main/resources/assets/aphelion/blockstates/pipe.json new file mode 100644 index 0000000..1a1ddcf --- /dev/null +++ b/src/main/resources/assets/aphelion/blockstates/pipe.json @@ -0,0 +1,11 @@ +{ + "multipart": [ + { "apply": { "model": "aphelion:block/pipe_core" }}, + { "when": { "north": "true" }, "apply": { "model": "aphelion:block/pipe_side" }}, + { "when": { "east": "true" }, "apply": { "model": "aphelion:block/pipe_side", "y": 90 }}, + { "when": { "south": "true" }, "apply": { "model": "aphelion:block/pipe_side", "y": 180 }}, + { "when": { "west": "true" }, "apply": { "model": "aphelion:block/pipe_side", "y": 270 }}, + { "when": { "up": "true" }, "apply": { "model": "aphelion:block/pipe_side", "x": 270 }}, + { "when": { "down": "true" }, "apply": { "model": "aphelion:block/pipe_side", "x": 90 }} + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/pipe_core.json b/src/main/resources/assets/aphelion/models/block/pipe_core.json new file mode 100644 index 0000000..6ffa10d --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/pipe_core.json @@ -0,0 +1,20 @@ +{ + "ambientocclusion": false, + "textures": { + "texture": "aphelion:block/pipe_texture" + }, + "elements": [ + { + "from": [ 6, 6, 6 ], + "to": [ 10, 10, 10 ], + "faces": { + "down": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] }, + "up": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] }, + "north": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] }, + "south": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] }, + "west": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] }, + "east": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/models/block/pipe_side.json b/src/main/resources/assets/aphelion/models/block/pipe_side.json new file mode 100644 index 0000000..c3780b5 --- /dev/null +++ b/src/main/resources/assets/aphelion/models/block/pipe_side.json @@ -0,0 +1,18 @@ +{ + "textures": { + "texture": "aphelion:block/pipe_texture" + }, + "elements": [ + { + "from": [ 6, 6, 0 ], + "to": [ 10, 10, 6 ], + "faces": { + "down": { "texture": "#texture", "uv": [ 6, 0, 10, 6 ] }, + "up": { "texture": "#texture", "uv": [ 6, 0, 10, 6 ] }, + "north": { "texture": "#texture", "uv": [ 6, 6, 10, 10 ] }, + "west": { "texture": "#texture", "uv": [ 0, 6, 6, 10 ] }, + "east": { "texture": "#texture", "uv": [ 0, 6, 6, 10 ] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/aphelion/textures/block/pipe_texture.png b/src/main/resources/assets/aphelion/textures/block/pipe_texture.png new file mode 100644 index 0000000..5411618 Binary files /dev/null and b/src/main/resources/assets/aphelion/textures/block/pipe_texture.png differ