Biome API: Re-calculate biome at every surface in a mapchunk column
authorparamat <mat.gregory@virginmedia.com>
Tue, 24 Feb 2015 04:06:05 +0000 (04:06 +0000)
committerparamat <mat.gregory@virginmedia.com>
Thu, 26 Feb 2015 03:35:25 +0000 (03:35 +0000)
src/mapgen_v5.cpp
src/mapgen_v5.h
src/mapgen_v7.cpp
src/mapgen_v7.h
src/mg_biome.cpp
src/mg_biome.h
src/script/lua_api/l_mapgen.cpp

index ed18f7d0b64ac46a632c2393f08f28ff649176e3..e3624c2bdf314147ec4cf1ae300e991ccfcd7261 100644 (file)
@@ -228,14 +228,16 @@ void MapgenV5::makeChunk(BlockMakeData *data)
 
        // Generate base terrain
        s16 stone_surface_max_y = generateBaseTerrain();
+
+       // Create heightmap
        updateHeightmap(node_min, node_max);
 
-       // Calculate biomes
+       // Create biomemap at heightmap surface
        bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
                noise_humidity->result, heightmap, biomemap);
 
        // Actually place the biome-specific nodes
-       generateBiomes();
+       generateBiomes(noise_heat->result, noise_humidity->result);
 
        // Generate caves
        if ((flags & MG_CAVES) && (stone_surface_max_y >= node_min.Y))
@@ -354,7 +356,7 @@ int MapgenV5::generateBaseTerrain()
 }
 
 
-void MapgenV5::generateBiomes()
+void MapgenV5::generateBiomes(float *heat_map, float *humidity_map)
 {
        if (node_max.Y < water_level)
                return;
@@ -368,12 +370,11 @@ void MapgenV5::generateBiomes()
 
        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        = (Biome *)bmgr->get(biomemap[index]);
-               s16 dfiller         = biome->depth_filler + noise_filler_depth->result[index];
-               s16 y0_top          = biome->depth_top;
-               s16 y0_filler       = biome->depth_top + dfiller;
-               s16 shore_max       = water_level + biome->height_shore;
-               s16 depth_water_top = biome->depth_water_top;
+               Biome *biome = NULL;
+               s16 dfiller = 0;
+               s16 y0_top = 0;
+               s16 y0_filler = 0;
+               s16 depth_water_top = 0;
 
                s16 nplaced = 0;
                u32 i = vm->m_area.index(x, node_max.Y, z);
@@ -384,25 +385,23 @@ void MapgenV5::generateBiomes()
                for (s16 y = node_max.Y; y >= node_min.Y; y--) {
                        content_t c = vm->m_data[i].getContent();
 
+                       if (c != CONTENT_IGNORE && c != CONTENT_AIR && (y == node_max.Y || have_air)) {
+                               biome           = bmgr->getBiome(heat_map[index], humidity_map[index], y);
+                               dfiller         = biome->depth_filler + noise_filler_depth->result[index];
+                               y0_top          = biome->depth_top;
+                               y0_filler       = biome->depth_top + dfiller;
+                               depth_water_top = biome->depth_water_top;
+                       }
+
                        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) {
-                                               if(y < water_level)
-                                                       vm->m_data[i] = MapNode(biome->c_underwater);
-                                               else if(y <= shore_max)
-                                                       vm->m_data[i] = MapNode(biome->c_shore_top);
-                                               else
-                                                       vm->m_data[i] = MapNode(biome->c_top);
+                                               vm->m_data[i] = MapNode(biome->c_top);
                                                nplaced++;
                                        } else if (nplaced < y0_filler && nplaced >= y0_top) {
-                                               if(y < water_level)
-                                                       vm->m_data[i] = MapNode(biome->c_underwater);
-                                               else if(y <= shore_max)
-                                                       vm->m_data[i] = MapNode(biome->c_shore_filler);
-                                               else
-                                                       vm->m_data[i] = MapNode(biome->c_filler);
+                                               vm->m_data[i] = MapNode(biome->c_filler);
                                                nplaced++;
                                        } else if (c == c_stone) {
                                                have_air = false;
index 703addf65265a1570265dffea06e870733802e9d..e95874e846dcb2c1ad303561461ded3aab58fca4 100644 (file)
@@ -93,7 +93,7 @@ public:
        int getGroundLevelAtPoint(v2s16 p);
        void calculateNoise();
        int generateBaseTerrain();
-       void generateBiomes();
+       void generateBiomes(float *heat_map, float *humidity_map);
        void generateCaves(int max_stone_y);
        void dustTopNodes();
 };
index a7b9076b3f2c77b9d0920699885985867fe6b8c2..29d311575d99c669df58d59c906e67fb41530bc7 100644 (file)
@@ -239,14 +239,15 @@ void MapgenV7::makeChunk(BlockMakeData *data)
        // Generate base terrain, mountains, and ridges with initial heightmaps
        s16 stone_surface_max_y = generateTerrain();
 
+       // Create heightmap
        updateHeightmap(node_min, node_max);
 
-       // Calculate biomes
+       // Create biomemap at heightmap surface
        bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
                noise_humidity->result, heightmap, biomemap);
 
