Mapgen: Combine generateBiomes, dustTopNodes, and generateCaves
authorkwolekr <kwolekr@minetest.net>
Mon, 2 May 2016 06:24:57 +0000 (02:24 -0400)
committerkwolekr <kwolekr@minetest.net>
Sat, 28 May 2016 03:23:58 +0000 (23:23 -0400)
This commit condenses the above methods into a single implementation used by
V7, V5, Flat, Fractal, and Valleys mapgens and introduces MapgenBasic.

12 files changed:
src/mapgen.cpp
src/mapgen.h
src/mapgen_flat.cpp
src/mapgen_flat.h
src/mapgen_fractal.cpp
src/mapgen_fractal.h
src/mapgen_v5.cpp
src/mapgen_v5.h
src/mapgen_v7.cpp
src/mapgen_v7.h
src/mapgen_valleys.cpp
src/mapgen_valleys.h

index e269bf4545b88345953bebf5bdb9b5cd3a4c72fd..f491ed9ebe9cd3f40f7790d5ee87dc12f45c981f 100644 (file)
@@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/numeric.h"
 #include "filesys.h"
 #include "log.h"
+#include "cavegen.h"
 
 FlagDesc flagdesc_mapgen[] = {
        {"trees",       MG_TREES},
@@ -369,6 +370,241 @@ void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax)
 }
 
 
+////
+//// MapgenBasic
+////
+
+MapgenBasic::MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge)
+       : Mapgen(mapgenid, params, emerge)
+{
+
+}
+
+MgStoneType MapgenBasic::generateBiomes()
+{
+       v3s16 em = vm->m_area.getExtent();
+       u32 index = 0;
+       MgStoneType stone_type = STONE;
+
+       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 = NULL;
+               u16 depth_top = 0;
+               u16 base_filler = 0;
+               u16 depth_water_top = 0;
+               u32 vi = vm->m_area.index(x, node_max.Y, z);
+
+               // Check node at base of mapchunk above, either a node of a previously
+               // generated mapchunk or if not, a node of overgenerated base terrain.
+               content_t c_above = vm->m_data[vi + em.X].getContent();
+               bool air_above = c_above == CONTENT_AIR;
+               bool water_above = (c_above == c_water_source || c_above == c_river_water_source);
+
+               // If there is air or water above enable top/filler placement, otherwise force
+               // nplaced to stone level by setting a number exceeding any possible filler depth.
+               u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
+
+               for (s16 y = node_max.Y; y >= node_min.Y; y--) {
+                       content_t c = vm->m_data[vi].getContent();
+
+                       // Biome is recalculated each time an upper surface is detected while
+                       // working down a column. The selected biome then remains in effect for
+                       // all nodes below until the next surface and biome recalculation.
+                       // Biome is recalculated:
+                       // 1. At the surface of stone below air or water.
+                       // 2. At the surface of water below air.
+                       // 3. When stone or water is detected but biome has not yet been calculated.
+                       if ((c == c_stone && (air_above || water_above || !biome))
+                                       || ((c == c_water_source || c == c_river_water_source)
+                                               && (air_above || !biome))) {
+                               biome = biomegen->getBiomeAtIndex(index, y);
+
+                               depth_top = biome->depth_top;
+                               base_filler = MYMAX(depth_top
+                                               + biome->depth_filler
+                                               + noise_filler_depth->result[index], 0.f);
+                               depth_water_top = biome->depth_water_top;
+
+                               // Detect stone type for dungeons during every biome calculation.
+                               // This is more efficient than detecting per-node and will not
+                               // miss any desert stone or sandstone biomes.
+                               if (biome->c_stone == c_desert_stone)
+                                       stone_type = DESERT_STONE;
+                               else if (biome->c_stone == c_sandstone)
+                                       stone_type = SANDSTONE;
+                       }
+
+                       if (c == c_stone) {
+                               content_t c_below = vm->m_data[vi - em.X].getContent();
+
+                               // If the node below isn't solid, make this node stone, so that
+                               // any top/filler nodes above are structurally supported.
+                               // This is done by aborting the cycle of top/filler placement
+                               // immediately by forcing nplaced to stone level.
+                               if (c_below == CONTENT_AIR
+                                               || c_below == c_water_source
+                                               || c_below == c_river_water_source)
+                                       nplaced = U16_MAX;
+
+                               if (nplaced < depth_top) {
+                                       vm->m_data[vi] = MapNode(biome->c_top);
+                                       nplaced++;
+                               } else if (nplaced < base_filler) {
+                                       vm->m_data[vi] = MapNode(biome->c_filler);
+                                       nplaced++;
+                               } else {
+                                       vm->m_data[vi] = MapNode(biome->c_stone);
+                               }
+
+                               air_above = false;
+                               water_above = false;
+                       } else if (c == c_water_source) {
+                               vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top))
+                                               ? biome->c_water_top : biome->c_water);
+                               nplaced = 0;  // Enable top/filler placement for next surface
+                               air_above = false;
+                               water_above = true;
+                       } else if (c == c_river_water_source) {
+                               vm->m_data[vi] = MapNode(biome->c_river_water);
+                               nplaced = depth_top;  // Enable filler placement for next surface
+                               air_above = false;
+                               water_above = true;
+                       } else if (c == CONTENT_AIR) {
+                               nplaced = 0;  // Enable top/filler placement for next surface
+                               air_above = true;
+                               water_above = false;
+                       } else {  // Possible various nodes overgenerated from neighbouring mapchunks
+                               nplaced = U16_MAX;  // Disable top/filler placement
+                               air_above = false;
+                               water_above = false;
+                       }
+
+                       vm->m_area.add_y(em, vi, -1);
+               }
+       }
+
+       return stone_type;
+}
+
+
+void MapgenBasic::dustTopNodes()
+{
+       if (node_max.Y < water_level)
+               return;
+
+       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++) {
+               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
+
+               if (biome->c_dust == CONTENT_IGNORE)
+                       continue;
+
+               u32 vi = vm->m_area.index(x, full_node_max.Y, z);
+               content_t c_full_max = vm->m_data[vi].getContent();
+               s16 y_start;
+
+               if (c_full_max == CONTENT_AIR) {
+                       y_start = full_node_max.Y - 1;
+               } else if (c_full_max == CONTENT_IGNORE) {
+                       vi = vm->m_area.index(x, node_max.Y + 1, z);
+                       content_t c_max = vm->m_data[vi].getContent();
+
+                       if (c_max == CONTENT_AIR)
+                               y_start = node_max.Y;
+                       else
+                               continue;
+               } else {
+                       continue;
+               }
+
+               vi = vm->m_area.index(x, y_start, z);
+               for (s16 y = y_start; y >= node_min.Y - 1; 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 (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
+                       vm->m_area.add_y(em, vi, 1);
+                       vm->m_data[vi] = MapNode(biome->c_dust);
+               }
+       }
+}
+
+
+void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth)
+{
+       if (max_stone_y < node_min.Y)
+               return;
+
+       noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
+       noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
+
+       v3s16 em = vm->m_area.getExtent();
+       u32 index2d = 0;
+
+       for (s16 z = node_min.Z; z <= node_max.Z; z++)
+       for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
+               bool column_is_open = false;  // Is column open to overground
+               bool is_tunnel = false;  // Is tunnel or tunnel floor
+               u32 vi = vm->m_area.index(x, node_max.Y, z);
+               u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
+                       (x - node_min.X);
+               // Biome of column
+               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
+
+               // Don't excavate the overgenerated stone at node_max.Y + 1,
+               // this creates a 'roof' over the tunnel, preventing light in
+               // tunnels at mapchunk borders when generating mapchunks upwards.
+               // This 'roof' is removed when the mapchunk above is generated.
+               for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
+                               index3d -= ystride,
+                               vm->m_area.add_y(em, vi, -1)) {
+
+                       content_t c = vm->m_data[vi].getContent();
+                       if (c == CONTENT_AIR || c == biome->c_water_top ||
+                                       c == biome->c_water) {
+                               column_is_open = true;
+                               continue;
+                       }
+                       // Ground
+                       float d1 = contour(noise_cave1->result[index3d]);
+                       float d2 = contour(noise_cave2->result[index3d]);
+
+                       if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) {
+                               // In tunnel and ground content, excavate
+                               vm->m_data[vi] = MapNode(CONTENT_AIR);
+                               is_tunnel = true;
+                       } else {
+                               // Not in tunnel or not ground content
+                               if (is_tunnel && column_is_open &&
+                                               (c == biome->c_filler || c == biome->c_stone))
+                                       // Tunnel entrance floor
+                                       vm->m_data[vi] = MapNode(biome->c_top);
+
+                               column_is_open = false;
+                               is_tunnel = false;
+                       }
+               }
+       }
+
+       if (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++) {
+               CaveV5 cave(this, &ps);       ////caves version varies  ---- todo- fix this!
+               cave.makeCave(node_min, node_max, max_stone_y);
+       }
+}
+
+
 ////
 //// GenerateNotifier
 ////
