[Change] WorldPresets are configured through BiomeSources

This commit is contained in:
Frank 2022-06-23 23:48:36 +02:00
parent 2a03b46a98
commit 877691011f
39 changed files with 1092 additions and 723 deletions

View file

@ -6,6 +6,9 @@ import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource; import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource;
import org.betterx.bclib.api.v2.generator.GeneratorOptions; import org.betterx.bclib.api.v2.generator.GeneratorOptions;
import org.betterx.bclib.api.v2.levelgen.LevelGenEvents; import org.betterx.bclib.api.v2.levelgen.LevelGenEvents;
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.blockpredicates.Types; import org.betterx.bclib.api.v2.levelgen.features.blockpredicates.Types;
import org.betterx.bclib.api.v2.levelgen.features.placement.PlacementModifiers; import org.betterx.bclib.api.v2.levelgen.features.placement.PlacementModifiers;
import org.betterx.bclib.api.v2.levelgen.structures.TemplatePiece; import org.betterx.bclib.api.v2.levelgen.structures.TemplatePiece;
@ -22,6 +25,8 @@ import org.betterx.worlds.together.tag.v3.TagManager;
import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.world.WorldConfig;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
@ -65,25 +70,78 @@ public class BCLib implements ModInitializer {
PlacementModifiers.ensureStaticInitialization(); PlacementModifiers.ensureStaticInitialization();
Configs.save(); Configs.save();
/*if (isDevEnvironment()) { if (isDevEnvironment()) {
Biome.BiomeBuilder builder = new Biome.BiomeBuilder() BCLBiome theYellow = BCLBiomeBuilder
.start(makeID("the_yellow"))
.precipitation(Biome.Precipitation.NONE) .precipitation(Biome.Precipitation.NONE)
.temperature(1.0f) .temperature(1.0f)
.downfall(1.0f) .wetness(1.0f)
.mobSpawnSettings(new MobSpawnSettings.Builder().build()) .fogColor(0xFFFF00)
.specialEffects(new BiomeSpecialEffects.Builder().fogColor(0xff00ff) .waterColor(0x777700)
.waterColor(0xff00ff) .waterFogColor(0xFFFF00)
.waterFogColor(0xff00ff) .skyColor(0xAAAA00)
.skyColor(0xff00ff) .addNetherClimateParamater(-1, 1)
.build()) .surface(Blocks.YELLOW_CONCRETE)
.generationSettings(new BiomeGenerationSettings.Builder().build()); .build();
BiomeAPI.registerEndLandBiome(theYellow);
Biome biome = builder.build(); BCLBiome theBlue = BCLBiomeBuilder
ResourceLocation loc = makeID("testbiome"); .start(makeID("the_blue"))
biome = Registry.register(BuiltinRegistries.BIOME, loc, biome); .precipitation(Biome.Precipitation.NONE)
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(biome).orElseThrow(); .temperature(1.0f)
NetherBiomeData.addNetherBiome(key, Climate.parameters(-1, 1, 0, 0, 0, 0, 0)); .wetness(1.0f)
}*/ .fogColor(0x0000FF)
.waterColor(0x000077)
.waterFogColor(0x0000FF)
.skyColor(0x0000AA)
.addNetherClimateParamater(-1, 1)
.surface(Blocks.LIGHT_BLUE_CONCRETE)
.build();
BiomeAPI.registerEndLandBiome(theBlue);
BCLBiome theGray = BCLBiomeBuilder
.start(makeID("the_gray"))
.precipitation(Biome.Precipitation.NONE)
.temperature(1.0f)
.wetness(1.0f)
.fogColor(0xFFFFFF)
.waterColor(0x777777)
.waterFogColor(0xFFFFFF)
.skyColor(0xAAAAAA)
.addNetherClimateParamater(-1, 1)
.surface(Blocks.GRAY_CONCRETE)
.build();
BiomeAPI.registerEndVoidBiome(theGray);
BCLBiome theOrange = BCLBiomeBuilder
.start(makeID("the_orange"))
.precipitation(Biome.Precipitation.NONE)
.temperature(1.0f)
.wetness(1.0f)
.fogColor(0xFF7700)
.waterColor(0x773300)
.waterFogColor(0xFF7700)
.skyColor(0xAA7700)
.addNetherClimateParamater(-1, 1.1f)
.surface(Blocks.ORANGE_CONCRETE)
.build();
BiomeAPI.registerNetherBiome(theOrange);
BCLBiome thePurple = BCLBiomeBuilder
.start(makeID("the_purple"))
.precipitation(Biome.Precipitation.NONE)
.temperature(1.0f)
.wetness(1.0f)
.fogColor(0xFF00FF)
.waterColor(0x770077)
.waterFogColor(0xFF00FF)
.skyColor(0xAA00AA)
.addNetherClimateParamater(-1.1f, 1)
.surface(Blocks.PURPLE_CONCRETE)
.build();
BiomeAPI.registerNetherBiome(thePurple);
}
} }
public static boolean isDevEnvironment() { public static boolean isDevEnvironment() {

View file

@ -6,21 +6,14 @@ import org.betterx.bclib.api.v2.datafixer.MigrationProfile;
import org.betterx.bclib.api.v2.generator.GeneratorOptions; import org.betterx.bclib.api.v2.generator.GeneratorOptions;
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil; import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
import org.betterx.bclib.config.Configs; import org.betterx.bclib.config.Configs;
import org.betterx.bclib.util.MHelper;
import com.mojang.serialization.Dynamic;
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.resources.RegistryOps; import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import java.util.Optional;
public final class BCLibPatch { public final class BCLibPatch {
public static void register() { public static void register() {
@ -94,60 +87,60 @@ final class BiomeSourcePatch extends ForcedLevelPatch {
RegistryOps<Tag> registryOps, RegistryOps<Tag> registryOps,
ResourceKey<LevelStem> dimensionKey ResourceKey<LevelStem> dimensionKey
) { ) {
final long seed = worldGenSettings.contains("seed")
? worldGenSettings.getLong("seed")
: MHelper.RANDOM.nextLong();
final boolean genStructures = !worldGenSettings.contains("generate_features") || worldGenSettings.getBoolean(
"generate_features");
final boolean genBonusChest = worldGenSettings.contains("bonus_chest") && worldGenSettings.getBoolean(
"bonus_chest");
boolean result = false; boolean result = false;
CompoundTag dimensionTag = dimensions.getCompound(dimensionKey.location().toString()); // final long seed = worldGenSettings.contains("seed")
Optional<WorldGenSettings> oWorldGen = WorldGenSettings.CODEC // ? worldGenSettings.getLong("seed")
.parse(new Dynamic<>(registryOps, worldGenSettings)) // : MHelper.RANDOM.nextLong();
.result(); //
// final boolean genStructures = !worldGenSettings.contains("generate_features") || worldGenSettings.getBoolean(
Optional<LevelStem> oLevelStem = LevelStem.CODEC // "generate_features");
.parse(new Dynamic<>(registryOps, dimensionTag)) //
.resultOrPartial(BCLib.LOGGER::error); // final boolean genBonusChest = worldGenSettings.contains("bonus_chest") && worldGenSettings.getBoolean(
// "bonus_chest");
Optional<ChunkGenerator> netherGenerator = oLevelStem.map(l -> l.generator()); //
int biomeSourceVersion = LevelGenUtil.getBiomeVersionForGenerator(netherGenerator.orElse(null)); //
int targetVersion = LevelGenUtil.getBiomeVersionForCurrentWorld(dimensionKey); // CompoundTag dimensionTag = dimensions.getCompound(dimensionKey.location().toString());
if (biomeSourceVersion != targetVersion) { // Optional<WorldGenSettings> oWorldGen = WorldGenSettings.CODEC
Optional<Holder<LevelStem>> refLevelStem = LevelGenUtil.referenceStemForVersion( // .parse(new Dynamic<>(registryOps, worldGenSettings))
dimensionKey, // .result();
targetVersion, //
registryAccess, // Optional<LevelStem> oLevelStem = LevelStem.CODEC
oWorldGen.map(g -> g.seed()).orElse(seed), // .parse(new Dynamic<>(registryOps, dimensionTag))
oWorldGen.map(g -> g.generateStructures()).orElse(genStructures), // .resultOrPartial(BCLib.LOGGER::error);
oWorldGen.map(g -> g.generateBonusChest()).orElse(genBonusChest) //
); // Optional<ChunkGenerator> netherGenerator = oLevelStem.map(l -> l.generator());
// int biomeSourceVersion = LevelGenUtil.getBiomeVersionForGenerator(netherGenerator.orElse(null));
BCLib.LOGGER.warning("The world uses the BiomeSource Version " + biomeSourceVersion + " but should have " + targetVersion + "."); // int targetVersion = LevelGenUtil.getBiomeVersionForCurrentWorld(dimensionKey);
BCLib.LOGGER.warning("Dimension: " + dimensionKey); // if (biomeSourceVersion != targetVersion) {
BCLib.LOGGER.warning("Found: " + netherGenerator); // Optional<Holder<LevelStem>> refLevelStem = LevelGenUtil.referenceStemForVersion(
BCLib.LOGGER.warning("Should: " + refLevelStem.map(l -> l.value().generator())); // dimensionKey,
// targetVersion,
if (refLevelStem.isPresent()) { // registryAccess,
var levelStem = refLevelStem.get(); // oWorldGen.map(g -> g.seed()).orElse(seed),
BCLib.LOGGER.warning("Repairing level.dat in order to ensure world continuity."); // oWorldGen.map(g -> g.generateStructures()).orElse(genStructures),
var codec = LevelStem.CODEC.orElse(levelStem.value()); // oWorldGen.map(g -> g.generateBonusChest()).orElse(genBonusChest)
var encodeResult = codec.encodeStart(registryOps, levelStem.value()); // );
if (encodeResult.result().isPresent()) { //
dimensions.put(dimensionKey.location().toString(), encodeResult.result().get()); // BCLib.LOGGER.warning("The world uses the BiomeSource Version " + biomeSourceVersion + " but should have " + targetVersion + ".");
result = true; // BCLib.LOGGER.warning("Dimension: " + dimensionKey);
} else { // BCLib.LOGGER.warning("Found: " + netherGenerator);
BCLib.LOGGER.error("Unable to encode '" + dimensionKey + "' generator for level.dat."); // BCLib.LOGGER.warning("Should: " + refLevelStem.map(l -> l.value().generator()));
} //
} else { // if (refLevelStem.isPresent()) {
BCLib.LOGGER.error("Unable to update '" + dimensionKey + "' generator in level.dat."); // var levelStem = refLevelStem.get();
} // BCLib.LOGGER.warning("Repairing level.dat in order to ensure world continuity.");
} // var codec = LevelStem.CODEC.orElse(levelStem.value());
// var encodeResult = codec.encodeStart(registryOps, levelStem.value());
// if (encodeResult.result().isPresent()) {
// dimensions.put(dimensionKey.location().toString(), encodeResult.result().get());
// result = true;
// } else {
// BCLib.LOGGER.error("Unable to encode '" + dimensionKey + "' generator for level.dat.");
// }
// } else {
// BCLib.LOGGER.error("Unable to update '" + dimensionKey + "' generator in level.dat.");
// }
// }
return result; return result;
} }

View file

@ -1,6 +1,7 @@
package org.betterx.bclib.api.v2.generator; package org.betterx.bclib.api.v2.generator;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import org.betterx.worlds.together.biomesource.MergeableBiomeSource;
import org.betterx.worlds.together.world.BiomeSourceWithSeed; import org.betterx.worlds.together.world.BiomeSourceWithSeed;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
@ -13,11 +14,9 @@ import com.google.common.collect.Sets;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed { public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource<BCLBiomeSource> {
public static int BIOME_SOURCE_VERSION_NONE = -1;
public static int BIOME_SOURCE_VERSION_VANILLA = 0; public static int BIOME_SOURCE_VERSION_VANILLA = 0;
public static int BIOME_SOURCE_VERSION_SQUARE = 17; public static int BIOME_SOURCE_VERSION_SQUARE = 17;
public static int BIOME_SOURCE_VERSION_HEX = 18; public static int BIOME_SOURCE_VERSION_HEX = 18;
@ -26,8 +25,6 @@ public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceW
protected long currentSeed; protected long currentSeed;
protected int maxHeight; protected int maxHeight;
public final int biomeSourceVersion;
private static List<Holder<Biome>> preInit(Registry<Biome> biomeRegistry, List<Holder<Biome>> biomes) { private static List<Holder<Biome>> preInit(Registry<Biome> biomeRegistry, List<Holder<Biome>> biomes) {
biomes = biomes.stream().sorted(Comparator.comparing(holder -> holder.unwrapKey() biomes = biomes.stream().sorted(Comparator.comparing(holder -> holder.unwrapKey()
.get() .get()
@ -41,19 +38,12 @@ public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceW
protected BCLBiomeSource( protected BCLBiomeSource(
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
List<Holder<Biome>> list, List<Holder<Biome>> list,
long seed, long seed
Optional<Integer> biomeSourceVersion
) { ) {
super(preInit(biomeRegistry, list)); super(preInit(biomeRegistry, list));
this.biomeRegistry = biomeRegistry; this.biomeRegistry = biomeRegistry;
this.biomeSourceVersion = biomeSourceVersion.orElse(DEFAULT_BIOME_SOURCE_VERSION);
this.currentSeed = seed; this.currentSeed = seed;
System.out.println(this + " with Registry: " + biomeRegistry.getClass().getName() + "@" + Integer.toHexString(
biomeRegistry.hashCode()));
//BiomeAPI.initRegistry(biomeRegistry);
} }
final public void setSeed(long seed) { final public void setSeed(long seed) {
@ -85,16 +75,6 @@ public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceW
protected abstract void onInitMap(long newSeed); protected abstract void onInitMap(long newSeed);
protected abstract void onHeightChange(int newHeight); protected abstract void onHeightChange(int newHeight);
public static int getVersionBiomeSource(BiomeSource biomeSource) {
if (biomeSource == null) return BCLBiomeSource.BIOME_SOURCE_VERSION_NONE;
if (biomeSource instanceof BCLBiomeSource bcl) {
return bcl.biomeSourceVersion;
} else {
return BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA;
}
}
public BCLBiomeSource createCopyForDatapack(Set<Holder<Biome>> datapackBiomes) { public BCLBiomeSource createCopyForDatapack(Set<Holder<Biome>> datapackBiomes) {
Set<Holder<Biome>> mutableSet = Sets.newHashSet(); Set<Holder<Biome>> mutableSet = Sets.newHashSet();
mutableSet.addAll(datapackBiomes); mutableSet.addAll(datapackBiomes);
@ -128,4 +108,10 @@ public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceW
}) })
.toList(); .toList();
} }
@Override
public BCLBiomeSource mergeWithBiomeSource(BiomeSource inputBiomeSource) {
final Set<Holder<Biome>> datapackBiomes = inputBiomeSource.possibleBiomes();
return this.createCopyForDatapack(datapackBiomes);
}
} }

View file

@ -1,15 +1,22 @@
package org.betterx.bclib.api.v2.generator; package org.betterx.bclib.api.v2.generator;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI;
import org.betterx.bclib.interfaces.NoiseGeneratorSettingsProvider; import org.betterx.bclib.interfaces.NoiseGeneratorSettingsProvider;
import org.betterx.bclib.mixin.common.ChunkGeneratorAccessor; import org.betterx.bclib.mixin.common.ChunkGeneratorAccessor;
import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.WorldsTogether;
import org.betterx.worlds.together.world.WorldGenUtil; import org.betterx.worlds.together.biomesource.MergeableBiomeSource;
import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator;
import org.betterx.worlds.together.chunkgenerator.InjectableSurfaceRules;
import org.betterx.worlds.together.chunkgenerator.RestorableBiomeSource;
import org.betterx.worlds.together.levelgen.WorldGenUtil;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.RegistryOps; import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
@ -18,6 +25,7 @@ import net.minecraft.world.level.biome.BiomeGenerationSettings;
import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.FeatureSorter; import net.minecraft.world.level.biome.FeatureSorter;
import net.minecraft.world.level.chunk.ChunkGenerator; 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.dimension.LevelStem;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
@ -31,7 +39,7 @@ import com.google.common.base.Suppliers;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
public class BCLChunkGenerator extends NoiseBasedChunkGenerator { public class BCLChunkGenerator extends NoiseBasedChunkGenerator implements RestorableBiomeSource<BCLChunkGenerator>, InjectableSurfaceRules<BCLChunkGenerator>, EnforceableChunkGenerator<BCLChunkGenerator> {
public static final Codec<BCLChunkGenerator> CODEC = RecordCodecBuilder public static final Codec<BCLChunkGenerator> CODEC = RecordCodecBuilder
.create((RecordCodecBuilder.Instance<BCLChunkGenerator> builderInstance) -> { .create((RecordCodecBuilder.Instance<BCLChunkGenerator> builderInstance) -> {
@ -92,7 +100,13 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator {
} }
} }
public void restoreInitialBiomeSource() { /**
* Other Mods like TerraBlender might inject new BiomeSources. We und that change after the world setup did run.
*
* @param dimensionKey The Dimension where this ChunkGenerator is used from
*/
@Override
public void restoreInitialBiomeSource(ResourceKey<LevelStem> dimensionKey) {
if (initialBiomeSource != getBiomeSource()) { if (initialBiomeSource != getBiomeSource()) {
if (this instanceof ChunkGeneratorAccessor acc) { if (this instanceof ChunkGeneratorAccessor acc) {
BiomeSource bs = WorldGenUtil.getWorldSettings() BiomeSource bs = WorldGenUtil.getWorldSettings()
@ -122,7 +136,9 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator {
return "BCLib - Chunk Generator (" + Integer.toHexString(hashCode()) + ")"; return "BCLib - Chunk Generator (" + Integer.toHexString(hashCode()) + ")";
} }
//Make sure terrablender does not rewrite the feature-set // This method is injected by Terrablender.
// We make sure terrablender does not rewrite the feature-set for our ChunkGenerator by overwriting the
// Mixin-Method with an empty implementation
public void appendFeaturesPerStep() { public void appendFeaturesPerStep() {
} }
@ -138,15 +154,75 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator {
} }
} }
public static void restoreInitialBiomeSources(WorldGenSettings settings) { @Override
restoreInitialBiomeSource(settings, LevelStem.NETHER); public WorldGenSettings enforceGeneratorInWorldGenSettings(
restoreInitialBiomeSource(settings, LevelStem.END); RegistryAccess access,
ResourceKey<LevelStem> dimensionKey,
ResourceKey<DimensionType> dimensionTypeKey,
ChunkGenerator loadedChunkGenerator,
WorldGenSettings settings
) {
BCLib.LOGGER.info("Enforcing Correct Generator for " + dimensionKey.location().toString() + ".");
ChunkGenerator referenceGenerator = this;
if (loadedChunkGenerator instanceof org.betterx.bclib.interfaces.ChunkGeneratorAccessor generator) {
if (loadedChunkGenerator instanceof NoiseGeneratorSettingsProvider noiseProvider) {
if (referenceGenerator instanceof NoiseGeneratorSettingsProvider referenceProvider) {
final BiomeSource bs;
if (referenceGenerator.getBiomeSource() instanceof MergeableBiomeSource mbs) {
bs = mbs.mergeWithBiomeSource(loadedChunkGenerator.getBiomeSource());
} else {
bs = referenceGenerator.getBiomeSource();
}
InternalBiomeAPI.applyModifications(bs, dimensionKey);
referenceGenerator = new BCLChunkGenerator(
generator.bclib_getStructureSetsRegistry(),
noiseProvider.bclib_getNoises(),
bs,
buildGeneratorSettings(
referenceProvider.bclib_getNoiseGeneratorSettingHolders(),
noiseProvider.bclib_getNoiseGeneratorSettingHolders(),
bs
)
);
}
}
}
return LevelGenUtil.replaceGenerator(
dimensionKey,
dimensionTypeKey,
access,
settings,
referenceGenerator
);
} }
public static void restoreInitialBiomeSource(WorldGenSettings settings, ResourceKey<LevelStem> dimension) { private static Holder<NoiseGeneratorSettings> buildGeneratorSettings(
LevelStem loadedStem = settings.dimensions().getOrThrow(dimension); Holder<NoiseGeneratorSettings> reference,
if (loadedStem.generator() instanceof BCLChunkGenerator cg) { Holder<NoiseGeneratorSettings> settings,
cg.restoreInitialBiomeSource(); BiomeSource biomeSource
} ) {
return settings;
// NoiseGeneratorSettings old = settings.value();
// NoiseGeneratorSettings noise = new NoiseGeneratorSettings(
// old.noiseSettings(),
// old.defaultBlock(),
// old.defaultFluid(),
// old.noiseRouter(),
// SurfaceRuleRegistry.mergeSurfaceRulesFromBiomes(old.surfaceRule(), biomeSource),
// //SurfaceRuleUtil.addRulesForBiomeSource(old.surfaceRule(), biomeSource),
// old.spawnTarget(),
// old.seaLevel(),
// old.disableMobGeneration(),
// old.aquifersEnabled(),
// old.oreVeinsEnabled(),
// old.useLegacyRandomSource()
// );
//
//
// return Holder.direct(noise);
} }
} }

View file

@ -1,17 +1,16 @@
package org.betterx.bclib.api.v2.generator; package org.betterx.bclib.api.v2.generator;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap; import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry; import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry;
import org.betterx.bclib.config.Configs; import org.betterx.bclib.config.Configs;
import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.bclib.interfaces.BiomeMap;
import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor; import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor;
import org.betterx.bclib.noise.OpenSimplexNoise;
import org.betterx.bclib.presets.worldgen.BCLWorldPresetSettings; import org.betterx.bclib.presets.worldgen.BCLWorldPresetSettings;
import org.betterx.worlds.together.world.WorldGenUtil; import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
import org.betterx.worlds.together.levelgen.WorldGenUtil;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
@ -22,27 +21,22 @@ import net.minecraft.core.SectionPos;
import net.minecraft.resources.RegistryOps; import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BiomeTags; import net.minecraft.tags.BiomeTags;
import net.minecraft.util.Mth;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.levelgen.DensityFunction; import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.LegacyRandomSource;
import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.synth.SimplexNoise;
import net.fabricmc.fabric.impl.biome.TheEndBiomeData; import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import org.jetbrains.annotations.NotNull;
public class BCLibEndBiomeSource extends BCLBiomeSource { public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibEndBiomeSource, BCLEndBiomeSourceConfig> {
private static final OpenSimplexNoise SMALL_NOISE = new OpenSimplexNoise(8324);
public static Codec<BCLibEndBiomeSource> CODEC public static Codec<BCLibEndBiomeSource> CODEC
= RecordCodecBuilder.create((instance) -> instance.group( = RecordCodecBuilder.create((instance) -> instance.group(
RegistryOps RegistryOps
@ -53,11 +47,11 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
.fieldOf("seed") .fieldOf("seed")
.stable() .stable()
.forGetter(source -> source.currentSeed), .forGetter(source -> source.currentSeed),
Codec BCLEndBiomeSourceConfig
.INT .CODEC
.optionalFieldOf("version") .fieldOf("config")
.stable() .orElse(BCLEndBiomeSourceConfig.DEFAULT)
.forGetter(source -> Optional.of(source.biomeSourceVersion)) .forGetter(o -> o.config)
) )
.apply( .apply(
instance, instance,
@ -68,40 +62,40 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
private final Holder<Biome> barrens; private final Holder<Biome> barrens;
private final Point pos; private final Point pos;
private final BiFunction<Point, Integer, Boolean> endLandFunction; private final BiFunction<Point, Integer, Boolean> endLandFunction;
private SimplexNoise noise;
private BiomeMap mapLand; private BiomeMap mapLand;
private BiomeMap mapVoid; private BiomeMap mapVoid;
private final BiomePicker endLandBiomePicker; private final BiomePicker endLandBiomePicker;
private final BiomePicker endVoidBiomePicker; private final BiomePicker endVoidBiomePicker;
private boolean generateEndVoids; private BCLEndBiomeSourceConfig config;
public BCLibEndBiomeSource(Registry<Biome> biomeRegistry, long seed, Optional<Integer> version) { public BCLibEndBiomeSource(Registry<Biome> biomeRegistry, long seed, BCLEndBiomeSourceConfig config) {
this(biomeRegistry, seed, version, true); this(biomeRegistry, seed, config, true);
} }
public BCLibEndBiomeSource(Registry<Biome> biomeRegistry, Optional<Integer> version) { public BCLibEndBiomeSource(Registry<Biome> biomeRegistry, BCLEndBiomeSourceConfig config) {
this(biomeRegistry, 0, version, false); this(biomeRegistry, 0, config, false);
} }
private BCLibEndBiomeSource(Registry<Biome> biomeRegistry, long seed, Optional<Integer> version, boolean initMaps) { private BCLibEndBiomeSource(
this(biomeRegistry, getBiomes(biomeRegistry), seed, version, initMaps); Registry<Biome> biomeRegistry,
long seed,
BCLEndBiomeSourceConfig config,
boolean initMaps
) {
this(biomeRegistry, getBiomes(biomeRegistry), seed, config, initMaps);
} }
private BCLibEndBiomeSource( private BCLibEndBiomeSource(
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
List<Holder<Biome>> list, List<Holder<Biome>> list,
long seed, long seed,
Optional<Integer> version, BCLEndBiomeSourceConfig config,
boolean initMaps boolean initMaps
) { ) {
super(biomeRegistry, list, seed, version); super(biomeRegistry, list, seed);
if (WorldGenUtil.getWorldSettings() instanceof BCLWorldPresetSettings settings) { this.config = config;
generateEndVoids = settings.generateEndVoid;
} else {
generateEndVoids = true;
}
endLandBiomePicker = new BiomePicker(biomeRegistry); endLandBiomePicker = new BiomePicker(biomeRegistry);
endVoidBiomePicker = new BiomePicker(biomeRegistry); endVoidBiomePicker = new BiomePicker(biomeRegistry);
@ -133,7 +127,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
BCLBiome bclBiome = BiomeAPI.getBiome(key); BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) { if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) { if (bclBiome.getParentBiome() == null) {
if (generateEndVoids) { if (config.withVoidBiomes) {
if (BiomeAPI.wasRegisteredAsEndVoidBiome(key) || includeVoid.contains(key.toString())) { if (BiomeAPI.wasRegisteredAsEndVoidBiome(key) || includeVoid.contains(key.toString())) {
endVoidBiomePicker.addBiome(bclBiome); endVoidBiomePicker.addBiome(bclBiome);
} else if (BiomeAPI.wasRegisteredAsEndLandBiome(key) || includeLand.contains(key.toString())) { } else if (BiomeAPI.wasRegisteredAsEndLandBiome(key) || includeLand.contains(key.toString())) {
@ -144,7 +138,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
endLandBiomePicker.addBiome(bclBiome); endLandBiomePicker.addBiome(bclBiome);
endVoidBiomePicker.addBiome(bclBiome); endVoidBiomePicker.addBiome(bclBiome);
} }
if (!key.equals(Biomes.SMALL_END_ISLANDS) && !key.equals(Biomes.THE_END) if (!key.equals(Biomes.SMALL_END_ISLANDS.location()) && !key.equals(Biomes.THE_END.location())
&& (BiomeAPI.wasRegisteredAsEndVoidBiome(key) || includeVoid.contains(key.toString())) && (BiomeAPI.wasRegisteredAsEndVoidBiome(key) || includeVoid.contains(key.toString()))
) { ) {
endVoidBiomePicker.addBiome(bclBiome); endVoidBiomePicker.addBiome(bclBiome);
@ -183,7 +177,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
this.biomeRegistry, this.biomeRegistry,
datapackBiomes.stream().toList(), datapackBiomes.stream().toList(),
this.currentSeed, this.currentSeed,
Optional.of(biomeSourceVersion), this.config,
true true
); );
} }
@ -258,63 +252,23 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_VOID); BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_VOID);
} }
public static float getLegacyHeightValue(SimplexNoise simplexNoise, int i, int j) {
int k = i / 2;
int l = j / 2;
int m = i % 2;
int n = j % 2;
float f = 100.0f - Mth.sqrt(i * i + j * j) * 8.0f;
f = Mth.clamp(f, -100.0f, 80.0f);
for (int o = -12; o <= 12; ++o) {
for (int p = -12; p <= 12; ++p) {
long q = k + o;
long r = l + p;
if (q * q + r * r <= 4096L || !(simplexNoise.getValue(q, r) < (double) -0.9f)) continue;
float g = (Mth.abs(q) * 3439.0f + Mth.abs(r) * 147.0f) % 13.0f + 9.0f;
float h = m - o * 2;
float s = n - p * 2;
float t = 100.0f - Mth.sqrt(h * h + s * s) * g;
t = Mth.clamp(t, -100.0f, 80.0f);
f = Math.max(f, t);
}
}
return f;
}
public static void register() { public static void register() {
Registry.register(Registry.BIOME_SOURCE, BCLib.makeID("end_biome_source"), CODEC); Registry.register(Registry.BIOME_SOURCE, BCLib.makeID("end_biome_source"), CODEC);
} }
@Override @Override
protected void onInitMap(long seed) { protected void onInitMap(long seed) {
if ((biomeSourceVersion != BIOME_SOURCE_VERSION_HEX)) { this.mapLand = config.mapVersion.mapBuilder.apply(
this.mapLand = new SquareBiomeMap( seed,
seed, GeneratorOptions.getBiomeSizeEndLand(),
GeneratorOptions.getBiomeSizeEndLand(), endLandBiomePicker
endLandBiomePicker );
);
this.mapVoid = new SquareBiomeMap(
seed,
GeneratorOptions.getBiomeSizeEndVoid(),
endVoidBiomePicker
);
} else {
this.mapLand = new HexBiomeMap(
seed,
GeneratorOptions.getBiomeSizeEndLand(),
endLandBiomePicker
);
this.mapVoid = new HexBiomeMap(
seed,
GeneratorOptions.getBiomeSizeEndVoid(),
endVoidBiomePicker
);
}
WorldgenRandom chunkRandom = new WorldgenRandom(new LegacyRandomSource(seed)); this.mapVoid = config.mapVersion.mapBuilder.apply(
chunkRandom.consumeCount(17292); seed,
this.noise = new SimplexNoise(chunkRandom); GeneratorOptions.getBiomeSizeEndVoid(),
endVoidBiomePicker
);
} }
@Override @Override
@ -323,17 +277,16 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
} }
@Override @Override
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler sampler) { public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.@NotNull Sampler sampler) {
if (mapLand == null || mapVoid == null) if (mapLand == null || mapVoid == null)
return this.possibleBiomes().stream().findFirst().get(); return this.possibleBiomes().stream().findFirst().orElseThrow();
int posX = QuartPos.toBlock(biomeX); int posX = QuartPos.toBlock(biomeX);
int posY = QuartPos.toBlock(biomeY); int posY = QuartPos.toBlock(biomeY);
int posZ = QuartPos.toBlock(biomeZ); int posZ = QuartPos.toBlock(biomeZ);
long farEndBiomes = GeneratorOptions.getFarEndBiomes();
long dist = Math.abs(posX) + Math.abs(posZ) > farEndBiomes long dist = Math.abs(posX) + Math.abs(posZ) > (long) config.innerVoidRadiusSquared
? (farEndBiomes + 1) ? ((long) config.innerVoidRadiusSquared + 1)
: (long) posX * (long) posX + (long) posZ * (long) posZ; : (long) posX * (long) posX + (long) posZ * (long) posZ;
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) { if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
@ -341,8 +294,8 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
mapVoid.clearCache(); mapVoid.clearCache();
} }
if (endLandFunction == null) { if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA || endLandFunction == null) {
if (dist <= farEndBiomes) { if (dist <= (long) config.innerVoidRadiusSquared) {
return this.centerBiome; return this.centerBiome;
} }
int x = (SectionPos.blockToSectionCoord(posX) * 2 + 1) * 8; int x = (SectionPos.blockToSectionCoord(posX) * 2 + 1) * 8;
@ -355,14 +308,15 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
} else { } else {
return d < -0.21875 return d < -0.21875
? mapVoid.getBiome(posX, biomeY << 2, posZ).biome ? mapVoid.getBiome(posX, biomeY << 2, posZ).biome
: generateEndVoids ? this.barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).biome; : config.withVoidBiomes ? this.barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).biome;
} }
} else { } else {
pos.setLocation(biomeX, biomeZ); pos.setLocation(biomeX, biomeZ);
if (endLandFunction.apply(pos, maxHeight)) { if (endLandFunction.apply(pos, maxHeight)) {
return dist <= farEndBiomes ? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).biome; return dist <= (long) config.innerVoidRadiusSquared
? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).biome;
} else { } else {
return dist <= farEndBiomes return dist <= (long) config.innerVoidRadiusSquared
? barrens ? barrens
: mapVoid.getBiome(posX, biomeY << 2, posZ).biome; : mapVoid.getBiome(posX, biomeY << 2, posZ).biome;
} }
@ -378,6 +332,17 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
@Override @Override
public String toString() { public String toString() {
return "BCLib - The End BiomeSource (" + Integer.toHexString(hashCode()) + ", version=" + biomeSourceVersion + ", seed=" + currentSeed + ", height=" + maxHeight + ", voids=" + generateEndVoids + ", customLand=" + (endLandFunction != null) + ", biomes=" + possibleBiomes().size() + ")"; return "BCLib - The End BiomeSource (" + Integer.toHexString(hashCode()) + ", config=" + config + ", seed=" + currentSeed + ", height=" + maxHeight + ", customLand=" + (endLandFunction != null) + ", biomes=" + possibleBiomes().size() + ")";
}
@Override
public BCLEndBiomeSourceConfig getTogetherConfig() {
return config;
}
@Override
public void setTogetherConfig(BCLEndBiomeSourceConfig newConfig) {
this.config = newConfig;
this.initMap(currentSeed);
} }
} }

View file

@ -1,14 +1,15 @@
package org.betterx.bclib.api.v2.generator; package org.betterx.bclib.api.v2.generator;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
import org.betterx.bclib.api.v2.generator.map.MapStack; import org.betterx.bclib.api.v2.generator.map.MapStack;
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap;
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome; import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI; import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry; import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry;
import org.betterx.bclib.config.Configs; import org.betterx.bclib.config.Configs;
import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.bclib.interfaces.BiomeMap;
import org.betterx.bclib.util.TriFunction;
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
@ -23,13 +24,10 @@ import net.minecraft.world.level.biome.Climate;
import net.fabricmc.fabric.api.biome.v1.NetherBiomes; import net.fabricmc.fabric.api.biome.v1.NetherBiomes;
import org.apache.commons.lang3.function.TriFunction;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
public class BCLibNetherBiomeSource extends BCLBiomeSource { public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibNetherBiomeSource, BCLNetherBiomeSourceConfig> {
public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder
.create(instance -> instance .create(instance -> instance
.group( .group(
@ -43,43 +41,44 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
.forGetter(source -> { .forGetter(source -> {
return source.currentSeed; return source.currentSeed;
}), }),
Codec BCLNetherBiomeSourceConfig
.INT .CODEC
.optionalFieldOf("version") .fieldOf("config")
.stable() .orElse(BCLNetherBiomeSourceConfig.DEFAULT)
.forGetter(source -> Optional.of(source.biomeSourceVersion)) .forGetter(o -> o.config)
) )
.apply(instance, instance.stable(BCLibNetherBiomeSource::new)) .apply(instance, instance.stable(BCLibNetherBiomeSource::new))
); );
private BiomeMap biomeMap; private BiomeMap biomeMap;
private final BiomePicker biomePicker; private final BiomePicker biomePicker;
private BCLNetherBiomeSourceConfig config;
public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry, Optional<Integer> version) { public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry, BCLNetherBiomeSourceConfig config) {
this(biomeRegistry, 0, version, false); this(biomeRegistry, 0, config, false);
} }
public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry, long seed, Optional<Integer> version) { public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry, long seed, BCLNetherBiomeSourceConfig config) {
this(biomeRegistry, seed, version, true); this(biomeRegistry, seed, config, true);
} }
private BCLibNetherBiomeSource( private BCLibNetherBiomeSource(
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
long seed, long seed,
Optional<Integer> version, BCLNetherBiomeSourceConfig config,
boolean initMaps boolean initMaps
) { ) {
this(biomeRegistry, getBiomes(biomeRegistry), seed, version, initMaps); this(biomeRegistry, getBiomes(biomeRegistry), seed, config, initMaps);
} }
private BCLibNetherBiomeSource( private BCLibNetherBiomeSource(
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
List<Holder<Biome>> list, List<Holder<Biome>> list,
long seed, long seed,
Optional<Integer> version, BCLNetherBiomeSourceConfig config,
boolean initMaps boolean initMaps
) { ) {
super(biomeRegistry, list, seed, version); super(biomeRegistry, list, seed);
this.config = config;
biomePicker = new BiomePicker(biomeRegistry); biomePicker = new BiomePicker(biomeRegistry);
this.possibleBiomes().forEach(biome -> { this.possibleBiomes().forEach(biome -> {
@ -111,7 +110,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
this.biomeRegistry, this.biomeRegistry,
datapackBiomes.stream().toList(), datapackBiomes.stream().toList(),
this.currentSeed, this.currentSeed,
Optional.of(biomeSourceVersion), config,
true true
); );
} }
@ -181,9 +180,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
@Override @Override
protected void onInitMap(long seed) { protected void onInitMap(long seed) {
TriFunction<Long, Integer, BiomePicker, BiomeMap> mapConstructor = (biomeSourceVersion != BIOME_SOURCE_VERSION_HEX) TriFunction<Long, Integer, BiomePicker, BiomeMap> mapConstructor = config.mapVersion.mapBuilder;
? SquareBiomeMap::new
: HexBiomeMap::new;
if (maxHeight > 128 && GeneratorOptions.useVerticalBiomes()) { if (maxHeight > 128 && GeneratorOptions.useVerticalBiomes()) {
this.biomeMap = new MapStack( this.biomeMap = new MapStack(
seed, seed,
@ -209,6 +206,17 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
@Override @Override
public String toString() { public String toString() {
return "BCLib - Nether BiomeSource (" + Integer.toHexString(hashCode()) + ", version=" + biomeSourceVersion + ", seed=" + currentSeed + ", height=" + maxHeight + ", biomes=" + possibleBiomes().size() + ")"; return "BCLib - Nether BiomeSource (" + Integer.toHexString(hashCode()) + ", config=" + config + ", seed=" + currentSeed + ", height=" + maxHeight + ", biomes=" + possibleBiomes().size() + ")";
}
@Override
public BCLNetherBiomeSourceConfig getTogetherConfig() {
return config;
}
@Override
public void setTogetherConfig(BCLNetherBiomeSourceConfig newConfig) {
this.config = config;
initMap(currentSeed);
} }
} }

View file

@ -0,0 +1,154 @@
package org.betterx.bclib.api.v2.generator.config;
import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
import org.betterx.bclib.api.v2.generator.BiomePicker;
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap;
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
import org.betterx.bclib.interfaces.BiomeMap;
import org.betterx.bclib.util.TriFunction;
import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.util.StringRepresentable;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeSource> {
public static final BCLEndBiomeSourceConfig MINECRAFT_17 = new BCLEndBiomeSourceConfig(
EndBiomeMapType.SQUARE,
EndBiomeGeneratorType.PAULEVS,
true,
1000000
);
public static final BCLEndBiomeSourceConfig MINECRAFT_18 = new BCLEndBiomeSourceConfig(
EndBiomeMapType.HEX,
EndBiomeGeneratorType.PAULEVS,
false,
MINECRAFT_17.innerVoidRadiusSquared
);
public static final BCLEndBiomeSourceConfig DEFAULT = MINECRAFT_18;
public static final Codec<BCLEndBiomeSourceConfig> CODEC = RecordCodecBuilder.create(instance -> instance
.group(
EndBiomeMapType.CODEC
.fieldOf("map_type")
.orElse(DEFAULT.mapVersion)
.forGetter(o -> o.mapVersion),
EndBiomeGeneratorType.CODEC
.fieldOf("generator_version")
.orElse(DEFAULT.generatorVersion)
.forGetter(o -> o.generatorVersion),
Codec.BOOL
.fieldOf("with_void_biomes")
.orElse(DEFAULT.withVoidBiomes)
.forGetter(o -> o.withVoidBiomes),
Codec.INT
.fieldOf("inner_void_radius_squared")
.orElse(DEFAULT.innerVoidRadiusSquared)
.forGetter(o -> o.innerVoidRadiusSquared)
)
.apply(instance, BCLEndBiomeSourceConfig::new));
public BCLEndBiomeSourceConfig(
@NotNull EndBiomeMapType mapVersion,
@NotNull EndBiomeGeneratorType generatorVersion,
boolean withVoidBiomes,
int innerVoidRadiusSquared
) {
this.mapVersion = mapVersion;
this.generatorVersion = generatorVersion;
this.withVoidBiomes = withVoidBiomes;
this.innerVoidRadiusSquared = innerVoidRadiusSquared;
}
public enum EndBiomeMapType implements StringRepresentable {
VANILLA("vanilla", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker)),
SQUARE("square", (seed, biomeSize, picker) -> new SquareBiomeMap(seed, biomeSize, picker)),
HEX("hex", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker));
public static final Codec<EndBiomeMapType> CODEC = StringRepresentable.fromEnum(EndBiomeMapType::values);
public final String name;
public final @NotNull TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder;
EndBiomeMapType(String name, @NotNull TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder) {
this.name = name;
this.mapBuilder = mapBuilder;
}
@Override
public String getSerializedName() {
return name;
}
@Override
public String toString() {
return name;
}
}
public enum EndBiomeGeneratorType implements StringRepresentable {
VANILLA("vanilla"),
PAULEVS("paulevs");
public static final Codec<EndBiomeGeneratorType> CODEC = StringRepresentable.fromEnum(EndBiomeGeneratorType::values);
public final String name;
EndBiomeGeneratorType(String name) {
this.name = name;
}
@Override
public String getSerializedName() {
return name;
}
@Override
public String toString() {
return name;
}
}
public final @NotNull EndBiomeMapType mapVersion;
public final @NotNull EndBiomeGeneratorType generatorVersion;
public final boolean withVoidBiomes;
public final int innerVoidRadiusSquared;
@Override
public String toString() {
return "BCLibEndBiomeSourceConfig{" +
"mapVersion=" + mapVersion +
", generatorVersion=" + generatorVersion +
", withVoidBiomes=" + withVoidBiomes +
", innerVoidRadiusSquared=" + innerVoidRadiusSquared +
'}';
}
@Override
public boolean couldSetWithoutRepair(BiomeSourceConfig<?> input) {
if (input instanceof BCLEndBiomeSourceConfig cfg) {
return withVoidBiomes == cfg.withVoidBiomes && mapVersion == cfg.mapVersion;
}
return false;
}
@Override
public boolean sameConfig(BiomeSourceConfig<?> input) {
return this.equals(input);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BCLEndBiomeSourceConfig)) return false;
BCLEndBiomeSourceConfig that = (BCLEndBiomeSourceConfig) o;
return withVoidBiomes == that.withVoidBiomes && innerVoidRadiusSquared == that.innerVoidRadiusSquared && mapVersion == that.mapVersion && generatorVersion == that.generatorVersion;
}
@Override
public int hashCode() {
return Objects.hash(mapVersion, generatorVersion, withVoidBiomes, innerVoidRadiusSquared);
}
}

View file

@ -0,0 +1,98 @@
package org.betterx.bclib.api.v2.generator.config;
import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource;
import org.betterx.bclib.api.v2.generator.BiomePicker;
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap;
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
import org.betterx.bclib.interfaces.BiomeMap;
import org.betterx.bclib.util.TriFunction;
import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.util.StringRepresentable;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNetherBiomeSource> {
public static final BCLNetherBiomeSourceConfig MINECRAFT_17 = new BCLNetherBiomeSourceConfig(
NetherBiomeMapType.SQUARE
);
public static final BCLNetherBiomeSourceConfig MINECRAFT_18 = new BCLNetherBiomeSourceConfig(
NetherBiomeMapType.HEX
);
public static final BCLNetherBiomeSourceConfig DEFAULT = MINECRAFT_18;
public static final Codec<BCLNetherBiomeSourceConfig> CODEC = RecordCodecBuilder.create(instance -> instance
.group(
BCLNetherBiomeSourceConfig.NetherBiomeMapType.CODEC
.fieldOf("map_type")
.orElse(DEFAULT.mapVersion)
.forGetter(o -> o.mapVersion)
)
.apply(instance, BCLNetherBiomeSourceConfig::new));
public final @NotNull NetherBiomeMapType mapVersion;
public BCLNetherBiomeSourceConfig(@NotNull NetherBiomeMapType mapVersion) {
this.mapVersion = mapVersion;
}
@Override
public String toString() {
return "BCLibNetherBiomeSourceConfig{" +
"mapVersion=" + mapVersion +
'}';
}
@Override
public boolean couldSetWithoutRepair(BiomeSourceConfig<?> input) {
if (input instanceof BCLNetherBiomeSourceConfig cfg) {
return mapVersion == cfg.mapVersion;
}
return false;
}
@Override
public boolean sameConfig(BiomeSourceConfig<?> input) {
return this.equals(input);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BCLNetherBiomeSourceConfig)) return false;
BCLNetherBiomeSourceConfig that = (BCLNetherBiomeSourceConfig) o;
return mapVersion == that.mapVersion;
}
@Override
public int hashCode() {
return Objects.hash(mapVersion);
}
public enum NetherBiomeMapType implements StringRepresentable {
VANILLA("vanilla", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker)),
SQUARE("square", (seed, biomeSize, picker) -> new SquareBiomeMap(seed, biomeSize, picker)),
HEX("hex", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker));
public static final Codec<NetherBiomeMapType> CODEC = StringRepresentable.fromEnum(NetherBiomeMapType::values);
public final String name;
public final TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder;
NetherBiomeMapType(String name, TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder) {
this.name = name;
this.mapBuilder = mapBuilder;
}
@Override
public String getSerializedName() {
return name;
}
@Override
public String toString() {
return name;
}
}
}

View file

@ -5,11 +5,10 @@ import org.betterx.bclib.interfaces.BiomeChunk;
import org.betterx.bclib.interfaces.BiomeMap; import org.betterx.bclib.interfaces.BiomeMap;
import org.betterx.bclib.interfaces.TriConsumer; import org.betterx.bclib.interfaces.TriConsumer;
import org.betterx.bclib.noise.OpenSimplexNoise; import org.betterx.bclib.noise.OpenSimplexNoise;
import org.betterx.bclib.util.TriFunction;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import org.apache.commons.lang3.function.TriFunction;
import java.util.Random; import java.util.Random;
public class MapStack implements BiomeMap { public class MapStack implements BiomeMap {

View file

@ -5,8 +5,8 @@ import org.betterx.bclib.api.v2.LifeCycleAPI;
import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI; import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI;
import org.betterx.bclib.api.v2.datafixer.DataFixerAPI; import org.betterx.bclib.api.v2.datafixer.DataFixerAPI;
import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI;
import org.betterx.bclib.presets.worldgen.BCLWorldPresetSettings;
import org.betterx.bclib.registry.PresetsRegistry; import org.betterx.bclib.registry.PresetsRegistry;
import org.betterx.worlds.together.world.event.WorldEvents; import org.betterx.worlds.together.world.event.WorldEvents;
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
@ -59,21 +59,24 @@ public class LevelGenEvents {
if (currentPreset.isPresent()) { if (currentPreset.isPresent()) {
if (currentPreset.get().value() instanceof TogetherWorldPreset worldPreset) { if (currentPreset.get().value() instanceof TogetherWorldPreset worldPreset) {
ResourceKey key = currentPreset.get().unwrapKey().orElse(null); ResourceKey worldPresetKey = currentPreset.get().unwrapKey().orElse(null);
//user did not configure the Preset!
if (PresetsRegistry.BCL_WORLD.equals(key) || PresetsRegistry.BCL_WORLD_17.equals(key)) { //user did not configure/change the Preset!
if (PresetsRegistry.BCL_WORLD.equals(worldPresetKey)
|| PresetsRegistry.BCL_WORLD_17.equals(worldPresetKey)) {
BCLib.LOGGER.info("Detected Datapack for END."); BCLib.LOGGER.info("Detected Datapack for END.");
if (worldPreset.settings instanceof BCLWorldPresetSettings settings) { LevelStem configuredEndStem = worldPreset.getDimension(LevelStem.END);
if (configuredEndStem.generator().getBiomeSource() instanceof BCLibEndBiomeSource endSource) {
BCLib.LOGGER.info("Changing Default WorldPreset Settings for Datapack use."); BCLib.LOGGER.info("Changing Default WorldPreset Settings for Datapack use.");
worldPreset = worldPreset.withSettings(new BCLWorldPresetSettings( BCLEndBiomeSourceConfig inputConfig = endSource.getTogetherConfig();
settings.netherVersion, endSource.setTogetherConfig(new BCLEndBiomeSourceConfig(
settings.endVersion, inputConfig.mapVersion,
BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA,
false, false,
false inputConfig.innerVoidRadiusSquared
)); ));
currentPreset = Optional.of(Holder.direct(worldPreset));
} }
} }
} }

View file

@ -5,11 +5,13 @@ import org.betterx.bclib.api.v2.generator.BCLBiomeSource;
import org.betterx.bclib.api.v2.generator.BCLChunkGenerator; import org.betterx.bclib.api.v2.generator.BCLChunkGenerator;
import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource; import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource;
import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
import org.betterx.bclib.presets.worldgen.BCLWorldPresetSettings; import org.betterx.bclib.presets.worldgen.BCLWorldPresetSettings;
import org.betterx.bclib.registry.PresetsRegistry; import org.betterx.bclib.registry.PresetsRegistry;
import org.betterx.worlds.together.levelgen.WorldGenUtil;
import org.betterx.worlds.together.util.ModUtil; import org.betterx.worlds.together.util.ModUtil;
import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.world.WorldConfig;
import org.betterx.worlds.together.world.WorldGenUtil;
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings;
@ -20,7 +22,6 @@ import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.chunk.ChunkGenerator; 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;
@ -35,41 +36,33 @@ public class LevelGenUtil {
private static final String TAG_BN_GEN_VERSION = "generator_version"; private static final String TAG_BN_GEN_VERSION = "generator_version";
@NotNull @NotNull
public static LevelStem getBCLNetherLevelStem(WorldGenUtil.Context context, Optional<Integer> version) { public static LevelStem getBCLNetherLevelStem(WorldGenUtil.Context context, BCLNetherBiomeSourceConfig config) {
BCLibNetherBiomeSource netherSource = new BCLibNetherBiomeSource(context.biomes, version); BCLibNetherBiomeSource netherSource = new BCLibNetherBiomeSource(context.biomes, config);
return getBCLNetherLevelStem(context, netherSource);
}
public static LevelStem getBCLNetherLevelStem(WorldGenUtil.StemContext context, BiomeSource biomeSource) {
return new LevelStem( return new LevelStem(
context.dimension, context.dimension,
new BCLChunkGenerator( new BCLChunkGenerator(
context.structureSets, context.structureSets,
context.noiseParameters, context.noiseParameters,
biomeSource, netherSource,
context.generatorSettings context.generatorSettings
) )
); );
} }
@NotNull public static LevelStem getBCLEndLevelStem(WorldGenUtil.Context context, BCLEndBiomeSourceConfig config) {
public static LevelStem getBCLEndLevelStem(WorldGenUtil.StemContext context, BiomeSource biomeSource) { BCLibEndBiomeSource endSource = new BCLibEndBiomeSource(context.biomes, config);
return new LevelStem( return new LevelStem(
context.dimension, context.dimension,
new BCLChunkGenerator( new BCLChunkGenerator(
context.structureSets, context.structureSets,
context.noiseParameters, context.noiseParameters,
biomeSource, endSource,
context.generatorSettings context.generatorSettings
) )
); );
} }
public static LevelStem getBCLEndLevelStem(WorldGenUtil.Context context, Optional<Integer> version) {
BCLibEndBiomeSource endSource = new BCLibEndBiomeSource(context.biomes, version);
return getBCLEndLevelStem(context, endSource);
}
public static WorldGenSettings replaceGenerator( public static WorldGenSettings replaceGenerator(
ResourceKey<LevelStem> dimensionKey, ResourceKey<LevelStem> dimensionKey,
@ -178,10 +171,10 @@ public class LevelGenUtil {
return writableRegistry; return writableRegistry;
} }
public static int getBiomeVersionForGenerator(ChunkGenerator generator) { // public static int getBiomeVersionForGenerator(ChunkGenerator generator) {
if (generator == null) return BCLBiomeSource.getVersionBiomeSource(null); // if (generator == null) return BCLBiomeSource.getVersionBiomeSource(null);
return BCLBiomeSource.getVersionBiomeSource(generator.getBiomeSource()); // return BCLBiomeSource.getVersionBiomeSource(generator.getBiomeSource());
} // }
public static Optional<Holder<LevelStem>> referenceStemForVersion( public static Optional<Holder<LevelStem>> referenceStemForVersion(
ResourceKey<LevelStem> dimensionKey, ResourceKey<LevelStem> dimensionKey,
@ -224,25 +217,25 @@ public class LevelGenUtil {
return settingsNbt.getInt(key.location().toString()); return settingsNbt.getInt(key.location().toString());
} }
private static int getDimensionVersion( // private static int getDimensionVersion(
WorldGenSettings settings, // WorldGenSettings settings,
ResourceKey<LevelStem> key // ResourceKey<LevelStem> key
) { // ) {
var dimension = settings.dimensions().getHolder(key); // var dimension = settings.dimensions().getHolder(key);
if (dimension.isPresent()) { // if (dimension.isPresent()) {
return getBiomeVersionForGenerator(dimension.get().value().generator()); // return getBiomeVersionForGenerator(dimension.get().value().generator());
} else { // } else {
return getBiomeVersionForGenerator(null); // return getBiomeVersionForGenerator(null);
} // }
} // }
private static void writeDimensionVersion( // private static void writeDimensionVersion(
WorldGenSettings settings, // WorldGenSettings settings,
CompoundTag generatorSettings, // CompoundTag generatorSettings,
ResourceKey<LevelStem> key // ResourceKey<LevelStem> key
) { // ) {
generatorSettings.putInt(key.location().toString(), getDimensionVersion(settings, key)); // generatorSettings.putInt(key.location().toString(), getDimensionVersion(settings, key));
} // }
public static void migrateGeneratorSettings() { public static void migrateGeneratorSettings() {
final CompoundTag settingsNbt = WorldGenUtil.getSettingsNbt(); final CompoundTag settingsNbt = WorldGenUtil.getSettingsNbt();

View file

@ -1,7 +1,5 @@
package org.betterx.bclib.api.v2.levelgen.biomes; package org.betterx.bclib.api.v2.levelgen.biomes;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleUtil;
import org.betterx.bclib.util.WeightedList; import org.betterx.bclib.util.WeightedList;
import org.betterx.worlds.together.tag.v3.TagManager; import org.betterx.worlds.together.tag.v3.TagManager;
@ -11,8 +9,6 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Climate; import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.levelgen.SurfaceRules;
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
import net.minecraft.world.level.levelgen.WorldgenRandom; import net.minecraft.world.level.levelgen.WorldgenRandom;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -36,7 +32,6 @@ public class BCLBiome extends BCLBiomeSettings {
private final List<Climate.ParameterPoint> parameterPoints = Lists.newArrayList(); private final List<Climate.ParameterPoint> parameterPoints = Lists.newArrayList();
private Consumer<ResourceKey<Biome>> surfaceInit;
private BCLBiome biomeParent; private BCLBiome biomeParent;
/** /**
@ -202,10 +197,6 @@ public class BCLBiome extends BCLBiomeSettings {
void afterRegistration() { void afterRegistration() {
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(getBiome()).orElseThrow(); ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(getBiome()).orElseThrow();
this.biomeTags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, biome)); this.biomeTags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, biome));
if (this.surfaceInit != null) {
surfaceInit.accept(key);
}
} }
@ -297,21 +288,6 @@ public class BCLBiome extends BCLBiomeSettings {
this.parameterPoints.forEach(consumer); this.parameterPoints.forEach(consumer);
} }
/**
* Sets biome surface rule.
*
* @param surface {@link SurfaceRules.RuleSource} rule.
*/
void setSurface(RuleSource surface) {
this.surfaceInit = (key) -> {
if (key == null) {
BCLib.LOGGER.warning("BCL Biome " + biomeID + " does not have registry key!");
} else {
SurfaceRuleUtil.addSurfaceRule(biomeID, SurfaceRules.ifTrue(SurfaceRules.isBiome(key), surface));
}
};
}
/** /**
* Returns the group used in the config Files for this biome * Returns the group used in the config Files for this biome
* <p> * <p>

View file

@ -1,87 +0,0 @@
package org.betterx.bclib.api.v2.levelgen.surface;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI;
import org.betterx.worlds.together.mixin.common.NoiseGeneratorSettingsMixin;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class SurfaceRuleUtil {
private static final Map<ResourceLocation, RuleSource> SURFACE_RULES = Maps.newHashMap();
private static List<RuleSource> getRuleSourcesForBiomes(Set<Holder<Biome>> biomes) {
Set<ResourceLocation> biomeIDs = biomes
.stream()
.map(biome -> BiomeAPI.getBiomeID(biome))
.collect(Collectors.toSet());
return getRuleSourcesFromIDs(biomeIDs);
}
/**
* Creates a list of SurfaceRules for all Biomes that are managed by the passed {@link BiomeSource}.
* If we have Surface rules for any of the Biomes from the given set of {@link BiomeSource}, they
* will be added to the result
* <p>
* Note: This Method is used in the {@link NoiseGeneratorSettingsMixin} which in turn
* is called from {@link InternalBiomeAPI#applyModificationsDeprecated(ServerLevel)}.
*
* @param sources The Set of {@link BiomeSource} we want to consider
* @return A list of {@link RuleSource}-Objects that are needed to create those Biomes
*/
public static List<RuleSource> getRuleSources(Set<BiomeSource> sources) {
final Set<Holder<Biome>> biomes = new HashSet<>();
for (BiomeSource s : sources) {
biomes.addAll(s.possibleBiomes());
}
return getRuleSourcesForBiomes(biomes);
}
public static List<RuleSource> getRuleSources(BiomeSource biomeSource) {
return getRuleSourcesForBiomes(Sets.newHashSet(biomeSource.possibleBiomes()));
}
private static List<RuleSource> getRuleSourcesFromIDs(Set<ResourceLocation> biomeIDs) {
List<RuleSource> rules = Lists.newArrayList();
SURFACE_RULES.forEach((biomeID, rule) -> {
if (biomeIDs.contains(biomeID)) {
rules.add(rule);
}
});
return rules;
}
/**
* Adds surface rule to specified biome.
*
* @param biomeID biome {@link ResourceLocation}.
* @param source {@link RuleSource}.
*/
public static void addSurfaceRule(ResourceLocation biomeID, RuleSource source) {
SURFACE_RULES.put(biomeID, source);
}
public static RuleSource addRulesForBiomeSource(RuleSource orgiginalSource, BiomeSource biomeSource) {
List<RuleSource> additionalRules = getRuleSources(biomeSource);
return org.betterx.worlds.together.surfaceRules.SurfaceRuleUtil.mergeSurfaceRules(
orgiginalSource,
additionalRules
);
}
}

View file

@ -1,16 +1,12 @@
package org.betterx.bclib.presets.worldgen; package org.betterx.bclib.presets.worldgen;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.generator.BCLBiomeSource; import org.betterx.bclib.api.v2.generator.BCLBiomeSource;
import org.betterx.bclib.api.v2.generator.BCLChunkGenerator;
import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil; import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; import org.betterx.worlds.together.levelgen.WorldGenUtil;
import org.betterx.bclib.interfaces.ChunkGeneratorAccessor;
import org.betterx.bclib.interfaces.NoiseGeneratorSettingsProvider;
import org.betterx.worlds.together.world.WorldGenUtil;
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
import org.betterx.worlds.together.worldPreset.settings.VanillaWorldPresetSettings;
import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
@ -20,40 +16,37 @@ import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.dimension.BuiltinDimensionTypes;
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.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.WorldGenSettings;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
public class BCLWorldPresetSettings extends WorldPresetSettings { public class BCLWorldPresetSettings extends WorldPresetSettings {
public final static BCLWorldPresetSettings DEFAULT = new BCLWorldPresetSettings(BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION); public final static BCLWorldPresetSettings DEFAULT = new BCLWorldPresetSettings(BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION);
public static final Codec<BCLWorldPresetSettings> CODEC = RecordCodecBuilder public static final Codec<BCLWorldPresetSettings> CODEC = RecordCodecBuilder
.create((RecordCodecBuilder.Instance<BCLWorldPresetSettings> builderInstance) -> { .create((RecordCodecBuilder.Instance<BCLWorldPresetSettings> builderInstance) -> builderInstance.group(
return builderInstance.group( Codec.INT
Codec.INT .fieldOf(LevelStem.NETHER.location().toString())
.fieldOf(LevelStem.NETHER.location().toString()) .forGetter(o -> o.netherVersion),
.forGetter(o -> o.netherVersion), Codec.INT
Codec.INT .fieldOf(LevelStem.END.location().toString())
.fieldOf(LevelStem.END.location().toString()) .forGetter(o -> o.endVersion),
.forGetter(o -> o.endVersion), Codec.BOOL
Codec.BOOL .fieldOf("custom_end_terrain")
.fieldOf("custom_end_terrain") .orElse(true)
.orElse(true) .forGetter(o -> o.useEndTerrainGenerator),
.forGetter(o -> o.useEndTerrainGenerator), Codec.BOOL
Codec.BOOL .fieldOf("generate_end_void")
.fieldOf("generate_end_void") .orElse(false)
.orElse(false) .forGetter(o -> o.generateEndVoid)
.forGetter(o -> o.generateEndVoid) )
) .apply(
.apply(builderInstance, builderInstance.stable(BCLWorldPresetSettings::new)); builderInstance,
}); builderInstance.stable(
BCLWorldPresetSettings::new)
));
public final int netherVersion; public final int netherVersion;
public final int endVersion; public final int endVersion;
public final boolean useEndTerrainGenerator; public final boolean useEndTerrainGenerator;
@ -89,6 +82,24 @@ public class BCLWorldPresetSettings extends WorldPresetSettings {
return new TogetherWorldPreset(buildDimensionMap(overworldStem, netherContext, endContext), 1000, this); return new TogetherWorldPreset(buildDimensionMap(overworldStem, netherContext, endContext), 1000, this);
} }
private static BCLEndBiomeSourceConfig getEndConfigForVersion(int version) {
if (version == BCLBiomeSource.BIOME_SOURCE_VERSION_HEX)
return BCLEndBiomeSourceConfig.MINECRAFT_18;
if (version == BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE)
return BCLEndBiomeSourceConfig.MINECRAFT_17;
return BCLEndBiomeSourceConfig.DEFAULT;
}
private static BCLNetherBiomeSourceConfig getNetherConfigForVersion(int version) {
if (version == BCLBiomeSource.BIOME_SOURCE_VERSION_HEX)
return BCLNetherBiomeSourceConfig.MINECRAFT_18;
if (version == BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE)
return BCLNetherBiomeSourceConfig.MINECRAFT_17;
return BCLNetherBiomeSourceConfig.DEFAULT;
}
public Map<ResourceKey<LevelStem>, LevelStem> buildDimensionMap( public Map<ResourceKey<LevelStem>, LevelStem> buildDimensionMap(
LevelStem overworldStem, LevelStem overworldStem,
WorldGenUtil.Context netherContext, WorldGenUtil.Context netherContext,
@ -98,32 +109,19 @@ public class BCLWorldPresetSettings extends WorldPresetSettings {
LevelStem.OVERWORLD, LevelStem.OVERWORLD,
overworldStem, overworldStem,
LevelStem.NETHER, LevelStem.NETHER,
createNetherStem(netherContext), LevelGenUtil.getBCLNetherLevelStem(netherContext, getNetherConfigForVersion(netherVersion)),
LevelStem.END, LevelStem.END,
createEndStem(endContext) LevelGenUtil.getBCLEndLevelStem(endContext, getEndConfigForVersion(endVersion))
); );
} }
public int getVersion(ResourceKey<LevelStem> key) { // public int getVersion(ResourceKey<LevelStem> key) {
if (key == LevelStem.NETHER) return netherVersion; // if (key == LevelStem.NETHER) return netherVersion;
if (key == LevelStem.END) return endVersion; // if (key == LevelStem.END) return endVersion;
//
// return BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA;
// }
return BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA;
}
public LevelStem createStem(WorldGenUtil.Context ctx, ResourceKey<LevelStem> key) {
if (key == LevelStem.NETHER) return createNetherStem(ctx);
if (key == LevelStem.END) return createEndStem(ctx);
return null;
}
public LevelStem createNetherStem(WorldGenUtil.Context ctx) {
return LevelGenUtil.getBCLNetherLevelStem(ctx, Optional.of(netherVersion));
}
public LevelStem createEndStem(WorldGenUtil.Context ctx) {
return LevelGenUtil.getBCLEndLevelStem(ctx, Optional.of(endVersion));
}
public BiomeSource addDatapackBiomes(BiomeSource biomeSource, Set<Holder<Biome>> datapackBiomes) { public BiomeSource addDatapackBiomes(BiomeSource biomeSource, Set<Holder<Biome>> datapackBiomes) {
if (biomeSource instanceof BCLBiomeSource bs) { if (biomeSource instanceof BCLBiomeSource bs) {
@ -132,114 +130,108 @@ public class BCLWorldPresetSettings extends WorldPresetSettings {
return biomeSource; return biomeSource;
} }
@Override
public void injectSurfaceRules(RegistryAccess registryAccess, WorldGenSettings settings) {
VanillaWorldPresetSettings.DEFAULT.injectSurfaceRules(registryAccess, settings);
}
private static Holder<NoiseGeneratorSettings> buildGeneratorSettings( // private static Holder<NoiseGeneratorSettings> buildGeneratorSettings(
Holder<NoiseGeneratorSettings> reference, // Holder<NoiseGeneratorSettings> reference,
Holder<NoiseGeneratorSettings> settings, // Holder<NoiseGeneratorSettings> settings,
BiomeSource biomeSource // BiomeSource biomeSource
) { // ) {
//SurfaceRuleUtil.injectSurfaceRules(settings.value(), biomeSource); // //SurfaceRuleUtil.injectSurfaceRules(settings.value(), biomeSource);
return settings; // return settings;
// NoiseGeneratorSettings old = settings.value(); //// NoiseGeneratorSettings old = settings.value();
// NoiseGeneratorSettings noise = new NoiseGeneratorSettings( //// NoiseGeneratorSettings noise = new NoiseGeneratorSettings(
// old.noiseSettings(), //// old.noiseSettings(),
// old.defaultBlock(), //// old.defaultBlock(),
// old.defaultFluid(), //// old.defaultFluid(),
// old.noiseRouter(), //// old.noiseRouter(),
// SurfaceRuleRegistry.mergeSurfaceRulesFromBiomes(old.surfaceRule(), biomeSource), //// SurfaceRuleRegistry.mergeSurfaceRulesFromBiomes(old.surfaceRule(), biomeSource),
// //SurfaceRuleUtil.addRulesForBiomeSource(old.surfaceRule(), biomeSource), //// //SurfaceRuleUtil.addRulesForBiomeSource(old.surfaceRule(), biomeSource),
// old.spawnTarget(), //// old.spawnTarget(),
// old.seaLevel(), //// old.seaLevel(),
// old.disableMobGeneration(), //// old.disableMobGeneration(),
// old.aquifersEnabled(), //// old.aquifersEnabled(),
// old.oreVeinsEnabled(), //// old.oreVeinsEnabled(),
// old.useLegacyRandomSource() //// old.useLegacyRandomSource()
// ); //// );
////
////
//// return Holder.direct(noise);
// }
// /**
// * Datapacks can change the world's generator. This Method will ensure, that the Generators contain
// * the correct BiomeSources for this world
// *
// * @param dimensionKey
// * @param dimensionTypeKey
// * @param settings
// * @return
// */
// private WorldGenSettings fixSettingsInCurrentWorld(
// RegistryAccess access, ResourceKey<LevelStem> dimensionKey,
// ResourceKey<DimensionType> dimensionTypeKey,
// WorldGenSettings settings
// ) {
// Optional<Holder<LevelStem>> loadedStem = settings.dimensions().getHolder(dimensionKey);
// final ChunkGenerator loadedChunkGenerator = loadedStem.map(h -> h.value().generator()).orElse(null);
// final int loaderVersion = LevelGenUtil.getBiomeVersionForGenerator(loadedStem
// .map(h -> h.value().generator())
// .orElse(null));
// //
// final int targetVersion = getVersion(dimensionKey);
// if (loaderVersion != targetVersion) {
// BCLib.LOGGER.info("Enforcing Correct Generator for " + dimensionKey.location().toString() + ".");
// //
// return Holder.direct(noise); // Optional<Holder<LevelStem>> refLevelStem = LevelGenUtil.referenceStemForVersion(
} // dimensionKey,
// targetVersion,
// access,
/** // settings.seed(),
* Datapacks can change the world's generator. This Method will ensure, that the Generators contain // settings.generateStructures(),
* the correct BiomeSources for this world // settings.generateBonusChest()
* // );
* @param dimensionKey //
* @param dimensionTypeKey // ChunkGenerator referenceGenerator = refLevelStem.map(h -> h.value().generator()).orElse(null);
* @param settings // if (referenceGenerator == null) {
* @return // BCLib.LOGGER.error("Failed to create Generator for " + dimensionKey.location().toString());
*/ // return settings;
private WorldGenSettings fixSettingsInCurrentWorld( // }
RegistryAccess access, ResourceKey<LevelStem> dimensionKey, //
ResourceKey<DimensionType> dimensionTypeKey, // if (loadedChunkGenerator instanceof ChunkGeneratorAccessor generator) {
WorldGenSettings settings // if (loadedChunkGenerator instanceof NoiseGeneratorSettingsProvider noiseProvider) {
) { // if (referenceGenerator instanceof NoiseGeneratorSettingsProvider referenceProvider) {
Optional<Holder<LevelStem>> loadedStem = settings.dimensions().getHolder(dimensionKey); // final Set<Holder<Biome>> biomes = loadedChunkGenerator.getBiomeSource().possibleBiomes();
final ChunkGenerator loadedChunkGenerator = loadedStem.map(h -> h.value().generator()).orElse(null); // final BiomeSource bs = addDatapackBiomes(referenceGenerator.getBiomeSource(), biomes);
final int loaderVersion = LevelGenUtil.getBiomeVersionForGenerator(loadedStem // InternalBiomeAPI.applyModifications(bs, dimensionKey);
.map(h -> h.value().generator()) // referenceGenerator = new BCLChunkGenerator(
.orElse(null)); // generator.bclib_getStructureSetsRegistry(),
// noiseProvider.bclib_getNoises(),
final int targetVersion = getVersion(dimensionKey); // bs,
if (loaderVersion != targetVersion) { // buildGeneratorSettings(
BCLib.LOGGER.info("Enforcing Correct Generator for " + dimensionKey.location().toString() + "."); // referenceProvider.bclib_getNoiseGeneratorSettingHolders(),
// noiseProvider.bclib_getNoiseGeneratorSettingHolders(),
Optional<Holder<LevelStem>> refLevelStem = LevelGenUtil.referenceStemForVersion( // bs
dimensionKey, // )
targetVersion, // );
access, // }
settings.seed(), // }
settings.generateStructures(), // }
settings.generateBonusChest() //
); // return LevelGenUtil.replaceGenerator(
// dimensionKey,
ChunkGenerator referenceGenerator = refLevelStem.map(h -> h.value().generator()).orElse(null); // dimensionTypeKey,
if (referenceGenerator == null) { // access,
BCLib.LOGGER.error("Failed to create Generator for " + dimensionKey.location().toString()); // settings,
return settings; // referenceGenerator
} // );
// }
if (loadedChunkGenerator instanceof ChunkGeneratorAccessor generator) { // return settings;
if (loadedChunkGenerator instanceof NoiseGeneratorSettingsProvider noiseProvider) { // }
if (referenceGenerator instanceof NoiseGeneratorSettingsProvider referenceProvider) {
final Set<Holder<Biome>> biomes = loadedChunkGenerator.getBiomeSource().possibleBiomes();
final BiomeSource bs = addDatapackBiomes(referenceGenerator.getBiomeSource(), biomes);
InternalBiomeAPI.applyModifications(bs, dimensionKey);
referenceGenerator = new BCLChunkGenerator(
generator.bclib_getStructureSetsRegistry(),
noiseProvider.bclib_getNoises(),
bs,
buildGeneratorSettings(
referenceProvider.bclib_getNoiseGeneratorSettingHolders(),
noiseProvider.bclib_getNoiseGeneratorSettingHolders(),
bs
)
);
}
}
}
return LevelGenUtil.replaceGenerator(
dimensionKey,
dimensionTypeKey,
access,
settings,
referenceGenerator
);
}/* else {
SurfaceRuleUtil.injectSurfaceRules(dimensionKey, loadedChunkGenerator);
}*/
return settings;
}
public WorldGenSettings repairSettingsOnLoad(RegistryAccess registryAccess, WorldGenSettings settings) { public WorldGenSettings repairSettingsOnLoad(RegistryAccess registryAccess, WorldGenSettings settings) {
settings = fixSettingsInCurrentWorld(registryAccess, LevelStem.NETHER, BuiltinDimensionTypes.NETHER, settings); // settings = fixSettingsInCurrentWorld(registryAccess, LevelStem.NETHER, BuiltinDimensionTypes.NETHER, settings);
settings = fixSettingsInCurrentWorld(registryAccess, LevelStem.END, BuiltinDimensionTypes.END, settings); // settings = fixSettingsInCurrentWorld(registryAccess, LevelStem.END, BuiltinDimensionTypes.END, settings);
return settings; return settings;
} }

View file

@ -18,9 +18,9 @@ public class PresetsRegistry {
public static void onLoad() { public static void onLoad() {
BCL_WORLD = BCL_WORLD =
WorldPresets.register( WorldPresets.register(
BCLib.makeID("normal"), BCLib.makeID("hex_map"),
(overworldStem, netherContext, endContext) -> (overworldStem, netherContext, endContext) ->
new BCLWorldPresetSettings(BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION).buildPreset( new BCLWorldPresetSettings(BCLBiomeSource.BIOME_SOURCE_VERSION_HEX).buildPreset(
overworldStem, overworldStem,
netherContext, netherContext,
endContext endContext

View file

@ -0,0 +1,10 @@
package org.betterx.worlds.together.biomesource;
import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig;
import net.minecraft.world.level.biome.BiomeSource;
public interface BiomeSourceWithConfig<B extends BiomeSource, C extends BiomeSourceConfig<B>> {
C getTogetherConfig();
void setTogetherConfig(C newConfig);
}

View file

@ -0,0 +1,17 @@
package org.betterx.worlds.together.biomesource;
import net.minecraft.world.level.biome.BiomeSource;
public interface MergeableBiomeSource<B extends BiomeSource> {
/**
* Returns a BiomeSource that merges the settings of this one with the Biomes (and possibly settings) from the
* {@code inputBiomeSource}.
*
* @param inputBiomeSource The {@link BiomeSource} you want to copy
* @return The merged or new BiomeSource
*/
B mergeWithBiomeSource(BiomeSource inputBiomeSource);
}

View file

@ -0,0 +1,7 @@
package org.betterx.worlds.together.biomesource;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
public interface MultiNoiseBiomeSourceAccessor {
}

View file

@ -0,0 +1,8 @@
package org.betterx.worlds.together.biomesource.config;
import net.minecraft.world.level.biome.BiomeSource;
public interface BiomeSourceConfig<B extends BiomeSource> {
boolean couldSetWithoutRepair(BiomeSourceConfig<?> input);
boolean sameConfig(BiomeSourceConfig<?> input);
}

View file

@ -0,0 +1,20 @@
package org.betterx.worlds.together.chunkgenerator;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.WorldGenSettings;
public class ChunkGeneratorUtils {
public static void restoreOriginalBiomeSourceInAllDimension(WorldGenSettings settings) {
for (var entry : settings.dimensions().entrySet()) {
ResourceKey<LevelStem> key = entry.getKey();
LevelStem stem = entry.getValue();
if (stem.generator() instanceof RestorableBiomeSource<?> generator) {
generator.restoreInitialBiomeSource(key);
}
}
}
}

View file

@ -0,0 +1,35 @@
package org.betterx.worlds.together.chunkgenerator;
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.BiomeSource;
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.WorldGenSettings;
public interface EnforceableChunkGenerator<G extends ChunkGenerator> {
WorldGenSettings enforceGeneratorInWorldGenSettings(
RegistryAccess access,
ResourceKey<LevelStem> dimensionKey,
ResourceKey<DimensionType> dimensionTypeKey,
ChunkGenerator loadedChunkGenerator,
WorldGenSettings settings
);
default boolean needsChunkGeneratorRepair(ChunkGenerator chunkGenerator) {
ChunkGenerator self = (ChunkGenerator) this;
if (this == chunkGenerator || chunkGenerator == null) return false;
BiomeSource one = self.getBiomeSource();
BiomeSource two = chunkGenerator.getBiomeSource();
if (one == two) return false;
if (one instanceof BiomeSourceWithConfig<?, ?> ba && two instanceof BiomeSourceWithConfig<?, ?> bb) {
return !ba.getTogetherConfig().couldSetWithoutRepair(bb.getTogetherConfig());
}
return !one.getClass().isAssignableFrom(two.getClass()) && !two.getClass().isAssignableFrom(one.getClass());
}
}

View file

@ -0,0 +1,21 @@
package org.betterx.worlds.together.chunkgenerator;
import org.betterx.worlds.together.surfaceRules.SurfaceRuleUtil;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
public interface InjectableSurfaceRules<G extends ChunkGenerator> {
/**
* Called when the Surface Rules for this BiomeSource need to be
*
* @param dimensionKey The Dimension for which this injection is performed
*/
default void injectSurfaceRules(ResourceKey<LevelStem> dimensionKey) {
if (this instanceof NoiseBasedChunkGenerator nbc) {
SurfaceRuleUtil.injectSurfaceRules(nbc.generatorSettings().value(), nbc.getBiomeSource());
}
}
}

View file

@ -0,0 +1,9 @@
package org.betterx.worlds.together.chunkgenerator;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.dimension.LevelStem;
public interface RestorableBiomeSource<G extends ChunkGenerator> {
void restoreInitialBiomeSource(ResourceKey<LevelStem> dimensionKey);
}

View file

@ -1,6 +1,11 @@
package org.betterx.worlds.together.world; 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.chunkgenerator.EnforceableChunkGenerator;
import org.betterx.worlds.together.world.BiomeSourceWithSeed;
import org.betterx.worlds.together.world.WorldConfig;
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
import org.betterx.worlds.together.worldPreset.WorldPresets; import org.betterx.worlds.together.worldPreset.WorldPresets;
import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings;
@ -17,6 +22,7 @@ import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
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.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
@ -85,7 +91,6 @@ public class WorldGenUtil {
} }
public static WorldPresetSettings getWorldSettings() { public static WorldPresetSettings getWorldSettings() {
if (BuiltinRegistries.ACCESS == null) return null;
final RegistryAccess registryAccess = BuiltinRegistries.ACCESS; final RegistryAccess registryAccess = BuiltinRegistries.ACCESS;
final RegistryOps<Tag> registryOps = RegistryOps.create(NbtOps.INSTANCE, registryAccess); final RegistryOps<Tag> registryOps = RegistryOps.create(NbtOps.INSTANCE, registryAccess);
@ -128,4 +133,39 @@ public class WorldGenUtil {
this.generatorSettings = generatorSettings; this.generatorSettings = generatorSettings;
} }
} }
@SuppressWarnings("unchecked")
public static WorldGenSettings repairBiomeSourceInAllDimensions(
RegistryAccess registryAccess,
WorldGenSettings settings
) {
var dimensions = TogetherWorldPreset.getWorldDimensions();
for (var entry : settings.dimensions().entrySet()) {
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 (enforcer.needsChunkGeneratorRepair(loadedChunkGenerator)) {
settings = enforcer.enforceGeneratorInWorldGenSettings(
registryAccess,
key,
loadedStem.typeHolder().unwrapKey().orElseThrow(),
loadedChunkGenerator,
settings
);
} else if (loadedChunkGenerator.getBiomeSource() instanceof BiomeSourceWithConfig bs) {
if (referenceGenerator.getBiomeSource() instanceof BiomeSourceWithConfig refbs) {
if (!refbs.getTogetherConfig().sameConfig(bs.getTogetherConfig())) {
bs.setTogetherConfig(refbs.getTogetherConfig());
}
}
}
}
}
return settings;
}
} }

View file

@ -1,6 +1,6 @@
package org.betterx.worlds.together.mixin.client; package org.betterx.worlds.together.mixin.client;
import org.betterx.worlds.together.world.WorldGenUtil; import org.betterx.worlds.together.levelgen.WorldGenUtil;
import org.betterx.worlds.together.world.event.WorldBootstrap; import org.betterx.worlds.together.world.event.WorldBootstrap;
import org.betterx.worlds.together.worldPreset.WorldPresets; import org.betterx.worlds.together.worldPreset.WorldPresets;

View file

@ -1,6 +1,6 @@
package org.betterx.worlds.together.mixin.common; package org.betterx.worlds.together.mixin.common;
import org.betterx.worlds.together.world.WorldGenUtil; import org.betterx.worlds.together.surfaceRules.SurfaceRuleUtil;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
@ -29,6 +29,6 @@ public class MinecraftServerMixin {
@Inject(method = "createLevels", at = @At(value = "HEAD")) @Inject(method = "createLevels", at = @At(value = "HEAD"))
private void together_addSurfaceRules(ChunkProgressListener worldGenerationProgressListener, CallbackInfo ci) { private void together_addSurfaceRules(ChunkProgressListener worldGenerationProgressListener, CallbackInfo ci) {
WorldGenUtil.getWorldSettings().injectSurfaceRules(registryHolder, this.worldData.worldGenSettings()); SurfaceRuleUtil.injectSurfaceRulesToAllDimensions(this.worldData.worldGenSettings());
} }
} }

View file

@ -1,6 +1,6 @@
package org.betterx.bclib.mixin.common; package org.betterx.worlds.together.mixin.common;
import org.betterx.bclib.api.v2.generator.BCLChunkGenerator; import org.betterx.worlds.together.chunkgenerator.ChunkGeneratorUtils;
import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixer;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
@ -31,6 +31,6 @@ public class MinecraftServerMixinLate {
ChunkProgressListenerFactory chunkProgressListenerFactory, ChunkProgressListenerFactory chunkProgressListenerFactory,
CallbackInfo ci CallbackInfo ci
) { ) {
BCLChunkGenerator.restoreInitialBiomeSources(worldStem.worldData().worldGenSettings()); ChunkGeneratorUtils.restoreOriginalBiomeSourceInAllDimension(worldStem.worldData().worldGenSettings());
} }
} }

View file

@ -0,0 +1,11 @@
package org.betterx.worlds.together.mixin.common;
import org.betterx.worlds.together.chunkgenerator.InjectableSurfaceRules;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(NoiseBasedChunkGenerator.class)
public class NoiseBasedChunkGeneratorMixin implements InjectableSurfaceRules {
}

View file

@ -1,22 +1,16 @@
package org.betterx.worlds.together.mixin.common; package org.betterx.worlds.together.mixin.common;
import org.betterx.bclib.api.v2.levelgen.surface.SurfaceRuleUtil; import org.betterx.worlds.together.WorldsTogether;
import org.betterx.worlds.together.surfaceRules.SurfaceRuleProvider; import org.betterx.worlds.together.surfaceRules.SurfaceRuleProvider;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.SurfaceRules;
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Mixin(NoiseGeneratorSettings.class) @Mixin(NoiseGeneratorSettings.class)
public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider { public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
@Mutable @Mutable
@ -24,80 +18,15 @@ public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
@Shadow @Shadow
private SurfaceRules.RuleSource surfaceRule; private SurfaceRules.RuleSource surfaceRule;
private SurfaceRules.RuleSource bclib_originalSurfaceRule;
private final Set<BiomeSource> bclib_biomeSources = new HashSet<>();
private void bclib_updateCustomRules() {
bclib_setCustomRules(SurfaceRuleUtil.getRuleSources(bclib_biomeSources));
}
@Override
public void bclib_addBiomeSource(BiomeSource source) {
// bclib_biomeSources.add(source);
// bclib_updateCustomRules();
}
@Override
public void bclib_clearBiomeSources() {
// bclib_biomeSources.clear();
// bclib_clearCustomRules();
}
private void bclib_clearCustomRules() {
// if (bclib_originalSurfaceRule != null) {
// this.surfaceRule = bclib_originalSurfaceRule;
// bclib_originalSurfaceRule = null;
// }
}
private void bclib_setCustomRules(List<RuleSource> rules) {
// if (rules.size() == 0) {
// bclib_clearCustomRules();
// return;
// }
//
// RuleSource org = bclib_getOriginalSurfaceRule();
// if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule) {
// List<RuleSource> currentSequence = sequenceRule.sequence();
// rules = rules.stream().filter(r -> currentSequence.indexOf(r) < 0).collect(Collectors.toList());
// rules.addAll(sequenceRule.sequence());
// } else {
// rules.add(org);
// }
//
// bclib_setSurfaceRule(SurfaceRules.sequence(rules.toArray(new RuleSource[rules.size()])));
}
public void bclib_overwrite(SurfaceRules.RuleSource surfaceRule) { public void bclib_overwrite(SurfaceRules.RuleSource surfaceRule) {
if (surfaceRule == this.surfaceRule) return; if (surfaceRule == this.surfaceRule) return;
if (this.bcl_containsOverride) { if (this.bcl_containsOverride) {
System.out.println("Adding another override"); WorldsTogether.LOGGER.warning("Overwriting an overwritten set of Surface Rules.");
} }
this.bcl_containsOverride = true; this.bcl_containsOverride = true;
this.surfaceRule = surfaceRule; this.surfaceRule = surfaceRule;
} }
void bclib_setSurfaceRule(SurfaceRules.RuleSource surfaceRule) {
if (bclib_originalSurfaceRule == null) {
bclib_originalSurfaceRule = this.surfaceRule;
}
this.surfaceRule = surfaceRule;
}
private boolean bcl_containsOverride = false; private boolean bcl_containsOverride = false;
RuleSource bclib_getOriginalSurfaceRule() {
if (bclib_originalSurfaceRule == null) {
return surfaceRule;
}
return bclib_originalSurfaceRule;
}
// @Inject(method = "surfaceRule", at = @At("HEAD"), cancellable = true)
// private void bclib_surfaceRule(CallbackInfoReturnable<SurfaceRules.RuleSource> info) {
// if (bclib_surfaceRule != null) {
// info.setReturnValue(bclib_surfaceRule);
// }
// }
} }

View file

@ -1,6 +1,6 @@
package org.betterx.worlds.together.mixin.common; package org.betterx.worlds.together.mixin.common;
import org.betterx.worlds.together.world.WorldGenUtil; import org.betterx.worlds.together.levelgen.WorldGenUtil;
import org.betterx.worlds.together.worldPreset.WorldPresets; import org.betterx.worlds.together.worldPreset.WorldPresets;
import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings;

View file

@ -1,10 +1,7 @@
package org.betterx.worlds.together.surfaceRules; package org.betterx.worlds.together.surfaceRules;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.SurfaceRules;
public interface SurfaceRuleProvider { public interface SurfaceRuleProvider {
void bclib_addBiomeSource(BiomeSource source);
void bclib_clearBiomeSources();
void bclib_overwrite(SurfaceRules.RuleSource surfaceRule); void bclib_overwrite(SurfaceRules.RuleSource surfaceRule);
} }

View file

@ -1,29 +1,24 @@
package org.betterx.worlds.together.surfaceRules; package org.betterx.worlds.together.surfaceRules;
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; import org.betterx.worlds.together.chunkgenerator.InjectableSurfaceRules;
import org.betterx.worlds.together.WorldsTogether;
import org.betterx.worlds.together.world.event.WorldBootstrap; import org.betterx.worlds.together.world.event.WorldBootstrap;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.chunk.ChunkGenerator;
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.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.SurfaceRules;
import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.WorldGenSettings;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class SurfaceRuleUtil { public class SurfaceRuleUtil {
public static List<SurfaceRules.RuleSource> getRulesForBiome(ResourceLocation biomeID) { private static List<SurfaceRules.RuleSource> getRulesForBiome(ResourceLocation biomeID) {
Registry<AssignedSurfaceRule> registry = SurfaceRuleRegistry.BUILTIN_SURFACE_RULES; Registry<AssignedSurfaceRule> registry = SurfaceRuleRegistry.BUILTIN_SURFACE_RULES;
if (WorldBootstrap.getLastRegistryAccess() != null) if (WorldBootstrap.getLastRegistryAccess() != null)
registry = WorldBootstrap.getLastRegistryAccess() registry = WorldBootstrap.getLastRegistryAccess()
@ -36,31 +31,30 @@ public class SurfaceRuleUtil {
} }
public static List<SurfaceRules.RuleSource> getRulesForBiomes(List<Biome> biomes) { private static List<SurfaceRules.RuleSource> getRulesForBiomes(List<Biome> biomes) {
Registry<Biome> biomeRegistry = WorldBootstrap.getLastRegistryAccess().registryOrThrow(Registry.BIOME_REGISTRY); Registry<Biome> biomeRegistry = WorldBootstrap.getLastRegistryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
List<ResourceLocation> biomeIDs = biomes.stream() List<ResourceLocation> biomeIDs = biomes.stream()
.map(b -> biomeRegistry.getKey(b)) .map(b -> biomeRegistry.getKey(b))
.filter(id -> id != null) .filter(id -> id != null)
.toList(); .toList();
return biomeIDs.stream().map(biomeID -> getRulesForBiome(biomeID)).flatMap(List::stream).toList(); return biomeIDs.stream()
.map(biomeID -> getRulesForBiome(biomeID))
.flatMap(List::stream)
.collect(Collectors.toCollection(LinkedList::new));
} }
public static SurfaceRules.RuleSource mergeSurfaceRulesFromBiomes( private static SurfaceRules.RuleSource mergeSurfaceRulesFromBiomes(
SurfaceRules.RuleSource org, SurfaceRules.RuleSource org,
BiomeSource source BiomeSource source
) { ) {
return mergeSurfaceRules(org, getRulesForBiomes(source.possibleBiomes().stream().map(h -> h.value()).toList())); return mergeSurfaceRules(
org,
getRulesForBiomes(source.possibleBiomes().stream().map(h -> h.value()).toList())
);
} }
public static SurfaceRules.RuleSource mergeSurfaceRulesFromBiomes( private static SurfaceRules.RuleSource mergeSurfaceRules(
SurfaceRules.RuleSource org,
List<Biome> biomes
) {
return mergeSurfaceRules(org, getRulesForBiomes(biomes));
}
public static SurfaceRules.RuleSource mergeSurfaceRules(
SurfaceRules.RuleSource org, SurfaceRules.RuleSource org,
List<SurfaceRules.RuleSource> additionalRules List<SurfaceRules.RuleSource> additionalRules
) { ) {
@ -82,20 +76,6 @@ public class SurfaceRuleUtil {
return new SurfaceRules.SequenceRuleSource(additionalRules); return new SurfaceRules.SequenceRuleSource(additionalRules);
} }
public static void injectSurfaceRules(
ResourceKey<LevelStem> dimensionKey,
ChunkGenerator loadedChunkGenerator
) {
WorldsTogether.LOGGER.debug("Checking Surface Rules for " + dimensionKey.location().toString());
final BiomeSource loadedBiomeSource = loadedChunkGenerator.getBiomeSource();
InternalBiomeAPI.applyModifications(loadedBiomeSource, dimensionKey);
if (loadedChunkGenerator instanceof NoiseBasedChunkGenerator nbc) {
injectSurfaceRules(nbc.generatorSettings().value(), loadedBiomeSource);
}
}
public static void injectSurfaceRules(NoiseGeneratorSettings noiseSettings, BiomeSource loadedBiomeSource) { public static void injectSurfaceRules(NoiseGeneratorSettings noiseSettings, BiomeSource loadedBiomeSource) {
if (((Object) noiseSettings) instanceof SurfaceRuleProvider srp) { if (((Object) noiseSettings) instanceof SurfaceRuleProvider srp) {
SurfaceRules.RuleSource originalRules = noiseSettings.surfaceRule(); SurfaceRules.RuleSource originalRules = noiseSettings.surfaceRule();
@ -103,19 +83,13 @@ public class SurfaceRuleUtil {
} }
} }
public static void injectSurfaceRules(WorldGenSettings settings, Predicate<ResourceKey<LevelStem>> filter) { public static void injectSurfaceRulesToAllDimensions(WorldGenSettings settings) {
List<ResourceKey<LevelStem>> otherDimensions = settings for (var entry : settings.dimensions().entrySet()) {
.dimensions() ResourceKey<LevelStem> key = entry.getKey();
.entrySet() LevelStem stem = entry.getValue();
.stream()
.map(e -> e.getKey())
.filter(filter)
.toList();
for (ResourceKey<LevelStem> key : otherDimensions) { if (stem.generator() instanceof InjectableSurfaceRules<?> generator) {
Optional<Holder<LevelStem>> stem = settings.dimensions().getHolder(key); generator.injectSurfaceRules(key);
if (stem.isPresent()) {
injectSurfaceRules(key, stem.get().value().generator());
} }
} }
} }

View file

@ -2,9 +2,10 @@ package org.betterx.worlds.together.world.event;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.WorldsTogether;
import org.betterx.worlds.together.levelgen.WorldGenUtil;
import org.betterx.worlds.together.mixin.common.RegistryOpsAccessor; import org.betterx.worlds.together.mixin.common.RegistryOpsAccessor;
import org.betterx.worlds.together.mixin.common.WorldPresetAccessor;
import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.world.WorldConfig;
import org.betterx.worlds.together.world.WorldGenUtil;
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
import org.betterx.worlds.together.worldPreset.WorldGenSettingsComponentAccessor; import org.betterx.worlds.together.worldPreset.WorldGenSettingsComponentAccessor;
import org.betterx.worlds.together.worldPreset.WorldPresets; import org.betterx.worlds.together.worldPreset.WorldPresets;
@ -36,15 +37,15 @@ public class WorldBootstrap {
} }
public static class Helpers { public static class Helpers {
private static void initializeWorldDataAPI( private static void initializeWorldConfig(
LevelStorageSource.LevelStorageAccess levelStorageAccess, LevelStorageSource.LevelStorageAccess levelStorageAccess,
boolean newWorld boolean newWorld
) { ) {
File levelPath = levelStorageAccess.getLevelPath(LevelResource.ROOT).toFile(); File levelPath = levelStorageAccess.getLevelPath(LevelResource.ROOT).toFile();
initializeWorldDataAPI(levelPath, newWorld); initializeWorldConfig(levelPath, newWorld);
} }
private static void initializeWorldDataAPI(File levelBaseDir, boolean newWorld) { private static void initializeWorldConfig(File levelBaseDir, boolean newWorld) {
WorldConfig.load(new File(levelBaseDir, "data")); WorldConfig.load(new File(levelBaseDir, "data"));
if (newWorld) { if (newWorld) {
@ -105,12 +106,12 @@ public class WorldBootstrap {
BCLib.LOGGER.info("Creating a new World, no fixes needed"); BCLib.LOGGER.info("Creating a new World, no fixes needed");
final WorldPresetSettings settings = Helpers.defaultServerSettings(); final WorldPresetSettings settings = Helpers.defaultServerSettings();
Helpers.initializeWorldDataAPI(levelStorageAccess, true); Helpers.initializeWorldConfig(levelStorageAccess, true);
WorldEventsImpl.BEFORE_SERVER_WORLD_LOAD.emit(e -> e.prepareWorld( WorldEventsImpl.BEFORE_SERVER_WORLD_LOAD.emit(e -> e.prepareWorld(
levelStorageAccess, settings, true levelStorageAccess, settings, true
)); ));
} else { } else {
Helpers.initializeWorldDataAPI(levelStorageAccess, false); Helpers.initializeWorldConfig(levelStorageAccess, false);
WorldEventsImpl.BEFORE_SERVER_WORLD_LOAD.emit(e -> e.prepareWorld( WorldEventsImpl.BEFORE_SERVER_WORLD_LOAD.emit(e -> e.prepareWorld(
levelStorageAccess, levelStorageAccess,
WorldGenUtil.getWorldSettings(), WorldGenUtil.getWorldSettings(),
@ -130,6 +131,12 @@ public class WorldBootstrap {
settings = t.settings; settings = t.settings;
} }
TogetherWorldPreset.writeWorldPresetSettings(settings); TogetherWorldPreset.writeWorldPresetSettings(settings);
if (currentPreset.map(h -> h.value()).orElse(null) instanceof WorldPresetAccessor acc) {
TogetherWorldPreset.writeWorldPresetSettings(acc.bcl_getDimensions());
} else {
WorldsTogether.LOGGER.error("Failed writing together File");
//TogetherWorldPreset.writeWorldPresetSettings(worldGenSettings);
}
WorldEventsImpl.ON_WORLD_LOAD.emit(OnWorldLoad::onLoad); WorldEventsImpl.ON_WORLD_LOAD.emit(OnWorldLoad::onLoad);
} }
} }
@ -173,9 +180,9 @@ public class WorldBootstrap {
static Optional<Holder<WorldPreset>> setupNewWorldCommon( static Optional<Holder<WorldPreset>> setupNewWorldCommon(
LevelStorageSource.LevelStorageAccess levelStorageAccess, LevelStorageSource.LevelStorageAccess levelStorageAccess,
Optional<Holder<WorldPreset>> currentPreset, Optional<Holder<WorldPreset>> currentPreset,
WorldGenSettings worldgenSettings WorldGenSettings worldGenSettings
) { ) {
Helpers.initializeWorldDataAPI(levelStorageAccess, true); Helpers.initializeWorldConfig(levelStorageAccess, true);
final WorldPresetSettings settings; final WorldPresetSettings settings;
@ -193,9 +200,15 @@ public class WorldBootstrap {
true true
)); ));
currentPreset = WorldEventsImpl.ADAPT_WORLD_PRESET.emit(currentPreset, worldgenSettings); currentPreset = WorldEventsImpl.ADAPT_WORLD_PRESET.emit(currentPreset, worldGenSettings);
TogetherWorldPreset.writeWorldPresetSettings(currentPreset); TogetherWorldPreset.writeWorldPresetSettings(currentPreset);
if (currentPreset.map(h -> h.value()).orElse(null) instanceof WorldPresetAccessor acc) {
TogetherWorldPreset.writeWorldPresetSettings(acc.bcl_getDimensions());
} else {
WorldsTogether.LOGGER.error("Failed writing together File");
//TogetherWorldPreset.writeWorldPresetSettings(worldGenSettings);
}
//LifeCycleAPI._runBeforeLevelLoad(); //LifeCycleAPI._runBeforeLevelLoad();
WorldEventsImpl.ON_WORLD_LOAD.emit(OnWorldLoad::onLoad); WorldEventsImpl.ON_WORLD_LOAD.emit(OnWorldLoad::onLoad);
@ -212,7 +225,7 @@ public class WorldBootstrap {
) { ) {
try { try {
var levelStorageAccess = levelSource.createAccess(levelID); var levelStorageAccess = levelSource.createAccess(levelID);
Helpers.initializeWorldDataAPI(levelStorageAccess, false); Helpers.initializeWorldConfig(levelStorageAccess, false);
//Helpers.setupWorld(); //Helpers.setupWorld();
WorldEventsImpl.BEFORE_WORLD_LOAD.emit(e -> e.prepareWorld( WorldEventsImpl.BEFORE_WORLD_LOAD.emit(e -> e.prepareWorld(
@ -270,10 +283,7 @@ public class WorldBootstrap {
} }
public static WorldGenSettings enforceInNewWorld(WorldGenSettings worldGenSettings) { public static WorldGenSettings enforceInNewWorld(WorldGenSettings worldGenSettings) {
worldGenSettings = WorldGenUtil return WorldGenUtil.repairBiomeSourceInAllDimensions(LAST_REGISTRY_ACCESS, worldGenSettings);
.getWorldSettings()
.repairSettingsOnLoad(LAST_REGISTRY_ACCESS, worldGenSettings);
return worldGenSettings;
} }
public static WorldGenSettings enforceInLoadedWorld( public static WorldGenSettings enforceInLoadedWorld(
@ -281,9 +291,7 @@ public class WorldBootstrap {
WorldGenSettings worldGenSettings WorldGenSettings worldGenSettings
) { ) {
if (registryOps.orElse(null) instanceof RegistryOpsAccessor acc) { if (registryOps.orElse(null) instanceof RegistryOpsAccessor acc) {
return WorldGenUtil return WorldGenUtil.repairBiomeSourceInAllDimensions(acc.bcl_getRegistryAccess(), worldGenSettings);
.getWorldSettings()
.repairSettingsOnLoad(acc.bcl_getRegistryAccess(), worldGenSettings);
//.repairSettingsOnLoad(LAST_REGISTRY_ACCESS, worldGenSettings); //.repairSettingsOnLoad(LAST_REGISTRY_ACCESS, worldGenSettings);
} else { } else {
BCLib.LOGGER.error("Unable to obtain registryAccess when enforcing generators."); BCLib.LOGGER.error("Unable to obtain registryAccess when enforcing generators.");

View file

@ -1,24 +1,32 @@
package org.betterx.worlds.together.worldPreset; package org.betterx.worlds.together.worldPreset;
import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.WorldsTogether;
import org.betterx.worlds.together.levelgen.WorldGenUtil;
import org.betterx.worlds.together.mixin.common.WorldPresetAccessor; import org.betterx.worlds.together.mixin.common.WorldPresetAccessor;
import org.betterx.worlds.together.world.WorldConfig; import org.betterx.worlds.together.world.WorldConfig;
import org.betterx.worlds.together.world.WorldGenUtil; import org.betterx.worlds.together.world.event.WorldBootstrap;
import org.betterx.worlds.together.worldPreset.settings.VanillaWorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.VanillaWorldPresetSettings;
import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings;
import net.minecraft.core.Holder; import com.mojang.serialization.Codec;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.data.BuiltinRegistries; import net.minecraft.data.BuiltinRegistries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.resources.RegistryOps; import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.presets.WorldPreset; import net.minecraft.world.level.levelgen.presets.WorldPreset;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.jetbrains.annotations.NotNull;
public class TogetherWorldPreset extends WorldPreset { public class TogetherWorldPreset extends WorldPreset {
public final WorldPresetSettings settings; public final WorldPresetSettings settings;
@ -54,20 +62,17 @@ public class TogetherWorldPreset extends WorldPreset {
return ((WorldPresetAccessor) this).bcl_getDimensions(); return ((WorldPresetAccessor) this).bcl_getDimensions();
} }
public static WorldPresetSettings writeWorldPresetSettings(Optional<Holder<WorldPreset>> worldPreset) { public LevelStem getDimension(ResourceKey<LevelStem> key) {
if (worldPreset.isPresent() && worldPreset.get().value() instanceof TogetherWorldPreset wp) { return getDimensions().get(key);
writeWorldPresetSettings(wp.settings);
return wp.settings;
} else {
writeWorldPresetSettings(VanillaWorldPresetSettings.DEFAULT);
return VanillaWorldPresetSettings.DEFAULT;
}
} }
public static void writeWorldPresetSettings(WorldPresetSettings presetSettings) { public static void writeWorldPresetSettings(Map<ResourceKey<LevelStem>, LevelStem> settings) {
final RegistryOps<Tag> registryOps = RegistryOps.create(NbtOps.INSTANCE, BuiltinRegistries.ACCESS); final RegistryOps<Tag> registryOps = RegistryOps.create(
final var codec = WorldPresetSettings.CODEC.orElse(presetSettings); NbtOps.INSTANCE,
final var encodeResult = codec.encodeStart(registryOps, presetSettings); WorldBootstrap.getLastRegistryAccess()
);
DimensionsWrapper wrapper = new DimensionsWrapper(DimensionsWrapper.build(settings));
final var encodeResult = wrapper.CODEC.encodeStart(registryOps, wrapper);
if (encodeResult.result().isPresent()) { if (encodeResult.result().isPresent()) {
final CompoundTag settingsNbt = WorldConfig.getRootTag(WorldsTogether.MOD_ID); final CompoundTag settingsNbt = WorldConfig.getRootTag(WorldsTogether.MOD_ID);
@ -78,4 +83,75 @@ public class TogetherWorldPreset extends WorldPreset {
WorldConfig.saveFile(WorldsTogether.MOD_ID); WorldConfig.saveFile(WorldsTogether.MOD_ID);
} }
private static DimensionsWrapper DEFAULT_DIMENSIONS_WRAPPER = null;
public static @NotNull Map<ResourceKey<LevelStem>, ChunkGenerator> getWorldDimensions() {
if (BuiltinRegistries.ACCESS == null) return null;
final RegistryAccess registryAccess;
if (WorldBootstrap.getLastRegistryAccess() != null) {
registryAccess = WorldBootstrap.getLastRegistryAccess();
} else {
registryAccess = BuiltinRegistries.ACCESS;
}
final RegistryOps<Tag> registryOps = RegistryOps.create(NbtOps.INSTANCE, registryAccess);
Optional<DimensionsWrapper> oLevelStem = DimensionsWrapper.CODEC
.parse(new Dynamic<>(registryOps, WorldGenUtil.getSettingsNbt()))
.resultOrPartial(WorldsTogether.LOGGER::error);
if (DEFAULT_DIMENSIONS_WRAPPER == null) {
DEFAULT_DIMENSIONS_WRAPPER = new DimensionsWrapper(WorldPresets
.get(
registryAccess,
WorldPresets.DEFAULT.orElseThrow()
)
.value()
.createWorldGenSettings(0, true, true)
.dimensions());
}
return oLevelStem.orElse(DEFAULT_DIMENSIONS_WRAPPER).dimensions;
}
private static class DimensionsWrapper {
public static final Codec<DimensionsWrapper> CODEC = RecordCodecBuilder.create(instance -> instance
.group(Codec.unboundedMap(
ResourceKey.codec(Registry.LEVEL_STEM_REGISTRY),
ChunkGenerator.CODEC
)
.fieldOf("dimensions")
.orElse(new HashMap<>())
.forGetter(o -> o.dimensions))
.apply(instance, DimensionsWrapper::new));
final Map<ResourceKey<LevelStem>, ChunkGenerator> dimensions;
static Map<ResourceKey<LevelStem>, ChunkGenerator> build(Registry<LevelStem> dimensions) {
Map<ResourceKey<LevelStem>, ChunkGenerator> map = new HashMap<>();
for (var entry : dimensions.entrySet()) {
ResourceKey<LevelStem> key = entry.getKey();
LevelStem stem = entry.getValue();
map.put(key, stem.generator());
}
return map;
}
static Map<ResourceKey<LevelStem>, ChunkGenerator> build(Map<ResourceKey<LevelStem>, LevelStem> input) {
Map<ResourceKey<LevelStem>, ChunkGenerator> map = new HashMap<>();
for (var entry : input.entrySet()) {
ResourceKey<LevelStem> key = entry.getKey();
LevelStem stem = entry.getValue();
map.put(key, stem.generator());
}
return map;
}
DimensionsWrapper(Registry<LevelStem> dimensions) {
this(build(dimensions));
}
private DimensionsWrapper(Map<ResourceKey<LevelStem>, ChunkGenerator> dimensions) {
this.dimensions = dimensions;
}
}
} }

View file

@ -4,7 +4,7 @@ import org.betterx.bclib.registry.PresetsRegistry;
import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.WorldsTogether;
import org.betterx.worlds.together.tag.v3.TagManager; import org.betterx.worlds.together.tag.v3.TagManager;
import org.betterx.worlds.together.tag.v3.TagRegistry; import org.betterx.worlds.together.tag.v3.TagRegistry;
import org.betterx.worlds.together.world.WorldGenUtil; import org.betterx.worlds.together.levelgen.WorldGenUtil;
import org.betterx.worlds.together.worldPreset.client.WorldPresetsClient; import org.betterx.worlds.together.worldPreset.client.WorldPresetsClient;
import org.betterx.worlds.together.worldPreset.settings.VanillaWorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.VanillaWorldPresetSettings;
import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings; import org.betterx.worlds.together.worldPreset.settings.WorldPresetSettings;

View file

@ -1,8 +1,5 @@
package org.betterx.worlds.together.worldPreset.settings; package org.betterx.worlds.together.worldPreset.settings;
import org.betterx.worlds.together.surfaceRules.SurfaceRuleRegistry;
import org.betterx.worlds.together.surfaceRules.SurfaceRuleUtil;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
@ -30,9 +27,4 @@ public class VanillaWorldPresetSettings extends WorldPresetSettings {
public BiomeSource addDatapackBiomes(BiomeSource biomeSource, Set<Holder<Biome>> datapackBiomes) { public BiomeSource addDatapackBiomes(BiomeSource biomeSource, Set<Holder<Biome>> datapackBiomes) {
return biomeSource; return biomeSource;
} }
public void injectSurfaceRules(RegistryAccess registryAccess, WorldGenSettings settings) {
SurfaceRuleUtil.injectSurfaceRules(settings, SurfaceRuleRegistry.ALL_DIMENSIONS);
}
} }

View file

@ -52,5 +52,5 @@ public abstract class WorldPresetSettings {
public abstract Codec<? extends WorldPresetSettings> codec(); public abstract Codec<? extends WorldPresetSettings> codec();
public abstract WorldGenSettings repairSettingsOnLoad(RegistryAccess registryAccess, WorldGenSettings settings); public abstract WorldGenSettings repairSettingsOnLoad(RegistryAccess registryAccess, WorldGenSettings settings);
public abstract BiomeSource addDatapackBiomes(BiomeSource biomeSource, Set<Holder<Biome>> datapackBiomes); public abstract BiomeSource addDatapackBiomes(BiomeSource biomeSource, Set<Holder<Biome>> datapackBiomes);
public abstract void injectSurfaceRules(RegistryAccess registryAccess, WorldGenSettings settings);
} }

View file

@ -23,7 +23,6 @@
"LayerLightSectionStorageMixin", "LayerLightSectionStorageMixin",
"LootPoolMixin", "LootPoolMixin",
"MinecraftServerMixin", "MinecraftServerMixin",
"MinecraftServerMixinLate",
"MobSpawnSettingsAccessor", "MobSpawnSettingsAccessor",
"NoiseBasedChunkGeneratorMixin", "NoiseBasedChunkGeneratorMixin",
"PistonBaseBlockMixin", "PistonBaseBlockMixin",

View file

@ -8,6 +8,8 @@
"DiggerItemAccessor", "DiggerItemAccessor",
"MainMixin", "MainMixin",
"MinecraftServerMixin", "MinecraftServerMixin",
"MinecraftServerMixinLate",
"NoiseBasedChunkGeneratorMixin",
"NoiseGeneratorSettingsMixin", "NoiseGeneratorSettingsMixin",
"PrimaryLevelDataMixin", "PrimaryLevelDataMixin",
"RegistryAccessMixin", "RegistryAccessMixin",