From 5c3a9986bc7b1dbdec2a9024640a2efdadb6a6de Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 1 Jul 2022 16:54:17 +0200 Subject: [PATCH] Migrated Feature Code to new BCLib API --- .../integration/byg/features/BYGFeatures.java | 65 +- .../betterend/registry/EndFeatures.java | 712 +++++++++++++----- .../world/biome/cave/EndCaveBiome.java | 9 +- .../world/biome/cave/LushAuroraCaveBiome.java | 4 +- .../world/features/BlueVineFeature.java | 10 +- .../world/features/BuildingListFeature.java | 86 ++- .../features/BuildingListFeatureConfig.java | 31 + .../world/features/CharniaFeature.java | 6 - .../world/features/CrashedShipFeature.java | 20 +- .../world/features/DoublePlantFeature.java | 30 +- .../features/DoublePlantFeatureConfig.java | 44 ++ .../world/features/EndLilyFeature.java | 8 +- .../world/features/EndLotusFeature.java | 8 +- .../world/features/EndLotusLeafFeature.java | 14 +- .../world/features/FilaluxFeature.java | 6 +- .../world/features/GlowPillarFeature.java | 12 +- .../world/features/HydraluxFeature.java | 8 +- .../features/InvertedScatterFeature.java | 24 +- .../world/features/LanceleafFeature.java | 10 +- .../betterend/world/features/ListFeature.java | 86 --- .../world/features/MengerSpongeFeature.java | 8 +- .../betterend/world/features/NBTFeature.java | 53 +- .../world/features/NBTFeatureConfig.java | 20 + .../world/features/ScatterFeature.java | 36 +- .../world/features/ScatterFeatureConfig.java | 35 + .../SingleInvertedScatterFeature.java | 22 +- .../world/features/SinglePlantFeature.java | 56 +- .../features/SinglePlantFeatureConfig.java | 59 ++ .../world/features/SkyScatterFeature.java | 11 +- .../features/UnderwaterPlantFeature.java | 21 +- .../features/UnderwaterPlantScatter.java | 14 +- .../betterend/world/features/VineFeature.java | 41 +- .../world/features/VineFeatureConfig.java | 42 ++ .../world/features/WallPlantFeature.java | 41 +- .../features/WallPlantFeatureConfig.java | 39 + .../world/features/WallPlantOnLogFeature.java | 14 +- .../world/features/WallScatterFeature.java | 28 +- .../world/features/terrain/ArchFeature.java | 50 +- .../features/terrain/ArchFeatureConfig.java | 58 ++ .../features/terrain/OreLayerFeature.java | 33 +- .../terrain/OreLayerFeatureConfig.java | 39 + .../features/terrain/ThinArchFeature.java | 17 +- .../terrain/ThinArchFeatureConfig.java | 28 + .../caves/CaveChunkPopulatorFeature.java | 15 +- .../CaveChunkPopulatorFeatureConfig.java | 19 + 45 files changed, 1363 insertions(+), 629 deletions(-) create mode 100644 src/main/java/org/betterx/betterend/world/features/BuildingListFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/DoublePlantFeatureConfig.java delete mode 100644 src/main/java/org/betterx/betterend/world/features/ListFeature.java create mode 100644 src/main/java/org/betterx/betterend/world/features/NBTFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/ScatterFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/SinglePlantFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/VineFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/WallPlantFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/terrain/ArchFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeatureConfig.java create mode 100644 src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeatureConfig.java diff --git a/src/main/java/org/betterx/betterend/integration/byg/features/BYGFeatures.java b/src/main/java/org/betterx/betterend/integration/byg/features/BYGFeatures.java index 9b79dd26..e2f230bd 100644 --- a/src/main/java/org/betterx/betterend/integration/byg/features/BYGFeatures.java +++ b/src/main/java/org/betterx/betterend/integration/byg/features/BYGFeatures.java @@ -5,66 +5,89 @@ import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder; import org.betterx.betterend.BetterEnd; import org.betterx.betterend.integration.Integrations; import org.betterx.betterend.integration.byg.BYGBlocks; -import org.betterx.betterend.world.features.SinglePlantFeature; -import org.betterx.betterend.world.features.VineFeature; -import org.betterx.betterend.world.features.WallPlantFeature; -import org.betterx.betterend.world.features.WallPlantOnLogFeature; +import org.betterx.betterend.registry.EndFeatures; +import org.betterx.betterend.world.features.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; public class BYGFeatures { - public static final BCLFeature OLD_BULBIS_TREE = redisterVegetation( + public static final BCLFeature OLD_BULBIS_TREE = redisterVegetation( "old_bulbis_tree", - new OldBulbisTreeFeature(), + EndFeatures.inlineBuild("old_bulbis_tree_feature", new OldBulbisTreeFeature()), 1 ); - public static final BCLFeature IVIS_SPROUT = redisterVegetation( + public static final BCLFeature IVIS_SPROUT = redisterVegetation( "ivis_sprout", - new SinglePlantFeature(Integrations.BYG.getBlock("ivis_sprout"), 6, 2), + EndFeatures.SINGLE_PLANT_FEATURE, + new SinglePlantFeatureConfig(Integrations.BYG.getBlock("ivis_sprout"), 6, 2), 6 ); - public static final BCLFeature IVIS_VINE = redisterVegetation( + public static final BCLFeature IVIS_VINE = redisterVegetation( "ivis_vine", - new VineFeature(BYGBlocks.IVIS_VINE, 24), + EndFeatures.VINE_FEATURE, + new VineFeatureConfig(BYGBlocks.IVIS_VINE, 24), 5 ); - public static final BCLFeature IVIS_MOSS = redisterVegetation( + public static final BCLFeature IVIS_MOSS = redisterVegetation( "ivis_moss", - new WallPlantFeature(BYGBlocks.IVIS_MOSS, 6), + EndFeatures.WALL_PLANT_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.IVIS_MOSS, 6), 1 ); - public static final BCLFeature IVIS_MOSS_WOOD = redisterVegetation( + public static final BCLFeature IVIS_MOSS_WOOD = redisterVegetation( "ivis_moss_wood", - new WallPlantOnLogFeature(BYGBlocks.IVIS_MOSS, 6), + EndFeatures.WALL_PLANT_ON_LOG_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.IVIS_MOSS, 6), 15 ); - public static final BCLFeature NIGHTSHADE_MOSS = redisterVegetation( + public static final BCLFeature NIGHTSHADE_MOSS = redisterVegetation( "nightshade_moss", - new WallPlantFeature(BYGBlocks.NIGHTSHADE_MOSS, 5), + EndFeatures.WALL_PLANT_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.NIGHTSHADE_MOSS, 5), 2 ); - public static final BCLFeature NIGHTSHADE_MOSS_WOOD = redisterVegetation( + public static final BCLFeature NIGHTSHADE_MOSS_WOOD = redisterVegetation( "nightshade_moss_wood", - new WallPlantOnLogFeature(BYGBlocks.NIGHTSHADE_MOSS, 5), + EndFeatures.WALL_PLANT_ON_LOG_FEATURE, + new WallPlantFeatureConfig(BYGBlocks.NIGHTSHADE_MOSS, 5), 8 ); - public static final BCLFeature NIGHTSHADE_REDWOOD_TREE = redisterVegetation( + public static final BCLFeature NIGHTSHADE_REDWOOD_TREE = redisterVegetation( "nightshade_redwood_tree", new NightshadeRedwoodTreeFeature(), 1 ); - public static final BCLFeature BIG_ETHER_TREE = redisterVegetation("big_ether_tree", new BigEtherTreeFeature(), 1); + public static final BCLFeature BIG_ETHER_TREE = redisterVegetation( + "big_ether_tree", + new BigEtherTreeFeature(), + 1 + ); public static void register() { } - private static BCLFeature redisterVegetation(String name, Feature feature, int density) { + private static > BCLFeature redisterVegetation( + String name, + F feature, + int density + ) { + return redisterVegetation(name, feature, NoneFeatureConfiguration.NONE, density); + } + + private static , FC extends FeatureConfiguration> BCLFeature redisterVegetation( + String name, + F feature, + FC config, + int density + ) { ResourceLocation id = BetterEnd.makeID(name); return BCLFeatureBuilder .start(id, feature) + .configuration(config) .buildAndRegister() .place() .countMax(density) diff --git a/src/main/java/org/betterx/betterend/registry/EndFeatures.java b/src/main/java/org/betterx/betterend/registry/EndFeatures.java index 7b6bbbb9..d08bec6c 100644 --- a/src/main/java/org/betterx/betterend/registry/EndFeatures.java +++ b/src/main/java/org/betterx/betterend/registry/EndFeatures.java @@ -4,17 +4,19 @@ 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.v2.levelgen.features.features.DefaultFeature; +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.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.biome.land.UmbraValleyBiome; 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.*; @@ -29,9 +31,11 @@ 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.configurations.FeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; import net.minecraft.world.level.levelgen.placement.CountPlacement; -import net.minecraft.world.level.levelgen.placement.PlacedFeature; import com.google.common.collect.Lists; import com.google.gson.JsonArray; @@ -41,7 +45,105 @@ import java.io.InputStream; import java.util.List; public class EndFeatures { - // Trees // + 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 BCLFeature MOSSY_GLOWSHROOM = registerVegetation( "mossy_glowshroom", new MossyGlowshroomFeature(), @@ -150,235 +252,246 @@ public class EndFeatures { ); // Plants // - public static final BCLFeature UMBRELLA_MOSS = registerVegetation( + public static final BCLFeature UMBRELLA_MOSS = registerVegetation( "umbrella_moss", - new DoublePlantFeature( + new DoublePlantFeatureConfig( EndBlocks.UMBRELLA_MOSS, EndBlocks.UMBRELLA_MOSS_TALL, 5 ), 3 ); - public static final BCLFeature CREEPING_MOSS = registerVegetation( + public static final BCLFeature CREEPING_MOSS = registerVegetation( "creeping_moss", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.CREEPING_MOSS, 5 ), 3 ); - public static final BCLFeature BLUE_VINE = registerVegetation( + public static final BCLFeature BLUE_VINE = registerVegetation( "blue_vine", - new BlueVineFeature(), + BLUE_VINE_FEATURE, + ScatterFeatureConfig.blueVine(), 1 ); - public static final BCLFeature CHORUS_GRASS = registerVegetation( + public static final BCLFeature CHORUS_GRASS = registerVegetation( "chorus_grass", - new SinglePlantFeature(EndBlocks.CHORUS_GRASS, 4), + new SinglePlantFeatureConfig(EndBlocks.CHORUS_GRASS, 4), 3 ); - public static final BCLFeature CRYSTAL_GRASS = registerVegetation( + public static final BCLFeature CRYSTAL_GRASS = registerVegetation( "crystal_grass", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.CRYSTAL_GRASS, 8, false ), 5 ); - public static final BCLFeature SHADOW_PLANT = registerVegetation( + public static final BCLFeature SHADOW_PLANT = registerVegetation( "shadow_plant", - new SinglePlantFeature(EndBlocks.SHADOW_PLANT, 6), + new SinglePlantFeatureConfig(EndBlocks.SHADOW_PLANT, 6), 5 ); - public static final BCLFeature MURKWEED = registerVegetation( + public static final BCLFeature MURKWEED = registerVegetation( "murkweed", - new SinglePlantFeature(EndBlocks.MURKWEED, 3), + new SinglePlantFeatureConfig(EndBlocks.MURKWEED, 3), 2 ); - public static final BCLFeature NEEDLEGRASS = registerVegetation( + public static final BCLFeature NEEDLEGRASS = registerVegetation( "needlegrass", - new SinglePlantFeature(EndBlocks.NEEDLEGRASS, 3), + new SinglePlantFeatureConfig(EndBlocks.NEEDLEGRASS, 3), 1 ); - public static final BCLFeature SHADOW_BERRY = registerVegetation( + public static final BCLFeature SHADOW_BERRY = registerVegetation( "shadow_berry", - new SinglePlantFeature(EndBlocks.SHADOW_BERRY, 2), + new SinglePlantFeatureConfig(EndBlocks.SHADOW_BERRY, 2), 1 ); - public static final BCLFeature BUSHY_GRASS = registerVegetation( + public static final BCLFeature BUSHY_GRASS = registerVegetation( "bushy_grass", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.BUSHY_GRASS, 8, false ), 10 ); - public static final BCLFeature BUSHY_GRASS_WG = registerVegetation( + public static final BCLFeature BUSHY_GRASS_WG = registerVegetation( "bushy_grass_wg", - new SinglePlantFeature(EndBlocks.BUSHY_GRASS, 5), + new SinglePlantFeatureConfig(EndBlocks.BUSHY_GRASS, 5), 8 ); - public static final BCLFeature AMBER_GRASS = registerVegetation( + public static final BCLFeature AMBER_GRASS = registerVegetation( "amber_grass", - new SinglePlantFeature(EndBlocks.AMBER_GRASS, 6), + new SinglePlantFeatureConfig(EndBlocks.AMBER_GRASS, 6), 7 ); - public static final BCLFeature LANCELEAF = registerVegetation("lanceleaf", new LanceleafFeature(), 2); - public static final BCLFeature GLOW_PILLAR = registerVegetation("glow_pillar", new GlowPillarFeature(), 1); - public static final BCLFeature TWISTED_UMBRELLA_MOSS = registerVegetation( + 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 DoublePlantFeature( + new DoublePlantFeatureConfig( EndBlocks.TWISTED_UMBRELLA_MOSS, EndBlocks.TWISTED_UMBRELLA_MOSS_TALL, 6 ), 3 ); - public static final BCLFeature JUNGLE_GRASS = registerVegetation( + public static final BCLFeature JUNGLE_GRASS = registerVegetation( "jungle_grass", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.JUNGLE_GRASS, 7, 3 ), 6 ); - public static final BCLFeature SMALL_JELLYSHROOM_FLOOR = registerVegetation( + public static final BCLFeature SMALL_JELLYSHROOM_FLOOR = registerVegetation( "small_jellyshroom_floor", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 5, 5 ), 2 ); - public static final BCLFeature BLOSSOM_BERRY = registerVegetation( + public static final BCLFeature BLOSSOM_BERRY = registerVegetation( "blossom_berry", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.BLOSSOM_BERRY, 3, 3 ), 2 ); - public static final BCLFeature BLOOMING_COOKSONIA = registerVegetation( + public static final BCLFeature BLOOMING_COOKSONIA = registerVegetation( "blooming_cooksonia", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.BLOOMING_COOKSONIA, 5 ), 5 ); - public static final BCLFeature SALTEAGO = registerVegetation( + public static final BCLFeature SALTEAGO = registerVegetation( "salteago", - new SinglePlantFeature(EndBlocks.SALTEAGO, 5), + new SinglePlantFeatureConfig(EndBlocks.SALTEAGO, 5), 5 ); - public static final BCLFeature VAIOLUSH_FERN = registerVegetation( + public static final BCLFeature VAIOLUSH_FERN = registerVegetation( "vaiolush_fern", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.VAIOLUSH_FERN, 5 ), 5 ); - public static final BCLFeature FRACTURN = registerVegetation( + public static final BCLFeature FRACTURN = registerVegetation( "fracturn", - new SinglePlantFeature(EndBlocks.FRACTURN, 5), + new SinglePlantFeatureConfig(EndBlocks.FRACTURN, 5), 5 ); - public static final BCLFeature UMBRELLA_MOSS_RARE = registerVegetation( + public static final BCLFeature UMBRELLA_MOSS_RARE = registerVegetation( "umbrella_moss_rare", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.UMBRELLA_MOSS, 3 ), 2 ); - public static final BCLFeature CREEPING_MOSS_RARE = registerVegetation( + public static final BCLFeature CREEPING_MOSS_RARE = registerVegetation( "creeping_moss_rare", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.CREEPING_MOSS, 3 ), 2 ); - public static final BCLFeature TWISTED_UMBRELLA_MOSS_RARE = registerVegetation( + public static final BCLFeature TWISTED_UMBRELLA_MOSS_RARE = registerVegetation( "twisted_umbrella_moss_rare", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.TWISTED_UMBRELLA_MOSS, 3 ), 2 ); - public static final BCLFeature ORANGO = registerVegetation( + public static final BCLFeature ORANGO = registerVegetation( "orango", - new SinglePlantFeature(EndBlocks.ORANGO, 5), + new SinglePlantFeatureConfig(EndBlocks.ORANGO, 5), 6 ); - public static final BCLFeature AERIDIUM = registerVegetation( + public static final BCLFeature AERIDIUM = registerVegetation( "aeridium", - new SinglePlantFeature(EndBlocks.AERIDIUM, 5, 4), + new SinglePlantFeatureConfig(EndBlocks.AERIDIUM, 5, 4), 5 ); - public static final BCLFeature LUTEBUS = registerVegetation( + public static final BCLFeature LUTEBUS = registerVegetation( "lutebus", - new SinglePlantFeature(EndBlocks.LUTEBUS, 5, 2), + new SinglePlantFeatureConfig(EndBlocks.LUTEBUS, 5, 2), 5 ); - public static final BCLFeature LAMELLARIUM = registerVegetation( + public static final BCLFeature LAMELLARIUM = registerVegetation( "lamellarium", - new SinglePlantFeature(EndBlocks.LAMELLARIUM, 5), + new SinglePlantFeatureConfig(EndBlocks.LAMELLARIUM, 5), 6 ); - public static final BCLFeature SMALL_AMARANITA = registerVegetation( + public static final BCLFeature SMALL_AMARANITA = registerVegetation( "small_amaranita", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.SMALL_AMARANITA_MUSHROOM, 5, 5 ), 4 ); - public static final BCLFeature GLOBULAGUS = registerVegetation( + public static final BCLFeature GLOBULAGUS = registerVegetation( "globulagus", - new SinglePlantFeature(EndBlocks.GLOBULAGUS, 5, 3), + new SinglePlantFeatureConfig(EndBlocks.GLOBULAGUS, 5, 3), 6 ); - public static final BCLFeature CLAWFERN = registerVegetation( + public static final BCLFeature CLAWFERN = registerVegetation( "clawfern", - new SinglePlantFeature(EndBlocks.CLAWFERN, 5, 4), + new SinglePlantFeatureConfig(EndBlocks.CLAWFERN, 5, 4), 5 ); - public static final BCLFeature BOLUX_MUSHROOM = registerVegetation( + public static final BCLFeature BOLUX_MUSHROOM = registerVegetation( "bolux_mushroom", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.BOLUX_MUSHROOM, 5, 5 ), 2 ); - public static final BCLFeature CHORUS_MUSHROOM = registerVegetation( + public static final BCLFeature CHORUS_MUSHROOM = registerVegetation( "chorus_mushroom", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.CHORUS_MUSHROOM, 3, 5 ), 1 ); - public static final BCLFeature AMBER_ROOT = registerVegetation( + public static final BCLFeature AMBER_ROOT = registerVegetation( "amber_root", - new SinglePlantFeature(EndBlocks.AMBER_ROOT, 5, 5), + new SinglePlantFeatureConfig(EndBlocks.AMBER_ROOT, 5, 5), 1 ); - //public static final BCLFeature PEARLBERRY = redisterVegetation("pearlberry", new SinglePlantFeature(EndBlocks.PEARLBERRY, 5, 5), 1); - public static final BCLFeature INFLEXIA = registerVegetation( + //public static final BCLFeature PEARLBERRY = redisterVegetation("pearlberry", new SinglePlantFeatureConfig(EndBlocks.PEARLBERRY, 5, 5), 1); + public static final BCLFeature INFLEXIA = registerVegetation( "inflexia", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.INFLEXIA, 7, false, @@ -386,9 +499,9 @@ public class EndFeatures { ), 16 ); - public static final BCLFeature FLAMMALIX = registerVegetation( + public static final BCLFeature FLAMMALIX = registerVegetation( "flammalix", - new SinglePlantFeature( + new SinglePlantFeatureConfig( EndBlocks.FLAMMALIX, 3, false, @@ -398,31 +511,31 @@ public class EndFeatures { ); // Vines // - public static final BCLFeature DENSE_VINE = registerVegetation( + public static final BCLFeature DENSE_VINE = registerVegetation( "dense_vine", - new VineFeature(EndBlocks.DENSE_VINE, 24), + VINE_FEATURE, new VineFeatureConfig(EndBlocks.DENSE_VINE, 24), 3 ); - public static final BCLFeature TWISTED_VINE = registerVegetation( + public static final BCLFeature TWISTED_VINE = registerVegetation( "twisted_vine", - new VineFeature(EndBlocks.TWISTED_VINE, 24), + VINE_FEATURE, new VineFeatureConfig(EndBlocks.TWISTED_VINE, 24), 1 ); - public static final BCLFeature BULB_VINE = registerVegetation( + public static final BCLFeature BULB_VINE = registerVegetation( "bulb_vine", - new VineFeature(EndBlocks.BULB_VINE, 24), + VINE_FEATURE, new VineFeatureConfig(EndBlocks.BULB_VINE, 24), 3 ); - public static final BCLFeature JUNGLE_VINE = registerVegetation( + public static final BCLFeature JUNGLE_VINE = registerVegetation( "jungle_vine", - new VineFeature(EndBlocks.JUNGLE_VINE, 24), + VINE_FEATURE, new VineFeatureConfig(EndBlocks.JUNGLE_VINE, 24), 5 ); // Ceil plants - public static final BCLFeature SMALL_JELLYSHROOM_CEIL = registerVegetation( + public static final BCLFeature SMALL_JELLYSHROOM_CEIL = registerVegetation( "small_jellyshroom_ceil", - new SingleInvertedScatterFeature( + SINGLE_INVERTED_SCATTER_FEATURE, new SinglePlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 8 ), @@ -430,208 +543,279 @@ public class EndFeatures { ); // Wall Plants // - public static final BCLFeature PURPLE_POLYPORE = registerVegetation( + public static final BCLFeature PURPLE_POLYPORE = registerVegetation( "purple_polypore", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.PURPLE_POLYPORE, 3 ), 5 ); - public static final BCLFeature AURANT_POLYPORE = registerVegetation( + public static final BCLFeature AURANT_POLYPORE = registerVegetation( "aurant_polypore", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.AURANT_POLYPORE, 3 ), 5 ); - public static final BCLFeature TAIL_MOSS = registerVegetation( + public static final BCLFeature TAIL_MOSS = registerVegetation( "tail_moss", - new WallPlantFeature(EndBlocks.TAIL_MOSS, 3), + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.TAIL_MOSS, 3), 15 ); - public static final BCLFeature CYAN_MOSS = registerVegetation( + public static final BCLFeature CYAN_MOSS = registerVegetation( "cyan_moss", - new WallPlantFeature(EndBlocks.CYAN_MOSS, 3), + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.CYAN_MOSS, 3), 15 ); - public static final BCLFeature TAIL_MOSS_WOOD = registerVegetation( + public static final BCLFeature TAIL_MOSS_WOOD = registerVegetation( "tail_moss_wood", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.TAIL_MOSS, 4 ), 25 ); - public static final BCLFeature CYAN_MOSS_WOOD = registerVegetation( + public static final BCLFeature CYAN_MOSS_WOOD = registerVegetation( "cyan_moss_wood", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.CYAN_MOSS, 4 ), 25 ); - public static final BCLFeature TWISTED_MOSS = registerVegetation( + public static final BCLFeature TWISTED_MOSS = registerVegetation( "twisted_moss", - new WallPlantFeature(EndBlocks.TWISTED_MOSS, 6), + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.TWISTED_MOSS, 6), 15 ); - public static final BCLFeature TWISTED_MOSS_WOOD = registerVegetation( + public static final BCLFeature TWISTED_MOSS_WOOD = registerVegetation( "twisted_moss_wood", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.TWISTED_MOSS, 6 ), 25 ); - public static final BCLFeature BULB_MOSS = registerVegetation( + public static final BCLFeature BULB_MOSS = registerVegetation( "bulb_moss", - new WallPlantFeature(EndBlocks.BULB_MOSS, 6), + WALL_PLANT_FEATURE, new WallPlantFeatureConfig(EndBlocks.BULB_MOSS, 6), 1 ); - public static final BCLFeature BULB_MOSS_WOOD = registerVegetation( + public static final BCLFeature BULB_MOSS_WOOD = registerVegetation( "bulb_moss_wood", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.BULB_MOSS, 6 ), 15 ); - public static final BCLFeature SMALL_JELLYSHROOM_WALL = registerVegetation( + public static final BCLFeature SMALL_JELLYSHROOM_WALL = registerVegetation( "small_jellyshroom_wall", - new WallPlantFeature( + WALL_PLANT_FEATURE, new WallPlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 4 ), 4 ); - public static final BCLFeature SMALL_JELLYSHROOM_WOOD = registerVegetation( + public static final BCLFeature SMALL_JELLYSHROOM_WOOD = registerVegetation( "small_jellyshroom_wood", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.SMALL_JELLYSHROOM, 4 ), 8 ); - public static final BCLFeature JUNGLE_FERN_WOOD = registerVegetation( + public static final BCLFeature JUNGLE_FERN_WOOD = registerVegetation( "jungle_fern_wood", - new WallPlantOnLogFeature( + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig( EndBlocks.JUNGLE_FERN, 3 ), 12 ); - public static final BCLFeature RUSCUS = registerVegetation("ruscus", new WallPlantFeature(EndBlocks.RUSCUS, 6), 10); - public static final BCLFeature RUSCUS_WOOD = registerVegetation( + 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", - new WallPlantOnLogFeature(EndBlocks.RUSCUS, 6), + WALL_PLANT_ON_LOG_FEATURE, new WallPlantFeatureConfig(EndBlocks.RUSCUS, 6), 10 ); // Sky plants - public static final BCLFeature FILALUX = registerVegetation("filalux", new FilaluxFeature(), 1); + public static final BCLFeature FILALUX = registerVegetation( + "filalux", + FILALUX_FEATURE, + ScatterFeatureConfig.filalux(), + 1 + ); // Water // - public static final BCLFeature BUBBLE_CORAL = registerVegetation( + public static final BCLFeature BUBBLE_CORAL = registerVegetation( "bubble_coral", - new UnderwaterPlantFeature( + UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( EndBlocks.BUBBLE_CORAL, 6 ), 10 ); - public static final BCLFeature BUBBLE_CORAL_RARE = registerVegetation( + public static final BCLFeature BUBBLE_CORAL_RARE = registerVegetation( "bubble_coral_rare", - new UnderwaterPlantFeature( + UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( EndBlocks.BUBBLE_CORAL, 3 ), 4 ); - public static final BCLFeature END_LILY = registerVegetation("end_lily", new EndLilyFeature(6), 10); - public static final BCLFeature END_LILY_RARE = registerVegetation("end_lily_rare", new EndLilyFeature(3), 4); - public static final BCLFeature END_LOTUS = registerVegetation("end_lotus", new EndLotusFeature(7), 5); - public static final BCLFeature END_LOTUS_LEAF = registerVegetation( + 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), + 5 + ); + public static final BCLFeature END_LOTUS_LEAF = registerVegetation( "end_lotus_leaf", - new EndLotusLeafFeature(20), + END_LOTUS_FEATURE, new ScatterFeatureConfig(20), 25 ); - public static final BCLFeature HYDRALUX = registerVegetation("hydralux", new HydraluxFeature(5), 5); - public static final BCLFeature POND_ANEMONE = registerVegetation( + public static final BCLFeature HYDRALUX = registerVegetation( + "hydralux", + HYDRALUX_FEATURE, + new ScatterFeatureConfig(5), + 5 + ); + public static final BCLFeature POND_ANEMONE = registerVegetation( "pond_anemone", - new UnderwaterPlantFeature( + UNDERWATER_PLANT_FEATURE, new SinglePlantFeatureConfig( EndBlocks.POND_ANEMONE, 6 ), 10 ); - public static final BCLFeature CHARNIA_RED = registerVegetation( + public static final BCLFeature CHARNIA_RED = registerVegetation( "charnia_red", - new CharniaFeature(EndBlocks.CHARNIA_RED), + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_RED), 10 ); - public static final BCLFeature CHARNIA_PURPLE = registerVegetation( + public static final BCLFeature CHARNIA_PURPLE = registerVegetation( "charnia_purple", - new CharniaFeature(EndBlocks.CHARNIA_PURPLE), + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_PURPLE), 10 ); - public static final BCLFeature CHARNIA_CYAN = registerVegetation( + public static final BCLFeature CHARNIA_CYAN = registerVegetation( "charnia_cyan", - new CharniaFeature(EndBlocks.CHARNIA_CYAN), + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_CYAN), 10 ); - public static final BCLFeature CHARNIA_LIGHT_BLUE = registerVegetation( + public static final BCLFeature CHARNIA_LIGHT_BLUE = registerVegetation( "charnia_light_blue", - new CharniaFeature(EndBlocks.CHARNIA_LIGHT_BLUE), + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_LIGHT_BLUE), 10 ); - public static final BCLFeature CHARNIA_ORANGE = registerVegetation( + public static final BCLFeature CHARNIA_ORANGE = registerVegetation( "charnia_orange", - new CharniaFeature(EndBlocks.CHARNIA_ORANGE), + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_ORANGE), 10 ); - public static final BCLFeature CHARNIA_GREEN = registerVegetation( + public static final BCLFeature CHARNIA_GREEN = registerVegetation( "charnia_green", - new CharniaFeature(EndBlocks.CHARNIA_GREEN), + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_GREEN), 10 ); - public static final BCLFeature MENGER_SPONGE = registerVegetation("menger_sponge", new MengerSpongeFeature(5), 1); - public static final BCLFeature CHARNIA_RED_RARE = registerVegetation( + 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", - new CharniaFeature(EndBlocks.CHARNIA_RED), + CHARNIA_FEATURE, SinglePlantFeatureConfig.charnia(EndBlocks.CHARNIA_RED), 2 ); public static final BCLFeature BIOME_ISLAND = BCLFeatureBuilder .start( BetterEnd.makeID("overworld_island"), - new BiomeIslandFeature() + inlineBuild("overworld_island", new BiomeIslandFeature()) ) .buildAndRegister() .place() .decoration(Decoration.RAW_GENERATION) .buildAndRegister(); - public static final BCLFeature FLAMAEA = registerVegetation( + public static final BCLFeature FLAMAEA = registerVegetation( "flamaea", - new SinglePlantFeature(EndBlocks.FLAMAEA, 12, false, 5), + new SinglePlantFeatureConfig(EndBlocks.FLAMAEA, 12, false, 5), 20 ); // Terrain // - public static final BCLFeature END_LAKE = registerLake("end_lake", new EndLakeFeature(), 4); - public static final BCLFeature END_LAKE_NORMAL = registerLake("end_lake_normal", new EndLakeFeature(), 20); - public static final BCLFeature END_LAKE_RARE = registerLake("end_lake_rare", new EndLakeFeature(), 40); - public static final BCLFeature DESERT_LAKE = registerLake("desert_lake", new DesertLakeFeature(), 8); - public static final BCLFeature ROUND_CAVE = registerRawGen("round_cave", new RoundCaveFeature(), 2); - public static final BCLFeature SPIRE = registerRawGen("spire", new SpireFeature(), 4); - public static final BCLFeature FLOATING_SPIRE = registerRawGen("floating_spire", new FloatingSpireFeature(), 8); - public static final BCLFeature GEYSER = registerRawGen("geyser", new GeyserFeature(), 8); - public static final BCLFeature SULPHURIC_LAKE = registerLake("sulphuric_lake", new SulphuricLakeFeature(), 8); - public static final BCLFeature SULPHURIC_CAVE = BCLFeatureBuilder + public static final BCLFeature END_LAKE = registerLake( + "end_lake", + new EndLakeFeature(), + 4 + ); + public static final BCLFeature END_LAKE_NORMAL = registerLake( + "end_lake_normal", + new EndLakeFeature(), + 20 + ); + public static final BCLFeature END_LAKE_RARE = registerLake( + "end_lake_rare", + new EndLakeFeature(), + 40 + ); + public static final BCLFeature DESERT_LAKE = registerLake( + "desert_lake", + new DesertLakeFeature(), + 8 + ); + public static final BCLFeature ROUND_CAVE = registerRawGen( + "round_cave", + new RoundCaveFeature(), + 2 + ); + public static final BCLFeature SPIRE = registerRawGen( + "spire", + new SpireFeature(), + 4 + ); + public static final BCLFeature FLOATING_SPIRE = registerRawGen( + "floating_spire", + new FloatingSpireFeature(), + 8 + ); + public static final BCLFeature GEYSER = registerRawGen( + "geyser", + new GeyserFeature(), + 8 + ); + public static final BCLFeature SULPHURIC_LAKE = registerLake( + "sulphuric_lake", + new SulphuricLakeFeature(), + 8 + ); + public static final BCLFeature SULPHURIC_CAVE = BCLFeatureBuilder .start( BetterEnd.makeID("sulphuric_cave"), - new SulphuricCaveFeature() + inlineBuild("sulphuric_cave", new SulphuricCaveFeature()) ) .buildAndRegister() .place() @@ -640,56 +824,92 @@ public class EndFeatures { .squarePlacement() .onlyInBiome() .buildAndRegister(); - public static final BCLFeature ICE_STAR = registerRawGen("ice_star", new IceStarFeature(5, 15, 10, 25), 15); - public static final BCLFeature ICE_STAR_SMALL = registerRawGen( + public static final BCLFeature ICE_STAR = registerRawGen( + "ice_star", + new IceStarFeature(5, 15, 10, 25), + 15 + ); + public static final BCLFeature ICE_STAR_SMALL = registerRawGen( "ice_star_small", new IceStarFeature(3, 5, 7, 12), 8 ); - public static final BCLFeature SURFACE_VENT = registerChanced("surface_vent", new SurfaceVentFeature(), 4); - public static final BCLFeature SULPHUR_HILL = registerChanced("sulphur_hill", new SulphurHillFeature(), 8); - public static final BCLFeature OBSIDIAN_PILLAR_BASEMENT = registerChanced( + public static final BCLFeature SURFACE_VENT = registerChanced( + "surface_vent", + new SurfaceVentFeature(), + 4 + ); + public static final BCLFeature SULPHUR_HILL = registerChanced( + "sulphur_hill", + new SulphurHillFeature(), + 8 + ); + public static final BCLFeature OBSIDIAN_PILLAR_BASEMENT = registerChanced( "obsidian_pillar_basement", new ObsidianPillarBasementFeature(), 8 ); - public static final BCLFeature OBSIDIAN_BOULDER = registerChanced( + public static final BCLFeature OBSIDIAN_BOULDER = registerChanced( "obsidian_boulder", new ObsidianBoulderFeature(), 10 ); - public static final BCLFeature FALLEN_PILLAR = registerChanced("fallen_pillar", new FallenPillarFeature(), 20); - public static final BCLFeature TUNEL_CAVE = BCLFeatureBuilder + public static final BCLFeature FALLEN_PILLAR = registerChanced( + "fallen_pillar", + new FallenPillarFeature(), + 20 + ); + public static final BCLFeature TUNEL_CAVE = BCLFeatureBuilder .start( BetterEnd.makeID("tunel_cave"), - new TunelCaveFeature() + inlineBuild("tunel_cave", new TunelCaveFeature()) ).buildAndRegister() .place() .decoration(Decoration.RAW_GENERATION) .count(1) .onlyInBiome() .buildAndRegister(); - public static final BCLFeature UMBRALITH_ARCH = registerChanced("umbralith_arch", new ArchFeature( - EndBlocks.UMBRALITH.stone, - pos -> UmbraValleyBiome.getSurface(pos.getX(), pos.getZ()).defaultBlockState() - ), 10); - public static final BCLFeature THIN_UMBRALITH_ARCH = registerChanced( + 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", - new ThinArchFeature(EndBlocks.UMBRALITH.stone), + 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( + 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( + public static final BCLFeature VIOLECITE_LAYER = registerLayer( "violecite_layer", EndBlocks.VIOLECITE, 15, @@ -697,7 +917,8 @@ public class EndFeatures { 128, 8 ); - public static final BCLFeature FLAVOLITE_LAYER = registerLayer( + + public static final BCLFeature FLAVOLITE_LAYER = registerLayer( "flavolite_layer", EndBlocks.FLAVOLITE, 12, @@ -707,10 +928,19 @@ public class EndFeatures { ); // Buildings - public static final BCLFeature CRASHED_SHIP = registerChanced("crashed_ship", new CrashedShipFeature(), 500); + public static final BCLFeature CRASHED_SHIP = registerChanced( + "crashed_ship", + new CrashedShipFeature(), + new NBTFeatureConfig(EndBiome.Config.DEFAULT_MATERIAL.getTopMaterial()), + 500 + ); // Mobs - public static final BCLFeature SILK_MOTH_NEST = registerChanced("silk_moth_nest", new SilkMothNestFeature(), 2); + public static final BCLFeature SILK_MOTH_NEST = registerChanced( + "silk_moth_nest", + new SilkMothNestFeature(), + 2 + ); // Caves public static final DefaultFeature SMARAGDANT_CRYSTAL = new SmaragdantCrystalFeature(); @@ -718,8 +948,16 @@ public class EndFeatures { public static final DefaultFeature BIG_AURORA_CRYSTAL = new BigAuroraCrystalFeature(); public static final DefaultFeature CAVE_BUSH = new BushFeature(EndBlocks.CAVE_BUSH, EndBlocks.CAVE_BUSH); public static final DefaultFeature CAVE_GRASS = new SingleBlockFeature(EndBlocks.CAVE_GRASS); - public static final DefaultFeature RUBINEA = new VineFeature(EndBlocks.RUBINEA, 8); - public static final DefaultFeature MAGNULA = new VineFeature(EndBlocks.MAGNULA, 8); + public static final BCLConfigureFeature RUBINEA = BCLFeatureBuilder + .start(BetterEnd.makeID("rubinea"), VINE_FEATURE) + .configuration(new VineFeatureConfig(EndBlocks.RUBINEA, 8)) + .buildAndRegister(); + + public static final BCLConfigureFeature MAGNULA = BCLFeatureBuilder + .start(BetterEnd.makeID("magnula"), VINE_FEATURE) + .configuration(new VineFeatureConfig(EndBlocks.MAGNULA, 8)) + .buildAndRegister(); + public static final DefaultFeature END_STONE_STALACTITE = new StalactiteFeature( true, EndBlocks.END_STONE_STALACTITE, @@ -743,13 +981,48 @@ public class EndFeatures { ); public static final DefaultFeature CAVE_PUMPKIN = new CavePumpkinFeature(); + public static , FC extends FeatureConfiguration> F inlineBuild(String name, F feature) { + ResourceLocation l = BetterEnd.makeID(name); + if (Registry.FEATURE.containsKey(l)) { + return (F) Registry.FEATURE.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 + ) { + feature = inlineBuild("feature_" + name, feature); ResourceLocation id = BetterEnd.makeID(name); return BCLFeatureBuilder.start(id, feature) + .configuration(config) .buildAndRegister() .place() .countMax(density) @@ -757,7 +1030,12 @@ public class EndFeatures { .buildAndRegister(); } - private static BCLFeature registerRawGen(String name, Feature feature, int chance) { + private static > BCLFeature registerRawGen( + String name, + F feature, + int chance + ) { + feature = inlineBuild("feature_" + name, feature); return BCLFeatureBuilder .start(BetterEnd.makeID(name), feature) .buildAndRegister() @@ -769,7 +1047,12 @@ public class EndFeatures { .buildAndRegister(); } - private static BCLFeature registerLake(String name, Feature feature, int chance) { + private static > BCLFeature registerLake( + String name, + F feature, + int chance + ) { + feature = inlineBuild("feature_" + name, feature); return BCLFeatureBuilder .start(BetterEnd.makeID(name), feature) .buildAndRegister() @@ -781,10 +1064,25 @@ public class EndFeatures { .buildAndRegister(); } - private static BCLFeature registerChanced(String name, Feature feature, int chance) { + 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 + ) { + feature = inlineBuild("feature_" + name, feature); return BCLFeatureBuilder .start(BetterEnd.makeID(name), feature) + .configuration(config) .buildAndRegister() .place() .decoration(Decoration.SURFACE_STRUCTURES) @@ -794,7 +1092,12 @@ public class EndFeatures { .buildAndRegister(); } - private static BCLFeature registerOre(String name, Block blockOre, int veins, int veinSize) { + private static BCLFeature registerOre( + String name, + Block blockOre, + int veins, + int veinSize + ) { return BCLFeatureBuilder .startOre(BetterEnd.makeID(name)) .add(Blocks.END_STONE, blockOre) @@ -810,10 +1113,18 @@ public class EndFeatures { .buildAndRegister(); } - private static BCLFeature registerLayer(String name, Block block, float radius, int minY, int maxY, int count) { - OreLayerFeature layer = new OreLayerFeature(block.defaultBlockState(), radius, minY, maxY); + 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)) .buildAndRegister() .place() .decoration(GenerationStep.Decoration.UNDERGROUND_ORES) @@ -821,7 +1132,7 @@ public class EndFeatures { .buildAndRegister(); } - private static BCLFeature registerLayer( + private static BCLFeature registerLayer( String name, StoneMaterial material, float radius, @@ -858,22 +1169,13 @@ public class EndFeatures { } } - private static BCLFeature getBiomeStructures(BCLBiome biome) { + private static BCLFeature getBiomeStructures(BCLBiome biome) { String ns = biome.getID().getNamespace(); String nm = biome.getID().getPath(); ResourceLocation id = new ResourceLocation(ns, nm + "_structures"); if (BuiltinRegistries.PLACED_FEATURE.containsKey(id)) { - PlacedFeature placed = BuiltinRegistries.PLACED_FEATURE.get(id); - Feature feature = (Feature) Registry.FEATURE.get(id); - return BCLFeatureBuilder - .start(id, feature) - .configuration((NoneFeatureConfiguration) placed.feature().value().config()) - .buildAndRegister() - .place() - .decoration(Decoration.SURFACE_STRUCTURES) - .modifier(placed.placement()) - .buildAndRegister(); + throw new IllegalStateException("Feature for " + id + "was already build"); } String path = "/data/" + ns + "/structures/biome/" + nm + "/"; @@ -882,7 +1184,7 @@ public class EndFeatures { JsonObject obj = JsonFactory.getJsonObject(inputstream); JsonArray structures = obj.getAsJsonArray("structures"); if (structures != null) { - List list = Lists.newArrayList(); + List list = Lists.newArrayList(); structures.forEach((entry) -> { JsonObject e = entry.getAsJsonObject(); String structure = path + e.get("nbt").getAsString() + ".nbt"; @@ -890,13 +1192,17 @@ public class EndFeatures { .get("terrainMerge") .getAsString()); int offsetY = e.get("offsetY").getAsInt(); - list.add(new ListFeature.StructureInfo(structure, offsetY, terrainMerge)); + list.add(new BuildingListFeature.StructureInfo(structure, offsetY, terrainMerge)); }); if (!list.isEmpty()) { return BCLFeatureBuilder.start( new ResourceLocation(ns, nm + "_structures"), - new BuildingListFeature(list, Blocks.END_STONE.defaultBlockState()) + BUILDING_LIST_FEATURE ) + .configuration(new BuildingListFeatureConfig( + list, + Blocks.END_STONE.defaultBlockState() + )) .buildAndRegister() .place() .decoration(Decoration.SURFACE_STRUCTURES) diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/EndCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/EndCaveBiome.java index 6012181e..7001ea04 100644 --- a/src/main/java/org/betterx/betterend/world/biome/cave/EndCaveBiome.java +++ b/src/main/java/org/betterx/betterend/world/biome/cave/EndCaveBiome.java @@ -3,14 +3,15 @@ package org.betterx.betterend.world.biome.cave; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder.BiomeSupplier; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeSettings; -import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v3.levelgen.features.BCLFeature; import org.betterx.bclib.api.v3.levelgen.features.BCLFeatureBuilder; import org.betterx.bclib.util.WeightedList; import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndFeatures; import org.betterx.betterend.registry.EndSounds; import org.betterx.betterend.world.biome.EndBiome; import org.betterx.betterend.world.features.terrain.caves.CaveChunkPopulatorFeature; +import org.betterx.betterend.world.features.terrain.caves.CaveChunkPopulatorFeatureConfig; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; @@ -28,11 +29,13 @@ public class EndCaveBiome extends EndBiome { @Override protected void addCustomBuildData(BCLBiomeBuilder builder) { - BCLFeature feature = BCLFeatureBuilder + + BCLFeature feature = BCLFeatureBuilder .start( BetterEnd.makeID(ID.getPath() + "_cave_populator"), - new CaveChunkPopulatorFeature(() -> (EndCaveBiome) BiomeAPI.getBiome(ID)) + EndFeatures.CAVE_CHUNK_POPULATOR ) + .configuration(new CaveChunkPopulatorFeatureConfig(ID)) .buildAndRegister() .place() .decoration(GenerationStep.Decoration.RAW_GENERATION) diff --git a/src/main/java/org/betterx/betterend/world/biome/cave/LushAuroraCaveBiome.java b/src/main/java/org/betterx/betterend/world/biome/cave/LushAuroraCaveBiome.java index 578b1807..a85551ca 100644 --- a/src/main/java/org/betterx/betterend/world/biome/cave/LushAuroraCaveBiome.java +++ b/src/main/java/org/betterx/betterend/world/biome/cave/LushAuroraCaveBiome.java @@ -26,8 +26,8 @@ public class LushAuroraCaveBiome extends EndCaveBiome.Config { this.addCeilFeature(EndFeatures.CAVE_BUSH, 1); this.addCeilFeature(EndFeatures.CAVE_PUMPKIN, 1); - this.addCeilFeature(EndFeatures.RUBINEA, 3); - this.addCeilFeature(EndFeatures.MAGNULA, 1); + this.addCeilFeature(EndFeatures.RUBINEA.getFeature(), 3); + this.addCeilFeature(EndFeatures.MAGNULA.getFeature(), 1); this.addCeilFeature(EndFeatures.END_STONE_STALACTITE_CAVEMOSS, 10); } diff --git a/src/main/java/org/betterx/betterend/world/features/BlueVineFeature.java b/src/main/java/org/betterx/betterend/world/features/BlueVineFeature.java index e9220401..31d77cc9 100644 --- a/src/main/java/org/betterx/betterend/world/features/BlueVineFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/BlueVineFeature.java @@ -1,5 +1,6 @@ package org.betterx.betterend.world.features; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.util.BlocksHelper; import org.betterx.bclib.util.MHelper; import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; @@ -9,16 +10,17 @@ import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -public class BlueVineFeature extends ScatterFeature { +public class BlueVineFeature extends ScatterFeature { private boolean small; public BlueVineFeature() { - super(5); + super(ScatterFeatureConfig.CODEC); } @Override @SuppressWarnings("deprecation") public boolean canGenerate( + ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -30,11 +32,11 @@ public class BlueVineFeature extends ScatterFeature { center.getZ() - blockPos.getZ() ) / radius * 0.6F + random.nextFloat() * 0.4F; small = d > 0.5F; - return EndBlocks.BLUE_VINE_SEED.canSurvive(AIR, world, blockPos); + return EndBlocks.BLUE_VINE_SEED.canSurvive(DefaultFeature.AIR, world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { if (small) { BlocksHelper.setWithoutUpdate( world, diff --git a/src/main/java/org/betterx/betterend/world/features/BuildingListFeature.java b/src/main/java/org/betterx/betterend/world/features/BuildingListFeature.java index 795c9c76..6085e89b 100644 --- a/src/main/java/org/betterx/betterend/world/features/BuildingListFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/BuildingListFeature.java @@ -1,13 +1,20 @@ package org.betterx.betterend.world.features; +import org.betterx.bclib.util.StructureHelper; import org.betterx.betterend.util.LootTableUtil; +import org.betterx.worlds.together.tag.v3.CommonBlockTags; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -17,20 +24,89 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; -import java.util.List; import org.jetbrains.annotations.Nullable; -public class BuildingListFeature extends ListFeature { - public BuildingListFeature(List list, BlockState defaultBlock) { - super(list, defaultBlock); +public class BuildingListFeature extends NBTFeature { + private StructureInfo selected; + + public BuildingListFeature() { + super(BuildingListFeatureConfig.CODEC); + } @Override protected void addStructureData(StructurePlaceSettings data) { - super.addStructureData(data); data.addProcessor(new ChestProcessor()); } + @Override + protected StructureTemplate getStructure( + BuildingListFeatureConfig cfg, + WorldGenLevel world, + BlockPos pos, + RandomSource random + ) { + selected = cfg.getRandom(random); + return selected.getStructure(); + } + + @Override + protected boolean canSpawn(WorldGenLevel world, BlockPos pos, RandomSource random) { + int cx = pos.getX() >> 4; + int cz = pos.getZ() >> 4; + return ((cx + cz) & 1) == 0 && pos.getY() > 58 + && world.getBlockState(pos).isAir() + && world.getBlockState(pos.below()).is(CommonBlockTags.TERRAIN); + } + + @Override + protected Rotation getRotation(WorldGenLevel world, BlockPos pos, RandomSource random) { + return Rotation.getRandom(random); + } + + @Override + protected Mirror getMirror(WorldGenLevel world, BlockPos pos, RandomSource random) { + return Mirror.values()[random.nextInt(3)]; + } + + @Override + protected int getYOffset(StructureTemplate structure, WorldGenLevel world, BlockPos pos, RandomSource random) { + return selected.offsetY; + } + + @Override + protected TerrainMerge getTerrainMerge(WorldGenLevel world, BlockPos pos, RandomSource random) { + return selected.terrainMerge; + } + + public static final class StructureInfo { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.STRING.fieldOf("path").forGetter(o -> o.structurePath), + Codec.INT.fieldOf("offset_y").forGetter(o -> o.offsetY), + TerrainMerge.CODEC.fieldOf("terrain_merger").forGetter(o -> o.terrainMerge) + ) + .apply(instance, StructureInfo::new)); + public final TerrainMerge terrainMerge; + public final String structurePath; + public final int offsetY; + + private StructureTemplate structure; + + public StructureInfo(String structurePath, int offsetY, TerrainMerge terrainMerge) { + this.terrainMerge = terrainMerge; + this.structurePath = structurePath; + this.offsetY = offsetY; + } + + public StructureTemplate getStructure() { + if (structure == null) { + structure = StructureHelper.readStructure(structurePath); + } + return structure; + } + } + class ChestProcessor extends StructureProcessor { @Nullable @Override diff --git a/src/main/java/org/betterx/betterend/world/features/BuildingListFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/BuildingListFeatureConfig.java new file mode 100644 index 00000000..bf17c8d5 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/BuildingListFeatureConfig.java @@ -0,0 +1,31 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; + +public class BuildingListFeatureConfig extends NBTFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + ExtraCodecs.nonEmptyList(BuildingListFeature.StructureInfo.CODEC.listOf()) + .fieldOf("structures") + .forGetter(a -> a.list), + BlockState.CODEC.fieldOf("default").forGetter(o -> o.defaultBlock) + ) + .apply(instance, BuildingListFeatureConfig::new) + ); + protected final List list; + + public BuildingListFeatureConfig(List list, BlockState defaultBlock) { + super(defaultBlock); + this.list = list; + } + + public BuildingListFeature.StructureInfo getRandom(RandomSource random) { + return this.list.get(random.nextInt(this.list.size())); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/CharniaFeature.java b/src/main/java/org/betterx/betterend/world/features/CharniaFeature.java index c6abdbf4..4e115604 100644 --- a/src/main/java/org/betterx/betterend/world/features/CharniaFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/CharniaFeature.java @@ -1,12 +1,6 @@ package org.betterx.betterend.world.features; -import net.minecraft.world.level.block.Block; - public class CharniaFeature extends UnderwaterPlantFeature { - public CharniaFeature(Block plant) { - super(plant, 6); - } - @Override protected int getChance() { return 3; diff --git a/src/main/java/org/betterx/betterend/world/features/CrashedShipFeature.java b/src/main/java/org/betterx/betterend/world/features/CrashedShipFeature.java index 8e362796..37b78739 100644 --- a/src/main/java/org/betterx/betterend/world/features/CrashedShipFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/CrashedShipFeature.java @@ -1,10 +1,10 @@ package org.betterx.betterend.world.features; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.util.MHelper; import org.betterx.bclib.util.StructureErode; import org.betterx.bclib.util.StructureHelper; import org.betterx.betterend.util.BlockFixer; -import org.betterx.betterend.world.biome.EndBiome; import org.betterx.worlds.together.tag.v3.CommonBlockTags; import net.minecraft.core.BlockPos; @@ -17,23 +17,27 @@ import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.templatesystem.*; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; import net.minecraft.world.level.material.Material; -public class CrashedShipFeature extends NBTFeature { +public class CrashedShipFeature extends NBTFeature { private static final StructureProcessor REPLACER; private static final String STRUCTURE_PATH = "/data/minecraft/structures/end_city/ship.nbt"; private StructureTemplate structure; public CrashedShipFeature() { - super(EndBiome.Config.DEFAULT_MATERIAL.getTopMaterial()); + super(NBTFeatureConfig.CODEC); } @Override - protected StructureTemplate getStructure(WorldGenLevel world, BlockPos pos, RandomSource random) { + protected StructureTemplate getStructure( + NBTFeatureConfig cfg, + WorldGenLevel world, + BlockPos pos, + RandomSource random + ) { if (structure == null) { structure = world.getLevel().getStructureManager().getOrCreate(new ResourceLocation("end_city/ship")); if (structure == null) { @@ -76,7 +80,7 @@ public class CrashedShipFeature extends NBTFeature { } @Override - public boolean place(FeaturePlaceContext featureConfig) { + public boolean place(FeaturePlaceContext featureConfig) { final RandomSource random = featureConfig.random(); BlockPos center = featureConfig.origin(); final WorldGenLevel world = featureConfig.level(); @@ -88,7 +92,7 @@ public class CrashedShipFeature extends NBTFeature { return false; } - StructureTemplate structure = getStructure(world, center, random); + StructureTemplate structure = getStructure(featureConfig.config(), world, center, random); Rotation rotation = getRotation(world, center, random); Mirror mirror = getMirror(world, center, random); BlockPos offset = StructureTemplate.transform( @@ -135,7 +139,7 @@ public class CrashedShipFeature extends NBTFeature { ) { BlockState state = structureBlockInfo2.state; if (state.is(Blocks.SPAWNER) || state.getMaterial().equals(Material.WOOL)) { - return new StructureBlockInfo(structureBlockInfo2.pos, AIR, null); + return new StructureBlockInfo(structureBlockInfo2.pos, DefaultFeature.AIR, null); } return structureBlockInfo2; } diff --git a/src/main/java/org/betterx/betterend/world/features/DoublePlantFeature.java b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeature.java index 1feb68da..9662207f 100644 --- a/src/main/java/org/betterx/betterend/world/features/DoublePlantFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeature.java @@ -7,22 +7,19 @@ import org.betterx.bclib.util.MHelper; import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public class DoublePlantFeature extends ScatterFeature { - private final Block smallPlant; - private final Block largePlant; - private Block plant; +public class DoublePlantFeature extends ScatterFeature { + private BlockState plant; + + public DoublePlantFeature() { + super(DoublePlantFeatureConfig.CODEC); - public DoublePlantFeature(Block smallPlant, Block largePlant, int radius) { - super(radius); - this.smallPlant = smallPlant; - this.largePlant = largePlant; } @Override public boolean canGenerate( + DoublePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -33,16 +30,21 @@ public class DoublePlantFeature extends ScatterFeature { center.getX() - blockPos.getX(), center.getZ() - blockPos.getZ() ) / radius * 0.6F + random.nextFloat() * 0.4F; - plant = d < 0.5F ? largePlant : smallPlant; + plant = d < 0.5F ? cfg.getLargePlantState(random, blockPos) : cfg.getSmallPlantState(random, blockPos); //noinspection deprecation - return plant.canSurvive(plant.defaultBlockState(), world, blockPos); + return plant.getBlock().canSurvive(plant, world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { - if (plant instanceof BaseDoublePlantBlock) { + public void generate( + DoublePlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos blockPos + ) { + if (plant.getBlock() instanceof BaseDoublePlantBlock) { int rot = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); + BlockState state = plant.setValue(BaseDoublePlantBlock.ROTATION, rot); BlocksHelper.setWithoutUpdate(world, blockPos, state); BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); } else { diff --git a/src/main/java/org/betterx/betterend/world/features/DoublePlantFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeatureConfig.java new file mode 100644 index 00000000..46914627 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/DoublePlantFeatureConfig.java @@ -0,0 +1,44 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class DoublePlantFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("small_state").forGetter(o -> o.smallPlant), + BlockStateProvider.CODEC.fieldOf("large_state").forGetter(o -> o.largePlant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius) + ) + .apply( + instance, + DoublePlantFeatureConfig::new + )); + + public final BlockStateProvider smallPlant; + public final BlockStateProvider largePlant; + + public DoublePlantFeatureConfig(Block smallPlant, Block largePlant, int radius) { + this(SimpleStateProvider.simple(smallPlant), SimpleStateProvider.simple(largePlant), radius); + } + + public DoublePlantFeatureConfig(BlockStateProvider smallPlant, BlockStateProvider largePlant, int radius) { + super(radius); + this.smallPlant = smallPlant; + this.largePlant = largePlant; + } + + BlockState getLargePlantState(RandomSource rnd, BlockPos pos) { + return largePlant.getState(rnd, pos); + } + + BlockState getSmallPlantState(RandomSource rnd, BlockPos pos) { + return smallPlant.getState(rnd, pos); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/EndLilyFeature.java b/src/main/java/org/betterx/betterend/world/features/EndLilyFeature.java index f19e7e51..cb2ec6a0 100644 --- a/src/main/java/org/betterx/betterend/world/features/EndLilyFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/EndLilyFeature.java @@ -7,13 +7,13 @@ import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -public class EndLilyFeature extends UnderwaterPlantScatter { - public EndLilyFeature(int radius) { - super(radius); +public class EndLilyFeature extends UnderwaterPlantScatter { + public EndLilyFeature() { + super(ScatterFeatureConfig.CODEC); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { EndLilySeedBlock seed = (EndLilySeedBlock) EndBlocks.END_LILY_SEED; seed.grow(world, random, blockPos); } diff --git a/src/main/java/org/betterx/betterend/world/features/EndLotusFeature.java b/src/main/java/org/betterx/betterend/world/features/EndLotusFeature.java index fef9d4f6..f89cc0a9 100644 --- a/src/main/java/org/betterx/betterend/world/features/EndLotusFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/EndLotusFeature.java @@ -7,13 +7,13 @@ import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -public class EndLotusFeature extends UnderwaterPlantScatter { - public EndLotusFeature(int radius) { - super(radius); +public class EndLotusFeature extends UnderwaterPlantScatter { + public EndLotusFeature() { + super(ScatterFeatureConfig.CODEC); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { EndLotusSeedBlock seed = (EndLotusSeedBlock) EndBlocks.END_LOTUS_SEED; seed.grow(world, random, blockPos); } diff --git a/src/main/java/org/betterx/betterend/world/features/EndLotusLeafFeature.java b/src/main/java/org/betterx/betterend/world/features/EndLotusLeafFeature.java index 0af2ba97..e86fea94 100644 --- a/src/main/java/org/betterx/betterend/world/features/EndLotusLeafFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/EndLotusLeafFeature.java @@ -1,5 +1,6 @@ package org.betterx.betterend.world.features; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.blocks.BlockProperties.TripleShape; import org.betterx.bclib.util.BlocksHelper; import org.betterx.betterend.blocks.EndLotusLeafBlock; @@ -13,13 +14,13 @@ import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -public class EndLotusLeafFeature extends ScatterFeature { - public EndLotusLeafFeature(int radius) { - super(radius); +public class EndLotusLeafFeature extends ScatterFeature { + public EndLotusLeafFeature() { + super(ScatterFeatureConfig.CODEC); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { if (canGenerate(world, blockPos)) { generateLeaf(world, blockPos); } @@ -31,8 +32,8 @@ public class EndLotusLeafFeature extends ScatterFeature { } @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - return getPosOnSurface(world, pos); + protected BlockPos getCenterGround(ScatterFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { + return DefaultFeature.getPosOnSurface(world, pos); } private void generateLeaf(WorldGenLevel world, BlockPos pos) { @@ -75,6 +76,7 @@ public class EndLotusLeafFeature extends ScatterFeature { @Override public boolean canGenerate( + ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, diff --git a/src/main/java/org/betterx/betterend/world/features/FilaluxFeature.java b/src/main/java/org/betterx/betterend/world/features/FilaluxFeature.java index 2203bcae..a99abc16 100644 --- a/src/main/java/org/betterx/betterend/world/features/FilaluxFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/FilaluxFeature.java @@ -14,12 +14,8 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class FilaluxFeature extends SkyScatterFeature { - public FilaluxFeature() { - super(10); - } - @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { BlockState vine = EndBlocks.FILALUX.defaultBlockState(); BlockState wings = EndBlocks.FILALUX_WINGS.defaultBlockState(); BlocksHelper.setWithoutUpdate(world, blockPos, EndBlocks.FILALUX_LANTERN); diff --git a/src/main/java/org/betterx/betterend/world/features/GlowPillarFeature.java b/src/main/java/org/betterx/betterend/world/features/GlowPillarFeature.java index bba1f118..b0034e7a 100644 --- a/src/main/java/org/betterx/betterend/world/features/GlowPillarFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/GlowPillarFeature.java @@ -1,5 +1,6 @@ package org.betterx.betterend.world.features; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; import org.betterx.betterend.registry.EndBlocks; @@ -7,13 +8,14 @@ import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -public class GlowPillarFeature extends ScatterFeature { +public class GlowPillarFeature extends ScatterFeature { public GlowPillarFeature() { - super(9); + super(ScatterFeatureConfig.CODEC); } @Override public boolean canGenerate( + ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -21,11 +23,13 @@ public class GlowPillarFeature extends ScatterFeature { float radius ) { //noinspection deprecation - return EndBlocks.GLOWING_PILLAR_SEED.canSurvive(AIR, world, blockPos); + return EndBlocks.GLOWING_PILLAR_SEED.canSurvive(DefaultFeature.AIR, world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate( + ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos + ) { EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.GLOWING_PILLAR_SEED); seed.growAdult(world, random, blockPos); } diff --git a/src/main/java/org/betterx/betterend/world/features/HydraluxFeature.java b/src/main/java/org/betterx/betterend/world/features/HydraluxFeature.java index a82bb2cc..440a7511 100644 --- a/src/main/java/org/betterx/betterend/world/features/HydraluxFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/HydraluxFeature.java @@ -7,13 +7,13 @@ import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -public class HydraluxFeature extends UnderwaterPlantScatter { - public HydraluxFeature(int radius) { - super(radius); +public class HydraluxFeature extends UnderwaterPlantScatter { + public HydraluxFeature() { + super(ScatterFeatureConfig.CODEC); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { HydraluxSaplingBlock seed = (HydraluxSaplingBlock) EndBlocks.HYDRALUX_SAPLING; seed.grow(world, random, blockPos); } diff --git a/src/main/java/org/betterx/betterend/world/features/InvertedScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/InvertedScatterFeature.java index 5e3f946a..3bb7e353 100644 --- a/src/main/java/org/betterx/betterend/world/features/InvertedScatterFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/InvertedScatterFeature.java @@ -1,26 +1,27 @@ package org.betterx.betterend.world.features; -import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.util.BlocksHelper; import org.betterx.bclib.util.MHelper; import org.betterx.betterend.util.GlobalState; +import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -public abstract class InvertedScatterFeature extends DefaultFeature { - private final int radius; +public abstract class InvertedScatterFeature extends Feature { - public InvertedScatterFeature(int radius) { - this.radius = radius; + + public InvertedScatterFeature(Codec codec) { + super(codec); } public abstract boolean canGenerate( + FC cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -28,10 +29,11 @@ public abstract class InvertedScatterFeature extends DefaultFeature { float radius ); - public abstract void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos); + public abstract void generate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos); @Override - public boolean place(FeaturePlaceContext featureConfig) { + public boolean place(FeaturePlaceContext featureConfig) { + FC cfg = featureConfig.config(); final MutableBlockPos POS = GlobalState.stateForThread().POS; final RandomSource random = featureConfig.random(); final BlockPos center = featureConfig.origin(); @@ -41,7 +43,7 @@ public abstract class InvertedScatterFeature extends DefaultFeature { for (int y = maxY; y > minY; y--) { POS.set(center.getX(), y, center.getZ()); if (world.getBlockState(POS).isAir() && !world.getBlockState(POS.above()).isAir()) { - float r = MHelper.randRange(radius * 0.5F, radius, random); + float r = MHelper.randRange(cfg.radius * 0.5F, cfg.radius, random); int count = MHelper.floor(r * r * MHelper.randRange(0.5F, 1.5F, random)); for (int i = 0; i < count; i++) { float pr = r * (float) Math.sqrt(random.nextFloat()); @@ -54,8 +56,8 @@ public abstract class InvertedScatterFeature extends DefaultFeature { if (up > 14) continue; POS.setY(POS.getY() + up); - if (canGenerate(world, random, center, POS, r)) { - generate(world, random, POS); + if (canGenerate(cfg, world, random, center, POS, r)) { + generate(cfg, world, random, POS); } } } diff --git a/src/main/java/org/betterx/betterend/world/features/LanceleafFeature.java b/src/main/java/org/betterx/betterend/world/features/LanceleafFeature.java index 7db2999c..d4fc631a 100644 --- a/src/main/java/org/betterx/betterend/world/features/LanceleafFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/LanceleafFeature.java @@ -1,5 +1,6 @@ package org.betterx.betterend.world.features; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; import org.betterx.betterend.registry.EndBlocks; @@ -7,13 +8,14 @@ import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -public class LanceleafFeature extends ScatterFeature { +public class LanceleafFeature extends ScatterFeature { public LanceleafFeature() { - super(7); + super(ScatterFeatureConfig.CODEC); } @Override public boolean canGenerate( + ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -21,11 +23,11 @@ public class LanceleafFeature extends ScatterFeature { float radius ) { //noinspection deprecation - return EndBlocks.LANCELEAF_SEED.canSurvive(AIR, world, blockPos); + return EndBlocks.LANCELEAF_SEED.canSurvive(DefaultFeature.AIR, world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { EndPlantWithAgeBlock seed = ((EndPlantWithAgeBlock) EndBlocks.LANCELEAF_SEED); seed.growAdult(world, random, blockPos); } diff --git a/src/main/java/org/betterx/betterend/world/features/ListFeature.java b/src/main/java/org/betterx/betterend/world/features/ListFeature.java deleted file mode 100644 index a328919f..00000000 --- a/src/main/java/org/betterx/betterend/world/features/ListFeature.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.betterx.betterend.world.features; - - -import org.betterx.bclib.util.StructureHelper; -import org.betterx.worlds.together.tag.v3.CommonBlockTags; - -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; - -import java.util.List; - -public class ListFeature extends NBTFeature { - private final List list; - private StructureInfo selected; - - public ListFeature(List list, BlockState defaultBlock) { - super(defaultBlock); - this.list = list; - } - - @Override - protected StructureTemplate getStructure(WorldGenLevel world, BlockPos pos, RandomSource random) { - selected = list.get(random.nextInt(list.size())); - return selected.getStructure(); - } - - @Override - protected boolean canSpawn(WorldGenLevel world, BlockPos pos, RandomSource random) { - int cx = pos.getX() >> 4; - int cz = pos.getZ() >> 4; - return ((cx + cz) & 1) == 0 && pos.getY() > 58 - && world.getBlockState(pos).isAir() - && world.getBlockState(pos.below()).is(CommonBlockTags.TERRAIN); - } - - @Override - protected Rotation getRotation(WorldGenLevel world, BlockPos pos, RandomSource random) { - return Rotation.getRandom(random); - } - - @Override - protected Mirror getMirror(WorldGenLevel world, BlockPos pos, RandomSource random) { - return Mirror.values()[random.nextInt(3)]; - } - - @Override - protected int getYOffset(StructureTemplate structure, WorldGenLevel world, BlockPos pos, RandomSource random) { - return selected.offsetY; - } - - @Override - protected TerrainMerge getTerrainMerge(WorldGenLevel world, BlockPos pos, RandomSource random) { - return selected.terrainMerge; - } - - @Override - protected void addStructureData(StructurePlaceSettings data) { - } - - public static final class StructureInfo { - public final TerrainMerge terrainMerge; - public final String structurePath; - public final int offsetY; - - private StructureTemplate structure; - - public StructureInfo(String structurePath, int offsetY, TerrainMerge terrainMerge) { - this.terrainMerge = terrainMerge; - this.structurePath = structurePath; - this.offsetY = offsetY; - } - - public StructureTemplate getStructure() { - if (structure == null) { - structure = StructureHelper.readStructure(structurePath); - } - return structure; - } - } -} diff --git a/src/main/java/org/betterx/betterend/world/features/MengerSpongeFeature.java b/src/main/java/org/betterx/betterend/world/features/MengerSpongeFeature.java index 1b8cd0b2..6bac370e 100644 --- a/src/main/java/org/betterx/betterend/world/features/MengerSpongeFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/MengerSpongeFeature.java @@ -11,15 +11,15 @@ import net.minecraft.world.level.block.state.BlockState; import java.util.function.Function; -public class MengerSpongeFeature extends UnderwaterPlantScatter { +public class MengerSpongeFeature extends UnderwaterPlantScatter { private static final Function REPLACE; - public MengerSpongeFeature(int radius) { - super(radius); + public MengerSpongeFeature() { + super(ScatterFeatureConfig.CODEC); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { + public void generate(ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { BlocksHelper.setWithoutUpdate(world, blockPos, EndBlocks.MENGER_SPONGE_WET); if (random.nextBoolean()) { for (Direction dir : BlocksHelper.DIRECTIONS) { diff --git a/src/main/java/org/betterx/betterend/world/features/NBTFeature.java b/src/main/java/org/betterx/betterend/world/features/NBTFeature.java index 4b671027..d9e47c48 100644 --- a/src/main/java/org/betterx/betterend/world/features/NBTFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/NBTFeature.java @@ -6,6 +6,7 @@ import org.betterx.bclib.api.v2.levelgen.structures.templatesystem.DestructionSt import org.betterx.bclib.util.BlocksHelper; import org.betterx.worlds.together.tag.v3.CommonBlockTags; +import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction; @@ -16,13 +17,14 @@ import net.minecraft.nbt.NbtIo; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.util.RandomSource; +import net.minecraft.util.StringRepresentable; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; @@ -30,17 +32,14 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp import java.io.IOException; import java.io.InputStream; -//TODO: 1.19 Check if we can merge this with the new TemplateFeature! -public abstract class NBTFeature extends DefaultFeature { - private final BlockState defaultBlock; - - public NBTFeature(BlockState defaultBlock) { - this.defaultBlock = defaultBlock; +public abstract class NBTFeature extends Feature { + public NBTFeature(Codec codec) { + super(codec); } protected static final DestructionStructureProcessor DESTRUCTION = new DestructionStructureProcessor(); - protected abstract StructureTemplate getStructure(WorldGenLevel world, BlockPos pos, RandomSource random); + protected abstract StructureTemplate getStructure(FC cfg, WorldGenLevel world, BlockPos pos, RandomSource random); protected abstract boolean canSpawn(WorldGenLevel world, BlockPos pos, RandomSource random); @@ -72,25 +71,26 @@ public abstract class NBTFeature extends DefaultFeature { } protected int getAverageY(WorldGenLevel world, BlockPos center) { - int y = getYOnSurface(world, center.getX(), center.getZ()); - y += getYOnSurface(world, center.getX() - 2, center.getZ() - 2); - y += getYOnSurface(world, center.getX() + 2, center.getZ() - 2); - y += getYOnSurface(world, center.getX() - 2, center.getZ() + 2); - y += getYOnSurface(world, center.getX() + 2, center.getZ() + 2); + int y = DefaultFeature.getYOnSurface(world, center.getX(), center.getZ()); + y += DefaultFeature.getYOnSurface(world, center.getX() - 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurface(world, center.getX() + 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurface(world, center.getX() - 2, center.getZ() + 2); + y += DefaultFeature.getYOnSurface(world, center.getX() + 2, center.getZ() + 2); return y / 5; } protected int getAverageYWG(WorldGenLevel world, BlockPos center) { - int y = getYOnSurfaceWG(world, center.getX(), center.getZ()); - y += getYOnSurfaceWG(world, center.getX() - 2, center.getZ() - 2); - y += getYOnSurfaceWG(world, center.getX() + 2, center.getZ() - 2); - y += getYOnSurfaceWG(world, center.getX() - 2, center.getZ() + 2); - y += getYOnSurfaceWG(world, center.getX() + 2, center.getZ() + 2); + int y = DefaultFeature.getYOnSurfaceWG(world, center.getX(), center.getZ()); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() - 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() + 2, center.getZ() - 2); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() - 2, center.getZ() + 2); + y += DefaultFeature.getYOnSurfaceWG(world, center.getX() + 2, center.getZ() + 2); return y / 5; } @Override - public boolean place(FeaturePlaceContext context) { + public boolean place(FeaturePlaceContext context) { + FC cfg = context.config(); WorldGenLevel world = context.level(); RandomSource random = context.random(); BlockPos center = context.origin(); @@ -103,7 +103,7 @@ public abstract class NBTFeature extends DefaultFeature { } int posY = center.getY() + 1; - StructureTemplate structure = getStructure(world, center, random); + StructureTemplate structure = getStructure(cfg, world, center, random); Rotation rotation = getRotation(world, center, random); Mirror mirror = getMirror(world, center, random); BlockPos offset = StructureTemplate.transform( @@ -160,7 +160,7 @@ public abstract class NBTFeature extends DefaultFeature { Holder b = world.getBiome(mut); BlockState top = (isTop ? BiomeAPI.findTopMaterial(b) - : BiomeAPI.findUnderMaterial(b)).orElse(defaultBlock); + : BiomeAPI.findUnderMaterial(b)).orElse(cfg.defaultBlock); BlocksHelper.setWithoutUpdate(world, mut, top); } else { BlocksHelper.setWithoutUpdate(world, mut, state); @@ -169,7 +169,7 @@ public abstract class NBTFeature extends DefaultFeature { if (isTerrain(state) && state.getMaterial().isSolidBlocking()) { if (merge == TerrainMerge.SURFACE) { Holder b = world.getBiome(mut); - BlockState bottom = BiomeAPI.findUnderMaterial(b).orElse(defaultBlock); + BlockState bottom = BiomeAPI.findUnderMaterial(b).orElse(cfg.defaultBlock); BlocksHelper.setWithoutUpdate(world, mut, bottom); } else { BlocksHelper.setWithoutUpdate(world, mut, state); @@ -222,9 +222,11 @@ public abstract class NBTFeature extends DefaultFeature { return template; } - public enum TerrainMerge { + public enum TerrainMerge implements StringRepresentable { NONE, SURFACE, OBJECT; + public static final Codec CODEC = StringRepresentable.fromEnum(TerrainMerge::values); + public static TerrainMerge getFromString(String type) { if (type.equals("surface")) { return SURFACE; @@ -234,5 +236,10 @@ public abstract class NBTFeature extends DefaultFeature { return NONE; } } + + @Override + public String getSerializedName() { + return this.name(); + } } } diff --git a/src/main/java/org/betterx/betterend/world/features/NBTFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/NBTFeatureConfig.java new file mode 100644 index 00000000..1552b7d0 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/NBTFeatureConfig.java @@ -0,0 +1,20 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public class NBTFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockState.CODEC.fieldOf("default").forGetter(o -> o.defaultBlock) + ) + .apply(instance, NBTFeatureConfig::new) + ); + public final BlockState defaultBlock; + + public NBTFeatureConfig(BlockState defaultBlock) { + this.defaultBlock = defaultBlock; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/ScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/ScatterFeature.java index 0af9a973..fbbcd779 100644 --- a/src/main/java/org/betterx/betterend/world/features/ScatterFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/ScatterFeature.java @@ -6,21 +6,21 @@ import org.betterx.bclib.util.MHelper; import org.betterx.betterend.util.GlobalState; import org.betterx.worlds.together.tag.v3.CommonBlockTags; +import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -public abstract class ScatterFeature extends DefaultFeature { - private final int radius; - - public ScatterFeature(int radius) { - this.radius = radius; +public abstract class ScatterFeature extends Feature { + public ScatterFeature(Codec codec) { + super(codec); } public abstract boolean canGenerate( + FC cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -28,19 +28,19 @@ public abstract class ScatterFeature extends DefaultFeature { float radius ); - public abstract void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos); + public abstract void generate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos); - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - return getPosOnSurfaceWG(world, pos); + protected BlockPos getCenterGround(FC cfg, WorldGenLevel world, BlockPos pos) { + return DefaultFeature.getPosOnSurfaceWG(world, pos); } - protected boolean canSpawn(WorldGenLevel world, BlockPos pos) { + protected boolean canSpawn(FC cfg, WorldGenLevel world, BlockPos pos) { if (pos.getY() < 5) { return false; } else return world.getBlockState(pos.below()).is(CommonBlockTags.END_STONES); } - protected boolean getGroundPlant(WorldGenLevel world, MutableBlockPos pos) { + protected boolean getGroundPlant(FC cfg, WorldGenLevel world, MutableBlockPos pos) { int down = BlocksHelper.downRay(world, pos, 16); if (down > Math.abs(getYOffset() * 2)) { return false; @@ -58,18 +58,19 @@ public abstract class ScatterFeature extends DefaultFeature { } @Override - public boolean place(FeaturePlaceContext featureConfig) { + public boolean place(FeaturePlaceContext featureConfig) { + FC cfg = featureConfig.config(); final MutableBlockPos POS = GlobalState.stateForThread().POS; final RandomSource random = featureConfig.random(); BlockPos center = featureConfig.origin(); final WorldGenLevel world = featureConfig.level(); - center = getCenterGround(world, center); + center = getCenterGround(cfg, world, center); - if (!canSpawn(world, center)) { + if (!canSpawn(cfg, world, center)) { return false; } - float r = MHelper.randRange(radius * 0.5F, radius, random); + float r = MHelper.randRange(cfg.radius * 0.5F, cfg.radius, random); int count = MHelper.floor(r * r * MHelper.randRange(1.5F, 3F, random)); for (int i = 0; i < count; i++) { float pr = r * (float) Math.sqrt(random.nextFloat()); @@ -78,14 +79,15 @@ public abstract class ScatterFeature extends DefaultFeature { float z = pr * (float) Math.sin(theta); POS.set(center.getX() + x, center.getY() + getYOffset(), center.getZ() + z); - if (getGroundPlant(world, POS) && canGenerate( + if (getGroundPlant(cfg, world, POS) && canGenerate( + cfg, world, random, center, POS, r ) && (getChance() < 2 || random.nextInt(getChance()) == 0)) { - generate(world, random, POS); + generate(cfg, world, random, POS); } } diff --git a/src/main/java/org/betterx/betterend/world/features/ScatterFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/ScatterFeatureConfig.java new file mode 100644 index 00000000..99c7e6ae --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/ScatterFeatureConfig.java @@ -0,0 +1,35 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public class ScatterFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.INT.fieldOf("radius").forGetter(o -> o.radius) + ) + .apply(instance, ScatterFeatureConfig::new)); + + public final int radius; + + public ScatterFeatureConfig(int radius) { + this.radius = radius; + } + + public static ScatterFeatureConfig blueVine() { + return new ScatterFeatureConfig(5); + } + + public static ScatterFeatureConfig filalux() { + return new ScatterFeatureConfig(10); + } + + public static ScatterFeatureConfig glowPillar() { + return new ScatterFeatureConfig(9); + } + + public static ScatterFeatureConfig lanceleaf() { + return new ScatterFeatureConfig(7); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/SingleInvertedScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/SingleInvertedScatterFeature.java index ef412ece..b76495ec 100644 --- a/src/main/java/org/betterx/betterend/world/features/SingleInvertedScatterFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/SingleInvertedScatterFeature.java @@ -7,20 +7,19 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -public class SingleInvertedScatterFeature extends InvertedScatterFeature { - private final Block block; +public class SingleInvertedScatterFeature extends InvertedScatterFeature { + private BlockState block; - public SingleInvertedScatterFeature(Block block, int radius) { - super(radius); - this.block = block; + public SingleInvertedScatterFeature() { + super(SinglePlantFeatureConfig.CODEC); } @Override public boolean canGenerate( + SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -30,17 +29,18 @@ public class SingleInvertedScatterFeature extends InvertedScatterFeature { if (!world.isEmptyBlock(blockPos)) { return false; } - BlockState state = block.defaultBlockState(); - if (block instanceof BaseAttachedBlock) { + block = cfg.getPlantState(random, blockPos); + BlockState state = block; + if (block.getBlock() instanceof BaseAttachedBlock) { state = state.setValue(BlockStateProperties.FACING, Direction.DOWN); } return state.canSurvive(world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { - BlockState state = block.defaultBlockState(); - if (block instanceof BaseAttachedBlock) { + public void generate(SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + BlockState state = block; + if (block.getBlock() instanceof BaseAttachedBlock) { state = state.setValue(BlockStateProperties.FACING, Direction.DOWN); } BlocksHelper.setWithoutUpdate(world, blockPos, state); diff --git a/src/main/java/org/betterx/betterend/world/features/SinglePlantFeature.java b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeature.java index a7521ebe..30500466 100644 --- a/src/main/java/org/betterx/betterend/world/features/SinglePlantFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeature.java @@ -1,5 +1,6 @@ package org.betterx.betterend.world.features; +import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.blocks.BaseCropBlock; import org.betterx.bclib.blocks.BaseDoublePlantBlock; import org.betterx.bclib.util.BlocksHelper; @@ -8,70 +9,53 @@ import org.betterx.betterend.blocks.basis.EndPlantWithAgeBlock; import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public class SinglePlantFeature extends ScatterFeature { - private final Block plant; - private final boolean rawHeightmap; - private final int chance; +public class SinglePlantFeature extends ScatterFeature { - public SinglePlantFeature(Block plant, int radius) { - this(plant, radius, true, 1); - } + BlockState plant; - public SinglePlantFeature(Block plant, int radius, int chance) { - this(plant, radius, true, chance); - } - - public SinglePlantFeature(Block plant, int radius, boolean rawHeightmap) { - this(plant, radius, rawHeightmap, 1); - } - - public SinglePlantFeature(Block plant, int radius, boolean rawHeightmap, int chance) { - super(radius); - this.plant = plant; - this.rawHeightmap = rawHeightmap; - this.chance = chance; - } - - protected int getChance() { - return chance; + public SinglePlantFeature() { + super(SinglePlantFeatureConfig.CODEC); } @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { - return rawHeightmap ? getPosOnSurfaceWG(world, pos) : getPosOnSurface(world, pos); + protected BlockPos getCenterGround(SinglePlantFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { + return cfg.rawHeightmap + ? DefaultFeature.getPosOnSurfaceWG(world, pos) + : DefaultFeature.getPosOnSurface(world, pos); } @Override public boolean canGenerate( + SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, BlockPos blockPos, float radius ) { + this.plant = cfg.getPlantState(random, blockPos); //noinspection deprecation - return plant.canSurvive(plant.defaultBlockState(), world, blockPos); + return plant.getBlock().canSurvive(plant, world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { - if (plant instanceof BaseDoublePlantBlock) { + public void generate(SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + if (this.plant.getBlock() instanceof BaseDoublePlantBlock) { int rot = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); + BlockState state = this.plant.setValue(BaseDoublePlantBlock.ROTATION, rot); BlocksHelper.setWithoutUpdate(world, blockPos, state); BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); - } else if (plant instanceof BaseCropBlock) { - BlockState state = plant.defaultBlockState().setValue(BaseCropBlock.AGE, 3); + } else if (this.plant.getBlock() instanceof BaseCropBlock) { + BlockState state = this.plant.setValue(BaseCropBlock.AGE, 3); BlocksHelper.setWithoutUpdate(world, blockPos, state); - } else if (plant instanceof EndPlantWithAgeBlock) { + } else if (this.plant.getBlock() instanceof EndPlantWithAgeBlock) { int age = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(EndPlantWithAgeBlock.AGE, age); + BlockState state = this.plant.setValue(EndPlantWithAgeBlock.AGE, age); BlocksHelper.setWithoutUpdate(world, blockPos, state); } else { - BlocksHelper.setWithoutUpdate(world, blockPos, plant); + BlocksHelper.setWithoutUpdate(world, blockPos, this.plant); } } } diff --git a/src/main/java/org/betterx/betterend/world/features/SinglePlantFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeatureConfig.java new file mode 100644 index 00000000..5ac20f6e --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/SinglePlantFeatureConfig.java @@ -0,0 +1,59 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class SinglePlantFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("state").forGetter(o -> o.plant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius), + Codec.BOOL.fieldOf("raw_heightmap").forGetter(o -> o.rawHeightmap), + Codec.INT.fieldOf("chance").forGetter(o -> o.chance) + ) + .apply( + instance, + SinglePlantFeatureConfig::new + )); + + public final BlockStateProvider plant; + public final boolean rawHeightmap; + public final int chance; + + public SinglePlantFeatureConfig(Block plant, int radius) { + this(SimpleStateProvider.simple(plant), radius, true, 1); + } + + public SinglePlantFeatureConfig(Block plant, int radius, int chance) { + this(SimpleStateProvider.simple(plant), radius, true, chance); + } + + public SinglePlantFeatureConfig(Block plant, int radius, boolean rawHeightmap) { + this(SimpleStateProvider.simple(plant), radius, rawHeightmap, 1); + } + + public SinglePlantFeatureConfig(Block plant, int radius, boolean rawHeightmap, int chance) { + this(SimpleStateProvider.simple(plant), radius, rawHeightmap, chance); + } + + public SinglePlantFeatureConfig(BlockStateProvider plant, int radius, boolean rawHeightmap, int chance) { + super(radius); + this.plant = plant; + this.rawHeightmap = rawHeightmap; + this.chance = chance; + } + + public BlockState getPlantState(RandomSource rnd, BlockPos pos) { + return plant.getState(rnd, pos); + } + + public static SinglePlantFeatureConfig charnia(Block plant) { + return new SinglePlantFeatureConfig(plant, 6); + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/SkyScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/SkyScatterFeature.java index 9a2f9224..71e024db 100644 --- a/src/main/java/org/betterx/betterend/world/features/SkyScatterFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/SkyScatterFeature.java @@ -9,9 +9,9 @@ import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -public abstract class SkyScatterFeature extends ScatterFeature { - public SkyScatterFeature(int radius) { - super(radius); +public abstract class SkyScatterFeature extends ScatterFeature { + public SkyScatterFeature() { + super(ScatterFeatureConfig.CODEC); } @Override @@ -21,6 +21,7 @@ public abstract class SkyScatterFeature extends ScatterFeature { @Override public boolean canGenerate( + ScatterFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -44,12 +45,12 @@ public abstract class SkyScatterFeature extends ScatterFeature { } @Override - protected boolean canSpawn(WorldGenLevel world, BlockPos pos) { + protected boolean canSpawn(ScatterFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { return true; } @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { + protected BlockPos getCenterGround(ScatterFeatureConfig cfg, WorldGenLevel world, BlockPos pos) { return new BlockPos(pos.getX(), MHelper.randRange(32, 192, world.getRandom()), pos.getZ()); } diff --git a/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantFeature.java b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantFeature.java index 0072218f..27180c76 100644 --- a/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantFeature.java @@ -6,34 +6,35 @@ import org.betterx.bclib.util.BlocksHelper; import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public class UnderwaterPlantFeature extends UnderwaterPlantScatter { - private final Block plant; +public class UnderwaterPlantFeature extends UnderwaterPlantScatter { + private BlockState plant; + + public UnderwaterPlantFeature() { + super(SinglePlantFeatureConfig.CODEC); - public UnderwaterPlantFeature(Block plant, int radius) { - super(radius); - this.plant = plant; } @Override public boolean canGenerate( + SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, BlockPos blockPos, float radius ) { + plant = cfg.getPlantState(random, blockPos); //noinspection deprecation - return super.canSpawn(world, blockPos) && plant.canSurvive(plant.defaultBlockState(), world, blockPos); + return super.canSpawn(cfg, world, blockPos) && plant.getBlock().canSurvive(plant, world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { - if (plant instanceof BaseDoublePlantBlock) { + public void generate(SinglePlantFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + if (plant.getBlock() instanceof BaseDoublePlantBlock) { int rot = random.nextInt(4); - BlockState state = plant.defaultBlockState().setValue(BaseDoublePlantBlock.ROTATION, rot); + BlockState state = plant.setValue(BaseDoublePlantBlock.ROTATION, rot); BlocksHelper.setWithoutUpdate(world, blockPos, state); BlocksHelper.setWithoutUpdate(world, blockPos.above(), state.setValue(BaseDoublePlantBlock.TOP, true)); } else { diff --git a/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantScatter.java b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantScatter.java index a98bfcd2..2fd45dea 100644 --- a/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantScatter.java +++ b/src/main/java/org/betterx/betterend/world/features/UnderwaterPlantScatter.java @@ -2,19 +2,20 @@ package org.betterx.betterend.world.features; import org.betterx.betterend.util.GlobalState; +import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Blocks; -public abstract class UnderwaterPlantScatter extends ScatterFeature { - public UnderwaterPlantScatter(int radius) { - super(radius); +public abstract class UnderwaterPlantScatter extends ScatterFeature { + public UnderwaterPlantScatter(Codec codec) { + super(codec); } @Override - protected BlockPos getCenterGround(WorldGenLevel world, BlockPos pos) { + protected BlockPos getCenterGround(FC cfg, WorldGenLevel world, BlockPos pos) { final MutableBlockPos POS = GlobalState.stateForThread().POS; POS.setX(pos.getX()); POS.setZ(pos.getZ()); @@ -24,6 +25,7 @@ public abstract class UnderwaterPlantScatter extends ScatterFeature { @Override public boolean canGenerate( + FC cfg, WorldGenLevel world, RandomSource random, BlockPos center, @@ -34,12 +36,12 @@ public abstract class UnderwaterPlantScatter extends ScatterFeature { } @Override - protected boolean canSpawn(WorldGenLevel world, BlockPos pos) { + protected boolean canSpawn(FC cfg, WorldGenLevel world, BlockPos pos) { return world.getBlockState(pos).is(Blocks.WATER); } @Override - protected boolean getGroundPlant(WorldGenLevel world, MutableBlockPos pos) { + protected boolean getGroundPlant(FC cfg, WorldGenLevel world, MutableBlockPos pos) { return getGround(world, pos).getY() < 128; } diff --git a/src/main/java/org/betterx/betterend/world/features/VineFeature.java b/src/main/java/org/betterx/betterend/world/features/VineFeature.java index bb7cb01e..87e6cc9b 100644 --- a/src/main/java/org/betterx/betterend/world/features/VineFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/VineFeature.java @@ -8,39 +8,37 @@ import org.betterx.bclib.util.BlocksHelper; import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public class VineFeature extends InvertedScatterFeature { - private final Block vineBlock; - private final int maxLength; - private final boolean vine; +public class VineFeature extends InvertedScatterFeature { + private BlockState plant; + boolean vine; - public VineFeature(Block vineBlock, int maxLength) { - super(6); - this.vineBlock = vineBlock; - this.maxLength = maxLength; - this.vine = vineBlock instanceof BaseVineBlock; + public VineFeature() { + super(VineFeatureConfig.CODEC); } @Override public boolean canGenerate( + VineFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos center, BlockPos blockPos, float radius ) { + plant = cfg.getPlantState(random, blockPos); + BlockState state = world.getBlockState(blockPos); return state.getMaterial().isReplaceable() && canPlaceBlock(state, world, blockPos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos blockPos) { - int h = BlocksHelper.downRay(world, blockPos, random.nextInt(maxLength)) - 1; + public void generate(VineFeatureConfig cfg, WorldGenLevel world, RandomSource random, BlockPos blockPos) { + int h = BlocksHelper.downRay(world, blockPos, random.nextInt(cfg.maxLength)) - 1; if (h > 2) { BlockState top = getTopState(); - BlockState middle = getMiggleState(); + BlockState middle = getMiddleState(); BlockState bottom = getBottomState(); BlocksHelper.setWithoutUpdate(world, blockPos, top); for (int i = 1; i < h; i++) { @@ -51,25 +49,28 @@ public class VineFeature extends InvertedScatterFeature { } private boolean canPlaceBlock(BlockState state, WorldGenLevel world, BlockPos blockPos) { - if (vine) { - return ((BaseVineBlock) vineBlock).canGenerate(state, world, blockPos); + if (plant == null) return false; + if (plant.getBlock() instanceof BaseVineBlock vineBlock) { + vine = true; + return vineBlock.canGenerate(state, world, blockPos); } else { - return vineBlock.canSurvive(state, world, blockPos); + vine = false; + return plant.getBlock().canSurvive(state, world, blockPos); } } private BlockState getTopState() { - BlockState state = vineBlock.defaultBlockState(); + BlockState state = plant; return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.TOP) : state; } - private BlockState getMiggleState() { - BlockState state = vineBlock.defaultBlockState(); + private BlockState getMiddleState() { + BlockState state = plant; return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.MIDDLE) : state; } private BlockState getBottomState() { - BlockState state = vineBlock.defaultBlockState(); + BlockState state = plant; return vine ? state.setValue(BlockProperties.TRIPLE_SHAPE, TripleShape.BOTTOM) : state; } } diff --git a/src/main/java/org/betterx/betterend/world/features/VineFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/VineFeatureConfig.java new file mode 100644 index 00000000..63908104 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/VineFeatureConfig.java @@ -0,0 +1,42 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class VineFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("state").forGetter(o -> o.plant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius), + Codec.INT.fieldOf("max_length").forGetter(o -> o.maxLength) + ) + .apply( + instance, + VineFeatureConfig::new + )); + + + public final BlockStateProvider plant; + public final int maxLength; + + public VineFeatureConfig(Block vineBlock, int maxLength) { + this(SimpleStateProvider.simple(vineBlock), 6, maxLength); + } + + public VineFeatureConfig(BlockStateProvider plant, int radius, int maxLength) { + super(radius); + this.plant = plant; + this.maxLength = maxLength; + } + + public BlockState getPlantState(RandomSource rnd, BlockPos pos) { + return plant.getState(rnd, pos); + } + +} diff --git a/src/main/java/org/betterx/betterend/world/features/WallPlantFeature.java b/src/main/java/org/betterx/betterend/world/features/WallPlantFeature.java index 8e17f5a3..faa053de 100644 --- a/src/main/java/org/betterx/betterend/world/features/WallPlantFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/WallPlantFeature.java @@ -12,34 +12,47 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; -public class WallPlantFeature extends WallScatterFeature { - private final Block block; +public class WallPlantFeature extends WallScatterFeature { + protected BlockState plant; - public WallPlantFeature(Block block, int radius) { - super(radius); - this.block = block; + public WallPlantFeature() { + super(WallPlantFeatureConfig.CODEC); } @Override - public boolean canGenerate(WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir) { + public boolean canGenerate( + WallPlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos pos, + Direction dir + ) { + plant = cfg.getPlantState(random, pos); + Block block = plant.getBlock(); if (block instanceof BaseWallPlantBlock) { - BlockState state = block.defaultBlockState().setValue(BaseWallPlantBlock.FACING, dir); + BlockState state = plant.setValue(BaseWallPlantBlock.FACING, dir); return block.canSurvive(state, world, pos); } else if (block instanceof BaseAttachedBlock) { - BlockState state = block.defaultBlockState().setValue(BlockStateProperties.FACING, dir); + BlockState state = plant.setValue(BlockStateProperties.FACING, dir); return block.canSurvive(state, world, pos); } - return block.canSurvive(block.defaultBlockState(), world, pos); + return block.canSurvive(plant, world, pos); } @Override - public void generate(WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir) { - BlockState state = block.defaultBlockState(); + public void generate( + WallPlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos pos, + Direction dir + ) { + Block block = plant.getBlock(); if (block instanceof BaseWallPlantBlock) { - state = state.setValue(BaseWallPlantBlock.FACING, dir); + plant = plant.setValue(BaseWallPlantBlock.FACING, dir); } else if (block instanceof BaseAttachedBlock) { - state = state.setValue(BlockStateProperties.FACING, dir); + plant = plant.setValue(BlockStateProperties.FACING, dir); } - BlocksHelper.setWithoutUpdate(world, pos, state); + BlocksHelper.setWithoutUpdate(world, pos, plant); } } diff --git a/src/main/java/org/betterx/betterend/world/features/WallPlantFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/WallPlantFeatureConfig.java new file mode 100644 index 00000000..010db91d --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/WallPlantFeatureConfig.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.world.features; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class WallPlantFeatureConfig extends ScatterFeatureConfig { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("state").forGetter(o -> o.plant), + Codec.INT.fieldOf("radius").forGetter(o -> o.radius) + ) + .apply( + instance, + WallPlantFeatureConfig::new + )); + + + public final BlockStateProvider plant; + + public WallPlantFeatureConfig(Block plant, int radius) { + this(SimpleStateProvider.simple(plant), radius); + } + + public WallPlantFeatureConfig(BlockStateProvider plant, int radius) { + super(radius); + this.plant = plant; + } + + public BlockState getPlantState(RandomSource rnd, BlockPos pos) { + return plant.getState(rnd, pos); + } + +} diff --git a/src/main/java/org/betterx/betterend/world/features/WallPlantOnLogFeature.java b/src/main/java/org/betterx/betterend/world/features/WallPlantOnLogFeature.java index b9000ac9..204443c6 100644 --- a/src/main/java/org/betterx/betterend/world/features/WallPlantOnLogFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/WallPlantOnLogFeature.java @@ -5,16 +5,18 @@ import net.minecraft.core.Direction; import net.minecraft.tags.BlockTags; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; public class WallPlantOnLogFeature extends WallPlantFeature { - public WallPlantOnLogFeature(Block block, int radius) { - super(block, radius); - } - @Override - public boolean canGenerate(WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir) { + public boolean canGenerate( + WallPlantFeatureConfig cfg, + WorldGenLevel world, + RandomSource random, + BlockPos pos, + Direction dir + ) { + plant = cfg.getPlantState(random, pos); BlockPos blockPos = pos.relative(dir.getOpposite()); BlockState blockState = world.getBlockState(blockPos); return blockState.is(BlockTags.LOGS); diff --git a/src/main/java/org/betterx/betterend/world/features/WallScatterFeature.java b/src/main/java/org/betterx/betterend/world/features/WallScatterFeature.java index d6a770f0..4e610908 100644 --- a/src/main/java/org/betterx/betterend/world/features/WallScatterFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/WallScatterFeature.java @@ -1,32 +1,32 @@ package org.betterx.betterend.world.features; -import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.util.BlocksHelper; import org.betterx.bclib.util.MHelper; +import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -public abstract class WallScatterFeature extends DefaultFeature { +public abstract class WallScatterFeature extends Feature { private static final Direction[] DIR = BlocksHelper.makeHorizontal(); - private final int radius; - public WallScatterFeature(int radius) { - this.radius = radius; + public WallScatterFeature(Codec codec) { + super(codec); } - public abstract boolean canGenerate(WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir); + public abstract boolean canGenerate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir); - public abstract void generate(WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir); + public abstract void generate(FC cfg, WorldGenLevel world, RandomSource random, BlockPos pos, Direction dir); @Override - public boolean place(FeaturePlaceContext featureConfig) { + public boolean place(FeaturePlaceContext featureConfig) { + FC cfg = featureConfig.config(); final RandomSource random = featureConfig.random(); final BlockPos center = featureConfig.origin(); final WorldGenLevel world = featureConfig.level(); @@ -38,17 +38,17 @@ public abstract class WallScatterFeature extends DefaultFeature { int py = MHelper.randRange(minY, maxY, random); MutableBlockPos mut = new MutableBlockPos(); - for (int x = -radius; x <= radius; x++) { + for (int x = -cfg.radius; x <= cfg.radius; x++) { mut.setX(center.getX() + x); - for (int y = -radius; y <= radius; y++) { + for (int y = -cfg.radius; y <= cfg.radius; y++) { mut.setY(py + y); - for (int z = -radius; z <= radius; z++) { + for (int z = -cfg.radius; z <= cfg.radius; z++) { mut.setZ(center.getZ() + z); if (random.nextInt(4) == 0 && world.isEmptyBlock(mut)) { shuffle(random); for (Direction dir : DIR) { - if (canGenerate(world, random, mut, dir)) { - generate(world, random, mut, dir); + if (canGenerate(cfg, world, random, mut, dir)) { + generate(cfg, world, random, mut, dir); break; } } diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeature.java index 43fa070b..eb174b41 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeature.java @@ -14,32 +14,25 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; -import com.google.common.collect.Lists; - -import java.util.List; -import java.util.function.Function; - -public class ArchFeature extends DefaultFeature { - private final Function surfaceFunction; - private final Block block; - - public ArchFeature(Block block, Function surfaceFunction) { - this.surfaceFunction = surfaceFunction; - this.block = block; +public class ArchFeature extends Feature { + public ArchFeature() { + super(ArchFeatureConfig.CODEC); } @Override - public boolean place(FeaturePlaceContext featurePlaceContext) { + public boolean place(FeaturePlaceContext featurePlaceContext) { + ArchFeatureConfig cfg = featurePlaceContext.config(); final WorldGenLevel world = featurePlaceContext.level(); BlockPos origin = featurePlaceContext.origin(); RandomSource random = featurePlaceContext.random(); - - BlockPos pos = getPosOnSurfaceWG( + BlockState cfgBlockState = cfg.block.getState(random, origin); + Block cfgBlock = cfgBlockState.getBlock(); + BlockPos pos = DefaultFeature.getPosOnSurfaceWG( world, new BlockPos((origin.getX() & 0xFFFFFFF0) | 7, 0, (origin.getZ() & 0xFFFFFFF0) | 7) ); @@ -52,27 +45,24 @@ public class ArchFeature extends DefaultFeature { if (smallRadius + bigRadius > 23) { smallRadius = 23 - bigRadius; } - SDF arch = new SDFTorus().setBigRadius(bigRadius).setSmallRadius(smallRadius).setBlock(block); + SDF arch = new SDFTorus().setBigRadius(bigRadius).setSmallRadius(smallRadius).setBlock(cfgBlock); arch = new SDFRotation().setRotation(MHelper.randomHorizontal(random), (float) Math.PI * 0.5F).setSource(arch); final float smallRadiusF = smallRadius; OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); - arch = new SDFDisplacement().setFunction((vec) -> { - return (float) (Math.abs(noise.eval( - vec.x() * 0.1, - vec.y() * 0.1, - vec.z() * 0.1 - )) * 3F + Math.abs(noise.eval( - vec.x() * 0.3, - vec.y() * 0.3 + 100, - vec.z() * 0.3 - )) * 1.3F) - smallRadiusF * Math.abs(1 - vec.y() / bigRadius); - }).setSource(arch); + arch = new SDFDisplacement().setFunction((vec) -> (float) (Math.abs(noise.eval( + vec.x() * 0.1, + vec.y() * 0.1, + vec.z() * 0.1 + )) * 3F + Math.abs(noise.eval( + vec.x() * 0.3, + vec.y() * 0.3 + 100, + vec.z() * 0.3 + )) * 1.3F) - smallRadiusF * Math.abs(1 - vec.y() / bigRadius)).setSource(arch); - List surface = Lists.newArrayList(); arch.addPostProcess((info) -> { if (info.getStateUp().isAir()) { - return surfaceFunction.apply(info.getPos()); + return cfg.surfaceFunction.apply(info.getPos()); } return info.getState(); }); diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeatureConfig.java new file mode 100644 index 00000000..b4c47aca --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ArchFeatureConfig.java @@ -0,0 +1,58 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.betterend.world.biome.land.UmbraValleyBiome; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +import java.util.function.Function; + +public class ArchFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("states").forGetter(o -> o.block), + SurfaceFunction.CODEC.fieldOf("surface_function").forGetter(o -> o.surfaceFunction) + ) + .apply(instance, ArchFeatureConfig::new)); + + + public final BlockStateProvider block; + public final SurfaceFunction surfaceFunction; + + public ArchFeatureConfig(Block block, SurfaceFunction surfaceFunction) { + this(SimpleStateProvider.simple(block), surfaceFunction); + } + + public ArchFeatureConfig(BlockStateProvider block, SurfaceFunction surfaceFunction) { + this.block = block; + this.surfaceFunction = surfaceFunction; + } + + public enum SurfaceFunction implements StringRepresentable { + UMBRA_VALLEY("umbra_valley", pos -> UmbraValleyBiome.getSurface(pos.getX(), pos.getZ()).defaultBlockState()); + public static final Codec CODEC = StringRepresentable.fromEnum(SurfaceFunction::values); + private final Function surfaceFunction; + private final String name; + + SurfaceFunction(String name, Function surfaceFunction) { + this.name = name; + this.surfaceFunction = surfaceFunction; + } + + @Override + public String getSerializedName() { + return name; + } + + public BlockState apply(BlockPos pos) { + return this.surfaceFunction.apply(pos); + } + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeature.java index 2cfa790c..33ed406e 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeature.java @@ -1,59 +1,46 @@ package org.betterx.betterend.world.features.terrain; -import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.sdf.SDF; import org.betterx.bclib.sdf.operator.SDFCoordModify; import org.betterx.bclib.sdf.operator.SDFScale3D; import org.betterx.bclib.sdf.primitive.SDFSphere; import org.betterx.bclib.util.MHelper; -import org.betterx.betterend.noise.OpenSimplexNoise; import net.minecraft.core.BlockPos; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; -public class OreLayerFeature extends DefaultFeature { +public class OreLayerFeature extends Feature { private static final SDFSphere SPHERE; private static final SDFCoordModify NOISE; private static final SDF FUNCTION; - private final BlockState state; - private final float radius; - private final int minY; - private final int maxY; - private OpenSimplexNoise noise; - public OreLayerFeature(BlockState state, float radius, int minY, int maxY) { - this.state = state; - this.radius = radius; - this.minY = minY; - this.maxY = maxY; + public OreLayerFeature() { + super(OreLayerFeatureConfig.CODEC); } @Override - public boolean place(FeaturePlaceContext featureConfig) { + public boolean place(FeaturePlaceContext featureConfig) { + final OreLayerFeatureConfig cfg = featureConfig.config(); final RandomSource random = featureConfig.random(); final BlockPos pos = featureConfig.origin(); final WorldGenLevel world = featureConfig.level(); - float radius = this.radius * 0.5F; + float radius = cfg.radius * 0.5F; int r = MHelper.floor(radius + 1); int posX = MHelper.randRange(Math.max(r - 16, 0), Math.min(31 - r, 15), random) + pos.getX(); int posZ = MHelper.randRange(Math.max(r - 16, 0), Math.min(31 - r, 15), random) + pos.getZ(); - int posY = MHelper.randRange(minY, maxY, random); + int posY = MHelper.randRange(cfg.minY, cfg.maxY, random); - if (noise == null) { - noise = new OpenSimplexNoise(world.getSeed()); - } - SPHERE.setRadius(radius).setBlock(state); + SPHERE.setRadius(radius).setBlock(cfg.state); NOISE.setFunction((vec) -> { double x = (vec.x() + pos.getX()) * 0.1; double z = (vec.z() + pos.getZ()) * 0.1; - double offset = noise.eval(x, z); + double offset = cfg.getNoise(world.getSeed()).eval(x, z); vec.set(vec.x(), vec.y() + (float) offset * 8, vec.z()); }); FUNCTION.fillRecursive(world, new BlockPos(posX, posY, posZ)); diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeatureConfig.java new file mode 100644 index 00000000..87eb0015 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/OreLayerFeatureConfig.java @@ -0,0 +1,39 @@ +package org.betterx.betterend.world.features.terrain; + +import org.betterx.betterend.noise.OpenSimplexNoise; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public class OreLayerFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockState.CODEC.fieldOf("state").forGetter(o -> o.state), + Codec.FLOAT.fieldOf("radius").forGetter(o -> o.radius), + Codec.INT.fieldOf("min_y").forGetter(o -> o.minY), + Codec.INT.fieldOf("max_y").forGetter(o -> o.maxY) + ) + .apply(instance, OreLayerFeatureConfig::new)); + + public final BlockState state; + public final float radius; + public final int minY; + public final int maxY; + private OpenSimplexNoise noise; + + public OreLayerFeatureConfig(BlockState state, float radius, int minY, int maxY) { + this.state = state; + this.radius = radius; + this.minY = minY; + this.maxY = maxY; + } + + public OpenSimplexNoise getNoise(long seed) { + if (noise == null) { + noise = new OpenSimplexNoise(seed); + } + return noise; + } +} diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeature.java index 0295f311..9324b963 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeature.java @@ -17,25 +17,28 @@ import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; -public class ThinArchFeature extends DefaultFeature { - private final Block block; +public class ThinArchFeature extends Feature { - public ThinArchFeature(Block block) { - this.block = block; + public ThinArchFeature() { + super(ThinArchFeatureConfig.CODEC); } @Override - public boolean place(FeaturePlaceContext featurePlaceContext) { + public boolean place(FeaturePlaceContext featurePlaceContext) { + final ThinArchFeatureConfig cfg = featurePlaceContext.config(); final WorldGenLevel world = featurePlaceContext.level(); BlockPos origin = featurePlaceContext.origin(); RandomSource random = featurePlaceContext.random(); + BlockState state = cfg.block.getState(random, origin); + Block block = state.getBlock(); - BlockPos pos = getPosOnSurfaceWG( + BlockPos pos = DefaultFeature.getPosOnSurfaceWG( world, new BlockPos( (origin.getX() & 0xFFFFFFF0) | 7, diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeatureConfig.java new file mode 100644 index 00000000..e0531836 --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/ThinArchFeatureConfig.java @@ -0,0 +1,28 @@ +package org.betterx.betterend.world.features.terrain; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.SimpleStateProvider; + +public class ThinArchFeatureConfig implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + BlockStateProvider.CODEC.fieldOf("states").forGetter(o -> o.block) + ) + .apply(instance, ThinArchFeatureConfig::new)); + + + public final BlockStateProvider block; + + public ThinArchFeatureConfig(Block block) { + this(SimpleStateProvider.simple(block)); + } + + public ThinArchFeatureConfig(BlockStateProvider block) { + this.block = block; + } +} + diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java index 1fc051dc..d8ec9a3d 100644 --- a/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeature.java @@ -1,6 +1,5 @@ package org.betterx.betterend.world.features.terrain.caves; -import org.betterx.bclib.api.v2.levelgen.features.features.DefaultFeature; import org.betterx.bclib.util.BlocksHelper; import org.betterx.betterend.util.BlockFixer; import org.betterx.betterend.world.biome.cave.EndCaveBiome; @@ -15,23 +14,21 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import com.google.common.collect.Sets; import java.util.Optional; import java.util.Set; -import java.util.function.Supplier; -public class CaveChunkPopulatorFeature extends DefaultFeature { - private final Supplier supplier; +public class CaveChunkPopulatorFeature extends Feature { - public CaveChunkPopulatorFeature(Supplier biome) { - this.supplier = biome; + public CaveChunkPopulatorFeature() { + super(CaveChunkPopulatorFeatureConfig.CODEC); } @Override - public boolean place(FeaturePlaceContext featureConfig) { + public boolean place(FeaturePlaceContext featureConfig) { + CaveChunkPopulatorFeatureConfig cfg = featureConfig.config(); final RandomSource random = featureConfig.random(); final BlockPos pos = featureConfig.origin(); final WorldGenLevel world = featureConfig.level(); @@ -42,7 +39,7 @@ public class CaveChunkPopulatorFeature extends DefaultFeature { MutableBlockPos min = new MutableBlockPos().set(pos); MutableBlockPos max = new MutableBlockPos().set(pos); fillSets(sx, sz, world.getChunk(pos), floorPositions, ceilPositions, min, max); - EndCaveBiome biome = supplier.get(); + EndCaveBiome biome = cfg.getCaveBiome(); BlockState surfaceBlock = Blocks.END_STONE.defaultBlockState(); //biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial(); placeFloor(world, biome, floorPositions, random, surfaceBlock); placeCeil(world, biome, ceilPositions, random); diff --git a/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeatureConfig.java b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeatureConfig.java new file mode 100644 index 00000000..a272dc9a --- /dev/null +++ b/src/main/java/org/betterx/betterend/world/features/terrain/caves/CaveChunkPopulatorFeatureConfig.java @@ -0,0 +1,19 @@ +package org.betterx.betterend.world.features.terrain.caves; + +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.betterend.world.biome.cave.EndCaveBiome; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; + +public record CaveChunkPopulatorFeatureConfig(ResourceLocation biomeID) implements FeatureConfiguration { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group(ResourceLocation.CODEC.fieldOf("biome").forGetter(o -> o.biomeID)) + .apply(instance, CaveChunkPopulatorFeatureConfig::new)); + + public EndCaveBiome getCaveBiome() { + return (EndCaveBiome) BiomeAPI.getBiome(biomeID); + } +}