107 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.level.block;
 | |
| 
 | |
| import com.mojang.serialization.MapCodec;
 | |
| import java.util.function.BiConsumer;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.particles.ParticleTypes;
 | |
| import net.minecraft.server.level.ServerLevel;
 | |
| import net.minecraft.sounds.SoundEvents;
 | |
| import net.minecraft.sounds.SoundSource;
 | |
| import net.minecraft.tags.BlockTags;
 | |
| import net.minecraft.util.RandomSource;
 | |
| import net.minecraft.world.entity.player.Player;
 | |
| import net.minecraft.world.entity.projectile.Projectile;
 | |
| import net.minecraft.world.item.ItemStack;
 | |
| import net.minecraft.world.level.Explosion;
 | |
| import net.minecraft.world.level.Level;
 | |
| import net.minecraft.world.level.LevelAccessor;
 | |
| import net.minecraft.world.level.block.state.BlockBehaviour;
 | |
| import net.minecraft.world.level.block.state.BlockState;
 | |
| import net.minecraft.world.level.block.state.properties.BlockStateProperties;
 | |
| import net.minecraft.world.level.block.state.properties.BooleanProperty;
 | |
| import net.minecraft.world.level.gameevent.GameEvent;
 | |
| import net.minecraft.world.phys.BlockHitResult;
 | |
| import net.minecraft.world.phys.Vec3;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| public abstract class AbstractCandleBlock extends Block {
 | |
| 	public static final int LIGHT_PER_CANDLE = 3;
 | |
| 	public static final BooleanProperty LIT = BlockStateProperties.LIT;
 | |
| 
 | |
| 	@Override
 | |
| 	protected abstract MapCodec<? extends AbstractCandleBlock> codec();
 | |
| 
 | |
| 	protected AbstractCandleBlock(BlockBehaviour.Properties properties) {
 | |
| 		super(properties);
 | |
| 	}
 | |
| 
 | |
| 	protected abstract Iterable<Vec3> getParticleOffsets(BlockState state);
 | |
| 
 | |
| 	public static boolean isLit(BlockState state) {
 | |
| 		return state.hasProperty(LIT) && (state.is(BlockTags.CANDLES) || state.is(BlockTags.CANDLE_CAKES)) && (Boolean)state.getValue(LIT);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) {
 | |
| 		if (!level.isClientSide && projectile.isOnFire() && this.canBeLit(state)) {
 | |
| 			setLit(level, state, hit.getBlockPos(), true);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	protected boolean canBeLit(BlockState state) {
 | |
| 		return !(Boolean)state.getValue(LIT);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
 | |
| 		if ((Boolean)state.getValue(LIT)) {
 | |
| 			this.getParticleOffsets(state).forEach(vec3 -> addParticlesAndSound(level, vec3.add(pos.getX(), pos.getY(), pos.getZ()), random));
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static void addParticlesAndSound(Level level, Vec3 offset, RandomSource random) {
 | |
| 		float f = random.nextFloat();
 | |
| 		if (f < 0.3F) {
 | |
| 			level.addParticle(ParticleTypes.SMOKE, offset.x, offset.y, offset.z, 0.0, 0.0, 0.0);
 | |
| 			if (f < 0.17F) {
 | |
| 				level.playLocalSound(
 | |
| 					offset.x + 0.5,
 | |
| 					offset.y + 0.5,
 | |
| 					offset.z + 0.5,
 | |
| 					SoundEvents.CANDLE_AMBIENT,
 | |
| 					SoundSource.BLOCKS,
 | |
| 					1.0F + random.nextFloat(),
 | |
| 					random.nextFloat() * 0.7F + 0.3F,
 | |
| 					false
 | |
| 				);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		level.addParticle(ParticleTypes.SMALL_FLAME, offset.x, offset.y, offset.z, 0.0, 0.0, 0.0);
 | |
| 	}
 | |
| 
 | |
| 	public static void extinguish(@Nullable Player player, BlockState state, LevelAccessor level, BlockPos pos) {
 | |
| 		setLit(level, state, pos, false);
 | |
| 		if (state.getBlock() instanceof AbstractCandleBlock) {
 | |
| 			((AbstractCandleBlock)state.getBlock())
 | |
| 				.getParticleOffsets(state)
 | |
| 				.forEach(vec3 -> level.addParticle(ParticleTypes.SMOKE, pos.getX() + vec3.x(), pos.getY() + vec3.y(), pos.getZ() + vec3.z(), 0.0, 0.1F, 0.0));
 | |
| 		}
 | |
| 
 | |
| 		level.playSound(null, pos, SoundEvents.CANDLE_EXTINGUISH, SoundSource.BLOCKS, 1.0F, 1.0F);
 | |
| 		level.gameEvent(player, GameEvent.BLOCK_CHANGE, pos);
 | |
| 	}
 | |
| 
 | |
| 	private static void setLit(LevelAccessor level, BlockState state, BlockPos pos, boolean lit) {
 | |
| 		level.setBlock(pos, state.setValue(LIT, lit), 11);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void onExplosionHit(BlockState state, ServerLevel level, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> dropConsumer) {
 | |
| 		if (explosion.canTriggerBlocks() && (Boolean)state.getValue(LIT)) {
 | |
| 			extinguish(null, state, level, pos);
 | |
| 		}
 | |
| 
 | |
| 		super.onExplosionHit(state, level, pos, explosion, dropConsumer);
 | |
| 	}
 | |
| }
 |