/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.mojang.serialization.MapCodec */ package net.minecraft.world.level.block; import com.mojang.serialization.MapCodec; import java.util.Iterator; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.item.FallingBlockEntity; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; 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.SimpleWaterloggedBlock; 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.BooleanProperty; import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; public class ScaffoldingBlock extends Block implements SimpleWaterloggedBlock { public static final MapCodec CODEC = ScaffoldingBlock.simpleCodec(ScaffoldingBlock::new); private static final int TICK_DELAY = 1; private static final VoxelShape SHAPE_STABLE = Shapes.or(Block.column(16.0, 14.0, 16.0), Shapes.rotateHorizontal(Block.box(0.0, 0.0, 0.0, 2.0, 16.0, 2.0)).values().stream().reduce(Shapes.empty(), Shapes::or)); private static final VoxelShape SHAPE_UNSTABLE_BOTTOM = Block.column(16.0, 0.0, 2.0); private static final VoxelShape SHAPE_UNSTABLE = Shapes.or(SHAPE_STABLE, SHAPE_UNSTABLE_BOTTOM, Shapes.rotateHorizontal(Block.boxZ(16.0, 0.0, 2.0, 0.0, 2.0)).values().stream().reduce(Shapes.empty(), Shapes::or)); private static final VoxelShape SHAPE_BELOW_BLOCK = Shapes.block().move(0.0, -1.0, 0.0).optimize(); public static final int STABILITY_MAX_DISTANCE = 7; public static final IntegerProperty DISTANCE = BlockStateProperties.STABILITY_DISTANCE; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; public static final BooleanProperty BOTTOM = BlockStateProperties.BOTTOM; public MapCodec codec() { return CODEC; } protected ScaffoldingBlock(BlockBehaviour.Properties properties) { super(properties); this.registerDefaultState((BlockState)((BlockState)((BlockState)((BlockState)this.stateDefinition.any()).setValue(DISTANCE, 7)).setValue(WATERLOGGED, false)).setValue(BOTTOM, false)); } @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(DISTANCE, WATERLOGGED, BOTTOM); } @Override protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { if (!context.isHoldingItem(state.getBlock().asItem())) { return state.getValue(BOTTOM) != false ? SHAPE_UNSTABLE : SHAPE_STABLE; } return Shapes.block(); } @Override protected VoxelShape getInteractionShape(BlockState state, BlockGetter level, BlockPos pos) { return Shapes.block(); } @Override protected boolean canBeReplaced(BlockState state, BlockPlaceContext context) { return context.getItemInHand().is(this.asItem()); } @Override public BlockState getStateForPlacement(BlockPlaceContext context) { BlockPos pos = context.getClickedPos(); Level level = context.getLevel(); int distance = ScaffoldingBlock.getDistance(level, pos); return (BlockState)((BlockState)((BlockState)this.defaultBlockState().setValue(WATERLOGGED, level.getFluidState(pos).getType() == Fluids.WATER)).setValue(DISTANCE, distance)).setValue(BOTTOM, this.isBottom(level, pos, distance)); } @Override protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { if (!level.isClientSide()) { level.scheduleTick(pos, this, 1); } } @Override protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticks, BlockPos pos, Direction directionToNeighbour, BlockPos neighbourPos, BlockState neighbourState, RandomSource random) { if (state.getValue(WATERLOGGED).booleanValue()) { ticks.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); } if (!level.isClientSide()) { ticks.scheduleTick(pos, this, 1); } return state; } @Override protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { int distance = ScaffoldingBlock.getDistance(level, pos); BlockState newState = (BlockState)((BlockState)state.setValue(DISTANCE, distance)).setValue(BOTTOM, this.isBottom(level, pos, distance)); if (newState.getValue(DISTANCE) == 7) { if (state.getValue(DISTANCE) == 7) { FallingBlockEntity.fall(level, pos, newState); } else { level.destroyBlock(pos, true); } } else if (state != newState) { level.setBlock(pos, newState, 3); } } @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { return ScaffoldingBlock.getDistance(level, pos) < 7; } @Override protected VoxelShape getCollisionShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { if (context.isPlacement()) { return Shapes.empty(); } if (!context.isAbove(Shapes.block(), pos, true) || context.isDescending()) { if (state.getValue(DISTANCE) != 0 && state.getValue(BOTTOM).booleanValue() && context.isAbove(SHAPE_BELOW_BLOCK, pos, true)) { return SHAPE_UNSTABLE_BOTTOM; } return Shapes.empty(); } return SHAPE_STABLE; } @Override protected FluidState getFluidState(BlockState state) { if (state.getValue(WATERLOGGED).booleanValue()) { return Fluids.WATER.getSource(false); } return super.getFluidState(state); } private boolean isBottom(BlockGetter level, BlockPos pos, int distance) { return distance > 0 && !level.getBlockState(pos.below()).is(this); } public static int getDistance(BlockGetter level, BlockPos pos) { Direction direction; BlockState relativeState; BlockPos.MutableBlockPos relativePos = pos.mutable().move(Direction.DOWN); BlockState belowState = level.getBlockState(relativePos); int distance = 7; if (belowState.is(Blocks.SCAFFOLDING)) { distance = belowState.getValue(DISTANCE); } else if (belowState.isFaceSturdy(level, relativePos, Direction.UP)) { return 0; } Iterator iterator = Direction.Plane.HORIZONTAL.iterator(); while (iterator.hasNext() && (!(relativeState = level.getBlockState(relativePos.setWithOffset((Vec3i)pos, direction = iterator.next()))).is(Blocks.SCAFFOLDING) || (distance = Math.min(distance, relativeState.getValue(DISTANCE) + 1)) != 1)) { } return distance; } }