index 554ec6084c74a0f7d31d028e96ccffb33754a261..bee8e786a702d306ddaddfc0bd2fbe2f00a840a4 100644 (file)
@@ -46,6 +46,7 @@ extern FlagDesc flagdesc_gennotify[];
 class Biome;
 class BiomeGen;
 struct BiomeParams;
+class BiomeManager;
 class EmergeManager;
 class MapBlock;
 class VoxelManipulator;
@@ -137,6 +138,16 @@ struct MapgenParams {
        void save(Settings &settings) const;
 };
 
+
+/*
+       Generic interface for map generators.  All mapgens must inherit this class.
+       If a feature exposed by a public member pointer is not supported by a
+       certain mapgen, it must be set to NULL.
+
+       Apart from makeChunk, getGroundLevelAtPoint, and getSpawnLevelAtPoint, all
+       methods can be used by constructing a Mapgen base class and setting the
+       appropriate public members (e.g. vm, ndef, and so on).
+*/
 class Mapgen {
 public:
        int seed;
@@ -189,6 +200,51 @@ private:
        DISABLE_CLASS_COPY(Mapgen);
 };
 
+/*
+       MapgenBasic is a Mapgen implementation that handles basic functionality
+       the majority of conventional mapgens will probably want to use, but isn't
+       generic enough to be included as part of the base Mapgen class (such as
+       generating biome terrain over terrain node skeletons, generating caves,
+       dungeons, etc.)
+
+       Inherit MapgenBasic instead of Mapgen to add this basic functionality to
+       your mapgen without having to reimplement it.  Feel free to override any of
+       these methods if you desire different or more advanced behavior.
+
+       Note that you must still create your own generateTerrain implementation when
+       inheriting MapgenBasic.
+*/
+class MapgenBasic : public Mapgen {
+public:
+       EmergeManager *m_emerge;
+       BiomeManager *bmgr;
+
+       Noise *noise_filler_depth;
+       Noise *noise_cave1;
+       Noise *noise_cave2;
+
+       v3s16 node_min;
+       v3s16 node_max;
+       v3s16 full_node_min;
+       v3s16 full_node_max;
+
+       content_t c_stone;
+       content_t c_water_source;
+       content_t c_river_water_source;
+       content_t c_desert_stone;
+       content_t c_sandstone;
+
+       int ystride;
+       int zstride_1d;
+       float cave_width;
+
+       MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge);
+
+       virtual MgStoneType generateBiomes();
+       virtual void dustTopNodes();
+       virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth);
+};
+
 struct MapgenFactory {
        virtual Mapgen *createMapgen(int mgid, MapgenParams *params,
                EmergeManager *emerge) = 0;
index cb9aa9a8b3d9f4cc6c99af993860a8bd42c5f01c..97f1c4b2a3fe53a8e5e4668859a88178de1e2501 100644 (file)
@@ -50,7 +50,7 @@ FlagDesc flagdesc_mapgen_flat[] = {
 
 
 MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge)
-       : Mapgen(mapgenid, params, emerge)
+       : MapgenBasic(mapgenid, params, emerge)
 {
        this->m_emerge = emerge;
        this->bmgr     = emerge->biomemgr;
@@ -248,7 +248,7 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
        MgStoneType stone_type = generateBiomes();
 
        if (flags & MG_CAVES)
-               generateCaves(stone_surface_max_y);
+               generateCaves(stone_surface_max_y, large_cave_depth);
 
        if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
                DungeonParams dp;
@@ -381,220 +381,3 @@ s16 MapgenFlat::generateTerrain()
 
        return stone_surface_max_y;
 }
-
-
-MgStoneType MapgenFlat::generateBiomes()
-{
-       v3s16 em = vm->m_area.getExtent();
-       u32 index = 0;
-       MgStoneType stone_type = STONE;
-
-       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 = NULL;
-               u16 depth_top = 0;
-               u16 base_filler = 0;
-               u16 depth_water_top = 0;
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-
-               // Check node at base of mapchunk above, either a node of a previously
-               // generated mapchunk or if not, a node of overgenerated base terrain.
-               content_t c_above = vm->m_data[vi + em.X].getContent();
-               bool air_above = c_above == CONTENT_AIR;
-               bool water_above = c_above == c_water_source;
-
-               // If there is air or water above enable top/filler placement, otherwise force
-               // nplaced to stone level by setting a number exceeding any possible filler depth.
-               u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
-
-
-               for (s16 y = node_max.Y; y >= node_min.Y; y--) {
-                       content_t c = vm->m_data[vi].getContent();
-
-                       // Biome is recalculated each time an upper surface is detected while
-                       // working down a column. The selected biome then remains in effect for
-                       // all nodes below until the next surface and biome recalculation.
-                       // Biome is recalculated:
-                       // 1. At the surface of stone below air or water.
-                       // 2. At the surface of water below air.
-                       // 3. When stone or water is detected but biome has not yet been calculated.
-                       if ((c == c_stone && (air_above || water_above || !biome)) ||
-                                       (c == c_water_source && (air_above || !biome))) {
-                               biome = biomegen->getBiomeAtIndex(index, y);
-
-                               depth_top = biome->depth_top;
-                               base_filler = MYMAX(depth_top + biome->depth_filler
-                                       + noise_filler_depth->result[index], 0);
-                               depth_water_top = biome->depth_water_top;
-
-                               // Detect stone type for dungeons during every biome calculation.
-                               // This is more efficient than detecting per-node and will not
-                               // miss any desert stone or sandstone biomes.
-                               if (biome->c_stone == c_desert_stone)
-                                       stone_type = DESERT_STONE;
-                               else if (biome->c_stone == c_sandstone)
-                                       stone_type = SANDSTONE;
-                       }
-
-                       if (c == c_stone) {
-                               content_t c_below = vm->m_data[vi - em.X].getContent();
-
-                               // If the node below isn't solid, make this node stone, so that
-                               // any top/filler nodes above are structurally supported.
-                               // This is done by aborting the cycle of top/filler placement
-                               // immediately by forcing nplaced to stone level.
-                               if (c_below == CONTENT_AIR || c_below == c_water_source)
-                                       nplaced = U16_MAX;
-
-                               if (nplaced < depth_top) {
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-                                       nplaced++;
-                               } else if (nplaced < base_filler) {
-                                       vm->m_data[vi] = MapNode(biome->c_filler);
-                                       nplaced++;
-                               } else {
-                                       vm->m_data[vi] = MapNode(biome->c_stone);
-                               }
-
-                               air_above = false;
-                               water_above = false;
-                       } else if (c == c_water_source) {
-                               vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) ?
-                                               biome->c_water_top : biome->c_water);
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = false;
-                               water_above = true;
-                       } else if (c == CONTENT_AIR) {
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = true;
-                               water_above = false;
-                       } else {  // Possible various nodes overgenerated from neighbouring mapchunks
-                               nplaced = U16_MAX;  // Disable top/filler placement
-                               air_above = false;
-                               water_above = false;
-                       }
-
-                       vm->m_area.add_y(em, vi, -1);
-               }
-       }
-
-       return stone_type;
-}
-
-
-void MapgenFlat::dustTopNodes()
-{
-       if (node_max.Y < water_level)
-               return;
-
-       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++) {
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
-
-               if (biome->c_dust == CONTENT_IGNORE)
-                       continue;
-
-               u32 vi = vm->m_area.index(x, full_node_max.Y, z);
-               content_t c_full_max = vm->m_data[vi].getContent();
-               s16 y_start;
-
-               if (c_full_max == CONTENT_AIR) {
-                       y_start = full_node_max.Y - 1;
-               } else if (c_full_max == CONTENT_IGNORE) {
-                       vi = vm->m_area.index(x, node_max.Y + 1, z);
-                       content_t c_max = vm->m_data[vi].getContent();
-
-                       if (c_max == CONTENT_AIR)
-                               y_start = node_max.Y;
-                       else
-                               continue;
-               } else {
-                       continue;
-               }
-
-               vi = vm->m_area.index(x, y_start, z);
-               for (s16 y = y_start; y >= node_min.Y - 1; 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 (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
-                       vm->m_area.add_y(em, vi, 1);
-                       vm->m_data[vi] = MapNode(biome->c_dust);
-               }
-       }
-}
-
-
-void MapgenFlat::generateCaves(s16 max_stone_y)
-{
-       if (max_stone_y < node_min.Y)
-               return;
-
-       noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-       noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-
-       v3s16 em = vm->m_area.getExtent();
-       u32 index2d = 0;
-
-       for (s16 z = node_min.Z; z <= node_max.Z; z++)
-       for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
-               bool column_is_open = false;  // Is column open to overground
-               bool is_tunnel = false;  // Is tunnel or tunnel floor
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-               u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
-                       (x - node_min.X);
-               // Biome of column
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
-
-               // Don't excavate the overgenerated stone at node_max.Y + 1,
-               // this creates a 'roof' over the tunnel, preventing light in
-               // tunnels at mapchunk borders when generating mapchunks upwards.
-               // This 'roof' is removed when the mapchunk above is generated.
-               for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
-                               index3d -= ystride,
-                               vm->m_area.add_y(em, vi, -1)) {
-
-                       content_t c = vm->m_data[vi].getContent();
-                       if (c == CONTENT_AIR || c == biome->c_water_top ||
-                                       c == biome->c_water) {
-                               column_is_open = true;
-                               continue;
-                       }
-                       // Ground
-                       float d1 = contour(noise_cave1->result[index3d]);
-                       float d2 = contour(noise_cave2->result[index3d]);
-
-                       if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) {
-                               // In tunnel and ground content, excavate
-                               vm->m_data[vi] = MapNode(CONTENT_AIR);
-                               is_tunnel = true;
-                       } else {
-                               // Not in tunnel or not ground content
-                               if (is_tunnel && column_is_open &&
-                                               (c == biome->c_filler || c == biome->c_stone))
-                                       // Tunnel entrance floor
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-
-                               column_is_open = false;
-                               is_tunnel = false;
-                       }
-               }
-       }
-
-       if (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++) {
-               CaveV5 cave(this, &ps);
-               cave.makeCave(node_min, node_max, max_stone_y);
-       }
-}
index 53fd66a674557809024c22351c896ada67f7e659..2b98c1f31a703b97efd2dc5da2324fe0eb90ebad 100644 (file)
@@ -53,43 +53,19 @@ struct MapgenFlatParams : public MapgenSpecificParams {
        void writeParams(Settings *settings) const;
 };
 
