From edb8a83e7723c095e77c3decf9fb37c3ff96c710 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 19 Jun 2023 17:36:10 +0200 Subject: [PATCH] [Change] Make sure we also load all vanilla Dimensions when merging Biomes (quiqueck/BetterNether#138) --- .../api/v2/levelgen/biomes/BiomeAPI.java | 7 ++ .../together/levelgen/BiomeRepairHelper.java | 107 ++++++++++++++++++ .../together/levelgen/WorldGenUtil.java | 66 +---------- 3 files changed, 115 insertions(+), 65 deletions(-) create mode 100644 src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java index ca68906e..be306655 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java @@ -193,6 +193,13 @@ public class BiomeAPI { public final BiomeType parentOrNull; private final String name; + public static BiomeType getMainBiomeTypeForDimension(ResourceKey key) { + if (key.equals(LevelStem.END)) return END_LAND; + else if (key.equals(LevelStem.NETHER)) return NETHER; + else if (key.equals(LevelStem.OVERWORLD)) return OVERWORLD; + return null; + } + @FunctionalInterface interface ExtraRegisterTaks { void register(@NotNull BCLBiome biome, @Nullable BCLBiome parent); diff --git a/src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java b/src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java new file mode 100644 index 00000000..0a0c0207 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/levelgen/BiomeRepairHelper.java @@ -0,0 +1,107 @@ +package org.betterx.worlds.together.levelgen; + +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; +import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry; +import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; +import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; +import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; +import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; +import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; + +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.dimension.LevelStem; + +import java.util.Map; + +class BiomeRepairHelper { + private Map, ChunkGenerator> vanillaDimensions = null; + + public Registry repairBiomeSourceInAllDimensions( + RegistryAccess registryAccess, + Registry dimensionRegistry + ) { + + Map, ChunkGenerator> dimensions = TogetherWorldPreset.loadWorldDimensions(); + for (var entry : dimensionRegistry.entrySet()) { + boolean didRepair = false; + ResourceKey key = entry.getKey(); + LevelStem loadedStem = entry.getValue(); + + ChunkGenerator referenceGenerator = dimensions.get(key); + if (referenceGenerator instanceof EnforceableChunkGenerator enforcer) { + final ChunkGenerator loadedChunkGenerator = loadedStem.generator(); + + // if the loaded ChunkGenerator is not the one we expect from vanilla, we will load the vanilla + // ones and mark all modded biomes with the respective dimension + registerAllBiomesFromVanillaDimension(key); + + // now compare the reference world settings (the ones that were created when the world was + // started) with the settings that were loaded by the game. + // If those do not match, we will create a new ChunkGenerator / BiomeSources with appropriate + // settings + if (enforcer.togetherShouldRepair(loadedChunkGenerator)) { + dimensionRegistry = enforcer.enforceGeneratorInWorldGenSettings( + registryAccess, + key, + loadedStem.type().unwrapKey().orElseThrow(), + loadedChunkGenerator, + dimensionRegistry + ); + didRepair = true; + } else if (loadedChunkGenerator.getBiomeSource() instanceof BiomeSourceWithConfig lodedSource) { + if (referenceGenerator.getBiomeSource() instanceof BiomeSourceWithConfig refSource) { + if (!refSource.getTogetherConfig().sameConfig(lodedSource.getTogetherConfig())) { + lodedSource.setTogetherConfig(refSource.getTogetherConfig()); + } + } + } + } + + + if (!didRepair) { + if (loadedStem.generator().getBiomeSource() instanceof ReloadableBiomeSource reload) { + reload.reloadBiomes(); + } + } + + } + return dimensionRegistry; + } + + private void registerAllBiomesFromVanillaDimension( + ResourceKey key + ) { + BiomeAPI.BiomeType type = BiomeAPI.BiomeType.getMainBiomeTypeForDimension(key); + + if (type != null) { + if (vanillaDimensions == null) { + vanillaDimensions = TogetherWorldPreset.getDimensionsMap(net.minecraft.world.level.levelgen.presets.WorldPresets.NORMAL); + } + var vanillaDim = vanillaDimensions.getOrDefault(key, null); + if (vanillaDim != null && vanillaDim.getBiomeSource() != null) { + var vanillaBiomes = vanillaDim + .getBiomeSource() + .possibleBiomes(); + + for (var holder : vanillaBiomes) { + ResourceKey biomeKey = holder.unwrapKey().orElse(null); + if (biomeKey != null) { + if (!BCLBiomeRegistry.hasBiome( + holder.unwrapKey().get(), + BCLBiomeRegistry.registryOrNull() + )) { + BCLBiomeRegistry.register(new BCLBiome( + biomeKey.location(), + type + )); + } + } + } + } + } + } +} diff --git a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java index ae787752..b90e4ed8 100644 --- a/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java +++ b/src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java @@ -1,14 +1,10 @@ package org.betterx.worlds.together.levelgen; import org.betterx.worlds.together.WorldsTogether; -import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig; -import org.betterx.worlds.together.biomesource.ReloadableBiomeSource; -import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator; import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings; import org.betterx.worlds.together.world.BiomeSourceWithSeed; import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.world.event.WorldBootstrap; -import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.WorldPresets; import net.minecraft.core.Holder; @@ -21,7 +17,6 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; @@ -30,7 +25,6 @@ import net.minecraft.world.level.levelgen.WorldDimensions; import net.minecraft.world.level.levelgen.presets.WorldPreset; import net.minecraft.world.level.levelgen.structure.StructureSet; -import java.util.Map; import org.jetbrains.annotations.ApiStatus; public class WorldGenUtil { @@ -99,8 +93,6 @@ public class WorldGenUtil { } public static class Context extends StemContext { - - public Context( Holder dimension, HolderGetter structureSets, @@ -133,63 +125,7 @@ public class WorldGenUtil { RegistryAccess registryAccess, Registry dimensionRegistry ) { - Map, ChunkGenerator> dimensions = TogetherWorldPreset.loadWorldDimensions(); - for (var entry : dimensionRegistry.entrySet()) { - boolean didRepair = false; - ResourceKey key = entry.getKey(); - LevelStem loadedStem = entry.getValue(); - - ChunkGenerator referenceGenerator = dimensions.get(key); - if (referenceGenerator instanceof EnforceableChunkGenerator enforcer) { - -// // probably not a datapack, so we need to check what other mods would have -// // added to the vanilla settings -// if (loadedStem.generator() instanceof EnforceableChunkGenerator) { -// // This list contains the vanilla default level stem (only available if a new world is loaded) as well as -// // The currently loaded stem -// var vanillaDimensionMap = WorldGenUtil.getDimensionsWithModData(net.minecraft.world.level.levelgen.presets.WorldPresets.NORMAL); -// -// LevelStem vanillaDefaultStem = vanillaDimensionMap.get(key); -// if (vanillaDefaultStem != null) { -// loadedStem = vanillaDefaultStem; -// } -// } - - - // now compare the reference world settings (the ones that were created when the world was - // started) with the settings that were loaded by the game. - // If those do not match, we will create a new ChunkGenerator / BiomeSources with appropriate - // settings - - final ChunkGenerator loadedChunkGenerator = loadedStem.generator(); - - if (enforcer.togetherShouldRepair(loadedChunkGenerator)) { - dimensionRegistry = enforcer.enforceGeneratorInWorldGenSettings( - registryAccess, - key, - loadedStem.type().unwrapKey().orElseThrow(), - loadedChunkGenerator, - dimensionRegistry - ); - didRepair = true; - } else if (loadedChunkGenerator.getBiomeSource() instanceof BiomeSourceWithConfig bs) { - if (referenceGenerator.getBiomeSource() instanceof BiomeSourceWithConfig refbs) { - if (!refbs.getTogetherConfig().sameConfig(bs.getTogetherConfig())) { - bs.setTogetherConfig(refbs.getTogetherConfig()); - } - } - } - } - - - if (!didRepair) { - if (loadedStem.generator().getBiomeSource() instanceof ReloadableBiomeSource reload) { - reload.reloadBiomes(); - } - } - - } - return dimensionRegistry; + return new BiomeRepairHelper().repairBiomeSourceInAllDimensions(registryAccess, dimensionRegistry); } public static ResourceLocation getBiomeID(Biome biome) {