package net.minecraft.world.level.levelgen.feature;

import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.level.LevelReader;
import net.minecraft.core.Vec3i;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.core.BlockPos;
import java.util.Random;
import net.minecraft.world.level.levelgen.ChunkGeneratorSettings;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.LevelAccessor;
import com.mojang.datafixers.Dynamic;
import java.util.function.Function;
import net.minecraft.world.level.levelgen.feature.configurations.RandomPatchConfiguration;

public class RandomPatchFeature extends Feature<RandomPatchConfiguration> {
    public RandomPatchFeature(final Function<Dynamic<?>, ? extends RandomPatchConfiguration> function) {
        super(function);
    }
    
    @Override
    public boolean place(final LevelAccessor bjx, final ChunkGenerator<? extends ChunkGeneratorSettings> caa, final Random random, final BlockPos fk, final RandomPatchConfiguration chb) {
        final BlockState byj7 = chb.stateProvider.getState(random, fk);
        BlockPos fk2;
        if (chb.project) {
            fk2 = bjx.getHeightmapPos(Heightmap.Types.WORLD_SURFACE_WG, fk);
        }
        else {
            fk2 = fk;
        }
        int integer9 = 0;
        final BlockPos.MutableBlockPos a10 = new BlockPos.MutableBlockPos();
        for (int integer10 = 0; integer10 < chb.tries; ++integer10) {
            a10.set(fk2).move(random.nextInt(chb.xspread + 1) - random.nextInt(chb.xspread + 1), random.nextInt(chb.yspread + 1) - random.nextInt(chb.yspread + 1), random.nextInt(chb.zspread + 1) - random.nextInt(chb.zspread + 1));
            final BlockPos fk3 = a10.below();
            final BlockState byj8 = bjx.getBlockState(fk3);
            if ((bjx.isEmptyBlock(a10) || (chb.canReplace && bjx.getBlockState(a10).getMaterial().isReplaceable())) && byj7.canSurvive(bjx, a10) && (chb.whitelist.isEmpty() || chb.whitelist.contains(byj8.getBlock())) && !chb.blacklist.contains(byj8) && (!chb.needWater || bjx.getFluidState(fk3.west()).is(FluidTags.WATER) || bjx.getFluidState(fk3.east()).is(FluidTags.WATER) || bjx.getFluidState(fk3.north()).is(FluidTags.WATER) || bjx.getFluidState(fk3.south()).is(FluidTags.WATER))) {
                chb.blockPlacer.place(bjx, a10, byj7, random);
                ++integer9;
            }
        }
        return integer9 > 0;
    }
}