-class MapgenFlat : public Mapgen {
+class MapgenFlat : public MapgenBasic {
 public:
-       EmergeManager *m_emerge;
-       BiomeManager *bmgr;
-
-       int ystride;
-       int zstride_1d;
-
-       v3s16 node_min;
-       v3s16 node_max;
-       v3s16 full_node_min;
-       v3s16 full_node_max;
-
        u32 spflags;
        s16 ground_level;
        s16 large_cave_depth;
-       float cave_width;
        float lake_threshold;
        float lake_steepness;
        float hill_threshold;
        float hill_steepness;
        Noise *noise_terrain;
-       Noise *noise_filler_depth;
-       Noise *noise_cave1;
-       Noise *noise_cave2;
-
-       Noise *noise_heat;
-       Noise *noise_humidity;
-       Noise *noise_heat_blend;
-       Noise *noise_humidity_blend;
 
-       content_t c_stone;
-       content_t c_water_source;
        content_t c_lava_source;
-       content_t c_desert_stone;
        content_t c_ice;
-       content_t c_sandstone;
 
        content_t c_cobble;
        content_t c_stair_cobble;
@@ -104,9 +80,6 @@ public:
        int getSpawnLevelAtPoint(v2s16 p);
        void calculateNoise();
        s16 generateTerrain();
-       MgStoneType generateBiomes();
-       void dustTopNodes();
-       void generateCaves(s16 max_stone_y);
 };
 
 struct MapgenFactoryFlat : public MapgenFactory {
index 9671a21438e19c25a19b93df0b6a831d11e86ab1..81e1620722e79fcbfe3099e37386c2f48eceb678 100644 (file)
@@ -48,7 +48,7 @@ FlagDesc flagdesc_mapgen_fractal[] = {
 
 
 MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge)
-       : Mapgen(mapgenid, params, emerge)
+       : MapgenBasic(mapgenid, params, emerge)
 {
        this->m_emerge = emerge;
        this->bmgr     = emerge->biomemgr;
@@ -264,7 +264,7 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
        MgStoneType stone_type = generateBiomes();
 
        if (flags & MG_CAVES)
-               generateCaves(stone_surface_max_y);
+               generateCaves(stone_surface_max_y, MGFRACTAL_LARGE_CAVE_DEPTH);
 
        if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
                DungeonParams dp;
@@ -505,220 +505,3 @@ s16 MapgenFractal::generateTerrain()
 
        return stone_surface_max_y;
 }
-
-
-MgStoneType MapgenFractal::generateBiomes()
-{
-       v3s16 em = vm->m_area.getExtent();
-       u32 index = 0;
-       MgStoneType stone_type = STONE;
-
-       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 = NULL;
-               u16 depth_top = 0;
-               u16 base_filler = 0;
-               u16 depth_water_top = 0;
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-
-               // Check node at base of mapchunk above, either a node of a previously
-               // generated mapchunk or if not, a node of overgenerated base terrain.
-               content_t c_above = vm->m_data[vi + em.X].getContent();
-               bool air_above = c_above == CONTENT_AIR;
-               bool water_above = c_above == c_water_source;
-
-               // If there is air or water above enable top/filler placement, otherwise force
-               // nplaced to stone level by setting a number exceeding any possible filler depth.
-               u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
-
-
-               for (s16 y = node_max.Y; y >= node_min.Y; y--) {
-                       content_t c = vm->m_data[vi].getContent();
-
-                       // Biome is recalculated each time an upper surface is detected while
-                       // working down a column. The selected biome then remains in effect for
-                       // all nodes below until the next surface and biome recalculation.
-                       // Biome is recalculated:
-                       // 1. At the surface of stone below air or water.
-                       // 2. At the surface of water below air.
-                       // 3. When stone or water is detected but biome has not yet been calculated.
-                       if ((c == c_stone && (air_above || water_above || !biome)) ||
-                                       (c == c_water_source && (air_above || !biome))) {
-                               biome = biomegen->getBiomeAtIndex(index, y);
-
-                               depth_top = biome->depth_top;
-                               base_filler = MYMAX(depth_top + biome->depth_filler
-                                       + noise_filler_depth->result[index], 0);
-                               depth_water_top = biome->depth_water_top;
-
-                               // Detect stone type for dungeons during every biome calculation.
-                               // This is more efficient than detecting per-node and will not
-                               // miss any desert stone or sandstone biomes.
-                               if (biome->c_stone == c_desert_stone)
-                                       stone_type = DESERT_STONE;
-                               else if (biome->c_stone == c_sandstone)
-                                       stone_type = SANDSTONE;
-                       }
-
-                       if (c == c_stone) {
-                               content_t c_below = vm->m_data[vi - em.X].getContent();
-
-                               // If the node below isn't solid, make this node stone, so that
-                               // any top/filler nodes above are structurally supported.
-                               // This is done by aborting the cycle of top/filler placement
-                               // immediately by forcing nplaced to stone level.
-                               if (c_below == CONTENT_AIR || c_below == c_water_source)
-                                       nplaced = U16_MAX;
-
-                               if (nplaced < depth_top) {
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-                                       nplaced++;
-                               } else if (nplaced < base_filler) {
-                                       vm->m_data[vi] = MapNode(biome->c_filler);
-                                       nplaced++;
-                               } else {
-                                       vm->m_data[vi] = MapNode(biome->c_stone);
-                               }
-
-                               air_above = false;
-                               water_above = false;
-                       } else if (c == c_water_source) {
-                               vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) ?
-                                               biome->c_water_top : biome->c_water);
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = false;
-                               water_above = true;
-                       } else if (c == CONTENT_AIR) {
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = true;
-                               water_above = false;
-                       } else {  // Possible various nodes overgenerated from neighbouring mapchunks
-                               nplaced = U16_MAX;  // Disable top/filler placement
-                               air_above = false;
-                               water_above = false;
-                       }
-
-                       vm->m_area.add_y(em, vi, -1);
-               }
-       }
-
-       return stone_type;
-}
-
-
-void MapgenFractal::dustTopNodes()
-{
-       if (node_max.Y < water_level)
-               return;
-
-       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++) {
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
-
-               if (biome->c_dust == CONTENT_IGNORE)
-                       continue;
-
-               u32 vi = vm->m_area.index(x, full_node_max.Y, z);
-               content_t c_full_max = vm->m_data[vi].getContent();
-               s16 y_start;
-
-               if (c_full_max == CONTENT_AIR) {
-                       y_start = full_node_max.Y - 1;
-               } else if (c_full_max == CONTENT_IGNORE) {
-                       vi = vm->m_area.index(x, node_max.Y + 1, z);
-                       content_t c_max = vm->m_data[vi].getContent();
-
-                       if (c_max == CONTENT_AIR)
-                               y_start = node_max.Y;
-                       else
-                               continue;
-               } else {
-                       continue;
-               }
-
-               vi = vm->m_area.index(x, y_start, z);
-               for (s16 y = y_start; y >= node_min.Y - 1; 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 (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
-                       vm->m_area.add_y(em, vi, 1);
-                       vm->m_data[vi] = MapNode(biome->c_dust);
-               }
-       }
-}
-
-
-void MapgenFractal::generateCaves(s16 max_stone_y)
-{
-       if (max_stone_y < node_min.Y)
-               return;
-
-       noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-       noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-
-       v3s16 em = vm->m_area.getExtent();
-       u32 index2d = 0;
-
-       for (s16 z = node_min.Z; z <= node_max.Z; z++)
-       for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
-               bool column_is_open = false;  // Is column open to overground
-               bool is_tunnel = false;  // Is tunnel or tunnel floor
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-               u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
-                       (x - node_min.X);
-               // Biome of column
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
-
-               // Don't excavate the overgenerated stone at node_max.Y + 1,
-               // this creates a 'roof' over the tunnel, preventing light in
-               // tunnels at mapchunk borders when generating mapchunks upwards.
-               // This 'roof' is removed when the mapchunk above is generated.
-               for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
-                               index3d -= ystride,
-                               vm->m_area.add_y(em, vi, -1)) {
-
-                       content_t c = vm->m_data[vi].getContent();
-                       if (c == CONTENT_AIR || c == biome->c_water_top ||
-                                       c == biome->c_water) {
-                               column_is_open = true;
-                               continue;
-                       }
-                       // Ground
-                       float d1 = contour(noise_cave1->result[index3d]);
-                       float d2 = contour(noise_cave2->result[index3d]);
-
-                       if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) {
-                               // In tunnel and ground content, excavate
-                               vm->m_data[vi] = MapNode(CONTENT_AIR);
-                               is_tunnel = true;
-                       } else {
-                               // Not in tunnel or not ground content
-                               if (is_tunnel && column_is_open &&
-                                               (c == biome->c_filler || c == biome->c_stone))
-                                       // Tunnel entrance floor
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-
-                               column_is_open = false;
-                               is_tunnel = false;
-                       }
-               }
-       }
-
-       if (node_max.Y > MGFRACTAL_LARGE_CAVE_DEPTH)
-               return;
-
-       PseudoRandom ps(blockseed + 21343);
-       u32 bruises_count = ps.range(0, 2);
-       for (u32 i = 0; i < bruises_count; i++) {
-               CaveV5 cave(this, &ps);
-               cave.makeCave(node_min, node_max, max_stone_y);
-       }
-}
index a0e51b2c62b0d11458c04df135cf4e2879a80d15..176885d46bfe309a3d7a3aedcba2fd0b0c043a17 100644 (file)
@@ -57,23 +57,12 @@ struct MapgenFractalParams : public MapgenSpecificParams {
        void writeParams(Settings *settings) const;
 };
 
