Mapgen caves: Re-order generation to fix cavern bug
authorParamat <paramat@users.noreply.github.com>
Sun, 29 Apr 2018 06:20:46 +0000 (07:20 +0100)
committerGitHub <noreply@github.com>
Sun, 29 Apr 2018 06:20:46 +0000 (07:20 +0100)
Previously, caverns confused tunnel generation causing biome top and filler
nodes to appear in caverns.
Split 'generateCaves()' into 2 functions to separate tunnel and large
randomwalk cave generation.
In each mapgen re-order cave generation to generate tunnels before caverns.

src/mapgen/mapgen.cpp
src/mapgen/mapgen.h
src/mapgen/mapgen_carpathian.cpp
src/mapgen/mapgen_flat.cpp
src/mapgen/mapgen_fractal.cpp
src/mapgen/mapgen_v5.cpp
src/mapgen/mapgen_v7.cpp
src/mapgen/mapgen_valleys.cpp

index 9aaead79d23c36b5b57f2647be19e5614ca41cad..eb562e76902a49359197c5d939a52b312e79d608 100644 (file)
@@ -824,21 +824,26 @@ void MapgenBasic::dustTopNodes()
 }
 
 
-void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth)
+void MapgenBasic::generateCavesNoiseIntersection(s16 max_stone_y)
 {
-       if (max_stone_y < node_min.Y)
+       if (node_min.Y > max_stone_y)
                return;
 
        CavesNoiseIntersection caves_noise(ndef, m_bmgr, csize,
                &np_cave1, &np_cave2, seed, cave_width);
 
        caves_noise.generateCaves(vm, node_min, node_max, biomemap);
+}
+
 
-       if (node_max.Y > large_cave_depth)
+void MapgenBasic::generateCavesRandomWalk(s16 max_stone_y, s16 large_cave_depth)
+{
+       if (node_min.Y > max_stone_y || node_max.Y > large_cave_depth)
                return;
 
        PseudoRandom ps(blockseed + 21343);
        u32 bruises_count = ps.range(0, 2);
+
        for (u32 i = 0; i < bruises_count; i++) {
                CavesRandomWalk cave(ndef, &gennotify, seed, water_level,
                        c_water_source, c_lava_source, lava_depth, biomegen);
@@ -849,7 +854,7 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth)
 }
 
 
-bool MapgenBasic::generateCaverns(s16 max_stone_y)
+bool MapgenBasic::generateCavernsNoise(s16 max_stone_y)
 {
        if (node_min.Y > max_stone_y || node_min.Y > cavern_limit)
                return false;
index 51d23cd28a8cde12c714547f31b08afb8e6ffb1c..abac79016ab9f8084ecfbf3fd864dabc84cefd17 100644 (file)
@@ -238,11 +238,12 @@ public:
        MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge);
        virtual ~MapgenBasic();
 
-       virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth);
-       virtual bool generateCaverns(s16 max_stone_y);
-       virtual void generateDungeons(s16 max_stone_y);
        virtual void generateBiomes();
        virtual void dustTopNodes();
+       virtual void generateCavesNoiseIntersection(s16 max_stone_y);
+       virtual void generateCavesRandomWalk(s16 max_stone_y, s16 large_cave_depth);
+       virtual bool generateCavernsNoise(s16 max_stone_y);
+       virtual void generateDungeons(s16 max_stone_y);
 
 protected:
        EmergeManager *m_emerge;
index 37c769693ba3f341cdd83e1b479714207736db75..4347f84793d62397ff9d54fc8ebb216f476ffbe6 100644 (file)
@@ -250,20 +250,25 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data)
        biomegen->calcBiomeNoise(node_min);
        generateBiomes();
 
-       // Generate caverns, tunnels and classic caves
+       // Generate tunnels, caverns and large randomwalk caves
        if (flags & MG_CAVES) {
-               bool has_cavern = false;
+               // Generate tunnels first as caverns confuse them
+               generateCavesNoiseIntersection(stone_surface_max_y);
+
                // Generate caverns
+               bool near_cavern = false;
                if (spflags & MGCARPATHIAN_CAVERNS)
-                       has_cavern = generateCaverns(stone_surface_max_y);
-               // Generate tunnels and classic caves
-               if (has_cavern)
-                       // Disable classic caves in this mapchunk by setting
+                       near_cavern = generateCavernsNoise(stone_surface_max_y);
+
+               // Generate large randomwalk caves
+               if (near_cavern)
+                       // Disable large randomwalk caves in this mapchunk by setting
                        // 'large cave depth' to world base. Avoids excessive liquid in
                        // large caverns and floating blobs of overgenerated liquid.
-                       generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
+                       generateCavesRandomWalk(stone_surface_max_y,
+                               -MAX_MAP_GENERATION_LIMIT);
                else
-                       generateCaves(stone_surface_max_y, large_cave_depth);
+                       generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
        }
 
        // Generate dungeons
index 60b30137b9763acce55238c4b23cc16f6fdb6ee6..dbe0bd5bbc7369145fb0bdc726153ebbd0c02db9 100644 (file)
@@ -198,8 +198,12 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
        biomegen->calcBiomeNoise(node_min);
        generateBiomes();
 
