/*******************************************************************************
 * Copyright 2014-2019, the Biomes O' Plenty Team
 *
 * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
 *
 * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
 ******************************************************************************/
package biomesoplenty.common.world.gen.feature;

import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.common.util.biome.FeatureUtil;
import biomesoplenty.common.world.biome.BiomeFeatureHelper;
import biomesoplenty.common.world.gen.placement.BOPPlacements;
import biomesoplenty.core.BiomesOPlenty;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.Blocks;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.blockplacer.SimpleBlockPlacer;
import net.minecraft.world.gen.blockstateprovider.SimpleBlockStateProvider;
import net.minecraft.world.gen.blockstateprovider.WeightedBlockStateProvider;
import net.minecraft.world.gen.feature.*;
import net.minecraft.world.gen.placement.AtSurfaceWithExtraConfig;
import net.minecraft.world.gen.placement.ChanceConfig;
import net.minecraft.world.gen.placement.NoPlacementConfig;
import net.minecraft.world.gen.placement.Placement;
import net.minecraft.world.gen.placement.TopSolidRangeConfig;

public class BOPConfiguredFeatures
{
    // Trees
    public static final ConfiguredFeature<?, ?> ACACIA_BUSH = register("acacia_bush", BOPFeatures.ACACIA_BUSH.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> ACACIA_TWIGLET = register("acacia_twiglet", BOPFeatures.ACACIA_TWIGLET.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> ACACIA_TWIGLET_SMALL = register("acacia_twiglet_small", BOPFeatures.ACACIA_TWIGLET_SMALL.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> ACACIA_TWIGLET_TREE = register("acacia_twiglet_tree", BOPFeatures.ACACIA_TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> ALPS_SPRUCE_TREE = register("alps_spruce_tree", BOPFeatures.ALPS_SPRUCE_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_FLOWERING_OAK_TREE = register("big_flowering_oak_tree", BOPFeatures.BIG_FLOWERING_OAK_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_HELLBARK_TREE = register("big_hellbark_tree", BOPFeatures.BIG_HELLBARK_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_JACARANDA_TREE = register("big_jacaranda_tree", BOPFeatures.BIG_JACARANDA_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_MAGIC_TREE = register("big_magic_tree", BOPFeatures.BIG_MAGIC_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_MAPLE_TREE = register("big_maple_tree", BOPFeatures.BIG_MAPLE_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_OAK_TREE = register("big_oak_tree", BOPFeatures.BIG_OAK_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_ORANGE_AUTUMN_TREE = register("big_orange_autumn_tree", BOPFeatures.BIG_ORANGE_AUTUMN_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_ORIGIN_TREE = register("big_origin_tree", BOPFeatures.BIG_ORIGIN_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_PINK_CHERRY_TREE = register("big_pink_cherry_tree", BOPFeatures.BIG_PINK_CHERRY_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_RAINBOW_BIRCH_TREE = register("big_rainbow_birch_tree", BOPFeatures.BIG_RAINBOW_BIRCH_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_WHITE_CHERRY_TREE = register("big_white_cherry_tree", BOPFeatures.BIG_WHITE_CHERRY_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BIG_YELLOW_AUTUMN_TREE = register("big_yellow_autumn_tree", BOPFeatures.BIG_YELLOW_AUTUMN_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BURNT_TREE = register("burnt_tree", BOPFeatures.BURNT_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> BUSH = register("bush", BOPFeatures.BUSH.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> CYPRESS_TREE = register("cypress_tree", BOPFeatures.CYPRESS_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> CYPRESS_TREE_MEDIUM = register("cypress_tree_medium", BOPFeatures.CYPRESS_TREE_MEDIUM.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DARK_OAK_POPLAR = register("dark_oak_poplar", BOPFeatures.DARK_OAK_POPLAR.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DARK_OAK_TWIGLET_TREE = register("dark_oak_twiglet_tree", BOPFeatures.DARK_OAK_TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DEAD_TREE = register("dead_tree", BOPFeatures.DEAD_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DEAD_TREE_WASTELAND = register("dead_tree_wasteland", BOPFeatures.DEAD_TREE_WASTELAND.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DEAD_TWIGLET_TREE = register("dead_twiglet_tree", BOPFeatures.DEAD_TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DEAD_TWIGLET_TREE_SMALL = register("dead_twiglet_tree_small", BOPFeatures.DEAD_TWIGLET_TREE_SMALL.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DEAD_TWIGLET_TREE_TALL = register("dead_twiglet_tree_tall", BOPFeatures.DEAD_TWIGLET_TREE_TALL.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DYING_TREE = register("dying_tree", BOPFeatures.DYING_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> DYING_TREE_WASTELAND = register("dying_tree_wasteland", BOPFeatures.DYING_TREE_WASTELAND.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> FIR_TREE = register("fir_tree", BOPFeatures.FIR_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> FIR_TREE_LARGE = register("fir_tree_large", BOPFeatures.FIR_TREE_LARGE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> FIR_TREE_SMALL = register("fir_tree_small", BOPFeatures.FIR_TREE_SMALL.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> FLOWERING_BUSH = register("flowering_bush", BOPFeatures.FLOWERING_BUSH.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> FLOWERING_OAK_TREE = register("flowering_oak_tree", BOPFeatures.FLOWERING_OAK_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> FLOWERING_OAK_TREE_BEES = register("flowering_oak_tree_bees", BOPFeatures.FLOWERING_OAK_TREE.configured(Features.OAK.config().withDecorators(ImmutableList.of(Features.Placements.BEEHIVE_005))));
    public static final ConfiguredFeature<?, ?> GIANT_TREE = register("giant_tree", BOPFeatures.GIANT_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> HELLBARK_TREE = register("hellbark_tree", BOPFeatures.HELLBARK_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> JACARANDA_TREE = register("jacaranda_tree", BOPFeatures.JACARANDA_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> JACARANDA_TREE_BEES = register("jacaranda_tree_bees", BOPFeatures.JACARANDA_TREE.configured(Features.OAK.config().withDecorators(ImmutableList.of(Features.Placements.BEEHIVE_0002))));
    public static final ConfiguredFeature<?, ?> JUNGLE_TWIGLET_TREE = register("jungle_twiglet_tree", BOPFeatures.JUNGLE_TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> MAGIC_TREE = register("magic_tree", BOPFeatures.MAGIC_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> MAHOGANY_TREE = register("mahogany_tree", BOPFeatures.MAHOGANY_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> MAPLE_TREE = register("maple_tree", BOPFeatures.MAPLE_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> MAPLE_TWIGLET_TREE = register("maple_twiglet_tree", BOPFeatures.MAPLE_TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> ORANGE_AUTUMN_TREE = register("orange_autumn_tree", BOPFeatures.ORANGE_AUTUMN_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> ORIGIN_TREE = register("origin_tree", BOPFeatures.ORIGIN_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> PALM_TREE = register("palm_tree", BOPFeatures.PALM_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> PINK_CHERRY_TREE_BEES = register("pink_cherry_tree_bees", BOPFeatures.PINK_CHERRY_TREE.configured(Features.OAK.config().withDecorators(ImmutableList.of(Features.Placements.BEEHIVE_002))));
    public static final ConfiguredFeature<?, ?> RAINBOW_BIRCH_TREE = register("rainbow_birch_tree", BOPFeatures.RAINBOW_BIRCH_TREE.configured(Features.OAK.config().withDecorators(ImmutableList.of(Features.Placements.BEEHIVE_005))));
    public static final ConfiguredFeature<?, ?> REDWOOD_TREE = register("redwood_tree", BOPFeatures.REDWOOD_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> REDWOOD_TREE_LARGE = register("redwood_tree_large", BOPFeatures.REDWOOD_TREE_LARGE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> REDWOOD_TREE_MEDIUM = register("redwood_tree_medium", BOPFeatures.REDWOOD_TREE_MEDIUM.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> SMALL_DEAD_TREE = register("small_dead_tree", BOPFeatures.SMALL_DEAD_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> SPARSE_ACACIA_TREE = register("sparse_acacia_tree", BOPFeatures.SPARSE_ACACIA_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> SPARSE_OAK_TREE = register("sparse_oak_tree", BOPFeatures.SPARSE_OAK_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> SPRUCE_BUSH = register("spruce_bush", BOPFeatures.SPRUCE_BUSH.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> SPRUCE_POPLAR = register("spruce_poplar", BOPFeatures.SPRUCE_POPLAR.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> SPRUCE_TWIGLET_TREE = register("spruce_twiglet_tree", BOPFeatures.SPRUCE_TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> TALL_DEAD_TREE = register("tall_dead_tree", BOPFeatures.TALL_DEAD_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> TALL_SPRUCE_TREE = register("tall_spruce_tree", BOPFeatures.TALL_SPRUCE_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> TALL_SPRUCE_TREE_BEES = register("tall_spruce_tree_bees", BOPFeatures.TALL_SPRUCE_TREE.configured(Features.OAK.config().withDecorators(ImmutableList.of(Features.Placements.BEEHIVE_005))));
    public static final ConfiguredFeature<?, ?> TALL_SWAMP_TREE = register("tall_swamp_tree", BOPFeatures.TALL_SWAMP_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> TALL_TWIGLET_TREE = register("tall_twiglet_tree", BOPFeatures.TALL_TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> TALL_UMBRAN_TREE = register("tall_umbran_tree", BOPFeatures.TALL_UMBRAN_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> TWIGLET_TREE = register("twiglet_tree", BOPFeatures.TWIGLET_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> TWIGLET_TREE_VOLCANO = register("twiglet_tree_volcano", BOPFeatures.TWIGLET_TREE_VOLCANO.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> UMBRAN_TREE = register("umbran_tree", BOPFeatures.UMBRAN_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> WHITE_CHERRY_TREE_BEES = register("white_cherry_tree_bees", BOPFeatures.WHITE_CHERRY_TREE.configured(Features.OAK.config().withDecorators(ImmutableList.of(Features.Placements.BEEHIVE_002))));
    public static final ConfiguredFeature<?, ?> WILLOW_TREE = register("willow_tree", BOPFeatures.WILLOW_TREE.configured(Features.OAK.config()));
    public static final ConfiguredFeature<?, ?> YELLOW_AUTUMN_TREE = register("yellow_autumn_tree", BOPFeatures.YELLOW_AUTUMN_TREE.configured(Features.OAK.config()));

    /////////////////////////////////////////////////////////////////////

    // Biome Tree Listings
    public static final ConfiguredFeature<?, ?> ALPS_FOOTHILLS_TREES = register("alps_foothills_trees", ALPS_SPRUCE_TREE.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> BAMBOO_BLOSSOM_GROVE_TREES = register("bamboo_blossom_grove_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(WHITE_CHERRY_TREE_BEES.weighted(0.05F), PINK_CHERRY_TREE_BEES.weighted(0.05F), BIG_WHITE_CHERRY_TREE.weighted(0.05F), BIG_PINK_CHERRY_TREE.weighted(0.05F), BIG_FLOWERING_OAK_TREE.weighted(0.1F), FLOWERING_BUSH.weighted(0.3F)), FLOWERING_OAK_TREE_BEES)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(7, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> BAYOU_TREES = register("bayou_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(CYPRESS_TREE_MEDIUM.weighted(0.3F)), CYPRESS_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.6F, 1))));
    public static final ConfiguredFeature<?, ?> BURNT_FOREST_TREES = register("burnt_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(DEAD_TREE.weighted(0.2F)), BURNT_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(4, 0.4F, 1))));
    public static final ConfiguredFeature<?, ?> CHERRY_BLOSSOM_GROVE_TREES = register("cherry_blossom_grove_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(WHITE_CHERRY_TREE_BEES.weighted(0.1F), PINK_CHERRY_TREE_BEES.weighted(0.2F), BIG_WHITE_CHERRY_TREE.weighted(0.3F), FLOWERING_OAK_TREE_BEES.weighted(0.15F), FLOWERING_BUSH.weighted(0.3F)), BIG_PINK_CHERRY_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(5, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> CONIFEROUS_FOREST_TREES = register("coniferous_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(FIR_TREE.weighted(0.33333334F)), FIR_TREE_LARGE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(10, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> CONIFEROUS_LAKES_TREES = register("coniferous_lakes_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(FIR_TREE.weighted(0.1F)), FIR_TREE_SMALL)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(5, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> DEAD_FOREST_TREES = register("dead_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(DYING_TREE.weighted(0.2F), TALL_SPRUCE_TREE.weighted(0.3F), SMALL_DEAD_TREE.weighted(0.3F), DEAD_TWIGLET_TREE.weighted(0.2F)), Features.OAK)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> DEEP_BAYOU_TREES = register("deep_bayou_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(CYPRESS_TREE.weighted(0.2F), CYPRESS_TREE_MEDIUM.weighted(0.5F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(26, 0.8F, 1))));
    public static final ConfiguredFeature<?, ?> DENSE_WOODLAND_TREES = register("dense_woodland_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BIG_OAK_TREE.weighted(0.5F)), Features.OAK)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(12, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> DRYLAND_TREES = register("dryland_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(TWIGLET_TREE.weighted(0.4F), SPARSE_OAK_TREE.weighted(0.2F)), ACACIA_TWIGLET_SMALL)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.4F, 1))));
    public static final ConfiguredFeature<?, ?> DRY_BONEYARD_TREES = register("dry_boneyard_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(TWIGLET_TREE.weighted(0.4F), SPARSE_OAK_TREE.weighted(0.2F)), ACACIA_TWIGLET_SMALL)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.2F, 1))));
    public static final ConfiguredFeature<?, ?> FIR_CLEARING_TREES = register("fir_clearing_trees", FIR_TREE_SMALL.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> FLOWER_MEADOW_TREES = register("flower_meadow_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(TALL_SPRUCE_TREE_BEES.weighted(0.1F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> FUNGAL_JUNGLE_TREES = register("fungal_jungle_trees", BUSH.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> GROVE_TREES = register("grove_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(SPARSE_OAK_TREE.weighted(0.05F), DARK_OAK_POPLAR.weighted(0.2F), SPRUCE_POPLAR.weighted(0.4F), FLOWERING_BUSH.weighted(0.1F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(3, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> GROVE_CLEARING_TREES = register("grove_clearing_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(SPARSE_OAK_TREE.weighted(0.1F), FLOWERING_BUSH.weighted(0.3F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.4F, 1))));
    public static final ConfiguredFeature<?, ?> JADE_CLIFFS_TREES = register("jade_cliffs_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(TALL_SPRUCE_TREE.weighted(0.075F), Features.PINE.weighted(0.025F)), SPRUCE_BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(35, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> LAVENDER_FIELD_TREES = register("lavender_field_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(FLOWERING_OAK_TREE_BEES.weighted(0.2F), BIG_FLOWERING_OAK_TREE.weighted(0.1F), BIG_JACARANDA_TREE.weighted(0.1F)), JACARANDA_TREE_BEES)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig((int)0.85F, 0.2F, 1))));
    public static final ConfiguredFeature<?, ?> LAVENDER_FOREST_TREES = register("lavender_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(FLOWERING_OAK_TREE_BEES.weighted(0.1F), BIG_FLOWERING_OAK_TREE.weighted(0.05F), BIG_JACARANDA_TREE.weighted(0.1F)), JACARANDA_TREE_BEES)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(7, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> LUSH_DESERT_TREES = register("lush_desert_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(ACACIA_BUSH.weighted(0.4F), SPARSE_ACACIA_TREE.weighted(0.2F)), ACACIA_TWIGLET_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(5, 0.4F, 1))));
    public static final ConfiguredFeature<?, ?> MEADOW_TREES = register("meadow_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(TALL_SPRUCE_TREE_BEES.weighted(0.1F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(4, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> MEADOW_FOREST_TREES = register("meadow_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BUSH.weighted(0.25F)), TALL_SPRUCE_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(8, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> MUSKEG_TREES = register("muskeg_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(TALL_DEAD_TREE.weighted(0.1F)), DEAD_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> MYSTIC_GROVE_TREES = register("mystic_grove_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BIG_FLOWERING_OAK_TREE.weighted(0.15F), JACARANDA_TREE.weighted(0.25F), BIG_MAGIC_TREE.weighted(0.3F), GIANT_TREE.weighted(0.02F)), MAGIC_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(10, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> MYSTIC_PLAINS_TREES = register("mystic_plains_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(FLOWERING_OAK_TREE.weighted(0.1F), JACARANDA_TREE.weighted(0.25F)), MAGIC_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.2F, 1))));
    public static final ConfiguredFeature<?, ?> OMINOUS_WOODS_TREES = register("ominous_woods_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(DEAD_TREE.weighted(0.05F), DYING_TREE.weighted(0.15F), TALL_UMBRAN_TREE.weighted(0.7F)), UMBRAN_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(7, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> OMINOUS_MIRE_TREES = register("ominous_mire_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(DEAD_TREE.weighted(0.1F), DYING_TREE.weighted(0.2F), UMBRAN_TREE.weighted(0.4F)), WILLOW_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(10, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> ORCHARD_TREES = register("orchard_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BIG_FLOWERING_OAK_TREE.weighted(0.1F)), FLOWERING_OAK_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> ORIGIN_VALLEY_TREES = register("origin_valley_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BIG_ORIGIN_TREE.weighted(0.1F)), ORIGIN_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(BOPPlacements.ALPHA_TREE.configured(NoPlacementConfig.INSTANCE)));
    public static final ConfiguredFeature<?, ?> PRAIRIE_TREES = register("prairie_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BIG_OAK_TREE.weighted(0.1F)), SPARSE_OAK_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig((int)0.85F, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> RAINBOW_HILLS_TREES = register("rainbow_hills_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BUSH.weighted(0.2F), FIR_TREE_SMALL.weighted(0.1F), FIR_TREE.weighted(0.025F), BIG_RAINBOW_BIRCH_TREE.weighted(0.2F)), RAINBOW_BIRCH_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(15, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> RAINFOREST_TREES = register("rainforest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(Features.JUNGLE_TREE.weighted(0.1F)), MAHOGANY_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(12, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> RAINFOREST_CLIFFS_TREES = register("rainforest_cliffs_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(JUNGLE_TWIGLET_TREE.weighted(0.4F), MAHOGANY_TREE.weighted(0.05F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(20, 0.4F, 1))));
    public static final ConfiguredFeature<?, ?> RAINFOREST_FLOODPLAIN_TREES = register("rainforest_floodplain_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(SPARSE_OAK_TREE.weighted(0.3F), BIG_OAK_TREE.weighted(0.1F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> REDWOOD_FOREST_EDGE_TREES = register("redwood_forest_edge_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(Features.OAK.weighted(0.2F), SPARSE_OAK_TREE.weighted(0.1F), REDWOOD_TREE.weighted(0.3F), REDWOOD_TREE_MEDIUM.weighted(0.1F)), BUSH)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(6, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> REDWOOD_FOREST_TREES = register("redwood_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BUSH.weighted(0.1F), REDWOOD_TREE.weighted(0.3F), REDWOOD_TREE_LARGE.weighted(0.5F)), REDWOOD_TREE_MEDIUM)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(18, 0.2F, 1))));
    public static final ConfiguredFeature<?, ?> REDWOOD_HILLS_TREES = register("redwood_hills_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BUSH.weighted(0.1F), REDWOOD_TREE_MEDIUM.weighted(0.3F)), REDWOOD_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(24, 0.2F, 1))));
    public static final ConfiguredFeature<?, ?> SEASONAL_FOREST_TREES = register("seasonal_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(Features.OAK.weighted(0.05F), BIG_OAK_TREE.weighted(0.025F), MAPLE_TREE.weighted(0.2F), YELLOW_AUTUMN_TREE.weighted(0.3F), BIG_MAPLE_TREE.weighted(0.1F), BIG_YELLOW_AUTUMN_TREE.weighted(0.1F), BIG_ORANGE_AUTUMN_TREE.weighted(0.1F)), ORANGE_AUTUMN_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(10, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> SEASONAL_ORCHARD_TREES = register("seasonal_orchard_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BIG_YELLOW_AUTUMN_TREE.weighted(0.05F)), YELLOW_AUTUMN_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(3, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> SEASONAL_PUMPKIN_PATCH_TREES = register("seasonal_pumpkin_patch_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BUSH.weighted(0.2F), ORANGE_AUTUMN_TREE.weighted(0.1F), BIG_ORANGE_AUTUMN_TREE.weighted(0.05F)), TWIGLET_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(6, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> SHROOMY_WETLAND_TREES = register("shroomy_wetland_trees", DARK_OAK_TWIGLET_TREE.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(2, 0.2F, 1))));
    public static final ConfiguredFeature<?, ?> SHRUBLAND_TREES = register("shrubland_trees", BUSH.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.05F, 1))));
    public static final ConfiguredFeature<?, ?> SHRUBLAND_HILLS_TREES = register("shrubland_hills_trees", BUSH.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(10, 0.05F, 1))));
    public static final ConfiguredFeature<?, ?> SNOWY_CONIFEROUS_FOREST_TREES = register("snowy_coniferous_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(FIR_TREE.weighted(0.4F), MAPLE_TREE.weighted(0.1F)), FIR_TREE_LARGE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(6, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> SNOWY_MAPLE_FOREST_TREES = register("snowy_maple_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(FIR_TREE.weighted(0.025F), FIR_TREE_SMALL.weighted(0.1F), BIG_MAPLE_TREE.weighted(0.3F)), MAPLE_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(10, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> TALL_DEAD_FOREST_TREES = register("tall_dead_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(DYING_TREE.weighted(0.2F), DEAD_TWIGLET_TREE.weighted(0.3F), TALL_SPRUCE_TREE.weighted(0.1F), SMALL_DEAD_TREE.weighted(0.1F), Features.OAK.weighted(0.05F)), DEAD_TWIGLET_TREE_TALL)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(4, 0.6F, 1))));
    public static final ConfiguredFeature<?, ?> TROPICS_TREES = register("tropics_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(JUNGLE_TWIGLET_TREE.weighted(0.3F), FLOWERING_BUSH.weighted(0.1F)), PALM_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(11, 0.2F, 1))));
    public static final ConfiguredFeature<?, ?> TUNDRA_TREES = register("tundra_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(DEAD_TWIGLET_TREE_SMALL.weighted(0.1F)), MAPLE_TWIGLET_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.3F, 1))));
    public static final ConfiguredFeature<?, ?> TUNDRA_BOG_TREES = register("tundra_bog_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(SPRUCE_TWIGLET_TREE.weighted(0.4F), MAPLE_TWIGLET_TREE.weighted(0.6F)), TWIGLET_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(16, 0.4F, 1))));
    public static final ConfiguredFeature<?, ?> UNDERGROWTH_TREES = register("undergrowth_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(BIG_HELLBARK_TREE.weighted(0.1F)), HELLBARK_TREE)).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(35)));
    public static final ConfiguredFeature<?, ?> VOLCANIC_PLAINS_TREES = register("volcanic_plains_trees", TWIGLET_TREE_VOLCANO.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(1, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> WASTELAND_TREES = register("wasteland_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(DEAD_TREE_WASTELAND.weighted(0.2F)), DYING_TREE_WASTELAND)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig((int)0.75F, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> WETLAND_TREES = register("wetland_trees", WILLOW_TREE.decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(3, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> WETLAND_FOREST_TREES = register("wetland_forest_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(WILLOW_TREE.weighted(0.25F)), TALL_SPRUCE_TREE)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(7, 0.1F, 1))));
    public static final ConfiguredFeature<?, ?> WOODED_SCRUBLAND_TREES = register("wooded_scrubland_trees", Feature.RANDOM_SELECTOR.configured(new MultipleRandomFeatureConfig(ImmutableList.of(SPRUCE_TWIGLET_TREE.weighted(0.3F), TALL_TWIGLET_TREE.weighted(0.1F)), ACACIA_TWIGLET)).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(6, 0.5F, 1))));
    public static final ConfiguredFeature<?, ?> WOODLAND_TREES = register("woodland_trees", Feature.TREE.configured(Features.OAK.config()).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(Placement.COUNT_EXTRA.configured(new AtSurfaceWithExtraConfig(6, 0.1F, 1))));

    // Biome Flower Listings
    public static final ConfiguredFeature<?, ?> CHERRY_BLOSSOM_GROVE_FLOWERS = register("cherry_blossom_grove_flowers", Feature.FLOWER.configured(BOPFeatures.CHERRY_BLOSSOM_GROVE_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> CLOVER_PATCH_FLOWERS = register("clover_patch_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(Blocks.AZURE_BLUET.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(16).build()).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(20)));
    public static final ConfiguredFeature<?, ?> CONIFEROUS_FOREST_FLOWERS = register("coniferous_forest_flowers", Feature.FLOWER.configured(BOPFeatures.CONIFEROUS_FOREST_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(4)));
    public static final ConfiguredFeature<?, ?> LUSH_DESERT_FLOWERS = register("lush_desert_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(BOPBlocks.wildflower.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> FLOWER_MEADOW_FLOWERS = register("flower_meadow_flowers", Feature.FLOWER.configured(BOPFeatures.FLOWER_MEADOW_FLOWER_CONFIG).decorated(Features.Placements.HEIGHTMAP_SQUARE).count(4));
    public static final ConfiguredFeature<?, ?> GROVE_FLOWERS = register("grove_flowers", Feature.FLOWER.configured(BOPFeatures.EXTENDED_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> LAVENDER_FLOWERS = register("lavender_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(BOPBlocks.lavender.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.HEIGHTMAP_SQUARE).count(15));
    public static final ConfiguredFeature<?, ?> MEADOW_FLOWERS = register("meadow_flowers", Feature.FLOWER.configured(BOPFeatures.MEADOW_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> MEADOW_FLOWERS_2 = register("meadow_flowers_2", Feature.FLOWER.configured(BOPFeatures.FLOWER_MEADOW_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> MOOR_FLOWERS = register("moor_flowers", Feature.FLOWER.configured(BOPFeatures.MOOR_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> MOOR_FLOWERS_2 = register("moor_flowers_2", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(BOPBlocks.violet.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(50)));
    public static final ConfiguredFeature<?, ?> MYSTIC_GROVE_FLOWERS = register("mystic_grove_flowers", Feature.FLOWER.configured(BOPFeatures.MYSTIC_GROVE_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(18)));
    public static final ConfiguredFeature<?, ?> MYSTIC_PLAINS_FLOWERS = register("mystic_plains_flowers", Feature.FLOWER.configured(BOPFeatures.MYSTIC_GROVE_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(50)));
    public static final ConfiguredFeature<?, ?> OMINOUS_WOODS_FLOWERS = register("ominous_woods_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(Blocks.WITHER_ROSE.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> ORCHARD_FLOWERS = register("orchard_flowers", Feature.FLOWER.configured(BOPFeatures.EXTENDED_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(15)));
    public static final ConfiguredFeature<?, ?> ORIGIN_FLOWERS = register("origin_flowers", Feature.FLOWER.configured(BOPFeatures.ORIGIN_VALLEY_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(4)));
    public static final ConfiguredFeature<?, ?> POPPY_FLOWERS = register("poppy_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(Blocks.POPPY.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.HEIGHTMAP_SQUARE).count(15));
    public static final ConfiguredFeature<?, ?> RAINBOW_HILLS_FLOWERS = register("rainbow_hills_flowers", Feature.FLOWER.configured(BOPFeatures.RAINBOW_HILLS_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(25)));
    public static final ConfiguredFeature<?, ?> RAINFOREST_FLOWERS = register("rainforest_flowers", Feature.FLOWER.configured(BOPFeatures.RAINFOREST_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> SHRUBLAND_FLOWERS = register("shrubland_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(Blocks.ALLIUM.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> SNOWY_FLOWERS = register("snowy_flowers", Feature.FLOWER.configured(BOPFeatures.SNOWY_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> TROPIC_FLOWERS = register("tropic_flowers", Feature.FLOWER.configured(BOPFeatures.TROPICS_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(15)));
    public static final ConfiguredFeature<?, ?> UNDERGROWTH_FLOWERS = register("undergrowth_flowers", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.burning_blossom.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(8)));
    public static final ConfiguredFeature<?, ?> WASTELAND_FLOWERS = register("wasteland_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(BOPBlocks.wilted_lily.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> WETLAND_FLOWERS = register("wetland_flowers", Feature.FLOWER.configured(BOPFeatures.WETLAND_FLOWER_CONFIG).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> SCRUBLAND_FLOWERS = register("scrubland_flowers", Feature.FLOWER.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(BOPBlocks.wildflower.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(64).build()).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(2)));

    /////////////////////////////////////////////////////////////////////

    // Foliage
    public static final ConfiguredFeature<?, ?> STANDARD_GRASS_1 = register("standard_grass_1", BOPFeatures.STANDARD_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> STANDARD_GRASS_3 = register("standard_grass_3", BOPFeatures.STANDARD_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> STANDARD_GRASS_6 = register("standard_grass_6", BOPFeatures.STANDARD_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> STANDARD_GRASS_12 = register("standard_grass_12", BOPFeatures.STANDARD_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(12)));
    public static final ConfiguredFeature<?, ?> STANDARD_GRASS_24 = register("standard_grass_24", BOPFeatures.STANDARD_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(24)));

    public static final ConfiguredFeature<?, ?> FERN_GRASS_4 = register("fern_grass_4", BOPFeatures.FERN_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(4)));
    public static final ConfiguredFeature<?, ?> FERN_GRASS_8 = register("fern_grass_8", BOPFeatures.FERN_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(8)));
    public static final ConfiguredFeature<?, ?> FERN_GRASS_16 = register("fern_grass_16", BOPFeatures.FERN_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(16)));

    public static final ConfiguredFeature<?, ?> FERN_24 = register("fern_24", BOPFeatures.FERN.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(24)));

    public static final ConfiguredFeature<?, ?> WASTELAND_GRASS_1 = register("wasteland_grass_1", BOPFeatures.WASTELAND_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> WASTELAND_GRASS_2 = register("wasteland_grass_2", BOPFeatures.WASTELAND_GRASS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(2)));

    public static final ConfiguredFeature<?, ?> BUSH_5 = register("bush_5", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.bush.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> BUSH_10 = register("bush_10", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.bush.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> BUSH_15 = register("bush_15", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.bush.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(15)));
    public static final ConfiguredFeature<?, ?> BUSH_50 = register("bush_50", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.bush.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(50)));

    public static final ConfiguredFeature<?, ?> SPROUTS_5 = register("sprouts_5", BOPFeatures.RANDOM_PATCH_ABOVE_GROUND.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> SPROUTS_10 = register("sprouts_10", BOPFeatures.RANDOM_PATCH_ABOVE_GROUND.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> SPROUTS_15 = register("sprouts_15", BOPFeatures.RANDOM_PATCH_ABOVE_GROUND.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(15)));
    public static final ConfiguredFeature<?, ?> SPROUTS_25 = register("sprouts_25", BOPFeatures.RANDOM_PATCH_ABOVE_GROUND.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(25)));
    public static final ConfiguredFeature<?, ?> SPROUTS_50 = register("sprouts_50", BOPFeatures.RANDOM_PATCH_ABOVE_GROUND.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(50)));
    public static final ConfiguredFeature<?, ?> SPROUTS_75 = register("sprouts_75", BOPFeatures.RANDOM_PATCH_ABOVE_GROUND.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(75)));
    public static final ConfiguredFeature<?, ?> SPROUTS_200 = register("sprouts_200", BOPFeatures.RANDOM_PATCH_ABOVE_GROUND.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).decorated(FeatureUtil.denseCount(200)));
    public static final ConfiguredFeature<?, ?> SPROUTS_UNDERGROWTH = register("sprouts_undergrowth", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.sprout.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(75)));

    public static final ConfiguredFeature<?, ?> CLOVER_3 = register("clover_3", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.clover.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> CLOVER_6 = register("clover_6", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.clover.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> CLOVER_250 = register("clover_250", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.clover.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(FeatureUtil.denseCount(250)));

    public static final ConfiguredFeature<?, ?> DUNE_GRASS_128 = register("dune_grass_128", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.dune_grass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(128)));

    public static final ConfiguredFeature<?, ?> DESERT_GRASS_10 = register("desert_grass_10", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.desert_grass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> DESERT_GRASS_20 = register("desert_grass_20", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.desert_grass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(20)));

    public static final ConfiguredFeature<?, ?> DEAD_GRASS_2 = register("dead_grass_2", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.dead_grass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(2)));
    public static final ConfiguredFeature<?, ?> DEAD_GRASS_5 = register("dead_grass_5", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.dead_grass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> DEAD_GRASS_25 = register("dead_grass_25", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.dead_grass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(25)));
    public static final ConfiguredFeature<?, ?> DEAD_GRASS_45 = register("dead_grass_45", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.dead_grass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(45)));

    public static final ConfiguredFeature<?, ?> TALL_GRASS_6 = register("tall_grass_6", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.TALL_GRASS.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> TALL_GRASS_12 = register("tall_grass_12", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.TALL_GRASS.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(12)));
    public static final ConfiguredFeature<?, ?> TALL_GRASS_24 = register("tall_grass_24", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.TALL_GRASS.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(24)));
    public static final ConfiguredFeature<?, ?> TALL_GRASS_64 = register("tall_grass_64", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.TALL_GRASS.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(64)));
    public static final ConfiguredFeature<?, ?> TALL_GRASS_250 = register("tall_grass_250", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.TALL_GRASS.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE).decorated(FeatureUtil.denseCount(250)));

    public static final ConfiguredFeature<?, ?> LARGE_FERN_7 = register("large_fern_7", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.LARGE_FERN.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(7)));
    public static final ConfiguredFeature<?, ?> LARGE_FERN_14 = register("large_fern_14", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.LARGE_FERN.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(14)));
    public static final ConfiguredFeature<?, ?> LARGE_FERN_25 = register("large_fern_25", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.LARGE_FERN.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(25)));

    /////////////////////////////////////////////////////////////////////

    // Plants
    public static final ConfiguredFeature<?, ?> CATTAIL_6 = register("cattail_6", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(BOPBlocks.cattail.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> CATTAIL_12 = register("cattail_12", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(BOPBlocks.cattail.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(12)));
    public static final ConfiguredFeature<?, ?> CATTAIL_24 = register("cattail_24", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(BOPBlocks.cattail.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(24)));

    public static final ConfiguredFeature<?, ?> TOADSTOOL_NORMAL = register("toadstool_normal", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.toadstool.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> TOADSTOOL_EXTRA = register("toadstool_extra", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.toadstool.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> GLOWSHROOM_UNCOMMON = register("glowshroom_uncommon", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.glowshroom.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(7)));
    public static final ConfiguredFeature<?, ?> GLOWSHROOM_NORMAL = register("glowshroom_normal", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfiguration(BOPBlocks.glowshroom.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(20)));
    public static final ConfiguredFeature<?, ?> BARLEY = register("barley", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleProjects(BOPBlocks.barley.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_SQUARE).count(15));

    // Water Plants
    public static final ConfiguredFeature<?, ?> REED_5 = register("reed_5", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.reed.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> REED_10 = register("reed_10", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.reed.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> REED_100 = register("reed_100", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.reed.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(100)));

    public static final ConfiguredFeature<?, ?> WATERGRASS_5 = register("watergrass_5", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.watergrass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> WATERGRASS_10 = register("watergrass_10", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.watergrass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> WATERGRASS_25 = register("watergrass_25", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.watergrass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(25)));
    public static final ConfiguredFeature<?, ?> WATERGRASS_50 = register("watergrass_50", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.watergrass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(50)));
    public static final ConfiguredFeature<?, ?> WATERGRASS_250 = register("watergrass_200", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDoubleWater(BOPBlocks.watergrass.defaultBlockState())).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).decorated(FeatureUtil.denseCount(250)));

    public static final ConfiguredFeature<?, ?> MANGROVE_ROOTS = register("mangrove_roots", BOPFeatures.MANGROVE.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(125)));

    public static final ConfiguredFeature<?, ?> LILY_PAD_5 = register("lily_pad_5", Feature.RANDOM_PATCH.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(Blocks.LILY_PAD.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(10).build()).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).count(5));
    public static final ConfiguredFeature<?, ?> LILY_PAD_10 = register("lily_pad_10", Feature.RANDOM_PATCH.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(Blocks.LILY_PAD.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(10).build()).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).count(10));
    public static final ConfiguredFeature<?, ?> LILY_PAD_15 = register("lily_pad_15", Feature.RANDOM_PATCH.configured((new BlockClusterFeatureConfig.Builder(new SimpleBlockStateProvider(Blocks.LILY_PAD.defaultBlockState()), SimpleBlockPlacer.INSTANCE)).tries(10).build()).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).count(15));

    // Large Flowers
    public static final ConfiguredFeature<?, ?> PEONY_1 = register("peony_1", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.PEONY.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> SUNFLOWER_1 = register("sunflower_1", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.SUNFLOWER.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(1)));

    public static final ConfiguredFeature<?, ?> LILAC_1 = register("lilac_1", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.LILAC.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> LILAC_2 = register("lilac_2", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.LILAC.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(2)));
    public static final ConfiguredFeature<?, ?> LILAC_4 = register("lilac_4", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.LILAC.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(4)));

    public static final ConfiguredFeature<?, ?> ROSE_BUSH_1 = register("rose_bush_1", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.ROSE_BUSH.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> ROSE_BUSH_2 = register("rose_bush_2", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.ROSE_BUSH.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(2)));
    public static final ConfiguredFeature<?, ?> ROSE_BUSH_4 = register("rose_bush_4", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.ROSE_BUSH.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(4)));
    public static final ConfiguredFeature<?, ?> ROSE_BUSH_15 = register("rose_bush_15", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(Blocks.ROSE_BUSH.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(15)));

    public static final ConfiguredFeature<?, ?> GOLDENROD_2 = register("goldenrod_2", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(BOPBlocks.goldenrod.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(2)));
    public static final ConfiguredFeature<?, ?> GOLDENROD_10 = register("goldenrod_10", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(BOPBlocks.goldenrod.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(10)));

    public static final ConfiguredFeature<?, ?> BLUE_HYDRANGEA_1 = register("blue_hydrangea_1", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(BOPBlocks.blue_hydrangea.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> BLUE_HYDRANGEA_4 = register("blue_hydrangea_4", Feature.RANDOM_PATCH.configured(BiomeFeatureHelper.createClusterConfigurationDouble(BOPBlocks.blue_hydrangea.defaultBlockState())).decorated(Features.Placements.ADD_32).decorated(Features.Placements.HEIGHTMAP_SQUARE.count(4)));

    /////////////////////////////////////////////////////////////////////

    // Features
    public static final ConfiguredFeature<?, ?> BIG_PUMPKIN = register("big_pumpkin", BOPFeatures.BIG_PUMPKIN.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> BLACK_SAND_DISK = register("black_sand_disk", Feature.DISK.configured(new SphereReplaceConfig(BOPBlocks.black_sand.defaultBlockState(), FeatureSpread.of(2, 4), 2, ImmutableList.of(Blocks.DIRT.defaultBlockState(), Blocks.GRASS_BLOCK.defaultBlockState()))).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).count(2));
    public static final ConfiguredFeature<?, ?> BLACK_SAND_SPLATTER = register("black_sand_splatter", BOPFeatures.BLACK_SAND_SPLATTER.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(25)));
    public static final ConfiguredFeature<?, ?> BONE_SPINE = register("bone_spine", BOPFeatures.BONE_SPINE.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> BRAMBLE = register("bramble", BOPFeatures.BRAMBLE.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> BRAMBLE_EXTRA = register("bramble_extra", BOPFeatures.BRAMBLE.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> CRAG_SPLATTER = register("crag_splatter", BOPFeatures.CRAG_SPLATTER.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.decorated(FeatureUtil.denseCount(300))));
    public static final ConfiguredFeature<?, ?> DEEP_BAYOU_VINES = register("deep_bayou_vines", BOPFeatures.DEEP_BAYOU_VINES.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).count(128));
    public static final ConfiguredFeature<?, ?> DIORITE_DISK = register("diorite_disk", Feature.DISK.configured(new SphereReplaceConfig(Blocks.DIORITE.defaultBlockState(), FeatureSpread.of(3, 4), 2, ImmutableList.of(Blocks.DIRT.defaultBlockState(), Blocks.GRASS_BLOCK.defaultBlockState(), Blocks.PODZOL.defaultBlockState(), Blocks.SAND.defaultBlockState(), Blocks.GRAVEL.defaultBlockState(), Blocks.GRANITE.defaultBlockState(), Blocks.ANDESITE.defaultBlockState(), Blocks.DIORITE.defaultBlockState(), Blocks.COAL_ORE.defaultBlockState(), Blocks.IRON_ORE.defaultBlockState(), Blocks.STONE.defaultBlockState()))).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).count(14));
    public static final ConfiguredFeature<?, ?> FLESH_TENDON = register("flesh_tendon", BOPFeatures.FLESH_TENDON.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(65)));
    public static final ConfiguredFeature<?, ?> GRAVEL_DISK_EXTRA = register("gravel_disk_extra", Feature.DISK.configured(new SphereReplaceConfig(Blocks.GRAVEL.defaultBlockState(), FeatureSpread.of(4, 2), 1, ImmutableList.of(Blocks.DIRT.defaultBlockState(), Blocks.GRASS_BLOCK.defaultBlockState()))).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).count(6));
    public static final ConfiguredFeature<?, ?> HUGE_BROWN_MUSHROOM_EXTRA = register("huge_brown_mushroom_extra", Features.HUGE_BROWN_MUSHROOM.decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(21)));
    public static final ConfiguredFeature<?, ?> HUGE_CLOVER = register("huge_clover", BOPFeatures.HUGE_CLOVER.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(25)));
    public static final ConfiguredFeature<?, ?> HUGE_GLOWSHROOM = register("huge_glowshroom", BOPFeatures.HUGE_GLOWSHROOM.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> HUGE_RED_MUSHROOM_EXTRA = register("huge_red_mushroom_extra", Features.HUGE_RED_MUSHROOM.decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(6)));
    public static final ConfiguredFeature<?, ?> HUGE_TOADSTOOL = register("huge_toadstool", BOPFeatures.HUGE_TOADSTOOL.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> LARGE_CRYSTAL = register("large_crystal", BOPFeatures.LARGE_CRYSTAL.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).decorated(FeatureUtil.denseCount(200)));
    public static final ConfiguredFeature<?, ?> LAVA_LAKE_COMMON = register("lava_lake_common", Feature.LAKE.configured(new BlockStateFeatureConfig(Blocks.LAVA.defaultBlockState())).decorated(Placement.LAVA_LAKE.configured(new ChanceConfig(10))));
    public static final ConfiguredFeature<?, ?> MUD_DISK = register("mud_disk", Feature.DISK.configured(new SphereReplaceConfig(BOPBlocks.mud.defaultBlockState(), FeatureSpread.of(4, 2), 1, ImmutableList.of(Blocks.DIRT.defaultBlockState(), Blocks.GRASS_BLOCK.defaultBlockState()))).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).count(5));
    public static final ConfiguredFeature<?, ?> MYCELIUM_SPLATTER = register("mycelium_splatter", BOPFeatures.MYCELIUM_SPLATTER.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(14)));
    public static final ConfiguredFeature<?, ?> NETHER_BRAMBLE = register("nether_bramble", BOPFeatures.BRAMBLE.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(50)));
    public static final ConfiguredFeature<?, ?> NETHER_VINES = register("nether_vines", BOPFeatures.NETHER_VINES.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).decorated(FeatureUtil.denseCount(150)));
    public static final ConfiguredFeature<?, ?> OBSIDIAN_SPLATTER = register("obsidian_splatter", BOPFeatures.OBSIDIAN_SPLATTER.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(12)));
    public static final ConfiguredFeature<?, ?> ORANGE_SAND_DISK = register("orange_sand_disk", Feature.DISK.configured(new SphereReplaceConfig(BOPBlocks.orange_sand.defaultBlockState(), FeatureSpread.of(2, 4), 2, ImmutableList.of(Blocks.DIRT.defaultBlockState(), Blocks.GRASS_BLOCK.defaultBlockState()))).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).count(3));
    public static final ConfiguredFeature<?, ?> PODZOL_SPLATTER = register("podzol_splatter", BOPFeatures.PODZOL_SPLATTER.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(22)));
    public static final ConfiguredFeature<?, ?> PUMPKIN_PATCH = register("pumpkin_patch", BOPFeatures.PUMPKIN_PATCH.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(35)));
    public static final ConfiguredFeature<?, ?> RAINFOREST_CLIFFS_VINES = register("overgrown_cliffs_vines", BOPFeatures.RAINFOREST_CLIFFS_VINES.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).count(128));
    public static final ConfiguredFeature<?, ?> SCATTERED_ROCKS = register("scattered_rocks", BOPFeatures.SCATTERED_ROCKS.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> SCRUB_EXTRA = register("scrub_extra", BOPFeatures.SCRUB.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(35)));
    public static final ConfiguredFeature<?, ?> SCRUB_NORMAL = register("scrub_normal", BOPFeatures.SCRUB.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> SHORT_BAMBOO_10 = register("short_bamboo_10", BOPFeatures.SHORT_BAMBOO.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(10)));
    public static final ConfiguredFeature<?, ?> SHORT_BAMBOO_5 = register("short_bamboo_5", BOPFeatures.SHORT_BAMBOO.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(5)));
    public static final ConfiguredFeature<?, ?> SMALL_BROWN_MUSHROOM = register("small_brown_mushroom", BOPFeatures.SMALL_BROWN_MUSHROOM.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> SMALL_CRYSTAL = register("small_crystal", BOPFeatures.SMALL_CRYSTAL.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(40)));
    public static final ConfiguredFeature<?, ?> SMALL_GLOWSHROOM_UNCOMMON = register("small_glowshroom_uncommon", BOPFeatures.SMALL_GLOWSHROOM.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> SMALL_GLOWSHROOM = register("small_glowshroom", BOPFeatures.SMALL_GLOWSHROOM.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(3)));
    public static final ConfiguredFeature<?, ?> SMALL_RED_MUSHROOM = register("small_red_mushroom", BOPFeatures.SMALL_RED_MUSHROOM.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> SMALL_TOADSTOOL = register("small_toadstool", BOPFeatures.SMALL_TOADSTOOL.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(1)));
    public static final ConfiguredFeature<?, ?> VOLCANO_GRASS_SPLATTER = register("volcano_grass_splatter", BOPFeatures.GRASS_SPLATTER.configured(IFeatureConfig.NONE).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE.count(25)));
    public static final ConfiguredFeature<?, ?> VOLCANO_SPRING = register("volcano_spring", Feature.SPRING.configured(BOPFeatures.VOLCANO_SPRING_CONFIG).decorated(Placement.RANGE_VERY_BIASED.configured(new TopSolidRangeConfig(8, 16, 256))).squared().count(75));
    public static final ConfiguredFeature<?, ?> WATER_LAKE_COMMON = register("water_lake_common", Feature.LAKE.configured(new BlockStateFeatureConfig(Blocks.WATER.defaultBlockState())).decorated(Placement.WATER_LAKE.configured(new ChanceConfig(1))));
    public static final ConfiguredFeature<?, ?> WATER_LAKE_UNCOMMON = register("water_lake_uncommon", Feature.LAKE.configured(new BlockStateFeatureConfig(Blocks.WATER.defaultBlockState())).decorated(Placement.WATER_LAKE.configured(new ChanceConfig(3))));
    public static final ConfiguredFeature<?, ?> WATER_SPRING_EXTRA = register("water_spring_extra", Feature.SPRING.configured(BOPFeatures.WATER_SPRING_EXTRA_CONFIG).decorated(Features.Placements.HEIGHTMAP_DOUBLE_SQUARE).count(128));
    public static final ConfiguredFeature<?, ?> WHITE_SAND_DISK = register("white_sand_disk", Feature.DISK.configured(new SphereReplaceConfig(BOPBlocks.white_sand.defaultBlockState(), FeatureSpread.of(2, 4), 2, ImmutableList.of(Blocks.DIRT.defaultBlockState(), Blocks.GRASS_BLOCK.defaultBlockState()))).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).count(2));
    public static final ConfiguredFeature<?, ?> WHITE_SAND_DISK_EXTRA = register("white_sand_disk_extra", Feature.DISK.configured(new SphereReplaceConfig(BOPBlocks.white_sand.defaultBlockState(), FeatureSpread.of(4, 2), 1, ImmutableList.of(Blocks.DIRT.defaultBlockState(), Blocks.GRASS_BLOCK.defaultBlockState()))).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).count(8));

    private static <FC extends IFeatureConfig> ConfiguredFeature<FC, ?> register(String key, ConfiguredFeature<FC, ?> feature)
    {
        return Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, new ResourceLocation(BiomesOPlenty.MOD_ID, key), feature);
    }
}
