From cce934d537305e04fcea2e2ef16e3ceea770be3d Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Wed, 28 Apr 2021 01:13:15 +0300 Subject: [PATCH] Cactus fixes & enhancements --- .../ru/betterend/blocks/NeonCactusBlock.java | 299 +------------ .../blocks/NeonCactusPlantBlock.java | 396 ++++++++++++++++++ .../java/ru/betterend/registry/EndBlocks.java | 5 +- .../world/features/NeonCactusFeature.java | 85 +--- .../blockstates/neon_cactus_slab.json | 15 + .../blockstates/neon_cactus_stairs.json | 44 ++ .../models/block/neon_cactus_slab.json | 8 + .../models/block/neon_cactus_stairs.json | 8 + .../block/neon_cactus_stairs_inner.json | 8 + .../block/neon_cactus_stairs_outer.json | 8 + .../models/item/neon_cactus_slab.json | 3 + .../models/item/neon_cactus_stairs.json | 3 + 12 files changed, 507 insertions(+), 375 deletions(-) create mode 100644 src/main/java/ru/betterend/blocks/NeonCactusPlantBlock.java create mode 100644 src/main/resources/assets/betterend/blockstates/neon_cactus_slab.json create mode 100644 src/main/resources/assets/betterend/blockstates/neon_cactus_stairs.json create mode 100644 src/main/resources/assets/betterend/models/block/neon_cactus_slab.json create mode 100644 src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json create mode 100644 src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json create mode 100644 src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json create mode 100644 src/main/resources/assets/betterend/models/item/neon_cactus_slab.json create mode 100644 src/main/resources/assets/betterend/models/item/neon_cactus_stairs.json diff --git a/src/main/java/ru/betterend/blocks/NeonCactusBlock.java b/src/main/java/ru/betterend/blocks/NeonCactusBlock.java index a9ad12c8..55fa5910 100644 --- a/src/main/java/ru/betterend/blocks/NeonCactusBlock.java +++ b/src/main/java/ru/betterend/blocks/NeonCactusBlock.java @@ -1,304 +1,11 @@ package ru.betterend.blocks; -import java.util.EnumMap; -import java.util.Random; - -import com.google.common.collect.Maps; - import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -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.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.pathfinder.PathComputationType; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.VoxelShape; -import ru.betterend.blocks.BlockProperties.CactusBottom; -import ru.betterend.blocks.BlockProperties.TripleShape; -import ru.betterend.blocks.basis.BlockBaseNotFull; -import ru.betterend.client.render.ERenderLayer; -import ru.betterend.interfaces.IRenderTypeable; -import ru.betterend.registry.EndBlocks; -import ru.betterend.registry.EndTags; -import ru.betterend.util.BlocksHelper; -import ru.betterend.util.MHelper; +import ru.betterend.blocks.basis.EndPillarBlock; -public class NeonCactusBlock extends BlockBaseNotFull implements SimpleWaterloggedBlock, IRenderTypeable { - public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; - public static final EnumProperty CACTUS_BOTTOM = BlockProperties.CACTUS_BOTTOM; - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - public static final DirectionProperty FACING = BlockStateProperties.FACING; - - private static final EnumMap BIG_SHAPES_OPEN = Maps.newEnumMap(Direction.class); - private static final EnumMap MEDIUM_SHAPES_OPEN = Maps.newEnumMap(Direction.class); - private static final EnumMap SMALL_SHAPES_OPEN = Maps.newEnumMap(Direction.class); - private static final EnumMap BIG_SHAPES = Maps.newEnumMap(Axis.class); - private static final EnumMap MEDIUM_SHAPES = Maps.newEnumMap(Axis.class); - private static final EnumMap SMALL_SHAPES = Maps.newEnumMap(Axis.class); - private static final int MAX_LENGTH = 12; - +public class NeonCactusBlock extends EndPillarBlock { public NeonCactusBlock() { - super(FabricBlockSettings.copyOf(Blocks.CACTUS).luminance(15).randomTicks()); - registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false).setValue(FACING, Direction.UP).setValue(SHAPE, TripleShape.TOP)); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { - stateManager.add(SHAPE, CACTUS_BOTTOM, WATERLOGGED, FACING); - } - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { - LevelAccessor world = ctx.getLevel(); - BlockPos pos = ctx.getClickedPos(); - Direction dir = ctx.getClickedFace(); - BlockState down = world.getBlockState(pos.relative(dir.getOpposite())); - BlockState state = this.defaultBlockState().setValue(WATERLOGGED, world.getFluidState(pos).getType() == Fluids.WATER).setValue(FACING, ctx.getClickedFace()); - if (down.is(Blocks.END_STONE) || down.is(EndBlocks.ENDSTONE_DUST)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); - } - else if (down.is(EndBlocks.END_MOSS)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); - } - else { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); - } - return state; - } - - @Override - public BlockState rotate(BlockState state, Rotation rotation) { - return BlocksHelper.rotateHorizontal(state, rotation, FACING); - } - - @Override - public BlockState mirror(BlockState state, Mirror mirror) { - return BlocksHelper.mirrorHorizontal(state, mirror, FACING); - } - - @Override - public FluidState getFluidState(BlockState state) { - return (Boolean) state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); - } - - @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { - if (!canSurvive(state, world, pos)) { - world.getBlockTicks().scheduleTick(pos, this, MHelper.randRange(1, 4, world.getRandom())); - return state; - } - if ((Boolean) state.getValue(WATERLOGGED)) { - world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - } - Direction dir = state.getValue(FACING); - BlockState downState = world.getBlockState(pos.relative(dir.getOpposite())); - if (downState.is(Blocks.END_STONE) || downState.is(EndBlocks.ENDSTONE_DUST)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); - } - else if (downState.is(EndBlocks.END_MOSS)) { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); - } - else { - state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); - } - return state; - } - - @Override - public void tick(BlockState blockState, ServerLevel serverLevel, BlockPos blockPos, Random random) { - if (!blockState.canSurvive(serverLevel, blockPos)) { - serverLevel.destroyBlock(blockPos, true); - } - } - - @Override - public ERenderLayer getRenderLayer() { - return ERenderLayer.CUTOUT; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { - TripleShape shape = state.getValue(SHAPE); - Direction dir = state.getValue(FACING); - BlockState next = view.getBlockState(pos.relative(dir)); - if (next.is(this)) { - Axis axis = dir.getAxis(); - if (shape == TripleShape.BOTTOM) { - return BIG_SHAPES.get(axis); - } - return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES.get(axis) : SMALL_SHAPES.get(axis); - } - else { - if (shape == TripleShape.BOTTOM) { - return BIG_SHAPES_OPEN.get(dir); - } - return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES_OPEN.get(dir) : SMALL_SHAPES_OPEN.get(dir); - } - } - - @Override - public boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { - Direction dir = state.getValue(FACING); - BlockPos supportPos = pos.relative(dir.getOpposite()); - BlockState support = level.getBlockState(supportPos); - return support.is(this) || support.isFaceSturdy(level, supportPos, dir); - } - - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { - if (!this.canSurvive(state, world, pos)) { - return; - } - Direction dir = state.getValue(FACING); - if (!world.isEmptyBlock(pos.relative(dir))) { - return; - } - int length = getLength(state, world, pos, MAX_LENGTH); - if (length < 0 || length > MAX_LENGTH - 1) { - return; - } - if (dir != Direction.UP) { - int horizontal = getHorizontal(state, world, pos, 2); - if (horizontal > random.nextInt(2)) { - dir = Direction.UP; - if (!world.getBlockState(pos.above()).isAir()) { - return; - } - } - } - else if (length > 1 && world.getBlockState(pos.below()).is(this)) { - Direction side = BlocksHelper.randomHorizontal(random); - BlockPos sidePos = pos.relative(side); - if (world.isEmptyBlock(sidePos)) { - BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, side); - BlocksHelper.setWithoutUpdate(world, sidePos, placement); - } - } - BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, dir); - BlocksHelper.setWithoutUpdate(world, pos.relative(dir), placement); - mutateStem(placement, world, pos, MAX_LENGTH); - } - - @Override - public boolean isPathfindable(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, PathComputationType pathComputationType) { - return false; - } - - @Override - public void entityInside(BlockState blockState, Level level, BlockPos blockPos, Entity entity) { - entity.hurt(DamageSource.CACTUS, 1.0F); - } - - private int getLength(BlockState state, ServerLevel world, BlockPos pos, int max) { - int length = 0; - Direction dir = state.getValue(FACING).getOpposite(); - MutableBlockPos mut = new MutableBlockPos().set(pos); - for (int i = 0; i < max; i++) { - mut.move(dir); - state = world.getBlockState(mut); - if (!state.is(this)) { - if (!state.is(EndTags.END_GROUND)) { - length = -1; - } - break; - } - dir = state.getValue(FACING).getOpposite(); - length ++; - } - return length; - } - - private int getHorizontal(BlockState state, ServerLevel world, BlockPos pos, int max) { - int count = 0; - Direction dir = state.getValue(FACING).getOpposite(); - MutableBlockPos mut = new MutableBlockPos().set(pos); - for (int i = 0; i < max; i++) { - mut.move(dir); - state = world.getBlockState(mut); - if (!state.is(this)) { - break; - } - dir = state.getValue(FACING).getOpposite(); - if (dir.getStepY() != 0) { - break; - } - count ++; - } - return count; - } - - private void mutateStem(BlockState state, ServerLevel world, BlockPos pos, int max) { - Direction dir = state.getValue(FACING).getOpposite(); - MutableBlockPos mut = new MutableBlockPos().set(pos); - for (int i = 0; i < max; i++) { - mut.move(dir); - state = world.getBlockState(mut); - if (!state.is(this)) { - return; - } - int size = (i + 2) * 3 / max; - int src = state.getValue(SHAPE).getIndex(); - dir = state.getValue(FACING).getOpposite(); - if (src < size) { - TripleShape shape = TripleShape.fromIndex(size); - BlocksHelper.setWithoutUpdate(world, mut, state.setValue(SHAPE, shape)); - } - } - } - - static { - BIG_SHAPES.put(Axis.X, Block.box(0, 2, 2, 16, 14, 14)); - BIG_SHAPES.put(Axis.Y, Block.box(2, 0, 2, 14, 16, 14)); - BIG_SHAPES.put(Axis.Z, Block.box(2, 2, 0, 14, 14, 16)); - - MEDIUM_SHAPES.put(Axis.X, Block.box(0, 3, 3, 16, 13, 13)); - MEDIUM_SHAPES.put(Axis.Y, Block.box(3, 0, 3, 13, 16, 13)); - MEDIUM_SHAPES.put(Axis.Z, Block.box(3, 3, 0, 13, 13, 16)); - - SMALL_SHAPES.put(Axis.X, Block.box(0, 4, 4, 16, 12, 12)); - SMALL_SHAPES.put(Axis.Y, Block.box(4, 0, 4, 12, 16, 12)); - SMALL_SHAPES.put(Axis.Z, Block.box(4, 4, 0, 12, 12, 16)); - - BIG_SHAPES_OPEN.put(Direction.UP, Block.box(2, 0, 2, 14, 14, 14)); - BIG_SHAPES_OPEN.put(Direction.DOWN, Block.box(2, 2, 2, 14, 16, 14)); - BIG_SHAPES_OPEN.put(Direction.NORTH, Block.box(2, 2, 2, 14, 14, 16)); - BIG_SHAPES_OPEN.put(Direction.SOUTH, Block.box(2, 2, 0, 14, 14, 14)); - BIG_SHAPES_OPEN.put(Direction.WEST, Block.box(2, 2, 2, 16, 14, 14)); - BIG_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 2, 2, 14, 14, 14)); - - MEDIUM_SHAPES_OPEN.put(Direction.UP, Block.box(3, 0, 3, 13, 13, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.DOWN, Block.box(3, 3, 3, 13, 16, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.NORTH, Block.box(3, 3, 3, 13, 13, 16)); - MEDIUM_SHAPES_OPEN.put(Direction.SOUTH, Block.box(3, 3, 0, 13, 13, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.WEST, Block.box(3, 3, 3, 16, 13, 13)); - MEDIUM_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 3, 3, 13, 13, 13)); - - SMALL_SHAPES_OPEN.put(Direction.UP, Block.box(4, 0, 4, 12, 12, 12)); - SMALL_SHAPES_OPEN.put(Direction.DOWN, Block.box(4, 4, 4, 12, 16, 12)); - SMALL_SHAPES_OPEN.put(Direction.NORTH, Block.box(4, 4, 4, 12, 12, 16)); - SMALL_SHAPES_OPEN.put(Direction.SOUTH, Block.box(4, 4, 0, 12, 12, 12)); - SMALL_SHAPES_OPEN.put(Direction.WEST, Block.box(4, 4, 4, 16, 12, 12)); - SMALL_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 4, 4, 12, 12, 12)); + super(FabricBlockSettings.copyOf(Blocks.CACTUS).luminance(15)); } } diff --git a/src/main/java/ru/betterend/blocks/NeonCactusPlantBlock.java b/src/main/java/ru/betterend/blocks/NeonCactusPlantBlock.java new file mode 100644 index 00000000..be5131e2 --- /dev/null +++ b/src/main/java/ru/betterend/blocks/NeonCactusPlantBlock.java @@ -0,0 +1,396 @@ +package ru.betterend.blocks; + +import java.util.EnumMap; +import java.util.List; +import java.util.Random; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos.MutableBlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +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.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import ru.betterend.blocks.BlockProperties.CactusBottom; +import ru.betterend.blocks.BlockProperties.TripleShape; +import ru.betterend.blocks.basis.BlockBaseNotFull; +import ru.betterend.client.render.ERenderLayer; +import ru.betterend.interfaces.IRenderTypeable; +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndTags; +import ru.betterend.util.BlocksHelper; +import ru.betterend.util.MHelper; + +public class NeonCactusPlantBlock extends BlockBaseNotFull implements SimpleWaterloggedBlock, IRenderTypeable { + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + public static final EnumProperty CACTUS_BOTTOM = BlockProperties.CACTUS_BOTTOM; + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + public static final DirectionProperty FACING = BlockStateProperties.FACING; + + private static final EnumMap BIG_SHAPES_OPEN = Maps.newEnumMap(Direction.class); + private static final EnumMap MEDIUM_SHAPES_OPEN = Maps.newEnumMap(Direction.class); + private static final EnumMap SMALL_SHAPES_OPEN = Maps.newEnumMap(Direction.class); + private static final EnumMap BIG_SHAPES = Maps.newEnumMap(Axis.class); + private static final EnumMap MEDIUM_SHAPES = Maps.newEnumMap(Axis.class); + private static final EnumMap SMALL_SHAPES = Maps.newEnumMap(Axis.class); + private static final int MAX_LENGTH = 12; + + public NeonCactusPlantBlock() { + super(FabricBlockSettings.copyOf(Blocks.CACTUS).luminance(15).randomTicks()); + registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false).setValue(FACING, Direction.UP).setValue(SHAPE, TripleShape.TOP)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder stateManager) { + stateManager.add(SHAPE, CACTUS_BOTTOM, WATERLOGGED, FACING); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext ctx) { + LevelAccessor world = ctx.getLevel(); + BlockPos pos = ctx.getClickedPos(); + Direction dir = ctx.getClickedFace(); + BlockState down = world.getBlockState(pos.relative(dir.getOpposite())); + BlockState state = this.defaultBlockState().setValue(WATERLOGGED, world.getFluidState(pos).getType() == Fluids.WATER).setValue(FACING, ctx.getClickedFace()); + if (down.is(Blocks.END_STONE) || down.is(EndBlocks.ENDSTONE_DUST)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); + } + else if (down.is(EndBlocks.END_MOSS)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); + } + else { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); + } + return state; + } + + @Override + public BlockState rotate(BlockState state, Rotation rotation) { + return BlocksHelper.rotateHorizontal(state, rotation, FACING); + } + + @Override + public BlockState mirror(BlockState state, Mirror mirror) { + return BlocksHelper.mirrorHorizontal(state, mirror, FACING); + } + + @Override + public FluidState getFluidState(BlockState state) { + return (Boolean) state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { + if (!canSurvive(state, world, pos)) { + world.getBlockTicks().scheduleTick(pos, this, MHelper.randRange(1, 4, world.getRandom())); + return state; + } + if ((Boolean) state.getValue(WATERLOGGED)) { + world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + } + Direction dir = state.getValue(FACING); + BlockState downState = world.getBlockState(pos.relative(dir.getOpposite())); + if (downState.is(Blocks.END_STONE) || downState.is(EndBlocks.ENDSTONE_DUST)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); + } + else if (downState.is(EndBlocks.END_MOSS)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); + } + else { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); + } + return state; + } + + @Override + public void tick(BlockState blockState, ServerLevel serverLevel, BlockPos blockPos, Random random) { + if (!blockState.canSurvive(serverLevel, blockPos)) { + serverLevel.destroyBlock(blockPos, true); + } + } + + @Override + public ERenderLayer getRenderLayer() { + return ERenderLayer.CUTOUT; + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) { + TripleShape shape = state.getValue(SHAPE); + Direction dir = state.getValue(FACING); + BlockState next = view.getBlockState(pos.relative(dir)); + if (next.is(this)) { + Axis axis = dir.getAxis(); + if (shape == TripleShape.BOTTOM) { + return BIG_SHAPES.get(axis); + } + return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES.get(axis) : SMALL_SHAPES.get(axis); + } + else { + if (shape == TripleShape.BOTTOM) { + return BIG_SHAPES_OPEN.get(dir); + } + return shape == TripleShape.MIDDLE ? MEDIUM_SHAPES_OPEN.get(dir) : SMALL_SHAPES_OPEN.get(dir); + } + } + + @Override + public boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + Direction dir = state.getValue(FACING); + BlockPos supportPos = pos.relative(dir.getOpposite()); + BlockState support = level.getBlockState(supportPos); + return support.is(this) || support.isFaceSturdy(level, supportPos, dir); + } + + @Override + public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) { + if (!this.canSurvive(state, world, pos) || random.nextInt(8) > 0) { + return; + } + Direction dir = state.getValue(FACING); + if (!world.isEmptyBlock(pos.relative(dir))) { + return; + } + int length = getLength(state, world, pos, MAX_LENGTH); + if (length < 0 || length > MAX_LENGTH - 1) { + return; + } + if (dir.getAxis().isHorizontal()) { + int horizontal = getHorizontal(state, world, pos, 2); + if (horizontal > random.nextInt(2)) { + dir = Direction.UP; + if (!world.getBlockState(pos.above()).isAir()) { + return; + } + } + } + else if (length > 1 && world.getBlockState(pos.below()).is(this)) { + Direction side = BlocksHelper.randomHorizontal(random); + BlockPos sidePos = pos.relative(side); + if (world.isEmptyBlock(sidePos)) { + BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, side); + BlocksHelper.setWithoutUpdate(world, sidePos, placement); + } + } + BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, dir); + BlocksHelper.setWithoutUpdate(world, pos.relative(dir), placement); + mutateStem(placement, world, pos, MAX_LENGTH); + } + + public void growPlant(WorldGenLevel world, BlockPos pos, Random random) { + growPlant(world, pos, random, MHelper.randRange(MAX_LENGTH >> 1, MAX_LENGTH, random)); + } + + public void growPlant(WorldGenLevel world, BlockPos pos, Random random, int iterations) { + BlockState state = defaultBlockState(); + BlockState downState = world.getBlockState(pos.below()); + if (downState.is(Blocks.END_STONE) || downState.is(EndBlocks.ENDSTONE_DUST)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.SAND); + } + else if (downState.is(EndBlocks.END_MOSS)) { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.MOSS); + } + else { + state = state.setValue(CACTUS_BOTTOM, CactusBottom.EMPTY); + } + BlocksHelper.setWithoutUpdate(world, pos, state); + List ends = Lists.newArrayList(pos.mutable()); + for (int i = 0; i < iterations; i++) { + int count = ends.size(); + for (int n = 0; n < count; n++) { + if (!growIteration(world, ends.get(n), random, ends, i)) { + ends.remove(n); + count--; + n--; + } + } + } + } + + private boolean growIteration(WorldGenLevel world, MutableBlockPos pos, Random random, List ends, int length) { + BlockState state = world.getBlockState(pos); + if (!state.is(this)) { + return false; + } + Direction dir = state.getValue(FACING); + if (!world.isEmptyBlock(pos.relative(dir))) { + return false; + } + if (dir.getAxis().isHorizontal()) { + int horizontal = getHorizontal(state, world, pos, 2); + if (horizontal > random.nextInt(2)) { + dir = Direction.UP; + if (!world.getBlockState(pos.above()).isAir()) { + return false; + } + } + } + else if (length > 1 && world.getBlockState(pos.below()).is(this)) { + MutableBlockPos iterPos = pos.mutable(); + BlockState iterState = state; + Direction startDir = null; + Direction lastDir = null; + while (iterState.is(this)) { + startDir = iterState.getValue(FACING); + if (lastDir == null) { + for (Direction side: BlocksHelper.HORIZONTAL) { + BlockState sideState = world.getBlockState(iterPos.relative(side)); + if (sideState.is(this)) { + Direction sideDir = sideState.getValue(FACING); + if (sideDir != side) { + continue; + } + lastDir = sideDir; + } + } + } + iterPos.move(dir); + iterState = world.getBlockState(iterPos); + } + + Direction side = lastDir == null ? BlocksHelper.randomHorizontal(random) : lastDir.getClockWise(); + if (side.getOpposite() == startDir) { + side = side.getClockWise(); + } + BlockPos sidePos = pos.relative(side); + if (world.isEmptyBlock(sidePos)) { + BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, side); + BlocksHelper.setWithoutUpdate(world, sidePos, placement); + ends.add(sidePos.mutable()); + } + } + BlockState placement = state.setValue(SHAPE, TripleShape.TOP).setValue(CACTUS_BOTTOM, CactusBottom.EMPTY).setValue(WATERLOGGED, false).setValue(FACING, dir); + BlocksHelper.setWithoutUpdate(world, pos.relative(dir), placement); + mutateStem(placement, world, pos, MAX_LENGTH); + pos.move(dir); + return true; + } + + @Override + public boolean isPathfindable(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, PathComputationType pathComputationType) { + return false; + } + + @Override + public void entityInside(BlockState blockState, Level level, BlockPos blockPos, Entity entity) { + entity.hurt(DamageSource.CACTUS, 1.0F); + } + + private int getLength(BlockState state, ServerLevel world, BlockPos pos, int max) { + int length = 0; + Direction dir = state.getValue(FACING).getOpposite(); + MutableBlockPos mut = new MutableBlockPos().set(pos); + for (int i = 0; i < max; i++) { + mut.move(dir); + state = world.getBlockState(mut); + if (!state.is(this)) { + if (!state.is(EndTags.END_GROUND)) { + length = -1; + } + break; + } + dir = state.getValue(FACING).getOpposite(); + length ++; + } + return length; + } + + private int getHorizontal(BlockState state, WorldGenLevel world, BlockPos pos, int max) { + int count = 0; + Direction dir = state.getValue(FACING).getOpposite(); + MutableBlockPos mut = new MutableBlockPos().set(pos); + for (int i = 0; i < max; i++) { + mut.move(dir); + state = world.getBlockState(mut); + if (!state.is(this)) { + break; + } + dir = state.getValue(FACING).getOpposite(); + if (dir.getStepY() != 0) { + break; + } + count ++; + } + return count; + } + + private void mutateStem(BlockState state, WorldGenLevel world, BlockPos pos, int max) { + Direction dir = state.getValue(FACING).getOpposite(); + MutableBlockPos mut = new MutableBlockPos().set(pos); + for (int i = 0; i < max; i++) { + mut.move(dir); + state = world.getBlockState(mut); + if (!state.is(this)) { + return; + } + int size = (i + 2) * 3 / max; + int src = state.getValue(SHAPE).getIndex(); + dir = state.getValue(FACING).getOpposite(); + if (src < size) { + TripleShape shape = TripleShape.fromIndex(size); + BlocksHelper.setWithoutUpdate(world, mut, state.setValue(SHAPE, shape)); + } + } + } + + static { + BIG_SHAPES.put(Axis.X, Block.box(0, 2, 2, 16, 14, 14)); + BIG_SHAPES.put(Axis.Y, Block.box(2, 0, 2, 14, 16, 14)); + BIG_SHAPES.put(Axis.Z, Block.box(2, 2, 0, 14, 14, 16)); + + MEDIUM_SHAPES.put(Axis.X, Block.box(0, 3, 3, 16, 13, 13)); + MEDIUM_SHAPES.put(Axis.Y, Block.box(3, 0, 3, 13, 16, 13)); + MEDIUM_SHAPES.put(Axis.Z, Block.box(3, 3, 0, 13, 13, 16)); + + SMALL_SHAPES.put(Axis.X, Block.box(0, 4, 4, 16, 12, 12)); + SMALL_SHAPES.put(Axis.Y, Block.box(4, 0, 4, 12, 16, 12)); + SMALL_SHAPES.put(Axis.Z, Block.box(4, 4, 0, 12, 12, 16)); + + BIG_SHAPES_OPEN.put(Direction.UP, Block.box(2, 0, 2, 14, 14, 14)); + BIG_SHAPES_OPEN.put(Direction.DOWN, Block.box(2, 2, 2, 14, 16, 14)); + BIG_SHAPES_OPEN.put(Direction.NORTH, Block.box(2, 2, 2, 14, 14, 16)); + BIG_SHAPES_OPEN.put(Direction.SOUTH, Block.box(2, 2, 0, 14, 14, 14)); + BIG_SHAPES_OPEN.put(Direction.WEST, Block.box(2, 2, 2, 16, 14, 14)); + BIG_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 2, 2, 14, 14, 14)); + + MEDIUM_SHAPES_OPEN.put(Direction.UP, Block.box(3, 0, 3, 13, 13, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.DOWN, Block.box(3, 3, 3, 13, 16, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.NORTH, Block.box(3, 3, 3, 13, 13, 16)); + MEDIUM_SHAPES_OPEN.put(Direction.SOUTH, Block.box(3, 3, 0, 13, 13, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.WEST, Block.box(3, 3, 3, 16, 13, 13)); + MEDIUM_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 3, 3, 13, 13, 13)); + + SMALL_SHAPES_OPEN.put(Direction.UP, Block.box(4, 0, 4, 12, 12, 12)); + SMALL_SHAPES_OPEN.put(Direction.DOWN, Block.box(4, 4, 4, 12, 16, 12)); + SMALL_SHAPES_OPEN.put(Direction.NORTH, Block.box(4, 4, 4, 12, 12, 16)); + SMALL_SHAPES_OPEN.put(Direction.SOUTH, Block.box(4, 4, 0, 12, 12, 12)); + SMALL_SHAPES_OPEN.put(Direction.WEST, Block.box(4, 4, 4, 16, 12, 12)); + SMALL_SHAPES_OPEN.put(Direction.EAST, Block.box(0, 4, 4, 12, 12, 12)); + } +} diff --git a/src/main/java/ru/betterend/registry/EndBlocks.java b/src/main/java/ru/betterend/registry/EndBlocks.java index 44a7f7b5..21a62209 100644 --- a/src/main/java/ru/betterend/registry/EndBlocks.java +++ b/src/main/java/ru/betterend/registry/EndBlocks.java @@ -205,7 +205,10 @@ public class EndBlocks { public static final Block AMARANITA_FUR = registerBlock("amaranita_fur", new FurBlock(MOSSY_GLOWSHROOM_SAPLING, 15, 4, true)); public static final Block AMARANITA_CAP = registerBlock("amaranita_cap", new AmaranitaCapBlock()); - public static final Block NEON_CACTUS = registerBlock("neon_cactus", new NeonCactusBlock()); + public static final Block NEON_CACTUS = registerBlock("neon_cactus", new NeonCactusPlantBlock()); + public static final Block NEON_CACTUS_BLOCK = registerBlock("neon_cactus_block", new NeonCactusBlock()); + public static final Block NEON_CACTUS_BLOCK_STAIRS = registerBlock("neon_cactus_stairs", new EndStairsBlock(NEON_CACTUS_BLOCK)); + public static final Block NEON_CACTUS_BLOCK_SLAB = registerBlock("neon_cactus_slab", new EndSlabBlock(NEON_CACTUS_BLOCK)); // Crops public static final Block SHADOW_BERRY = registerBlock("shadow_berry", new ShadowBerryBlock()); diff --git a/src/main/java/ru/betterend/world/features/NeonCactusFeature.java b/src/main/java/ru/betterend/world/features/NeonCactusFeature.java index 2accf7f3..a4bfcd80 100644 --- a/src/main/java/ru/betterend/world/features/NeonCactusFeature.java +++ b/src/main/java/ru/betterend/world/features/NeonCactusFeature.java @@ -3,95 +3,24 @@ package ru.betterend.world.features; import java.util.Random; import net.minecraft.core.BlockPos; -import net.minecraft.core.BlockPos.MutableBlockPos; -import net.minecraft.core.Direction; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -import ru.betterend.blocks.BlockProperties; -import ru.betterend.blocks.BlockProperties.CactusBottom; -import ru.betterend.blocks.BlockProperties.TripleShape; +import ru.betterend.blocks.NeonCactusPlantBlock; import ru.betterend.registry.EndBlocks; -import ru.betterend.util.BlocksHelper; -import ru.betterend.util.MHelper; public class NeonCactusFeature extends DefaultFeature { @Override - public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, - NoneFeatureConfiguration config) { - if (!world.getBlockState(pos.below()).is(EndBlocks.ENDSTONE_DUST)) { + public boolean place(WorldGenLevel world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, NoneFeatureConfiguration config) { + BlockState ground = world.getBlockState(pos.below()); + if (!ground.is(EndBlocks.ENDSTONE_DUST) && !ground.is(EndBlocks.END_MOSS)) { return false; } - - int h = MHelper.randRange(5, 20, random); - MutableBlockPos mut = new MutableBlockPos().set(pos); - Direction hor = BlocksHelper.randomHorizontal(random); - for (int i = 0; i < h; i++) { - if (!world.getBlockState(mut).getMaterial().isReplaceable()) { - break; - } - int size = (h - i) >> 2; - BlockState state = EndBlocks.NEON_CACTUS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, getBySize(size)).setValue(BlockStateProperties.FACING, Direction.UP); - if (i == 0) { - BlockState down = world.getBlockState(mut.below()); - if (down.is(Blocks.END_STONE) || down.is(EndBlocks.ENDSTONE_DUST)) { - state = state.setValue(BlockProperties.CACTUS_BOTTOM, CactusBottom.SAND); - } - else if (down.is(EndBlocks.END_MOSS)) { - state = state.setValue(BlockProperties.CACTUS_BOTTOM, CactusBottom.MOSS); - } - else { - state = state.setValue(BlockProperties.CACTUS_BOTTOM, CactusBottom.EMPTY); - } - } - else { - state = state.setValue(BlockProperties.CACTUS_BOTTOM, CactusBottom.EMPTY); - } - BlocksHelper.setWithUpdate(world, mut, state); - if (i > 2 && i < (h - 1) && random.nextBoolean()) { - int length = h - i - MHelper.randRange(1, 2, random); - if (length > 0) { - Direction dir2 = hor; - hor = hor.getClockWise(); - int bsize = i > ((h << 1) / 3) ? 0 : size > 1 ? 1 : size; - branch(world, mut.relative(dir2), dir2, random, length, bsize); - } - } - mut.move(Direction.UP); - } + + NeonCactusPlantBlock cactus = ((NeonCactusPlantBlock) EndBlocks.NEON_CACTUS); + cactus.growPlant(world, pos, random); return true; } - - private void branch(WorldGenLevel world, BlockPos pos, Direction dir, Random random, int length, int size) { - int rotIndex = length >> 2; - MutableBlockPos mut = new MutableBlockPos().set(pos); - Direction hor = BlocksHelper.randomHorizontal(random); - for (int i = 0; i < length; i++) { - if (!world.getBlockState(mut).getMaterial().isReplaceable()) { - return; - } - BlocksHelper.setWithUpdate(world, mut, - EndBlocks.NEON_CACTUS.defaultBlockState().setValue(BlockProperties.TRIPLE_SHAPE, getBySize(size)) - .setValue(BlockStateProperties.FACING, dir)); - if (i == rotIndex) { - dir = Direction.UP; - size--; - } - if (i > 1 && i < (length - 1) && random.nextBoolean()) { - Direction dir2 = dir == Direction.UP ? hor : Direction.UP; - hor = hor.getClockWise(); - branch(world, mut.relative(dir2), dir2, random, MHelper.randRange(length / 4, length / 2, random), - size > 0 ? size - 1 : size); - } - mut.move(dir); - } - } - - private TripleShape getBySize(int size) { - return size < 1 ? TripleShape.TOP : size == 1 ? TripleShape.MIDDLE : TripleShape.BOTTOM; - } } diff --git a/src/main/resources/assets/betterend/blockstates/neon_cactus_slab.json b/src/main/resources/assets/betterend/blockstates/neon_cactus_slab.json new file mode 100644 index 00000000..bdfc0157 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/neon_cactus_slab.json @@ -0,0 +1,15 @@ +{ + "variants": { + "type=bottom": { + "model": "betterend:block/neon_cactus_slab" + }, + "type=top": { + "model": "betterend:block/neon_cactus_slab", + "x": 180, + "uvlock": true + }, + "type=double": { + "model": "betterend:block/neon_cactus_block" + } + } +} diff --git a/src/main/resources/assets/betterend/blockstates/neon_cactus_stairs.json b/src/main/resources/assets/betterend/blockstates/neon_cactus_stairs.json new file mode 100644 index 00000000..edc5a3a5 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/neon_cactus_stairs.json @@ -0,0 +1,44 @@ +{ + "variants": { + "facing=east,half=bottom,shape=straight": { "model": "betterend:block/neon_cactus_stairs" }, + "facing=west,half=bottom,shape=straight": { "model": "betterend:block/neon_cactus_stairs", "y": 180 }, + "facing=south,half=bottom,shape=straight": { "model": "betterend:block/neon_cactus_stairs", "y": 90 }, + "facing=north,half=bottom,shape=straight": { "model": "betterend:block/neon_cactus_stairs", "y": 270 }, + "facing=east,half=bottom,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer" }, + "facing=west,half=bottom,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer", "y": 180 }, + "facing=south,half=bottom,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer", "y": 90 }, + "facing=north,half=bottom,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer", "y": 270 }, + "facing=east,half=bottom,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer", "y": 270 }, + "facing=west,half=bottom,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer", "y": 90 }, + "facing=south,half=bottom,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer" }, + "facing=north,half=bottom,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer", "y": 180 }, + "facing=east,half=bottom,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner" }, + "facing=west,half=bottom,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner", "y": 180 }, + "facing=south,half=bottom,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner", "y": 90 }, + "facing=north,half=bottom,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner", "y": 270 }, + "facing=east,half=bottom,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner", "y": 270 }, + "facing=west,half=bottom,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner", "y": 90 }, + "facing=south,half=bottom,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner" }, + "facing=north,half=bottom,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner", "y": 180 }, + "facing=east,half=top,shape=straight": { "model": "betterend:block/neon_cactus_stairs", "x": 180 }, + "facing=west,half=top,shape=straight": { "model": "betterend:block/neon_cactus_stairs", "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight": { "model": "betterend:block/neon_cactus_stairs", "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight": { "model": "betterend:block/neon_cactus_stairs", "x": 180, "y": 270 }, + "facing=east,half=top,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180 }, + "facing=east,half=top,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180 }, + "facing=west,half=top,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left": { "model": "betterend:block/neon_cactus_stairs_outer", "x": 180, "y": 270 }, + "facing=east,half=top,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180 }, + "facing=east,half=top,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180 }, + "facing=west,half=top,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left": { "model": "betterend:block/neon_cactus_stairs_inner", "x": 180, "y": 270 } + } +} diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_slab.json b/src/main/resources/assets/betterend/models/block/neon_cactus_slab.json new file mode 100644 index 00000000..22fb196b --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "block/slab", + "textures": { + "bottom": "betterend:block/neon_cactus_block_top", + "top": "betterend:block/neon_cactus_block_top", + "side": "betterend:block/neon_cactus_block_side" + } +} diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json new file mode 100644 index 00000000..0a0df2b2 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/stairs", + "textures": { + "bottom": "betterend:block/neon_cactus_block_top", + "top": "betterend:block/neon_cactus_block_top", + "side": "betterend:block/neon_cactus_block_side" + } +} diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json new file mode 100644 index 00000000..78d80cc5 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/inner_stairs", + "textures": { + "bottom": "betterend:block/neon_cactus_block_top", + "top": "betterend:block/neon_cactus_block_top", + "side": "betterend:block/neon_cactus_block_side" + } +} diff --git a/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json new file mode 100644 index 00000000..01f12961 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/neon_cactus_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/outer_stairs", + "textures": { + "bottom": "betterend:block/neon_cactus_block_top", + "top": "betterend:block/neon_cactus_block_top", + "side": "betterend:block/neon_cactus_block_side" + } +} diff --git a/src/main/resources/assets/betterend/models/item/neon_cactus_slab.json b/src/main/resources/assets/betterend/models/item/neon_cactus_slab.json new file mode 100644 index 00000000..7bfe894c --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/neon_cactus_slab.json @@ -0,0 +1,3 @@ +{ + "parent": "betterend:block/neon_cactus_slab" +} diff --git a/src/main/resources/assets/betterend/models/item/neon_cactus_stairs.json b/src/main/resources/assets/betterend/models/item/neon_cactus_stairs.json new file mode 100644 index 00000000..22cab921 --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/neon_cactus_stairs.json @@ -0,0 +1,3 @@ +{ + "parent": "betterend:block/neon_cactus_stairs" +}