146 lines
5.8 KiB
Java
146 lines
5.8 KiB
Java
package net.minecraft.world.level.block;
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.mojang.serialization.MapCodec;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.EntitySpawnReason;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.InsideBlockEffectApplier;
|
|
import net.minecraft.world.entity.animal.frog.Tadpole;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.LevelReader;
|
|
import net.minecraft.world.level.ScheduledTickAccess;
|
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.material.FluidState;
|
|
import net.minecraft.world.level.material.Fluids;
|
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
|
|
public class FrogspawnBlock extends Block {
|
|
public static final MapCodec<FrogspawnBlock> CODEC = simpleCodec(FrogspawnBlock::new);
|
|
private static final int MIN_TADPOLES_SPAWN = 2;
|
|
private static final int MAX_TADPOLES_SPAWN = 5;
|
|
private static final int DEFAULT_MIN_HATCH_TICK_DELAY = 3600;
|
|
private static final int DEFAULT_MAX_HATCH_TICK_DELAY = 12000;
|
|
private static final VoxelShape SHAPE = Block.column(16.0, 0.0, 1.5);
|
|
private static int minHatchTickDelay = 3600;
|
|
private static int maxHatchTickDelay = 12000;
|
|
|
|
@Override
|
|
public MapCodec<FrogspawnBlock> codec() {
|
|
return CODEC;
|
|
}
|
|
|
|
public FrogspawnBlock(BlockBehaviour.Properties p_221177_) {
|
|
super(p_221177_);
|
|
}
|
|
|
|
@Override
|
|
protected VoxelShape getShape(BlockState p_221199_, BlockGetter p_221200_, BlockPos p_221201_, CollisionContext p_221202_) {
|
|
return SHAPE;
|
|
}
|
|
|
|
@Override
|
|
protected boolean canSurvive(BlockState p_221209_, LevelReader p_221210_, BlockPos p_221211_) {
|
|
return mayPlaceOn(p_221210_, p_221211_.below());
|
|
}
|
|
|
|
@Override
|
|
protected void onPlace(BlockState p_221227_, Level p_221228_, BlockPos p_221229_, BlockState p_221230_, boolean p_221231_) {
|
|
p_221228_.scheduleTick(p_221229_, this, getFrogspawnHatchDelay(p_221228_.getRandom()));
|
|
}
|
|
|
|
private static int getFrogspawnHatchDelay(RandomSource p_221186_) {
|
|
return p_221186_.nextInt(minHatchTickDelay, maxHatchTickDelay);
|
|
}
|
|
|
|
@Override
|
|
protected BlockState updateShape(
|
|
BlockState p_221213_,
|
|
LevelReader p_365824_,
|
|
ScheduledTickAccess p_361762_,
|
|
BlockPos p_221217_,
|
|
Direction p_221214_,
|
|
BlockPos p_221218_,
|
|
BlockState p_221215_,
|
|
RandomSource p_364719_
|
|
) {
|
|
return !this.canSurvive(p_221213_, p_365824_, p_221217_)
|
|
? Blocks.AIR.defaultBlockState()
|
|
: super.updateShape(p_221213_, p_365824_, p_361762_, p_221217_, p_221214_, p_221218_, p_221215_, p_364719_);
|
|
}
|
|
|
|
@Override
|
|
protected void tick(BlockState p_221194_, ServerLevel p_221195_, BlockPos p_221196_, RandomSource p_221197_) {
|
|
if (!this.canSurvive(p_221194_, p_221195_, p_221196_)) {
|
|
this.destroyBlock(p_221195_, p_221196_);
|
|
} else {
|
|
this.hatchFrogspawn(p_221195_, p_221196_, p_221197_);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void entityInside(BlockState p_221204_, Level p_221205_, BlockPos p_221206_, Entity p_221207_, InsideBlockEffectApplier p_392110_) {
|
|
if (p_221207_.getType().equals(EntityType.FALLING_BLOCK)) {
|
|
this.destroyBlock(p_221205_, p_221206_);
|
|
}
|
|
}
|
|
|
|
private static boolean mayPlaceOn(BlockGetter p_221188_, BlockPos p_221189_) {
|
|
FluidState fluidstate = p_221188_.getFluidState(p_221189_);
|
|
FluidState fluidstate1 = p_221188_.getFluidState(p_221189_.above());
|
|
return fluidstate.getType() == Fluids.WATER && fluidstate1.getType() == Fluids.EMPTY;
|
|
}
|
|
|
|
private void hatchFrogspawn(ServerLevel p_221182_, BlockPos p_221183_, RandomSource p_221184_) {
|
|
this.destroyBlock(p_221182_, p_221183_);
|
|
p_221182_.playSound(null, p_221183_, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F);
|
|
this.spawnTadpoles(p_221182_, p_221183_, p_221184_);
|
|
}
|
|
|
|
private void destroyBlock(Level p_221191_, BlockPos p_221192_) {
|
|
p_221191_.destroyBlock(p_221192_, false);
|
|
}
|
|
|
|
private void spawnTadpoles(ServerLevel p_221221_, BlockPos p_221222_, RandomSource p_221223_) {
|
|
int i = p_221223_.nextInt(2, 6);
|
|
|
|
for (int j = 1; j <= i; j++) {
|
|
Tadpole tadpole = EntityType.TADPOLE.create(p_221221_, EntitySpawnReason.BREEDING);
|
|
if (tadpole != null) {
|
|
double d0 = p_221222_.getX() + this.getRandomTadpolePositionOffset(p_221223_);
|
|
double d1 = p_221222_.getZ() + this.getRandomTadpolePositionOffset(p_221223_);
|
|
int k = p_221223_.nextInt(1, 361);
|
|
tadpole.snapTo(d0, p_221222_.getY() - 0.5, d1, k, 0.0F);
|
|
tadpole.setPersistenceRequired();
|
|
p_221221_.addFreshEntity(tadpole);
|
|
}
|
|
}
|
|
}
|
|
|
|
private double getRandomTadpolePositionOffset(RandomSource p_221225_) {
|
|
double d0 = 0.2F;
|
|
return Mth.clamp(p_221225_.nextDouble(), 0.2F, 0.7999999970197678);
|
|
}
|
|
|
|
@VisibleForTesting
|
|
public static void setHatchDelay(int p_221179_, int p_221180_) {
|
|
minHatchTickDelay = p_221179_;
|
|
maxHatchTickDelay = p_221180_;
|
|
}
|
|
|
|
@VisibleForTesting
|
|
public static void setDefaultHatchDelay() {
|
|
minHatchTickDelay = 3600;
|
|
maxHatchTickDelay = 12000;
|
|
}
|
|
} |