177 lines
6.2 KiB
Java
177 lines
6.2 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.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.level.gameevent.GameEvent.Context;
|
|
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.BLOCKS, 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 (level.isDay() != this.type.open) {
|
|
return false;
|
|
} else {
|
|
EyeblossomBlock.Type type = this.type.transform();
|
|
level.setBlock(pos, type.state(), 3);
|
|
level.gameEvent(GameEvent.BLOCK_CHANGE, pos, 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) {
|
|
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.CONFUSION, 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;
|
|
}
|
|
}
|
|
}
|