-       // Actually place the biome-specific nodes and what not
-       generateBiomes();
+       // Actually place the biome-specific nodes
+       generateBiomes(noise_heat->result, noise_humidity->result);
 
        if (flags & MG_CAVES)
                generateCaves(stone_surface_max_y);
@@ -534,7 +535,7 @@ void MapgenV7::generateRidgeTerrain()
 }
 
 
-void MapgenV7::generateBiomes()
+void MapgenV7::generateBiomes(float *heat_map, float *humidity_map)
 {
        if (node_max.Y < water_level)
                return;
@@ -548,12 +549,11 @@ void MapgenV7::generateBiomes()
 
        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        = (Biome *)bmgr->get(biomemap[index]);
-               s16 dfiller         = biome->depth_filler + noise_filler_depth->result[index];
-               s16 y0_top          = biome->depth_top;
-               s16 y0_filler       = biome->depth_top + dfiller;
-               s16 shore_max       = water_level + biome->height_shore;
-               s16 depth_water_top = biome->depth_water_top;
+               Biome *biome = NULL;
+               s16 dfiller = 0;
+               s16 y0_top = 0;
+               s16 y0_filler = 0;
+               s16 depth_water_top = 0;
 
                s16 nplaced = 0;
                u32 i = vm->m_area.index(x, node_max.Y, z);
@@ -574,25 +574,23 @@ void MapgenV7::generateBiomes()
                                have_air = !getMountainTerrainFromMap(j, index, y);
                        }
 
