diff --git a/adapters/bukkit/nms/v26_2_R1/src/main/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSource.java b/adapters/bukkit/nms/v26_2_R1/src/main/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSource.java index 630910985..43d6dad87 100644 --- a/adapters/bukkit/nms/v26_2_R1/src/main/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSource.java +++ b/adapters/bukkit/nms/v26_2_R1/src/main/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSource.java @@ -1,6 +1,7 @@ package art.arcane.iris.core.nms.v26_2_R1; import art.arcane.iris.platform.bukkit.BukkitWorldBinding; +import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.engine.data.cache.AtomicCache; @@ -13,6 +14,7 @@ import art.arcane.iris.engine.object.IrisDimension; import art.arcane.iris.util.project.context.IrisContext; import art.arcane.volmlib.util.collection.KMap; import art.arcane.volmlib.util.math.RNG; +import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.QuartPos; import net.minecraft.core.Registry; @@ -20,6 +22,7 @@ import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.Climate; @@ -40,10 +43,14 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Stream; public class CustomBiomeSource extends BiomeSource { private static final int NOISE_BIOME_CACHE_MAX = 262144; + private static final int STRONGHOLD_RING_SEARCH_Y = 0; + private static final int STRONGHOLD_RING_SEARCH_RADIUS = 112; + private static final int STRONGHOLD_RING_SEARCH_QUART_STEP = 4; private final long seed; private final Engine engine; @@ -309,6 +316,30 @@ public class CustomBiomeSource extends BiomeSource { } } + @Override + public Pair> findBiomeHorizontal( + int x, + int y, + int z, + int searchRadius, + Predicate> allowed, + RandomSource random, + Climate.Sampler sampler + ) { + int quartStep = horizontalBiomeSearchQuartStep(y, searchRadius); + if (quartStep == 1) { + return super.findBiomeHorizontal(x, y, z, searchRadius, allowed, random, sampler); + } + return super.findBiomeHorizontal( + x, y, z, searchRadius, quartStep, allowed, random, false, sampler); + } + + static int horizontalBiomeSearchQuartStep(int blockY, int searchRadius) { + return blockY == STRONGHOLD_RING_SEARCH_Y && searchRadius == STRONGHOLD_RING_SEARCH_RADIUS + ? STRONGHOLD_RING_SEARCH_QUART_STEP + : 1; + } + @Override public Set> getBiomesWithin(int x, int y, int z, int radius, Climate.Sampler sampler) { GenerationSessionLease lease = tryAcquireGenerationLease("bukkit_biomes_within"); diff --git a/adapters/bukkit/nms/v26_2_R1/src/test/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSourceStructureContractTest.java b/adapters/bukkit/nms/v26_2_R1/src/test/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSourceStructureContractTest.java index 8c4d17d88..76fb17d62 100644 --- a/adapters/bukkit/nms/v26_2_R1/src/test/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSourceStructureContractTest.java +++ b/adapters/bukkit/nms/v26_2_R1/src/test/java/art/arcane/iris/core/nms/v26_2_R1/CustomBiomeSourceStructureContractTest.java @@ -37,4 +37,16 @@ public class CustomBiomeSourceStructureContractTest { assertTrue(source.contains("catch (GenerationSessionException e)")); assertTrue(source.contains("e.isExpectedTeardown()")); } + + @Test + public void strongholdRingSearchSamplesOneQuartColumnPerChunk() throws IOException { + String source = Files.readString(Path.of(System.getProperty("iris.customBiomeSource"))); + + assertTrue(source.contains("private static final int STRONGHOLD_RING_SEARCH_Y = 0")); + assertTrue(source.contains("private static final int STRONGHOLD_RING_SEARCH_RADIUS = 112")); + assertTrue(source.contains("private static final int STRONGHOLD_RING_SEARCH_QUART_STEP = 4")); + assertTrue(source.contains("x, y, z, searchRadius, quartStep, allowed, random, false, sampler")); + assertTrue(source.contains( + "return super.findBiomeHorizontal(x, y, z, searchRadius, allowed, random, sampler)")); + } } diff --git a/adapters/modded-common/src/main/java/art/arcane/iris/modded/IrisModdedBiomeSource.java b/adapters/modded-common/src/main/java/art/arcane/iris/modded/IrisModdedBiomeSource.java index dc51dac6a..de3e09a03 100644 --- a/adapters/modded-common/src/main/java/art/arcane/iris/modded/IrisModdedBiomeSource.java +++ b/adapters/modded-common/src/main/java/art/arcane/iris/modded/IrisModdedBiomeSource.java @@ -25,7 +25,9 @@ import art.arcane.iris.engine.object.IrisBiome; import art.arcane.iris.engine.object.IrisBiomeCustom; import art.arcane.iris.util.project.context.IrisContext; import art.arcane.volmlib.util.math.RNG; +import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; import net.minecraft.core.QuartPos; @@ -34,6 +36,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.resources.Identifier; import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.Climate; @@ -49,10 +52,14 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.function.Predicate; import java.util.stream.Stream; final class IrisModdedBiomeSource extends BiomeSource { private static final int UNRESOLVED_WARN_KEYS_MAX = 256; + private static final int STRONGHOLD_RING_SEARCH_Y = 0; + private static final int STRONGHOLD_RING_SEARCH_RADIUS = 112; + private static final int STRONGHOLD_RING_SEARCH_QUART_STEP = 4; private final BiomeSource serializedSource; private final Set warnedUnresolvedBiomeKeys = ConcurrentHashMap.newKeySet(); @@ -554,6 +561,12 @@ final class IrisModdedBiomeSource extends BiomeSource { return radius == 29 && blockY == minHeight + fluidHeight; } + static int horizontalBiomeSearchQuartStep(int blockY, int searchRadius) { + return blockY == STRONGHOLD_RING_SEARCH_Y && searchRadius == STRONGHOLD_RING_SEARCH_RADIUS + ? STRONGHOLD_RING_SEARCH_QUART_STEP + : 1; + } + private static boolean isReady(Engine engine) { return engine != null && !engine.isClosed() && engine.getComplex() != null; } @@ -861,6 +874,24 @@ final class IrisModdedBiomeSource extends BiomeSource { return resolved; } + @Override + public Pair> findBiomeHorizontal( + int x, + int y, + int z, + int searchRadius, + Predicate> allowed, + RandomSource random, + Climate.Sampler sampler + ) { + int quartStep = horizontalBiomeSearchQuartStep(y, searchRadius); + if (quartStep == 1) { + return super.findBiomeHorizontal(x, y, z, searchRadius, allowed, random, sampler); + } + return super.findBiomeHorizontal( + x, y, z, searchRadius, quartStep, allowed, random, false, sampler); + } + @Override public Set> getBiomesWithin(int x, int y, int z, int radius, Climate.Sampler sampler) { return super.getBiomesWithin(x, y, z, radius, sampler); diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java index 4e6b92975..6cf161e4a 100644 --- a/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/IrisModdedStructureParityTest.java @@ -13,6 +13,9 @@ import net.minecraft.server.Bootstrap; import org.junit.BeforeClass; import org.junit.Test; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -56,6 +59,19 @@ public class IrisModdedStructureParityTest { assertFalse(IrisModdedBiomeSource.isMonumentSurfaceBiomeQuery(50, 28, -256, 306)); } + @Test + public void strongholdRingSearchSamplesOneQuartColumnPerChunk() throws IOException { + assertEquals(4, IrisModdedBiomeSource.horizontalBiomeSearchQuartStep(0, 112)); + assertEquals(1, IrisModdedBiomeSource.horizontalBiomeSearchQuartStep(1, 112)); + assertEquals(1, IrisModdedBiomeSource.horizontalBiomeSearchQuartStep(0, 111)); + String source = Files.readString(Path.of( + System.getProperty("iris.moddedCommonSources"), + "art/arcane/iris/modded/IrisModdedBiomeSource.java")); + assertTrue(source.contains("x, y, z, searchRadius, quartStep, allowed, random, false, sampler")); + assertTrue(source.contains( + "return super.findBiomeHorizontal(x, y, z, searchRadius, allowed, random, sampler)")); + } + @Test public void spawnHeightMatchesPaperFixedSpawnClamp() { assertEquals(96, ModdedDimensionMetadata.clampSpawnHeight(-64, 384));