-       if (flags & MG_CAVES)
-               generateCaves(stone_surface_max_y, large_cave_depth);
+       if (flags & MG_CAVES) {
+               // Generate tunnels
+               generateCavesNoiseIntersection(stone_surface_max_y);
+               // Generate large randomwalk caves
+               generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
+       }
 
        if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
                        full_node_max.Y <= dungeon_ymax)
index 10397f7b824f1da5b4cbe33541cc5e2c68a016f0..a1d425cd08b69ae1b2a1ba6a1ec60f218033a936 100644 (file)
@@ -209,8 +209,12 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
        biomegen->calcBiomeNoise(node_min);
        generateBiomes();
 
-       if (flags & MG_CAVES)
-               generateCaves(stone_surface_max_y, large_cave_depth);
+       if (flags & MG_CAVES) {
+               // Generate tunnels
+               generateCavesNoiseIntersection(stone_surface_max_y);
+               // Generate large randomwalk caves
+               generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
+       }
 
        if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
                        full_node_max.Y <= dungeon_ymax)
index aabc86c4d7c6b89d48aae452ab9e1cb0101888d8..fc0970363a27e52e7ad839c6482ac968c072e426 100644 (file)
@@ -209,20 +209,25 @@ void MapgenV5::makeChunk(BlockMakeData *data)
        biomegen->calcBiomeNoise(node_min);
        generateBiomes();
 
-       // Generate caverns, tunnels and classic caves
+       // Generate tunnels, caverns and large randomwalk caves
        if (flags & MG_CAVES) {
-               bool near_cavern = false;
+               // Generate tunnels first as caverns confuse them
+               generateCavesNoiseIntersection(stone_surface_max_y);
+
                // Generate caverns
+               bool near_cavern = false;
                if (spflags & MGV5_CAVERNS)
-                       near_cavern = generateCaverns(stone_surface_max_y);
-               // Generate tunnels and classic caves
+                       near_cavern = generateCavernsNoise(stone_surface_max_y);
+
+               // Generate large randomwalk caves
                if (near_cavern)
-                       // Disable classic caves in this mapchunk by setting
+                       // Disable large randomwalk caves in this mapchunk by setting
                        // 'large cave depth' to world base. Avoids excessive liquid in
                        // large caverns and floating blobs of overgenerated liquid.
-                       generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
+                       generateCavesRandomWalk(stone_surface_max_y,
+                               -MAX_MAP_GENERATION_LIMIT);
                else
-                       generateCaves(stone_surface_max_y, large_cave_depth);
+                       generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
        }
 
        // Generate dungeons and desert temples
index c83a5105dcd42ed20d7298f8cec5ec6d93656360..23e8dbdd2bd3f3cf022f5388af94a9796b2ff507 100644 (file)
@@ -313,20 +313,25 @@ void MapgenV7::makeChunk(BlockMakeData *data)
        biomegen->calcBiomeNoise(node_min);
        generateBiomes();
 
-       // Generate caverns, tunnels and classic caves
+       // Generate tunnels, caverns and large randomwalk caves
        if (flags & MG_CAVES) {
-               bool near_cavern = false;
+               // Generate tunnels first as caverns confuse them
+               generateCavesNoiseIntersection(stone_surface_max_y);
+
                // Generate caverns
+               bool near_cavern = false;
                if (spflags & MGV7_CAVERNS)
-                       near_cavern = generateCaverns(stone_surface_max_y);
-               // Generate tunnels and classic caves
+                       near_cavern = generateCavernsNoise(stone_surface_max_y);
+
+               // Generate large randomwalk caves
                if (near_cavern)
-                       // Disable classic caves in this mapchunk by setting
+                       // Disable large randomwalk caves in this mapchunk by setting
                        // 'large cave depth' to world base. Avoids excessive liquid in
                        // large caverns and floating blobs of overgenerated liquid.
-                       generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
+                       generateCavesRandomWalk(stone_surface_max_y,
+                               -MAX_MAP_GENERATION_LIMIT);
                else
-                       generateCaves(stone_surface_max_y, large_cave_depth);
+                       generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
        }
 
        // Generate dungeons
index 72f47880315eff6fd8ccfc65a672389814f0aeda..843acb69034fdcbf80c8953fe191547823c462fa 100644 (file)
@@ -233,18 +233,23 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
        // Place biome-specific nodes and build biomemap
        generateBiomes();
 
-       // Generate caverns, tunnels and classic caves
+       // Generate tunnels, caverns and large randomwalk caves
        if (flags & MG_CAVES) {
+               // Generate tunnels first as caverns confuse them
+               generateCavesNoiseIntersection(stone_surface_max_y);
+
                // Generate caverns
-               bool near_cavern = generateCaverns(stone_surface_max_y);
-               // Generate tunnels and classic caves
+               bool near_cavern = generateCavernsNoise(stone_surface_max_y);
+
+               // Generate large randomwalk caves
                if (near_cavern)
-                       // Disable classic caves in this mapchunk by setting
+                       // Disable large randomwalk caves in this mapchunk by setting
                        // 'large cave depth' to world base. Avoids excessive liquid in
                        // large caverns and floating blobs of overgenerated liquid.
-                       generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT);
+                       generateCavesRandomWalk(stone_surface_max_y,
+                               -MAX_MAP_GENERATION_LIMIT);
                else
-                       generateCaves(stone_surface_max_y, large_cave_depth);
+                       generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
        }
 
        // Dungeon creation