要让方块可含水,实现 Waterloggable
接口并覆盖一些方法。
public class VerticalSlabBlock extends HorizontalFacingBlock implements Waterloggable { [...] }
在本例中,我们将 Properties.WATERLOGGED
存储为类中的静态字段,然后你可以直接使用 WATERLOGGED
来访问这个字段。(虽然不必要,但是大多数 Minecraft 原版的方块类都是这么做的,所以我们也这么做。当然你也可以不这么做,然后每次使用 Properties.WATERLOGGED
来访问,或者直接导入静态字段。)我们需要手动让方块认识这个属性,因为 Waterloggable
接口并没有自动为你完成这些。
// 注意 ''Properties'' 是 net.minecraft.state.property.Properties,别导入错了。 public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; // 将 WATERLOGGED 属性的默认值设为 ``false`` public VerticalSlabBlock(Settings settings) { super(settings); setDefaultState(getDefaultState() .with(Properties.HORIZONTAL_FACING, Direction.NORTH) .with(WATERLOGGED, false)); } // 让方块认识这个属性,否则设置该属性将会抛出异常。 @Override protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { builder.add(Properties.HORIZONTAL_FACING, WATERLOGGED); }
我们还需要覆盖 getPlacementState
,这样放在水中的方块就会一开始就含水。
@Override public BlockState getPlacementState(ItemPlacementContext ctx) { return this.getDefaultState() .with(Properties.HORIZONTAL_FACING, ctx.getHorizontalPlayerFacing().getOpposite()) .with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER); }
覆盖 getFluidState
,这样方块含水后就会显示水。
@Override public FluidState getFluidState(BlockState state) { return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state); }
覆盖 getStateForNeighborUpdate
,以正确地处理水流。
1.21.2 之前的版本,请这么写:
@Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { if (state.get(WATERLOGGED)) { // 对于 1.17 以及更低的版本: // world.getFluidTickScheduler().schedule(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); // 对于 1.18 之后、1.21.2 之前的版本: world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); } return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos); }
1.21.2 以及更高的版本,请这么写:
@Override public BlockState getStateForNeighborUpdate(BlockState state, WorldView world, ScheduledTickView tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, Random random) { if (state.get(WATERLOGGED)) { // For versions since 1.21.2: tickView.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); } return super.getStateForNeighborUpdate(state, world, tickView, pos, direction, neighborPos, neighborState, random); }
现在方块可含水了,并且与水有关的功能都能正常运作。