package org.betterx.betterend.registry; import org.betterx.bclib.BCLib; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v3.levelgen.features.BCLConfigureFeature; import org.betterx.bclib.api.v3.levelgen.features.BCLFeature; import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder; import org.betterx.bclib.api.v3.levelgen.features.config.ConditionFeatureConfig; import org.betterx.bclib.api.v3.levelgen.features.placement.InBiome; import org.betterx.bclib.util.JsonFactory; import org.betterx.betterend.BetterEnd; import org.betterx.betterend.complexmaterials.StoneMaterial; import org.betterx.betterend.config.Configs; import org.betterx.betterend.world.biome.EndBiome; import org.betterx.betterend.world.biome.cave.EndCaveBiome; import org.betterx.betterend.world.features.*; import org.betterx.betterend.world.features.bushes.*; import org.betterx.betterend.world.features.terrain.*; import org.betterx.betterend.world.features.terrain.caves.CaveChunkPopulatorFeature; import org.betterx.betterend.world.features.terrain.caves.RoundCaveFeature; import org.betterx.betterend.world.features.terrain.caves.TunelCaveFeature; import org.betterx.betterend.world.features.trees.*; import org.betterx.worlds.together.world.event.WorldBootstrap; import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.GenerationStep.Decoration; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.OreFeature; import net.minecraft.world.level.levelgen.feature.RandomPatchFeature; import net.minecraft.world.level.levelgen.feature.configurations.*; import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; import net.minecraft.world.level.levelgen.placement.PlacedFeature; import com.google.common.collect.Lists; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import java.io.InputStream; import java.util.List; public class EndFeatures { public static final StalactiteFeature STALACTITE_FEATURE = inlineBuild( "stalactite_feature", new StalactiteFeature() ); public static final BuildingListFeature BUILDING_LIST_FEATURE = inlineBuild( "building_list_feature", new BuildingListFeature() ); public static final VineFeature VINE_FEATURE = inlineBuild( "vine_feature", new VineFeature() ); public static final WallPlantFeature WALL_PLANT_FEATURE = inlineBuild( "wall_plant_feature", new WallPlantFeature() ); public static final WallPlantOnLogFeature WALL_PLANT_ON_LOG_FEATURE = inlineBuild( "wall_plant_on_log_feature", new WallPlantOnLogFeature() ); public static final GlowPillarFeature GLOW_PILLAR_FEATURE = inlineBuild( "glow_pillar_feature", new GlowPillarFeature() ); public static final HydraluxFeature HYDRALUX_FEATURE = inlineBuild( "hydralux_feature", new HydraluxFeature() ); public static final LanceleafFeature LANCELEAF_FEATURE = inlineBuild( "lanceleaf_feature", new LanceleafFeature() ); public static final MengerSpongeFeature MENGER_SPONGE_FEATURE = inlineBuild( "menger_sponge_feature", new MengerSpongeFeature() ); public static final CaveChunkPopulatorFeature CAVE_CHUNK_POPULATOR = inlineBuild( "cave_chunk_populator", new CaveChunkPopulatorFeature() ); public static final SinglePlantFeature SINGLE_PLANT_FEATURE = inlineBuild( "single_plant_feature", new SinglePlantFeature() ); public static final SingleInvertedScatterFeature SINGLE_INVERTED_SCATTER_FEATURE = inlineBuild( "single_inverted_scatter_feature", new SingleInvertedScatterFeature() ); public static final DoublePlantFeature DOUBLE_PLANT_FEATURE = inlineBuild( "double_plant_feature", new DoublePlantFeature() ); public static final UnderwaterPlantFeature UNDERWATER_PLANT_FEATURE = inlineBuild( "underwater_plant_feature", new UnderwaterPlantFeature() ); public static final ArchFeature ARCH_FEATURE = inlineBuild( "arch_feature", new ArchFeature() ); public static final ThinArchFeature THIN_ARCH_FEATURE = inlineBuild( "thin_arch_feature", new ThinArchFeature() ); public static final CharniaFeature CHARNIA_FEATURE = inlineBuild( "charnia_feature", new CharniaFeature() ); public static final BlueVineFeature BLUE_VINE_FEATURE = inlineBuild( "blue_vine_feature", new BlueVineFeature() ); public static final FilaluxFeature FILALUX_FEATURE = inlineBuild( "filalux_feature", new FilaluxFeature() ); public static final EndLilyFeature END_LILY_FEATURE = inlineBuild( "end_lily_feature", new EndLilyFeature() ); public static final EndLotusFeature END_LOTUS_FEATURE = inlineBuild( "end_lotus_feature", new EndLotusFeature() ); public static final EndLotusLeafFeature END_LOTUS_LEAF_FEATURE = inlineBuild( "end_lotus_leaf_feature", new EndLotusLeafFeature() ); public static final BushFeature BUSH_FEATURE = inlineBuild( "bush_feature", new BushFeature() ); public static final SingleBlockFeature SINGLE_BLOCK_FEATURE = inlineBuild( "single_block_feature", new SingleBlockFeature() ); public static final BushWithOuterFeature BUSH_WITH_OUTER_FEATURE = inlineBuild( "bush_with_outer_feature", new BushWithOuterFeature() ); public static final BCLFeature MOSSY_GLOWSHROOM = registerVegetation( "mossy_glowshroom", inlineBuild("mossy_glowshroom", new MossyGlowshroomFeature()), 2 ); public static final BCLFeature PYTHADENDRON_TREE = registerVegetation( "pythadendron_tree", inlineBuild("pythadendron_tree", new PythadendronTreeFeature()), 1 ); public static final BCLFeature LACUGROVE = registerVegetation( "lacugrove", inlineBuild("lacugrove", new LacugroveFeature()), 4 ); public static final BCLFeature DRAGON_TREE = registerVegetation( "dragon_tree", inlineBuild("dragon_tree", new DragonTreeFeature()), 2 ); public static final BCLFeature TENANEA = registerVegetation( "tenanea", inlineBuild("tenanea", new TenaneaFeature()), 3 ); public static final BCLFeature HELIX_TREE = registerVegetation( "helix_tree", inlineBuild("helix_tree", new HelixTreeFeature()), 1 ); public static final BCLFeature UMBRELLA_TREE = registerVegetation( "umbrella_tree", inlineBuild("umbrella_tree", new UmbrellaTreeFeature()), 2 ); public static final BCLFeature JELLYSHROOM = registerVegetation( "jellyshroom", inlineBuild("jellyshroom", new JellyshroomFeature()), 2 ); public static final BCLFeature GIGANTIC_AMARANITA = registerVegetation( "gigantic_amaranita", inlineBuild("gigantic_amaranita", new GiganticAmaranitaFeature()), 1 ); public static final BCLFeature LUCERNIA = registerVegetation( "lucernia", inlineBuild("lucernia", new LucerniaFeature()), 3 ); // Bushes // public static final BCLFeature PYTHADENDRON_BUSH = registerVegetation( "pythadendron_bush", BUSH_FEATURE, new BushFeatureConfig( EndBlocks.PYTHADENDRON_LEAVES, EndBlocks.PYTHADENDRON.getBark() ), 3 ); public static final BCLFeature DRAGON_TREE_BUSH = registerVegetation( "dragon_tree_bush", BUSH_FEATURE, new BushFeatureConfig( EndBlocks.DRAGON_TREE_LEAVES, EndBlocks.DRAGON_TREE.getBark() ), 5 ); public static final BCLFeature TENANEA_BUSH = registerVegetation( "tenanea_bush", inlineBuild("tenanea_bush", new TenaneaBushFeature()), 12 ); public static final BCLFeature LUMECORN = registerVegetation( "lumecorn", inlineBuild("lumecorn", new Lumecorn()), 5 ); public static final BCLFeature LARGE_AMARANITA = registerVegetation( "large_amaranita", inlineBuild("large_amaranita", new LargeAmaranitaFeature()), 5 ); public static final BCLFeature LUCERNIA_BUSH = registerVegetation( "lucernia_bush", BUSH_WITH_OUTER_FEATURE, new BushWithOuterFeatureConfig( EndBlocks.LUCERNIA_LEAVES, EndBlocks.LUCERNIA_OUTER_LEAVES, EndBlocks.LUCERNIA.getBark() ), 10 ); public static final BCLFeature LUCERNIA_BUSH_RARE = registerVegetation( "lucernia_bush_rare", BUSH_WITH_OUTER_FEATURE, new BushWithOuterFeatureConfig( EndBlocks.LUCERNIA_LEAVES, EndBlocks.LUCERNIA_OUTER_LEAVES, EndBlocks.LUCERNIA.getBark() ), 1 ); public static final BCLFeature NEON_CACTUS = registerVegetation( "neon_cactus", inlineBuild("neon_cactus", new NeonCactusFeature()), 2 ); // Plants // public static final BCLFeature UMBRELLA_MOSS = registerVegetation( "umbrella_moss", new DoublePlantFeatureConfig( EndBlocks.UMBRELLA_MOSS, EndBlocks.UMBRELLA_MOSS_TALL, 5 ), 3 ); public static final BCLFeature CREEPING_MOSS = registerVegetation( "creeping_moss", new SinglePlantFeatureConfig( EndBlocks.CREEPING_MOSS, 5 ), 3 ); public static final BCLFeature BLUE_VINE = registerVegetation( "blue_vine", BLUE_VINE_FEATURE, ScatterFeatureConfig.blueVine(), 1 ); public static final BCLFeature CHORUS_GRASS = registerVegetation( "chorus_grass", new SinglePlantFeatureConfig(EndBlocks.CHORUS_GRASS, 4), 3 ); public static final BCLFeature CRYSTAL_GRASS = registerVegetation( "crystal_grass", new SinglePlantFeatureConfig( EndBlocks.CRYSTAL_GRASS, 8, false ), 5 ); public static final BCLFeature SHADOW_PLANT = registerVegetation( "shadow_plant", new SinglePlantFeatureConfig(EndBlocks.SHADOW_PLANT, 6), 5 ); public static final BCLFeature MURKWEED = registerVegetation( "murkweed", new SinglePlantFeatureConfig(EndBlocks.MURKWEED, 3), 2 ); public static final BCLFeature NEEDLEGRASS = registerVegetation( "needlegrass", new SinglePlantFeatureConfig(EndBlocks.NEEDLEGRASS, 3), 1 ); public static final BCLFeature SHADOW_BERRY = registerVegetation( "shadow_berry", new SinglePlantFeatureConfig(EndBlocks.SHADOW_BERRY, 2), 1 ); public static final BCLFeature BUSHY_GRASS = registerVegetation( "bushy_grass", new SinglePlantFeatureConfig( EndBlocks.BUSHY_GRASS, 8, false ), 10 ); public static final BCLFeature BUSHY_GRASS_WG = registerVegetation( "bushy_grass_wg", new SinglePlantFeatureConfig(EndBlocks.BUSHY_GRASS, 5), 8 ); public static final BCLFeature AMBER_GRASS = registerVegetation( "amber_grass", new SinglePlantFeatureConfig(EndBlocks.AMBER_GRASS, 6), 7 ); public static final BCLFeature LANCELEAF = registerVegetation( "lanceleaf", LANCELEAF_FEATURE, ScatterFeatureConfig.lanceleaf(), 2 ); public static final BCLFeature GLOW_PILLAR = registerVegetation( "glow_pillar", GLOW_PILLAR_FEATURE, ScatterFeatureConfig.glowPillar(), 1 ); public static final BCLFeature TWISTED_UMBRELLA_MOSS = registerVegetation( "twisted_umbrella_moss", new DoublePlantFeatureConfig( EndBlocks.TWISTED_UMBRELLA_MOSS, EndBlocks.TWISTED_UMBRELLA_MOSS_TALL, 6 ), 3 ); public static final BCLFeature JUNGLE_GRASS = registerVegetation( "jungle_grass", new SinglePlantFeatureConfig( EndBlocks.JUNGLE_GRASS, 7, 3 ), 6 ); public static final BCLFeature SMALL_JELLYSHROOM_FLOOR = registerVegetation( "small_jellyshroom_floor", new SinglePlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 5, 5 ), 2 ); public static final BCLFeature BLOSSOM_BERRY = registerVegetation( "blossom_berry", new SinglePlantFeatureConfig( EndBlocks.BLOSSOM_BERRY, 4, 4 ), 3 ); public static final BCLFeature BLOOMING_COOKSONIA = registerVegetation( "blooming_cooksonia", new SinglePlantFeatureConfig( EndBlocks.BLOOMING_COOKSONIA, 5 ), 5 ); public static final BCLFeature SALTEAGO = registerVegetation( "salteago", new SinglePlantFeatureConfig(EndBlocks.SALTEAGO, 5), 5 ); public static final BCLFeature VAIOLUSH_FERN = registerVegetation( "vaiolush_fern", new SinglePlantFeatureConfig( EndBlocks.VAIOLUSH_FERN, 5 ), 5 ); public static final BCLFeature FRACTURN = registerVegetation( "fracturn", new SinglePlantFeatureConfig(EndBlocks.FRACTURN, 5), 5 ); public static final BCLFeature UMBRELLA_MOSS_RARE = registerVegetation( "umbrella_moss_rare", new SinglePlantFeatureConfig( EndBlocks.UMBRELLA_MOSS, 3 ), 2 ); public static final BCLFeature CREEPING_MOSS_RARE = registerVegetation( "creeping_moss_rare", new SinglePlantFeatureConfig( EndBlocks.CREEPING_MOSS, 3 ), 2 ); public static final BCLFeature TWISTED_UMBRELLA_MOSS_RARE = registerVegetation( "twisted_umbrella_moss_rare", new SinglePlantFeatureConfig( EndBlocks.TWISTED_UMBRELLA_MOSS, 3 ), 2 ); public static final BCLFeature ORANGO = registerVegetation( "orango", new SinglePlantFeatureConfig(EndBlocks.ORANGO, 5), 6 ); public static final BCLFeature AERIDIUM = registerVegetation( "aeridium", new SinglePlantFeatureConfig(EndBlocks.AERIDIUM, 5, 4), 5 ); public static final BCLFeature LUTEBUS = registerVegetation( "lutebus", new SinglePlantFeatureConfig(EndBlocks.LUTEBUS, 5, 2), 5 ); public static final BCLFeature LAMELLARIUM = registerVegetation( "lamellarium", new SinglePlantFeatureConfig(EndBlocks.LAMELLARIUM, 5), 6 ); public static final BCLFeature SMALL_AMARANITA = registerVegetation( "small_amaranita", new SinglePlantFeatureConfig( EndBlocks.SMALL_AMARANITA_MUSHROOM, 5, 5 ), 4 ); public static final BCLFeature GLOBULAGUS = registerVegetation( "globulagus", new SinglePlantFeatureConfig(EndBlocks.GLOBULAGUS, 5, 3), 6 ); public static final BCLFeature CLAWFERN = registerVegetation( "clawfern", new SinglePlantFeatureConfig(EndBlocks.CLAWFERN, 5, 4), 5 ); public static final BCLFeature BOLUX_MUSHROOM = registerVegetation( "bolux_mushroom", new SinglePlantFeatureConfig( EndBlocks.BOLUX_MUSHROOM, 5, 5 ), 2 ); public static final BCLFeature CHORUS_MUSHROOM = registerVegetation( "chorus_mushroom", new SinglePlantFeatureConfig( EndBlocks.CHORUS_MUSHROOM, 3, 5 ), 1 ); public static final BCLFeature AMBER_ROOT = registerVegetation( "amber_root", new SinglePlantFeatureConfig(EndBlocks.AMBER_ROOT, 5, 5), 1 ); //public static final BCLFeature PEARLBERRY = redisterVegetation("pearlberry", new SinglePlantFeatureConfig(EndBlocks.PEARLBERRY, 5, 5), 1); public static final BCLFeature INFLEXIA = registerVegetation( "inflexia", new SinglePlantFeatureConfig( EndBlocks.INFLEXIA, 7, false, 3 ), 16 ); public static final BCLFeature FLAMMALIX = registerVegetation( "flammalix", new SinglePlantFeatureConfig( EndBlocks.FLAMMALIX, 3, false, 7 ), 5 ); // Vines // public static final BCLFeature DENSE_VINE = registerVegetation( "dense_vine", VINE_FEATURE, new VineFeatureConfig(EndBlocks.DENSE_VINE, 24), 3 ); public static final BCLFeature TWISTED_VINE = registerVegetation( "twisted_vine", VINE_FEATURE, new VineFeatureConfig(EndBlocks.TWISTED_VINE, 24), 1 ); public static final BCLFeature BULB_VINE = registerVegetation( "bulb_vine", VINE_FEATURE, new VineFeatureConfig(EndBlocks.BULB_VINE, 24), 5 ); public static final BCLFeature JUNGLE_VINE = registerVegetation( "jungle_vine", VINE_FEATURE, new VineFeatureConfig(EndBlocks.JUNGLE_VINE, 24), 5 ); // Ceil plants public static final BCLFeature SMALL_JELLYSHROOM_CEIL = registerVegetation( "small_jellyshroom_ceil", SINGLE_INVERTED_SCATTER_FEATURE, new SinglePlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 8 ), 8 ); // Wall Plants // public static final BCLFeature PURPLE_POLYPORE = registerVegetation( "purple_polypore", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.PURPLE_POLYPORE, 3 ), 5 ); public static final BCLFeature AURANT_POLYPORE = registerVegetation( "aurant_polypore", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.AURANT_POLYPORE, 3 ), 5 ); public static final BCLFeature TAIL_MOSS = registerVegetation( "tail_moss", WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.TAIL_MOSS, 3), 15 ); public static final BCLFeature CYAN_MOSS = registerVegetation( "cyan_moss", WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.CYAN_MOSS, 3), 15 ); public static final BCLFeature TAIL_MOSS_WOOD = registerVegetation( "tail_moss_wood", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.TAIL_MOSS, 4 ), 25 ); public static final BCLFeature CYAN_MOSS_WOOD = registerVegetation( "cyan_moss_wood", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.CYAN_MOSS, 4 ), 25 ); public static final BCLFeature TWISTED_MOSS = registerVegetation( "twisted_moss", WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.TWISTED_MOSS, 6), 15 ); public static final BCLFeature TWISTED_MOSS_WOOD = registerVegetation( "twisted_moss_wood", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.TWISTED_MOSS, 6 ), 25 ); public static final BCLFeature BULB_MOSS = registerVegetation( "bulb_moss", WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.BULB_MOSS, 6), 1 ); public static final BCLFeature BULB_MOSS_WOOD = registerVegetation( "bulb_moss_wood", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.BULB_MOSS, 6 ), 15 ); public static final BCLFeature SMALL_JELLYSHROOM_WALL = registerVegetation( "small_jellyshroom_wall", WALL_PLANT_FEATURE, new WallPlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 4 ), 4 ); public static final BCLFeature SMALL_JELLYSHROOM_WOOD = registerVegetation( "small_jellyshroom_wood", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 4 ), 8 ); public static final BCLFeature JUNGLE_FERN_WOOD = registerVegetation( "jungle_fern_wood", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.JUNGLE_FERN, 3 ), 12 ); public static final BCLFeature RUSCUS = registerVegetation( "ruscus", WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.RUSCUS, 6), 10 ); public static final BCLFeature RUSCUS_WOOD = registerVegetation( "ruscus_wood", WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig(EndBlocks.RUSCUS, 6), 10 ); // Sky plants public static final BCLFeature FILALUX = registerVegetation( "filalux", FILALUX_FEATURE, ScatterFeatureConfig.filalux(), 1 ); // Water // public static final BCLFeature BUBBLE_CORAL = registerVegetation( "bubble_coral", UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( EndBlocks.BUBBLE_CORAL, 6 ), 10 ); public static final BCLFeature BUBBLE_CORAL_RARE = registerVegetation( "bubble_coral_rare", UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( EndBlocks.BUBBLE_CORAL, 3 ), 4 ); public static final BCLFeature END_LILY = registerVegetation( "end_lily", END_LILY_FEATURE, new ScatterFeatureConfig(6), 10 ); public static final BCLFeature END_LILY_RARE = registerVegetation( "end_lily_rare", END_LILY_FEATURE, new ScatterFeatureConfig(3), 4 ); public static final BCLFeature END_LOTUS = registerVegetation( "end_lotus", END_LOTUS_FEATURE, new ScatterFeatureConfig(7), 6 ); public static final BCLFeature END_LOTUS_LEAF = registerVegetation( "end_lotus_leaf", END_LOTUS_LEAF_FEATURE, new ScatterFeatureConfig(20), 4 ); public static final BCLFeature HYDRALUX = registerVegetation( "hydralux", HYDRALUX_FEATURE, new ScatterFeatureConfig(5), 5 ); public static final BCLFeature POND_ANEMONE = registerVegetation( "pond_anemone", UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( EndBlocks.POND_ANEMONE, 6 ), 10 ); public static final BCLFeature CHARNIA_RED = registerVegetation( "charnia_red", CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_RED), 10 ); public static final BCLFeature CHARNIA_PURPLE = registerVegetation( "charnia_purple", CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_PURPLE), 10 ); public static final BCLFeature CHARNIA_CYAN = registerVegetation( "charnia_cyan", CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_CYAN), 10 ); public static final BCLFeature CHARNIA_LIGHT_BLUE = registerVegetation( "charnia_light_blue", CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_LIGHT_BLUE), 10 ); public static final BCLFeature CHARNIA_ORANGE = registerVegetation( "charnia_orange", CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_ORANGE), 10 ); public static final BCLFeature CHARNIA_GREEN = registerVegetation( "charnia_green", CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_GREEN), 10 ); public static final BCLFeature MENGER_SPONGE = registerVegetation( "menger_sponge", MENGER_SPONGE_FEATURE, new ScatterFeatureConfig(5), 1 ); public static final BCLFeature CHARNIA_RED_RARE = registerVegetation( "charnia_red_rare", CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_RED), 2 ); public static final BCLFeature BIOME_ISLAND = BCLFeatureBuilder .start( BetterEnd.makeID("overworld_island"), inlineBuild("overworld_island", new BiomeIslandFeature()) ) .build() .place() .decoration(Decoration.RAW_GENERATION) .build(); public static final BCLFeature FLAMAEA = registerVegetation( "flamaea", new SinglePlantFeatureConfig(EndBlocks.FLAMAEA, 12, false, 5), 20 ); public static final EndLakeFeature END_LAKE_FEATURE = inlineBuild("end_lake", new EndLakeFeature()); // Terrain // public static final BCLFeature END_LAKE = registerLake( "end_lake", END_LAKE_FEATURE, 4 ); public static final BCLFeature END_LAKE_NORMAL = registerLake( "end_lake_normal", END_LAKE_FEATURE, 20 ); public static final BCLFeature END_LAKE_RARE = registerLake( "end_lake_rare", END_LAKE_FEATURE, 40 ); public static final BCLFeature DESERT_LAKE = registerLake( "desert_lake", inlineBuild("desert_lake", new DesertLakeFeature()), 8 ); public static final BCLFeature ROUND_CAVE = registerRawGen( "round_cave", inlineBuild("round_cave", new RoundCaveFeature()), 2 ); public static final BCLFeature SPIRE = registerRawGen( "spire", inlineBuild("spire", new SpireFeature()), 4 ); public static final BCLFeature FLOATING_SPIRE = registerRawGen( "floating_spire", inlineBuild("floating_spire", new FloatingSpireFeature()), 8 ); public static final BCLFeature GEYSER = registerRawGen( "geyser", inlineBuild("geyser", new GeyserFeature()), 8 ); public static final BCLFeature SULPHURIC_LAKE = registerLake( "sulphuric_lake", inlineBuild("sulphuric_lake", new SulphuricLakeFeature()), 8 ); public static final BCLFeature SULPHURIC_CAVE = BCLFeatureBuilder .start( BetterEnd.makeID("sulphuric_cave"), inlineBuild("sulphuric_cave", new SulphuricCaveFeature()) ) .build() .place() .decoration(Decoration.RAW_GENERATION) .count(2) .squarePlacement() .onlyInBiome() .build(); public static final IceStarFeature ICE_STAR_FEATURE = inlineBuild("ice_star", new IceStarFeature()); public static final BCLFeature ICE_STAR = registerRawGen( "ice_star", ICE_STAR_FEATURE, new IceStarFeatureConfig(5, 15, 10, 25), 15 ); public static final BCLFeature ICE_STAR_SMALL = registerRawGen( "ice_star_small", ICE_STAR_FEATURE, new IceStarFeatureConfig(3, 5, 7, 12), 8 ); public static final BCLFeature SURFACE_VENT = registerChanced( "surface_vent", inlineBuild("surface_vent", new SurfaceVentFeature()), 4 ); public static final BCLFeature SULPHUR_HILL = registerChanced( "sulphur_hill", inlineBuild("sulphur_hill", new SulphurHillFeature()), 8 ); public static final BCLFeature OBSIDIAN_PILLAR_BASEMENT = registerChanced( "obsidian_pillar_basement", inlineBuild("obsidian_pillar_basement", new ObsidianPillarBasementFeature()), 8 ); public static final BCLFeature OBSIDIAN_BOULDER = registerChanced( "obsidian_boulder", inlineBuild("obsidian_boulder", new ObsidianBoulderFeature()), 10 ); public static final BCLFeature FALLEN_PILLAR = registerChanced( "fallen_pillar", inlineBuild("fallen_pillar", new FallenPillarFeature()), 20 ); public static final BCLFeature TUNEL_CAVE = BCLFeatureBuilder .start( BetterEnd.makeID("tunel_cave"), inlineBuild("tunel_cave", new TunelCaveFeature()) ).build() .place() .decoration(Decoration.RAW_GENERATION) .count(1) .onlyInBiome() .build(); public static final BCLFeature UMBRALITH_ARCH = registerChanced( "umbralith_arch", ARCH_FEATURE, new ArchFeatureConfig( EndBlocks.UMBRALITH.stone, ArchFeatureConfig.SurfaceFunction.UMBRA_VALLEY ), 10 ); public static final BCLFeature THIN_UMBRALITH_ARCH = registerChanced( "thin_umbralith_arch", THIN_ARCH_FEATURE, new ThinArchFeatureConfig(EndBlocks.UMBRALITH.stone), 15 ); // Ores // public static final BCLFeature THALLASIUM_ORE = registerOre( "thallasium_ore", EndBlocks.THALLASIUM.ore, 24, 8 ); public static final BCLFeature ENDER_ORE = registerOre( "ender_ore", EndBlocks.ENDER_ORE, 12, 4 ); public static final BCLFeature AMBER_ORE = registerOre( "amber_ore", EndBlocks.AMBER_ORE, 60, 6 ); public static final BCLFeature DRAGON_BONE_BLOCK_ORE = registerOre( "dragon_bone_ore", EndBlocks.DRAGON_BONE_BLOCK, 24, 8 ); public static final BCLFeature VIOLECITE_LAYER = registerLayer( "violecite_layer", EndBlocks.VIOLECITE, 15, 16, 128, 8 ); public static final BCLFeature FLAVOLITE_LAYER = registerLayer( "flavolite_layer", EndBlocks.FLAVOLITE, 12, 16, 128, 6 ); // Buildings public static final BCLFeature CRASHED_SHIP = registerChanced( "crashed_ship", inlineBuild("crashed_ship", new CrashedShipFeature()), new NBTFeatureConfig(EndBiome.Config.DEFAULT_MATERIAL.getTopMaterial()), 500 ); // Mobs public static final BCLFeature SILK_MOTH_NEST = registerChanced( "silk_moth_nest", inlineBuild("silk_moth_nest", new SilkMothNestFeature()), 2 ); // Caves public static final BCLConfigureFeature SMARAGDANT_CRYSTAL = BCLFeatureBuilder .start( BetterEnd.makeID("smaragdant_crystal"), inlineBuild("smaragdant_crystal", new SmaragdantCrystalFeature()) ) .build(); public static final BCLConfigureFeature SMARAGDANT_CRYSTAL_SHARD = BCLFeatureBuilder .start(BetterEnd.makeID("smaragdant_crystal_shard"), SINGLE_BLOCK_FEATURE) .configuration(new SimpleBlockConfiguration(SimpleStateProvider.simple(EndBlocks.SMARAGDANT_CRYSTAL_SHARD))) .build(); public static final BCLConfigureFeature BIG_AURORA_CRYSTAL = BCLFeatureBuilder .start( BetterEnd.makeID("big_aurora_crystal"), inlineBuild("big_aurora_crystal", new BigAuroraCrystalFeature()) ) .build(); public static final BCLConfigureFeature CAVE_BUSH = BCLFeatureBuilder .start(BetterEnd.makeID("cave_bush"), BUSH_FEATURE) .configuration(new BushFeatureConfig(EndBlocks.CAVE_BUSH, EndBlocks.CAVE_BUSH)) .build(); public static final BCLConfigureFeature CAVE_GRASS = BCLFeatureBuilder .start(BetterEnd.makeID("cave_grass"), SINGLE_BLOCK_FEATURE) .configuration(new SimpleBlockConfiguration(SimpleStateProvider.simple(EndBlocks.CAVE_GRASS))) .build(); public static final BCLConfigureFeature RUBINEA = BCLFeatureBuilder .start(BetterEnd.makeID("rubinea"), VINE_FEATURE) .configuration(new VineFeatureConfig(EndBlocks.RUBINEA, 8)) .build(); public static final BCLConfigureFeature MAGNULA = BCLFeatureBuilder .start(BetterEnd.makeID("magnula"), VINE_FEATURE) .configuration(new VineFeatureConfig(EndBlocks.MAGNULA, 8)) .build(); public static final BCLConfigureFeature END_STONE_STALACTITE = BCLFeatureBuilder .start(BetterEnd.makeID("end_stone_stalactite"), STALACTITE_FEATURE) .configuration(new StalactiteFeatureConfig(true, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE)) .build(); public static final BCLConfigureFeature END_STONE_STALAGMITE = BCLFeatureBuilder .start(BetterEnd.makeID("end_stone_stalagmite"), STALACTITE_FEATURE) .configuration(new StalactiteFeatureConfig(false, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE)) .build(); public static final BCLConfigureFeature END_STONE_STALACTITE_CAVEMOSS = BCLFeatureBuilder .start(BetterEnd.makeID("end_stone_stalactite_cavemoss"), STALACTITE_FEATURE) .configuration(new StalactiteFeatureConfig( true, EndBlocks.END_STONE_STALACTITE_CAVEMOSS, Blocks.END_STONE, EndBlocks.CAVE_MOSS )) .build(); public static final BCLConfigureFeature END_STONE_STALAGMITE_CAVEMOSS = BCLFeatureBuilder .start(BetterEnd.makeID("end_stone_stalagmite_cavemoss"), STALACTITE_FEATURE) .configuration(new StalactiteFeatureConfig( false, EndBlocks.END_STONE_STALACTITE_CAVEMOSS, EndBlocks.CAVE_MOSS )) .build(); public static final BCLConfigureFeature CAVE_PUMPKIN = BCLFeatureBuilder .start( BetterEnd.makeID("cave_pumpkin"), inlineBuild("cave_pumpkin", new CavePumpkinFeature()) ) .build(); private static final Holder BONEMEAL_END_MOSS_NOT_GLOWING_GRASSLANDS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_end_moss_not_glowing_grasslands")) .add(EndBlocks.CREEPING_MOSS, 10) .add(EndBlocks.UMBRELLA_MOSS, 10) .inlinePlace().build().placedFeature; private static final Holder BONEMEAL_END_MOSS_GLOWING_GRASSLANDS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_end_moss_glowing_grasslands")) .add(EndBlocks.CREEPING_MOSS, 10) .add(EndBlocks.UMBRELLA_MOSS, 10) .add(EndBlocks.BLOOMING_COOKSONIA, 100) .add(EndBlocks.VAIOLUSH_FERN, 100) .add(EndBlocks.FRACTURN, 100) .add(EndBlocks.SALTEAGO, 100) .add(EndBlocks.TWISTED_UMBRELLA_MOSS, 10) .inlinePlace().build().placedFeature; public static final BCLConfigureFeature, ConditionFeatureConfig> BONEMEAL_END_MOSS = BCLFeatureBuilder .start( BetterEnd.makeID("bonemeal_end_moss"), BCLFeature.CONDITION ) .configuration(new ConditionFeatureConfig( InBiome.matchingID(EndBiomes.GLOWING_GRASSLANDS.getID()), BONEMEAL_END_MOSS_GLOWING_GRASSLANDS, BONEMEAL_END_MOSS_NOT_GLOWING_GRASSLANDS )) .build(); private static final Holder BONEMEAL_RUTISCUS_NOT_LANTERN_WOODS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_rutiscus_not_lantern_woods")) .add(EndBlocks.ORANGO, 100) .add(EndBlocks.AERIDIUM, 20) .add(EndBlocks.LUTEBUS, 20) .add(EndBlocks.LAMELLARIUM, 100) .inlinePlace() .build().placedFeature; private static final Holder BONEMEAL_RUTISCUS_LANTERN_WOODS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_rutiscus_lantern_woods")) .add(EndBlocks.AERIDIUM, 20) .add(EndBlocks.BOLUX_MUSHROOM, 5) .add(EndBlocks.LAMELLARIUM, 100) .inlinePlace() .build().placedFeature; public static final BCLConfigureFeature, ConditionFeatureConfig> BONEMEAL_RUTISCUS = BCLFeatureBuilder .start( BetterEnd.makeID("bonemeal_rutiscus"), BCLFeature.CONDITION ) .configuration(new ConditionFeatureConfig( InBiome.matchingID(EndBiomes.LANTERN_WOODS.getID()), BONEMEAL_RUTISCUS_LANTERN_WOODS, BONEMEAL_RUTISCUS_NOT_LANTERN_WOODS )) .build(); public static final BCLConfigureFeature BONEMEAL_END_MYCELIUM = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_end_mycelium")) .add(EndBlocks.CREEPING_MOSS, 100) .add(EndBlocks.UMBRELLA_MOSS, 100) .build(); public static final BCLConfigureFeature BONEMEAL_JUNGLE_MOSS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_jungle_moss")) .add(EndBlocks.JUNGLE_GRASS, 100) .add(EndBlocks.TWISTED_UMBRELLA_MOSS, 100) .add(EndBlocks.SMALL_JELLYSHROOM, 10) .build(); public static final BCLConfigureFeature BONEMEAL_SANGNUM = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_sangnum")) .add(EndBlocks.CLAWFERN, 100) .add(EndBlocks.GLOBULAGUS, 100) .add(EndBlocks.SMALL_AMARANITA_MUSHROOM, 10) .build(); public static final BCLConfigureFeature BONEMEAL_MOSSY_DRAGON_BONE = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_mossy_dragon_bone")) .add(EndBlocks.CLAWFERN, 100) .add(EndBlocks.GLOBULAGUS, 100) .add(EndBlocks.SMALL_AMARANITA_MUSHROOM, 10) .build(); public static final BCLConfigureFeature BONEMEAL_MOSSY_OBSIDIAN = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_mossy_obsidian")) .add(EndBlocks.CLAWFERN, 100) .add(EndBlocks.GLOBULAGUS, 100) .add(EndBlocks.SMALL_AMARANITA_MUSHROOM, 10) .build(); public static final BCLConfigureFeature BONEMEAL_CAVE_MOSS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_cave_moss")) .add(EndBlocks.CAVE_GRASS, 100) .build(); public static final BCLConfigureFeature BONEMEAL_CHORUS_NYLIUM = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_chorus_nylium")) .add(EndBlocks.CHORUS_GRASS, 100) .build(); public static final BCLConfigureFeature BONEMEAL_CRYSTAL_MOSS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_crystal_moss")) .add(EndBlocks.CRYSTAL_GRASS, 100) .build(); public static final BCLConfigureFeature BONEMEAL_SHADOW_GRASS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_shadow_grass")) .add(EndBlocks.SHADOW_PLANT, 100) .build(); public static final BCLConfigureFeature BONEMEAL_PINK_MOSS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_pink_moss")) .add(EndBlocks.BUSHY_GRASS, 100) .build(); public static final BCLConfigureFeature BONEMEAL_AMBER_MOSS = BCLFeatureBuilder .startBonemealPatch(BetterEnd.makeID("bonemeal_amber_moss")) .add(EndBlocks.AMBER_GRASS, 100) .build(); public static , FC extends FeatureConfiguration> F inlineBuild(String name, F feature) { ResourceLocation l = BetterEnd.makeID(name); if (WorldBootstrap.getLastRegistryAccess() != null) { Registry> features = WorldBootstrap.getLastRegistryAccess().registryOrThrow(Registries.FEATURE); if (features.containsKey(l)) { return (F) features.get(l); } } return BCLFeature.register(l, feature); } private static BCLFeature registerVegetation( String name, DoublePlantFeatureConfig config, int density ) { return registerVegetation(name, DOUBLE_PLANT_FEATURE, config, density); } private static BCLFeature registerVegetation( String name, SinglePlantFeatureConfig config, int density ) { return registerVegetation(name, SINGLE_PLANT_FEATURE, config, density); } private static > BCLFeature registerVegetation( String name, F feature, int density ) { return registerVegetation(name, feature, NoneFeatureConfiguration.NONE, density); } private static , FC extends FeatureConfiguration> BCLFeature registerVegetation( String name, F feature, FC config, int density ) { ResourceLocation id = BetterEnd.makeID(name); return BCLFeatureBuilder.start(id, feature) .configuration(config) .build() .place() .onEveryLayerMax(density) .onlyInBiome() .build(); } private static > BCLFeature registerRawGen( String name, F feature, int chance ) { return registerRawGen(name, feature, FeatureConfiguration.NONE, chance); } private static , FC extends FeatureConfiguration> BCLFeature registerRawGen( String name, F feature, FC config, int chance ) { return BCLFeatureBuilder .start(BetterEnd.makeID(name), feature) .configuration(config) .build() .place() .decoration(Decoration.RAW_GENERATION) .onceEvery(chance) .squarePlacement() .onlyInBiome() .build(); } private static > BCLFeature registerLake( String name, F feature, int chance ) { return BCLFeatureBuilder .start(BetterEnd.makeID(name), feature) .build() .place() .decoration(Decoration.LAKES) .onceEvery(chance) .squarePlacement() .onlyInBiome() .build(); } private static > BCLFeature registerChanced( String name, F feature, int chance ) { return registerChanced(name, feature, FeatureConfiguration.NONE, chance); } private static , FC extends FeatureConfiguration> BCLFeature registerChanced( String name, F feature, FC config, int chance ) { return BCLFeatureBuilder .start(BetterEnd.makeID(name), feature) .configuration(config) .build() .place() .decoration(Decoration.SURFACE_STRUCTURES) .onceEvery(chance) .squarePlacement() .onlyInBiome() .build(); } private static BCLFeature registerOre( String name, Block blockOre, int veins, int veinSize ) { return BCLFeatureBuilder .startOre(BetterEnd.makeID(name)) .add(Blocks.END_STONE, blockOre) .veinSize(veinSize) .discardChanceOnAirExposure(0) .build() .place() .decoration(Decoration.UNDERGROUND_ORES) .count(veins) .randomHeight8FromFloorCeil() .squarePlacement() .onlyInBiome() .build(); } private static BCLFeature registerLayer( String name, Block block, float radius, int minY, int maxY, int count ) { OreLayerFeature layer = inlineBuild("ore_layer", new OreLayerFeature()); return BCLFeatureBuilder .start(BetterEnd.makeID(name), layer) .configuration(new OreLayerFeatureConfig(block.defaultBlockState(), radius, minY, maxY)) .build() .place() .decoration(GenerationStep.Decoration.UNDERGROUND_ORES) .count(count) .build(); } private static BCLFeature registerLayer( String name, StoneMaterial material, float radius, int minY, int maxY, int count ) { return registerLayer(name, material.stone, radius, minY, maxY, count); } public static void addBiomeFeatures(ResourceLocation id, Holder biome) { if (!BetterEnd.MOD_ID.equals(id.getNamespace())) { BiomeAPI.addBiomeFeature(biome, FLAVOLITE_LAYER); BiomeAPI.addBiomeFeature(biome, THALLASIUM_ORE); BiomeAPI.addBiomeFeature(biome, ENDER_ORE); BiomeAPI.addBiomeFeature(biome, CRASHED_SHIP); BCLBiome bclbiome = BiomeAPI.getBiome(id); BCLFeature feature = getBiomeStructures(bclbiome); if (feature != null) { BiomeAPI.addBiomeFeature(biome, feature); } boolean hasCaves = !(bclbiome instanceof EndCaveBiome); if (!(bclbiome instanceof EndCaveBiome) && bclbiome instanceof EndBiome endBiome) { hasCaves = endBiome.hasCaves(); } if (hasCaves && !BiomeAPI.wasRegisteredAsEndVoidBiome(id) /*!BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(id)*/) { if (Configs.BIOME_CONFIG.getBoolean(id, "hasCaves", true)) { BiomeAPI.addBiomeFeature(biome, ROUND_CAVE); BiomeAPI.addBiomeFeature(biome, TUNEL_CAVE); } } } } private static BCLFeature getBiomeStructures(BCLBiome biome) { return getBiomeStructures(biome.getID()); } private static BCLFeature getBiomeStructures(ResourceLocation loc) { String ns = loc.getNamespace(); String nm = loc.getPath(); return getBiomeStructures(ns, nm); } private static BCLFeature getBiomeStructures(String ns, String nm) { ResourceLocation id = new ResourceLocation(ns, nm + "_structures"); if (WorldBootstrap.getLastRegistryAccess() != null) { Registry features = WorldBootstrap.getLastRegistryAccess() .registryOrThrow(Registries.PLACED_FEATURE); if (features.containsKey(id)) { BCLib.LOGGER.info("Feature for " + id + " was already build"); } } String path = "/data/" + ns + "/structures/biome/" + nm + "/"; InputStream inputstream = EndFeatures.class.getResourceAsStream(path + "structures.json"); if (inputstream != null) { JsonObject obj = JsonFactory.getJsonObject(inputstream); JsonArray structures = obj.getAsJsonArray("structures"); if (structures != null) { List list = Lists.newArrayList(); structures.forEach((entry) -> { JsonObject e = entry.getAsJsonObject(); String structure = path + e.get("nbt").getAsString() + ".nbt"; NBTFeature.TerrainMerge terrainMerge = NBTFeature.TerrainMerge.getFromString(e .get("terrainMerge") .getAsString()); int offsetY = e.get("offsetY").getAsInt(); list.add(new BuildingListFeature.StructureInfo(structure, offsetY, terrainMerge)); }); if (!list.isEmpty()) { return BCLFeatureBuilder.start( new ResourceLocation(ns, nm + "_structures"), BUILDING_LIST_FEATURE ) .configuration(new BuildingListFeatureConfig( list, Blocks.END_STONE.defaultBlockState() )) .build() .place() .decoration(Decoration.SURFACE_STRUCTURES) .onceEvery(10) .squarePlacement() .onlyInBiome() .build(); } } } return null; } public static BCLBiomeBuilder addDefaultFeatures( ResourceLocation biomeID, BCLBiomeBuilder builder, boolean hasCaves ) { builder.feature(FLAVOLITE_LAYER); builder.feature(THALLASIUM_ORE); builder.feature(ENDER_ORE); builder.feature(CRASHED_SHIP); BCLFeature feature = getBiomeStructures(biomeID); if (feature != null) { builder.feature(feature); } if (hasCaves) { builder.feature(ROUND_CAVE); builder.feature(TUNEL_CAVE); } return builder; } public static void register() { } }