From baf1e0f4b1ade2873b8b58ffd50c48901c349ce6 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 26 Jan 2022 17:56:54 +0100 Subject: [PATCH] Cleanup and Speed Improvement of SurfaceRules/Structures (paulevsGitch/BetterNether#485, paulevsGitch/BetterEnd#420) --- src/main/java/ru/bclib/BCLib.java | 2 - .../java/ru/bclib/api/biomes/BiomeAPI.java | 271 +++++++----------- .../NoiseGeneratorSettingsProvider.java | 7 + .../bclib/interfaces/SurfaceRuleProvider.java | 5 +- .../ru/bclib/mixin/client/MinecraftMixin.java | 4 +- .../bclib/mixin/common/BiomeSourceMixin.java | 5 - .../mixin/common/MinecraftServerMixin.java | 1 - .../common/NoiseBasedChunkGeneratorMixin.java | 8 +- .../common/NoiseGeneratorSettingsMixin.java | 27 +- .../java/ru/bclib/world/biomes/BCLBiome.java | 3 +- 10 files changed, 144 insertions(+), 189 deletions(-) create mode 100644 src/main/java/ru/bclib/interfaces/NoiseGeneratorSettingsProvider.java diff --git a/src/main/java/ru/bclib/BCLib.java b/src/main/java/ru/bclib/BCLib.java index 7b1d4dd7..e356e7f7 100644 --- a/src/main/java/ru/bclib/BCLib.java +++ b/src/main/java/ru/bclib/BCLib.java @@ -48,8 +48,6 @@ public class BCLib implements ModInitializer { Chunker.DESCRIPTOR )); - BiomeAPI.registerStructureEvents(); - BCLibPatch.register(); Configs.save(); } diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index dedeed1a..1ddaeff4 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -1,12 +1,6 @@ package ru.bclib.api.biomes; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; +import com.google.common.collect.*; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback; @@ -28,11 +22,7 @@ import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeGenerationSettings; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Biomes; -import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.biome.*; import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -43,6 +33,7 @@ import net.minecraft.world.level.levelgen.GenerationStep.Carving; import net.minecraft.world.level.levelgen.GenerationStep.Decoration; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; +import net.minecraft.world.level.levelgen.StructureSettings; import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver; @@ -56,10 +47,7 @@ import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.Nullable; import ru.bclib.BCLib; import ru.bclib.entity.BCLEntityWrapper; -import ru.bclib.interfaces.BiomeSourceAccessor; -import ru.bclib.interfaces.SurfaceMaterialProvider; -import ru.bclib.interfaces.SurfaceProvider; -import ru.bclib.interfaces.SurfaceRuleProvider; +import ru.bclib.interfaces.*; import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor; import ru.bclib.mixin.common.BiomeSourceMixin; import ru.bclib.mixin.common.MobSpawnSettingsAccessor; @@ -73,16 +61,8 @@ import ru.bclib.world.features.BCLFeature; import ru.bclib.world.generator.BiomePicker; import ru.bclib.world.structures.BCLStructureFeature; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; -import java.util.Optional; -import java.util.Random; -import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -108,8 +88,8 @@ public class BiomeAPI { private final static Map, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>>> STRUCTURE_STARTS = new HashMap<>(); private static final Map>> MODIFICATIONS = Maps.newHashMap(); private static final Map SURFACE_RULES = Maps.newHashMap(); - private static final Set NOISE_GENERATOR_SETTINGS = new HashSet<>(); - + private static final Set MODIFIED_SURFACE_PROVIDERS = new HashSet<>(8); + public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES)); public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST)); public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST)); @@ -155,42 +135,18 @@ public class BiomeAPI { CLIENT.clear(); } } - - private static final Set worldSources = new HashSet<>(); - - /** - * For internal use only. - * - * Used by {@link BiomeSourceMixin} to add new BiomeSources to the BiomeAPI. We need to know all - * created Sources in order to rebuild their feature set whenever biomes get recreated - * through a datapack. - * @param source The new {@link BiomeSource} - */ - public static void registerBiomeSource(BiomeSource source){ - worldSources.add(source); - } - - private static WorldData worldData; - public static void registerWorldData(WorldData w){ - worldData = w; - if (worldData!=null){ - worldData.worldGenSettings().dimensions().forEach(dim->{ - StructureSettingsAccessor a = (StructureSettingsAccessor)dim.generator().getSettings(); - STRUCTURE_STARTS.entrySet().forEach(entry -> applyStructureStarts(a, entry.getValue())); - }); - } - } - + /** * For internal use only. * * This method gets called before a world is loaded/created to flush cashes we build. The Method is * called from {@link ru.bclib.mixin.client.MinecraftMixin} */ - public static void prepareWorldData(){ + public static void prepareNewLevel(){ STRUCTURE_STARTS.clear(); - worldSources.clear(); - NOISE_GENERATOR_SETTINGS.clear(); + + MODIFIED_SURFACE_PROVIDERS.forEach(p->p.bclib_clearBiomeSources()); + MODIFIED_SURFACE_PROVIDERS.clear(); } /** @@ -517,34 +473,60 @@ public class BiomeAPI { * @param level */ public static void applyModifications(ServerLevel level) { - BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource(); - Set biomes = source.possibleBiomes(); - - NoiseGeneratorSettings generator = null; - if (level.dimension() == Level.NETHER) { - generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.NETHER); + final BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource(); + final StructureSettings settings = level.getChunkSource().getGenerator().getSettings(); + final Set biomes = source.possibleBiomes(); + + NoiseGeneratorSettings generator = level + .getServer() + .getWorldData() + .worldGenSettings() + .dimensions() + .stream() + .filter(dim->dim.generator().getSettings()==settings) + .map(dim->((NoiseGeneratorSettingsProvider)dim.generator()).bclib_getNoiseGeneratorSettings()).findFirst().orElse(null);; + + // Datapacks (like Amplified Nether)will change the GeneratorSettings upon load, so we will + // only use the default Setting for Nether/End if we were unable to find a settings object + if (generator==null){ + if (level.dimension() == Level.NETHER) { + generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.NETHER); + } else if (level.dimension() == Level.END) { + generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.END); + } } - else if (level.dimension() == Level.END) { - generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.END); - } - - if (generator != null) { - List rules = getRuleSources(biomes); - SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator); - changeSurfaceRules(rules, provider); - } - + List> modifications = MODIFICATIONS.get(level.dimension()); if (modifications == null) { biomes.forEach(biome -> sortBiomeFeatures(biome)); - ((BiomeSourceAccessor) source).bclRebuildFeatures(); - return; + } else { + biomes.forEach(biome -> { + applyModificationsToBiome(modifications, biome); + }); } - biomes.forEach(biome -> { - applyModificationsToBiome(modifications, biome); - }); - + if (generator != null) { + final SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator); + // Multiple Biomes can use the same generator. So we need to keep track of all Biomes that are + // Provided by all the BiomeSources that use the same generator. + // This happens for example when using the MiningDimensions, which reuses the generator for the + // Nethering Dimension + MODIFIED_SURFACE_PROVIDERS.add(provider); + provider.bclib_addBiomeSource(source); + } else { + BCLib.LOGGER.warning("No generator for " + source); + } + + if (settings!=null){ + final StructureSettingsAccessor settingsAccessor = (StructureSettingsAccessor)settings; + final Set biomeIDs = biomes.stream().map(BiomeAPI::getBiomeID).collect(Collectors.toSet()); + for (Entry, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>>> e : STRUCTURE_STARTS.entrySet()) { + if (biomeIDs.contains(e.getKey().biomeID)) { + applyStructureStarts(settingsAccessor, e.getValue()); + } + } + } + ((BiomeSourceAccessor) source).bclRebuildFeatures(); } @@ -562,6 +544,10 @@ public class BiomeAPI { sortBiomeFeatures(biome); } + /** + * Create a unique sort order for all Features of the Biome + * @param biome The {@link Biome} to sort the features for + */ public static void sortBiomeFeatures(Biome biome) { BiomeGenerationSettings settings = biome.getGenerationSettings(); BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings; @@ -575,7 +561,7 @@ public class BiomeAPI { accessor.bclib_setFeatures(featureList); } - private static List getRuleSources(Set biomes) { + private static List getRuleSourcesForBiomes(Set biomes) { Set biomeIDs = biomes .stream() .map(biome -> getBiomeID(biome)) @@ -583,12 +569,23 @@ public class BiomeAPI { return getRuleSourcesFromIDs(biomeIDs); } - private static List getAllRuleSources() { - List rules = Lists.newArrayList(); - SURFACE_RULES.forEach((biomeID, rule) -> { - rules.add(rule); - }); - return rules; + /** + * 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 + * + * Note: This Method is used in the {@link ru.bclib.mixin.common.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 getRuleSources(Set sources) { + final Set biomes = new HashSet<>(); + for (BiomeSource s : sources) { + biomes.addAll(s.possibleBiomes()); + } + + return getRuleSourcesForBiomes(biomes); } private static List getRuleSourcesFromIDs(Set biomeIDs) { @@ -643,11 +640,12 @@ public class BiomeAPI { /** * For internal use only! * - * Adds new features to existing biome. Called from {@link BCLBiome#setFeatures(Map)} when the Biome is first built + * Adds new features to existing biome. Called from {@link #applyModificationsToBiome(List, Biome)} when the Biome is + * present in any {@link BiomeSource} * @param biome {@link Biome} to add features in. * @param featureMap Map of {@link ConfiguredFeature} to add. */ - public static void addStepFeaturesToBiome(Biome biome, Map>> featureMap) { + private static void addStepFeaturesToBiome(Biome biome, Map>> featureMap) { BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings(); List>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); Set set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet()); @@ -685,7 +683,12 @@ public class BiomeAPI { } }); } - + + /** + * Add an existing StructureFeature to a Biome + * @param biome The {@link Biome} you want to add teh feature to + * @param structure The {@link ConfiguredStructureFeature} to add + */ public static void addBiomeStructure(Biome biome, ConfiguredStructureFeature structure) { changeStructureStarts(BiomeAPI.getBiomeID(biome), structure, (structureMap, configMap) -> { Multimap, ResourceKey> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create()); @@ -744,7 +747,7 @@ public class BiomeAPI { */ public static void addSurfaceRule(ResourceLocation biomeID, SurfaceRules.RuleSource source) { SURFACE_RULES.put(biomeID, source); - NOISE_GENERATOR_SETTINGS.forEach(BiomeAPI::changeSurfaceRulesForGenerator); + //NOISE_GENERATOR_SETTINGS.forEach(BiomeAPI::changeSurfaceRulesForGenerator); } /** @@ -859,17 +862,17 @@ public class BiomeAPI { } static class StructureID { - public final ResourceLocation id; + public final ResourceLocation biomeID; public final ConfiguredStructureFeature structure; - StructureID(ResourceLocation id, ConfiguredStructureFeature structure){ - this.id = id; + StructureID(ResourceLocation biomeID, ConfiguredStructureFeature structure){ + this.biomeID = biomeID; this.structure = structure; } @Override public String toString() { - return "StructureID{" + "id=" + id + ", structure=" + structure + '}'; + return "StructureID{" + "id=" + biomeID + ", structure=" + structure + '}'; } @Override @@ -877,91 +880,19 @@ public class BiomeAPI { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; StructureID that = (StructureID) o; - return id.equals(that.id) && structure.equals(that.structure); + return biomeID.equals(that.biomeID) && structure.equals(that.structure); } @Override public int hashCode() { - return Objects.hash(id, structure); + return Objects.hash(biomeID, structure); } } - private static void registerNoiseGeneratorAndChangeSurfaceRules(NoiseGeneratorSettings settings){ - NOISE_GENERATOR_SETTINGS.add(settings); - changeSurfaceRulesForGenerator(settings); + private static void changeStructureStarts(ResourceLocation biomeID, ConfiguredStructureFeature structure, BiConsumer, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>> modifier) { + STRUCTURE_STARTS.put(new StructureID(biomeID, structure), modifier); } - - public static void registerStructureEvents(){ - DynamicRegistrySetupCallback.EVENT.register(registryManager -> { - Optional> oGeneratorRegistry = registryManager.registry(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY); -// Optional>> oBiomeSourceRegistry = registryManager.registry(Registry.BIOME_SOURCE_REGISTRY); -// -// if (oBiomeSourceRegistry.isPresent()) { -// RegistryEntryAddedCallback -// .event(oBiomeSourceRegistry.get()) -// .register((rawId, id, source) -> { -// BCLib.LOGGER.info(" #### " + rawId + ", " + source + ", " + id); -// }); -// } - - if (oGeneratorRegistry.isPresent()) { - oGeneratorRegistry.get().forEach(BiomeAPI::registerNoiseGeneratorAndChangeSurfaceRules); - RegistryEntryAddedCallback - .event(oGeneratorRegistry.get()) - .register((rawId, id, settings) -> { - //BCLib.LOGGER.info(" #### " + rawId + ", " + object + ", " + id); - - //add back modded structures - StructureSettingsAccessor a = (StructureSettingsAccessor)settings.structureSettings(); - STRUCTURE_STARTS.entrySet().forEach(entry -> applyStructureStarts(a, entry.getValue())); - - //add surface rules - registerNoiseGeneratorAndChangeSurfaceRules(settings); - }); - } - - - }); - } - - private static void changeSurfaceRulesForGenerator(NoiseGeneratorSettings settings){ - List rules; - if (biomeRegistry!=null) { - rules = getRuleSourcesFromIDs(biomeRegistry.keySet()); - } else { - rules = getAllRuleSources(); - } - SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(settings); - changeSurfaceRules(rules, provider); - } - - private static void changeSurfaceRules(List rules, SurfaceRuleProvider provider) { - if (rules.size() > 0) { - provider.addCustomRules(rules); - } - else { - provider.clearCustomRules(); - } - } - - private static void changeStructureStarts(ResourceLocation id, ConfiguredStructureFeature structure, BiConsumer, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>> modifier) { - STRUCTURE_STARTS.put(new StructureID(id, structure), modifier); - Registry chunkGenSettingsRegistry = BuiltinRegistries.NOISE_GENERATOR_SETTINGS; - - for (Map.Entry, NoiseGeneratorSettings> entry : chunkGenSettingsRegistry.entrySet()) { - final StructureSettingsAccessor access = (StructureSettingsAccessor) entry.getValue().structureSettings(); - applyStructureStarts(access, modifier); - } - - if (worldData!=null){ - worldData.worldGenSettings().dimensions().forEach(dim->{ - StructureSettingsAccessor access = (StructureSettingsAccessor)dim.generator().getSettings(); - applyStructureStarts(access, modifier); - }); - } - } - - + private static void applyStructureStarts(StructureSettingsAccessor access, BiConsumer, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>> modifier) { Map, Multimap, ResourceKey>> structureMap; Map, StructureFeatureConfiguration> configMap; diff --git a/src/main/java/ru/bclib/interfaces/NoiseGeneratorSettingsProvider.java b/src/main/java/ru/bclib/interfaces/NoiseGeneratorSettingsProvider.java new file mode 100644 index 00000000..1d00e595 --- /dev/null +++ b/src/main/java/ru/bclib/interfaces/NoiseGeneratorSettingsProvider.java @@ -0,0 +1,7 @@ +package ru.bclib.interfaces; + +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; + +public interface NoiseGeneratorSettingsProvider { + NoiseGeneratorSettings bclib_getNoiseGeneratorSettings(); +} diff --git a/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java b/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java index fe40c99a..e4482def 100644 --- a/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java +++ b/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java @@ -1,10 +1,11 @@ package ru.bclib.interfaces; +import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; import java.util.List; public interface SurfaceRuleProvider { - void clearCustomRules(); - void addCustomRules(List rules); + void bclib_addBiomeSource(BiomeSource source); + void bclib_clearBiomeSources(); } diff --git a/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java b/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java index 1104fe25..87bce5f6 100644 --- a/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java +++ b/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java @@ -62,7 +62,7 @@ public abstract class MinecraftMixin { @Inject(method = "loadLevel", cancellable = true, at = @At("HEAD")) private void bclib_callFixerOnLoad(String levelID, CallbackInfo ci) { DataExchangeAPI.prepareServerside(); - BiomeAPI.prepareWorldData(); + BiomeAPI.prepareNewLevel(); if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> { LifeCycleAPI._runBeforeLevelLoad(); @@ -84,7 +84,7 @@ public abstract class MinecraftMixin { @Inject(method = "createLevel", at = @At("HEAD")) private void bclib_initPatchData(String levelID, LevelSettings levelSettings, RegistryHolder registryHolder, WorldGenSettings worldGenSettings, CallbackInfo ci) { DataExchangeAPI.prepareServerside(); - BiomeAPI.prepareWorldData(); + BiomeAPI.prepareNewLevel(); DataFixerAPI.initializeWorldData(this.levelSource, levelID, true); LifeCycleAPI._runBeforeLevelLoad(); diff --git a/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java b/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java index 95e4e83e..89d1e22b 100644 --- a/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java +++ b/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java @@ -30,9 +30,4 @@ public abstract class BiomeSourceMixin implements BiomeSourceAccessor { BCLib.LOGGER.info("Rebuilding features in BiomeSource " + this.getClass()); featuresPerStep = buildFeaturesPerStep(this.possibleBiomes().stream().toList(), true); } - - @Inject(method="(Ljava/util/List;)V", at=@At(value="INVOKE", shift = Shift.AFTER, target="Lnet/minecraft/world/level/biome/BiomeSource;buildFeaturesPerStep(Ljava/util/List;Z)Ljava/util/List;")) - private void bcl_Init(List list, CallbackInfo ci){ - BiomeAPI.registerBiomeSource((BiomeSource)(Object)this); - } } diff --git a/src/main/java/ru/bclib/mixin/common/MinecraftServerMixin.java b/src/main/java/ru/bclib/mixin/common/MinecraftServerMixin.java index 661195c5..0c470b28 100644 --- a/src/main/java/ru/bclib/mixin/common/MinecraftServerMixin.java +++ b/src/main/java/ru/bclib/mixin/common/MinecraftServerMixin.java @@ -46,7 +46,6 @@ public class MinecraftServerMixin { @Inject(method = "*", at = @At("TAIL")) private void bclib_onServerInit(Thread thread, RegistryHolder registryHolder, LevelStorageAccess levelStorageAccess, WorldData worldData, PackRepository packRepository, Proxy proxy, DataFixer dataFixer, ServerResources serverResources, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache gameProfileCache, ChunkProgressListenerFactory chunkProgressListenerFactory, CallbackInfo ci) { DataExchangeAPI.prepareServerside(); - BiomeAPI.registerWorldData(worldData); } @Inject(method = "reloadResources", at = @At(value = "RETURN"), cancellable = true) diff --git a/src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java b/src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java index f09bce4f..96e4fc4c 100644 --- a/src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java +++ b/src/main/java/ru/bclib/mixin/common/NoiseBasedChunkGeneratorMixin.java @@ -19,6 +19,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import ru.bclib.BCLib; +import ru.bclib.interfaces.NoiseGeneratorSettingsProvider; import ru.bclib.interfaces.SurfaceProvider; import java.lang.reflect.Constructor; @@ -26,7 +27,7 @@ import java.util.Optional; import java.util.function.Supplier; @Mixin(NoiseBasedChunkGenerator.class) -public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider { +public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider, NoiseGeneratorSettingsProvider { @Final @Shadow private NoiseSampler sampler; @@ -41,6 +42,11 @@ public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider { private static BlockState bclib_air = Blocks.AIR.defaultBlockState(); private static Constructor bclib_constructor; + + @Override + public NoiseGeneratorSettings bclib_getNoiseGeneratorSettings(){ + return settings.get(); + } @Override @SuppressWarnings("deprecation") diff --git a/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java b/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java index 8b3afa9c..808f7cf6 100644 --- a/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java +++ b/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java @@ -1,5 +1,6 @@ package ru.bclib.mixin.common; +import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; @@ -7,9 +8,12 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Shadow; +import ru.bclib.api.biomes.BiomeAPI; import ru.bclib.interfaces.SurfaceRuleProvider; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; @Mixin(NoiseGeneratorSettings.class) @@ -20,17 +24,32 @@ public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider { private SurfaceRules.RuleSource surfaceRule; private SurfaceRules.RuleSource bclib_originalSurfaceRule; - + private Set bclib_biomeSources = new HashSet<>(); + + private void bclib_updateCutomRules(){ + bclib_setCustomRules(BiomeAPI.getRuleSources(bclib_biomeSources)); + } + @Override - public void clearCustomRules() { + public void bclib_addBiomeSource(BiomeSource source) { + bclib_biomeSources.add(source); + bclib_updateCutomRules(); + } + + @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; } } - @Override - public void addCustomRules(List rules) { + private void bclib_setCustomRules(List rules) { RuleSource org = getOriginalSurfaceRule(); if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule){ List currentSequence = sequenceRule.sequence(); diff --git a/src/main/java/ru/bclib/world/biomes/BCLBiome.java b/src/main/java/ru/bclib/world/biomes/BCLBiome.java index 2cbe01f8..bbfdafaa 100644 --- a/src/main/java/ru/bclib/world/biomes/BCLBiome.java +++ b/src/main/java/ru/bclib/world/biomes/BCLBiome.java @@ -288,7 +288,7 @@ public class BCLBiome extends BCLBiomeSettings { this.surfaceInit = (actualBiome) -> { ResourceKey key = BiomeAPI.getBiomeKey(actualBiome); if (key == null) { - BCLib.LOGGER.warning("BCL Biome " + biomeID + " don't have registry key!"); + BCLib.LOGGER.warning("BCL Biome " + biomeID + " does not have registry key!"); } else { BiomeAPI.addSurfaceRule(biomeID, SurfaceRules.ifTrue(SurfaceRules.isBiome(key), surface)); @@ -304,7 +304,6 @@ public class BCLBiome extends BCLBiomeSettings { */ public void setFeatures(Map>> features) { this.features = features; - BiomeAPI.addStepFeaturesToBiome(getBiome(), features); } /**