diff --git a/src/main/java/dev/micle/wildflowers_backport/block/FlowerBedBlock.java b/src/main/java/dev/micle/wildflowers_backport/block/FlowerBedBlock.java new file mode 100644 index 0000000..7a1b62d --- /dev/null +++ b/src/main/java/dev/micle/wildflowers_backport/block/FlowerBedBlock.java @@ -0,0 +1,110 @@ +package dev.micle.wildflowers_backport.block; + +import com.google.common.collect.ImmutableMap; +import com.mojang.serialization.MapCodec; +import dev.micle.wildflowers_backport.util.BlockBehaviourUtils; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +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.*; +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.EnumProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.function.Function; + +public class FlowerBedBlock extends BushBlock implements BonemealableBlock, SegmentableBlock { + public static final MapCodec CODEC = BlockBehaviourUtils.simpleCodec(FlowerBedBlock::new); + public static final EnumProperty FACING = BlockStateProperties.HORIZONTAL_FACING; + public static final IntegerProperty AMOUNT = BlockStateProperties.FLOWER_AMOUNT; + private final Function shapes; + + public FlowerBedBlock(Properties pProperties) { + super(pProperties); + this.registerDefaultState(this.getStateDefinition().any().setValue(FACING, Direction.NORTH).setValue(AMOUNT, 1)); + this.shapes = this.makeShapes(); + } + + private Function makeShapes() { + return this.stateDefinition.getPossibleStates().stream().collect(ImmutableMap.toImmutableMap(Function.identity(), this.getShapeCalculator(FACING, AMOUNT)))::get; + } + + @Override + public BlockState rotate(BlockState blockState, LevelAccessor levelAccessor, BlockPos blockPos, Rotation rotation) { + return blockState.setValue(FACING, rotation.rotate(blockState.getValue(FACING))); + } + + @Override + public @NotNull BlockState mirror(BlockState blockState, Mirror mirror) { + return blockState.rotate(mirror.getRotation(blockState.getValue(FACING))); + } + + @Override + @ParametersAreNonnullByDefault + public boolean canBeReplaced(BlockState blockState, BlockPlaceContext blockPlaceContext) { + return this.canBeReplaced(blockState, blockPlaceContext, AMOUNT) ? true : super.canBeReplaced(blockState, blockPlaceContext); + } + + @Override + @ParametersAreNonnullByDefault + public @NotNull VoxelShape getShape(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext) { + return this.shapes.apply(blockState); + } + + @Override + public double getShapeHeight() { + return 3.0; + } + + @Override + public IntegerProperty getSegmentAmountProperty() { + return AMOUNT; + } + + @Override + @ParametersAreNonnullByDefault + public BlockState getStateForPlacement(BlockPlaceContext blockPlaceContext) { + return this.getStateForPlacement(blockPlaceContext, this, AMOUNT, FACING); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING, AMOUNT); + } + + @Override + @ParametersAreNonnullByDefault + public boolean isValidBonemealTarget(LevelReader levelReader, BlockPos blockPos, BlockState blockState, boolean isClient) { + return true; + } + + @Override + @ParametersAreNonnullByDefault + public boolean isBonemealSuccess(Level level, RandomSource randomSource, BlockPos blockPos, BlockState blockState) { + return true; + } + + @Override + @ParametersAreNonnullByDefault + public void performBonemeal(ServerLevel serverLevel, RandomSource randomSource, BlockPos blockPos, BlockState blockState) { + int i = blockState.getValue(AMOUNT); + if (i < 4) { + serverLevel.setBlock(blockPos, blockState.setValue(AMOUNT, i + 1), 2); + } else { + popResource(serverLevel, blockPos, new ItemStack(this)); + } + } +} diff --git a/src/main/java/dev/micle/wildflowers_backport/mixin/BlockBehaviourAccessor.java b/src/main/java/dev/micle/wildflowers_backport/mixin/BlockBehaviourAccessor.java new file mode 100644 index 0000000..ca69491 --- /dev/null +++ b/src/main/java/dev/micle/wildflowers_backport/mixin/BlockBehaviourAccessor.java @@ -0,0 +1,11 @@ +package dev.micle.wildflowers_backport.mixin; + +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(BlockBehaviour.class) +public interface BlockBehaviourAccessor { + @Accessor("properties") + BlockBehaviour.Properties wildflowers_backport$getProperties(); +} diff --git a/src/main/java/dev/micle/wildflowers_backport/util/BlockBehaviourUtils.java b/src/main/java/dev/micle/wildflowers_backport/util/BlockBehaviourUtils.java new file mode 100644 index 0000000..242d660 --- /dev/null +++ b/src/main/java/dev/micle/wildflowers_backport/util/BlockBehaviourUtils.java @@ -0,0 +1,22 @@ +package dev.micle.wildflowers_backport.util; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.micle.wildflowers_backport.mixin.BlockBehaviourAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; + +import java.util.function.Function; + +public class BlockBehaviourUtils { + public static final Codec PROPERTIES_CODEC = Codec.unit(BlockBehaviour.Properties::of); + + public static RecordCodecBuilder propertiesCodec() { + return PROPERTIES_CODEC.fieldOf("properties").forGetter(x -> ((BlockBehaviourAccessor) x).wildflowers_backport$getProperties()); + } + + public static MapCodec simpleCodec(Function blockPropertiesFunc) { + return RecordCodecBuilder.mapCodec(x -> x.group(propertiesCodec()).apply(x, blockPropertiesFunc)); + } +} diff --git a/src/main/resources/wildflowers_backport.mixins.json b/src/main/resources/wildflowers_backport.mixins.json index 9fb047d..c9cbf28 100644 --- a/src/main/resources/wildflowers_backport.mixins.json +++ b/src/main/resources/wildflowers_backport.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_8", "refmap": "firefly_bush_backport.refmap.json", "mixins": [ + "BlockBehaviourAccessor", "OctahedralGroupAccessor", "VoxelShapeAccessor", "ArrayVoxelShapeAccessor",