diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index 8752a34b..99a889b0 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -10,6 +10,7 @@ import net.fabricmc.fabric.impl.biome.NetherBiomeData; import net.fabricmc.fabric.impl.biome.TheEndBiomeData; import net.minecraft.client.Minecraft; import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; import net.minecraft.data.BuiltinRegistries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -40,6 +41,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; import java.util.function.BiConsumer; +import java.util.stream.Collectors; public class BiomeAPI { /** @@ -78,7 +80,16 @@ public class BiomeAPI { * @param server - {@link MinecraftServer} */ public static void initRegistry(MinecraftServer server) { - biomeRegistry = server.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); + initRegistry(server.registryAccess()); + } + + /** + * Initialize registry for current server. + * + * @param access - {@link RegistryAccess} + */ + public static void initRegistry(RegistryAccess access) { + biomeRegistry = access.registryOrThrow(Registry.BIOME_REGISTRY); CLIENT.clear(); } @@ -388,13 +399,30 @@ public class BiomeAPI { * @param level */ public static void applyModifications(ServerLevel level) { - List> modifications = MODIFICATIONS.get(level.dimension()); - if (modifications == null) { - return; - } BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource(); Set biomes = source.possibleBiomes(); + applyModifications(biomes, level.dimension()); + } + + /** + * Will apply biome modifications to world, internal usage only. + * @param registryAccess + */ + public static void applyModifications(RegistryAccess registryAccess) { + Registry biomeReg = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY); + Set biomes = biomeReg.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toSet()); + + applyModifications(biomes, Level.NETHER); + applyModifications(biomes, Level.OVERWORLD); + applyModifications(biomes, Level.END); + } + + private static void applyModifications(Set biomes, ResourceKey dimension) { + List> modifications = MODIFICATIONS.get(dimension); + if (modifications == null) { + return; + } biomes.forEach(biome -> { ResourceLocation biomeID = getBiomeID(biome); boolean modify = isDatapackBiome(biomeID); diff --git a/src/main/java/ru/bclib/mixin/common/RegistryReadOpsMixin.java b/src/main/java/ru/bclib/mixin/common/RegistryReadOpsMixin.java new file mode 100644 index 00000000..1ca0f981 --- /dev/null +++ b/src/main/java/ru/bclib/mixin/common/RegistryReadOpsMixin.java @@ -0,0 +1,25 @@ +package ru.bclib.mixin.common; + +import com.mojang.serialization.DynamicOps; +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.RegistryReadOps; +import net.minecraft.resources.RegistryResourceAccess; +import net.minecraft.server.level.ServerLevel; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import ru.bclib.api.biomes.BiomeAPI; + +/** + * Fabrics BiomeModifications API is called at this point. We have to ensure that BCLibs Modification API + * runs before Fabric, so we need to hook into the same class. + */ +@Mixin(RegistryReadOps.class) +public class RegistryReadOpsMixin { + @Inject(method = "createAndLoad(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resources/RegistryResourceAccess;Lnet/minecraft/core/RegistryAccess;)Lnet/minecraft/resources/RegistryReadOps;", at = @At("RETURN")) + private static void foo(DynamicOps dynamicOps, RegistryResourceAccess registryResourceAccess, RegistryAccess registryAccess, CallbackInfoReturnable> cir){ + BiomeAPI.initRegistry(registryAccess); + BiomeAPI.applyModifications(registryAccess); + } +} diff --git a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java index ccb3b8be..e94c49e2 100644 --- a/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java +++ b/src/main/java/ru/bclib/mixin/common/ServerLevelMixin.java @@ -38,8 +38,9 @@ public abstract class ServerLevelMixin extends Level { ServerLevel world = ServerLevel.class.cast(this); LifeCycleAPI._runLevelLoad(world, server, executor, levelStorageAccess, serverLevelData, resourceKey, dimensionType, chunkProgressListener, chunkGenerator, bl, l, list, bl2); - BiomeAPI.initRegistry(server); - BiomeAPI.applyModifications(ServerLevel.class.cast(this)); + //called from RegistryReadOpsMixin for now +// BiomeAPI.initRegistry(server); +// BiomeAPI.applyModifications(ServerLevel.class.cast(this)); if (bclib_lastWorld != null && bclib_lastWorld.equals(levelStorageAccess.getLevelId())) { return; diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 7e9c2373..d7578488 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -13,8 +13,6 @@ "shears.MushroomCowMixin", "ComposterBlockAccessor", "PotionBrewingAccessor", - "PotionBrewingAccessor", - "RecipeManagerAccessor", "RecipeManagerAccessor", "shears.SnowGolemMixin", "EnchantmentMenuMixin", @@ -24,21 +22,19 @@ "TheEndBiomeDataMixin", "ChunkGeneratorMixin", "WorldGenRegionMixin", - "WorldGenRegionMixin", "DimensionTypeMixin", "RecipeManagerMixin", "RecipeManagerMixin", "BoneMealItemMixin", "CraftingMenuMixin", - "CraftingMenuMixin", - "shears.SheepMixin", "shears.SheepMixin", "PortalShapeMixin", "ServerLevelMixin", "AnvilBlockMixin", "AnvilMenuMixin", "TagLoaderMixin", - "MainMixin" + "MainMixin", + "RegistryReadOpsMixin" ], "injectors": { "defaultRequire": 1