diff --git a/adapters/forge/src/test/java/art/arcane/volmlib/nativelib/minecraft26_2/forge/NativeForgeBiomeDefinitionTest.java b/adapters/forge/src/test/java/art/arcane/volmlib/nativelib/minecraft26_2/forge/NativeForgeBiomeDefinitionTest.java new file mode 100644 index 000000000..d2273b95c --- /dev/null +++ b/adapters/forge/src/test/java/art/arcane/volmlib/nativelib/minecraft26_2/forge/NativeForgeBiomeDefinitionTest.java @@ -0,0 +1,100 @@ +package art.arcane.volmlib.nativelib.minecraft26_2.forge; + +import art.arcane.volmlib.nativelib.minecraft26_2.terrain.NativeRegistryDefinitions; +import art.arcane.volmlib.nativelib.modded.NativeLoaderOptions; +import com.google.gson.JsonParser; +import com.mojang.serialization.JsonOps; +import com.mojang.serialization.Lifecycle; +import com.mojang.serialization.MapCodec; +import net.minecraft.SharedConstants; +import net.minecraft.core.Holder; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.RegistrationInfo; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.RegistryOps; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.Bootstrap; +import net.minecraft.world.attribute.EnvironmentAttributes; +import net.minecraft.world.attribute.modifier.MobSpawnSettingsModifier; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.carver.WorldCarver; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; +import net.minecraftforge.common.world.BiomeModifier; +import net.minecraftforge.common.world.ModifiableBiomeInfo; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; +import java.util.function.BooleanSupplier; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +public class NativeForgeBiomeDefinitionTest { + private static final String BIOME_REGISTRY = "minecraft:worldgen/biome"; + private static final String BIOME_KEY = "iris:biomes/forge_modified"; + private static final String SOURCE_JSON = "{\"has_precipitation\":true,\"temperature\":0.8,\"downfall\":0.4," + + "\"effects\":{\"water_color\":\"#3f76e4\"},\"carvers\":[],\"features\":[]}"; + + @BeforeClass + public static void bootstrap() { + SharedConstants.tryDetectVersion(); + Bootstrap.bootStrap(); + } + + @Test + public void generatedBiomeDefinitionExcludesForgeBiomeModifierOutput() { + MappedRegistry features = new MappedRegistry<>(Registries.PLACED_FEATURE, Lifecycle.stable()); + Holder.Reference ore = features.register( + ResourceKey.create(Registries.PLACED_FEATURE, Identifier.parse("iris:modded_ore")), + new PlacedFeature(Holder.direct(mock(Feature.class)), List.of()), + RegistrationInfo.BUILT_IN); + features.freeze(); + MappedRegistry carvers = new MappedRegistry<>(Registries.CARVER, Lifecycle.stable()); + carvers.freeze(); + MappedRegistry biomes = new MappedRegistry<>(Registries.BIOME, Lifecycle.stable()); + RegistryAccess access = new RegistryAccess.ImmutableRegistryAccess(List.of(biomes, features, carvers)); + Biome source = Biome.DIRECT_CODEC.parse(RegistryOps.create(JsonOps.INSTANCE, access), + JsonParser.parseString(SOURCE_JSON)).getOrThrow(); + Holder.Reference biome = biomes.register( + ResourceKey.create(Registries.BIOME, Identifier.parse(BIOME_KEY)), source, RegistrationInfo.BUILT_IN); + biomes.freeze(); + biome.value().modifiableBiomeInfo().applyBiomeModifiers(biome, List.of(new ModdedContent(ore))); + NativeRegistryDefinitions definitions = new NativeRegistryDefinitions(() -> access, + new NativeForgeLoader(new NativeLoaderOptions("irisworldgen", "treefeller", + BooleanSupplier::getAsBoolean))::unmodifiedBiome); + + assertEquals(0.1F, biome.value().getBaseTemperature(), 0.0F); + assertEquals(0x102030, biome.value().getWaterColor() & 0xFFFFFF); + assertTrue(biome.value().getGenerationSettings().hasFeature(ore.value())); + assertTrue(biome.value().getAttributes().contains(EnvironmentAttributes.NATURAL_MOB_SPAWNS)); + assertEquals(JsonParser.parseString(definitions.canonicalDefinition(BIOME_REGISTRY, BIOME_KEY, SOURCE_JSON).value()), + JsonParser.parseString(definitions.generatedDefinition(BIOME_REGISTRY, BIOME_KEY).value())); + } + + private record ModdedContent(Holder ore) implements BiomeModifier { + @Override + public void modify(Holder biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) { + if (phase != Phase.ADD) { + return; + } + builder.climateSettings().setTemperature(0.1F); + builder.effects().waterColor(0x102030); + builder.attributes().modify(EnvironmentAttributes.NATURAL_MOB_SPAWNS, MobSpawnSettingsModifier.overlay(), + new MobSpawnSettings.Builder().addSpawn(EntityTypes.ZOMBIE, 5, 1, 2).build()); + builder.generationSettings().addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, ore); + } + + @Override + public MapCodec codec() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedPlatform.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedPlatform.java index 24309bd2d..be4de0d5e 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedPlatform.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/ModdedPlatform.java @@ -61,7 +61,7 @@ public final class ModdedPlatform implements IrisPlatform { this.loader = loader; this.registries = new ModdedRegistries( NativeModdedServer.registryAccess(ModdedEngineBootstrap::currentServer, ModdedRegistries::warnNotReady), - ModdedPlatform::generationRegistry); + () -> generationRegistry(loader)); this.scheduler = new ModdedScheduler(); this.structureHooks = new ModdedStructureHooks(ModdedEngineBootstrap::currentServer); this.biomeWriter = new ModdedBiomeWriter(new NativeBiomeRegistry(ModdedEngineBootstrap::currentServer, "minecraft:plains")); @@ -352,11 +352,11 @@ public final class ModdedPlatform implements IrisPlatform { } } - private static PlatformGenerationRegistry generationRegistry() { + private static PlatformGenerationRegistry generationRegistry(NativeModdedLoader loader) { if (ModdedEngineBootstrap.currentServer() == null) { throw new IllegalStateException("Minecraft server is not ready for generation registry capture."); } - return new ModdedGenerationRegistry(NativeModdedServer.registryDefinitions(ModdedEngineBootstrap::currentServer), + return new ModdedGenerationRegistry(NativeModdedServer.registryDefinitions(ModdedEngineBootstrap::currentServer, loader), "modded-generation-registry-v1"); } diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedPlatformPathsTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedPlatformPathsTest.java index c46775ab3..8fc4445a9 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedPlatformPathsTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedPlatformPathsTest.java @@ -12,6 +12,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.Mob; import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.state.BlockState; import org.junit.Rule; import org.junit.Test; @@ -91,6 +92,11 @@ public class ModdedPlatformPathsTest { public boolean checkSpawnPosition(Mob mob, ServerLevelAccessor level, EntitySpawnReason reason) { return false; } + + @Override + public Biome unmodifiedBiome(Biome biome) { + return biome; + } }); }