package net.minecraft.world.level.levelgen.feature; import com.mojang.serialization.Codec; import java.util.Optional; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.levelgen.feature.configurations.PointedDripstoneConfiguration; public class PointedDripstoneFeature extends Feature { public PointedDripstoneFeature(Codec codec) { super(codec); } @Override public boolean place(FeaturePlaceContext context) { LevelAccessor levelAccessor = context.level(); BlockPos blockPos = context.origin(); RandomSource randomSource = context.random(); PointedDripstoneConfiguration pointedDripstoneConfiguration = context.config(); Optional optional = getTipDirection(levelAccessor, blockPos, randomSource); if (optional.isEmpty()) { return false; } else { BlockPos blockPos2 = blockPos.relative(((Direction)optional.get()).getOpposite()); createPatchOfDripstoneBlocks(levelAccessor, randomSource, blockPos2, pointedDripstoneConfiguration); int i = randomSource.nextFloat() < pointedDripstoneConfiguration.chanceOfTallerDripstone && DripstoneUtils.isEmptyOrWater(levelAccessor.getBlockState(blockPos.relative((Direction)optional.get()))) ? 2 : 1; DripstoneUtils.growPointedDripstone(levelAccessor, blockPos, (Direction)optional.get(), i, false); return true; } } private static Optional getTipDirection(LevelAccessor level, BlockPos pos, RandomSource random) { boolean bl = DripstoneUtils.isDripstoneBase(level.getBlockState(pos.above())); boolean bl2 = DripstoneUtils.isDripstoneBase(level.getBlockState(pos.below())); if (bl && bl2) { return Optional.of(random.nextBoolean() ? Direction.DOWN : Direction.UP); } else if (bl) { return Optional.of(Direction.DOWN); } else { return bl2 ? Optional.of(Direction.UP) : Optional.empty(); } } private static void createPatchOfDripstoneBlocks(LevelAccessor level, RandomSource random, BlockPos pos, PointedDripstoneConfiguration config) { DripstoneUtils.placeDripstoneBlockIfPossible(level, pos); for (Direction direction : Direction.Plane.HORIZONTAL) { if (!(random.nextFloat() > config.chanceOfDirectionalSpread)) { BlockPos blockPos = pos.relative(direction); DripstoneUtils.placeDripstoneBlockIfPossible(level, blockPos); if (!(random.nextFloat() > config.chanceOfSpreadRadius2)) { BlockPos blockPos2 = blockPos.relative(Direction.getRandom(random)); DripstoneUtils.placeDripstoneBlockIfPossible(level, blockPos2); if (!(random.nextFloat() > config.chanceOfSpreadRadius3)) { BlockPos blockPos3 = blockPos2.relative(Direction.getRandom(random)); DripstoneUtils.placeDripstoneBlockIfPossible(level, blockPos3); } } } } } }