diff --git a/core/src/main/java/art/arcane/iris/generation/stage/IrisCarveModifier.java b/core/src/main/java/art/arcane/iris/generation/stage/IrisCarveModifier.java index 97a1f2ec9..bc0d71c76 100644 --- a/core/src/main/java/art/arcane/iris/generation/stage/IrisCarveModifier.java +++ b/core/src/main/java/art/arcane/iris/generation/stage/IrisCarveModifier.java @@ -971,6 +971,7 @@ public class IrisCarveModifier extends EngineAssignedModifier } } CaveInputs resolver = CaveInputs.forContentChunk(getEngine(), blockX >> 4, blockZ >> 4); + boolean caveFloorMarkers = getDimension().hasUndergroundSpawners(getEngine()); Long2ObjectOpenHashMap caveBiomes = new Long2ObjectOpenHashMap<>(256); Map customBiomes = new HashMap<>(); int width = output.getWidth(); @@ -993,13 +994,11 @@ public class IrisCarveModifier extends EngineAssignedModifier CaveZone zone = new CaveZone(); zone.setFloor(floor); zone.setCeiling(y - 1); - if (zone.isValid(resolver.height) - && (subterrainCell(worldX, floor, worldZ).occupied() + SubterrainCell floorCell = zone.isValid(resolver.height) + ? subterrainCell(worldX, floor, worldZ) : null; + if (floorCell != null && (floorCell.occupied() || !isNaturalTerrainOpening(getComplex(), worldX, floor, worldZ, context))) { - if (markerRoll(worldX, zone.ceiling, worldZ, 0x9E3779B97F4A7C15L)) { - mantle.set(worldX, zone.ceiling, worldZ, MarkerMatter.CAVE_CEILING); - } - if (markerRoll(worldX, zone.floor, worldZ, 0xC2B2AE3D27D4EB4FL)) { + if (caveFloorMarkers && markerRoll(worldX, zone.floor, worldZ, 0xC2B2AE3D27D4EB4FL)) { mantle.set(worldX, zone.floor, worldZ, MarkerMatter.CAVE_FLOOR); } IrisBiome floorBiome = resolveCaveBoundaryBiome(terrain, localX, floor, localZ, @@ -1007,7 +1006,7 @@ public class IrisCarveModifier extends EngineAssignedModifier IrisBiome ceilingBiome = resolveCaveBoundaryBiome(terrain, localX, y - 1, localZ, worldX, worldZ, resolver, caveBiomes, customBiomes); decorateZone(output, zone, localX, localZ, worldX, worldZ, - floorBiome, ceilingBiome); + floorBiome, ceilingBiome, floorCell); if (extent != null) { top = extent.highestStoredY(localX, localZ); } @@ -1023,9 +1022,8 @@ public class IrisCarveModifier extends EngineAssignedModifier restoreSubterrainSolids(output, blockX >> 4, blockZ >> 4, true); } - private void decorateZone(Hunk output, CaveZone zone, - int rx, int rz, int xx, int zz, IrisBiome floorBiome, IrisBiome ceilingBiome) { - SubterrainCell feature = subterrainCell(xx, zone.getFloor(), zz); + private void decorateZone(Hunk output, CaveZone zone, int rx, int rz, int xx, int zz, + IrisBiome floorBiome, IrisBiome ceilingBiome, SubterrainCell feature) { boolean reservedPassage = feature.owned() && feature.room().reservedPassage(); int maxY = output.getHeight(); IrisDecorator[] surfaceDecorators = floorBiome == null diff --git a/core/src/test/java/art/arcane/iris/generation/stage/IrisNaturalCaveScanTest.java b/core/src/test/java/art/arcane/iris/generation/stage/IrisNaturalCaveScanTest.java index b09d8dc85..34e934a63 100644 --- a/core/src/test/java/art/arcane/iris/generation/stage/IrisNaturalCaveScanTest.java +++ b/core/src/test/java/art/arcane/iris/generation/stage/IrisNaturalCaveScanTest.java @@ -7,6 +7,7 @@ import art.arcane.iris.generation.decoration.IrisCeilingDecorator; import art.arcane.iris.generation.decoration.IrisSurfaceDecorator; import art.arcane.iris.generation.runtime.Engine; import art.arcane.iris.generation.runtime.SeedManager; +import art.arcane.iris.generation.terrain.IrisDimension; import art.arcane.iris.generation.terrain.transform.TerrainTransformRuntime; import art.arcane.iris.generation.terrain.Terrain3DColumn; import art.arcane.iris.generation.context.ChunkContext; @@ -72,12 +73,17 @@ public class IrisNaturalCaveScanTest { @Test public void narrowScanPreservesDecoratedBlocksMarkersAndMutationOrder() throws Exception { - verifyScan(5, 3); + verifyScan(5, 3, true); } @Test public void chunkScanPreservesDecoratedBlocksMarkersAndMutationOrder() throws Exception { - verifyScan(16, 16); + verifyScan(16, 16, true); + } + + @Test + public void scanWithoutCaveSpawnersWritesNoCaveMarkers() throws Exception { + verifyScan(16, 16, false); } @Test @@ -277,8 +283,8 @@ public class IrisNaturalCaveScanTest { assertEquals(List.of("floor:0:0:3:3", "ceiling:0:0:8:3"), fixture.calls); } - private static void verifyScan(int width, int depth) throws Exception { - Fixture fixture = new Fixture(); + private static void verifyScan(int width, int depth, boolean caveSpawners) throws Exception { + Fixture fixture = new Fixture(false, caveSpawners); Hunk output = fixture.output(width, depth); List writes = new ArrayList<>(); fixture.modifier.decorateNaturalCaves(-32, 48, @@ -302,10 +308,8 @@ public class IrisNaturalCaveScanTest { } } expectedWrites.add(x + ":" + ceiling + ":" + z + ":minecraft:calcite"); - if ((boolean) markerRoll.invoke(fixture.modifier, x - 32, ceiling, z + 48, 0x9E3779B97F4A7C15L)) { - expectedMarkers.add((x - 32) + ":" + ceiling + ":" + (z + 48) + ":" + MarkerMatter.CAVE_CEILING); - } - if ((boolean) markerRoll.invoke(fixture.modifier, x - 32, floor, z + 48, 0xC2B2AE3D27D4EB4FL)) { + if (caveSpawners + && (boolean) markerRoll.invoke(fixture.modifier, x - 32, floor, z + 48, 0xC2B2AE3D27D4EB4FL)) { expectedMarkers.add((x - 32) + ":" + floor + ":" + (z + 48) + ":" + MarkerMatter.CAVE_FLOOR); } } @@ -327,7 +331,7 @@ public class IrisNaturalCaveScanTest { assertEquals(expectedCalls, fixture.calls); assertEquals(expectedWrites, writes); assertEquals(expectedMarkers, fixture.markers); - assertTrue("fixture must exercise marker writes", !expectedMarkers.isEmpty()); + assertEquals("fixture must exercise marker writes", caveSpawners, !expectedMarkers.isEmpty()); verify(fixture.mantle).useChunk(-2, 3); verify(fixture.chunk).release(); } @@ -361,9 +365,16 @@ public class IrisNaturalCaveScanTest { this(false); } - @SuppressWarnings("unchecked") private Fixture(boolean buildAboveTop) throws Exception { + this(buildAboveTop, true); + } + + @SuppressWarnings("unchecked") + private Fixture(boolean buildAboveTop, boolean caveSpawners) throws Exception { Engine engine = mock(Engine.class); + IrisDimension dimension = mock(IrisDimension.class); + doReturn(dimension).when(engine).getDimension(); + doReturn(caveSpawners).when(dimension).hasUndergroundSpawners(engine); EngineMantle engineMantle = mock(EngineMantle.class); mantle = mock(Mantle.class); chunk = mock(MantleChunk.class);