177 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.level.block;
 | |
| 
 | |
| import com.mojang.serialization.Codec;
 | |
| import com.mojang.serialization.MapCodec;
 | |
| import com.mojang.serialization.codecs.RecordCodecBuilder;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.Holder;
 | |
| import net.minecraft.core.particles.TrailParticleOption;
 | |
| import net.minecraft.server.level.ServerLevel;
 | |
| import net.minecraft.sounds.SoundEvent;
 | |
| import net.minecraft.sounds.SoundEvents;
 | |
| import net.minecraft.sounds.SoundSource;
 | |
| import net.minecraft.util.RandomSource;
 | |
| import net.minecraft.world.Difficulty;
 | |
| import net.minecraft.world.effect.MobEffect;
 | |
| import net.minecraft.world.effect.MobEffectInstance;
 | |
| import net.minecraft.world.effect.MobEffects;
 | |
| import net.minecraft.world.entity.Entity;
 | |
| import net.minecraft.world.entity.InsideBlockEffectApplier;
 | |
| import net.minecraft.world.entity.animal.Bee;
 | |
| import net.minecraft.world.level.Level;
 | |
| import net.minecraft.world.level.block.state.BlockBehaviour;
 | |
| import net.minecraft.world.level.block.state.BlockState;
 | |
| import net.minecraft.world.level.gameevent.GameEvent;
 | |
| import net.minecraft.world.phys.Vec3;
 | |
| 
 | |
