/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.mojang.datafixers.kinds.App * com.mojang.datafixers.kinds.Applicative * com.mojang.serialization.Codec * com.mojang.serialization.MapCodec * com.mojang.serialization.codecs.RecordCodecBuilder */ package net.minecraft.world.level.block; import com.mojang.datafixers.kinds.App; import com.mojang.datafixers.kinds.Applicative; 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.Vec3i; 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.attribute.EnvironmentAttributes; 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.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.FlowerBlock; 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 CODEC = RecordCodecBuilder.mapCodec(i -> i.group((App)Codec.BOOL.fieldOf("open").forGetter(e -> e.type.open), EyeblossomBlock.propertiesCodec()).apply((Applicative)i, EyeblossomBlock::new)); private static final int EYEBLOSSOM_XZ_RANGE = 3; private static final int EYEBLOSSOM_Y_RANGE = 2; private final Type type; public MapCodec codec() { return CODEC; } public EyeblossomBlock(Type type, BlockBehaviour.Properties properties) { super(type.effect, type.effectDuration, properties); this.type = type; } public EyeblossomBlock(boolean open, BlockBehaviour.Properties properties) { super(Type.fromBoolean((boolean)open).effect, Type.fromBoolean((boolean)open).effectDuration, properties); this.type = Type.fromBoolean(open); } @Override public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) { BlockState below; if (this.type.emitSounds() && random.nextInt(700) == 0 && (below = level.getBlockState(pos.below())).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) { boolean shouldBeOpen = level.environmentAttributes().getValue(EnvironmentAttributes.EYEBLOSSOM_OPEN, pos).toBoolean(this.type.open); if (shouldBeOpen == this.type.open) { return false; } Type newType = this.type.transform(); level.setBlock(pos, newType.state(), 3); level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state)); newType.spawnTransformParticle(level, pos, random); BlockPos.betweenClosed(pos.offset(-3, -2, -3), pos.offset(3, 2, 3)).forEach(nearby -> { BlockState nearbyState = level.getBlockState((BlockPos)nearby); if (nearbyState == state) { double distance = Math.sqrt(pos.distSqr((Vec3i)nearby)); int delay = random.nextIntBetweenInclusive((int)(distance * 5.0), (int)(distance * 10.0)); level.scheduleTick((BlockPos)nearby, state.getBlock(), delay); } }); return true; } @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier, boolean isPrecise) { if (!level.isClientSide() && level.getDifficulty() != Difficulty.PEACEFUL && entity instanceof Bee) { Bee bee = (Bee)entity; if (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, 0x5F5F5F); private final boolean open; private final Holder effect; private final float effectDuration; private final SoundEvent longSwitchSound; private final SoundEvent shortSwitchSound; private final int particleColor; private Type(boolean open, Holder effect, float duration, SoundEvent longSwitchSound, SoundEvent shortSwitchSound, int particleColor) { this.open = open; this.effect = effect; this.effectDuration = duration; 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 Type transform() { return Type.fromBoolean(!this.open); } public boolean emitSounds() { return this.open; } public static Type fromBoolean(boolean open) { return open ? OPEN : CLOSED; } public void spawnTransformParticle(ServerLevel level, BlockPos pos, RandomSource random) { Vec3 start = pos.getCenter(); double lifetime = 0.5 + random.nextDouble(); Vec3 velocity = new Vec3(random.nextDouble() - 0.5, random.nextDouble() + 1.0, random.nextDouble() - 0.5); Vec3 target = start.add(velocity.scale(lifetime)); TrailParticleOption particle = new TrailParticleOption(target, this.particleColor, (int)(20.0 * lifetime)); level.sendParticles(particle, start.x, start.y, start.z, 1, 0.0, 0.0, 0.0, 0.0); } public SoundEvent longSwitchSound() { return this.longSwitchSound; } } }