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.world.level.LevelAccessor;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.tags.Tag;
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.chunk.ChunkGenerator;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import com.mojang.serialization.Codec;
import net.minecraft.world.level.levelgen.feature.configurations.RandomPatchConfiguration;

public class RandomPatchFeature extends Feature<RandomPatchConfiguration> {
    public RandomPatchFeature(final Codec<RandomPatchConfiguration> codec) {
        super(codec);
    }
    
    @Override
    public boolean place(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, final BlockPos fu, final RandomPatchConfiguration cog) {
        final BlockState cfj8 = cog.stateProvider.getState(random, fu);
        BlockPos fu2;
        if (cog.project) {
            fu2 = bqu.getHeightmapPos(Heightmap.Types.WORLD_SURFACE_WG, fu);
        }
        else {
            fu2 = fu;
        }
        int integer10 = 0;
        final BlockPos.MutableBlockPos a11 = new BlockPos.MutableBlockPos();
        for (int integer11 = 0; integer11 < cog.tries; ++integer11) {
            a11.setWithOffset(fu2, random.nextInt(cog.xspread + 1) - random.nextInt(cog.xspread + 1), random.nextInt(cog.yspread + 1) - random.nextInt(cog.yspread + 1), random.nextInt(cog.zspread + 1) - random.nextInt(cog.zspread + 1));
            final BlockPos fu3 = a11.below();
            final BlockState cfj9 = bqu.getBlockState(fu3);
            if ((bqu.isEmptyBlock(a11) || (cog.canReplace && bqu.getBlockState(a11).getMaterial().isReplaceable())) && cfj8.canSurvive(bqu, a11) && (cog.whitelist.isEmpty() || cog.whitelist.contains(cfj9.getBlock())) && !cog.blacklist.contains(cfj9) && (!cog.needWater || bqu.getFluidState(fu3.west()).is(FluidTags.WATER) || bqu.getFluidState(fu3.east()).is(FluidTags.WATER) || bqu.getFluidState(fu3.north()).is(FluidTags.WATER) || bqu.getFluidState(fu3.south()).is(FluidTags.WATER))) {
                cog.blockPlacer.place(bqu, a11, cfj8, random);
                ++integer10;
            }
        }
        return integer10 > 0;
    }
}