| public class EyeblossomBlock extends FlowerBlock {
 | |
| 	public static final MapCodec<EyeblossomBlock> CODEC = RecordCodecBuilder.mapCodec(
 | |
| 		instance -> instance.group(Codec.BOOL.fieldOf("open").forGetter(eyeblossomBlock -> eyeblossomBlock.type.open), propertiesCodec())
 | |
| 			.apply(instance, EyeblossomBlock::new)
 | |
| 	);
 | |
| 	private static final int EYEBLOSSOM_XZ_RANGE = 3;
 | |
| 	private static final int EYEBLOSSOM_Y_RANGE = 2;
 | |
| 	private final EyeblossomBlock.Type type;
 | |
| 
 | |
| 	@Override
 | |
| 	public MapCodec<? extends EyeblossomBlock> codec() {
 | |
| 		return CODEC;
 | |
| 	}
 | |
| 
 | |
| 	public EyeblossomBlock(EyeblossomBlock.Type type, BlockBehaviour.Properties properties) {
 | |
| 		super(type.effect, type.effectDuration, properties);
 | |
| 		this.type = type;
 | |
| 	}
 | |
| 
 | |
| 	public EyeblossomBlock(boolean open, BlockBehaviour.Properties properties) {
 | |
| 		super(EyeblossomBlock.Type.fromBoolean(open).effect, EyeblossomBlock.Type.fromBoolean(open).effectDuration, properties);
 | |
| 		this.type = EyeblossomBlock.Type.fromBoolean(open);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
 | |
| 		if (this.type.emitSounds() && random.nextInt(700) == 0) {
 | |
| 			BlockState blockState = level.getBlockState(pos.below());
 | |
| 			if (blockState.is(Blocks.PALE_MOSS_BLOCK)) {
 | |
| 				level.playLocalSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.EYEBLOSSOM_IDLE, SoundSource.AMBIENT, 1.0F, 1.0F, false);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
 | |
| 		if (this.tryChangingState(state, level, pos, random)) {
 | |
| 			level.playSound(null, pos, this.type.transform().longSwitchSound, SoundSource.BLOCKS, 1.0F, 1.0F);
 | |
| 		}
 | |
| 
 | |
| 		super.randomTick(state, level, pos, random);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
 | |
| 		if (this.tryChangingState(state, level, pos, random)) {
 | |
| 			level.playSound(null, pos, this.type.transform().shortSwitchSound, SoundSource.BLOCKS, 1.0F, 1.0F);
 | |
| 		}
 | |
| 
 | |
| 		super.tick(state, level, pos, random);
 | |
| 	}
 | |
| 
 | |
| 	private boolean tryChangingState(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
 | |
| 		if (!level.dimensionType().natural()) {
 | |
| 			return false;
 | |
| 		} else if (CreakingHeartBlock.isNaturalNight(level) == this.type.open) {
 | |
| 			return false;
 | |
| 		} else {
 | |
| 			EyeblossomBlock.Type type = this.type.transform();
 | |
| 			level.setBlock(pos, type.state(), 3);
 | |
| 			level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state));
 | |
| 			type.spawnTransformParticle(level, pos, random);
 | |
| 			BlockPos.betweenClosed(pos.offset(-3, -2, -3), pos.offset(3, 2, 3)).forEach(blockPos2 -> {
 | |
| 				BlockState blockState2 = level.getBlockState(blockPos2);
 | |
| 				if (blockState2 == state) {
 | |
| 					double d = Math.sqrt(pos.distSqr(blockPos2));
 | |
| 					int i = random.nextIntBetweenInclusive((int)(d * 5.0), (int)(d * 10.0));
 | |
| 					level.scheduleTick(blockPos2, state.getBlock(), i);
 | |
| 				}
 | |
| 			});
 | |
| 			return true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
 | |
| 		if (!level.isClientSide()
 | |
| 			&& level.getDifficulty() != Difficulty.PEACEFUL
 | |
| 			&& entity instanceof Bee bee
 | |
| 			&& Bee.attractsBees(state)
 | |
| 			&& !bee.hasEffect(MobEffects.POISON)) {
 | |
| 			bee.addEffect(this.getBeeInteractionEffect());
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public MobEffectInstance getBeeInteractionEffect() {
 | |
| 		return new MobEffectInstance(MobEffects.POISON, 25);
 | |
| 	}
 | |
| 
 | |
| 	public static enum Type {
 | |
| 		OPEN(true, MobEffects.BLINDNESS, 11.0F, SoundEvents.EYEBLOSSOM_OPEN_LONG, SoundEvents.EYEBLOSSOM_OPEN, 16545810),
 | |
| 		CLOSED(false, MobEffects.NAUSEA, 7.0F, SoundEvents.EYEBLOSSOM_CLOSE_LONG, SoundEvents.EYEBLOSSOM_CLOSE, 6250335);
 | |
| 
 | |
| 		final boolean open;
 | |
| 		final Holder<MobEffect> effect;
 | |
| 		final float effectDuration;
 | |
| 		final SoundEvent longSwitchSound;
 | |
| 		final SoundEvent shortSwitchSound;
 | |
| 		private final int particleColor;
 | |
| 
 | |
| 		private Type(
 | |
| 			final boolean open,
 | |
| 			final Holder<MobEffect> effect,
 | |
| 			final float effectDuration,
 | |
| 			final SoundEvent longSwitchSound,
 | |
| 			final SoundEvent shortSwitchSound,
 | |
| 			final int particleColor
 | |
| 		) {
 | |
| 			this.open = open;
 | |
| 			this.effect = effect;
 | |
| 			this.effectDuration = effectDuration;
 | |
| 			this.longSwitchSound = longSwitchSound;
 | |
| 			this.shortSwitchSound = shortSwitchSound;
 | |
| 			this.particleColor = particleColor;
 | |
| 		}
 | |
| 
 | |
| 		public Block block() {
 | |
| 			return this.open ? Blocks.OPEN_EYEBLOSSOM : Blocks.CLOSED_EYEBLOSSOM;
 | |
| 		}
 | |
| 
 | |
| 		public BlockState state() {
 | |
| 			return this.block().defaultBlockState();
 | |
| 		}
 | |
| 
 | |
| 		public EyeblossomBlock.Type transform() {
 | |
| 			return fromBoolean(!this.open);
 | |
| 		}
 | |
| 
 | |
| 		public boolean emitSounds() {
 | |
| 			return this.open;
 | |
| 		}
 | |
| 
 | |
| 		public static EyeblossomBlock.Type fromBoolean(boolean open) {
 | |
| 			return open ? OPEN : CLOSED;
 | |
| 		}
 | |
| 
 | |
| 		public void spawnTransformParticle(ServerLevel level, BlockPos pos, RandomSource random) {
 | |
| 			Vec3 vec3 = pos.getCenter();
 | |
| 			double d = 0.5 + random.nextDouble();
 | |
| 			Vec3 vec32 = new Vec3(random.nextDouble() - 0.5, random.nextDouble() + 1.0, random.nextDouble() - 0.5);
 | |
| 			Vec3 vec33 = vec3.add(vec32.scale(d));
 | |
| 			TrailParticleOption trailParticleOption = new TrailParticleOption(vec33, this.particleColor, (int)(20.0 * d));
 | |
| 			level.sendParticles(trailParticleOption, vec3.x, vec3.y, vec3.z, 1, 0.0, 0.0, 0.0, 0.0);
 | |
| 		}
 | |
| 
 | |
| 		public SoundEvent longSwitchSound() {
 | |
| 			return this.longSwitchSound;
 | |
| 		}
 | |
| 	}
 | |
| }
 |