SurfaceRule handling

This commit is contained in:
Frank 2022-05-25 14:00:24 +02:00
parent 7a891d71ee
commit 919e3c25c5
15 changed files with 147 additions and 96 deletions

View file

@ -128,7 +128,6 @@ public class BiomeAPI {
private static final Map<ResourceKey, List<BiConsumer<ResourceLocation, Holder<Biome>>>> MODIFICATIONS = Maps.newHashMap();
private static final Map<ResourceKey, List<BiConsumer<ResourceLocation, Holder<Biome>>>> TAG_ADDERS = Maps.newHashMap();
private static final Map<ResourceLocation, SurfaceRules.RuleSource> SURFACE_RULES = Maps.newHashMap();
private static final Set<SurfaceRuleProvider> MODIFIED_SURFACE_PROVIDERS = new HashSet<>(8);
public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES).value());
@ -728,45 +727,7 @@ public class BiomeAPI {
}
accessor.bclib_setFeatures(featureList);
}
private static List<SurfaceRules.RuleSource> getRuleSourcesForBiomes(Set<Holder<Biome>> biomes) {
Set<ResourceLocation> biomeIDs = biomes
.stream()
.map(biome -> 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 #applyModifications(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<SurfaceRules.RuleSource> getRuleSources(Set<BiomeSource> sources) {
final Set<Holder<Biome>> biomes = new HashSet<>();
for (BiomeSource s : sources) {
biomes.addAll(s.possibleBiomes());
}
return getRuleSourcesForBiomes(biomes);
}
private static List<SurfaceRules.RuleSource> getRuleSourcesFromIDs(Set<ResourceLocation> biomeIDs) {
List<SurfaceRules.RuleSource> rules = Lists.newArrayList();
SURFACE_RULES.forEach((biomeID, rule) -> {
if (biomeIDs.contains(biomeID)) {
rules.add(rule);
}
});
return rules;
}
/**
* Adds new features to existing biome.
*
@ -827,20 +788,8 @@ public class BiomeAPI {
accessor.bclib_setFeatureSet(featureSet);
accessor.bclib_setFlowerFeatures(flowerFeatures);
}
/**
* Adds surface rule to specified biome.
*
* @param biomeID biome {@link ResourceLocation}.
* @param source {@link SurfaceRules.RuleSource}.
*/
public static void addSurfaceRule(ResourceLocation biomeID, SurfaceRules.RuleSource source) {
SURFACE_RULES.put(biomeID, source);
//NOISE_GENERATOR_SETTINGS.forEach(BiomeAPI::changeSurfaceRulesForGenerator);
}
/**
* Adds mob spawning to specified biome.
*

View file

@ -24,7 +24,7 @@ import org.betterx.bclib.gui.screens.ConfirmFixScreen;
import org.betterx.bclib.gui.screens.LevelFixErrorScreen;
import org.betterx.bclib.gui.screens.LevelFixErrorScreen.Listener;
import org.betterx.bclib.gui.screens.ProgressScreen;
import org.betterx.bclib.presets.worldgen.WorldGenUtilities;
import org.betterx.bclib.api.worldgen.WorldGenUtil;
import org.betterx.bclib.util.Logger;
import java.io.*;
@ -181,7 +181,7 @@ public class DataFixerAPI {
public static void createWorldData(LevelStorageAccess access, WorldGenSettings settings) {
initializeWorldData(access, true);
WorldGenUtilities.initializeWorldData(settings);
WorldGenUtil.initializeWorldData(settings);
WorldDataAPI.saveFile(BCLib.MOD_ID);
}

View file

@ -0,0 +1,67 @@
package org.betterx.bclib.api.worldgen;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.resources.RegistryOps;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.structure.StructureSet;
import net.minecraft.world.level.levelgen.synth.NormalNoise;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import org.betterx.bclib.interfaces.NoiseGeneratorSettingsProvider;
public class BCLChunkGenerator extends NoiseBasedChunkGenerator {
public static final Codec<BCLChunkGenerator> CODEC = RecordCodecBuilder
.create((RecordCodecBuilder.Instance<BCLChunkGenerator> builderInstance) -> {
final RecordCodecBuilder<BCLChunkGenerator, Registry<NormalNoise.NoiseParameters>> noiseGetter = RegistryOps
.retrieveRegistry(
Registry.NOISE_REGISTRY)
.forGetter(
BCLChunkGenerator::getNoises);
RecordCodecBuilder<BCLChunkGenerator, BiomeSource> biomeSourceCodec = BiomeSource.CODEC
.fieldOf("biome_source")
.forGetter((BCLChunkGenerator generator) -> generator.biomeSource);
RecordCodecBuilder<BCLChunkGenerator, Holder<NoiseGeneratorSettings>> settingsCodec = NoiseGeneratorSettings.CODEC
.fieldOf("settings")
.forGetter((BCLChunkGenerator generator) -> generator.settings);
return NoiseBasedChunkGenerator
.commonCodec(builderInstance)
.and(builderInstance.group(noiseGetter, biomeSourceCodec, settingsCodec))
.apply(builderInstance, builderInstance.stable(BCLChunkGenerator::new));
});
public BCLChunkGenerator(Registry<StructureSet> registry,
Registry<NormalNoise.NoiseParameters> registry2,
BiomeSource biomeSource,
Holder<NoiseGeneratorSettings> holder) {
super(registry, registry2, biomeSource, holder);
System.out.println("Chunk Generator: " + this);
}
@Override
protected Codec<? extends ChunkGenerator> codec() {
return CODEC;
}
private Registry<NormalNoise.NoiseParameters> getNoises() {
if (this instanceof NoiseGeneratorSettingsProvider p) {
return p.bclib_getNoises();
}
return null;
}
@Override
public String toString() {
return "BCLib - Chunk Generator (" + Integer.toHexString(hashCode()) + ")";
}
}

View file

@ -0,0 +1,77 @@
package org.betterx.bclib.api.worldgen;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
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;
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
import org.betterx.bclib.api.biomes.BiomeAPI;
import org.betterx.bclib.mixin.common.NoiseGeneratorSettingsMixin;
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 #applyModifications(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);
//NOISE_GENERATOR_SETTINGS.forEach(BiomeAPI::changeSurfaceRulesForGenerator);
}
}

View file

@ -0,0 +1,403 @@
package org.betterx.bclib.api.worldgen;
import net.minecraft.core.Holder;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.biome.Biome;
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.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.SurfaceRules;
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.presets.WorldPreset;
import net.minecraft.world.level.levelgen.structure.StructureSet;
import net.minecraft.world.level.levelgen.synth.NormalNoise;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.Lifecycle;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.WorldDataAPI;
import org.betterx.bclib.mixin.common.RegistryOpsAccessor;
import org.betterx.bclib.presets.worldgen.BCLWorldPresetSettings;
import org.betterx.bclib.presets.worldgen.BCLWorldPresets;
import org.betterx.bclib.presets.worldgen.WorldPresetSettings;
import org.betterx.bclib.util.ModUtil;
import org.betterx.bclib.world.generator.BCLBiomeSource;
import org.betterx.bclib.world.generator.BCLibEndBiomeSource;
import org.betterx.bclib.world.generator.BCLibNetherBiomeSource;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
public class WorldGenUtil {
private static final String TAG_VERSION = "version";
private static final String TAG_BN_GEN_VERSION = "generator_version";
private static String TAG_GENERATOR = "generator";
@NotNull
public static LevelStem getBCLNetherLevelStem(Context context, Optional<Integer> version) {
BCLibNetherBiomeSource netherSource = new BCLibNetherBiomeSource(context.biomes, version);
return getBCLNetherLevelStem(context, netherSource);
}
public static LevelStem getBCLNetherLevelStem(StemContext context, BiomeSource biomeSource) {
return new LevelStem(
context.dimension,
new BCLChunkGenerator(
context.structureSets,
context.noiseParameters,
biomeSource,
context.generatorSettings)
);
}
@NotNull
public static LevelStem getBCLEndLevelStem(StemContext context, BiomeSource biomeSource) {
return new LevelStem(
context.dimension,
new BCLChunkGenerator(
context.structureSets,
context.noiseParameters,
biomeSource,
context.generatorSettings)
);
}
public static LevelStem getBCLEndLevelStem(Context context, Optional<Integer> version) {
BCLibEndBiomeSource endSource = new BCLibEndBiomeSource(context.biomes, version);
return getBCLEndLevelStem(context, endSource);
}
/**
* Datapacks can change the world's generator. This Method will ensure, that the Generators contain
* the correct BiomeSources for this world
*
* @param settings
* @return
*/
public static WorldGenSettings fixSettingsInCurrentWorld(Optional<RegistryOps<Tag>> registryOps,
WorldGenSettings settings) {
if (registryOps.orElse(null) instanceof RegistryOpsAccessor acc) {
return getWorldSettings().repairSettingsOnLoad(acc.bcl_getRegistryAccess(), settings);
} else {
BCLib.LOGGER.error("Unable to obtain registryAccess when enforcing generators.");
}
return settings;
}
public static WorldGenSettings createWorldFromPreset(ResourceKey<WorldPreset> preset,
RegistryAccess registryAccess,
long seed,
boolean generateStructures,
boolean generateBonusChest) {
WorldGenSettings settings = registryAccess
.registryOrThrow(Registry.WORLD_PRESET_REGISTRY)
.getHolderOrThrow(preset)
.value()
.createWorldGenSettings(seed, generateStructures, generateBonusChest);
for (LevelStem stem : settings.dimensions()) {
if (stem.generator().getBiomeSource() instanceof BCLBiomeSource bcl) {
bcl.setSeed(seed);
}
}
return settings;
}
public static WorldGenSettings createDefaultWorldFromPreset(RegistryAccess registryAccess,
long seed,
boolean generateStructures,
boolean generateBonusChest) {
return createWorldFromPreset(BCLWorldPresets.DEFAULT.orElseThrow(),
registryAccess,
seed,
generateStructures,
generateBonusChest);
}
public static Pair<WorldGenSettings, RegistryAccess.Frozen> defaultWorldDataSupplier(RegistryAccess.Frozen frozen) {
WorldGenSettings worldGenSettings = createDefaultWorldFromPreset(frozen);
return Pair.of(worldGenSettings, frozen);
}
public static WorldGenSettings createDefaultWorldFromPreset(RegistryAccess registryAccess, long seed) {
return createDefaultWorldFromPreset(registryAccess, seed, true, false);
}
public static WorldGenSettings createDefaultWorldFromPreset(RegistryAccess registryAccess) {
return createDefaultWorldFromPreset(registryAccess, RandomSource.create().nextLong());
}
public static WorldGenSettings replaceGenerator(
ResourceKey<LevelStem> dimensionKey,
ResourceKey<DimensionType> dimensionTypeKey,
int biomeSourceVersion,
RegistryAccess registryAccess,
WorldGenSettings worldGenSettings
) {
Optional<Holder<LevelStem>> oLevelStem = referenceStemForVersion(
dimensionKey,
biomeSourceVersion,
registryAccess,
worldGenSettings.seed(),
worldGenSettings.generateStructures(),
worldGenSettings.generateStructures()
);
return replaceGenerator(dimensionKey,
dimensionTypeKey,
registryAccess,
worldGenSettings,
oLevelStem.map(l -> l.value().generator()).orElseThrow());
}
public static WorldGenSettings replaceGenerator(
ResourceKey<LevelStem> dimensionKey,
ResourceKey<DimensionType> dimensionTypeKey,
RegistryAccess registryAccess,
WorldGenSettings worldGenSettings,
ChunkGenerator generator
) {
Registry<DimensionType> dimensionTypeRegistry = registryAccess.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY);
Registry<LevelStem> newDimensions = withDimension(dimensionKey,
dimensionTypeKey,
dimensionTypeRegistry,
worldGenSettings.dimensions(),
generator);
return new WorldGenSettings(worldGenSettings.seed(),
worldGenSettings.generateStructures(),
worldGenSettings.generateBonusChest(),
newDimensions);
}
public static WorldGenSettings replaceStem(
ResourceKey<LevelStem> dimensionKey,
WorldGenSettings worldGenSettings,
LevelStem levelStem
) {
Registry<LevelStem> newDimensions = withDimension(dimensionKey,
worldGenSettings.dimensions(),
levelStem);
return new WorldGenSettings(worldGenSettings.seed(),
worldGenSettings.generateStructures(),
worldGenSettings.generateBonusChest(),
newDimensions);
}
public static Registry<LevelStem> withDimension(ResourceKey<LevelStem> dimensionKey,
ResourceKey<DimensionType> dimensionTypeKey,
Registry<DimensionType> dimensionTypeRegistry,
Registry<LevelStem> inputDimensions,
ChunkGenerator generator) {
LevelStem levelStem = inputDimensions.get(dimensionKey);
Holder<DimensionType> dimensionType = levelStem == null
? dimensionTypeRegistry.getOrCreateHolderOrThrow(dimensionTypeKey)
: levelStem.typeHolder();
return withDimension(dimensionKey, inputDimensions, new LevelStem(dimensionType, generator));
}
public static Registry<LevelStem> withDimension(ResourceKey<LevelStem> dimensionKey,
Registry<LevelStem> inputDimensions,
LevelStem levelStem) {
MappedRegistry<LevelStem> writableRegistry = new MappedRegistry<>(Registry.LEVEL_STEM_REGISTRY,
Lifecycle.experimental(),
null);
writableRegistry.register(dimensionKey,
levelStem,
Lifecycle.stable());
for (Map.Entry<ResourceKey<LevelStem>, LevelStem> entry : inputDimensions.entrySet()) {
ResourceKey<LevelStem> resourceKey = entry.getKey();
if (resourceKey == dimensionKey) continue;
writableRegistry.register(resourceKey,
entry.getValue(),
inputDimensions.lifecycle(entry.getValue()));
}
return writableRegistry;
}
public static int getBiomeVersionForGenerator(ChunkGenerator generator) {
if (generator == null) return BCLBiomeSource.getVersionBiomeSource(null);
return BCLBiomeSource.getVersionBiomeSource(generator.getBiomeSource());
}
public static Optional<Holder<LevelStem>> referenceStemForVersion(
ResourceKey<LevelStem> dimensionKey,
int biomeSourceVersion,
RegistryAccess registryAccess,
long seed,
boolean generateStructures,
boolean generateBonusChest
) {
final WorldGenSettings referenceSettings;
if (biomeSourceVersion == BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA) {
referenceSettings = net.minecraft.world.level.levelgen.presets.WorldPresets.createNormalWorldFromPreset(
registryAccess,
seed,
generateStructures,
generateBonusChest);
} else if (biomeSourceVersion == BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE) {
referenceSettings = createWorldFromPreset(
BCLWorldPresets.BCL_WORLD_17,
registryAccess,
seed,
generateStructures,
generateBonusChest);
} else {
referenceSettings = createDefaultWorldFromPreset(
registryAccess,
seed,
generateStructures,
generateBonusChest);
}
return referenceSettings.dimensions().getHolder(dimensionKey);
}
public static int getBiomeVersionForCurrentWorld(ResourceKey<LevelStem> key) {
final CompoundTag settingsNbt = getSettingsNbt();
if (!settingsNbt.contains(key.location().toString())) return BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION;
return settingsNbt.getInt(key.location().toString());
}
private static int getDimensionVersion(WorldGenSettings settings,
ResourceKey<LevelStem> key) {
var dimension = settings.dimensions().getHolder(key);
if (dimension.isPresent()) {
return getBiomeVersionForGenerator(dimension.get().value().generator());
} else {
return getBiomeVersionForGenerator(null);
}
}
private static void writeDimensionVersion(WorldGenSettings settings,
CompoundTag generatorSettings,
ResourceKey<LevelStem> key) {
generatorSettings.putInt(key.location().toString(), getDimensionVersion(settings, key));
}
public static void initializeWorldData(WorldGenSettings settings) {
updateWorldData(getDimensionVersion(settings, LevelStem.NETHER), getDimensionVersion(settings, LevelStem.END));
}
public static void updateWorldData(int netherVersion, int endVersion) {
BCLWorldPresetSettings worldSettings = new BCLWorldPresetSettings(netherVersion, endVersion);
final RegistryAccess registryAccess = RegistryAccess.builtinCopy();
final RegistryOps<Tag> registryOps = RegistryOps.create(NbtOps.INSTANCE, registryAccess);
final var codec = WorldPresetSettings.CODEC.orElse(worldSettings);
final var encodeResult = codec.encodeStart(registryOps, worldSettings);
if (encodeResult.result().isPresent()) {
final CompoundTag settingsNbt = WorldDataAPI.getRootTag(BCLib.TOGETHER_WORLDS);
settingsNbt.put(TAG_GENERATOR, encodeResult.result().get());
} else {
BCLib.LOGGER.error("Unable to encode world generator settings generator for level.dat.");
}
WorldDataAPI.saveFile(BCLib.TOGETHER_WORLDS);
}
static CompoundTag getSettingsNbt() {
return WorldDataAPI.getCompoundTag(BCLib.TOGETHER_WORLDS, TAG_GENERATOR);
}
public static WorldPresetSettings getWorldSettings() {
final RegistryAccess registryAccess = RegistryAccess.builtinCopy();
final RegistryOps<Tag> registryOps = RegistryOps.create(NbtOps.INSTANCE, registryAccess);
Optional<WorldPresetSettings> oLevelStem = WorldPresetSettings.CODEC
.parse(new Dynamic<>(registryOps, getSettingsNbt()))
.resultOrPartial(BCLib.LOGGER::error);
return oLevelStem.orElse(BCLWorldPresetSettings.DEFAULT);
}
public static void migrateGeneratorSettings() {
final CompoundTag settingsNbt = getSettingsNbt();
if (settingsNbt.size() == 0) {
BCLib.LOGGER.info("Found World without generator Settings. Setting up data...");
int biomeSourceVersion = BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION;
final CompoundTag bclRoot = WorldDataAPI.getRootTag(BCLib.MOD_ID);
String bclVersion = "0.0.0";
if (bclRoot.contains(TAG_VERSION)) {
bclVersion = bclRoot.getString(TAG_VERSION);
}
boolean isPre18 = !ModUtil.isLargerOrEqualVersion(bclVersion, "1.0.0");
if (isPre18) {
BCLib.LOGGER.info("World was create pre 1.18!");
biomeSourceVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE;
}
if (WorldDataAPI.hasMod("betternether")) {
BCLib.LOGGER.info("Found Data from BetterNether, using for migration.");
final CompoundTag bnRoot = WorldDataAPI.getRootTag("betternether");
biomeSourceVersion = "1.17".equals(bnRoot.getString(TAG_BN_GEN_VERSION))
? BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE
: BCLBiomeSource.BIOME_SOURCE_VERSION_HEX;
}
BCLib.LOGGER.info("Set world to BiomeSource Version " + biomeSourceVersion);
updateWorldData(biomeSourceVersion, biomeSourceVersion);
}
}
public static class StemContext {
public final Holder<DimensionType> dimension;
public final Registry<StructureSet> structureSets;
public final Registry<NormalNoise.NoiseParameters> noiseParameters;
public final Holder<NoiseGeneratorSettings> generatorSettings;
public StemContext(Holder<DimensionType> dimension,
Registry<StructureSet> structureSets,
Registry<NormalNoise.NoiseParameters> noiseParameters,
Holder<NoiseGeneratorSettings> generatorSettings) {
this.dimension = dimension;
this.structureSets = structureSets;
this.noiseParameters = noiseParameters;
this.generatorSettings = generatorSettings;
}
}
public static class Context extends StemContext {
public final Registry<Biome> biomes;
public Context(Registry<Biome> biomes, Holder<DimensionType> dimension,
Registry<StructureSet> structureSets,
Registry<NormalNoise.NoiseParameters> noiseParameters,
Holder<NoiseGeneratorSettings> generatorSettings) {
super(dimension, structureSets, noiseParameters, generatorSettings);
this.biomes = biomes;
}
}
public static RuleSource addRulesForBiomeSource(RuleSource org, BiomeSource biomeSource) {
List<RuleSource> additionalRules = SurfaceRuleUtil.getRuleSources(biomeSource);
if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule) {
List<RuleSource> existingSequence = sequenceRule.sequence();
additionalRules = additionalRules.stream().filter(r -> existingSequence.indexOf(r) < 0).collect(Collectors.toList());
additionalRules.addAll(sequenceRule.sequence());
} else {
additionalRules.add(org);
}
return SurfaceRules.sequence(additionalRules.toArray(new RuleSource[additionalRules.size()]));
}
}