-class MapgenFractal : public Mapgen {
+class MapgenFractal : public MapgenBasic {
 public:
-       EmergeManager *m_emerge;
-       BiomeManager *bmgr;
-
-       int ystride;
-       int zstride_1d;
        u16 formula;
        bool julia;
 
-       v3s16 node_min;
-       v3s16 node_max;
-       v3s16 full_node_min;
-       v3s16 full_node_max;
-
        u32 spflags;
-       float cave_width;
        u16 fractal;
        u16 iterations;
        v3f scale;
@@ -84,16 +73,9 @@ public:
        float julia_z;
        float julia_w;
        Noise *noise_seabed;
-       Noise *noise_filler_depth;
-       Noise *noise_cave1;
-       Noise *noise_cave2;
 
-       content_t c_stone;
-       content_t c_water_source;
        content_t c_lava_source;
-       content_t c_desert_stone;
        content_t c_ice;
-       content_t c_sandstone;
 
        content_t c_cobble;
        content_t c_stair_cobble;
@@ -109,9 +91,6 @@ public:
        void calculateNoise();
        bool getFractalAtPoint(s16 x, s16 y, s16 z);
        s16 generateTerrain();
-       MgStoneType generateBiomes();
-       void dustTopNodes();
-       void generateCaves(s16 max_stone_y);
 };
 
 struct MapgenFactoryFractal : public MapgenFactory {
index 829a1f432165a58e2aaf06791d9c2b889401a8ac..7698af825cfc1f495bd5338f25197298efc542cf 100644 (file)
@@ -46,7 +46,7 @@ FlagDesc flagdesc_mapgen_v5[] = {
 
 
 MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge)
-       : Mapgen(mapgenid, params, emerge)
+       : MapgenBasic(mapgenid, params, emerge)
 {
        this->m_emerge = emerge;
        this->bmgr     = emerge->biomemgr;
@@ -245,7 +245,7 @@ void MapgenV5::makeChunk(BlockMakeData *data)
 
        // Generate caves
        if ((flags & MG_CAVES) && (stone_surface_max_y >= node_min.Y))
-               generateCaves(stone_surface_max_y);
+               generateCaves(stone_surface_max_y, MGV5_LARGE_CAVE_DEPTH);
 
        // Generate dungeons and desert temples
        if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
@@ -391,220 +391,3 @@ int MapgenV5::generateBaseTerrain()
 
        return stone_surface_max_y;
 }
-
-
-MgStoneType MapgenV5::generateBiomes()
-{
-       v3s16 em = vm->m_area.getExtent();
-       u32 index = 0;
-       MgStoneType stone_type = STONE;
-
-       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 = NULL;
-               u16 depth_top = 0;
-               u16 base_filler = 0;
-               u16 depth_water_top = 0;
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-
-               // Check node at base of mapchunk above, either a node of a previously
-               // generated mapchunk or if not, a node of overgenerated base terrain.
-               content_t c_above = vm->m_data[vi + em.X].getContent();
-               bool air_above = c_above == CONTENT_AIR;
-               bool water_above = c_above == c_water_source;
-
-               // If there is air or water above enable top/filler placement, otherwise force
-               // nplaced to stone level by setting a number exceeding any possible filler depth.
-               u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
-
-               for (s16 y = node_max.Y; y >= node_min.Y; y--) {
-                       content_t c = vm->m_data[vi].getContent();
-
-                       // Biome is recalculated each time an upper surface is detected while
-                       // working down a column. The selected biome then remains in effect for
-                       // all nodes below until the next surface and biome recalculation.
-                       // Biome is recalculated:
-                       // 1. At the surface of stone below air or water.
-                       // 2. At the surface of water below air.
-                       // 3. When stone or water is detected but biome has not yet been calculated.
-                       if ((c == c_stone && (air_above || water_above || !biome)) ||
-                                       (c == c_water_source && (air_above || !biome))) {
-                               biome = biomegen->getBiomeAtIndex(index, y);
-
-                               depth_top = biome->depth_top;
-                               base_filler = MYMAX(depth_top + biome->depth_filler
-                                               + noise_filler_depth->result[index], 0);
-                               depth_water_top = biome->depth_water_top;
-
-                               // Detect stone type for dungeons during every biome calculation.
-                               // This is more efficient than detecting per-node and will not
-                               // miss any desert stone or sandstone biomes.
-                               if (biome->c_stone == c_desert_stone)
-                                       stone_type = DESERT_STONE;
-                               else if (biome->c_stone == c_sandstone)
-                                       stone_type = SANDSTONE;
-                       }
-
-                       if (c == c_stone) {
-                               content_t c_below = vm->m_data[vi - em.X].getContent();
-
-                               // If the node below isn't solid, make this node stone, so that
-                               // any top/filler nodes above are structurally supported.
-                               // This is done by aborting the cycle of top/filler placement
-                               // immediately by forcing nplaced to stone level.
-                               if (c_below == CONTENT_AIR || c_below == c_water_source)
-                                       nplaced = U16_MAX;
-
-                               if (nplaced < depth_top) {
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-                                       nplaced++;
-                               } else if (nplaced < base_filler) {
-                                       vm->m_data[vi] = MapNode(biome->c_filler);
-                                       nplaced++;
-                               } else {
-                                       vm->m_data[vi] = MapNode(biome->c_stone);
-                               }
-
-                               air_above = false;
-                               water_above = false;
-                       } else if (c == c_water_source) {
-                               vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) ?
-                                               biome->c_water_top : biome->c_water);
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = false;
-                               water_above = true;
-                       } else if (c == CONTENT_AIR) {
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = true;
-                               water_above = false;
-                       } else {  // Possible various nodes overgenerated from neighbouring mapchunks
-                               nplaced = U16_MAX;  // Disable top/filler placement
-                               air_above = false;
-                               water_above = false;
-                       }
-
-                       vm->m_area.add_y(em, vi, -1);
-               }
-       }
-
-       return stone_type;
-}
-
-
-void MapgenV5::dustTopNodes()
-{
-       if (node_max.Y < water_level)
-               return;
-
-       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++) {
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
-
-               if (biome->c_dust == CONTENT_IGNORE)
-                       continue;
-
-               u32 vi = vm->m_area.index(x, full_node_max.Y, z);
-               content_t c_full_max = vm->m_data[vi].getContent();
-               s16 y_start;
-
-               if (c_full_max == CONTENT_AIR) {
-                       y_start = full_node_max.Y - 1;
-               } else if (c_full_max == CONTENT_IGNORE) {
-                       vi = vm->m_area.index(x, node_max.Y + 1, z);
-                       content_t c_max = vm->m_data[vi].getContent();
-
-                       if (c_max == CONTENT_AIR)
-                               y_start = node_max.Y;
-                       else
-                               continue;
-               } else {
-                       continue;
-               }
-
-               vi = vm->m_area.index(x, y_start, z);
-               for (s16 y = y_start; y >= node_min.Y - 1; 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 (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
-                       vm->m_area.add_y(em, vi, 1);
-                       vm->m_data[vi] = MapNode(biome->c_dust);
-               }
-       }
-}
-
-
-void MapgenV5::generateCaves(int max_stone_y)
-{
-       if (max_stone_y < node_min.Y)
-               return;
-
-       noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-       noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-
-       v3s16 em = vm->m_area.getExtent();
-       u32 index2d = 0;
-
-       for (s16 z = node_min.Z; z <= node_max.Z; z++)
-       for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
-               bool column_is_open = false;  // Is column open to overground
-               bool is_tunnel = false;  // Is tunnel or tunnel floor
-               // Indexes at column top (node_max.Y)
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-               u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
-                       (x - node_min.X);
-               // Biome of column
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
-
-               // Don't excavate the overgenerated stone at node_max.Y + 1,
-               // this creates a 'roof' over the tunnel, preventing light in
-               // tunnels at mapchunk borders when generating mapchunks upwards.
-               // This 'roof' is removed when the mapchunk above is generated.
-               for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
-                               index3d -= ystride,
-                               vm->m_area.add_y(em, vi, -1)) {
-
-                       content_t c = vm->m_data[vi].getContent();
-                       if (c == CONTENT_AIR || c == biome->c_water_top ||
-                                       c == biome->c_water) {
-                               column_is_open = true;
-                               continue;
-                       }
-                       // Ground
-                       float d1 = contour(noise_cave1->result[index3d]);
-                       float d2 = contour(noise_cave2->result[index3d]);
-
-                       if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) {
-                               // In tunnel and ground content, excavate
-                               vm->m_data[vi] = MapNode(CONTENT_AIR);
-                               is_tunnel = true;
-                       } else {
-                               // Not in tunnel or not ground content
-                               if (is_tunnel && column_is_open &&
-                                               (c == biome->c_filler || c == biome->c_stone))
-                                       // Tunnel entrance floor
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-
-                               column_is_open = false;
-                               is_tunnel = false;
-                       }
-               }
-       }
-
-       if (node_max.Y > MGV5_LARGE_CAVE_DEPTH)
-               return;
-
-       PseudoRandom ps(blockseed + 21343);
-       u32 bruises_count = ps.range(0, 2);
-       for (u32 i = 0; i < bruises_count; i++) {
-               CaveV5 cave(this, &ps);
-               cave.makeCave(node_min, node_max, max_stone_y);
-       }
-}
index eef3da617816150f3db86150363ec922bc68c80f..99836b23e0bad597119b6b82412a5a10614cfc12 100644 (file)
@@ -48,34 +48,15 @@ struct MapgenV5Params : public MapgenSpecificParams {
 };
 
 
