Mapgen V7: Huge rewrite, also tweaks to cavegen et al.
authorkwolekr <kwolekr@minetest.net>
Sat, 6 Jul 2013 06:21:35 +0000 (02:21 -0400)
committerkwolekr <kwolekr@minetest.net>
Sat, 6 Jul 2013 06:21:54 +0000 (02:21 -0400)
12 files changed:
src/biome.cpp
src/biome.h
src/cavegen.cpp
src/cavegen.h
src/defaultsettings.cpp
src/mapgen.cpp
src/mapgen.h
src/mapgen_math.cpp
src/mapgen_math.h
src/mapgen_v7.cpp
src/mapgen_v7.h
src/script/lua_api/luaapi.cpp

index 356476b13de6adb2e51b41a4b23d6a26d8f9b303..19630019fc10728baacf004198998059bcf7396d 100644 (file)
@@ -43,9 +43,9 @@ BiomeDefManager::BiomeDefManager() {
        b->flags = 0;
 
        b->c_top         = CONTENT_AIR;
-       b->top_depth     = 0;
-       b->c_filler      = b->c_top;
-       b->filler_height = MAP_GENERATION_LIMIT;
+       b->depth_top     = 0;
+       b->c_filler      = CONTENT_AIR;
+       b->depth_filler  = 0;
 
        b->height_min     = -MAP_GENERATION_LIMIT;
        b->height_max     = MAP_GENERATION_LIMIT;
@@ -101,27 +101,42 @@ void BiomeDefManager::resolveNodeNames(INodeDefManager *ndef) {
        
        biome_registration_finished = true;
        
-       for (size_t i = 0; i != biomes.size(); i++) {
+       for (size_t i = 1; i < biomes.size(); i++) {
                b = biomes[i];
-               
+
+               b->c_top = ndef->getId(b->nname_top);
                if (b->c_top == CONTENT_IGNORE) {
-                       b->c_top = ndef->getId(b->top_nodename);
-                       if (b->c_top == CONTENT_IGNORE) {
-                               errorstream << "BiomeDefManager::resolveNodeNames: node '"
-                                       << b->top_nodename << "' not defined" << std::endl;
-                               b->c_top = CONTENT_AIR;
-                               b->top_depth = 0;
-                       }
+                       errorstream << "BiomeDefManager::resolveNodeNames: node '"
+                               << b->nname_top << "' not defined" << std::endl;
+                       b->c_top     = CONTENT_AIR;
+                       b->depth_top = 0;
                }
-               
+       
+               b->c_filler = ndef->getId(b->nname_filler);
                if (b->c_filler == CONTENT_IGNORE) {
-                       b->c_filler = ndef->getId(b->filler_nodename);
-                       if (b->c_filler == CONTENT_IGNORE) {
-                               errorstream << "BiomeDefManager::resolveNodeNames: node '"
-                                       << b->filler_nodename << "' not defined" << std::endl;
-                               b->c_filler = CONTENT_AIR;
-                               b->filler_height = MAP_GENERATION_LIMIT;
-                       }
+                       errorstream << "BiomeDefManager::resolveNodeNames: node '"
+                               << b->nname_filler << "' not defined" << std::endl;
+                       b->c_filler     = CONTENT_AIR;
+                       b->depth_filler = 0;
+               }
+               
+               b->c_water = ndef->getId(b->nname_water);
+               if (b->c_water == CONTENT_IGNORE) {
+                       errorstream << "BiomeDefManager::resolveNodeNames: node '"
+                               << b->nname_water << "' not defined" << std::endl;
+                       b->c_water = CONTENT_AIR;
+               }
+               
+               b->c_dust = ndef->getId(b->nname_dust);
+               if (b->c_dust == CONTENT_IGNORE) {
+                       errorstream << "BiomeDefManager::resolveNodeNames: node '"
+                               << b->nname_dust << "' not defined" << std::endl;
+               }
+               
+               b->c_dust_water = ndef->getId(b->nname_dust_water);
+               if (b->c_dust_water == CONTENT_IGNORE) {
+                       errorstream << "BiomeDefManager::resolveNodeNames: node '"
+                               << b->nname_dust_water << "' not defined" << std::endl;
                }
        }
 }
index 535dc498947c96a7ca9ec569bd6fc36d1cd6a630..cf3bd1b9f073affebf17ffbd7dd4937a3e7bb7ed 100644 (file)
@@ -45,14 +45,20 @@ public:
        std::string name;
        u32 flags;
        
-       std::string top_nodename;
-       std::string filler_nodename;
+       std::string nname_top;
+       std::string nname_filler;
+       std::string nname_water;
+       std::string nname_dust;
+       std::string nname_dust_water;
 
        content_t c_top;
-       s16 top_depth;
-
        content_t c_filler;
-       s16 filler_height;
+       content_t c_water;
+       content_t c_dust;
+       content_t c_dust_water;
+       
+       s16 depth_top;
+       s16 depth_filler;
        
        s16 height_min;
        s16 height_max;
index 01149084b0690625a6a1def9456e0930a0f59c14..51af5098421ef15c5d7d1f0d887471100709d256 100644 (file)
@@ -275,6 +275,7 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
        this->ps = ps;
        this->c_water_source = mg->c_water_source;
        this->c_lava_source  = mg->c_lava_source;
+       this->c_ice          = mg->c_ice;
        this->np_caveliquids = &nparams_caveliquids;
 
        dswitchint = ps->range(1, 14);
@@ -454,8 +455,9 @@ void CaveV7::makeTunnel(bool dirswitch) {
        bool randomize_xz = (ps->range(1, 2) == 1);
 
        // Make a ravine every once in a while if it's long enough
-       float xylen = vec.X * vec.X + vec.Z * vec.Z;
-       bool is_ravine = (xylen > 500.0) && !large_cave && (ps->range(1, 8) == 1);
+       //float xylen = vec.X * vec.X + vec.Z * vec.Z;
+       //disable ravines for now
+       bool is_ravine = false; //(xylen > 500.0) && !large_cave && (ps->range(1, 8) == 1);
 
        // Carve routes
        for (float f = 0; f < 1.0; f += 1.0 / veclen)
@@ -490,6 +492,7 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
        }
        
        bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
+       bool should_make_cave_hole = ps->range(1, 10) == 1;
        
        for (s16 z0 = d0; z0 <= d1; z0++) {
                s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
@@ -513,10 +516,10 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
                                v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
                                p += of;
                                
-                               if (!is_ravine && mg->heightmap) {
+                               if (!is_ravine && mg->heightmap && should_make_cave_hole) {
                                        int maplen = node_max.X - node_min.X + 1;
                                        int idx = (p.Z - node_min.Z) * maplen + (p.X - node_min.X);
-                                       if (p.Y >= mg->heightmap[idx])
+                                       if (p.Y >= mg->heightmap[idx] - 2)
                                                continue;
                                }
 
@@ -525,9 +528,10 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
 
                                u32 i = vm->m_area.index(p);
                                
-                               // Don't replace air or water or lava
+                               // Don't replace air, water, lava, or ice
                                content_t c = vm->m_data[i].getContent();
-                               if (c == CONTENT_AIR || c == c_water_source || c == c_lava_source)
+                               if (c == CONTENT_AIR   || c == c_water_source ||
+                                       c == c_lava_source || c == c_ice)
                                        continue;
                                        
                                if (large_cave) {
@@ -541,6 +545,9 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
                                        else
                                                vm->m_data[i] = airnode;
                                } else {
+                                       if (c == CONTENT_IGNORE)
+                                               continue;
+                                       
                                        vm->m_data[i] = airnode;
                                        vm->m_flags[i] |= VMANIP_FLAG_CAVE;
                                }
index a908c61d83105ee9e28f981056d738fa865880b5..a0268a645429b8a3f876d0d708165f0026e77412 100644 (file)
@@ -104,6 +104,7 @@ public:
        
        content_t c_water_source;
        content_t c_lava_source;
+       content_t c_ice;
        
        int water_level;
 
index af73adfe2f862ecf2cdf10f6a36887a6adbb2bbd..101eb35a4def3dfc28ec70ccc29eed21cd9a34ec 100644 (file)
@@ -235,12 +235,15 @@ void set_default_settings(Settings *settings)
        settings->setDefault("mgv6_np_trees",          "0, 1, (125, 125, 125), 2, 4, 0.66");
        settings->setDefault("mgv6_np_apple_trees",    "0, 1, (100, 100, 100), 342902, 3, 0.45");
 
-       settings->setDefault("mgv7_np_terrain_base",     "0, 80, (250, 250, 250), 82341, 5, 0.6");
-       settings->setDefault("mgv7_np_terrain_alt",      "0, 20, (250, 250, 250), 5934, 5, 0.6");
-       settings->setDefault("mgv7_np_terrain_mod",      "0, 1, (350, 350, 350), 85039, 5, 0.6");
-       settings->setDefault("mgv7_np_terrain_persist",  "0, 1, (500, 500, 500), 539, 3, 0.6");
-       settings->setDefault("mgv7_np_height_select",    "0.5, 0.5, (250, 250, 250), 4213, 5, 0.69");
-       settings->setDefault("mgv7_np_ridge",            "0, 1, (100, 100, 100), 6467, 4, 0.75");
+       settings->setDefault("mgv7_np_terrain_base",     "4, 70, (300, 300, 300), 82341, 6, 0.7");
+       settings->setDefault("mgv7_np_terrain_alt",      "4, 25, (600, 600, 600), 5934, 5, 0.6");
+       settings->setDefault("mgv7_np_terrain_persist",  "0.6, 0.1, (500, 500, 500), 539, 3, 0.6");
+       settings->setDefault("mgv7_np_height_select",    "-0.5, 1, (250, 250, 250), 4213, 5, 0.69");
+       settings->setDefault("mgv7_np_filler_depth",     "0, 1.2, (150, 150, 150), 261, 4, 0.7");       
+       settings->setDefault("mgv7_np_mount_height",     "100, 30, (500, 500, 500), 72449, 4, 0.6");
+       settings->setDefault("mgv7_np_ridge_uwater",     "0, 1, (500, 500, 500), 85039, 4, 0.6");
+       settings->setDefault("mgv7_np_mountain",         "0, 1, (250, 350, 250), 5333, 5, 0.68");
+       settings->setDefault("mgv7_np_ridge",            "0, 1, (100, 120, 100), 6467, 4, 0.75");
 
        settings->setDefault("mgindev_np_terrain_base",   "-4,   20,  (250, 250, 250), 82341, 5, 0.6,  10,  10");
        settings->setDefault("mgindev_np_terrain_higher", "20,   16,  (500, 500, 500), 85039, 5, 0.6,  10,  10");
index 905e80e89eb7e2bcb378caba732d4278e61db0aa..94d1a6310a51177cd1fa73e0527a4bd8bfcf1d88 100644 (file)
@@ -291,7 +291,7 @@ void Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
                                continue;
 
                        int height = getHeight();
-                       int max_y = nmax.Y + MAP_BLOCKSIZE;
+                       int max_y = nmax.Y;// + MAP_BLOCKSIZE - 1;
                        if (y + 1 + height > max_y) {
                                continue;
 #if 0
@@ -859,9 +859,16 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) {
        //TimeTaker t("Mapgen::updateHeightmap", NULL, PRECISION_MICRO);
        int index = 0;
        for (s16 z = nmin.Z; z <= nmax.Z; z++) {
-               for (s16 x = nmin.X; x <= nmax.X; x++) {
+               for (s16 x = nmin.X; x <= nmax.X; x++, index++) {
                        s16 y = findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y);
-                       heightmap[index++] = y;
+
+                       // if the values found are out of range, trust the old heightmap
+                       if (y == nmax.Y && heightmap[index] > nmax.Y)
+                               continue;
+                       if (y == nmin.Y - 1 && heightmap[index] < nmin.Y)
+                               continue;
+                               
+                       heightmap[index] = y;
                }
        }
        //printf("updateHeightmap: %dus\n", t.stop());
@@ -1060,9 +1067,12 @@ bool MapgenV7Params::readParams(Settings *settings) {
        bool success = 
                settings->getNoiseParams("mgv7_np_terrain_base",    np_terrain_base)    &&
                settings->getNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt)     &&
-               settings->getNoiseParams("mgv7_np_terrain_mod",     np_terrain_mod)     &&
                settings->getNoiseParams("mgv7_np_terrain_persist", np_terrain_persist) &&
                settings->getNoiseParams("mgv7_np_height_select",   np_height_select)   &&
+               settings->getNoiseParams("mgv7_np_filler_depth",    np_filler_depth)    &&
+               settings->getNoiseParams("mgv7_np_mount_height",    np_mount_height)    &&
+               settings->getNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater)    &&
+               settings->getNoiseParams("mgv7_np_mountain",        np_mountain)        &&
                settings->getNoiseParams("mgv7_np_ridge",           np_ridge);
        return success;
 }
@@ -1071,9 +1081,12 @@ bool MapgenV7Params::readParams(Settings *settings) {
 void MapgenV7Params::writeParams(Settings *settings) {
        settings->setNoiseParams("mgv7_np_terrain_base",    np_terrain_base);
        settings->setNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt);
-       settings->setNoiseParams("mgv7_np_terrain_mod",     np_terrain_mod);
        settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist);
        settings->setNoiseParams("mgv7_np_height_select",   np_height_select);
+       settings->setNoiseParams("mgv7_np_filler_depth",    np_filler_depth);
+       settings->setNoiseParams("mgv7_np_mount_height",    np_mount_height);
+       settings->setNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater);
+       settings->setNoiseParams("mgv7_np_mountain",        np_mountain);
        settings->setNoiseParams("mgv7_np_ridge",           np_ridge);
 }
 
index 4ed81b99b854287a0c5bd801e6bb9dda99863b28..7229e89967660e7183f7c95bb81ccbeaf653e08b 100644 (file)
@@ -36,6 +36,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MGV6_BIOME_BLEND 0x10
 #define MG_FLAT          0x20
 #define MG_NOLIGHT       0x40
+#define MGV7_MOUNTAINS   0x80
+#define MGV7_RIDGES      0x100
 
 /////////////////// Ore generation flags
 // Use absolute value of height to determine ore placement
index 6d0bf12923436c4d7a89ec3ead70b7f121a637b6..f2b17896d27fb6c3a5a5d36628a58145cd0fc2ca 100644 (file)
@@ -172,7 +172,6 @@ void MapgenMathParams::writeParams(Settings *settings) {
 MapgenMath::MapgenMath(int mapgenid, MapgenMathParams *params_, EmergeManager *emerge) : MapgenV7(mapgenid, params_, emerge) {
        mg_params = params_;
        this->flags |= MG_NOLIGHT;
-       this->ridges = 0;
 
        Json::Value & params = mg_params->params;
        invert = params["invert"].empty() ? 1 : params["invert"].asBool(); //params["invert"].empty()?1:params["invert"].asBool();
@@ -238,7 +237,7 @@ MapgenMath::~MapgenMath() {
 
 //////////////////////// Map generator
 
-void MapgenMath::generateTerrain() {
+int MapgenMath::generateTerrain() {
 
        MapNode n_air(CONTENT_AIR, LIGHT_SUN), n_water_source(c_water_source, LIGHT_SUN);
        MapNode n_stone(c_stone, LIGHT_SUN);
@@ -263,9 +262,9 @@ void MapgenMath::generateTerrain() {
                                double d = (*func)(vec.X, vec.Y, vec.Z, distance, iterations);
                                if ((!invert && d > 0) || (invert && d == 0)  ) {
                                        if (vm->m_data[i].getContent() == CONTENT_IGNORE)
-                                               vm->m_data[i] = (y > water_level + biome->filler_height) ?
-                                                               MapNode(biome->c_filler) : n_stone;
-//                                             vm->m_data[i] = n_stone;
+       //                                      vm->m_data[i] = (y > water_level + biome->filler) ?
+               //                                              MapNode(biome->c_filler) : n_stone;
+                                               vm->m_data[i] = n_stone;
                                } else if (y <= water_level) {
                                        vm->m_data[i] = n_water_source;
                                } else {
@@ -361,7 +360,7 @@ void MapgenMath::generateTerrain() {
 
 
 #endif
-
+       return 0;
 }
 
 int MapgenMath::getGroundLevelAtPoint(v2s16 p) {
index 3d3929c51a5949c7ec29f0c8ee306ee43e2d4f26..1bc404641389f01da32286c2be8d0d81633d328c 100644 (file)
@@ -42,7 +42,7 @@ class MapgenMath : public MapgenV7 {
                MapgenMath(int mapgenid, MapgenMathParams *mg_params, EmergeManager *emerge);
                ~MapgenMath();
 
-               void generateTerrain();
+               int generateTerrain();
                int getGroundLevelAtPoint(v2s16 p);
 
                bool invert;
index 861cdde626089acad778bd078ef59d05365c39ee..9b8c2c53ac8f260fbc65c747a5e0cb3722d51079 100644 (file)
@@ -24,10 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapblock.h"
 #include "mapnode.h"
 #include "map.h"
-//#include "serverobject.h"
 #include "content_sao.h"
 #include "nodedef.h"
-#include "content_mapnode.h" // For content_mapnode_get_new_name
 #include "voxelalgorithms.h"
 #include "profiler.h"
 #include "settings.h" // For g_settings
@@ -42,29 +40,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 /////////////////// Mapgen V7 perlin noise default values
 NoiseParams nparams_v7_def_terrain_base =
-       {0, 80.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6};
+       {4, 70, v3f(300, 300, 300), 82341, 6, 0.7};
 NoiseParams nparams_v7_def_terrain_alt =
-       {0, 20.0, v3f(250.0, 250.0, 250.0), 5934, 5, 0.6};
-NoiseParams nparams_v7_def_terrain_mod =
-       {0, 1.0, v3f(350.0, 350.0, 350.0), 85039, 5, 0.6};
+       {4, 25, v3f(600, 600, 600), 5934, 5, 0.6};
 NoiseParams nparams_v7_def_terrain_persist =
-       {0, 1.0, v3f(500.0, 500.0, 500.0), 539, 3, 0.6};
+       {0.6, 0.1, v3f(500, 500, 500), 539, 3, 0.6};
 NoiseParams nparams_v7_def_height_select =
-       {0.5, 0.5, v3f(250.0, 250.0, 250.0), 4213, 5, 0.69};
+       {-0.5, 1, v3f(250, 250, 250), 4213, 5, 0.69};
+       
+NoiseParams nparams_v7_def_filler_depth =
+       {0, 1.2, v3f(150, 150, 150), 261, 4, 0.7};
+
+NoiseParams nparams_v7_def_mount_height =
+       {100, 30, v3f(500, 500, 500), 72449, 4, 0.6};   
+NoiseParams nparams_v7_def_ridge_uwater =
+       {0, 1, v3f(500, 500, 500), 85039, 4, 0.6};
+NoiseParams nparams_v7_def_mountain =
+       {0, 1, v3f(250, 350, 250), 5333, 5, 0.68};
 NoiseParams nparams_v7_def_ridge =
-       {0, 1.0, v3f(100.0, 100.0, 100.0), 6467, 4, 0.75};
-/*
-NoiseParams nparams_v6_def_beach =
-       {0.0, 1.0, v3f(250.0, 250.0, 250.0), 59420, 3, 0.50};
-NoiseParams nparams_v6_def_cave =
-       {6.0, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50};
-NoiseParams nparams_v6_def_humidity =
-       {0.5, 0.5, v3f(500.0, 500.0, 500.0), 72384, 4, 0.66};
-NoiseParams nparams_v6_def_trees =
-       {0.0, 1.0, v3f(125.0, 125.0, 125.0), 2, 4, 0.66};
-NoiseParams nparams_v6_def_apple_trees =
-       {0.0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45};
-*/
+       {0, 1, v3f(100, 100, 100), 6467, 4, 0.75};
+
+
 ///////////////////////////////////////////////////////////////////////////////
 
 
@@ -76,11 +72,14 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
 
        this->seed     = (int)params->seed;
        this->water_level = params->water_level;
-       this->flags    = params->flags;
-       this->ridges   = 1;
+       this->flags    = params->flags | MGV7_MOUNTAINS | MGV7_RIDGES;
 
        this->csize   = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
-       this->ystride = csize.X; //////fix this
+
+       // amount of elements to skip for the next index
+       // for noise/height/biome maps (not vmanip)
+       this->ystride = csize.X;
+       this->zstride = csize.X * csize.Y;
 
        this->biomemap  = new u8[csize.X * csize.Z];
        this->heightmap = new s16[csize.X * csize.Z];
@@ -89,10 +88,15 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
        // Terrain noise
        noise_terrain_base    = new Noise(&params->np_terrain_base,    seed, csize.X, csize.Z);
        noise_terrain_alt     = new Noise(&params->np_terrain_alt,     seed, csize.X, csize.Z);
-       noise_terrain_mod     = new Noise(&params->np_terrain_mod,     seed, csize.X, csize.Z);
        noise_terrain_persist = new Noise(&params->np_terrain_persist, seed, csize.X, csize.Z);
        noise_height_select   = new Noise(&params->np_height_select,   seed, csize.X, csize.Z);
-       noise_ridge           = new Noise(&params->np_ridge, seed, csize.X, csize.Y, csize.Z);
+       noise_filler_depth    = new Noise(&params->np_filler_depth,    seed, csize.X, csize.Z);
+       noise_mount_height    = new Noise(&params->np_mount_height,    seed, csize.X, csize.Z);
+       noise_ridge_uwater    = new Noise(&params->np_ridge_uwater,    seed, csize.X, csize.Z);
+       
+       // 3d terrain noise
+       noise_mountain = new Noise(&params->np_mountain, seed, csize.X, csize.Y, csize.Z);
+       noise_ridge    = new Noise(&params->np_ridge,    seed, csize.X, csize.Y, csize.Z);
        
        // Biome noise
        noise_heat     = new Noise(bmgr->np_heat,     seed, csize.X, csize.Z);
@@ -102,11 +106,15 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
 
 MapgenV7::~MapgenV7() {
        delete noise_terrain_base;
-       delete noise_terrain_mod;
        delete noise_terrain_persist;
        delete noise_height_select;
        delete noise_terrain_alt;
+       delete noise_filler_depth;
+       delete noise_mount_height;
+       delete noise_ridge_uwater;
+       delete noise_mountain;
        delete noise_ridge;
+
        delete noise_heat;
        delete noise_humidity;
        
@@ -117,25 +125,28 @@ MapgenV7::~MapgenV7() {
 
 
 int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
-       s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Y);
-       float heat      = NoisePerlin2D(bmgr->np_heat, p.X, p.Y, seed);
-       float humidity  = NoisePerlin2D(bmgr->np_humidity, p.X, p.Y, seed);
-       Biome *b = bmgr->getBiome(heat, humidity, groundlevel);
+       // Base terrain calculation
+       s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
        
-       s16 y = groundlevel;
-       int iters = 1024; // don't even bother iterating more than 64 times..
+       // Ridge/river terrain calculation
+       float width = 0.3;
+       float uwatern = NoisePerlin2DNoTxfm(noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
+       // actually computing the depth of the ridge is much more expensive;
+       // if inside a river, simply guess
+       if (uwatern >= -width && uwatern <= width)
+               return water_level - 10;
+       
+       // Mountain terrain calculation
+       int iters = 128; // don't even bother iterating more than 128 times..
        while (iters--) {
-               if (y <= water_level)
-                       break;
-               
-               float ridgenoise = NoisePerlin3D(noise_ridge->np, p.X, y, p.Y, seed);
-               if (ridgenoise * (float)(y * y) < 15.0)
-                       break;
+               //current point would have been air
+               if (!getMountainTerrainAtPoint(p.X, y, p.Y))
+                       return y;
                        
-               y--;
+               y++;
        }
 
-       return y + b->top_depth;
+       return y;
 }
 
 
@@ -162,20 +173,6 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
        full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
 
        blockseed = emerge->getBlockSeed(full_node_min);  //////use getBlockSeed2()!
-
-       // Make some noise
-       calculateNoise();
-
-       // Calculate height map
-       s16 stone_surface_max_y = calcHeightMap();
-       
-       // Calculate biomes
-       BiomeNoiseInput binput;
-       binput.mapsize       = v2s16(csize.X, csize.Z);
-       binput.heat_map      = noise_heat->result;
-       binput.humidity_map  = noise_humidity->result;
-       binput.height_map    = heightmap;
-       bmgr->calcBiomes(&binput, biomemap);
        
        c_stone           = ndef->getId("mapgen_stone");
        c_dirt            = ndef->getId("mapgen_dirt");
@@ -183,17 +180,31 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
        c_sand            = ndef->getId("mapgen_sand");
        c_water_source    = ndef->getId("mapgen_water_source");
        c_lava_source     = ndef->getId("mapgen_lava_source");
+       c_ice             = ndef->getId("default:ice");
+       if (c_ice == CONTENT_IGNORE)
+               c_ice = CONTENT_AIR;
        
-       generateTerrain();
-       if (this->ridges)
-               carveRidges();
-
-       if (flags & MG_CAVES)
-               generateCaves(stone_surface_max_y);
+       // Make some noise
+       calculateNoise();
        
-       addTopNodes();
+       // Generate base terrain, mountains, and ridges with initial heightmaps
+       s16 stone_surface_max_y = generateTerrain();
        
        updateHeightmap(node_min, node_max);
+       
+       // Calculate biomes
+       BiomeNoiseInput binput;
+       binput.mapsize      = v2s16(csize.X, csize.Z);
+       binput.heat_map     = noise_heat->result;
+       binput.humidity_map = noise_humidity->result;
+       binput.height_map   = heightmap;
+       bmgr->calcBiomes(&binput, biomemap);
+       
+       // Actually place the biome-specific nodes and what not
+       generateBiomes();
+
+       if (flags & MG_CAVES)
+               generateCaves(stone_surface_max_y);
 
        if (flags & MG_DUNGEONS) {
                DungeonGen dgen(ndef, data->seed, water_level);
@@ -210,6 +221,9 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
                ore->placeOre(this, blockseed + i, node_min, node_max);
        }
        
+       // Sprinkle some dust on top after everything else was generated
+       dustTopNodes();
+       
        //printf("makeChunk: %dms\n", t.stop());
        
        updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
@@ -219,7 +233,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
                                         node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
        //setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
        //                      node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
-
+       
        this->generating = false;
 }
 
@@ -230,15 +244,14 @@ void MapgenV7::calculateNoise() {
        int y = node_min.Y;
        int z = node_min.Z;
        
-       noise_terrain_mod->perlinMap2D(x, z);
-       
        noise_height_select->perlinMap2D(x, z);
        noise_height_select->transformNoiseMap();
        
        noise_terrain_persist->perlinMap2D(x, z);
+       noise_terrain_persist->transformNoiseMap();
        float *persistmap = noise_terrain_persist->result;
        for (int i = 0; i != csize.X * csize.Z; i++)
-               persistmap[i] = abs(persistmap[i]);
+               persistmap[i] = rangelim(persistmap[i], 0.4, 0.9);
        
        noise_terrain_base->perlinMap2DModulated(x, z, persistmap);
        noise_terrain_base->transformNoiseMap();
@@ -246,10 +259,20 @@ void MapgenV7::calculateNoise() {
        noise_terrain_alt->perlinMap2DModulated(x, z, persistmap);
        noise_terrain_alt->transformNoiseMap();
        
-       noise_ridge->perlinMap3D(x, y, z);
+       noise_filler_depth->perlinMap2D(x, z);
        
-       noise_heat->perlinMap2D(x, z);
+       if (flags & MGV7_MOUNTAINS) {
+               noise_mountain->perlinMap3D(x, y, z);
+               noise_mount_height->perlinMap2D(x, z);
+               noise_mount_height->transformNoiseMap();
+       }
+
+       if (flags & MGV7_RIDGES) {
+               noise_ridge->perlinMap3D(x, y, z);
+               noise_ridge_uwater->perlinMap2D(x, z);
+       }
        
+       noise_heat->perlinMap2D(x, z);
        noise_humidity->perlinMap2D(x, z);
        
        //printf("calculateNoise: %dus\n", t.stop());
@@ -264,36 +287,56 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
        return bmgr->getBiome(heat, humidity, groundlevel);
 }
 
-
+//needs to be updated
 float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
-       float terrain_mod = NoisePerlin2DNoTxfm(noise_terrain_mod->np, x, z, seed);
-       float hselect     = NoisePerlin2D(noise_height_select->np, x, z, seed);
-       float persist     = abs(NoisePerlin2DNoTxfm(noise_terrain_persist->np, x, z, seed));
+       float hselect = NoisePerlin2D(noise_height_select->np, x, z, seed);
+       hselect = rangelim(hselect, 0.0, 1.0);
+       
+       float persist = NoisePerlin2D(noise_terrain_persist->np, x, z, seed);
+       persist = rangelim(persist, 0.4, 0.9);
 
        noise_terrain_base->np->persist = persist;
-       float terrain_base = NoisePerlin2D(noise_terrain_base->np, x, z, seed);
-       float height_base  = terrain_base * terrain_mod;
+       float height_base = NoisePerlin2D(noise_terrain_base->np, x, z, seed);
 
        noise_terrain_alt->np->persist = persist;
        float height_alt = NoisePerlin2D(noise_terrain_alt->np, x, z, seed);
 
+       if (height_alt > height_base)
+               return height_alt;
+               
        return (height_base * hselect) + (height_alt * (1.0 - hselect));
 }
 
 
 float MapgenV7::baseTerrainLevelFromMap(int index) {
-       float terrain_mod  = noise_terrain_mod->result[index];
-       float hselect      = noise_height_select->result[index];
-       float terrain_base = noise_terrain_base->result[index];
-       float height_base  = terrain_base * terrain_mod;
-       float height_alt   = noise_terrain_alt->result[index];
+       float hselect     = rangelim(noise_height_select->result[index], 0.0, 1.0);
+       float height_base = noise_terrain_base->result[index];
+       float height_alt  = noise_terrain_alt->result[index];
+       
+       if (height_alt > height_base)
+               return height_alt;
 
        return (height_base * hselect) + (height_alt * (1.0 - hselect));
 }
 
 
+bool MapgenV7::getMountainTerrainAtPoint(int x, int y, int z) {
+       float mnt_h_n = NoisePerlin2D(noise_mount_height->np, x, z, seed);
+       float height_modifier = -((float)y / rangelim(mnt_h_n, 80.0, 150.0));
+       float mnt_n = NoisePerlin3D(noise_mountain->np, x, y, z, seed);
+
+       return mnt_n + height_modifier >= 0.6;
+}
+
+
+bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, int y) {
+       float mounthn = noise_mount_height->result[idx_xz];
+       float height_modifier = -((float)y / rangelim(mounthn, 80.0, 150.0));
+       return (noise_mountain->result[idx_xyz] + height_modifier >= 0.6);
+}
+
+
 #if 0
-// Crap code to test log rivers as a proof-of-concept.  Didn't work out too well.
 void MapgenV7::carveRivers() {
        MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
        MapNode n_stone(c_stone);
@@ -328,8 +371,26 @@ void MapgenV7::carveRivers() {
 #endif
 
 
-int MapgenV7::calcHeightMap() {
+int MapgenV7::generateTerrain() {
+       int ymax = generateBaseTerrain();
+
+       if (flags & MGV7_MOUNTAINS)
+               generateMountainTerrain();
+
+       if (flags & MGV7_RIDGES)
+               generateRidgeTerrain();
+               
+       return ymax;
+}
+
+
+int MapgenV7::generateBaseTerrain() {
+       MapNode n_air(CONTENT_AIR);
+       MapNode n_stone(c_stone);
+       MapNode n_water(c_water_source);
+       
        int stone_surface_max_y = -MAP_GENERATION_LIMIT;
+       v3s16 em = vm->m_area.getExtent();
        u32 index = 0;
        
        for (s16 z = node_min.Z; z <= node_max.Z; z++)
@@ -342,46 +403,50 @@ int MapgenV7::calcHeightMap() {
                
                if (surface_y > stone_surface_max_y)
                        stone_surface_max_y = surface_y;
-       }
-               
-       return stone_surface_max_y;
-}
 
-
-void MapgenV7::generateTerrain() {
-       MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
-       MapNode n_stone(c_stone);
-
-       v3s16 em = vm->m_area.getExtent();
-       u32 index = 0;
-       
-       for (s16 z = node_min.Z; z <= node_max.Z; z++)
-       for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
-               s16 surface_y = heightmap[index];
-               Biome *biome = bmgr->biomes[biomemap[index]];
-               
-               u32 i = vm->m_area.index(x, node_min.Y, z);
+               u32 i = vm->m_area.index(x, node_min.Y, z);             
                for (s16 y = node_min.Y; y <= node_max.Y; y++) {
                        if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
-                               if (y <= surface_y) {
-                                       vm->m_data[i] = (y > water_level + biome->filler_height) ?
-                                               MapNode(biome->c_filler) : n_stone;
-                               } else if (y <= water_level) {
-                                       vm->m_data[i] = n_water_source;
-                               } else {
+                               if (y <= surface_y)
+                                       vm->m_data[i] = n_stone;
+                               else if (y <= water_level)
+                                       vm->m_data[i] = n_water;
+                               else
                                        vm->m_data[i] = n_air;
-                               }
                        }
                        vm->m_area.add_y(em, i, 1);
                }
        }
+       
+       return stone_surface_max_y;
 }
 
 
-void MapgenV7::carveRidges() {
+void MapgenV7::generateMountainTerrain() {
        if (node_max.Y <= water_level)
                return;
                
+       MapNode n_stone(c_stone);
+       u32 index = 0;
+       
+       for (s16 z = node_min.Z; z <= node_max.Z; z++)
+       for (s16 y = node_min.Y; y <= node_max.Y; y++) {
+               u32 vi = vm->m_area.index(node_min.X, y, z);
+               for (s16 x = node_min.X; x <= node_max.X; x++) {
+                       int j = (z - node_min.Z) * csize.X + (x - node_min.X);
+
+                       if (getMountainTerrainFromMap(index, j, y))
+                               vm->m_data[vi] = n_stone;
+                               
+                       vi++;
+                       index++;
+               }
+       }
+}
+
+
+void MapgenV7::generateRidgeTerrain() {
+       MapNode n_water(c_water_source);
        MapNode n_air(CONTENT_AIR);
        u32 index = 0;
        
@@ -389,37 +454,150 @@ void MapgenV7::carveRidges() {
        for (s16 y = node_min.Y; y <= node_max.Y; y++) {
                u32 vi = vm->m_area.index(node_min.X, y, z);
                for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) {
-                       // Removing this check will create huge underwater caverns,
-                       // which are interesting but not desirable for gameplay
-                       if (y <= water_level)
+                       int j = (z - node_min.Z) * csize.X + (x - node_min.X);
+                       
+                       if (heightmap[j] < water_level - 4)
                                continue;
-                               
-                       if (noise_ridge->result[index] * (float)(y * y) < 15.0)
+                       
+                       float widthn = (noise_terrain_persist->result[j] - 0.6) / 0.1;
+                       //widthn = rangelim(widthn, -0.05, 0.5);
+                       
+                       float width = 0.3; // TODO: figure out acceptable perlin noise values
+                       float uwatern = noise_ridge_uwater->result[j] * 2;
+                       if (uwatern < -width || uwatern > width)
                                continue;
+                       
+                       float height_mod = (float)(y + 17) / 2.5;
+                       float width_mod  = (width - fabs(uwatern));
+                       float nridge = noise_ridge->result[index] * (float)y / 7.0;
 
-                       int j = (z - node_min.Z) * csize.Z + (x - node_min.X); //////obviously just temporary
+                       if (y < water_level)
+                               nridge = -fabs(nridge) * 3.0 * widthn * 0.3;
+                       
+                       if (nridge + width_mod * height_mod < 0.6)
+                               continue;
+                       
                        if (y < ridge_heightmap[j])
                                ridge_heightmap[j] = y - 1; 
 
-                       vm->m_data[vi] = n_air;
+                       vm->m_data[vi] = (y > water_level) ? n_air : n_water;
                }
        }
 }
 
-/*
-void MapgenV7::testBiomes() {
+
+void MapgenV7::generateBiomes() {
+       if (node_max.Y < water_level)
+               return;
+
+       MapNode n_air(CONTENT_AIR);
+       MapNode n_stone(c_stone);
+       MapNode n_water(c_water_source);
+
+       v3s16 em = vm->m_area.getExtent();
        u32 index = 0;
        
-       for (s16 z = node_min.Z; z <= node_min.Z; z++)
-       for (s16 x = node_min.X; x <= node_min.X; x++) {;
-               Biome *b = bmgr->getBiome(heat, humidity, 0);
+       for (s16 z = node_min.Z; z <= node_max.Z; z++)
+       for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
+               Biome *biome  = bmgr->biomes[biomemap[index]];
+               s16 dfiller   = biome->depth_filler + noise_filler_depth->result[index];
+               s16 y0_top    = biome->depth_top;
+               s16 y0_filler = biome->depth_filler + biome->depth_top + dfiller;
+               
+               s16 nplaced = 0;
+               u32 i = vm->m_area.index(x, node_max.Y, z);     
+
+               content_t c_above = vm->m_data[i + em.X].getContent();
+               bool have_air = c_above == CONTENT_AIR;
+               
+               for (s16 y = node_max.Y; y >= node_min.Y; y--) {
+                       content_t c = vm->m_data[i].getContent();
+                       
+                       // It could be the case that the elevation is equal to the chunk
+                       // boundary, but the chunk above has not been generated yet
+                       if (y == node_max.Y && c_above == CONTENT_IGNORE &&
+                               y == heightmap[index] && c == c_stone) {
+                               int j = z * zstride + y * ystride + x;
+                               have_air = !getMountainTerrainFromMap(j, index, y);
+                       }
+                       
+                       if (c == c_stone && have_air) {
+                               content_t c_below = vm->m_data[i - em.X].getContent();
+                               
+                               if (c_below != CONTENT_AIR) {
+                                       if (nplaced < y0_top) {
+                                               // A hack to prevent dirt_with_grass from being
+                                               // placed below water.  TODO: fix later
+                                               content_t c_place = ((y < water_level) &&
+                                                               (biome->c_top == c_dirt_with_grass)) ?
+                                                                c_dirt : biome->c_top;
+                                               
+                                               vm->m_data[i] = MapNode(c_place);
+                                               nplaced++;
+                                       } else if (nplaced < y0_filler && nplaced >= y0_top) {
+                                               vm->m_data[i] = MapNode(biome->c_filler);
+                                               nplaced++;
+                                       } else {
+                                               have_air = false;
+                                               nplaced  = 0;
+                                       }
+                               }
+                       } else if (c == c_water_source) {
+                               have_air = true;
+                               nplaced = 0;
+                               vm->m_data[i] = MapNode(biome->c_water);
+                       } else if (c == CONTENT_AIR) {
+                               have_air = true;
+                               nplaced = 0;
+                       }
+                       
+                       vm->m_area.add_y(em, i, -1);
+               }
        }
-       // make an 80x80 grid with axes heat/humidity as a voroni diagram for biomes
-       // clear out y space for it first with air
-       // use absolute positioning, each chunk will be a +1 height
-}*/
+}
 
 
+void MapgenV7::dustTopNodes() {
+       v3s16 em = vm->m_area.getExtent();
+       u32 index = 0;
+       
+       if (water_level > node_max.Y)
+               return;
+
+       for (s16 z = node_min.Z; z <= node_max.Z; z++)
+       for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
+               Biome *biome = bmgr->biomes[biomemap[index]];
+       
+               if (biome->c_dust == CONTENT_IGNORE)
+                       continue;
+
+               s16 y = node_max.Y;
+               u32 vi = vm->m_area.index(x, y, z);
+               for (; y >= node_min.Y; y--) {
+                       if (vm->m_data[vi].getContent() != CONTENT_AIR)
+                               break;
+
+                       vm->m_area.add_y(em, vi, -1);
+               }
+                       
+               content_t c = vm->m_data[vi].getContent();
+               if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
+                       if (y < node_min.Y)
+                               continue;
+                               
+                       vm->m_data[vi] = MapNode(biome->c_dust_water);
+               } else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE) {
+                       if (y == node_max.Y)
+                               continue;
+                               
+                       vm->m_area.add_y(em, vi, 1);
+                       vm->m_data[vi] = MapNode(biome->c_dust);
+               }
+       }
+}
+
+
+#if 0
 void MapgenV7::addTopNodes() {
        v3s16 em = vm->m_area.getExtent();
        s16 ntopnodes;
@@ -511,6 +689,7 @@ void MapgenV7::addTopNodes() {
                }
        }
 }
+#endif
 
 
 #include "mapgen_v6.h"
index e39bf715857b0f5cabf42f62f608f47c455c1de4..e7a72e464655ee34fa0762d837b1a10300dcf748 100644 (file)
@@ -24,25 +24,34 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 extern NoiseParams nparams_v7_def_terrain_base;
 extern NoiseParams nparams_v7_def_terrain_alt;
-extern NoiseParams nparams_v7_def_terrain_mod;
 extern NoiseParams nparams_v7_def_terrain_persist;
 extern NoiseParams nparams_v7_def_height_select;
+extern NoiseParams nparams_v7_def_filler_depth;
+extern NoiseParams nparams_v7_def_mount_height;
+extern NoiseParams nparams_v7_def_ridge_uwater;
+extern NoiseParams nparams_v7_def_mountain;
 extern NoiseParams nparams_v7_def_ridge;
 
 struct MapgenV7Params : public MapgenParams {
        NoiseParams np_terrain_base;
        NoiseParams np_terrain_alt;
-       NoiseParams np_terrain_mod;
        NoiseParams np_terrain_persist;
        NoiseParams np_height_select;
+       NoiseParams np_filler_depth;
+       NoiseParams np_mount_height;
+       NoiseParams np_ridge_uwater;
+       NoiseParams np_mountain;
        NoiseParams np_ridge;
        
        MapgenV7Params() {
                np_terrain_base    = nparams_v7_def_terrain_base;
                np_terrain_alt     = nparams_v7_def_terrain_alt;
-               np_terrain_mod     = nparams_v7_def_terrain_mod;
                np_terrain_persist = nparams_v7_def_terrain_persist;
                np_height_select   = nparams_v7_def_height_select;
+               np_filler_depth    = nparams_v7_def_filler_depth;
+               np_mount_height    = nparams_v7_def_mount_height;
+               np_ridge_uwater    = nparams_v7_def_ridge_uwater;
+               np_mountain        = nparams_v7_def_mountain;
                np_ridge           = nparams_v7_def_ridge;
        }
        
@@ -58,8 +67,8 @@ public:
        BiomeDefManager *bmgr;
 
        int ystride;
+       int zstride;
        u32 flags;
-       bool ridges;
 
        u32 blockseed;
        v3s16 node_min;
@@ -71,10 +80,12 @@ public:
        
        Noise *noise_terrain_base;
        Noise *noise_terrain_alt;
-       Noise *noise_terrain_mod;
        Noise *noise_terrain_persist;
        Noise *noise_height_select;
-       
+       Noise *noise_filler_depth;
+       Noise *noise_mount_height;
+       Noise *noise_ridge_uwater;
+       Noise *noise_mountain;
        Noise *noise_ridge;
        
        Noise *noise_heat;
@@ -86,6 +97,7 @@ public:
        content_t c_sand;
        content_t c_water_source;
        content_t c_lava_source;
+       content_t c_ice;
        content_t c_gravel;
        content_t c_cobble;
        content_t c_desert_sand;
@@ -100,15 +112,20 @@ public:
 
        float baseTerrainLevelAtPoint(int x, int z);
        float baseTerrainLevelFromMap(int index);
+       bool getMountainTerrainAtPoint(int x, int y, int z);
+       bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, int y);
+       
        void calculateNoise();
-       int calcHeightMap();
        
-       virtual void generateTerrain();
-       void carveRidges();
-       //void carveRivers(); //experimental
+       virtual int generateTerrain();
+       int generateBaseTerrain();
+       void generateMountainTerrain();
+       void generateRidgeTerrain();
+       
+       void generateBiomes();
+       void dustTopNodes();
        
-       void testBiomes();
-       void addTopNodes();
+       //void addTopNodes();
        
        void generateCaves(int max_stone_y);
 };
index de0c3a670058b03b79aa233c10215265f950ddf1..020d1cf324aecab6f3f02897f0f5960fe9506d03 100644 (file)
@@ -204,19 +204,33 @@ int ModApiBasic::l_register_biome(lua_State *L)
                                "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
        Biome *b = bmgr->createBiome(terrain);
 
-       b->name            = getstringfield_default(L, index, "name", "");
-       b->top_nodename    = getstringfield_default(L, index, "top_node", "");
-       b->top_depth       = getintfield_default(L, index, "top_depth", 0);
-       b->filler_nodename = getstringfield_default(L, index, "filler_node", "");
-       b->filler_height   = getintfield_default(L, index, "filler_height", 0);
-       b->height_min      = getintfield_default(L, index, "height_min", 0);
-       b->height_max      = getintfield_default(L, index, "height_max", 0);
-       b->heat_point      = getfloatfield_default(L, index, "heat_point", 0.);
-       b->humidity_point  = getfloatfield_default(L, index, "humidity_point", 0.);
-
-       b->flags    = 0; //reserved
-       b->c_top    = CONTENT_IGNORE;
-       b->c_filler = CONTENT_IGNORE;
+       b->name         = getstringfield_default(L, index, "name",
+                                                                                               "<no name>");
+       b->nname_top    = getstringfield_default(L, index, "node_top",
+                                                                                               "mapgen_dirt_with_grass");
+       b->nname_filler = getstringfield_default(L, index, "node_filler",
+                                                                                               "mapgen_dirt");
+       b->nname_water  = getstringfield_default(L, index, "node_water",
+                                                                                               "mapgen_water_source");
+       b->nname_dust   = getstringfield_default(L, index, "node_dust",
+                                                                                               "air");
+       b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
+                                                                                               "mapgen_water_source");
+       
+       b->depth_top      = getintfield_default(L, index, "depth_top",    1);
+       b->depth_filler   = getintfield_default(L, index, "depth_filler", 3);
+       b->height_min     = getintfield_default(L, index, "height_min",   0);
+       b->height_max     = getintfield_default(L, index, "height_max",   0);
+       b->heat_point     = getfloatfield_default(L, index, "heat_point",     0.);
+       b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
+
+       b->flags        = 0; //reserved
+       b->c_top        = CONTENT_IGNORE;
+       b->c_filler     = CONTENT_IGNORE;
+       b->c_water      = CONTENT_IGNORE;
+       b->c_dust       = CONTENT_IGNORE;
+       b->c_dust_water = CONTENT_IGNORE;
+       
        verbosestream << "register_biome: " << b->name << std::endl;
        bmgr->addBiome(b);