Создание блока заполняемым водой
Чтобы сделать блоки заполняемыми водой, реализуйте интерфейс Waterloggable
и переопределите некоторые методы.
public class VerticalSlabBlock extends HorizontalFacingBlock implements Waterloggable { [...] }
В этом случае мы сохраняем Properties.WATERLOGGED
как статическое поле в этом классе, и вы можете использовать WATERLOGGED
для доступа к полю. (Как бы ненужно это ни выглядело, большинство классов блоков ванильного Майнкрафта делают это, поэтому мы делаем то же самое. Конечно, вы можете отказаться от этого и использовать 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(this.stateManager.getDefaultState() .with(Properties.HORIZONTAL_FACING, Direction.NORTH) .with(WATERLOGGED, false); } // Заставьте блок распознавать свойство, в противном случае установка свойства приведет к ошибкам. @Override protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) { stateManager.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.createAndScheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); } return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos); }
Теперь блок становится заполняемым и корректно работает с водой.