137 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.level.block;
 | |
| 
 | |
| import com.mojang.serialization.MapCodec;
 | |
| import com.mojang.serialization.codecs.RecordCodecBuilder;
 | |
| import net.minecraft.Util;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.cauldron.CauldronInteraction;
 | |
| import net.minecraft.server.level.ServerLevel;
 | |
| import net.minecraft.world.entity.Entity;
 | |
| import net.minecraft.world.entity.InsideBlockEffectApplier;
 | |
| import net.minecraft.world.entity.InsideBlockEffectType;
 | |
| import net.minecraft.world.level.BlockGetter;
 | |
| import net.minecraft.world.level.Level;
 | |
| import net.minecraft.world.level.biome.Biome;
 | |
| 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.IntegerProperty;
 | |
| import net.minecraft.world.level.gameevent.GameEvent;
 | |
| import net.minecraft.world.level.material.Fluid;
 | |
| import net.minecraft.world.level.material.Fluids;
 | |
| import net.minecraft.world.phys.shapes.Shapes;
 | |
| import net.minecraft.world.phys.shapes.VoxelShape;
 | |
| 
 | |
| public class LayeredCauldronBlock extends AbstractCauldronBlock {
 | |
| 	public static final MapCodec<LayeredCauldronBlock> CODEC = RecordCodecBuilder.mapCodec(
 | |
| 		instance -> instance.group(
 | |
| 				Biome.Precipitation.CODEC.fieldOf("precipitation").forGetter(layeredCauldronBlock -> layeredCauldronBlock.precipitationType),
 | |
| 				CauldronInteraction.CODEC.fieldOf("interactions").forGetter(layeredCauldronBlock -> layeredCauldronBlock.interactions),
 | |
| 				propertiesCodec()
 | |
| 			)
 | |
| 			.apply(instance, LayeredCauldronBlock::new)
 | |
| 	);
 | |
| 	public static final int MIN_FILL_LEVEL = 1;
 | |
| 	public static final int MAX_FILL_LEVEL = 3;
 | |
| 	public static final IntegerProperty LEVEL = BlockStateProperties.LEVEL_CAULDRON;
 | |
| 	private static final int BASE_CONTENT_HEIGHT = 6;
 | |
| 	private static final double HEIGHT_PER_LEVEL = 3.0;
 | |
| 	private static final VoxelShape[] FILLED_SHAPES = Util.make(
 | |
| 		() -> Block.boxes(2, i -> Shapes.or(AbstractCauldronBlock.SHAPE, Block.column(12.0, 4.0, getPixelContentHeight(i + 1))))
 | |
| 	);
 | |
| 	private final Biome.Precipitation precipitationType;
 | |
| 
 | |
| 	@Override
 | |
| 	public MapCodec<LayeredCauldronBlock> codec() {
 | |
| 		return CODEC;
 | |
| 	}
 | |
| 
 | |
| 	public LayeredCauldronBlock(Biome.Precipitation precipitationType, CauldronInteraction.InteractionMap interactions, BlockBehaviour.Properties properties) {
 | |
| 		super(properties, interactions);
 | |
| 		this.precipitationType = precipitationType;
 | |
| 		this.registerDefaultState(this.stateDefinition.any().setValue(LEVEL, 1));
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean isFull(BlockState state) {
 | |
| 		return (Integer)state.getValue(LEVEL) == 3;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected boolean canReceiveStalactiteDrip(Fluid fluid) {
 | |
| 		return fluid == Fluids.WATER && this.precipitationType == Biome.Precipitation.RAIN;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected double getContentHeight(BlockState state) {
 | |
| 		return getPixelContentHeight((Integer)state.getValue(LEVEL)) / 16.0;
 | |
| 	}
 | |
| 
 | |
| 	private static double getPixelContentHeight(int level) {
 | |
| 		return 6.0 + level * 3.0;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected VoxelShape getEntityInsideCollisionShape(BlockState state, BlockGetter level, BlockPos pos, Entity entity) {
 | |
| 		return FILLED_SHAPES[state.getValue(LEVEL) - 1];
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
 | |
| 		if (level instanceof ServerLevel serverLevel) {
 | |
| 			BlockPos blockPos = pos.immutable();
 | |
| 			effectApplier.runBefore(InsideBlockEffectType.EXTINGUISH, entityx -> {
 | |
| 				if (entityx.isOnFire() && entityx.mayInteract(serverLevel, blockPos)) {
 | |
| 					this.handleEntityOnFireInside(state, level, blockPos);
 | |
| 				}
 | |
| 			});
 | |
| 		}
 | |
| 
 | |
| 		effectApplier.apply(InsideBlockEffectType.EXTINGUISH);
 | |
| 	}
 | |
| 
 | |
| 	private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) {
 | |
| 		if (this.precipitationType == Biome.Precipitation.SNOW) {
 | |
| 			lowerFillLevel(Blocks.WATER_CAULDRON.defaultBlockState().setValue(LEVEL, (Integer)state.getValue(LEVEL)), level, pos);
 | |
| 		} else {
 | |
| 			lowerFillLevel(state, level, pos);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static void lowerFillLevel(BlockState state, Level level, BlockPos pos) {
 | |
| 		int i = (Integer)state.getValue(LEVEL) - 1;
 | |
| 		BlockState blockState = i == 0 ? Blocks.CAULDRON.defaultBlockState() : state.setValue(LEVEL, i);
 | |
| 		level.setBlockAndUpdate(pos, blockState);
 | |
| 		level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) {
 | |
| 		if (CauldronBlock.shouldHandlePrecipitation(level, precipitation) && (Integer)state.getValue(LEVEL) != 3 && precipitation == this.precipitationType) {
 | |
| 			BlockState blockState = state.cycle(LEVEL);
 | |
| 			level.setBlockAndUpdate(pos, blockState);
 | |
| 			level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected int getAnalogOutputSignal(BlockState state, Level level, BlockPos pos) {
 | |
| 		return (Integer)state.getValue(LEVEL);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
 | |
| 		builder.add(LEVEL);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) {
 | |
| 		if (!this.isFull(state)) {
 | |
| 			BlockState blockState = state.setValue(LEVEL, (Integer)state.getValue(LEVEL) + 1);
 | |
| 			level.setBlockAndUpdate(pos, blockState);
 | |
| 			level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState));
 | |
| 			level.levelEvent(1047, pos, 0);
 | |
| 		}
 | |
| 	}
 | |
| }
 |