====== 让方块可含水 ======
要让方块可含水,实现 ''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 builder) {
builder.add(Properties.HORIZONTAL_FACING, WATERLOGGED);
}
我们还需要覆盖 ''getPlacementState'',这样放在水中的方块就会一开始就含水。
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return (BlockState)this.getDefaultState()
.with(Properties.HORIZONTAL_FACING, ctx.getPlayerFacing().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'',以正确地处理水流。
@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));
world.method_39281(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
}
return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos);
}
现在方块可含水了,并且与水有关的功能都能正常运作。