[Change] Make sure we also load all vanilla Dimensions when merging Biomes (quiqueck/BetterNether#138)

This commit is contained in:
Frank 2023-06-19 17:36:10 +02:00
parent c0c35ed81e
commit edb8a83e77
3 changed files with 115 additions and 65 deletions

View file

@ -193,6 +193,13 @@ public class BiomeAPI {
public final BiomeType parentOrNull; public final BiomeType parentOrNull;
private final String name; private final String name;
public static BiomeType getMainBiomeTypeForDimension(ResourceKey<LevelStem> 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 @FunctionalInterface
interface ExtraRegisterTaks { interface ExtraRegisterTaks {
void register(@NotNull BCLBiome biome, @Nullable BCLBiome parent); void register(@NotNull BCLBiome biome, @Nullable BCLBiome parent);

View file

@ -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<ResourceKey<LevelStem>, ChunkGenerator> vanillaDimensions = null;
public Registry<LevelStem> repairBiomeSourceInAllDimensions(
RegistryAccess registryAccess,
Registry<LevelStem> dimensionRegistry
) {
Map<ResourceKey<LevelStem>, ChunkGenerator> dimensions = TogetherWorldPreset.loadWorldDimensions();
for (var entry : dimensionRegistry.entrySet()) {
boolean didRepair = false;
ResourceKey<LevelStem> 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<LevelStem> 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<Biome> biomeKey = holder.unwrapKey().orElse(null);
if (biomeKey != null) {
if (!BCLBiomeRegistry.hasBiome(
holder.unwrapKey().get(),
BCLBiomeRegistry.registryOrNull()
)) {
BCLBiomeRegistry.register(new BCLBiome(
biomeKey.location(),
type
));
}
}
}
}
}
}
}

View file

@ -1,14 +1,10 @@
package org.betterx.worlds.together.levelgen; package org.betterx.worlds.together.levelgen;
import org.betterx.worlds.together.WorldsTogether; 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.BiomeSourceWithNoiseRelatedSettings;
import org.betterx.worlds.together.world.BiomeSourceWithSeed; import org.betterx.worlds.together.world.BiomeSourceWithSeed;
import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.world.WorldConfig;
import org.betterx.worlds.together.world.event.WorldBootstrap; import org.betterx.worlds.together.world.event.WorldBootstrap;
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
import org.betterx.worlds.together.worldPreset.WorldPresets; import org.betterx.worlds.together.worldPreset.WorldPresets;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
@ -21,7 +17,6 @@ import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource; import net.minecraft.util.RandomSource;
import net.minecraft.world.level.biome.Biome; 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.DimensionType;
import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; 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.presets.WorldPreset;
import net.minecraft.world.level.levelgen.structure.StructureSet; import net.minecraft.world.level.levelgen.structure.StructureSet;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
public class WorldGenUtil { public class WorldGenUtil {
@ -99,8 +93,6 @@ public class WorldGenUtil {
} }
public static class Context extends StemContext { public static class Context extends StemContext {
public Context( public Context(
Holder<DimensionType> dimension, Holder<DimensionType> dimension,
HolderGetter<StructureSet> structureSets, HolderGetter<StructureSet> structureSets,
@ -133,63 +125,7 @@ public class WorldGenUtil {
RegistryAccess registryAccess, RegistryAccess registryAccess,
Registry<LevelStem> dimensionRegistry Registry<LevelStem> dimensionRegistry
) { ) {
Map<ResourceKey<LevelStem>, ChunkGenerator> dimensions = TogetherWorldPreset.loadWorldDimensions(); return new BiomeRepairHelper().repairBiomeSourceInAllDimensions(registryAccess, dimensionRegistry);
for (var entry : dimensionRegistry.entrySet()) {
boolean didRepair = false;
ResourceKey<LevelStem> 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;
} }
public static ResourceLocation getBiomeID(Biome biome) { public static ResourceLocation getBiomeID(Biome biome) {