package net.minecraft.world.level.levelgen.feature; import com.mojang.serialization.Codec; import java.util.Optional; import java.util.OptionalInt; import java.util.function.Predicate; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.Column; import net.minecraft.world.level.levelgen.feature.configurations.UnderwaterMagmaConfiguration; import net.minecraft.world.level.levelgen.structure.BoundingBox; public class UnderwaterMagmaFeature extends Feature { public UnderwaterMagmaFeature(Codec codec) { super(codec); } @Override public boolean place(FeaturePlaceContext context) { WorldGenLevel worldGenLevel = context.level(); BlockPos blockPos = context.origin(); UnderwaterMagmaConfiguration underwaterMagmaConfiguration = context.config(); RandomSource randomSource = context.random(); OptionalInt optionalInt = getFloorY(worldGenLevel, blockPos, underwaterMagmaConfiguration); if (optionalInt.isEmpty()) { return false; } else { BlockPos blockPos2 = blockPos.atY(optionalInt.getAsInt()); Vec3i vec3i = new Vec3i( underwaterMagmaConfiguration.placementRadiusAroundFloor, underwaterMagmaConfiguration.placementRadiusAroundFloor, underwaterMagmaConfiguration.placementRadiusAroundFloor ); BoundingBox boundingBox = BoundingBox.fromCorners(blockPos2.subtract(vec3i), blockPos2.offset(vec3i)); return BlockPos.betweenClosedStream(boundingBox) .filter(blockPosx -> randomSource.nextFloat() < underwaterMagmaConfiguration.placementProbabilityPerValidPosition) .filter(blockPosx -> this.isValidPlacement(worldGenLevel, blockPosx)) .mapToInt(blockPosx -> { worldGenLevel.setBlock(blockPosx, Blocks.MAGMA_BLOCK.defaultBlockState(), 2); return 1; }) .sum() > 0; } } private static OptionalInt getFloorY(WorldGenLevel level, BlockPos pos, UnderwaterMagmaConfiguration config) { Predicate predicate = blockState -> blockState.is(Blocks.WATER); Predicate predicate2 = blockState -> !blockState.is(Blocks.WATER); Optional optional = Column.scan(level, pos, config.floorSearchRange, predicate, predicate2); return (OptionalInt)optional.map(Column::getFloor).orElseGet(OptionalInt::empty); } private boolean isValidPlacement(WorldGenLevel level, BlockPos pos) { if (!this.isWaterOrAir(level, pos) && !this.isWaterOrAir(level, pos.below())) { for (Direction direction : Direction.Plane.HORIZONTAL) { if (this.isWaterOrAir(level, pos.relative(direction))) { return false; } } return true; } else { return false; } } private boolean isWaterOrAir(LevelAccessor level, BlockPos pos) { BlockState blockState = level.getBlockState(pos); return blockState.is(Blocks.WATER) || blockState.isAir(); } }