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 { private static final float HUGE_PROBABILITY = 0.06F; public HugeFungusFeature(Codec p_65922_) { super(p_65922_); } @Override public boolean place(FeaturePlaceContext 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); } } }