/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.mojang.serialization.MapCodec * org.jspecify.annotations.Nullable */ package net.minecraft.world.level.block; import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.ScheduledTickAccess; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.VegetationBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockBehaviour; 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.DoubleBlockHalf; import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.level.material.Fluids; import org.jspecify.annotations.Nullable; public class DoublePlantBlock extends VegetationBlock { public static final MapCodec CODEC = DoublePlantBlock.simpleCodec(DoublePlantBlock::new); public static final EnumProperty HALF = BlockStateProperties.DOUBLE_BLOCK_HALF; public MapCodec codec() { return CODEC; } public DoublePlantBlock(BlockBehaviour.Properties properties) { super(properties); this.registerDefaultState((BlockState)((BlockState)this.stateDefinition.any()).setValue(HALF, DoubleBlockHalf.LOWER)); } @Override protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticks, BlockPos pos, Direction directionToNeighbour, BlockPos neighbourPos, BlockState neighbourState, RandomSource random) { DoubleBlockHalf half = state.getValue(HALF); if (!(directionToNeighbour.getAxis() != Direction.Axis.Y || half == DoubleBlockHalf.LOWER != (directionToNeighbour == Direction.UP) || neighbourState.is(this) && neighbourState.getValue(HALF) != half)) { return Blocks.AIR.defaultBlockState(); } if (half == DoubleBlockHalf.LOWER && directionToNeighbour == Direction.DOWN && !state.canSurvive(level, pos)) { return Blocks.AIR.defaultBlockState(); } return super.updateShape(state, level, ticks, pos, directionToNeighbour, neighbourPos, neighbourState, random); } @Override public @Nullable BlockState getStateForPlacement(BlockPlaceContext context) { BlockPos pos = context.getClickedPos(); Level level = context.getLevel(); if (pos.getY() < level.getMaxY() && level.getBlockState(pos.above()).canBeReplaced(context)) { return super.getStateForPlacement(context); } return null; } @Override public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity by, ItemStack itemStack) { BlockPos abovePos = pos.above(); level.setBlock(abovePos, DoublePlantBlock.copyWaterloggedFrom(level, abovePos, (BlockState)this.defaultBlockState().setValue(HALF, DoubleBlockHalf.UPPER)), 3); } @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { if (state.getValue(HALF) == DoubleBlockHalf.UPPER) { BlockState belowState = level.getBlockState(pos.below()); return belowState.is(this) && belowState.getValue(HALF) == DoubleBlockHalf.LOWER; } return super.canSurvive(state, level, pos); } public static void placeAt(LevelAccessor level, BlockState state, BlockPos lowerPos, @Block.UpdateFlags int updateType) { BlockPos upperPos = lowerPos.above(); level.setBlock(lowerPos, DoublePlantBlock.copyWaterloggedFrom(level, lowerPos, (BlockState)state.setValue(HALF, DoubleBlockHalf.LOWER)), updateType); level.setBlock(upperPos, DoublePlantBlock.copyWaterloggedFrom(level, upperPos, (BlockState)state.setValue(HALF, DoubleBlockHalf.UPPER)), updateType); } public static BlockState copyWaterloggedFrom(LevelReader level, BlockPos pos, BlockState state) { if (state.hasProperty(BlockStateProperties.WATERLOGGED)) { return (BlockState)state.setValue(BlockStateProperties.WATERLOGGED, level.isWaterAt(pos)); } return state; } @Override public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { if (!level.isClientSide()) { if (player.preventsBlockDrops()) { DoublePlantBlock.preventDropFromBottomPart(level, pos, state, player); } else { DoublePlantBlock.dropResources(state, level, pos, null, player, player.getMainHandItem()); } } return super.playerWillDestroy(level, pos, state, player); } @Override public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack destroyedWith) { super.playerDestroy(level, player, pos, Blocks.AIR.defaultBlockState(), blockEntity, destroyedWith); } protected static void preventDropFromBottomPart(Level level, BlockPos pos, BlockState state, Player player) { BlockPos bottomPos; BlockState bottomState; DoubleBlockHalf part = state.getValue(HALF); if (part == DoubleBlockHalf.UPPER && (bottomState = level.getBlockState(bottomPos = pos.below())).is(state.getBlock()) && bottomState.getValue(HALF) == DoubleBlockHalf.LOWER) { BlockState blockState = bottomState.getFluidState().is(Fluids.WATER) ? Blocks.WATER.defaultBlockState() : Blocks.AIR.defaultBlockState(); level.setBlock(bottomPos, blockState, 35); level.levelEvent(player, 2001, bottomPos, Block.getId(bottomState)); } } @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(HALF); } @Override protected long getSeed(BlockState state, BlockPos pos) { return Mth.getSeed(pos.getX(), pos.below(state.getValue(HALF) == DoubleBlockHalf.LOWER ? 0 : 1).getY(), pos.getZ()); } }