diff --git a/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java b/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java index ffccce3ab..8be2cf179 100644 --- a/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java +++ b/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java @@ -537,6 +537,14 @@ public final class HydrologyTileCache implements AutoCloseable { chunkColumns(blockX, blockZ); } + /** + * Every column of the block's chunk, indexed {@code localZ * 16 + localX}; a column without hydrology + * is null. The array is shared with the cache and must not be modified. + */ + public HydrologyColumnSample[] chunkSamples(int blockX, int blockZ) { + return chunkColumns(blockX, blockZ).columns(); + } + /** * Whether the column's chunk can be answered without planning: every tile it composes from is * already planned. A caller that must not wait (the server thread answering a height or biome diff --git a/core/src/main/java/art/arcane/iris/generation/hydrology/runtime/IrisHydrologyRuntime.java b/core/src/main/java/art/arcane/iris/generation/hydrology/runtime/IrisHydrologyRuntime.java index 2cff804f9..789b63b75 100644 --- a/core/src/main/java/art/arcane/iris/generation/hydrology/runtime/IrisHydrologyRuntime.java +++ b/core/src/main/java/art/arcane/iris/generation/hydrology/runtime/IrisHydrologyRuntime.java @@ -195,6 +195,11 @@ public final class IrisHydrologyRuntime implements AutoCloseable { cache.prepareChunkColumns(blockX, blockZ); } + /** The block's chunk columns indexed {@code localZ * 16 + localX}; shared, never modified by callers. */ + public HydrologyColumnSample[] chunkSamples(int blockX, int blockZ) { + return cache.chunkSamples(blockX, blockZ); + } + /** Whether the chunk or one of its eight neighbours holds a planned footprint column. */ public boolean hasColumnsAround(int chunkX, int chunkZ) { return cache.hasColumnsAround(chunkX, chunkZ); diff --git a/core/src/main/java/art/arcane/iris/generation/runtime/IrisComplex.java b/core/src/main/java/art/arcane/iris/generation/runtime/IrisComplex.java index 4c04aa714..286bf2a19 100644 --- a/core/src/main/java/art/arcane/iris/generation/runtime/IrisComplex.java +++ b/core/src/main/java/art/arcane/iris/generation/runtime/IrisComplex.java @@ -1062,6 +1062,31 @@ public class IrisComplex implements DataProvider { return transitionHydrologySample(sample, hydrologyWeight, transitionDisplacement); } + /** + * The raw hydrology columns of the chunk holding the block, for a caller that samples every column of + * one chunk through {@link #sampleHydrologyColumn(HydrologyColumnSample[], int, int)}; null without + * hydrology. + */ + public HydrologyColumnSample[] hydrologyChunkSamples(int x, int z) { + return hydrologyRuntime == null ? null : hydrologyRuntime.chunkSamples(x, z); + } + + /** {@link #sampleHydrologyColumn(double, double)} for a column of the chunk {@code chunkSamples} came from. */ + public HydrologyColumnSample sampleHydrologyColumn(HydrologyColumnSample[] chunkSamples, int x, int z) { + if (chunkSamples == null) { + return null; + } + HydrologyColumnSample sample = chunkSamples[(z & 15) << 4 | (x & 15)]; + if (transitionGenerationPlan == null) { + return sample; + } + double hydrologyWeight = transitionHydrologyWeight(x, z); + if (sample == null) { + return sample; + } + return transitionHydrologySample(sample, hydrologyWeight, transitionDisplacement); + } + private HydrologyColumnSnapshot sampleHydrologySnapshot(int x, int z) { if (hydrologyRuntime == null) { return HydrologyColumnSnapshot.ready(null); diff --git a/core/src/main/java/art/arcane/iris/generation/stage/IrisTerrainNormalActuator.java b/core/src/main/java/art/arcane/iris/generation/stage/IrisTerrainNormalActuator.java index 9e5bf6754..7da845d0d 100644 --- a/core/src/main/java/art/arcane/iris/generation/stage/IrisTerrainNormalActuator.java +++ b/core/src/main/java/art/arcane/iris/generation/stage/IrisTerrainNormalActuator.java @@ -154,6 +154,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator riverWaterSurfaceStream; + private final HydrologyColumnSample[] hydrologySamples; private final boolean bedrockEnabled; private final boolean hideOres; private final boolean transitionDisplaced; @@ -186,6 +187,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator 0); + } + @Test public void singleColumnContributionReusesItsImmutableSample() { HydrologyColumnSample sample = compositionSample(90, List.of(compositionLayer(11L, 80)));