+                       if (c != CONTENT_IGNORE && c != CONTENT_AIR && (y == node_max.Y || have_air)) {
+                               biome           = bmgr->getBiome(heat_map[index], humidity_map[index], y);
+                               dfiller         = biome->depth_filler + noise_filler_depth->result[index];
+                               y0_top          = biome->depth_top;
+                               y0_filler       = biome->depth_top + dfiller;
+                               depth_water_top = biome->depth_water_top;
+                       }
+
                        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) {
-                                               if(y < water_level)
-                                                       vm->m_data[i] = MapNode(biome->c_underwater);
-                                               else if(y <= shore_max)
-                                                       vm->m_data[i] = MapNode(biome->c_shore_top);
-                                               else
-                                                       vm->m_data[i] = MapNode(biome->c_top);
+                                               vm->m_data[i] = MapNode(biome->c_top);
                                                nplaced++;
                                        } else if (nplaced < y0_filler && nplaced >= y0_top) {
-                                               if(y < water_level)
-                                                       vm->m_data[i] = MapNode(biome->c_underwater);
-                                               else if(y <= shore_max)
-                                                       vm->m_data[i] = MapNode(biome->c_shore_filler);
-                                               else
-                                                       vm->m_data[i] = MapNode(biome->c_filler);
+                                               vm->m_data[i] = MapNode(biome->c_filler);
                                                nplaced++;
                                        } else if (c == c_stone) {
                                                have_air = false;
index bcf362ac92a66b92086b556ad0bc2c2780959869..8a02bf56465728499614fbef7e44e61578d40a1c 100644 (file)
@@ -114,7 +114,7 @@ public:
        int generateMountainTerrain(int ymax);
        void generateRidgeTerrain();
 
-       void generateBiomes();
+       void generateBiomes(float *heat_map, float *humidity_map);
        void dustTopNodes();
 
        //void addTopNodes();
index 0d17ae5ed4fd0a19a8fe52123fbc02ffa0d6b190..e076d30922dcdcf48591c1ccb1ca4ae92119d6dc 100644 (file)
@@ -43,7 +43,6 @@ BiomeManager::BiomeManager(IGameDef *gamedef) :
        b->flags           = 0;
        b->depth_top       = 0;
        b->depth_filler    = 0;
-       b->height_shore    = 0;
        b->depth_water_top = 0;
        b->y_min           = -MAP_GENERATION_LIMIT;
        b->y_max           = MAP_GENERATION_LIMIT;
@@ -53,9 +52,6 @@ BiomeManager::BiomeManager(IGameDef *gamedef) :
        NodeResolveInfo *nri = new NodeResolveInfo(b);
        nri->nodenames.push_back("air");
        nri->nodenames.push_back("air");
-       nri->nodenames.push_back("air");
-       nri->nodenames.push_back("air");
-       nri->nodenames.push_back("air");
        nri->nodenames.push_back("mapgen_stone");
        nri->nodenames.push_back("mapgen_water_source");
        nri->nodenames.push_back("mapgen_water_source");
@@ -126,9 +122,6 @@ void Biome::resolveNodeNames(NodeResolveInfo *nri)
 {
        m_ndef->getIdFromResolveInfo(nri, "mapgen_dirt_with_grass", CONTENT_AIR,    c_top);
        m_ndef->getIdFromResolveInfo(nri, "mapgen_dirt",            CONTENT_AIR,    c_filler);
-       m_ndef->getIdFromResolveInfo(nri, "mapgen_sand",            CONTENT_AIR,    c_shore_top);
-       m_ndef->getIdFromResolveInfo(nri, "mapgen_sand",            CONTENT_AIR,    c_shore_filler);
-       m_ndef->getIdFromResolveInfo(nri, "mapgen_sand",            CONTENT_AIR,    c_underwater);
        m_ndef->getIdFromResolveInfo(nri, "mapgen_stone",           CONTENT_AIR,    c_stone);
        m_ndef->getIdFromResolveInfo(nri, "mapgen_water_source",    CONTENT_AIR,    c_water_top);
        m_ndef->getIdFromResolveInfo(nri, "mapgen_water_source",    CONTENT_AIR,    c_water);
index 3577960a9890494b2aebb164f0094ee076f18b6c..3648c085dfec21f27f46f08b892c3b63f44124f9 100644 (file)
@@ -39,9 +39,6 @@ public:
 
        content_t c_top;
        content_t c_filler;
-       content_t c_shore_top;
-       content_t c_shore_filler;
-       content_t c_underwater;
        content_t c_stone;
        content_t c_water_top;
        content_t c_water;
@@ -49,7 +46,6 @@ public:
 
        s16 depth_top;
        s16 depth_filler;
-       s16 height_shore;
        s16 depth_water_top;
 
        s16 y_min;
index d470cef883ccd9b72493916f982a4def90c4f993..f14b0dfcba0e60c70dfc7107606dbfee8b06d5f1 100644 (file)
@@ -444,8 +444,7 @@ int ModApiMapgen::l_register_biome(lua_State *L)
 
        b->name            = getstringfield_default(L, index, "name", "");
        b->depth_top       = getintfield_default(L, index, "depth_top",          1);
-       b->depth_filler    = getintfield_default(L, index, "depth_filler",       3);
-       b->height_shore    = getintfield_default(L, index, "height_shore",       3);
+       b->depth_filler    = getintfield_default(L, index, "depth_filler",       2);
        b->depth_water_top = getintfield_default(L, index, "depth_water_top",    0);
        b->y_min           = getintfield_default(L, index, "y_min",         -31000);
        b->y_max           = getintfield_default(L, index, "y_max",          31000);
@@ -463,9 +462,6 @@ int ModApiMapgen::l_register_biome(lua_State *L)
        std::list<std::string> &nnames = nri->nodenames;
        nnames.push_back(getstringfield_default(L, index, "node_top",          ""));
        nnames.push_back(getstringfield_default(L, index, "node_filler",       ""));
-       nnames.push_back(getstringfield_default(L, index, "node_shore_top",    ""));
-       nnames.push_back(getstringfield_default(L, index, "node_shore_filler", ""));
-       nnames.push_back(getstringfield_default(L, index, "node_underwater",   ""));
        nnames.push_back(getstringfield_default(L, index, "node_stone",        ""));
        nnames.push_back(getstringfield_default(L, index, "node_water_top",    ""));
        nnames.push_back(getstringfield_default(L, index, "node_water",        ""));