-class MapgenV5 : public Mapgen {
+class MapgenV5 : public MapgenBasic {
 public:
-       EmergeManager *m_emerge;
-       BiomeManager *bmgr;
-
-       int ystride;
-       int zstride_1d;
-
-       v3s16 node_min;
-       v3s16 node_max;
-       v3s16 full_node_min;
-       v3s16 full_node_max;
-
        u32 spflags;
-       float cave_width;
-       Noise *noise_filler_depth;
        Noise *noise_factor;
        Noise *noise_height;
-       Noise *noise_cave1;
-       Noise *noise_cave2;
        Noise *noise_ground;
 
-       content_t c_stone;
-       content_t c_water_source;
        content_t c_lava_source;
-       content_t c_desert_stone;
        content_t c_ice;
-       content_t c_sandstone;
 
        content_t c_cobble;
        content_t c_stair_cobble;
@@ -90,9 +71,6 @@ public:
        int getSpawnLevelAtPoint(v2s16 p);
        void calculateNoise();
        int generateBaseTerrain();
-       MgStoneType generateBiomes();
-       void generateCaves(int max_stone_y);
-       void dustTopNodes();
 };
 
 
index fddb346827347c39a3dfca64d9e33895f701f73f..ee609bc956ef6a735b3bf20bf0776742699c6de1 100644 (file)
@@ -51,7 +51,7 @@ FlagDesc flagdesc_mapgen_v7[] = {
 
 
 MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
-       : Mapgen(mapgenid, params, emerge)
+       : MapgenBasic(mapgenid, params, emerge)
 {
        this->m_emerge = emerge;
        this->bmgr     = emerge->biomemgr;
@@ -276,7 +276,7 @@ void MapgenV7::makeChunk(BlockMakeData *data)
        MgStoneType stone_type = generateBiomes();
 
        if (flags & MG_CAVES)
-               generateCaves(stone_surface_max_y);
+               generateCaves(stone_surface_max_y, water_level);
 
        if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
                DungeonParams dp;
@@ -517,225 +517,13 @@ void MapgenV7::generateRidgeTerrain()
 }
 
 
-MgStoneType MapgenV7::generateBiomes()
-{
-       v3s16 em = vm->m_area.getExtent();
-       u32 index = 0;
-       MgStoneType stone_type = STONE;
-
-       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 = NULL;
-               u16 depth_top = 0;
-               u16 base_filler = 0;
-               u16 depth_water_top = 0;
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-
-               // Check node at base of mapchunk above, either a node of a previously
-               // generated mapchunk or if not, a node of overgenerated base terrain.
-               content_t c_above = vm->m_data[vi + em.X].getContent();
-               bool air_above = c_above == CONTENT_AIR;
-               bool water_above = c_above == c_water_source;
-
-               // If there is air or water above enable top/filler placement, otherwise force
-               // nplaced to stone level by setting a number exceeding any possible filler depth.
-               u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
-
-               for (s16 y = node_max.Y; y >= node_min.Y; y--) {
-                       content_t c = vm->m_data[vi].getContent();
-
-                       // Biome is recalculated each time an upper surface is detected while
-                       // working down a column. The selected biome then remains in effect for
-                       // all nodes below until the next surface and biome recalculation.
-                       // Biome is recalculated:
-                       // 1. At the surface of stone below air or water.
-                       // 2. At the surface of water below air.
-                       // 3. When stone or water is detected but biome has not yet been calculated.
-                       if ((c == c_stone && (air_above || water_above || !biome)) ||
-                                       (c == c_water_source && (air_above || !biome))) {
-                               biome = biomegen->getBiomeAtIndex(index, y);
-
-                               depth_top = biome->depth_top;
-                               base_filler = MYMAX(depth_top + biome->depth_filler
-                                               + noise_filler_depth->result[index], 0);
-                               depth_water_top = biome->depth_water_top;
-
-                               // Detect stone type for dungeons during every biome calculation.
-                               // This is more efficient than detecting per-node and will not
-                               // miss any desert stone or sandstone biomes.
-                               if (biome->c_stone == c_desert_stone)
-                                       stone_type = DESERT_STONE;
-                               else if (biome->c_stone == c_sandstone)
-                                       stone_type = SANDSTONE;
-                       }
-
-                       if (c == c_stone) {
-                               content_t c_below = vm->m_data[vi - em.X].getContent();
-
-                               // If the node below isn't solid, make this node stone, so that
-                               // any top/filler nodes above are structurally supported.
-                               // This is done by aborting the cycle of top/filler placement
-                               // immediately by forcing nplaced to stone level.
-                               if (c_below == CONTENT_AIR || c_below == c_water_source)
-                                       nplaced = U16_MAX;
-
-                               if (nplaced < depth_top) {
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-                                       nplaced++;
-                               } else if (nplaced < base_filler) {
-                                       vm->m_data[vi] = MapNode(biome->c_filler);
-                                       nplaced++;
-                               } else {
-                                       vm->m_data[vi] = MapNode(biome->c_stone);
-                               }
-
-                               air_above = false;
-                               water_above = false;
-                       } else if (c == c_water_source) {
-                               vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top)) ?
-                                               biome->c_water_top : biome->c_water);
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = false;
-                               water_above = true;
-                       } else if (c == CONTENT_AIR) {
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = true;
-                               water_above = false;
-                       } else {  // Possible various nodes overgenerated from neighbouring mapchunks
-                               nplaced = U16_MAX;  // Disable top/filler placement
-                               air_above = false;
-                               water_above = false;
-                       }
-
-                       vm->m_area.add_y(em, vi, -1);
-               }
-       }
-
-       return stone_type;
-}
-
-
-void MapgenV7::dustTopNodes()
-{
-       if (node_max.Y < water_level)
-               return;
-
-       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++) {
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
-
-               if (biome->c_dust == CONTENT_IGNORE)
-                       continue;
-
-               u32 vi = vm->m_area.index(x, full_node_max.Y, z);
-               content_t c_full_max = vm->m_data[vi].getContent();
-               s16 y_start;
-
-               if (c_full_max == CONTENT_AIR) {
-                       y_start = full_node_max.Y - 1;
-               } else if (c_full_max == CONTENT_IGNORE) {
-                       vi = vm->m_area.index(x, node_max.Y + 1, z);
-                       content_t c_max = vm->m_data[vi].getContent();
-
-                       if (c_max == CONTENT_AIR)
-                               y_start = node_max.Y;
-                       else
-                               continue;
-               } else {
-                       continue;
-               }
-
-               vi = vm->m_area.index(x, y_start, z);
-               for (s16 y = y_start; y >= node_min.Y - 1; 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 (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
-                       vm->m_area.add_y(em, vi, 1);
-                       vm->m_data[vi] = MapNode(biome->c_dust);
-               }
-       }
-}
-
-
-void MapgenV7::generateCaves(s16 max_stone_y)
-{
-       if (max_stone_y < node_min.Y)
-               return;
-
-       noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-       noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
-
-       v3s16 em = vm->m_area.getExtent();
-       u32 index2d = 0;
-
-       for (s16 z = node_min.Z; z <= node_max.Z; z++)
-       for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
-               bool column_is_open = false;  // Is column open to overground
-               bool is_tunnel = false;  // Is tunnel or tunnel floor
-               // Indexes at column top (node_max.Y)
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-               u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
-                       (x - node_min.X);
-               // Biome of column
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
-
-               // Don't excavate the overgenerated stone at node_max.Y + 1,
-               // this creates a 'roof' over the tunnel, preventing light in
-               // tunnels at mapchunk borders when generating mapchunks upwards.
-               // This 'roof' is removed when the mapchunk above is generated.
-               for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
-                               index3d -= ystride,
-                               vm->m_area.add_y(em, vi, -1)) {
-
-                       content_t c = vm->m_data[vi].getContent();
-                       if (c == CONTENT_AIR || c == biome->c_water_top ||
-                                       c == biome->c_water) {
-                               column_is_open = true;
-                               continue;
-                       }
-                       // Ground
-                       float d1 = contour(noise_cave1->result[index3d]);
-                       float d2 = contour(noise_cave2->result[index3d]);
-
-                       if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) {
-                               // In tunnel and ground content, excavate
-                               vm->m_data[vi] = MapNode(CONTENT_AIR);
-                               is_tunnel = true;
-                       } else {
-                               // Not in tunnel or not ground content
-                               if (is_tunnel && column_is_open &&
-                                               (c == biome->c_filler || c == biome->c_stone))
-                                       // Tunnel entrance floor
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-
-                               column_is_open = false;
-                               is_tunnel = false;
-                       }
-               }
-       }
-
-       if (node_min.Y >= water_level)
-               return;
-
-       PseudoRandom ps(blockseed + 21343);
-       u32 bruises_count = ps.range(0, 2);
-       for (u32 i = 0; i < bruises_count; i++) {
-               CaveV7 cave(this, &ps);
-               cave.makeCave(node_min, node_max, max_stone_y);
-       }
-}
-
-
-///////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////
+//// Code Boneyard
+////
+//// Much of the stuff here has potential to become useful again at some point
+//// in the future, but we don't want it to get lost or forgotten in version
+//// control.
+////
 
 #if 0
 int MapgenV7::generateMountainTerrain(s16 ymax)
