From b60df41c6c06c49183bd59278e55f5cd75f3ff1f Mon Sep 17 00:00:00 2001 From: Frank Date: Sat, 18 Dec 2021 00:27:50 +0100 Subject: [PATCH] Fix for crash when biomeSource is not initialized twice (paulevsGitch/BetterNether#468) --- .../java/ru/bclib/api/biomes/BiomeAPI.java | 197 +++++++++++------- .../bclib/interfaces/BiomeSourceAccessor.java | 5 + .../ru/bclib/mixin/client/MinecraftMixin.java | 5 +- .../bclib/mixin/common/BiomeSourceMixin.java | 38 ++++ .../common/StructureSettingsAccessor.java | 12 +- .../java/ru/bclib/world/biomes/BCLBiome.java | 3 +- .../bclib/world/generator/BCLBiomeSource.java | 2 +- src/main/resources/bclib.mixins.common.json | 3 +- 8 files changed, 179 insertions(+), 86 deletions(-) create mode 100644 src/main/java/ru/bclib/interfaces/BiomeSourceAccessor.java create mode 100644 src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index 574c54a5..a0165bee 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -7,12 +7,14 @@ 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.mojang.serialization.Codec; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback; import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; import net.fabricmc.fabric.impl.biome.NetherBiomeData; import net.fabricmc.fabric.impl.biome.TheEndBiomeData; +import net.fabricmc.fabric.impl.structure.FabricStructureImpl; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; @@ -45,16 +47,19 @@ import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.feature.configurations.StructureFeatureConfiguration; import net.minecraft.world.level.levelgen.placement.PlacedFeature; import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.Nullable; import ru.bclib.BCLib; import ru.bclib.config.Configs; 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.mixin.common.BiomeGenerationSettingsAccessor; +import ru.bclib.mixin.common.BiomeSourceMixin; import ru.bclib.mixin.common.MobSpawnSettingsAccessor; import ru.bclib.mixin.common.StructureSettingsAccessor; import ru.bclib.util.CollectionsUtil; @@ -67,14 +72,15 @@ 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.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.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -118,21 +124,19 @@ public class BiomeAPI { return; } - BuiltinRegistries.BIOME - .entrySet() - .stream() - .filter(entry -> entry.getKey().location().getNamespace().equals("minecraft")) - .map(entry -> entry.getValue()) - .forEach(biome -> { - BiomeGenerationSettingsAccessor accessor = BiomeGenerationSettingsAccessor.class.cast(biome.getGenerationSettings()); - List>> features = accessor.bclib_getFeatures(); - features.forEach(step -> { - step.forEach(provider -> { - PlacedFeature feature = provider.get(); - FEATURE_ORDER.computeIfAbsent(feature, f -> FEATURE_ORDER_ID.getAndIncrement()); - }); - }); - }); + BuiltinRegistries.BIOME.entrySet() + .stream() + .filter(entry -> entry.getKey() + .location() + .getNamespace() + .equals("minecraft")) + .map(Entry::getValue) + .map(biome -> (BiomeGenerationSettingsAccessor) biome.getGenerationSettings()) + .map(BiomeGenerationSettingsAccessor::bclib_getFeatures) + .forEach(stepFeatureSuppliers -> stepFeatureSuppliers.forEach(step -> step.forEach(featureSupplier -> { + PlacedFeature feature = featureSupplier.get(); + FEATURE_ORDER.computeIfAbsent(feature, f -> FEATURE_ORDER_ID.getAndIncrement()); + }))); } /** @@ -156,17 +160,56 @@ public class BiomeAPI { } } + 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); + } + + /** + * 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(){ + structureStarts.clear(); + worldSources.clear(); + } + + /** + * Registered by {@link #initRegistry(Registry)} as a callback for whenever a new Biome was + * added to our registry + * @param biome The {@link Biome} that got added + */ private static void onAddedBiome(Biome biome) { + boolean didChange = false; //BCLib.LOGGER.info(" ++++ " + getBiomeID(biome) + ", " + getBiomeKey(biome) + ", " + biome); for (var dim : MODIFICATIONS.keySet()) { List> modifications = MODIFICATIONS.get(dim); if (modifications == null) { sortBiomeFeatures(biome); - return; + continue; } - applyModifications(modifications, biome); + didChange=true; + applyModificationsToBiome(modifications, biome); } + +// if (didChange) { +// worldSources.stream() +// .filter(s -> s.possibleBiomes() +// .contains(biome)) +// .forEach(s -> ((BiomeSourceAccessor) s).bclRebuildFeatures()); +// } } /** @@ -214,7 +257,7 @@ public class BiomeAPI { MHelper.randRange(-1.5F, 1.5F, random), random.nextFloat() ); - ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).get(); + ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).orElseThrow(); NetherBiomeData.addNetherBiome(key, parameters); return biome; } @@ -244,7 +287,7 @@ public class BiomeAPI { configureBiome(biome); END_LAND_BIOME_PICKER.addBiome(biome); float weight = biome.getGenChance(); - ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).get(); + ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).orElseThrow(); TheEndBiomeData.addEndBiomeReplacement(Biomes.END_HIGHLANDS, key, weight); TheEndBiomeData.addEndBiomeReplacement(Biomes.END_MIDLANDS, key, weight); return biome; @@ -290,7 +333,7 @@ public class BiomeAPI { configureBiome(biome); END_VOID_BIOME_PICKER.addBiome(biome); float weight = biome.getGenChance(); - ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).get(); + ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome.getBiome()).orElseThrow(); TheEndBiomeData.addEndBiomeReplacement(Biomes.SMALL_END_ISLANDS, key, weight); return biome; } @@ -317,7 +360,6 @@ public class BiomeAPI { * @return {@link BCLBiome} */ public static BCLBiome registerEndVoidBiome(Biome biome, float genChance) { - ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome).get(); BCLBiome bclBiome = new BCLBiome(biome).setGenChance(genChance); configureBiome(bclBiome); END_VOID_BIOME_PICKER.addBiome(bclBiome); @@ -361,8 +403,9 @@ public class BiomeAPI { */ @Nullable public static ResourceKey getBiomeKey(Biome biome) { - ResourceKey key = BuiltinRegistries.BIOME.getResourceKey(biome).orElse(null); - return key != null ? key : biomeRegistry != null ? biomeRegistry.getResourceKey(biome).orElse(null) : null; + return BuiltinRegistries.BIOME.getResourceKey(biome) + .orElseGet(() -> biomeRegistry != null ? biomeRegistry.getResourceKey(biome) + .orElse(null) : null); } /** @@ -460,11 +503,7 @@ public class BiomeAPI { * @param modification {@link BiConsumer} with {@link ResourceKey} biome ID and {@link Biome} parameters. */ public static void registerBiomeModification(ResourceKey dimensionID, BiConsumer modification) { - List> modifications = MODIFICATIONS.get(dimensionID); - if (modifications == null) { - modifications = Lists.newArrayList(); - MODIFICATIONS.put(dimensionID, modifications); - } + List> modifications = MODIFICATIONS.computeIfAbsent(dimensionID, k -> Lists.newArrayList()); modifications.add(modification); } @@ -521,11 +560,13 @@ public class BiomeAPI { } biomes.forEach(biome -> { - applyModifications(modifications, biome); + applyModificationsToBiome(modifications, biome); }); + + ((BiomeSourceAccessor) source).bclRebuildFeatures(); } - private static void applyModifications(List> modifications, Biome biome) { + private static void applyModificationsToBiome(List> modifications, Biome biome) { ResourceLocation biomeID = getBiomeID(biome); boolean modify = isDatapackBiome(biomeID); if (biome != BuiltinRegistries.BIOME.get(biomeID)) { @@ -543,7 +584,7 @@ public class BiomeAPI { final BCLBiome bclBiome = BiomeAPI.getBiome(biome); if (bclBiome!=null) { - addBiomeFeature(biome, bclBiome.getFeatures()); + addStepFeaturesToBiome(biome, bclBiome.getFeatures()); } sortBiomeFeatures(biome); @@ -551,7 +592,7 @@ public class BiomeAPI { public static void sortBiomeFeatures(Biome biome) { BiomeGenerationSettings settings = biome.getGenerationSettings(); - BiomeGenerationSettingsAccessor accessor = BiomeGenerationSettingsAccessor.class.cast(settings); + BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings; List>> featureList = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); final int size = featureList.size(); for (int i = 0; i < size; i++) { @@ -629,13 +670,13 @@ public class BiomeAPI { * @param step a {@link Decoration} step for the feature. * @param featureList List of {@link ConfiguredFeature} to add. */ - public static void addBiomeFeature(Biome biome, Decoration step, List featureList) { + private static void addBiomeFeature(Biome biome, Decoration step, List featureList) { BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings(); List>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); Set set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet()); List> features = getFeaturesList(allFeatures, step); for (var feature : featureList) { - features.add(() -> feature); + features.add(() -> feature); set.add(feature); } accessor.bclib_setFeatures(allFeatures); @@ -643,11 +684,14 @@ public class BiomeAPI { } /** - * Adds new features to existing biome. + * For internal use only! + * + * Adds new features to existing biome. Called from {@link BCLBiome#setFeatures(Map)} when the Biome is + * first built, and from {@link #onAddedBiome(Biome)} whenever a Biome is readded through a Datapack * @param biome {@link Biome} to add features in. * @param featureMap Map of {@link ConfiguredFeature} to add. */ - public static void addBiomeFeature(Biome biome, Map>> featureMap) { + public 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()); @@ -665,34 +709,6 @@ public class BiomeAPI { accessor.bclib_setFeatureSet(set); } - /** - * Adds new features to existing biome. - * @param biomeID {@link ResourceLocation} of the {@link Biome} to add features in. - * @param feature {@link ConfiguredFeature} to add. - * @param step a {@link Decoration} step for the feature. - */ - private static void addBiomeFeature(ResourceLocation biomeID, PlacedFeature feature, Decoration step) { - addBiomeFeature(BuiltinRegistries.BIOME.get(biomeID), step, feature); - } - - /** - * Adds new features to existing biome. - * @param biome {@link Biome} to add features in. - * @param features array of {@link BCLFeature} to add. - */ - public static void addBiomeFeatures(Biome biome, BCLFeature... features) { - BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings(); - List>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures()); - Set set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet()); - for (BCLFeature feature: features) { - List> featureList = getFeaturesList(allFeatures, feature.getDecoration()); - featureList.add(() -> feature.getPlacedFeature()); - set.add(feature.getPlacedFeature()); - } - accessor.bclib_setFeatures(allFeatures); - accessor.bclib_setFeatureSet(set); - } - /** * Adds new structure feature to existing biome. * @param biomeKey {@link ResourceKey} for the {@link Biome} to add structure feature in. @@ -703,17 +719,26 @@ public class BiomeAPI { BCLib.LOGGER.error("null is not a valid biomeKey for " + structure); return; } - changeStructureStarts(biomeKey.location(), structure, structureMap -> { + changeStructureStarts(biomeKey.location(), structure, (structureMap, configMap) -> { Multimap, ResourceKey> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create()); configuredMap.put(structure, biomeKey); + + StructureFeatureConfiguration config = FabricStructureImpl.STRUCTURE_TO_CONFIG_MAP.get(structure.feature); + if (config!=null){ + configMap.put(structure.feature, config); + } }); } public static void addBiomeStructure(Biome biome, ConfiguredStructureFeature structure) { - changeStructureStarts(BiomeAPI.getBiomeID(biome), structure, structureMap -> { + changeStructureStarts(BiomeAPI.getBiomeID(biome), structure, (structureMap, configMap) -> { Multimap, ResourceKey> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create()); var key = getBiomeKey(biome); if (key!=null) { + StructureFeatureConfiguration config = FabricStructureImpl.STRUCTURE_TO_CONFIG_MAP.get(structure.feature); + if (config!=null){ + configMap.put(structure.feature, config); + } configuredMap.put(structure, key); } else { BCLib.LOGGER.warning("Unable to find Biome " + getBiomeID(biome)); @@ -881,11 +906,13 @@ public class BiomeAPI { } } - private final static Map, Multimap, ResourceKey>>>> structureStarts = new HashMap<>(); + private final static Map, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>>> structureStarts = new HashMap<>(); 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 (oGeneratorRegistry.isPresent()) { RegistryEntryAddedCallback @@ -895,7 +922,7 @@ public class BiomeAPI { //add back modded structures StructureSettingsAccessor a = (StructureSettingsAccessor)settings.structureSettings(); - structureStarts.values().forEach(modifier -> changeStructureStarts(a, modifier)); + structureStarts.entrySet().forEach(entry -> changeStructureStarts(a, entry.getValue())); //add surface rules if (biomeRegistry!=null) { @@ -919,11 +946,7 @@ public class BiomeAPI { } } - public static void clearStructureStarts(){ - structureStarts.clear(); - } - - private static void changeStructureStarts(ResourceLocation id, ConfiguredStructureFeature structure, Consumer, Multimap, ResourceKey>>> modifier) { + private static void changeStructureStarts(ResourceLocation id, ConfiguredStructureFeature structure, BiConsumer, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>> modifier) { structureStarts.put(new StructureID(id, structure), modifier); Registry chunkGenSettingsRegistry = BuiltinRegistries.NOISE_GENERATOR_SETTINGS; @@ -934,11 +957,17 @@ public class BiomeAPI { } - private static void changeStructureStarts(StructureSettingsAccessor access, Consumer, Multimap, ResourceKey>>> modifier) { + private static void changeStructureStarts(StructureSettingsAccessor access, BiConsumer, Multimap, ResourceKey>>, Map, StructureFeatureConfiguration>> modifier) { Map, Multimap, ResourceKey>> structureMap; - structureMap = getMutableStructureConfig(access); - modifier.accept(structureMap); - setMutableStructureConfig(access, structureMap); + Map, StructureFeatureConfiguration> configMap; + + structureMap = getMutableConfiguredStructures(access); + configMap = getMutableStructureConfig(access); + + modifier.accept(structureMap, configMap); + + setMutableConfiguredStructures(access, structureMap); + setMutableStructureConfig(access, configMap); } private static void sortFeatures(List> features) { @@ -1000,7 +1029,7 @@ public class BiomeAPI { } //inspired by net.fabricmc.fabric.impl.biome.modification.BiomeStructureStartsImpl - private static Map, Multimap, ResourceKey>> getMutableStructureConfig(StructureSettingsAccessor access) { + private static Map, Multimap, ResourceKey>> getMutableConfiguredStructures(StructureSettingsAccessor access) { ImmutableMap, ImmutableMultimap, ResourceKey>> configuredStructures = access.bcl_getConfiguredStructures(); Map, Multimap, ResourceKey>> result = new HashMap<>(configuredStructures.size()); @@ -1012,7 +1041,7 @@ public class BiomeAPI { } //inspired by net.fabricmc.fabric.impl.biome.modification.BiomeStructureStartsImpl - private static void setMutableStructureConfig(StructureSettingsAccessor access, Map, Multimap, ResourceKey>> structureStarts) { + private static void setMutableConfiguredStructures(StructureSettingsAccessor access, Map, Multimap, ResourceKey>> structureStarts) { access.bcl_setConfiguredStructures( structureStarts .entrySet() @@ -1020,4 +1049,12 @@ public class BiomeAPI { .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, e -> ImmutableMultimap.copyOf(e.getValue()))) ); } + + private static Map, StructureFeatureConfiguration> getMutableStructureConfig(StructureSettingsAccessor access) { + return CollectionsUtil.getMutable(access.bcl_getStructureConfig()); + } + + private static void setMutableStructureConfig(StructureSettingsAccessor access, Map, StructureFeatureConfiguration> structureConfig) { + access.bcl_setStructureConfig(structureConfig); + } } diff --git a/src/main/java/ru/bclib/interfaces/BiomeSourceAccessor.java b/src/main/java/ru/bclib/interfaces/BiomeSourceAccessor.java new file mode 100644 index 00000000..356330fd --- /dev/null +++ b/src/main/java/ru/bclib/interfaces/BiomeSourceAccessor.java @@ -0,0 +1,5 @@ +package ru.bclib.interfaces; + +public interface BiomeSourceAccessor { + void bclRebuildFeatures(); +} diff --git a/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java b/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java index b0a83ed9..462fbd2c 100644 --- a/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java +++ b/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java @@ -61,7 +61,7 @@ public abstract class MinecraftMixin { @Inject(method = "loadLevel", cancellable = true, at = @At("HEAD")) private void bclib_callFixerOnLoad(String levelID, CallbackInfo ci) { DataExchangeAPI.prepareServerside(); - BiomeAPI.clearStructureStarts(); + BiomeAPI.prepareWorldData(); if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> { LifeCycleAPI._runBeforeLevelLoad(); @@ -76,6 +76,9 @@ 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(); + 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 new file mode 100644 index 00000000..95e4e83e --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java @@ -0,0 +1,38 @@ +package ru.bclib.mixin.common; + +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.BiomeSource.StepFeatureData; +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 org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import ru.bclib.BCLib; +import ru.bclib.api.biomes.BiomeAPI; +import ru.bclib.interfaces.BiomeSourceAccessor; + +import java.util.List; +import java.util.Set; + +@Mixin(BiomeSource.class) +public abstract class BiomeSourceMixin implements BiomeSourceAccessor { + @Shadow protected abstract List buildFeaturesPerStep(List list, boolean bl); + + @Shadow public abstract Set possibleBiomes(); + + @Mutable @Shadow @Final private List featuresPerStep; + + public void bclRebuildFeatures(){ + 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/StructureSettingsAccessor.java b/src/main/java/ru/bclib/mixin/common/StructureSettingsAccessor.java index 886c9be5..bd3dc67a 100644 --- a/src/main/java/ru/bclib/mixin/common/StructureSettingsAccessor.java +++ b/src/main/java/ru/bclib/mixin/common/StructureSettingsAccessor.java @@ -7,16 +7,26 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.levelgen.StructureSettings; import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.feature.configurations.StructureFeatureConfiguration; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; +import java.util.Map; + @Mixin(StructureSettings.class) public interface StructureSettingsAccessor { @Accessor("configuredStructures") ImmutableMap, ImmutableMultimap, ResourceKey>> bcl_getConfiguredStructures(); + @Accessor("structureConfig") + Map, StructureFeatureConfiguration> bcl_getStructureConfig(); + @Accessor("configuredStructures") @Mutable - void bcl_setConfiguredStructures(ImmutableMap, ImmutableMultimap, ResourceKey>> structureConfig); + void bcl_setConfiguredStructures(ImmutableMap, ImmutableMultimap, ResourceKey>> configuredStructures); + + @Accessor("structureConfig") + @Mutable + void bcl_setStructureConfig(Map, StructureFeatureConfiguration> structureConfig); } diff --git a/src/main/java/ru/bclib/world/biomes/BCLBiome.java b/src/main/java/ru/bclib/world/biomes/BCLBiome.java index acd422a1..58197c09 100644 --- a/src/main/java/ru/bclib/world/biomes/BCLBiome.java +++ b/src/main/java/ru/bclib/world/biomes/BCLBiome.java @@ -15,10 +15,8 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature; import org.jetbrains.annotations.Nullable; import ru.bclib.BCLib; import ru.bclib.api.biomes.BiomeAPI; -import ru.bclib.util.Pair; import ru.bclib.util.WeightedList; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -370,6 +368,7 @@ public class BCLBiome { */ public void setFeatures(Map>> features) { this.features = features; + BiomeAPI.addStepFeaturesToBiome(getBiome(), features); } /** diff --git a/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java index f9db3a37..a329a875 100644 --- a/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLBiomeSource.java @@ -21,7 +21,7 @@ public abstract class BCLBiomeSource extends BiomeSource { this.seed = seed; this.biomeRegistry = biomeRegistry; - + BiomeAPI.initRegistry(biomeRegistry); } } diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 34b786a2..8ef31f61 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -39,7 +39,8 @@ "AnvilMenuMixin", "TagLoaderMixin", "MainMixin", - "SurfaceRulesContextAccessor" + "SurfaceRulesContextAccessor", + "BiomeSourceMixin" ], "injectors": { "defaultRequire": 1