192 lines
8.3 KiB
Java
192 lines
8.3 KiB
Java
|
package net.minecraft.world.level.levelgen.feature;
|
||
|
|
||
|
import com.mojang.serialization.Codec;
|
||
|
import net.minecraft.core.BlockPos;
|
||
|
import net.minecraft.core.Direction;
|
||
|
import net.minecraft.util.Mth;
|
||
|
import net.minecraft.util.RandomSource;
|
||
|
import net.minecraft.world.level.LevelAccessor;
|
||
|
import net.minecraft.world.level.WorldGenLevel;
|
||
|
import net.minecraft.world.level.block.Block;
|
||
|
import net.minecraft.world.level.block.Blocks;
|
||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||
|
import net.minecraft.world.level.block.state.BlockState;
|
||
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||
|
|
||
|
public class HugeFungusFeature extends Feature<HugeFungusConfiguration> {
|
||
|
private static final float HUGE_PROBABILITY = 0.06F;
|
||
|
|
||
|
public HugeFungusFeature(Codec<HugeFungusConfiguration> p_65922_) {
|
||
|
super(p_65922_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean place(FeaturePlaceContext<HugeFungusConfiguration> p_159878_) {
|
||
|
WorldGenLevel worldgenlevel = p_159878_.level();
|
||
|
BlockPos blockpos = p_159878_.origin();
|
||
|
RandomSource randomsource = p_159878_.random();
|
||
|
ChunkGenerator chunkgenerator = p_159878_.chunkGenerator();
|
||
|
HugeFungusConfiguration hugefungusconfiguration = p_159878_.config();
|
||
|
Block block = hugefungusconfiguration.validBaseState.getBlock();
|
||
|
BlockPos blockpos1 = null;
|
||
|
BlockState blockstate = worldgenlevel.getBlockState(blockpos.below());
|
||
|
if (blockstate.is(block)) {
|
||
|
blockpos1 = blockpos;
|
||
|
}
|
||
|
|
||
|
if (blockpos1 == null) {
|
||
|
return false;
|
||
|
} else {
|
||
|
int i = Mth.nextInt(randomsource, 4, 13);
|
||
|
if (randomsource.nextInt(12) == 0) {
|
||
|
i *= 2;
|
||
|
}
|
||
|
|
||
|
if (!hugefungusconfiguration.planted) {
|
||
|
int j = chunkgenerator.getGenDepth();
|
||
|
if (blockpos1.getY() + i + 1 >= j) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
boolean flag = !hugefungusconfiguration.planted && randomsource.nextFloat() < 0.06F;
|
||
|
worldgenlevel.setBlock(blockpos, Blocks.AIR.defaultBlockState(), 260);
|
||
|
this.placeStem(worldgenlevel, randomsource, hugefungusconfiguration, blockpos1, i, flag);
|
||
|
this.placeHat(worldgenlevel, randomsource, hugefungusconfiguration, blockpos1, i, flag);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static boolean isReplaceable(WorldGenLevel p_285049_, BlockPos p_285309_, HugeFungusConfiguration p_284992_, boolean p_285162_) {
|
||
|
if (p_285049_.isStateAtPosition(p_285309_, BlockBehaviour.BlockStateBase::canBeReplaced)) {
|
||
|
return true;
|
||
|
} else {
|
||
|
return p_285162_ ? p_284992_.replaceableBlocks.test(p_285049_, p_285309_) : false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void placeStem(
|
||
|
WorldGenLevel p_285364_, RandomSource p_285032_, HugeFungusConfiguration p_285198_, BlockPos p_285090_, int p_285249_, boolean p_285355_
|
||
|
) {
|
||
|
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
||
|
BlockState blockstate = p_285198_.stemState;
|
||
|
int i = p_285355_ ? 1 : 0;
|
||
|
|
||
|
for (int j = -i; j <= i; j++) {
|
||
|
for (int k = -i; k <= i; k++) {
|
||
|
boolean flag = p_285355_ && Mth.abs(j) == i && Mth.abs(k) == i;
|
||
|
|
||
|
for (int l = 0; l < p_285249_; l++) {
|
||
|
blockpos$mutableblockpos.setWithOffset(p_285090_, j, l, k);
|
||
|
if (isReplaceable(p_285364_, blockpos$mutableblockpos, p_285198_, true)) {
|
||
|
if (p_285198_.planted) {
|
||
|
if (!p_285364_.getBlockState(blockpos$mutableblockpos.below()).isAir()) {
|
||
|
p_285364_.destroyBlock(blockpos$mutableblockpos, true);
|
||
|
}
|
||
|
|
||
|
p_285364_.setBlock(blockpos$mutableblockpos, blockstate, 3);
|
||
|
} else if (flag) {
|
||
|
if (p_285032_.nextFloat() < 0.1F) {
|
||
|
this.setBlock(p_285364_, blockpos$mutableblockpos, blockstate);
|
||
|
}
|
||
|
} else {
|
||
|
this.setBlock(p_285364_, blockpos$mutableblockpos, blockstate);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void placeHat(
|
||
|
WorldGenLevel p_285200_, RandomSource p_285456_, HugeFungusConfiguration p_285146_, BlockPos p_285097_, int p_285156_, boolean p_285265_
|
||
|
) {
|
||
|
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
||
|
boolean flag = p_285146_.hatState.is(Blocks.NETHER_WART_BLOCK);
|
||
|
int i = Math.min(p_285456_.nextInt(1 + p_285156_ / 3) + 5, p_285156_);
|
||
|
int j = p_285156_ - i;
|
||
|
|
||
|
for (int k = j; k <= p_285156_; k++) {
|
||
|
int l = k < p_285156_ - p_285456_.nextInt(3) ? 2 : 1;
|
||
|
if (i > 8 && k < j + 4) {
|
||
|
l = 3;
|
||
|
}
|
||
|
|
||
|
if (p_285265_) {
|
||
|
l++;
|
||
|
}
|
||
|
|
||
|
for (int i1 = -l; i1 <= l; i1++) {
|
||
|
for (int j1 = -l; j1 <= l; j1++) {
|
||
|
boolean flag1 = i1 == -l || i1 == l;
|
||
|
boolean flag2 = j1 == -l || j1 == l;
|
||
|
boolean flag3 = !flag1 && !flag2 && k != p_285156_;
|
||
|
boolean flag4 = flag1 && flag2;
|
||
|
boolean flag5 = k < j + 3;
|
||
|
blockpos$mutableblockpos.setWithOffset(p_285097_, i1, k, j1);
|
||
|
if (isReplaceable(p_285200_, blockpos$mutableblockpos, p_285146_, false)) {
|
||
|
if (p_285146_.planted && !p_285200_.getBlockState(blockpos$mutableblockpos.below()).isAir()) {
|
||
|
p_285200_.destroyBlock(blockpos$mutableblockpos, true);
|
||
|
}
|
||
|
|
||
|
if (flag5) {
|
||
|
if (!flag3) {
|
||
|
this.placeHatDropBlock(p_285200_, p_285456_, blockpos$mutableblockpos, p_285146_.hatState, flag);
|
||
|
}
|
||
|
} else if (flag3) {
|
||
|
this.placeHatBlock(p_285200_, p_285456_, p_285146_, blockpos$mutableblockpos, 0.1F, 0.2F, flag ? 0.1F : 0.0F);
|
||
|
} else if (flag4) {
|
||
|
this.placeHatBlock(p_285200_, p_285456_, p_285146_, blockpos$mutableblockpos, 0.01F, 0.7F, flag ? 0.083F : 0.0F);
|
||
|
} else {
|
||
|
this.placeHatBlock(p_285200_, p_285456_, p_285146_, blockpos$mutableblockpos, 5.0E-4F, 0.98F, flag ? 0.07F : 0.0F);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void placeHatBlock(
|
||
|
LevelAccessor p_225050_,
|
||
|
RandomSource p_225051_,
|
||
|
HugeFungusConfiguration p_225052_,
|
||
|
BlockPos.MutableBlockPos p_225053_,
|
||
|
float p_225054_,
|
||
|
float p_225055_,
|
||
|
float p_225056_
|
||
|
) {
|
||
|
if (p_225051_.nextFloat() < p_225054_) {
|
||
|
this.setBlock(p_225050_, p_225053_, p_225052_.decorState);
|
||
|
} else if (p_225051_.nextFloat() < p_225055_) {
|
||
|
this.setBlock(p_225050_, p_225053_, p_225052_.hatState);
|
||
|
if (p_225051_.nextFloat() < p_225056_) {
|
||
|
tryPlaceWeepingVines(p_225053_, p_225050_, p_225051_);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void placeHatDropBlock(LevelAccessor p_225065_, RandomSource p_225066_, BlockPos p_225067_, BlockState p_225068_, boolean p_225069_) {
|
||
|
if (p_225065_.getBlockState(p_225067_.below()).is(p_225068_.getBlock())) {
|
||
|
this.setBlock(p_225065_, p_225067_, p_225068_);
|
||
|
} else if (p_225066_.nextFloat() < 0.15) {
|
||
|
this.setBlock(p_225065_, p_225067_, p_225068_);
|
||
|
if (p_225069_ && p_225066_.nextInt(11) == 0) {
|
||
|
tryPlaceWeepingVines(p_225067_, p_225065_, p_225066_);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void tryPlaceWeepingVines(BlockPos p_225071_, LevelAccessor p_225072_, RandomSource p_225073_) {
|
||
|
BlockPos.MutableBlockPos blockpos$mutableblockpos = p_225071_.mutable().move(Direction.DOWN);
|
||
|
if (p_225072_.isEmptyBlock(blockpos$mutableblockpos)) {
|
||
|
int i = Mth.nextInt(p_225073_, 1, 5);
|
||
|
if (p_225073_.nextInt(7) == 0) {
|
||
|
i *= 2;
|
||
|
}
|
||
|
|
||
|
int j = 23;
|
||
|
int k = 25;
|
||
|
WeepingVinesFeature.placeWeepingVinesColumn(p_225072_, p_225073_, blockpos$mutableblockpos, i, 23, 25);
|
||
|
}
|
||
|
}
|
||
|
}
|