index a8dd9986dc04c0ec18d6db6a063aed0eadf413bf..21beab2b493fcb416eb23e9adf262fe9e1a1c246 100644 (file)
@@ -54,42 +54,24 @@ struct MapgenV7Params : public MapgenSpecificParams {
        void writeParams(Settings *settings) const;
 };
 
-class MapgenV7 : public Mapgen {
+class MapgenV7 : public MapgenBasic {
 public:
-       EmergeManager *m_emerge;
-       BiomeManager *bmgr;
-
-       int ystride;
        int zstride_1u1d;
-       int zstride_1d;
-
-       v3s16 node_min;
-       v3s16 node_max;
-       v3s16 full_node_min;
-       v3s16 full_node_max;
 
        s16 *ridge_heightmap;
 
        u32 spflags;
-       float cave_width;
        Noise *noise_terrain_base;
        Noise *noise_terrain_alt;
        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_cave1;
-       Noise *noise_cave2;
 
-       content_t c_stone;
-       content_t c_water_source;
        content_t c_lava_source;
-       content_t c_desert_stone;
        content_t c_ice;
-       content_t c_sandstone;
 
        content_t c_cobble;
        content_t c_stair_cobble;
@@ -112,11 +94,6 @@ public:
 
        int generateTerrain();
        void generateRidgeTerrain();
-
-       MgStoneType generateBiomes();
-       void dustTopNodes();
-
-       void generateCaves(s16 max_stone_y);
 };
 
 struct MapgenFactoryV7 : public MapgenFactory {
index 44083d9d34af7d21c93c002c7df9e818cc46bfda..fa790677a638ca4c13f20f0f79caa195a5588cc5 100644 (file)
@@ -65,7 +65,7 @@ static FlagDesc flagdesc_mapgen_valleys[] = {
 
 
 MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge)
-       : Mapgen(mapgenid, params, emerge)
+       : MapgenBasic(mapgenid, params, emerge)
 {
        this->m_emerge = emerge;
        this->bmgr     = emerge->biomemgr;
@@ -302,7 +302,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
 
        // Cave creation.
        if (flags & MG_CAVES)
-               generateCaves(stone_surface_max_y);
+               generateCaves(stone_surface_max_y, large_cave_depth);
 
        // Dungeon creation
        if ((flags & MG_DUNGEONS) && node_max.Y < 50 && (stone_surface_max_y >= node_min.Y)) {
@@ -692,166 +692,7 @@ int MapgenValleys::generateTerrain()
        return surface_max_y;
 }
 
-
-MgStoneType MapgenValleys::generateBiomes()
-{
-       v3s16 em = vm->m_area.getExtent();
-       u32 index = 0;
-       MgStoneType stone_type = STONE;
-
-       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 = NULL;
-               u16 depth_top = 0;
-               u16 base_filler = 0;
-               u16 depth_water_top = 0;
-               u32 vi = vm->m_area.index(x, node_max.Y, z);
-
-               // Check node at base of mapchunk above, either a node of a previously
-               // generated mapchunk or if not, a node of overgenerated base terrain.
-               content_t c_above = vm->m_data[vi + em.X].getContent();
-               bool air_above = c_above == CONTENT_AIR;
-               bool water_above = (c_above == c_water_source || c_above == c_river_water_source);
-
-               // If there is air or water above enable top/filler placement, otherwise force
-               // nplaced to stone level by setting a number exceeding any possible filler depth.
-               u16 nplaced = (air_above || water_above) ? 0 : U16_MAX;
-
-               for (s16 y = node_max.Y; y >= node_min.Y; y--) {
-                       content_t c = vm->m_data[vi].getContent();
-
-                       // Biome is recalculated each time an upper surface is detected while
-                       // working down a column. The selected biome then remains in effect for
-                       // all nodes below until the next surface and biome recalculation.
-                       // Biome is recalculated:
-                       // 1. At the surface of stone below air or water.
-                       // 2. At the surface of water below air.
-                       // 3. When stone or water is detected but biome has not yet been calculated.
-                       if ((c == c_stone && (air_above || water_above || !biome))
-                                       || ((c == c_water_source || c == c_river_water_source)
-                                               && (air_above || !biome))) {
-                               // Both heat and humidity have already been adjusted for altitude.
-                               biome = biomegen->getBiomeAtIndex(index, y);
-
-                               depth_top = biome->depth_top;
-                               base_filler = MYMAX(depth_top
-                                               + biome->depth_filler
-                                               + noise_filler_depth->result[index], 0.f);
-                               depth_water_top = biome->depth_water_top;
-
-                               // Detect stone type for dungeons during every biome calculation.
-                               // This is more efficient than detecting per-node and will not
-                               // miss any desert stone or sandstone biomes.
-                               if (biome->c_stone == c_desert_stone)
-                                       stone_type = DESERT_STONE;
-                               else if (biome->c_stone == c_sandstone)
-                                       stone_type = SANDSTONE;
-                       }
-
-                       if (c == c_stone) {
-                               content_t c_below = vm->m_data[vi - em.X].getContent();
-
-                               // If the node below isn't solid, make this node stone, so that
-                               // any top/filler nodes above are structurally supported.
-                               // This is done by aborting the cycle of top/filler placement
-                               // immediately by forcing nplaced to stone level.
-                               if (c_below == CONTENT_AIR
-                                               || c_below == c_water_source
-                                               || c_below == c_river_water_source)
-                                       nplaced = U16_MAX;
-
-                               if (nplaced < depth_top) {
-                                       vm->m_data[vi] = MapNode(biome->c_top);
-                                       nplaced++;
-                               } else if (nplaced < base_filler) {
-                                       vm->m_data[vi] = MapNode(biome->c_filler);
-                                       nplaced++;
-                               } else {
-                                       vm->m_data[vi] = MapNode(biome->c_stone);
-                               }
-
-                               air_above = false;
-                               water_above = false;
-                       } else if (c == c_water_source) {
-                               vm->m_data[vi] = MapNode((y > (s32)(water_level - depth_water_top))
-                                               ? biome->c_water_top : biome->c_water);
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = false;
-                               water_above = true;
-                       } else if (c == c_river_water_source) {
-                               vm->m_data[vi] = MapNode(biome->c_river_water);
-                               nplaced = depth_top;  // Enable filler placement for next surface
-                               air_above = false;
-                               water_above = true;
-                       } else if (c == CONTENT_AIR) {
-                               nplaced = 0;  // Enable top/filler placement for next surface
-                               air_above = true;
-                               water_above = false;
-                       } else {  // Possible various nodes overgenerated from neighbouring mapchunks
-                               nplaced = U16_MAX;  // Disable top/filler placement
-                               air_above = false;
-                               water_above = false;
-                       }
-
-                       vm->m_area.add_y(em, vi, -1);
-               }
-       }
-
-       return stone_type;
-}
-
-
-void MapgenValleys::dustTopNodes()
-{
-       if (node_max.Y < water_level)
-               return;
-
-       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++) {
-               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
-
-               if (biome->c_dust == CONTENT_IGNORE)
-                       continue;
-
-               u32 vi = vm->m_area.index(x, full_node_max.Y, z);
-               content_t c_full_max = vm->m_data[vi].getContent();
-               s16 y_start;
-
-               if (c_full_max == CONTENT_AIR) {
-                       y_start = full_node_max.Y - 1;
-               } else if (c_full_max == CONTENT_IGNORE) {
-                       vi = vm->m_area.index(x, node_max.Y + 1, z);
-                       content_t c_max = vm->m_data[vi].getContent();
-
-                       if (c_max == CONTENT_AIR)
-                               y_start = node_max.Y;
-                       else
-                               continue;
-               } else {
-                       continue;
-               }
-
-               vi = vm->m_area.index(x, y_start, z);
-               for (s16 y = y_start; y >= node_min.Y - 1; 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 (!ndef->get(c).buildable_to && c != CONTENT_IGNORE && c != biome->c_dust) {
-                       vm->m_area.add_y(em, vi, 1);
-                       vm->m_data[vi] = MapNode(biome->c_dust);
-               }
-       }
-}
-
-
-void MapgenValleys::generateCaves(s16 max_stone_y)
+void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth)
 {
        if (max_stone_y < node_min.Y)
                return;
index 0e268c1cf4e40b1c7d2bf170928de3a85ca60c05..2ab253430e1024980ffdd64b7f0b14f4b0874398 100644 (file)
@@ -85,7 +85,7 @@ struct TerrainNoise {
        float inter_valley_fill;
 };
 
-class MapgenValleys : public Mapgen {
+class MapgenValleys : public MapgenBasic {
 public:
 
        MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge);
@@ -97,13 +97,9 @@ public:
        s16 large_cave_depth;
 
 private:
-       EmergeManager *m_emerge;
-       BiomeManager *bmgr;
        BiomeGenOriginal *m_bgen;
 
-       int ystride;
        int zstride;
-       int zstride_1d;
 
        float map_gen_limit;
 
@@ -113,11 +109,6 @@ private:
        s16 cave_water_max_height;
        s16 lava_max_height;
 
-       v3s16 node_min;
-       v3s16 node_max;
-       v3s16 full_node_min;
-       v3s16 full_node_max;
-
        u32 spflags;
        float altitude_chill;
        s16 lava_features_lim;
@@ -126,10 +117,6 @@ private:
        float river_size_factor;
        float *tcave_cache;
        s16 water_features_lim;
-       float cave_width;
-       Noise *noise_filler_depth;
-       Noise *noise_cave1;
-       Noise *noise_cave2;
        Noise *noise_inter_valley_fill;
        Noise *noise_inter_valley_slope;
        Noise *noise_rivers;
@@ -139,19 +126,13 @@ private:
        Noise *noise_valley_profile;
 
        content_t c_cobble;
-       content_t c_desert_stone;
        content_t c_dirt;
-       content_t c_ice;
        content_t c_lava_source;
        content_t c_mossycobble;
-       content_t c_river_water_source;
        content_t c_sand;
-       content_t c_sandstone;
        content_t c_sandstonebrick;
        content_t c_stair_cobble;
        content_t c_stair_sandstonebrick;
-       content_t c_stone;
-       content_t c_water_source;
 
        float terrainLevelAtPoint(s16 x, s16 z);
 
@@ -161,10 +142,7 @@ private:
        float terrainLevelFromNoise(TerrainNoise *tn);
        float adjustedTerrainLevelFromNoise(TerrainNoise *tn);
 
-       MgStoneType generateBiomes();
-       void dustTopNodes();
-
-       void generateCaves(s16 max_stone_y);
+       virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth);
 };
 
 struct MapgenFactoryValleys : public MapgenFactory {