]> git.lizzy.rs Git - minetest.git/blobdiff - src/mapgen_v5.cpp
Fix RUN_IN_PLACE broken due to invalid usage of assert
[minetest.git] / src / mapgen_v5.cpp
index ed18f7d0b64ac46a632c2393f08f28ff649176e3..ffd16477440009db3da0af70f5e54c746835afdb 100644 (file)
@@ -60,6 +60,8 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
        this->biomemap  = new u8[csize.X * csize.Z];
        this->heightmap = new s16[csize.X * csize.Z];
 
+       initHeightMap(this->heightmap, csize.X * csize.Z);
+
        MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
        this->spflags      = sp->spflags;
 
@@ -171,9 +173,9 @@ int MapgenV5::getGroundLevelAtPoint(v2s16 p)
        //TimeTaker t("getGroundLevelAtPoint", NULL, PRECISION_MICRO);
 
        float f = 0.55 + NoisePerlin2D(&noise_factor->np, p.X, p.Y, seed);
-       if(f < 0.01)
+       if (f < 0.01)
                f = 0.01;
-       else if(f >= 1.0)
+       else if (f >= 1.0)
                f *= 1.6;
        float h = water_level + NoisePerlin2D(&noise_height->np, p.X, p.Y, seed);
 
@@ -183,8 +185,8 @@ int MapgenV5::getGroundLevelAtPoint(v2s16 p)
        s16 level = -31000;
        for (s16 y = search_top; y >= search_base; y--) {
                float n_ground = NoisePerlin3D(&noise_ground->np, p.X, y, p.Y, seed);
-               if(n_ground * f > y - h) {
-                       if(y >= search_top - 7)
+               if (n_ground * f > y - h) {
+                       if (y >= search_top - 7)
                                break;
                        else
                                level = y;
@@ -199,6 +201,7 @@ int MapgenV5::getGroundLevelAtPoint(v2s16 p)
 
 void MapgenV5::makeChunk(BlockMakeData *data)
 {
+       // Pre-conditions
        assert(data->vmanip);
        assert(data->nodedef);
        assert(data->blockpos_requested.X >= data->blockpos_min.X &&
@@ -228,14 +231,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))
@@ -320,22 +325,22 @@ int MapgenV5::generateBaseTerrain()
        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++) {
+       for (s16 z=node_min.Z; z<=node_max.Z; z++) {
+               for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
                        u32 i = vm->m_area.index(node_min.X, y, z);
-                       for(s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) {
-                               if(vm->m_data[i].getContent() != CONTENT_IGNORE)
+                       for (s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) {
+                               if (vm->m_data[i].getContent() != CONTENT_IGNORE)
                                        continue;
 
                                float f = 0.55 + noise_factor->result[index2d];
-                               if(f < 0.01)
+                               if (f < 0.01)
                                        f = 0.01;
-                               else if(f >= 1.0)
+                               else if (f >= 1.0)
                                        f *= 1.6;
                                float h = noise_height->result[index2d];
 
-                               if(noise_ground->result[index] * f < y - h) {
-                                       if(y <= water_level)
+                               if (noise_ground->result[index] * f < y - h) {
+                                       if (y <= water_level)
                                                vm->m_data[i] = MapNode(c_water_source);
                                        else
                                                vm->m_data[i] = MapNode(CONTENT_AIR);
@@ -354,7 +359,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 +373,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 +388,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;
@@ -444,13 +446,13 @@ void MapgenV5::generateCaves(int max_stone_y)
        u32 index = 0;
        u32 index2d = 0;
 
-       for(s16 z=node_min.Z; z<=node_max.Z; z++) {
-               for(s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
+       for (s16 z=node_min.Z; z<=node_max.Z; z++) {
+               for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
                        u32 i = vm->m_area.index(node_min.X, y, z);
-                       for(s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) {
+                       for (s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) {
                                Biome *biome = (Biome *)bmgr->get(biomemap[index2d]);
                                content_t c = vm->m_data[i].getContent();
-                               if(c == CONTENT_AIR
+                               if (c == CONTENT_AIR
                                                || (y <= water_level
                                                && c != biome->c_stone
                                                && c != c_stone))
@@ -458,7 +460,7 @@ void MapgenV5::generateCaves(int max_stone_y)
 
                                float d1 = contour(noise_cave1->result[index]);
                                float d2 = contour(noise_cave2->result[index]);
-                               if(d1*d2 > 0.125)
+                               if (d1*d2 > 0.125)
                                        vm->m_data[i] = MapNode(CONTENT_AIR);
                        }
                        index2d = index2d - ystride;