From c5a594accaacc2951b6d7cf4c0499b0fc57fa519 Mon Sep 17 00:00:00 2001 From: Kaupenjoe Date: Wed, 15 Nov 2023 19:06:40 +0100 Subject: [PATCH] custom biomes --- build.gradle | 6 +- gradle.properties | 3 + settings.gradle | 1 + .../103d9f3f36b01595f1aa5172191e60eff02e6924 | 3 +- .../worldgen/biome/test_biome.json | 207 ++++++++++++++++++ .../kaupenjoe/tutorialmod/TutorialMod.java | 6 + .../datagen/ModWorldGenProvider.java | 4 +- .../tutorialmod/worldgen/biome/ModBiomes.java | 78 +++++++ .../worldgen/biome/ModOverworldRegion.java | 26 +++ .../worldgen/biome/ModTerrablender.java | 11 + .../biome/surface/ModSurfaceRules.java | 35 +++ src/main/resources/META-INF/mods.toml | 7 + 12 files changed, 384 insertions(+), 3 deletions(-) create mode 100644 src/generated/resources/data/tutorialmod/worldgen/biome/test_biome.json create mode 100644 src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModBiomes.java create mode 100644 src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModOverworldRegion.java create mode 100644 src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModTerrablender.java create mode 100644 src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/surface/ModSurfaceRules.java diff --git a/build.gradle b/build.gradle index 3e8e3cf..8b14f39 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ plugins { id 'maven-publish' id 'net.minecraftforge.gradle' version '[6.0,6.2)' id 'org.parchmentmc.librarian.forgegradle' version '1.+' + id 'org.spongepowered.mixin' version '0.7-SNAPSHOT' apply true } version = mod_version @@ -180,6 +181,8 @@ dependencies { // at runtime, use the full JEI jar for Forge runtimeOnly(fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${jei_version}")) + implementation fg.deobf("com.github.glitchfiend:TerraBlender-forge:${minecraft_version}-${terrablender_version}") + // Example mod dependency using a mod jar from ./libs with a flat dir repository // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar // The group id is ignored when searching -- in this case, it is "blank" @@ -200,7 +203,8 @@ def replaceProperties = [ forge_version: forge_version, forge_version_range: forge_version_range, loader_version_range: loader_version_range, mod_id: mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, - mod_authors: mod_authors, mod_description: mod_description + mod_authors: mod_authors, mod_description: mod_description, + terrablender_version_range: terrablender_version_range ] processResources { inputs.properties replaceProperties diff --git a/gradle.properties b/gradle.properties index a7204f2..ae99435 100644 --- a/gradle.properties +++ b/gradle.properties @@ -41,6 +41,9 @@ mapping_version=2023.06.26-1.20.1 ## Dependency Properties jei_version=15.2.0.27 +terrablender_version=3.0.0.169 +terrablender_version_range=[3.0.0.169,) + ## Mod Properties diff --git a/settings.gradle b/settings.gradle index b7fe2dc..1e4b6e7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,6 +6,7 @@ pluginManagement { url = 'https://maven.minecraftforge.net/' } maven { url = 'https://maven.parchmentmc.org' } + maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } } } diff --git a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 index 99ecab7..c44d8de 100644 --- a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 +++ b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 @@ -1,8 +1,9 @@ -// 1.20.1 2023-11-09T17:22:52.1443876 Registries +// 1.20.1 2023-11-15T18:58:01.8034533 Registries 51c9eccab97082d42b64f544d2177b5d81ad7822 data/tutorialmod/forge/biome_modifier/add_end_sapphire_ore.json 64776d3eaf666ec57a7e039d2d4b5801202f71c5 data/tutorialmod/forge/biome_modifier/add_nether_sapphire_ore.json 6e10223d8ca98f02feea2da07585014b7a38b1e4 data/tutorialmod/forge/biome_modifier/add_sapphire_ore.json 7abbc38508270c3ef909f11615161f9ff69837f7 data/tutorialmod/forge/biome_modifier/add_tree_pine.json +0035d9c75212e96cccaec16bb237fb0d6b98fe08 data/tutorialmod/worldgen/biome/test_biome.json 71c606e75851b75cbba5b8f0682fcf5b5af6df8e data/tutorialmod/worldgen/configured_feature/end_sapphire_ore.json 5ad8ebc3f43d28d4e7f41e38e69091f380cde75b data/tutorialmod/worldgen/configured_feature/nether_sapphire_ore.json a4f8bd2fb532c269b5a7e4f8322c0f822cb46cdc data/tutorialmod/worldgen/configured_feature/pine.json diff --git a/src/generated/resources/data/tutorialmod/worldgen/biome/test_biome.json b/src/generated/resources/data/tutorialmod/worldgen/biome/test_biome.json new file mode 100644 index 0000000..c5cbb2a --- /dev/null +++ b/src/generated/resources/data/tutorialmod/worldgen/biome/test_biome.json @@ -0,0 +1,207 @@ +{ + "carvers": { + "air": [ + "minecraft:cave", + "minecraft:cave_extra_underground", + "minecraft:canyon" + ] + }, + "downfall": 0.8, + "effects": { + "fog_color": 2269670, + "foliage_color": 13763580, + "grass_color": 8324092, + "mood_sound": { + "block_search_extent": 8, + "offset": 2.0, + "sound": "minecraft:ambient.cave", + "tick_delay": 6000 + }, + "music": { + "max_delay": 24000, + "min_delay": 12000, + "replace_current_music": false, + "sound": "tutorialmod:bar_brawl" + }, + "sky_color": 3197208, + "water_color": 15216187, + "water_fog_color": 12524326 + }, + "features": [ + [], + [ + "minecraft:lake_lava_underground", + "minecraft:lake_lava_surface" + ], + [ + "minecraft:amethyst_geode", + "minecraft:forest_rock" + ], + [ + "minecraft:monster_room", + "minecraft:monster_room_deep" + ], + [], + [], + [ + "minecraft:ore_dirt", + "minecraft:ore_gravel", + "minecraft:ore_granite_upper", + "minecraft:ore_granite_lower", + "minecraft:ore_diorite_upper", + "minecraft:ore_diorite_lower", + "minecraft:ore_andesite_upper", + "minecraft:ore_andesite_lower", + "minecraft:ore_tuff", + "minecraft:ore_coal_upper", + "minecraft:ore_coal_lower", + "minecraft:ore_iron_upper", + "minecraft:ore_iron_middle", + "minecraft:ore_iron_small", + "minecraft:ore_gold", + "minecraft:ore_gold_lower", + "minecraft:ore_redstone", + "minecraft:ore_redstone_lower", + "minecraft:ore_diamond", + "minecraft:ore_diamond_large", + "minecraft:ore_diamond_buried", + "minecraft:ore_lapis", + "minecraft:ore_lapis_buried", + "minecraft:ore_copper", + "minecraft:underwater_magma", + "minecraft:ore_gold_extra" + ], + [], + [ + "minecraft:spring_water", + "minecraft:spring_lava" + ], + [ + "minecraft:glow_lichen", + "minecraft:forest_flowers", + "minecraft:patch_large_fern", + "minecraft:trees_plains", + "minecraft:brown_mushroom_normal", + "minecraft:red_mushroom_normal", + "minecraft:patch_sugar_cane", + "minecraft:patch_pumpkin", + "tutorialmod:pine_placed" + ], + [ + "minecraft:freeze_top_layer" + ] + ], + "has_precipitation": true, + "spawn_costs": {}, + "spawners": { + "ambient": [ + { + "type": "minecraft:bat", + "maxCount": 8, + "minCount": 8, + "weight": 10 + } + ], + "axolotls": [], + "creature": [ + { + "type": "tutorialmod:rhino", + "maxCount": 5, + "minCount": 3, + "weight": 2 + }, + { + "type": "minecraft:wolf", + "maxCount": 4, + "minCount": 4, + "weight": 5 + }, + { + "type": "minecraft:sheep", + "maxCount": 4, + "minCount": 4, + "weight": 12 + }, + { + "type": "minecraft:pig", + "maxCount": 4, + "minCount": 4, + "weight": 10 + }, + { + "type": "minecraft:chicken", + "maxCount": 4, + "minCount": 4, + "weight": 10 + }, + { + "type": "minecraft:cow", + "maxCount": 4, + "minCount": 4, + "weight": 8 + } + ], + "misc": [], + "monster": [ + { + "type": "minecraft:spider", + "maxCount": 4, + "minCount": 4, + "weight": 100 + }, + { + "type": "minecraft:zombie", + "maxCount": 4, + "minCount": 4, + "weight": 95 + }, + { + "type": "minecraft:zombie_villager", + "maxCount": 1, + "minCount": 1, + "weight": 5 + }, + { + "type": "minecraft:skeleton", + "maxCount": 4, + "minCount": 4, + "weight": 100 + }, + { + "type": "minecraft:creeper", + "maxCount": 4, + "minCount": 4, + "weight": 100 + }, + { + "type": "minecraft:slime", + "maxCount": 4, + "minCount": 4, + "weight": 100 + }, + { + "type": "minecraft:enderman", + "maxCount": 4, + "minCount": 1, + "weight": 10 + }, + { + "type": "minecraft:witch", + "maxCount": 1, + "minCount": 1, + "weight": 5 + } + ], + "underground_water_creature": [ + { + "type": "minecraft:glow_squid", + "maxCount": 6, + "minCount": 4, + "weight": 10 + } + ], + "water_ambient": [], + "water_creature": [] + }, + "temperature": 0.7 +} \ No newline at end of file diff --git a/src/main/java/net/kaupenjoe/tutorialmod/TutorialMod.java b/src/main/java/net/kaupenjoe/tutorialmod/TutorialMod.java index 0349afa..8c043c8 100644 --- a/src/main/java/net/kaupenjoe/tutorialmod/TutorialMod.java +++ b/src/main/java/net/kaupenjoe/tutorialmod/TutorialMod.java @@ -15,6 +15,8 @@ import net.kaupenjoe.tutorialmod.screen.ModMenuTypes; import net.kaupenjoe.tutorialmod.sound.ModSounds; import net.kaupenjoe.tutorialmod.util.ModWoodTypes; import net.kaupenjoe.tutorialmod.villager.ModVillagers; +import net.kaupenjoe.tutorialmod.worldgen.biome.ModTerrablender; +import net.kaupenjoe.tutorialmod.worldgen.biome.surface.ModSurfaceRules; import net.kaupenjoe.tutorialmod.worldgen.tree.ModFoliagePlacers; import net.kaupenjoe.tutorialmod.worldgen.tree.ModTrunkPlacerTypes; import net.minecraft.client.gui.screens.MenuScreens; @@ -37,6 +39,7 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.slf4j.Logger; +import terrablender.api.SurfaceRuleManager; // The value here should match an entry in the META-INF/mods.toml file @Mod(TutorialMod.MOD_ID) @@ -65,6 +68,7 @@ public class TutorialMod { ModTrunkPlacerTypes.register(modEventBus); ModFoliagePlacers.register(modEventBus); + ModTerrablender.registerBiomes(); modEventBus.addListener(this::commonSetup); @@ -75,6 +79,8 @@ public class TutorialMod { private void commonSetup(final FMLCommonSetupEvent event) { event.enqueueWork(() -> { ((FlowerPotBlock) Blocks.FLOWER_POT).addPlant(ModBlocks.CATMINT.getId(), ModBlocks.POTTED_CATMINT); + + SurfaceRuleManager.addSurfaceRules(SurfaceRuleManager.RuleCategory.OVERWORLD, MOD_ID, ModSurfaceRules.makeRules()); }); } diff --git a/src/main/java/net/kaupenjoe/tutorialmod/datagen/ModWorldGenProvider.java b/src/main/java/net/kaupenjoe/tutorialmod/datagen/ModWorldGenProvider.java index fd8aee9..7704133 100644 --- a/src/main/java/net/kaupenjoe/tutorialmod/datagen/ModWorldGenProvider.java +++ b/src/main/java/net/kaupenjoe/tutorialmod/datagen/ModWorldGenProvider.java @@ -4,6 +4,7 @@ import net.kaupenjoe.tutorialmod.TutorialMod; import net.kaupenjoe.tutorialmod.worldgen.ModBiomeModifiers; import net.kaupenjoe.tutorialmod.worldgen.ModConfiguredFeatures; import net.kaupenjoe.tutorialmod.worldgen.ModPlacedFeatures; +import net.kaupenjoe.tutorialmod.worldgen.biome.ModBiomes; import net.minecraft.core.HolderLookup; import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.registries.Registries; @@ -18,7 +19,8 @@ public class ModWorldGenProvider extends DatapackBuiltinEntriesProvider { public static final RegistrySetBuilder BUILDER = new RegistrySetBuilder() .add(Registries.CONFIGURED_FEATURE, ModConfiguredFeatures::bootstrap) .add(Registries.PLACED_FEATURE, ModPlacedFeatures::bootstrap) - .add(ForgeRegistries.Keys.BIOME_MODIFIERS, ModBiomeModifiers::bootstrap); + .add(ForgeRegistries.Keys.BIOME_MODIFIERS, ModBiomeModifiers::bootstrap) + .add(Registries.BIOME, ModBiomes::boostrap); public ModWorldGenProvider(PackOutput output, CompletableFuture registries) { super(output, registries, BUILDER, Set.of(TutorialMod.MOD_ID)); diff --git a/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModBiomes.java b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModBiomes.java new file mode 100644 index 0000000..1d0f25c --- /dev/null +++ b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModBiomes.java @@ -0,0 +1,78 @@ +package net.kaupenjoe.tutorialmod.worldgen.biome; + +import net.kaupenjoe.tutorialmod.TutorialMod; +import net.kaupenjoe.tutorialmod.entity.ModEntities; +import net.kaupenjoe.tutorialmod.sound.ModSounds; +import net.kaupenjoe.tutorialmod.worldgen.ModPlacedFeatures; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.worldgen.BiomeDefaultFeatures; +import net.minecraft.data.worldgen.BootstapContext; +import net.minecraft.data.worldgen.placement.VegetationPlacements; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.Musics; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.*; +import net.minecraft.world.level.levelgen.GenerationStep; + +public class ModBiomes { + public static final ResourceKey TEST_BIOME = ResourceKey.create(Registries.BIOME, + new ResourceLocation(TutorialMod.MOD_ID, "test_biome")); + + public static void boostrap(BootstapContext context) { + context.register(TEST_BIOME, testBiome(context)); + } + + public static void globalOverworldGeneration(BiomeGenerationSettings.Builder builder) { + BiomeDefaultFeatures.addDefaultCarversAndLakes(builder); + BiomeDefaultFeatures.addDefaultCrystalFormations(builder); + BiomeDefaultFeatures.addDefaultMonsterRoom(builder); + BiomeDefaultFeatures.addDefaultUndergroundVariety(builder); + BiomeDefaultFeatures.addDefaultSprings(builder); + BiomeDefaultFeatures.addSurfaceFreezing(builder); + } + + public static Biome testBiome(BootstapContext context) { + MobSpawnSettings.Builder spawnBuilder = new MobSpawnSettings.Builder(); + spawnBuilder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(ModEntities.RHINO.get(), 2, 3, 5)); + + spawnBuilder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.WOLF, 5, 4, 4)); + + BiomeDefaultFeatures.farmAnimals(spawnBuilder); + BiomeDefaultFeatures.commonSpawns(spawnBuilder); + + BiomeGenerationSettings.Builder biomeBuilder = + new BiomeGenerationSettings.Builder(context.lookup(Registries.PLACED_FEATURE), context.lookup(Registries.CONFIGURED_CARVER)); + //we need to follow the same order as vanilla biomes for the BiomeDefaultFeatures + globalOverworldGeneration(biomeBuilder); + BiomeDefaultFeatures.addMossyStoneBlock(biomeBuilder); + BiomeDefaultFeatures.addForestFlowers(biomeBuilder); + BiomeDefaultFeatures.addFerns(biomeBuilder); + BiomeDefaultFeatures.addDefaultOres(biomeBuilder); + BiomeDefaultFeatures.addExtraGold(biomeBuilder); + + biomeBuilder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_PLAINS); + + BiomeDefaultFeatures.addDefaultMushrooms(biomeBuilder); + BiomeDefaultFeatures.addDefaultExtraVegetation(biomeBuilder); + biomeBuilder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, ModPlacedFeatures.PINE_PLACED_KEY); + + return new Biome.BiomeBuilder() + .hasPrecipitation(true) + .downfall(0.8f) + .temperature(0.7f) + .generationSettings(biomeBuilder.build()) + .mobSpawnSettings(spawnBuilder.build()) + .specialEffects((new BiomeSpecialEffects.Builder()) + .waterColor(0xe82e3b) + .waterFogColor(0xbf1b26) + .skyColor(0x30c918) + .grassColorOverride(0x7f03fc) + .foliageColorOverride(0xd203fc) + .fogColor(0x22a1e6) + .ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS) + .backgroundMusic(Musics.createGameMusic(ModSounds.BAR_BRAWL.getHolder().get())).build()) + .build(); + } +} diff --git a/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModOverworldRegion.java b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModOverworldRegion.java new file mode 100644 index 0000000..16d19a4 --- /dev/null +++ b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModOverworldRegion.java @@ -0,0 +1,26 @@ +package net.kaupenjoe.tutorialmod.worldgen.biome; + +import com.mojang.datafixers.util.Pair; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.biome.Climate; +import terrablender.api.Region; +import terrablender.api.RegionType; + +import java.util.function.Consumer; + +public class ModOverworldRegion extends Region { + public ModOverworldRegion(ResourceLocation name, int weight) { + super(name, RegionType.OVERWORLD, weight); + } + + @Override + public void addBiomes(Registry registry, Consumer>> mapper) { + this.addModifiedVanillaOverworldBiomes(mapper, modifiedVanillaOverworldBuilder -> { + modifiedVanillaOverworldBuilder.replaceBiome(Biomes.FOREST, ModBiomes.TEST_BIOME); + }); + } +} diff --git a/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModTerrablender.java b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModTerrablender.java new file mode 100644 index 0000000..26bddd7 --- /dev/null +++ b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/ModTerrablender.java @@ -0,0 +1,11 @@ +package net.kaupenjoe.tutorialmod.worldgen.biome; + +import net.kaupenjoe.tutorialmod.TutorialMod; +import net.minecraft.resources.ResourceLocation; +import terrablender.api.Regions; + +public class ModTerrablender { + public static void registerBiomes() { + Regions.register(new ModOverworldRegion(new ResourceLocation(TutorialMod.MOD_ID, "overworld"), 5)); + } +} diff --git a/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/surface/ModSurfaceRules.java b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/surface/ModSurfaceRules.java new file mode 100644 index 0000000..43b6b31 --- /dev/null +++ b/src/main/java/net/kaupenjoe/tutorialmod/worldgen/biome/surface/ModSurfaceRules.java @@ -0,0 +1,35 @@ +package net.kaupenjoe.tutorialmod.worldgen.biome.surface; + +import net.kaupenjoe.tutorialmod.block.ModBlocks; +import net.kaupenjoe.tutorialmod.worldgen.biome.ModBiomes; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.SurfaceRules; + +public class ModSurfaceRules { + private static final SurfaceRules.RuleSource DIRT = makeStateRule(Blocks.DIRT); + private static final SurfaceRules.RuleSource GRASS_BLOCK = makeStateRule(Blocks.GRASS_BLOCK); + private static final SurfaceRules.RuleSource SAPPHIRE = makeStateRule(ModBlocks.SAPPHIRE_BLOCK.get()); + private static final SurfaceRules.RuleSource RAW_SAPPHIRE = makeStateRule(ModBlocks.RAW_SAPPHIRE_BLOCK.get()); + + + public static SurfaceRules.RuleSource makeRules() { + SurfaceRules.ConditionSource isAtOrAboveWaterLevel = SurfaceRules.waterBlockCheck(-1, 0); + + SurfaceRules.RuleSource grassSurface = SurfaceRules.sequence(SurfaceRules.ifTrue(isAtOrAboveWaterLevel, GRASS_BLOCK), DIRT); + + return SurfaceRules.sequence( + SurfaceRules.sequence(SurfaceRules.ifTrue(SurfaceRules.isBiome(ModBiomes.TEST_BIOME), + SurfaceRules.ifTrue(SurfaceRules.ON_FLOOR, RAW_SAPPHIRE)), + SurfaceRules.ifTrue(SurfaceRules.ON_CEILING, SAPPHIRE)), + + + // Default to a grass and dirt surface + SurfaceRules.ifTrue(SurfaceRules.ON_FLOOR, grassSurface) + ); + } + + private static SurfaceRules.RuleSource makeStateRule(Block block) { + return SurfaceRules.state(block.defaultBlockState()); + } +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 3f5f56d..701aab7 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -62,3 +62,10 @@ description='''${mod_description}''' versionRange="${minecraft_version_range}" ordering="NONE" side="BOTH" +[[dependencies.${mod_id}]] + modId="terrablender" + mandatory=true + # This version range declares a minimum of the current minecraft version up to but not including the next major version + versionRange="${terrablender_version_range}" + ordering="NONE" + side="BOTH"