MgV5/6/7: Generate dungeons above water level
authorparamat <mat.gregory@virginmedia.com>
Wed, 31 Dec 2014 00:19:05 +0000 (00:19 +0000)
committerkwolekr <kwolekr@minetest.net>
Thu, 1 Jan 2015 20:44:26 +0000 (15:44 -0500)
Use/add stone_surface_max_y to speed-optimise/guide dungeon generation
MgV7: Don't let mountain terrain chop dungeons at mapchunk borders
Make mountain terrain update stone_surface_max_y for caves in mountains

src/dungeongen.cpp
src/mapgen_v5.cpp
src/mapgen_v5.h
src/mapgen_v6.cpp
src/mapgen_v7.cpp
src/mapgen_v7.h

index 7462c275e515c67bce7b3fdc578d1383575661ab..eb452a196a534e03c68ae398ca185af690bd1841 100644 (file)
@@ -70,10 +70,7 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams) {
 
 void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) {
        //TimeTaker t("gen dungeons");
-       int approx_groundlevel = 10 + mg->water_level;
-
-       if ((nmin.Y + nmax.Y) / 2 >= approx_groundlevel ||
-               NoisePerlin3D(&dp.np_rarity, nmin.X, nmin.Y, nmin.Z, mg->seed) < 0.2)
+       if (NoisePerlin3D(&dp.np_rarity, nmin.X, nmin.Y, nmin.Z, mg->seed) < 0.2)
                return;
 
        this->blockseed = bseed;
index 64879b0bbd0bc748fce8ab464ce311aeca7fd7aa..24c81e56d287d5ced796f394886c9cd23b0689b6 100644 (file)
@@ -252,7 +252,8 @@ void MapgenV5::makeChunk(BlockMakeData *data)
        calculateNoise();
 
        // Generate base terrain
-       generateBaseTerrain();
+       s16 stone_surface_max_y = generateBaseTerrain();
+
        updateHeightmap(node_min, node_max);
 
        // Generate underground dirt, sand, gravel and lava blobs
@@ -268,7 +269,7 @@ void MapgenV5::makeChunk(BlockMakeData *data)
        generateBiomes();
 
        // Generate dungeons and desert temples
-       if (flags & MG_DUNGEONS) {
+       if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
                DungeonGen dgen(this, NULL);
                dgen.generate(blockseed, full_node_min, full_node_max);
        }
@@ -342,10 +343,11 @@ void MapgenV5::calculateNoise()
 
 
 // Make base ground level
-void MapgenV5::generateBaseTerrain()
+int MapgenV5::generateBaseTerrain()
 {
        u32 index = 0;
        u32 index2d = 0;
+       int stone_surface_max_y = -MAP_GENERATION_LIMIT;
 
        for(s16 z=node_min.Z; z<=node_max.Z; z++) {
                for(s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
@@ -372,12 +374,16 @@ void MapgenV5::generateBaseTerrain()
                                        vm->m_data[i] = MapNode(CONTENT_AIR);
                                } else {
                                        vm->m_data[i] = MapNode(c_stone);
+                                       if (y > stone_surface_max_y)
+                                               stone_surface_max_y = y;
                                }
                        }
                        index2d = index2d - ystride;
                }
                index2d = index2d + ystride;
        }
+
+       return stone_surface_max_y;
 }
 
 
index 06be1ed5fae1f7ce4eb688bb7e2597471fbea587..18f0ffa03561a0d857faa0e353274a63786f5927 100644 (file)
@@ -94,7 +94,7 @@ public:
        virtual void makeChunk(BlockMakeData *data);
        int getGroundLevelAtPoint(v2s16 p);
        void calculateNoise();
-       void generateBaseTerrain();
+       int generateBaseTerrain();
        void generateBlobs();
        void generateBiomes();
        void dustTopNodes();
index 5c989a773a3999772ec8344eb3880627ded528e2..b9751253508322831aef9c9e885ec1b7d607fd09 100644 (file)
@@ -500,7 +500,7 @@ void MapgenV6::makeChunk(BlockMakeData *data)
        }
 
        // Add dungeons
-       if (flags & MG_DUNGEONS) {
+       if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
                DungeonParams dp;
 
                dp.np_rarity  = nparams_dungeon_rarity;
index d9e9280066e1768e9e530d048cd0b4a471480d5b..3b7c20b96dfa89515eb0a029659b018b259d0567 100644 (file)
@@ -241,7 +241,7 @@ void MapgenV7::makeChunk(BlockMakeData *data)
        if (flags & MG_CAVES)
                generateCaves(stone_surface_max_y);
 
-       if (flags & MG_DUNGEONS) {
+       if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
                DungeonGen dgen(this, NULL);
                dgen.generate(blockseed, full_node_min, full_node_max);
        }
@@ -405,7 +405,7 @@ int MapgenV7::generateTerrain()
        int ymax = generateBaseTerrain();
 
        if (spflags & MGV7_MOUNTAINS)
-               generateMountainTerrain();
+               ymax = generateMountainTerrain(ymax);
 
        if (spflags & MGV7_RIDGES)
                generateRidgeTerrain();
@@ -453,10 +453,10 @@ int MapgenV7::generateBaseTerrain()
 }
 
 
-void MapgenV7::generateMountainTerrain()
+int MapgenV7::generateMountainTerrain(int ymax)
 {
        if (node_max.Y <= water_level)
-               return;
+               return ymax;
 
        MapNode n_stone(c_stone);
        u32 j = 0;
@@ -466,14 +466,21 @@ void MapgenV7::generateMountainTerrain()
                u32 vi = vm->m_area.index(node_min.X, y, z);
                for (s16 x = node_min.X; x <= node_max.X; x++) {
                        int index = (z - node_min.Z) * csize.X + (x - node_min.X);
+                       content_t c = vm->m_data[vi].getContent();
 
-                       if (getMountainTerrainFromMap(j, index, y))
+                       if (getMountainTerrainFromMap(j, index, y)
+                                       && (c == CONTENT_AIR || c == c_water_source)) {
                                vm->m_data[vi] = n_stone;
+                               if (y > ymax)
+                                       ymax = y;
+                       }
 
                        vi++;
                        j++;
                }
        }
+
+       return ymax;
 }
 
 
index 7b08971bb8c69ec92d346b98025fcc22adac3f45..b297770d5a375cef9dbea5a2fd56a94fa17f1a5f 100644 (file)
@@ -107,7 +107,7 @@ public:
 
        virtual int generateTerrain();
        int generateBaseTerrain();
-       void generateMountainTerrain();
+       int generateMountainTerrain(int ymax);
        void generateRidgeTerrain();
 
        void generateBiomes();