diff --git a/src/main/java/ru/bclib/BCLib.java b/src/main/java/ru/bclib/BCLib.java index bc71a685..ab732c72 100644 --- a/src/main/java/ru/bclib/BCLib.java +++ b/src/main/java/ru/bclib/BCLib.java @@ -6,6 +6,7 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.resources.ResourceLocation; import ru.bclib.api.TagAPI; import ru.bclib.api.WorldDataAPI; +import ru.bclib.api.biomes.BiomeAPI; import ru.bclib.api.dataexchange.DataExchangeAPI; import ru.bclib.api.dataexchange.handler.autosync.Chunker; import ru.bclib.api.dataexchange.handler.autosync.HelloClient; @@ -47,6 +48,8 @@ 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 6d357af7..4c43d712 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -9,6 +9,8 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Sets; 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.minecraft.client.Minecraft; @@ -64,6 +66,7 @@ import ru.bclib.world.structures.BCLStructureFeature; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -631,7 +634,6 @@ public class BiomeAPI { } changeStructureStarts(structureMap -> { Multimap, ResourceKey> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create()); - configuredMap.put(structure, biomeKey); }); } @@ -780,17 +782,45 @@ public class BiomeAPI { return Optional.empty(); } + private final static List, Multimap, ResourceKey>>>> structureStarts = new LinkedList<>(); + + public static void registerStructureEvents(){ + DynamicRegistrySetupCallback.EVENT.register(registryManager -> { + Optional> v = registryManager.registry(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY); + if (v.isPresent()) { + RegistryEntryAddedCallback + .event(v.get()) + .register((rawId, id, object) -> { + BCLib.LOGGER.info(" #### " + rawId + ", " + object + ", " + id); + StructureSettingsAccessor a = (StructureSettingsAccessor)object.structureSettings(); + structureStarts.forEach(modifier -> changeStructureStarts(a, modifier)); + }); + } + }); + } + + public static void clearStructureStarts(){ + structureStarts.clear(); + } + private static void changeStructureStarts(Consumer, Multimap, ResourceKey>>> modifier) { + structureStarts.add(modifier); Registry chunkGenSettingsRegistry = BuiltinRegistries.NOISE_GENERATOR_SETTINGS; for (Map.Entry, NoiseGeneratorSettings> entry : chunkGenSettingsRegistry.entrySet()) { - Map, Multimap, ResourceKey>> structureMap = getMutableStructureConfig(entry.getValue()); - - modifier.accept(structureMap); - setMutableStructureConfig(entry.getValue(), structureMap); + final StructureSettingsAccessor access = (StructureSettingsAccessor) entry.getValue().structureSettings(); + changeStructureStarts(access, modifier); } } + + private static void changeStructureStarts(StructureSettingsAccessor access, Consumer, Multimap, ResourceKey>>> modifier) { + Map, Multimap, ResourceKey>> structureMap; + structureMap = getMutableStructureConfig(access); + modifier.accept(structureMap); + setMutableStructureConfig(access, structureMap); + } + private static void sortFeatures(List> features) { initFeatureOrder(); @@ -850,12 +880,11 @@ public class BiomeAPI { } //inspired by net.fabricmc.fabric.impl.biome.modification.BiomeStructureStartsImpl - private static Map, Multimap, ResourceKey>> getMutableStructureConfig(NoiseGeneratorSettings settings) { - final StructureSettingsAccessor access = (StructureSettingsAccessor)settings.structureSettings(); - ImmutableMap, ImmutableMultimap, ResourceKey>> immutableMap = access.bcl_getStructureConfig(); - Map, Multimap, ResourceKey>> result = new HashMap<>(immutableMap.size()); + private static Map, Multimap, ResourceKey>> getMutableStructureConfig(StructureSettingsAccessor access) { + ImmutableMap, ImmutableMultimap, ResourceKey>> configuredStructures = access.bcl_getConfiguredStructures(); + Map, Multimap, ResourceKey>> result = new HashMap<>(configuredStructures.size()); - for (Map.Entry, ImmutableMultimap, ResourceKey>> entry : immutableMap.entrySet()) { + for (Map.Entry, ImmutableMultimap, ResourceKey>> entry : configuredStructures.entrySet()) { result.put(entry.getKey(), HashMultimap.create(entry.getValue())); } @@ -863,9 +892,8 @@ public class BiomeAPI { } //inspired by net.fabricmc.fabric.impl.biome.modification.BiomeStructureStartsImpl - private static void setMutableStructureConfig(NoiseGeneratorSettings settings, Map, Multimap, ResourceKey>> structureStarts) { - final StructureSettingsAccessor access = (StructureSettingsAccessor) settings.structureSettings(); - access.bcl_setStructureConfig( + private static void setMutableStructureConfig(StructureSettingsAccessor access, Map, Multimap, ResourceKey>> structureStarts) { + access.bcl_setConfiguredStructures( structureStarts .entrySet() .stream() diff --git a/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java b/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java index 6c884bcf..7be3364a 100644 --- a/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java +++ b/src/main/java/ru/bclib/mixin/client/MinecraftMixin.java @@ -1,6 +1,12 @@ package ru.bclib.mixin.client; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Multimap; import com.mojang.datafixers.util.Function4; +import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback; +import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft.ExperimentalDialogType; import net.minecraft.client.color.block.BlockColors; @@ -9,10 +15,17 @@ import net.minecraft.client.main.GameConfig; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess.RegistryHolder; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.resources.ResourceKey; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.world.level.DataPackConfig; import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; +import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.WorldGenSettings; +import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.world.level.levelgen.feature.StructureFeature; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess; import net.minecraft.world.level.storage.WorldData; @@ -22,11 +35,18 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import ru.bclib.BCLib; import ru.bclib.api.LifeCycleAPI; +import ru.bclib.api.biomes.BiomeAPI; import ru.bclib.api.dataexchange.DataExchangeAPI; import ru.bclib.api.datafixer.DataFixerAPI; import ru.bclib.interfaces.CustomColorProvider; +import ru.bclib.mixin.common.StructureSettingsAccessor; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; @Mixin(Minecraft.class) @@ -60,13 +80,15 @@ public abstract class MinecraftMixin { @Inject(method = "loadLevel", cancellable = true, at = @At("HEAD")) private void bclib_callFixerOnLoad(String levelID, CallbackInfo ci) { DataExchangeAPI.prepareServerside(); + BiomeAPI.clearStructureStarts(); if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> { LifeCycleAPI._runBeforeLevelLoad(); - this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, appliedFixes?ExperimentalDialogType.NONE:ExperimentalDialogType.BACKUP); + this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, appliedFixes ? ExperimentalDialogType.NONE : ExperimentalDialogType.BACKUP); })) { ci.cancel(); - } else { + } + else { LifeCycleAPI._runBeforeLevelLoad(); } } diff --git a/src/main/java/ru/bclib/mixin/common/StructureSettingsAccessor.java b/src/main/java/ru/bclib/mixin/common/StructureSettingsAccessor.java index cb323706..886c9be5 100644 --- a/src/main/java/ru/bclib/mixin/common/StructureSettingsAccessor.java +++ b/src/main/java/ru/bclib/mixin/common/StructureSettingsAccessor.java @@ -14,9 +14,9 @@ import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(StructureSettings.class) public interface StructureSettingsAccessor { @Accessor("configuredStructures") - ImmutableMap, ImmutableMultimap, ResourceKey>> bcl_getStructureConfig(); + ImmutableMap, ImmutableMultimap, ResourceKey>> bcl_getConfiguredStructures(); @Accessor("configuredStructures") @Mutable - void bcl_setStructureConfig(ImmutableMap, ImmutableMultimap, ResourceKey>> structureConfig); + void bcl_setConfiguredStructures(ImmutableMap, ImmutableMultimap, ResourceKey>> structureConfig); }