From 76f485647983ebd7eb4c3abbca0869d13f76920b Mon Sep 17 00:00:00 2001 From: kwolekr Date: Thu, 28 Apr 2016 03:43:09 -0400 Subject: Move biome calculation to BiomeGen BiomeGen defines an interface that, given a set of BiomeParams, computes biomes for a given area using the algorithm implemented by that specific BiomeGen. This abstracts away the old system where each mapgen supplied the noises required for biome generation. --- src/mapgen_v7.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index c25220646..a8dd9986d 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -84,11 +84,6 @@ public: 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; @@ -107,7 +102,6 @@ public: virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); - Biome *getBiomeAtPoint(v3s16 p); float baseTerrainLevelAtPoint(s16 x, s16 z); float baseTerrainLevelFromMap(int index); @@ -119,7 +113,7 @@ public: int generateTerrain(); void generateRidgeTerrain(); - MgStoneType generateBiomes(float *heat_map, float *humidity_map); + MgStoneType generateBiomes(); void dustTopNodes(); void generateCaves(s16 max_stone_y); -- cgit v1.2.3 From 87bc39dca733a2cc805bc1071794c4d5d7937115 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Mon, 2 May 2016 02:24:57 -0400 Subject: Mapgen: Combine generateBiomes, dustTopNodes, and generateCaves This commit condenses the above methods into a single implementation used by V7, V5, Flat, Fractal, and Valleys mapgens and introduces MapgenBasic. --- src/mapgen.cpp | 236 +++++++++++++++++++++++++++++++++++++++++++++++++ src/mapgen.h | 56 ++++++++++++ src/mapgen_flat.cpp | 221 +-------------------------------------------- src/mapgen_flat.h | 29 +----- src/mapgen_fractal.cpp | 221 +-------------------------------------------- src/mapgen_fractal.h | 23 +---- src/mapgen_v5.cpp | 221 +-------------------------------------------- src/mapgen_v5.h | 24 +---- src/mapgen_v7.cpp | 230 ++--------------------------------------------- src/mapgen_v7.h | 25 +----- src/mapgen_valleys.cpp | 165 +--------------------------------- src/mapgen_valleys.h | 26 +----- 12 files changed, 316 insertions(+), 1161 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index e269bf454..f491ed9eb 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -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 //// diff --git a/src/mapgen.h b/src/mapgen.h index 554ec6084..bee8e786a 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -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; diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index cb9aa9a8b..97f1c4b2a 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -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); - } -} diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index 53fd66a67..2b98c1f31 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -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 { diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 9671a2143..81e162072 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -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); - } -} diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index a0e51b2c6..176885d46 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -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 { diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 829a1f432..7698af825 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -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); - } -} diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h index eef3da617..99836b23e 100644 --- a/src/mapgen_v5.h +++ b/src/mapgen_v5.h @@ -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(); }; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index fddb34682..ee609bc95 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -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) diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index a8dd9986d..21beab2b4 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -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 { diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 44083d9d3..fa790677a 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -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; diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 0e268c1cf..2ab253430 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -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 { -- cgit v1.2.3 From c5968049bbf73ceff08a2b1d35bb34192fa3f315 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Thu, 19 May 2016 14:05:51 -0400 Subject: Mapgen V7: Remove now-unused ridge heightmap --- src/mapgen_v7.cpp | 10 ++-------- src/mapgen_v7.h | 2 -- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index e297a1d3e..ee2c5f45f 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -62,8 +62,7 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) // 1-up 1-down overgeneration this->zstride_1u1d = csize.X * (csize.Y + 2); - this->heightmap = new s16[csize.X * csize.Z]; - this->ridge_heightmap = new s16[csize.X * csize.Z]; + this->heightmap = new s16[csize.X * csize.Z]; MapgenV7Params *sp = (MapgenV7Params *)params->sparams; @@ -134,7 +133,6 @@ MapgenV7::~MapgenV7() delete biomegen; - delete[] ridge_heightmap; delete[] heightmap; } @@ -440,8 +438,7 @@ int MapgenV7::generateTerrain() for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { s16 surface_y = baseTerrainLevelFromMap(index2d); - heightmap[index2d] = surface_y; // Create base terrain heightmap - ridge_heightmap[index2d] = surface_y; + heightmap[index2d] = surface_y; // Create base terrain heightmap if (surface_y > stone_surface_max_y) stone_surface_max_y = surface_y; @@ -504,9 +501,6 @@ void MapgenV7::generateRidgeTerrain() if (nridge + width_mod * height_mod < 0.6) continue; - if (y < ridge_heightmap[j]) - ridge_heightmap[j] = y - 1; - vm->m_data[vi] = (y > water_level) ? n_air : n_water; } } diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index 21beab2b4..eb89d5978 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -58,8 +58,6 @@ class MapgenV7 : public MapgenBasic { public: int zstride_1u1d; - s16 *ridge_heightmap; - u32 spflags; Noise *noise_terrain_base; Noise *noise_terrain_alt; -- cgit v1.2.3 From 0df5c01a8ce927c33ae9b67f459365505b980c33 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Fri, 20 May 2016 03:37:31 -0400 Subject: Mapgen: Remove calculateNoise from most mapgens This commit moves noise calculation to the functions where the noise is actually required, increasing the separation of concerns and level of interdependency for each mapgen method. Valleys Mapgen is left unmodified. --- src/mapgen.cpp | 2 ++ src/mapgen_flat.cpp | 30 +++++----------------------- src/mapgen_flat.h | 1 - src/mapgen_fractal.cpp | 22 ++------------------ src/mapgen_fractal.h | 1 - src/mapgen_v5.cpp | 27 ++++--------------------- src/mapgen_v5.h | 1 - src/mapgen_v7.cpp | 54 +++++++++++++++++--------------------------------- src/mapgen_v7.h | 3 --- src/mapgen_valleys.cpp | 1 - 10 files changed, 31 insertions(+), 111 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 7e959533d..009a81f0c 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -386,6 +386,8 @@ MgStoneType MapgenBasic::generateBiomes() u32 index = 0; MgStoneType stone_type = MGSTONE_STONE; + noise_filler_depth->perlinMap2D(node_min.X, node_min.Z); + 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; diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index a541a54f3..ded859f65 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -227,9 +227,6 @@ void MapgenFlat::makeChunk(BlockMakeData *data) blockseed = getBlockSeed2(full_node_min, seed); - // Make some noise - calculateNoise(); - // Generate base terrain, mountains, and ridges with initial heightmaps s16 stone_surface_max_y = generateTerrain(); @@ -312,24 +309,6 @@ void MapgenFlat::makeChunk(BlockMakeData *data) } -void MapgenFlat::calculateNoise() -{ - //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - s16 x = node_min.X; - s16 z = node_min.Z; - - if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) - noise_terrain->perlinMap2D(x, z); - - // Cave noises are calculated in generateCaves() - // only if solid terrain is present in mapchunk - - noise_filler_depth->perlinMap2D(x, z); - - //printf("calculateNoise: %dus\n", t.stop()); -} - - s16 MapgenFlat::generateTerrain() { MapNode n_air(CONTENT_AIR); @@ -340,13 +319,14 @@ s16 MapgenFlat::generateTerrain() s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; u32 ni2d = 0; + bool use_noise = (spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS); + if (use_noise) + noise_terrain->perlinMap2D(node_min.X, node_min.Z); + for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, ni2d++) { s16 stone_level = ground_level; - float n_terrain = 0.0f; - - if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) - n_terrain = noise_terrain->result[ni2d]; + float n_terrain = use_noise ? noise_terrain->result[ni2d] : 0.0f; if ((spflags & MGFLAT_LAKES) && n_terrain < lake_threshold) { s16 depress = (lake_threshold - n_terrain) * lake_steepness; diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index 2b98c1f31..39da6e025 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -78,7 +78,6 @@ public: virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); - void calculateNoise(); s16 generateTerrain(); }; diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index dca10d253..f54de6275 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -243,9 +243,6 @@ void MapgenFractal::makeChunk(BlockMakeData *data) blockseed = getBlockSeed2(full_node_min, seed); - // Make some noise - calculateNoise(); - // Generate base terrain, mountains, and ridges with initial heightmaps s16 stone_surface_max_y = generateTerrain(); @@ -328,23 +325,6 @@ void MapgenFractal::makeChunk(BlockMakeData *data) } -void MapgenFractal::calculateNoise() -{ - //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - s16 x = node_min.X; - s16 z = node_min.Z; - - noise_seabed->perlinMap2D(x, z); - - // Cave noises are calculated in generateCaves() - // only if solid terrain is present in mapchunk - - noise_filler_depth->perlinMap2D(x, z); - - //printf("calculateNoise: %dus\n", t.stop()); -} - - bool MapgenFractal::getFractalAtPoint(s16 x, s16 y, s16 z) { float cx, cy, cz, cw, ox, oy, oz, ow; @@ -474,6 +454,8 @@ s16 MapgenFractal::generateTerrain() s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; u32 index2d = 0; + noise_seabed->perlinMap2D(node_min.X, node_min.Z); + 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 vi = vm->m_area.index(node_min.X, y, z); diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index 176885d46..e30550405 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -88,7 +88,6 @@ public: virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); - void calculateNoise(); bool getFractalAtPoint(s16 x, s16 y, s16 z); s16 generateTerrain(); }; diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 0c063dc6f..85df34353 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -225,9 +225,6 @@ void MapgenV5::makeChunk(BlockMakeData *data) // Create a block-specific seed blockseed = getBlockSeed2(full_node_min, seed); - // Make some noise - calculateNoise(); - // Generate base terrain s16 stone_surface_max_y = generateBaseTerrain(); @@ -312,26 +309,6 @@ void MapgenV5::makeChunk(BlockMakeData *data) } -void MapgenV5::calculateNoise() -{ - //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - s16 x = node_min.X; - s16 y = node_min.Y - 1; - s16 z = node_min.Z; - - noise_factor->perlinMap2D(x, z); - noise_height->perlinMap2D(x, z); - noise_ground->perlinMap3D(x, y, z); - - // Cave noises are calculated in generateCaves() - // only if solid terrain is present in mapchunk - - noise_filler_depth->perlinMap2D(x, z); - - //printf("calculateNoise: %dus\n", t.stop()); -} - - //bool is_cave(u32 index) { // double d1 = contour(noise_cave1->result[index]); // double d2 = contour(noise_cave2->result[index]); @@ -355,6 +332,10 @@ int MapgenV5::generateBaseTerrain() u32 index2d = 0; int stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + noise_factor->perlinMap2D(node_min.X, node_min.Z); + noise_height->perlinMap2D(node_min.X, node_min.Z); + noise_ground->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + 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 vi = vm->m_area.index(node_min.X, y, z); diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h index 99836b23e..dd5ca0a31 100644 --- a/src/mapgen_v5.h +++ b/src/mapgen_v5.h @@ -69,7 +69,6 @@ public: virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); - void calculateNoise(); int generateBaseTerrain(); }; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index ee2c5f45f..5c5f13b88 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -252,9 +252,6 @@ void MapgenV7::makeChunk(BlockMakeData *data) blockseed = getBlockSeed2(full_node_min, seed); - // Make some noise - calculateNoise(); - // Generate terrain and ridges with initial heightmaps s16 stone_surface_max_y = generateTerrain(); @@ -340,37 +337,6 @@ void MapgenV7::makeChunk(BlockMakeData *data) } -void MapgenV7::calculateNoise() -{ - //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); - s16 x = node_min.X; - s16 y = node_min.Y - 1; - s16 z = node_min.Z; - - noise_terrain_persist->perlinMap2D(x, z); - float *persistmap = noise_terrain_persist->result; - - noise_terrain_base->perlinMap2D(x, z, persistmap); - noise_terrain_alt->perlinMap2D(x, z, persistmap); - noise_height_select->perlinMap2D(x, z); - - if (spflags & MGV7_MOUNTAINS) { - noise_mountain->perlinMap3D(x, y, z); - noise_mount_height->perlinMap2D(x, z); - } - - if ((spflags & MGV7_RIDGES) && node_max.Y >= water_level) { - noise_ridge->perlinMap3D(x, y, z); - noise_ridge_uwater->perlinMap2D(x, z); - } - - // Cave noises are calculated in generateCaves() - // only if solid terrain is present in mapchunk - - //printf("calculateNoise: %dus\n", t.stop()); -} - - float MapgenV7::baseTerrainLevelAtPoint(s16 x, s16 z) { float hselect = NoisePerlin2D(&noise_height_select->np, x, z, seed); @@ -430,10 +396,23 @@ int MapgenV7::generateTerrain() MapNode n_stone(c_stone); MapNode n_water(c_water_source); + //// Calculate noise for terrain generation + noise_terrain_persist->perlinMap2D(node_min.X, node_min.Z); + float *persistmap = noise_terrain_persist->result; + + noise_terrain_base->perlinMap2D(node_min.X, node_min.Z, persistmap); + noise_terrain_alt->perlinMap2D(node_min.X, node_min.Z, persistmap); + noise_height_select->perlinMap2D(node_min.X, node_min.Z); + + if (spflags & MGV7_MOUNTAINS) { + noise_mountain->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_mount_height->perlinMap2D(node_min.X, node_min.Z); + } + + //// Place nodes v3s16 em = vm->m_area.getExtent(); s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; u32 index2d = 0; - bool mountain_flag = spflags & MGV7_MOUNTAINS; for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { @@ -450,7 +429,7 @@ int MapgenV7::generateTerrain() if (vm->m_data[vi].getContent() == CONTENT_IGNORE) { if (y <= surface_y) { vm->m_data[vi] = n_stone; // Base terrain - } else if (mountain_flag && + } else if ((spflags & MGV7_MOUNTAINS) && getMountainTerrainFromMap(index3d, index2d, y)) { vm->m_data[vi] = n_stone; // Mountain terrain if (y > stone_surface_max_y) @@ -475,6 +454,9 @@ void MapgenV7::generateRidgeTerrain() if (node_max.Y < water_level - 16) return; + noise_ridge->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + noise_ridge_uwater->perlinMap2D(node_min.X, node_min.Z); + MapNode n_water(c_water_source); MapNode n_air(CONTENT_AIR); u32 index = 0; diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index eb89d5978..723f1217f 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -87,9 +87,6 @@ public: float baseTerrainLevelFromMap(int index); bool getMountainTerrainAtPoint(s16 x, s16 y, s16 z); bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y); - - void calculateNoise(); - int generateTerrain(); void generateRidgeTerrain(); }; diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 699554ecd..3a4f984f9 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -388,7 +388,6 @@ void MapgenValleys::calculateNoise() //TimeTaker tcn("actualNoise"); - noise_filler_depth->perlinMap2D(x, z); noise_inter_valley_slope->perlinMap2D(x, z); noise_rivers->perlinMap2D(x, z); noise_terrain_height->perlinMap2D(x, z); -- cgit v1.2.3 From 081090176666e849d01f9a02b15279bdf72570bc Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 22 May 2016 02:17:19 -0400 Subject: Mapgen: Deduplicate common constructor code --- src/mapgen.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/mapgen.h | 22 +++++++++++++------- src/mapgen_flat.cpp | 30 ++------------------------- src/mapgen_flat.h | 19 ++++++++--------- src/mapgen_fractal.cpp | 30 ++------------------------- src/mapgen_fractal.h | 21 +++++++++---------- src/mapgen_v5.cpp | 30 ++------------------------- src/mapgen_v5.h | 19 ++++++++--------- src/mapgen_v7.cpp | 33 ++---------------------------- src/mapgen_v7.h | 31 ++++++++++++---------------- src/mapgen_valleys.cpp | 42 ++++++++------------------------------ src/mapgen_valleys.h | 5 ----- 12 files changed, 122 insertions(+), 215 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 009a81f0c..a2d207bff 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -377,9 +377,60 @@ void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax) MapgenBasic::MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge) : Mapgen(mapgenid, params, emerge) { + this->m_emerge = emerge; + this->m_bmgr = emerge->biomemgr; + + //// Here, 'stride' refers to the number of elements needed to skip to index + //// an adjacent element for that coordinate in noise/height/biome maps + //// (*not* vmanip content map!) + + // Note there is no X stride explicitly defined. Items adjacent in the X + // coordinate are assumed to be adjacent in memory as well (i.e. stride of 1). + + // Number of elements to skip to get to the next Y coordinate + this->ystride = csize.X; + + // Number of elements to skip to get to the next Z coordinate + this->zstride = csize.X * csize.Y; + + // Z-stride value for maps oversized for 1-down overgeneration + this->zstride_1d = csize.X * (csize.Y + 1); + + // Z-stride value for maps oversized for 1-up 1-down overgeneration + this->zstride_1u1d = csize.X * (csize.Y + 2); + + //// Allocate heightmap + this->heightmap = new s16[csize.X * csize.Z]; + + //// Initialize biome generator + // TODO(hmmmm): should we have a way to disable biomemanager biomes? + biomegen = m_bmgr->createBiomeGen(BIOMEGEN_ORIGINAL, params->bparams, csize); + biomemap = biomegen->biomemap; + + //// Look up some commonly used content + c_stone = ndef->getId("mapgen_stone"); + c_water_source = ndef->getId("mapgen_water_source"); + c_desert_stone = ndef->getId("mapgen_desert_stone"); + c_sandstone = ndef->getId("mapgen_sandstone"); + c_river_water_source = ndef->getId("mapgen_river_water_source"); + + //// Fall back to more basic content if not defined + if (c_desert_stone == CONTENT_IGNORE) + c_desert_stone = c_stone; + if (c_sandstone == CONTENT_IGNORE) + c_sandstone = c_stone; + if (c_river_water_source == CONTENT_IGNORE) + c_river_water_source = c_water_source; +} + +MapgenBasic::~MapgenBasic() +{ + delete biomegen; + delete []heightmap; } + MgStoneType MapgenBasic::generateBiomes() { v3s16 em = vm->m_area.getExtent(); @@ -499,7 +550,7 @@ void MapgenBasic::dustTopNodes() 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]); + Biome *biome = (Biome *)m_bmgr->getRaw(biomemap[index]); if (biome->c_dust == CONTENT_IGNORE) continue; @@ -544,7 +595,7 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth) if (max_stone_y < node_min.Y) return; - CavesNoiseIntersection caves_noise(ndef, bmgr, csize, + CavesNoiseIntersection caves_noise(ndef, m_bmgr, csize, &np_cave1, &np_cave2, seed, cave_width); caves_noise.generateCaves(vm, node_min, node_max, biomemap); diff --git a/src/mapgen.h b/src/mapgen.h index 8db01f5c1..0b552e508 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -216,8 +216,16 @@ private: */ class MapgenBasic : public Mapgen { public: + MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge); + virtual ~MapgenBasic(); + + virtual MgStoneType generateBiomes(); + virtual void dustTopNodes(); + virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth); + +protected: EmergeManager *m_emerge; - BiomeManager *bmgr; + BiomeManager *m_bmgr; Noise *noise_filler_depth; @@ -233,15 +241,15 @@ public: content_t c_sandstone; int ystride; + int zstride; + int zstride_1d; + int zstride_1u1d; + + u32 spflags; + NoiseParams np_cave1; NoiseParams np_cave2; 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 { diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index ded859f65..cc43684c4 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -52,15 +52,6 @@ FlagDesc flagdesc_mapgen_flat[] = { MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - this->m_emerge = emerge; - this->bmgr = emerge->biomemgr; - - //// amount of elements to skip for the next index - //// for noise/height/biome maps (not vmanip) - this->ystride = csize.X; - - this->heightmap = new s16[csize.X * csize.Z]; - MapgenFlatParams *sp = (MapgenFlatParams *)params->sparams; this->spflags = sp->spflags; @@ -79,27 +70,14 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge MapgenBasic::np_cave1 = sp->np_cave1; MapgenBasic::np_cave2 = sp->np_cave2; - //// Initialize biome generator - biomegen = emerge->biomemgr->createBiomeGen( - BIOMEGEN_ORIGINAL, params->bparams, csize); - biomemap = biomegen->biomemap; - - //// Resolve nodes to be used - c_stone = ndef->getId("mapgen_stone"); - c_water_source = ndef->getId("mapgen_water_source"); - c_lava_source = ndef->getId("mapgen_lava_source"); - c_desert_stone = ndef->getId("mapgen_desert_stone"); - c_ice = ndef->getId("mapgen_ice"); - c_sandstone = ndef->getId("mapgen_sandstone"); - + // Content used for dungeon generation c_cobble = ndef->getId("mapgen_cobble"); c_stair_cobble = ndef->getId("mapgen_stair_cobble"); c_mossycobble = ndef->getId("mapgen_mossycobble"); c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - if (c_ice == CONTENT_IGNORE) - c_ice = CONTENT_AIR; + // Fall back to more basic content if not defined if (c_mossycobble == CONTENT_IGNORE) c_mossycobble = c_cobble; if (c_stair_cobble == CONTENT_IGNORE) @@ -115,10 +93,6 @@ MapgenFlat::~MapgenFlat() { delete noise_terrain; delete noise_filler_depth; - - delete biomegen; - - delete[] heightmap; } diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index 39da6e025..ffec4b924 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -55,7 +55,14 @@ struct MapgenFlatParams : public MapgenSpecificParams { class MapgenFlat : public MapgenBasic { public: - u32 spflags; + MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge); + ~MapgenFlat(); + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + s16 generateTerrain(); + +private: s16 ground_level; s16 large_cave_depth; float lake_threshold; @@ -64,21 +71,11 @@ public: float hill_steepness; Noise *noise_terrain; - content_t c_lava_source; - content_t c_ice; - content_t c_cobble; content_t c_stair_cobble; content_t c_mossycobble; content_t c_sandstonebrick; content_t c_stair_sandstonebrick; - - MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge); - ~MapgenFlat(); - - virtual void makeChunk(BlockMakeData *data); - int getSpawnLevelAtPoint(v2s16 p); - s16 generateTerrain(); }; struct MapgenFactoryFlat : public MapgenFactory { diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index f54de6275..50e10d128 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -50,15 +50,6 @@ FlagDesc flagdesc_mapgen_fractal[] = { MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - this->m_emerge = emerge; - this->bmgr = emerge->biomemgr; - - //// amount of elements to skip for the next index - //// for noise/height/biome maps (not vmanip) - this->ystride = csize.X; - - this->heightmap = new s16[csize.X * csize.Z]; - MapgenFractalParams *sp = (MapgenFractalParams *)params->sparams; this->spflags = sp->spflags; @@ -80,30 +71,17 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * MapgenBasic::np_cave1 = sp->np_cave1; MapgenBasic::np_cave2 = sp->np_cave2; - //// Initialize biome generator - biomegen = emerge->biomemgr->createBiomeGen( - BIOMEGEN_ORIGINAL, params->bparams, csize); - biomemap = biomegen->biomemap; - this->formula = fractal / 2 + fractal % 2; this->julia = fractal % 2 == 0; - //// Resolve nodes to be used - c_stone = ndef->getId("mapgen_stone"); - c_water_source = ndef->getId("mapgen_water_source"); - c_lava_source = ndef->getId("mapgen_lava_source"); - c_desert_stone = ndef->getId("mapgen_desert_stone"); - c_ice = ndef->getId("mapgen_ice"); - c_sandstone = ndef->getId("mapgen_sandstone"); - + // Content used for dungeon generation c_cobble = ndef->getId("mapgen_cobble"); c_stair_cobble = ndef->getId("mapgen_stair_cobble"); c_mossycobble = ndef->getId("mapgen_mossycobble"); c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - if (c_ice == CONTENT_IGNORE) - c_ice = CONTENT_AIR; + // Fall back to more basic content if not defined if (c_mossycobble == CONTENT_IGNORE) c_mossycobble = c_cobble; if (c_stair_cobble == CONTENT_IGNORE) @@ -119,10 +97,6 @@ MapgenFractal::~MapgenFractal() { delete noise_seabed; delete noise_filler_depth; - - delete biomegen; - - delete[] heightmap; } diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index e30550405..de0ccaa2f 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -59,10 +59,18 @@ struct MapgenFractalParams : public MapgenSpecificParams { class MapgenFractal : public MapgenBasic { public: + MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge); + ~MapgenFractal(); + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + bool getFractalAtPoint(s16 x, s16 y, s16 z); + s16 generateTerrain(); + +private: u16 formula; bool julia; - u32 spflags; u16 fractal; u16 iterations; v3f scale; @@ -74,22 +82,11 @@ public: float julia_w; Noise *noise_seabed; - content_t c_lava_source; - content_t c_ice; - content_t c_cobble; content_t c_stair_cobble; content_t c_mossycobble; content_t c_sandstonebrick; content_t c_stair_sandstonebrick; - - MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge); - ~MapgenFractal(); - - virtual void makeChunk(BlockMakeData *data); - int getSpawnLevelAtPoint(v2s16 p); - bool getFractalAtPoint(s16 x, s16 y, s16 z); - s16 generateTerrain(); }; struct MapgenFactoryFractal : public MapgenFactory { diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 85df34353..167a38282 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -48,15 +48,6 @@ FlagDesc flagdesc_mapgen_v5[] = { MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - this->m_emerge = emerge; - this->bmgr = emerge->biomemgr; - - // amount of elements to skip for the next index - // for noise/height/biome maps (not vmanip) - this->ystride = csize.X; - - this->heightmap = new s16[csize.X * csize.Z]; - MapgenV5Params *sp = (MapgenV5Params *)params->sparams; this->spflags = sp->spflags; @@ -74,27 +65,14 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) MapgenBasic::np_cave1 = sp->np_cave1; MapgenBasic::np_cave2 = sp->np_cave2; - //// Initialize biome generator - biomegen = emerge->biomemgr->createBiomeGen( - BIOMEGEN_ORIGINAL, params->bparams, csize); - biomemap = biomegen->biomemap; - - //// Resolve nodes to be used - c_stone = ndef->getId("mapgen_stone"); - c_water_source = ndef->getId("mapgen_water_source"); - c_lava_source = ndef->getId("mapgen_lava_source"); - c_desert_stone = ndef->getId("mapgen_desert_stone"); - c_ice = ndef->getId("mapgen_ice"); - c_sandstone = ndef->getId("mapgen_sandstone"); - + // Content used for dungeon generation c_cobble = ndef->getId("mapgen_cobble"); c_stair_cobble = ndef->getId("mapgen_stair_cobble"); c_mossycobble = ndef->getId("mapgen_mossycobble"); c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - if (c_ice == CONTENT_IGNORE) - c_ice = CONTENT_AIR; + // Fall back to more basic content if not defined if (c_mossycobble == CONTENT_IGNORE) c_mossycobble = c_cobble; if (c_stair_cobble == CONTENT_IGNORE) @@ -112,10 +90,6 @@ MapgenV5::~MapgenV5() delete noise_factor; delete noise_height; delete noise_ground; - - delete biomegen; - - delete[] heightmap; } diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h index dd5ca0a31..e7e5b2327 100644 --- a/src/mapgen_v5.h +++ b/src/mapgen_v5.h @@ -50,26 +50,23 @@ struct MapgenV5Params : public MapgenSpecificParams { class MapgenV5 : public MapgenBasic { public: - u32 spflags; + MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge); + ~MapgenV5(); + + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + int generateBaseTerrain(); + +private: Noise *noise_factor; Noise *noise_height; Noise *noise_ground; - content_t c_lava_source; - content_t c_ice; - content_t c_cobble; content_t c_stair_cobble; content_t c_mossycobble; content_t c_sandstonebrick; content_t c_stair_sandstonebrick; - - MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge); - ~MapgenV5(); - - virtual void makeChunk(BlockMakeData *data); - int getSpawnLevelAtPoint(v2s16 p); - int generateBaseTerrain(); }; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 5c5f13b88..29c81e8a7 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -53,17 +53,6 @@ FlagDesc flagdesc_mapgen_v7[] = { MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - this->m_emerge = emerge; - this->bmgr = emerge->biomemgr; - - //// amount of elements to skip for the next index - //// for noise/height/biome maps (not vmanip) - this->ystride = csize.X; - // 1-up 1-down overgeneration - this->zstride_1u1d = csize.X * (csize.Y + 2); - - this->heightmap = new s16[csize.X * csize.Z]; - MapgenV7Params *sp = (MapgenV7Params *)params->sparams; this->spflags = sp->spflags; @@ -86,28 +75,14 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) MapgenBasic::np_cave1 = sp->np_cave1; MapgenBasic::np_cave2 = sp->np_cave2; - // TODO(hmmmm): should we have a way to disable biomemanager biomes? - //// Initialize biome generator - biomegen = emerge->biomemgr->createBiomeGen( - BIOMEGEN_ORIGINAL, params->bparams, csize); - biomemap = biomegen->biomemap; - - //// Resolve nodes to be used - c_stone = ndef->getId("mapgen_stone"); - c_water_source = ndef->getId("mapgen_water_source"); - c_lava_source = ndef->getId("mapgen_lava_source"); - c_desert_stone = ndef->getId("mapgen_desert_stone"); - c_ice = ndef->getId("mapgen_ice"); - c_sandstone = ndef->getId("mapgen_sandstone"); - + // Content used for dungeon generation c_cobble = ndef->getId("mapgen_cobble"); c_stair_cobble = ndef->getId("mapgen_stair_cobble"); c_mossycobble = ndef->getId("mapgen_mossycobble"); c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - if (c_ice == CONTENT_IGNORE) - c_ice = CONTENT_AIR; + // Fall back to more basic content if not defined if (c_mossycobble == CONTENT_IGNORE) c_mossycobble = c_cobble; if (c_stair_cobble == CONTENT_IGNORE) @@ -130,10 +105,6 @@ MapgenV7::~MapgenV7() delete noise_ridge_uwater; delete noise_mountain; delete noise_ridge; - - delete biomegen; - - delete[] heightmap; } diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index 723f1217f..aee171b48 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -56,9 +56,20 @@ struct MapgenV7Params : public MapgenSpecificParams { class MapgenV7 : public MapgenBasic { public: - int zstride_1u1d; + MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge); + ~MapgenV7(); - u32 spflags; + virtual void makeChunk(BlockMakeData *data); + int getSpawnLevelAtPoint(v2s16 p); + + float baseTerrainLevelAtPoint(s16 x, s16 z); + float baseTerrainLevelFromMap(int index); + bool getMountainTerrainAtPoint(s16 x, s16 y, s16 z); + bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y); + int generateTerrain(); + void generateRidgeTerrain(); + +private: Noise *noise_terrain_base; Noise *noise_terrain_alt; Noise *noise_terrain_persist; @@ -68,27 +79,11 @@ public: Noise *noise_mountain; Noise *noise_ridge; - content_t c_lava_source; - content_t c_ice; - content_t c_cobble; content_t c_stair_cobble; content_t c_mossycobble; content_t c_sandstonebrick; content_t c_stair_sandstonebrick; - - MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge); - ~MapgenV7(); - - virtual void makeChunk(BlockMakeData *data); - int getSpawnLevelAtPoint(v2s16 p); - - float baseTerrainLevelAtPoint(s16 x, s16 z); - float baseTerrainLevelFromMap(int index); - bool getMountainTerrainAtPoint(s16 x, s16 y, s16 z); - bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y); - int generateTerrain(); - void generateRidgeTerrain(); }; struct MapgenFactoryV7 : public MapgenFactory { diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 3a4f984f9..c0094eb3b 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -67,17 +67,8 @@ static FlagDesc flagdesc_mapgen_valleys[] = { MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - this->m_emerge = emerge; - this->bmgr = emerge->biomemgr; - - //// amount of elements to skip for the next index - //// for noise/height/biome maps (not vmanip) - this->ystride = csize.X; - this->zstride = csize.X * (csize.Y + 2); - // 1-down overgeneration - this->zstride_1d = csize.X * (csize.Y + 1); - - this->heightmap = new s16[csize.X * csize.Z]; + // NOTE: MapgenValleys has a hard dependency on BiomeGenOriginal + this->m_bgen = (BiomeGenOriginal *)biomegen; this->map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT, g_settings->getU16("map_generation_limit")); @@ -111,13 +102,6 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z); - //// Initialize biome generator - // NOTE: valleys mapgen can only use BiomeGenOriginal - biomegen = emerge->biomemgr->createBiomeGen( - BIOMEGEN_ORIGINAL, params->bparams, csize); - biomemap = biomegen->biomemap; - m_bgen = (BiomeGenOriginal *)biomegen; - this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS); this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL); this->humidity_adjust = bp->np_humidity.offset - 50.f; @@ -128,25 +112,18 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * tcave_cache = new float[csize.Y + 2]; - //// Resolve nodes to be used + // Resolve content to be used c_cobble = ndef->getId("mapgen_cobble"); - c_desert_stone = ndef->getId("mapgen_desert_stone"); - c_dirt = ndef->getId("mapgen_dirt"); c_lava_source = ndef->getId("mapgen_lava_source"); c_mossycobble = ndef->getId("mapgen_mossycobble"); - c_river_water_source = ndef->getId("mapgen_river_water_source"); c_sand = ndef->getId("mapgen_sand"); c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); - c_sandstone = ndef->getId("mapgen_sandstone"); c_stair_cobble = ndef->getId("mapgen_stair_cobble"); c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - c_stone = ndef->getId("mapgen_stone"); - c_water_source = ndef->getId("mapgen_water_source"); + // Fall back to more basic content if not defined if (c_mossycobble == CONTENT_IGNORE) c_mossycobble = c_cobble; - if (c_river_water_source == CONTENT_IGNORE) - c_river_water_source = c_water_source; if (c_sand == CONTENT_IGNORE) c_sand = c_stone; if (c_sandstonebrick == CONTENT_IGNORE) @@ -171,9 +148,6 @@ MapgenValleys::~MapgenValleys() delete noise_valley_depth; delete noise_valley_profile; - delete biomegen; - - delete[] heightmap; delete[] tcave_cache; } @@ -289,13 +263,13 @@ void MapgenValleys::makeChunk(BlockMakeData *data) // Generate biome noises. Note this must be executed strictly before // generateTerrain, because generateTerrain depends on intermediate // biome-related noises. - biomegen->calcBiomeNoise(node_min); + m_bgen->calcBiomeNoise(node_min); // Generate base terrain with initial heightmaps s16 stone_surface_max_y = generateTerrain(); // Build biomemap - biomegen->getBiomes(heightmap); + m_bgen->getBiomes(heightmap); // Place biome-specific nodes MgStoneType stone_type = generateBiomes(); @@ -606,7 +580,7 @@ int MapgenValleys::generateTerrain() } } - u32 index_3d = (z - node_min.Z) * zstride + (x - node_min.X); + u32 index_3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X); u32 index_data = vm->m_area.index(x, node_min.Y - 1, z); // Mapgens concern themselves with stone and water. @@ -755,7 +729,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth) u32 index_2d = 0; for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, index_2d++) { - Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]); + Biome *biome = (Biome *)m_bmgr->getRaw(biomemap[index_2d]); bool tunnel_air_above = false; bool underground = false; u32 index_data = vm->m_area.index(x, node_max.Y, z); diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 4f87be6b6..bab3a756e 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -99,9 +99,6 @@ public: private: BiomeGenOriginal *m_bgen; - int zstride; - int zstride_1d; - float map_gen_limit; bool humid_rivers; @@ -110,7 +107,6 @@ private: s16 cave_water_max_height; s16 lava_max_height; - u32 spflags; float altitude_chill; s16 lava_features_lim; s16 massive_cave_depth; @@ -129,7 +125,6 @@ private: Noise *noise_valley_profile; content_t c_cobble; - content_t c_dirt; content_t c_lava_source; content_t c_mossycobble; content_t c_sand; -- cgit v1.2.3 From fd0efb21c3d40a963a813d73a09bb80df625b247 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 22 May 2016 16:27:31 -0400 Subject: Mapgen: Combine dungeon generation code --- src/mapgen.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++++++- src/mapgen.h | 11 +++++++- src/mapgen_flat.cpp | 61 ++--------------------------------------- src/mapgen_flat.h | 6 ----- src/mapgen_fractal.cpp | 61 ++--------------------------------------- src/mapgen_fractal.h | 6 ----- src/mapgen_v5.cpp | 61 ++--------------------------------------- src/mapgen_v5.h | 6 ----- src/mapgen_v7.cpp | 61 ++--------------------------------------- src/mapgen_v7.h | 6 ----- src/mapgen_valleys.cpp | 61 +++-------------------------------------- src/mapgen_valleys.h | 5 ---- 12 files changed, 94 insertions(+), 324 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index a2d207bff..56fe34e16 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -40,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "log.h" #include "cavegen.h" +#include "dungeongen.h" FlagDesc flagdesc_mapgen[] = { {"trees", MG_TREES}, @@ -414,13 +415,30 @@ MapgenBasic::MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emer c_sandstone = ndef->getId("mapgen_sandstone"); c_river_water_source = ndef->getId("mapgen_river_water_source"); - //// Fall back to more basic content if not defined + // Fall back to more basic content if not defined if (c_desert_stone == CONTENT_IGNORE) c_desert_stone = c_stone; if (c_sandstone == CONTENT_IGNORE) c_sandstone = c_stone; if (c_river_water_source == CONTENT_IGNORE) c_river_water_source = c_water_source; + + //// Content used for dungeon generation + c_cobble = ndef->getId("mapgen_cobble"); + c_stair_cobble = ndef->getId("mapgen_stair_cobble"); + c_mossycobble = ndef->getId("mapgen_mossycobble"); + c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); + c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); + + // Fall back to more basic content if not defined + if (c_mossycobble == CONTENT_IGNORE) + c_mossycobble = c_cobble; + if (c_stair_cobble == CONTENT_IGNORE) + c_stair_cobble = c_cobble; + if (c_sandstonebrick == CONTENT_IGNORE) + c_sandstonebrick = c_sandstone; + if (c_stair_sandstonebrick == CONTENT_IGNORE) + c_stair_sandstonebrick = c_sandstone; } @@ -614,6 +632,59 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth) } +void MapgenBasic::generateDungeons(s16 max_stone_y, MgStoneType stone_type) +{ + if (max_stone_y < node_min.Y) + return; + + DungeonParams dp; + + dp.np_rarity = nparams_dungeon_rarity; + dp.np_density = nparams_dungeon_density; + dp.np_wetness = nparams_dungeon_wetness; + dp.c_water = c_water_source; + switch (stone_type) { + default: + case MGSTONE_STONE: + dp.c_cobble = c_cobble; + dp.c_moss = c_mossycobble; + dp.c_stair = c_stair_cobble; + + dp.diagonal_dirs = false; + dp.mossratio = 3.0; + dp.holesize = v3s16(1, 2, 1); + dp.roomsize = v3s16(0, 0, 0); + dp.notifytype = GENNOTIFY_DUNGEON; + break; + case MGSTONE_DESERT_STONE: + dp.c_cobble = c_desert_stone; + dp.c_moss = c_desert_stone; + dp.c_stair = c_desert_stone; + + dp.diagonal_dirs = true; + dp.mossratio = 0.0; + dp.holesize = v3s16(2, 3, 2); + dp.roomsize = v3s16(2, 5, 2); + dp.notifytype = GENNOTIFY_TEMPLE; + break; + case MGSTONE_SANDSTONE: + dp.c_cobble = c_sandstonebrick; + dp.c_moss = c_sandstonebrick; + dp.c_stair = c_sandstonebrick; + + dp.diagonal_dirs = false; + dp.mossratio = 0.0; + dp.holesize = v3s16(2, 2, 2); + dp.roomsize = v3s16(2, 0, 2); + dp.notifytype = GENNOTIFY_DUNGEON; + break; + } + + DungeonGen dgen(this, &dp); + dgen.generate(blockseed, full_node_min, full_node_max); +} + + //// //// GenerateNotifier //// diff --git a/src/mapgen.h b/src/mapgen.h index 0b552e508..10595fafc 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -219,9 +219,10 @@ public: MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge); virtual ~MapgenBasic(); + virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth); + virtual void generateDungeons(s16 max_stone_y, MgStoneType stone_type); virtual MgStoneType generateBiomes(); virtual void dustTopNodes(); - virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth); protected: EmergeManager *m_emerge; @@ -234,12 +235,20 @@ protected: v3s16 full_node_min; v3s16 full_node_max; + // Content required for generateBiomes content_t c_stone; content_t c_water_source; content_t c_river_water_source; content_t c_desert_stone; content_t c_sandstone; + // Content required for generateDungeons + content_t c_cobble; + content_t c_stair_cobble; + content_t c_mossycobble; + content_t c_sandstonebrick; + content_t c_stair_sandstonebrick; + int ystride; int zstride; int zstride_1d; diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index cc43684c4..724f06825 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -69,23 +69,6 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge MapgenBasic::np_cave1 = sp->np_cave1; MapgenBasic::np_cave2 = sp->np_cave2; - - // Content used for dungeon generation - c_cobble = ndef->getId("mapgen_cobble"); - c_stair_cobble = ndef->getId("mapgen_stair_cobble"); - c_mossycobble = ndef->getId("mapgen_mossycobble"); - c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); - c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - - // Fall back to more basic content if not defined - if (c_mossycobble == CONTENT_IGNORE) - c_mossycobble = c_cobble; - if (c_stair_cobble == CONTENT_IGNORE) - c_stair_cobble = c_cobble; - if (c_sandstonebrick == CONTENT_IGNORE) - c_sandstonebrick = c_sandstone; - if (c_stair_sandstonebrick == CONTENT_IGNORE) - c_stair_sandstonebrick = c_sandstone; } @@ -215,48 +198,8 @@ void MapgenFlat::makeChunk(BlockMakeData *data) if (flags & MG_CAVES) generateCaves(stone_surface_max_y, large_cave_depth); - if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) { - DungeonParams dp; - - dp.np_rarity = nparams_dungeon_rarity; - dp.np_density = nparams_dungeon_density; - dp.np_wetness = nparams_dungeon_wetness; - dp.c_water = c_water_source; - if (stone_type == MGSTONE_STONE) { - dp.c_cobble = c_cobble; - dp.c_moss = c_mossycobble; - dp.c_stair = c_stair_cobble; - - dp.diagonal_dirs = false; - dp.mossratio = 3.0; - dp.holesize = v3s16(1, 2, 1); - dp.roomsize = v3s16(0, 0, 0); - dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == MGSTONE_DESERT_STONE) { - dp.c_cobble = c_desert_stone; - dp.c_moss = c_desert_stone; - dp.c_stair = c_desert_stone; - - dp.diagonal_dirs = true; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 3, 2); - dp.roomsize = v3s16(2, 5, 2); - dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == MGSTONE_SANDSTONE) { - dp.c_cobble = c_sandstonebrick; - dp.c_moss = c_sandstonebrick; - dp.c_stair = c_sandstonebrick; - - dp.diagonal_dirs = false; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 2, 2); - dp.roomsize = v3s16(2, 0, 2); - dp.notifytype = GENNOTIFY_DUNGEON; - } - - DungeonGen dgen(this, &dp); - dgen.generate(blockseed, full_node_min, full_node_max); - } + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y, stone_type); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index ffec4b924..afe67b04e 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -70,12 +70,6 @@ private: float hill_threshold; float hill_steepness; Noise *noise_terrain; - - content_t c_cobble; - content_t c_stair_cobble; - content_t c_mossycobble; - content_t c_sandstonebrick; - content_t c_stair_sandstonebrick; }; struct MapgenFactoryFlat : public MapgenFactory { diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 50e10d128..b613bf358 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -73,23 +73,6 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * this->formula = fractal / 2 + fractal % 2; this->julia = fractal % 2 == 0; - - // Content used for dungeon generation - c_cobble = ndef->getId("mapgen_cobble"); - c_stair_cobble = ndef->getId("mapgen_stair_cobble"); - c_mossycobble = ndef->getId("mapgen_mossycobble"); - c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); - c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - - // Fall back to more basic content if not defined - if (c_mossycobble == CONTENT_IGNORE) - c_mossycobble = c_cobble; - if (c_stair_cobble == CONTENT_IGNORE) - c_stair_cobble = c_cobble; - if (c_sandstonebrick == CONTENT_IGNORE) - c_sandstonebrick = c_sandstone; - if (c_stair_sandstonebrick == CONTENT_IGNORE) - c_stair_sandstonebrick = c_sandstone; } @@ -231,48 +214,8 @@ void MapgenFractal::makeChunk(BlockMakeData *data) if (flags & MG_CAVES) generateCaves(stone_surface_max_y, MGFRACTAL_LARGE_CAVE_DEPTH); - if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) { - DungeonParams dp; - - dp.np_rarity = nparams_dungeon_rarity; - dp.np_density = nparams_dungeon_density; - dp.np_wetness = nparams_dungeon_wetness; - dp.c_water = c_water_source; - if (stone_type == MGSTONE_STONE) { - dp.c_cobble = c_cobble; - dp.c_moss = c_mossycobble; - dp.c_stair = c_stair_cobble; - - dp.diagonal_dirs = false; - dp.mossratio = 3.0; - dp.holesize = v3s16(1, 2, 1); - dp.roomsize = v3s16(0, 0, 0); - dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == MGSTONE_DESERT_STONE) { - dp.c_cobble = c_desert_stone; - dp.c_moss = c_desert_stone; - dp.c_stair = c_desert_stone; - - dp.diagonal_dirs = true; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 3, 2); - dp.roomsize = v3s16(2, 5, 2); - dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == MGSTONE_SANDSTONE) { - dp.c_cobble = c_sandstonebrick; - dp.c_moss = c_sandstonebrick; - dp.c_stair = c_sandstonebrick; - - dp.diagonal_dirs = false; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 2, 2); - dp.roomsize = v3s16(2, 0, 2); - dp.notifytype = GENNOTIFY_DUNGEON; - } - - DungeonGen dgen(this, &dp); - dgen.generate(blockseed, full_node_min, full_node_max); - } + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y, stone_type); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index de0ccaa2f..065142b84 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -81,12 +81,6 @@ private: float julia_z; float julia_w; Noise *noise_seabed; - - content_t c_cobble; - content_t c_stair_cobble; - content_t c_mossycobble; - content_t c_sandstonebrick; - content_t c_stair_sandstonebrick; }; struct MapgenFactoryFractal : public MapgenFactory { diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 167a38282..3e10ec2a5 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -64,23 +64,6 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) MapgenBasic::np_cave1 = sp->np_cave1; MapgenBasic::np_cave2 = sp->np_cave2; - - // Content used for dungeon generation - c_cobble = ndef->getId("mapgen_cobble"); - c_stair_cobble = ndef->getId("mapgen_stair_cobble"); - c_mossycobble = ndef->getId("mapgen_mossycobble"); - c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); - c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - - // Fall back to more basic content if not defined - if (c_mossycobble == CONTENT_IGNORE) - c_mossycobble = c_cobble; - if (c_stair_cobble == CONTENT_IGNORE) - c_stair_cobble = c_cobble; - if (c_sandstonebrick == CONTENT_IGNORE) - c_sandstonebrick = c_sandstone; - if (c_stair_sandstonebrick == CONTENT_IGNORE) - c_stair_sandstonebrick = c_sandstone; } @@ -215,48 +198,8 @@ void MapgenV5::makeChunk(BlockMakeData *data) 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)) { - DungeonParams dp; - - dp.np_rarity = nparams_dungeon_rarity; - dp.np_density = nparams_dungeon_density; - dp.np_wetness = nparams_dungeon_wetness; - dp.c_water = c_water_source; - if (stone_type == MGSTONE_STONE) { - dp.c_cobble = c_cobble; - dp.c_moss = c_mossycobble; - dp.c_stair = c_stair_cobble; - - dp.diagonal_dirs = false; - dp.mossratio = 3.0; - dp.holesize = v3s16(1, 2, 1); - dp.roomsize = v3s16(0, 0, 0); - dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == MGSTONE_DESERT_STONE) { - dp.c_cobble = c_desert_stone; - dp.c_moss = c_desert_stone; - dp.c_stair = c_desert_stone; - - dp.diagonal_dirs = true; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 3, 2); - dp.roomsize = v3s16(2, 5, 2); - dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == MGSTONE_SANDSTONE) { - dp.c_cobble = c_sandstonebrick; - dp.c_moss = c_sandstonebrick; - dp.c_stair = c_sandstonebrick; - - dp.diagonal_dirs = false; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 2, 2); - dp.roomsize = v3s16(2, 0, 2); - dp.notifytype = GENNOTIFY_DUNGEON; - } - - DungeonGen dgen(this, &dp); - dgen.generate(blockseed, full_node_min, full_node_max); - } + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y, stone_type); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h index e7e5b2327..4e1772a64 100644 --- a/src/mapgen_v5.h +++ b/src/mapgen_v5.h @@ -61,12 +61,6 @@ private: Noise *noise_factor; Noise *noise_height; Noise *noise_ground; - - content_t c_cobble; - content_t c_stair_cobble; - content_t c_mossycobble; - content_t c_sandstonebrick; - content_t c_stair_sandstonebrick; }; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 29c81e8a7..9ff2fbe66 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -74,23 +74,6 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) MapgenBasic::np_cave1 = sp->np_cave1; MapgenBasic::np_cave2 = sp->np_cave2; - - // Content used for dungeon generation - c_cobble = ndef->getId("mapgen_cobble"); - c_stair_cobble = ndef->getId("mapgen_stair_cobble"); - c_mossycobble = ndef->getId("mapgen_mossycobble"); - c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); - c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); - - // Fall back to more basic content if not defined - if (c_mossycobble == CONTENT_IGNORE) - c_mossycobble = c_cobble; - if (c_stair_cobble == CONTENT_IGNORE) - c_stair_cobble = c_cobble; - if (c_sandstonebrick == CONTENT_IGNORE) - c_sandstonebrick = c_sandstone; - if (c_stair_sandstonebrick == CONTENT_IGNORE) - c_stair_sandstonebrick = c_sandstone; } @@ -240,48 +223,8 @@ void MapgenV7::makeChunk(BlockMakeData *data) if (flags & MG_CAVES) generateCaves(stone_surface_max_y, water_level); - if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) { - DungeonParams dp; - - dp.np_rarity = nparams_dungeon_rarity; - dp.np_density = nparams_dungeon_density; - dp.np_wetness = nparams_dungeon_wetness; - dp.c_water = c_water_source; - if (stone_type == MGSTONE_STONE) { - dp.c_cobble = c_cobble; - dp.c_moss = c_mossycobble; - dp.c_stair = c_stair_cobble; - - dp.diagonal_dirs = false; - dp.mossratio = 3.0; - dp.holesize = v3s16(1, 2, 1); - dp.roomsize = v3s16(0, 0, 0); - dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == MGSTONE_DESERT_STONE) { - dp.c_cobble = c_desert_stone; - dp.c_moss = c_desert_stone; - dp.c_stair = c_desert_stone; - - dp.diagonal_dirs = true; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 3, 2); - dp.roomsize = v3s16(2, 5, 2); - dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == MGSTONE_SANDSTONE) { - dp.c_cobble = c_sandstonebrick; - dp.c_moss = c_sandstonebrick; - dp.c_stair = c_sandstonebrick; - - dp.diagonal_dirs = false; - dp.mossratio = 0.0; - dp.holesize = v3s16(2, 2, 2); - dp.roomsize = v3s16(2, 0, 2); - dp.notifytype = GENNOTIFY_DUNGEON; - } - - DungeonGen dgen(this, &dp); - dgen.generate(blockseed, full_node_min, full_node_max); - } + if (flags & MG_DUNGEONS) + generateDungeons(stone_surface_max_y, stone_type); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index aee171b48..9ed89a511 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -78,12 +78,6 @@ private: Noise *noise_ridge_uwater; Noise *noise_mountain; Noise *noise_ridge; - - content_t c_cobble; - content_t c_stair_cobble; - content_t c_mossycobble; - content_t c_sandstonebrick; - content_t c_stair_sandstonebrick; }; struct MapgenFactoryV7 : public MapgenFactory { diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index c0094eb3b..2cd733d36 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -113,25 +113,12 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * tcave_cache = new float[csize.Y + 2]; // Resolve content to be used - c_cobble = ndef->getId("mapgen_cobble"); - c_lava_source = ndef->getId("mapgen_lava_source"); - c_mossycobble = ndef->getId("mapgen_mossycobble"); - c_sand = ndef->getId("mapgen_sand"); - c_sandstonebrick = ndef->getId("mapgen_sandstonebrick"); - c_stair_cobble = ndef->getId("mapgen_stair_cobble"); - c_stair_sandstonebrick = ndef->getId("mapgen_stair_sandstonebrick"); + c_lava_source = ndef->getId("mapgen_lava_source"); + c_sand = ndef->getId("mapgen_sand"); // Fall back to more basic content if not defined - if (c_mossycobble == CONTENT_IGNORE) - c_mossycobble = c_cobble; if (c_sand == CONTENT_IGNORE) c_sand = c_stone; - if (c_sandstonebrick == CONTENT_IGNORE) - c_sandstonebrick = c_sandstone; - if (c_stair_cobble == CONTENT_IGNORE) - c_stair_cobble = c_cobble; - if (c_stair_sandstonebrick == CONTENT_IGNORE) - c_stair_sandstonebrick = c_sandstone; } @@ -279,48 +266,8 @@ void MapgenValleys::makeChunk(BlockMakeData *data) 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)) { - DungeonParams dp; - - dp.np_rarity = nparams_dungeon_rarity; - dp.np_density = nparams_dungeon_density; - dp.np_wetness = nparams_dungeon_wetness; - dp.c_water = c_water_source; - if (stone_type == MGSTONE_STONE) { - dp.c_cobble = c_cobble; - dp.c_moss = c_mossycobble; - dp.c_stair = c_stair_cobble; - - dp.diagonal_dirs = false; - dp.mossratio = 3.f; - dp.holesize = v3s16(1, 2, 1); - dp.roomsize = v3s16(0, 0, 0); - dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == MGSTONE_DESERT_STONE) { - dp.c_cobble = c_desert_stone; - dp.c_moss = c_desert_stone; - dp.c_stair = c_desert_stone; - - dp.diagonal_dirs = true; - dp.mossratio = 0.f; - dp.holesize = v3s16(2, 3, 2); - dp.roomsize = v3s16(2, 5, 2); - dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == MGSTONE_SANDSTONE) { - dp.c_cobble = c_sandstonebrick; - dp.c_moss = c_sandstonebrick; - dp.c_stair = c_sandstonebrick; - - dp.diagonal_dirs = false; - dp.mossratio = 0.f; - dp.holesize = v3s16(2, 2, 2); - dp.roomsize = v3s16(2, 0, 2); - dp.notifytype = GENNOTIFY_DUNGEON; - } - - DungeonGen dgen(this, &dp); - dgen.generate(blockseed, full_node_min, full_node_max); - } + if ((flags & MG_DUNGEONS) && node_max.Y < 50) + generateDungeons(stone_surface_max_y, stone_type); // Generate the registered decorations if (flags & MG_DECORATIONS) diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index bab3a756e..a7369ea92 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -124,13 +124,8 @@ private: Noise *noise_valley_depth; Noise *noise_valley_profile; - content_t c_cobble; content_t c_lava_source; - content_t c_mossycobble; content_t c_sand; - content_t c_sandstonebrick; - content_t c_stair_cobble; - content_t c_stair_sandstonebrick; float terrainLevelAtPoint(s16 x, s16 z); -- cgit v1.2.3 From 92705306bfb4994107a43514f29997cea15d48dc Mon Sep 17 00:00:00 2001 From: kwolekr Date: Tue, 14 Jun 2016 00:10:55 -0400 Subject: Mapgen: Refactor mapgen creation and management - Move mapgen creation logic out of EmergeManager and into Mapgen - Internally represent mapgen type as an enum value, instead of a string - Remove the need for a MapgenFactory per mapgen --- src/emerge.cpp | 68 +++-------------------- src/emerge.h | 3 - src/mapgen.cpp | 112 +++++++++++++++++++++++++++++++++++++- src/mapgen.h | 33 ++++++++--- src/mapgen_flat.h | 14 +---- src/mapgen_fractal.h | 14 +---- src/mapgen_singlenode.h | 17 ++---- src/mapgen_v5.h | 15 +---- src/mapgen_v6.h | 16 +----- src/mapgen_v7.h | 14 +---- src/mapgen_valleys.h | 14 +---- src/script/lua_api/l_mainmenu.cpp | 4 +- 12 files changed, 160 insertions(+), 164 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/src/emerge.cpp b/src/emerge.cpp index a2a10a177..48de6cb1a 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -34,13 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "map.h" #include "mapblock.h" -#include "mapgen_flat.h" -#include "mapgen_fractal.h" -#include "mapgen_v5.h" -#include "mapgen_v6.h" -#include "mapgen_v7.h" -#include "mapgen_valleys.h" -#include "mapgen_singlenode.h" #include "mg_biome.h" #include "mg_ore.h" #include "mg_decoration.h" @@ -53,13 +46,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "voxel.h" - -struct MapgenDesc { - const char *name; - MapgenFactory *factory; - bool is_user_visible; -}; - class EmergeThread : public Thread { public: bool enable_mapgen_debug_info; @@ -99,20 +85,6 @@ private: friend class EmergeManager; }; -//// -//// Built-in mapgens -//// - -MapgenDesc g_reg_mapgens[] = { - {"v5", new MapgenFactoryV5, true}, - {"v6", new MapgenFactoryV6, true}, - {"v7", new MapgenFactoryV7, true}, - {"flat", new MapgenFactoryFlat, true}, - {"fractal", new MapgenFactoryFractal, true}, - {"valleys", new MapgenFactoryValleys, true}, - {"singlenode", new MapgenFactorySinglenode, false}, -}; - //// //// EmergeManager //// @@ -195,24 +167,24 @@ void EmergeManager::initMapgens() if (m_mapgens.size()) return; - MapgenFactory *mgfactory = getMapgenFactory(params.mg_name); - if (!mgfactory) { + MapgenType mgtype = Mapgen::getMapgenType(params.mg_name); + if (mgtype == MAPGEN_INVALID) { + const char *default_mapgen_name = Mapgen::getMapgenName(MAPGEN_DEFAULT); errorstream << "EmergeManager: mapgen " << params.mg_name << - " not registered; falling back to " << DEFAULT_MAPGEN << std::endl; - - params.mg_name = DEFAULT_MAPGEN; + " not registered; falling back to " << + default_mapgen_name << std::endl; - mgfactory = getMapgenFactory(params.mg_name); - FATAL_ERROR_IF(mgfactory == NULL, "Couldn't use any mapgen!"); + params.mg_name = default_mapgen_name; + mgtype = MAPGEN_DEFAULT; } if (!params.sparams) { - params.sparams = mgfactory->createMapgenParams(); + params.sparams = Mapgen::createMapgenParams(mgtype); params.sparams->readParams(g_settings); } for (u32 i = 0; i != m_threads.size(); i++) { - Mapgen *mg = mgfactory->createMapgen(i, ¶ms, this); + Mapgen *mg = Mapgen::createMapgen(mgtype, i, ¶ms, this); m_mapgens.push_back(mg); } } @@ -369,28 +341,6 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos) return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params.water_level; } - -void EmergeManager::getMapgenNames( - std::vector *mgnames, bool include_hidden) -{ - for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) { - if (include_hidden || g_reg_mapgens[i].is_user_visible) - mgnames->push_back(g_reg_mapgens[i].name); - } -} - - -MapgenFactory *EmergeManager::getMapgenFactory(const std::string &mgname) -{ - for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) { - if (mgname == g_reg_mapgens[i].name) - return g_reg_mapgens[i].factory; - } - - return NULL; -} - - bool EmergeManager::pushBlockEmergeData( v3s16 pos, u16 peer_requested, diff --git a/src/emerge.h b/src/emerge.h index 825ac1c0f..303a35529 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -140,9 +140,6 @@ public: int getGroundLevelAtPoint(v2s16 p); bool isBlockUnderground(v3s16 blockpos); - static MapgenFactory *getMapgenFactory(const std::string &mgname); - static void getMapgenNames( - std::vector *mgnames, bool include_hidden); static v3s16 getContainingChunk(v3s16 blockpos, s16 chunksize); private: diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 1e0e3aa44..e45233b33 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -39,6 +39,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/numeric.h" #include "filesys.h" #include "log.h" +#include "mapgen_flat.h" +#include "mapgen_fractal.h" +#include "mapgen_v5.h" +#include "mapgen_v6.h" +#include "mapgen_v7.h" +#include "mapgen_valleys.h" +#include "mapgen_singlenode.h" #include "cavegen.h" #include "dungeongen.h" @@ -63,6 +70,28 @@ FlagDesc flagdesc_gennotify[] = { {NULL, 0} }; +struct MapgenDesc { + const char *name; + bool is_user_visible; +}; + +//// +//// Built-in mapgens +//// + +static MapgenDesc g_reg_mapgens[] = { + {"v5", true}, + {"v6", true}, + {"v7", true}, + {"flat", true}, + {"fractal", true}, + {"valleys", true}, + {"singlenode", false}, +}; + +STATIC_ASSERT( + ARRLEN(g_reg_mapgens) == MAPGEN_INVALID, + registered_mapgens_is_wrong_size); //// //// Mapgen @@ -121,6 +150,83 @@ Mapgen::~Mapgen() } +MapgenType Mapgen::getMapgenType(const std::string &mgname) +{ + for (size_t i = 0; i != ARRLEN(g_reg_mapgens); i++) { + if (mgname == g_reg_mapgens[i].name) + return (MapgenType)i; + } + + return MAPGEN_INVALID; +} + + +const char *Mapgen::getMapgenName(MapgenType mgtype) +{ + size_t index = (size_t)mgtype; + if (index == MAPGEN_INVALID || index >= ARRLEN(g_reg_mapgens)) + return "invalid"; + + return g_reg_mapgens[index].name; +} + + +Mapgen *Mapgen::createMapgen(MapgenType mgtype, int mgid, + MapgenParams *params, EmergeManager *emerge) +{ + switch (mgtype) { + case MAPGEN_FLAT: + return new MapgenFlat(mgid, params, emerge); + case MAPGEN_FRACTAL: + return new MapgenFractal(mgid, params, emerge); + case MAPGEN_SINGLENODE: + return new MapgenSinglenode(mgid, params, emerge); + case MAPGEN_V5: + return new MapgenV5(mgid, params, emerge); + case MAPGEN_V6: + return new MapgenV6(mgid, params, emerge); + case MAPGEN_V7: + return new MapgenV7(mgid, params, emerge); + case MAPGEN_VALLEYS: + return new MapgenValleys(mgid, params, emerge); + default: + return NULL; + } +} + + +MapgenSpecificParams *Mapgen::createMapgenParams(MapgenType mgtype) +{ + switch (mgtype) { + case MAPGEN_FLAT: + return new MapgenFlatParams; + case MAPGEN_FRACTAL: + return new MapgenFractalParams; + case MAPGEN_SINGLENODE: + return new MapgenSinglenodeParams; + case MAPGEN_V5: + return new MapgenV5Params; + case MAPGEN_V6: + return new MapgenV6Params; + case MAPGEN_V7: + return new MapgenV7Params; + case MAPGEN_VALLEYS: + return new MapgenValleysParams; + default: + return NULL; + } +} + + +void Mapgen::getMapgenNames(std::vector *mgnames, bool include_hidden) +{ + for (u32 i = 0; i != ARRLEN(g_reg_mapgens); i++) { + if (include_hidden || g_reg_mapgens[i].is_user_visible) + mgnames->push_back(g_reg_mapgens[i].name); + } +} + + u32 Mapgen::getBlockSeed(v3s16 p, s32 seed) { return (u32)seed + @@ -891,9 +997,9 @@ void MapgenParams::load(const Settings &settings) } delete sparams; - MapgenFactory *mgfactory = EmergeManager::getMapgenFactory(mg_name); - if (mgfactory) { - sparams = mgfactory->createMapgenParams(); + MapgenType mgtype = Mapgen::getMapgenType(mg_name); + if (mgtype != MAPGEN_INVALID) { + sparams = Mapgen::createMapgenParams(mgtype); sparams->readParams(&settings); } } diff --git a/src/mapgen.h b/src/mapgen.h index 90ac84bd8..618a2f6b8 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -26,7 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" #include "util/container.h" -#define DEFAULT_MAPGEN "v6" +#define MAPGEN_DEFAULT MAPGEN_V6 +#define MAPGEN_DEFAULT_NAME "v6" /////////////////// Mapgen flags #define MG_TREES 0x01 @@ -107,6 +108,17 @@ private: std::list m_notify_events; }; +enum MapgenType { + MAPGEN_V5, + MAPGEN_V6, + MAPGEN_V7, + MAPGEN_FLAT, + MAPGEN_FRACTAL, + MAPGEN_VALLEYS, + MAPGEN_SINGLENODE, + MAPGEN_INVALID, +}; + struct MapgenSpecificParams { virtual void readParams(const Settings *settings) = 0; virtual void writeParams(Settings *settings) const = 0; @@ -124,7 +136,7 @@ struct MapgenParams { MapgenSpecificParams *sparams; MapgenParams() : - mg_name(DEFAULT_MAPGEN), + mg_name(MAPGEN_DEFAULT_NAME), chunksize(5), seed(0), water_level(1), @@ -173,6 +185,8 @@ public: Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge); virtual ~Mapgen(); + virtual MapgenType getType() const { return MAPGEN_INVALID; } + static u32 getBlockSeed(v3s16 p, s32 seed); static u32 getBlockSeed2(v3s16 p, s32 seed); s16 findGroundLevelFull(v2s16 p2d); @@ -198,6 +212,14 @@ public: // signify this and to cause Server::findSpawnPos() to try another (X, Z). virtual int getSpawnLevelAtPoint(v2s16 p) { return 0; } + // Mapgen management functions + static MapgenType getMapgenType(const std::string &mgname); + static const char *getMapgenName(MapgenType mgtype); + static Mapgen *createMapgen(MapgenType mgtype, int mgid, + MapgenParams *params, EmergeManager *emerge); + static MapgenSpecificParams *createMapgenParams(MapgenType mgtype); + static void getMapgenNames(std::vector *mgnames, bool include_hidden); + private: // isLiquidHorizontallyFlowable() is a helper function for updateLiquid() // that checks whether there are floodable nodes without liquid beneath @@ -267,11 +289,4 @@ protected: float cave_width; }; -struct MapgenFactory { - virtual Mapgen *createMapgen(int mgid, MapgenParams *params, - EmergeManager *emerge) = 0; - virtual MapgenSpecificParams *createMapgenParams() = 0; - virtual ~MapgenFactory() {} -}; - #endif diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index afe67b04e..39b6dc302 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -58,6 +58,8 @@ public: MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge); ~MapgenFlat(); + virtual MapgenType getType() const { return MAPGEN_FLAT; } + virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); s16 generateTerrain(); @@ -72,16 +74,4 @@ private: Noise *noise_terrain; }; -struct MapgenFactoryFlat : public MapgenFactory { - Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) - { - return new MapgenFlat(mgid, params, emerge); - }; - - MapgenSpecificParams *createMapgenParams() - { - return new MapgenFlatParams(); - }; -}; - #endif diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index 065142b84..cbd5567c4 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -62,6 +62,8 @@ public: MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge); ~MapgenFractal(); + virtual MapgenType getType() const { return MAPGEN_FRACTAL; } + virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); bool getFractalAtPoint(s16 x, s16 y, s16 z); @@ -83,16 +85,4 @@ private: Noise *noise_seabed; }; -struct MapgenFactoryFractal : public MapgenFactory { - Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) - { - return new MapgenFractal(mgid, params, emerge); - }; - - MapgenSpecificParams *createMapgenParams() - { - return new MapgenFractalParams(); - }; -}; - #endif diff --git a/src/mapgen_singlenode.h b/src/mapgen_singlenode.h index 2c6496c00..58672a0ed 100644 --- a/src/mapgen_singlenode.h +++ b/src/mapgen_singlenode.h @@ -23,10 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen.h" struct MapgenSinglenodeParams : public MapgenSpecificParams { - MapgenSinglenodeParams() {} ~MapgenSinglenodeParams() {} - + void readParams(const Settings *settings) {} void writeParams(Settings *settings) const {} }; @@ -39,19 +38,11 @@ public: MapgenSinglenode(int mapgenid, MapgenParams *params, EmergeManager *emerge); ~MapgenSinglenode(); - + + virtual MapgenType getType() const { return MAPGEN_SINGLENODE; } + void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); }; -struct MapgenFactorySinglenode : public MapgenFactory { - Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) { - return new MapgenSinglenode(mgid, params, emerge); - }; - - MapgenSpecificParams *createMapgenParams() { - return new MapgenSinglenodeParams(); - }; -}; - #endif diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h index 4e1772a64..5f6b10383 100644 --- a/src/mapgen_v5.h +++ b/src/mapgen_v5.h @@ -53,6 +53,8 @@ public: MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge); ~MapgenV5(); + virtual MapgenType getType() const { return MAPGEN_V5; } + virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); int generateBaseTerrain(); @@ -63,17 +65,4 @@ private: Noise *noise_ground; }; - -struct MapgenFactoryV5 : public MapgenFactory { - Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) - { - return new MapgenV5(mgid, params, emerge); - }; - - MapgenSpecificParams *createMapgenParams() - { - return new MapgenV5Params(); - }; -}; - #endif diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h index a55fc6d53..20b0bf92e 100644 --- a/src/mapgen_v6.h +++ b/src/mapgen_v6.h @@ -127,6 +127,8 @@ public: MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge); ~MapgenV6(); + virtual MapgenType getType() const { return MAPGEN_V6; } + void makeChunk(BlockMakeData *data); int getGroundLevelAtPoint(v2s16 p); int getSpawnLevelAtPoint(v2s16 p); @@ -162,18 +164,4 @@ public: virtual void generateCaves(int max_stone_y); }; - -struct MapgenFactoryV6 : public MapgenFactory { - Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) - { - return new MapgenV6(mgid, params, emerge); - }; - - MapgenSpecificParams *createMapgenParams() - { - return new MapgenV6Params(); - }; -}; - - #endif diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index 9ed89a511..c75f18a93 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -59,6 +59,8 @@ public: MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge); ~MapgenV7(); + virtual MapgenType getType() const { return MAPGEN_V7; } + virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); @@ -80,16 +82,4 @@ private: Noise *noise_ridge; }; -struct MapgenFactoryV7 : public MapgenFactory { - Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) - { - return new MapgenV7(mgid, params, emerge); - }; - - MapgenSpecificParams *createMapgenParams() - { - return new MapgenV7Params(); - }; -}; - #endif diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index faaffa905..00f6aff07 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -91,6 +91,8 @@ public: MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge); ~MapgenValleys(); + virtual MapgenType getType() const { return MAPGEN_VALLEYS; } + virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); @@ -137,16 +139,4 @@ private: virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth); }; -struct MapgenFactoryValleys : public MapgenFactory { - Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) - { - return new MapgenValleys(mgid, params, emerge); - }; - - MapgenSpecificParams *createMapgenParams() - { - return new MapgenValleysParams(); - }; -}; - #endif diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 7b29db159..8b078eafd 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "convert_json.h" #include "serverlist.h" -#include "emerge.h" +#include "mapgen.h" #include "sound.h" #include "settings.h" #include "log.h" @@ -707,7 +707,7 @@ int ModApiMainMenu::l_set_topleft_text(lua_State *L) int ModApiMainMenu::l_get_mapgen_names(lua_State *L) { std::vector names; - EmergeManager::getMapgenNames(&names, lua_toboolean(L, 1)); + Mapgen::getMapgenNames(&names, lua_toboolean(L, 1)); lua_newtable(L); for (size_t i = 0; i != names.size(); i++) { -- cgit v1.2.3 From 3c63c3044d5e4ca36c2649c530f31622581d90fd Mon Sep 17 00:00:00 2001 From: kwolekr Date: Fri, 24 Jun 2016 18:15:56 -0400 Subject: Add MapSettingsManager and new mapgen setting script API functions This commit refactors the majority of the Mapgen settings system. - MapgenParams is now owned by MapSettingsManager, itself a part of ServerMap, instead of the EmergeManager. - New Script API functions added: core.get_mapgen_setting core.get_mapgen_setting_noiseparams, core.set_mapgen_setting, and core.set_mapgen_setting_noiseparams. - minetest.get/set_mapgen_params are deprecated by the above new functions. - It is now possible to view and modify any arbitrary mapgen setting from a mod, rather than the base MapgenParams structure. - MapgenSpecificParams has been removed. --- build/android/jni/Android.mk | 2 + doc/lua_api.txt | 19 +++ src/CMakeLists.txt | 1 + src/emerge.cpp | 40 ++--- src/emerge.h | 15 +- src/map.cpp | 100 +++-------- src/map.h | 10 +- src/map_settings_manager.cpp | 194 ++++++++++++++++++++++ src/map_settings_manager.h | 79 +++++++++ src/mapgen.cpp | 68 ++++---- src/mapgen.h | 20 +-- src/mapgen_flat.cpp | 28 ++-- src/mapgen_flat.h | 4 +- src/mapgen_fractal.cpp | 34 ++-- src/mapgen_fractal.h | 4 +- src/mapgen_singlenode.h | 2 +- src/mapgen_v5.cpp | 20 +-- src/mapgen_v5.h | 4 +- src/mapgen_v6.cpp | 33 ++-- src/mapgen_v6.h | 4 +- src/mapgen_v7.cpp | 30 ++-- src/mapgen_v7.h | 4 +- src/mapgen_valleys.cpp | 41 +++-- src/mapgen_valleys.h | 4 +- src/script/lua_api/l_mapgen.cpp | 154 +++++++++++++---- src/script/lua_api/l_mapgen.h | 12 ++ src/script/lua_api/l_vmanip.cpp | 2 +- src/server.cpp | 15 +- src/subgame.cpp | 4 +- src/unittest/CMakeLists.txt | 1 + src/unittest/test_map_settings_manager.cpp | 255 +++++++++++++++++++++++++++++ 31 files changed, 889 insertions(+), 314 deletions(-) create mode 100644 src/map_settings_manager.cpp create mode 100644 src/map_settings_manager.h create mode 100644 src/unittest/test_map_settings_manager.cpp (limited to 'src/mapgen_v7.h') diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index afd8c76b2..a42ab76b8 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -169,6 +169,7 @@ LOCAL_SRC_FILES := \ jni/src/log.cpp \ jni/src/main.cpp \ jni/src/map.cpp \ + jni/src/map_settings_manager.cpp \ jni/src/mapblock.cpp \ jni/src/mapblock_mesh.cpp \ jni/src/mapgen.cpp \ @@ -238,6 +239,7 @@ LOCAL_SRC_FILES := \ jni/src/unittest/test_connection.cpp \ jni/src/unittest/test_filepath.cpp \ jni/src/unittest/test_inventory.cpp \ + jni/src/unittest/test_map_settings_manager.cpp \ jni/src/unittest/test_mapnode.cpp \ jni/src/unittest/test_nodedef.cpp \ jni/src/unittest/test_noderesolver.cpp \ diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 6d359379e..297566068 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2089,7 +2089,9 @@ and `minetest.auth_reload` call the authetification handler. given biome_name string. * `minetest.get_mapgen_params()` Returns mapgen parameters, a table containing `mgname`, `seed`, `chunksize`, `water_level`, and `flags`. + * Deprecated: use minetest.get_mapgen_setting(name) instead * `minetest.set_mapgen_params(MapgenParams)` + * Deprecated: use minetest.set_mapgen_setting(name, value, override) instead * Set map generation parameters * Function cannot be called after the registration period; only initialization and `on_mapgen_init` @@ -2099,6 +2101,23 @@ and `minetest.auth_reload` call the authetification handler. * `flags` contains a comma-delimited string of flags to set, or if the prefix `"no"` is attached, clears instead. * `flags` is in the same format and has the same options as `mg_flags` in `minetest.conf` +* `minetest.get_mapgen_setting(name)` + * Gets the *active* mapgen setting (or nil if none exists) in string format with the following + order of precedence: + 1) Settings loaded from map_meta.txt or overrides set during mod execution + 2) Settings set by mods without a metafile override + 3) Settings explicitly set in the user config file, minetest.conf + 4) Settings set as the user config default +* `minetest.get_mapgen_setting_noiseparams(name)` + * Same as above, but returns the value as a NoiseParams table if the setting `name` exists + and is a valid NoiseParams +* `minetest.set_mapgen_setting(name, value, [override_meta=false])` + * Sets a mapgen param to `value`, and will take effect if the corresponding mapgen setting + is not already present in map_meta.txt. If the optional boolean override_meta is set to true, + this setting will become the active setting regardless of the map metafile contents. + * Note: to set the seed, use "seed", not "fixed_map_seed" +* `minetest.set_mapgen_setting_noiseparams(name, value, [override_meta=false])` + * Same as above, except value is a NoiseParams table * `minetest.set_noiseparams(name, noiseparams, set_default)` * Sets the noiseparams setting of `name` to the noiseparams table specified in `noiseparams`. * `set_default` is an optional boolean (default: `true`) that specifies whether the setting diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bffc1f7eb..bcd7a5984 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -414,6 +414,7 @@ set(common_SRCS light.cpp log.cpp map.cpp + map_settings_manager.cpp mapblock.cpp mapgen.cpp mapgen_flat.cpp diff --git a/src/emerge.cpp b/src/emerge.cpp index 48de6cb1a..daf42f5e2 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -156,37 +156,19 @@ EmergeManager::~EmergeManager() } -void EmergeManager::loadMapgenParams() -{ - params.load(*g_settings); -} - - -void EmergeManager::initMapgens() +bool EmergeManager::initMapgens(MapgenParams *params) { if (m_mapgens.size()) - return; - - MapgenType mgtype = Mapgen::getMapgenType(params.mg_name); - if (mgtype == MAPGEN_INVALID) { - const char *default_mapgen_name = Mapgen::getMapgenName(MAPGEN_DEFAULT); - errorstream << "EmergeManager: mapgen " << params.mg_name << - " not registered; falling back to " << - default_mapgen_name << std::endl; - - params.mg_name = default_mapgen_name; - mgtype = MAPGEN_DEFAULT; - } + return false; - if (!params.sparams) { - params.sparams = Mapgen::createMapgenParams(mgtype); - params.sparams->readParams(g_settings); - } + this->mgparams = params; for (u32 i = 0; i != m_threads.size(); i++) { - Mapgen *mg = Mapgen::createMapgen(mgtype, i, ¶ms, this); + Mapgen *mg = Mapgen::createMapgen(params->mgtype, i, params, this); m_mapgens.push_back(mg); } + + return true; } @@ -288,12 +270,14 @@ bool EmergeManager::enqueueBlockEmergeEx( // Mapgen-related helper functions // + +// TODO(hmmmm): Move this to ServerMap v3s16 EmergeManager::getContainingChunk(v3s16 blockpos) { - return getContainingChunk(blockpos, params.chunksize); + return getContainingChunk(blockpos, mgparams->chunksize); } - +// TODO(hmmmm): Move this to ServerMap v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize) { s16 coff = -chunksize / 2; @@ -327,7 +311,7 @@ int EmergeManager::getGroundLevelAtPoint(v2s16 p) return m_mapgens[0]->getGroundLevelAtPoint(p); } - +// TODO(hmmmm): Move this to ServerMap bool EmergeManager::isBlockUnderground(v3s16 blockpos) { #if 0 @@ -338,7 +322,7 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos) #endif // Use a simple heuristic; the above method is wildly inaccurate anyway. - return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params.water_level; + return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level; } bool EmergeManager::pushBlockEmergeData( diff --git a/src/emerge.h b/src/emerge.h index 303a35529..cf0677145 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -97,8 +97,16 @@ public: u32 gen_notify_on; std::set gen_notify_on_deco_ids; - // Map generation parameters - MapgenParams params; + // Parameters passed to mapgens owned by ServerMap + // TODO(hmmmm): Remove this after mapgen helper methods using them + // are moved to ServerMap + MapgenParams *mgparams; + + // Hackish workaround: + // For now, EmergeManager must hold onto a ptr to the Map's setting manager + // since the Map can only be accessed through the Environment, and the + // Environment is not created until after script initialization. + MapSettingsManager *map_settings_mgr; // Managers of various map generation-related components BiomeManager *biomemgr; @@ -110,8 +118,7 @@ public: EmergeManager(IGameDef *gamedef); ~EmergeManager(); - void loadMapgenParams(); - void initMapgens(); + bool initMapgens(MapgenParams *mgparams); void startThreads(); void stopThreads(); diff --git a/src/map.cpp b/src/map.cpp index a1f2086ce..38f0fa37c 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2130,11 +2130,15 @@ void Map::removeNodeTimer(v3s16 p) */ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge): Map(dout_server, gamedef), + settings_mgr(g_settings, savedir + DIR_DELIM + "map_meta.txt"), m_emerge(emerge), m_map_metadata_changed(true) { verbosestream<map_settings_mgr = &settings_mgr; + /* Try to load map; if not found, create a new one. */ @@ -2170,26 +2174,15 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer } else { - try{ - // Load map metadata (seed, chunksize) - loadMapMeta(); - } - catch(SettingNotFoundException &e){ - infostream<<"ServerMap: Some metadata not found." - <<" Using default settings."<params.seed; + return getMapgenParams()->seed; } s16 ServerMap::getWaterLevel() { - return m_emerge->params.water_level; + return getMapgenParams()->water_level; } bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) { - s16 csize = m_emerge->params.chunksize; + s16 csize = getMapgenParams()->chunksize; v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize); v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1); @@ -2287,7 +2287,7 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) blockpos_over_limit(full_bpmax)) return false; - data->seed = m_emerge->params.seed; + data->seed = getSeed(); data->blockpos_min = bpmin; data->blockpos_max = bpmax; data->blockpos_requested = blockpos; @@ -2905,8 +2905,9 @@ void ServerMap::save(ModifiedState save_level) infostream<<"ServerMap: Saving whole map, this can take time." < &dst) } } -void ServerMap::saveMapMeta() -{ - DSTACK(FUNCTION_NAME); - - createDirs(m_savedir); - - std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt"; - std::ostringstream oss(std::ios_base::binary); - Settings conf; - - m_emerge->params.save(conf); - conf.writeLines(oss); - - oss << "[end_of_params]\n"; - - if(!fs::safeWriteToFile(fullpath, oss.str())) { - errorstream << "ServerMap::saveMapMeta(): " - << "could not write " << fullpath << std::endl; - throw FileNotGoodException("Cannot save chunk metadata"); - } - - m_map_metadata_changed = false; -} - -void ServerMap::loadMapMeta() -{ - DSTACK(FUNCTION_NAME); - - Settings conf; - std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt"; - - std::ifstream is(fullpath.c_str(), std::ios_base::binary); - if (!is.good()) { - errorstream << "ServerMap::loadMapMeta(): " - "could not open " << fullpath << std::endl; - throw FileNotGoodException("Cannot open map metadata"); - } - - if (!conf.parseConfigLines(is, "[end_of_params]")) { - throw SerializationError("ServerMap::loadMapMeta(): " - "[end_of_params] not found!"); - } - - m_emerge->params.load(conf); - - verbosestream << "ServerMap::loadMapMeta(): seed=" - << m_emerge->params.seed << std::endl; -} - void ServerMap::saveSectorMeta(ServerMapSector *sector) { DSTACK(FUNCTION_NAME); diff --git a/src/map.h b/src/map.h index 23da56471..13775fde1 100644 --- a/src/map.h +++ b/src/map.h @@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "modifiedstate.h" #include "util/container.h" #include "nodetimer.h" +#include "map_settings_manager.h" class Settings; class Database; @@ -46,8 +47,6 @@ class IRollbackManager; class EmergeManager; class ServerEnvironment; struct BlockMakeData; -struct MapgenParams; - /* MapEditEvent @@ -463,9 +462,8 @@ public: void save(ModifiedState save_level); void listAllLoadableBlocks(std::vector &dst); void listAllLoadedBlocks(std::vector &dst); - // Saves map seed and possibly other stuff - void saveMapMeta(); - void loadMapMeta(); + + MapgenParams *getMapgenParams(); /*void saveChunkMeta(); void loadChunkMeta();*/ @@ -506,6 +504,8 @@ public: u64 getSeed(); s16 getWaterLevel(); + MapSettingsManager settings_mgr; + private: // Emerge manager EmergeManager *m_emerge; diff --git a/src/map_settings_manager.cpp b/src/map_settings_manager.cpp new file mode 100644 index 000000000..53d17125c --- /dev/null +++ b/src/map_settings_manager.cpp @@ -0,0 +1,194 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "debug.h" +#include "filesys.h" +#include "log.h" +#include "mapgen.h" +#include "settings.h" + +#include "map_settings_manager.h" + +MapSettingsManager::MapSettingsManager( + Settings *user_settings, const std::string &map_meta_path) +{ + m_map_meta_path = map_meta_path; + m_user_settings = user_settings; + m_map_settings = new Settings; + mapgen_params = NULL; + + assert(m_user_settings != NULL); +} + + +MapSettingsManager::~MapSettingsManager() +{ + delete m_map_settings; + delete mapgen_params; +} + + +bool MapSettingsManager::getMapSetting( + const std::string &name, std::string *value_out) +{ + if (m_map_settings->getNoEx(name, *value_out)) + return true; + + // Compatibility kludge + if (m_user_settings == g_settings && name == "seed") + return m_user_settings->getNoEx("fixed_map_seed", *value_out); + + return m_user_settings->getNoEx(name, *value_out); +} + + +bool MapSettingsManager::getMapSettingNoiseParams( + const std::string &name, NoiseParams *value_out) +{ + return m_map_settings->getNoiseParams(name, *value_out) || + m_user_settings->getNoiseParams(name, *value_out); +} + + +bool MapSettingsManager::setMapSetting( + const std::string &name, const std::string &value, bool override_meta) +{ + if (mapgen_params) + return false; + + if (override_meta) + m_map_settings->set(name, value); + else + m_map_settings->setDefault(name, value); + + return true; +} + + +bool MapSettingsManager::setMapSettingNoiseParams( + const std::string &name, const NoiseParams *value, bool override_meta) +{ + if (mapgen_params) + return false; + + m_map_settings->setNoiseParams(name, *value, !override_meta); + return true; +} + + +bool MapSettingsManager::loadMapMeta() +{ + std::ifstream is(m_map_meta_path.c_str(), std::ios_base::binary); + + if (!is.good()) { + errorstream << "loadMapMeta: could not open " + << m_map_meta_path << std::endl; + return false; + } + + if (!m_map_settings->parseConfigLines(is, "[end_of_params]")) { + errorstream << "loadMapMeta: [end_of_params] not found!" << std::endl; + return false; + } + + return true; +} + + +bool MapSettingsManager::saveMapMeta() +{ + // If mapgen params haven't been created yet; abort + if (!mapgen_params) + return false; + + if (!fs::CreateAllDirs(fs::RemoveLastPathComponent(m_map_meta_path))) { + errorstream << "saveMapMeta: could not create dirs to " + << m_map_meta_path; + return false; + } + + std::ostringstream oss(std::ios_base::binary); + Settings conf; + + mapgen_params->MapgenParams::writeParams(&conf); + mapgen_params->writeParams(&conf); + conf.writeLines(oss); + + // NOTE: If there are ever types of map settings other than + // those relating to map generation, save them here + + oss << "[end_of_params]\n"; + + if (!fs::safeWriteToFile(m_map_meta_path, oss.str())) { + errorstream << "saveMapMeta: could not write " + << m_map_meta_path << std::endl; + return false; + } + + return true; +} + + +MapgenParams *MapSettingsManager::makeMapgenParams() +{ + if (mapgen_params) + return mapgen_params; + + assert(m_user_settings != NULL); + assert(m_map_settings != NULL); + + // At this point, we have (in order of precedence): + // 1). m_mapgen_settings->m_settings containing map_meta.txt settings or + // explicit overrides from scripts + // 2). m_mapgen_settings->m_defaults containing script-set mgparams without + // overrides + // 3). g_settings->m_settings containing all user-specified config file + // settings + // 4). g_settings->m_defaults containing any low-priority settings from + // scripts, e.g. mods using Lua as an enhanced config file) + + // Now, get the mapgen type so we can create the appropriate MapgenParams + std::string mg_name; + MapgenType mgtype = getMapSetting("mg_name", &mg_name) ? + Mapgen::getMapgenType(mg_name) : MAPGEN_DEFAULT; + if (mgtype == MAPGEN_INVALID) { + errorstream << "EmergeManager: mapgen '" << mg_name << + "' not valid; falling back to " << + Mapgen::getMapgenName(MAPGEN_DEFAULT) << std::endl; + mgtype = MAPGEN_DEFAULT; + } + + // Create our MapgenParams + MapgenParams *params = Mapgen::createMapgenParams(mgtype); + if (params == NULL) + return NULL; + + params->mgtype = mgtype; + + // Load the rest of the mapgen params from our active settings + params->MapgenParams::readParams(m_user_settings); + params->MapgenParams::readParams(m_map_settings); + params->readParams(m_user_settings); + params->readParams(m_map_settings); + + // Hold onto our params + mapgen_params = params; + + return params; +} diff --git a/src/map_settings_manager.h b/src/map_settings_manager.h new file mode 100644 index 000000000..9f766f1f0 --- /dev/null +++ b/src/map_settings_manager.h @@ -0,0 +1,79 @@ +/* +Minetest +Copyright (C) 2010-2013 kwolekr, Ryan Kwolek + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef MAP_SETTINGS_MANAGER_HEADER +#define MAP_SETTINGS_MANAGER_HEADER + +#include + +class Settings; +struct NoiseParams; +struct MapgenParams; + +/* + MapSettingsManager is a centralized object for management (creating, + loading, storing, saving, etc.) of config settings related to the Map. + + It has two phases: the initial r/w "gather and modify settings" state, and + the final r/o "read and save settings" state. + + The typical use case is, in order, as follows: + - Create a MapSettingsManager object + - Try to load map metadata into it from the metadata file + - Manually view and modify the current configuration as desired through a + Settings-like interface + - When all modifications are finished, create a 'Parameters' object + containing the finalized, active parameters. This could be passed along + to whichever Map-related objects that may require it. + - Save these active settings to the metadata file when requested +*/ +class MapSettingsManager { +public: + // Finalized map generation parameters + MapgenParams *mapgen_params; + + MapSettingsManager(Settings *user_settings, + const std::string &map_meta_path); + ~MapSettingsManager(); + + bool getMapSetting(const std::string &name, std::string *value_out); + + bool getMapSettingNoiseParams( + const std::string &name, NoiseParams *value_out); + + // Note: Map config becomes read-only after makeMapgenParams() gets called + // (i.e. mapgen_params is non-NULL). Attempts to set map config after + // params have been finalized will result in failure. + bool setMapSetting(const std::string &name, + const std::string &value, bool override_meta = false); + + bool setMapSettingNoiseParams(const std::string &name, + const NoiseParams *value, bool override_meta = false); + + bool loadMapMeta(); + bool saveMapMeta(); + MapgenParams *makeMapgenParams(); + +private: + std::string m_map_meta_path; + Settings *m_map_settings; + Settings *m_user_settings; +}; + +#endif diff --git a/src/mapgen.cpp b/src/mapgen.cpp index e45233b33..b6fda91ac 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -176,26 +176,26 @@ Mapgen *Mapgen::createMapgen(MapgenType mgtype, int mgid, { switch (mgtype) { case MAPGEN_FLAT: - return new MapgenFlat(mgid, params, emerge); + return new MapgenFlat(mgid, (MapgenFlatParams *)params, emerge); case MAPGEN_FRACTAL: - return new MapgenFractal(mgid, params, emerge); + return new MapgenFractal(mgid, (MapgenFractalParams *)params, emerge); case MAPGEN_SINGLENODE: - return new MapgenSinglenode(mgid, params, emerge); + return new MapgenSinglenode(mgid, (MapgenSinglenodeParams *)params, emerge); case MAPGEN_V5: - return new MapgenV5(mgid, params, emerge); + return new MapgenV5(mgid, (MapgenV5Params *)params, emerge); case MAPGEN_V6: - return new MapgenV6(mgid, params, emerge); + return new MapgenV6(mgid, (MapgenV6Params *)params, emerge); case MAPGEN_V7: - return new MapgenV7(mgid, params, emerge); + return new MapgenV7(mgid, (MapgenV7Params *)params, emerge); case MAPGEN_VALLEYS: - return new MapgenValleys(mgid, params, emerge); + return new MapgenValleys(mgid, (MapgenValleysParams *)params, emerge); default: return NULL; } } -MapgenSpecificParams *Mapgen::createMapgenParams(MapgenType mgtype) +MapgenParams *Mapgen::createMapgenParams(MapgenType mgtype) { switch (mgtype) { case MAPGEN_FLAT: @@ -970,52 +970,46 @@ void GenerateNotifier::getEvents( MapgenParams::~MapgenParams() { delete bparams; - delete sparams; } -void MapgenParams::load(const Settings &settings) +void MapgenParams::readParams(const Settings *settings) { std::string seed_str; - const char *seed_name = (&settings == g_settings) ? "fixed_map_seed" : "seed"; + const char *seed_name = (settings == g_settings) ? "fixed_map_seed" : "seed"; - if (settings.getNoEx(seed_name, seed_str) && !seed_str.empty()) - seed = read_seed(seed_str.c_str()); - else - myrand_bytes(&seed, sizeof(seed)); + if (settings->getNoEx(seed_name, seed_str)) { + if (!seed_str.empty()) + seed = read_seed(seed_str.c_str()); + else + myrand_bytes(&seed, sizeof(seed)); + } + + std::string mg_name; + if (settings->getNoEx("mg_name", mg_name)) + this->mgtype = Mapgen::getMapgenType(mg_name); - settings.getNoEx("mg_name", mg_name); - settings.getS16NoEx("water_level", water_level); - settings.getS16NoEx("chunksize", chunksize); - settings.getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen); + settings->getS16NoEx("water_level", water_level); + settings->getS16NoEx("chunksize", chunksize); + settings->getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen); delete bparams; bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL); if (bparams) { - bparams->readParams(&settings); + bparams->readParams(settings); bparams->seed = seed; } - - delete sparams; - MapgenType mgtype = Mapgen::getMapgenType(mg_name); - if (mgtype != MAPGEN_INVALID) { - sparams = Mapgen::createMapgenParams(mgtype); - sparams->readParams(&settings); - } } -void MapgenParams::save(Settings &settings) const +void MapgenParams::writeParams(Settings *settings) const { - settings.set("mg_name", mg_name); - settings.setU64("seed", seed); - settings.setS16("water_level", water_level); - settings.setS16("chunksize", chunksize); - settings.setFlagStr("mg_flags", flags, flagdesc_mapgen, U32_MAX); + settings->set("mg_name", Mapgen::getMapgenName(mgtype)); + settings->setU64("seed", seed); + settings->setS16("water_level", water_level); + settings->setS16("chunksize", chunksize); + settings->setFlagStr("mg_flags", flags, flagdesc_mapgen, U32_MAX); if (bparams) - bparams->writeParams(&settings); - - if (sparams) - sparams->writeParams(&settings); + bparams->writeParams(settings); } diff --git a/src/mapgen.h b/src/mapgen.h index 618a2f6b8..5fcf2a365 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -119,37 +119,29 @@ enum MapgenType { MAPGEN_INVALID, }; -struct MapgenSpecificParams { - virtual void readParams(const Settings *settings) = 0; - virtual void writeParams(Settings *settings) const = 0; - virtual ~MapgenSpecificParams() {} -}; - struct MapgenParams { - std::string mg_name; + MapgenType mgtype; s16 chunksize; u64 seed; s16 water_level; u32 flags; BiomeParams *bparams; - MapgenSpecificParams *sparams; MapgenParams() : - mg_name(MAPGEN_DEFAULT_NAME), + mgtype(MAPGEN_DEFAULT), chunksize(5), seed(0), water_level(1), flags(MG_CAVES | MG_LIGHT | MG_DECORATIONS), - bparams(NULL), - sparams(NULL) + bparams(NULL) { } virtual ~MapgenParams(); - void load(const Settings &settings); - void save(Settings &settings) const; + virtual void readParams(const Settings *settings); + virtual void writeParams(Settings *settings) const; }; @@ -217,7 +209,7 @@ public: static const char *getMapgenName(MapgenType mgtype); static Mapgen *createMapgen(MapgenType mgtype, int mgid, MapgenParams *params, EmergeManager *emerge); - static MapgenSpecificParams *createMapgenParams(MapgenType mgtype); + static MapgenParams *createMapgenParams(MapgenType mgtype); static void getMapgenNames(std::vector *mgnames, bool include_hidden); private: diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index 956af999a..2c1715e61 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -49,26 +49,24 @@ FlagDesc flagdesc_mapgen_flat[] = { /////////////////////////////////////////////////////////////////////////////////////// -MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge) +MapgenFlat::MapgenFlat(int mapgenid, MapgenFlatParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - MapgenFlatParams *sp = (MapgenFlatParams *)params->sparams; - - this->spflags = sp->spflags; - this->ground_level = sp->ground_level; - this->large_cave_depth = sp->large_cave_depth; - this->cave_width = sp->cave_width; - this->lake_threshold = sp->lake_threshold; - this->lake_steepness = sp->lake_steepness; - this->hill_threshold = sp->hill_threshold; - this->hill_steepness = sp->hill_steepness; + this->spflags = params->spflags; + this->ground_level = params->ground_level; + this->large_cave_depth = params->large_cave_depth; + this->cave_width = params->cave_width; + this->lake_threshold = params->lake_threshold; + this->lake_steepness = params->lake_steepness; + this->hill_threshold = params->hill_threshold; + this->hill_steepness = params->hill_steepness; //// 2D noise - noise_terrain = new Noise(&sp->np_terrain, seed, csize.X, csize.Z); - noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); + noise_terrain = new Noise(¶ms->np_terrain, seed, csize.X, csize.Z); + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); - MapgenBasic::np_cave1 = sp->np_cave1; - MapgenBasic::np_cave2 = sp->np_cave2; + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; } diff --git a/src/mapgen_flat.h b/src/mapgen_flat.h index 39b6dc302..8b3de2bcf 100644 --- a/src/mapgen_flat.h +++ b/src/mapgen_flat.h @@ -32,7 +32,7 @@ class BiomeManager; extern FlagDesc flagdesc_mapgen_flat[]; -struct MapgenFlatParams : public MapgenSpecificParams { +struct MapgenFlatParams : public MapgenParams { u32 spflags; s16 ground_level; s16 large_cave_depth; @@ -55,7 +55,7 @@ struct MapgenFlatParams : public MapgenSpecificParams { class MapgenFlat : public MapgenBasic { public: - MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge); + MapgenFlat(int mapgenid, MapgenFlatParams *params, EmergeManager *emerge); ~MapgenFlat(); virtual MapgenType getType() const { return MAPGEN_FLAT; } diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 9e4c210dc..0951a0afa 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -47,29 +47,27 @@ FlagDesc flagdesc_mapgen_fractal[] = { /////////////////////////////////////////////////////////////////////////////////////// -MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge) +MapgenFractal::MapgenFractal(int mapgenid, MapgenFractalParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - MapgenFractalParams *sp = (MapgenFractalParams *)params->sparams; - - this->spflags = sp->spflags; - this->cave_width = sp->cave_width; - this->fractal = sp->fractal; - this->iterations = sp->iterations; - this->scale = sp->scale; - this->offset = sp->offset; - this->slice_w = sp->slice_w; - this->julia_x = sp->julia_x; - this->julia_y = sp->julia_y; - this->julia_z = sp->julia_z; - this->julia_w = sp->julia_w; + this->spflags = params->spflags; + this->cave_width = params->cave_width; + this->fractal = params->fractal; + this->iterations = params->iterations; + this->scale = params->scale; + this->offset = params->offset; + this->slice_w = params->slice_w; + this->julia_x = params->julia_x; + this->julia_y = params->julia_y; + this->julia_z = params->julia_z; + this->julia_w = params->julia_w; //// 2D terrain noise - noise_seabed = new Noise(&sp->np_seabed, seed, csize.X, csize.Z); - noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); + noise_seabed = new Noise(¶ms->np_seabed, seed, csize.X, csize.Z); + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); - MapgenBasic::np_cave1 = sp->np_cave1; - MapgenBasic::np_cave2 = sp->np_cave2; + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; this->formula = fractal / 2 + fractal % 2; this->julia = fractal % 2 == 0; diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index cbd5567c4..3331848bc 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -33,7 +33,7 @@ class BiomeManager; extern FlagDesc flagdesc_mapgen_fractal[]; -struct MapgenFractalParams : public MapgenSpecificParams { +struct MapgenFractalParams : public MapgenParams { u32 spflags; float cave_width; u16 fractal; @@ -59,7 +59,7 @@ struct MapgenFractalParams : public MapgenSpecificParams { class MapgenFractal : public MapgenBasic { public: - MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *emerge); + MapgenFractal(int mapgenid, MapgenFractalParams *params, EmergeManager *emerge); ~MapgenFractal(); virtual MapgenType getType() const { return MAPGEN_FRACTAL; } diff --git a/src/mapgen_singlenode.h b/src/mapgen_singlenode.h index 58672a0ed..07520134d 100644 --- a/src/mapgen_singlenode.h +++ b/src/mapgen_singlenode.h @@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen.h" -struct MapgenSinglenodeParams : public MapgenSpecificParams { +struct MapgenSinglenodeParams : public MapgenParams { MapgenSinglenodeParams() {} ~MapgenSinglenodeParams() {} diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 74d5e1ee3..9f189e253 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -45,25 +45,23 @@ FlagDesc flagdesc_mapgen_v5[] = { }; -MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) +MapgenV5::MapgenV5(int mapgenid, MapgenV5Params *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - MapgenV5Params *sp = (MapgenV5Params *)params->sparams; - - this->spflags = sp->spflags; - this->cave_width = sp->cave_width; + this->spflags = params->spflags; + this->cave_width = params->cave_width; // Terrain noise - noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); - noise_factor = new Noise(&sp->np_factor, seed, csize.X, csize.Z); - noise_height = new Noise(&sp->np_height, seed, csize.X, csize.Z); + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + noise_factor = new Noise(¶ms->np_factor, seed, csize.X, csize.Z); + noise_height = new Noise(¶ms->np_height, seed, csize.X, csize.Z); // 3D terrain noise // 1-up 1-down overgeneration - noise_ground = new Noise(&sp->np_ground, seed, csize.X, csize.Y + 2, csize.Z); + noise_ground = new Noise(¶ms->np_ground, seed, csize.X, csize.Y + 2, csize.Z); - MapgenBasic::np_cave1 = sp->np_cave1; - MapgenBasic::np_cave2 = sp->np_cave2; + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; } diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h index 5f6b10383..ddb090a9c 100644 --- a/src/mapgen_v5.h +++ b/src/mapgen_v5.h @@ -30,7 +30,7 @@ class BiomeManager; extern FlagDesc flagdesc_mapgen_v5[]; -struct MapgenV5Params : public MapgenSpecificParams { +struct MapgenV5Params : public MapgenParams { u32 spflags; float cave_width; NoiseParams np_filler_depth; @@ -50,7 +50,7 @@ struct MapgenV5Params : public MapgenSpecificParams { class MapgenV5 : public MapgenBasic { public: - MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge); + MapgenV5(int mapgenid, MapgenV5Params *params, EmergeManager *emerge); ~MapgenV5(); virtual MapgenType getType() const { return MAPGEN_V5; } diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index caa64827e..e4444963f 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -53,7 +53,7 @@ FlagDesc flagdesc_mapgen_v6[] = { ///////////////////////////////////////////////////////////////////////////// -MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) +MapgenV6::MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge) : Mapgen(mapgenid, params, emerge) { this->m_emerge = emerge; @@ -61,26 +61,25 @@ MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) this->heightmap = new s16[csize.X * csize.Z]; - MapgenV6Params *sp = (MapgenV6Params *)params->sparams; - this->spflags = sp->spflags; - this->freq_desert = sp->freq_desert; - this->freq_beach = sp->freq_beach; + this->spflags = params->spflags; + this->freq_desert = params->freq_desert; + this->freq_beach = params->freq_beach; - np_cave = &sp->np_cave; - np_humidity = &sp->np_humidity; - np_trees = &sp->np_trees; - np_apple_trees = &sp->np_apple_trees; + np_cave = ¶ms->np_cave; + np_humidity = ¶ms->np_humidity; + np_trees = ¶ms->np_trees; + np_apple_trees = ¶ms->np_apple_trees; //// Create noise objects - noise_terrain_base = new Noise(&sp->np_terrain_base, seed, csize.X, csize.Y); - noise_terrain_higher = new Noise(&sp->np_terrain_higher, seed, csize.X, csize.Y); - noise_steepness = new Noise(&sp->np_steepness, seed, csize.X, csize.Y); - noise_height_select = new Noise(&sp->np_height_select, seed, csize.X, csize.Y); - noise_mud = new Noise(&sp->np_mud, seed, csize.X, csize.Y); - noise_beach = new Noise(&sp->np_beach, seed, csize.X, csize.Y); - noise_biome = new Noise(&sp->np_biome, seed, + noise_terrain_base = new Noise(¶ms->np_terrain_base, seed, csize.X, csize.Y); + noise_terrain_higher = new Noise(¶ms->np_terrain_higher, seed, csize.X, csize.Y); + noise_steepness = new Noise(¶ms->np_steepness, seed, csize.X, csize.Y); + noise_height_select = new Noise(¶ms->np_height_select, seed, csize.X, csize.Y); + noise_mud = new Noise(¶ms->np_mud, seed, csize.X, csize.Y); + noise_beach = new Noise(¶ms->np_beach, seed, csize.X, csize.Y); + noise_biome = new Noise(¶ms->np_biome, seed, csize.X + 2 * MAP_BLOCKSIZE, csize.Y + 2 * MAP_BLOCKSIZE); - noise_humidity = new Noise(&sp->np_humidity, seed, + noise_humidity = new Noise(¶ms->np_humidity, seed, csize.X + 2 * MAP_BLOCKSIZE, csize.Y + 2 * MAP_BLOCKSIZE); //// Resolve nodes to be used diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h index 20b0bf92e..f018ffaca 100644 --- a/src/mapgen_v6.h +++ b/src/mapgen_v6.h @@ -53,7 +53,7 @@ enum BiomeV6Type }; -struct MapgenV6Params : public MapgenSpecificParams { +struct MapgenV6Params : public MapgenParams { u32 spflags; float freq_desert; float freq_beach; @@ -124,7 +124,7 @@ public: content_t c_mossycobble; content_t c_stair_cobble; - MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge); + MapgenV6(int mapgenid, MapgenV6Params *params, EmergeManager *emerge); ~MapgenV6(); virtual MapgenType getType() const { return MAPGEN_V6; } diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index c24b3e8d1..d14fdb97a 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -50,30 +50,28 @@ FlagDesc flagdesc_mapgen_v7[] = { /////////////////////////////////////////////////////////////////////////////// -MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) +MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - MapgenV7Params *sp = (MapgenV7Params *)params->sparams; - - this->spflags = sp->spflags; - this->cave_width = sp->cave_width; + this->spflags = params->spflags; + this->cave_width = params->cave_width; //// Terrain noise - noise_terrain_base = new Noise(&sp->np_terrain_base, seed, csize.X, csize.Z); - noise_terrain_alt = new Noise(&sp->np_terrain_alt, seed, csize.X, csize.Z); - noise_terrain_persist = new Noise(&sp->np_terrain_persist, seed, csize.X, csize.Z); - noise_height_select = new Noise(&sp->np_height_select, seed, csize.X, csize.Z); - noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); - noise_mount_height = new Noise(&sp->np_mount_height, seed, csize.X, csize.Z); - noise_ridge_uwater = new Noise(&sp->np_ridge_uwater, seed, csize.X, csize.Z); + noise_terrain_base = new Noise(¶ms->np_terrain_base, seed, csize.X, csize.Z); + noise_terrain_alt = new Noise(¶ms->np_terrain_alt, seed, csize.X, csize.Z); + noise_terrain_persist = new Noise(¶ms->np_terrain_persist, seed, csize.X, csize.Z); + noise_height_select = new Noise(¶ms->np_height_select, seed, csize.X, csize.Z); + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + noise_mount_height = new Noise(¶ms->np_mount_height, seed, csize.X, csize.Z); + noise_ridge_uwater = new Noise(¶ms->np_ridge_uwater, seed, csize.X, csize.Z); //// 3d terrain noise // 1-up 1-down overgeneration - noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y + 2, csize.Z); - noise_ridge = new Noise(&sp->np_ridge, seed, csize.X, csize.Y + 2, csize.Z); + noise_mountain = new Noise(¶ms->np_mountain, seed, csize.X, csize.Y + 2, csize.Z); + noise_ridge = new Noise(¶ms->np_ridge, seed, csize.X, csize.Y + 2, csize.Z); - MapgenBasic::np_cave1 = sp->np_cave1; - MapgenBasic::np_cave2 = sp->np_cave2; + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; } diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index c75f18a93..3a6bc0801 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -32,7 +32,7 @@ class BiomeManager; extern FlagDesc flagdesc_mapgen_v7[]; -struct MapgenV7Params : public MapgenSpecificParams { +struct MapgenV7Params : public MapgenParams { u32 spflags; float cave_width; NoiseParams np_terrain_base; @@ -56,7 +56,7 @@ struct MapgenV7Params : public MapgenSpecificParams { class MapgenV7 : public MapgenBasic { public: - MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge); + MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge); ~MapgenV7(); virtual MapgenType getType() const { return MAPGEN_V7; } diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 02a8fbfe0..a61f1b329 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -64,7 +64,7 @@ static FlagDesc flagdesc_mapgen_valleys[] = { /////////////////////////////////////////////////////////////////////////////// -MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge) +MapgenValleys::MapgenValleys(int mapgenid, MapgenValleysParams *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { // NOTE: MapgenValleys has a hard dependency on BiomeGenOriginal @@ -73,34 +73,33 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * this->map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT, g_settings->getU16("map_generation_limit")); - MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams; BiomeParamsOriginal *bp = (BiomeParamsOriginal *)params->bparams; - this->spflags = sp->spflags; - this->altitude_chill = sp->altitude_chill; - this->large_cave_depth = sp->large_cave_depth; - this->lava_features_lim = rangelim(sp->lava_features, 0, 10); - this->massive_cave_depth = sp->massive_cave_depth; - this->river_depth_bed = sp->river_depth + 1.f; - this->river_size_factor = sp->river_size / 100.f; - this->water_features_lim = rangelim(sp->water_features, 0, 10); - this->cave_width = sp->cave_width; + this->spflags = params->spflags; + this->altitude_chill = params->altitude_chill; + this->large_cave_depth = params->large_cave_depth; + this->lava_features_lim = rangelim(params->lava_features, 0, 10); + this->massive_cave_depth = params->massive_cave_depth; + this->river_depth_bed = params->river_depth + 1.f; + this->river_size_factor = params->river_size / 100.f; + this->water_features_lim = rangelim(params->water_features, 0, 10); + this->cave_width = params->cave_width; //// 2D Terrain noise - noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z); - noise_inter_valley_slope = new Noise(&sp->np_inter_valley_slope, seed, csize.X, csize.Z); - noise_rivers = new Noise(&sp->np_rivers, seed, csize.X, csize.Z); - noise_terrain_height = new Noise(&sp->np_terrain_height, seed, csize.X, csize.Z); - noise_valley_depth = new Noise(&sp->np_valley_depth, seed, csize.X, csize.Z); - noise_valley_profile = new Noise(&sp->np_valley_profile, seed, csize.X, csize.Z); + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + noise_inter_valley_slope = new Noise(¶ms->np_inter_valley_slope, seed, csize.X, csize.Z); + noise_rivers = new Noise(¶ms->np_rivers, seed, csize.X, csize.Z); + noise_terrain_height = new Noise(¶ms->np_terrain_height, seed, csize.X, csize.Z); + noise_valley_depth = new Noise(¶ms->np_valley_depth, seed, csize.X, csize.Z); + noise_valley_profile = new Noise(¶ms->np_valley_profile, seed, csize.X, csize.Z); //// 3D Terrain noise // 1-up 1-down overgeneration - noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z); + noise_inter_valley_fill = new Noise(¶ms->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z); // 1-down overgeneraion - noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z); - noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); - noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z); + noise_cave1 = new Noise(¶ms->np_cave1, seed, csize.X, csize.Y + 1, csize.Z); + noise_cave2 = new Noise(¶ms->np_cave2, seed, csize.X, csize.Y + 1, csize.Z); + noise_massive_caves = new Noise(¶ms->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z); this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS); this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL); diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 00f6aff07..6dd7ebc47 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -46,7 +46,7 @@ class BiomeGenOriginal; //extern Profiler *mapgen_profiler; -struct MapgenValleysParams : public MapgenSpecificParams { +struct MapgenValleysParams : public MapgenParams { u32 spflags; s16 large_cave_depth; s16 massive_cave_depth; @@ -88,7 +88,7 @@ struct TerrainNoise { class MapgenValleys : public MapgenBasic { public: - MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *emerge); + MapgenValleys(int mapgenid, MapgenValleysParams *params, EmergeManager *emerge); ~MapgenValleys(); virtual MapgenType getType() const { return MAPGEN_VALLEYS; } diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index dc188f8a4..9f14838ce 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -600,24 +600,37 @@ int ModApiMapgen::l_get_mapgen_params(lua_State *L) { NO_MAP_LOCK_REQUIRED; - MapgenParams *params = &getServer(L)->getEmergeManager()->params; + log_deprecated(L, "get_mapgen_params is deprecated; " + "use get_mapgen_setting instead"); + + std::string value; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; lua_newtable(L); - lua_pushstring(L, params->mg_name.c_str()); + settingsmgr->getMapSetting("mg_name", &value); + lua_pushstring(L, value.c_str()); lua_setfield(L, -2, "mgname"); - lua_pushinteger(L, params->seed); + settingsmgr->getMapSetting("seed", &value); + std::istringstream ss(value); + u64 seed; + ss >> seed; + lua_pushinteger(L, seed); lua_setfield(L, -2, "seed"); - lua_pushinteger(L, params->water_level); + settingsmgr->getMapSetting("water_level", &value); + lua_pushinteger(L, stoi(value, -32768, 32767)); lua_setfield(L, -2, "water_level"); - lua_pushinteger(L, params->chunksize); + settingsmgr->getMapSetting("chunksize", &value); + lua_pushinteger(L, stoi(value, -32768, 32767)); lua_setfield(L, -2, "chunksize"); - std::string flagstr = writeFlagString(params->flags, flagdesc_mapgen, U32_MAX); - lua_pushstring(L, flagstr.c_str()); + settingsmgr->getMapSetting("mg_flags", &value); + lua_pushstring(L, value.c_str()); lua_setfield(L, -2, "flags"); return 1; @@ -630,44 +643,120 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L) { NO_MAP_LOCK_REQUIRED; + log_deprecated(L, "set_mapgen_params is deprecated; " + "use set_mapgen_setting instead"); + if (!lua_istable(L, 1)) return 0; - EmergeManager *emerge = getServer(L)->getEmergeManager(); - if (emerge->isRunning()) - throw LuaError("Cannot set parameters while mapgen is running"); - - MapgenParams *params = &emerge->params; - u32 flags = 0, flagmask = 0; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; lua_getfield(L, 1, "mgname"); - if (lua_isstring(L, -1)) { - params->mg_name = lua_tostring(L, -1); - delete params->sparams; - params->sparams = NULL; - } + if (lua_isstring(L, -1)) + settingsmgr->setMapSetting("mg_name", lua_tostring(L, -1), true); lua_getfield(L, 1, "seed"); if (lua_isnumber(L, -1)) - params->seed = lua_tointeger(L, -1); + settingsmgr->setMapSetting("seed", lua_tostring(L, -1), true); lua_getfield(L, 1, "water_level"); if (lua_isnumber(L, -1)) - params->water_level = lua_tointeger(L, -1); + settingsmgr->setMapSetting("water_level", lua_tostring(L, -1), true); lua_getfield(L, 1, "chunksize"); if (lua_isnumber(L, -1)) - params->chunksize = lua_tointeger(L, -1); + settingsmgr->setMapSetting("chunksize", lua_tostring(L, -1), true); warn_if_field_exists(L, 1, "flagmask", "Deprecated: flags field now includes unset flags."); - lua_getfield(L, 1, "flagmask"); + + lua_getfield(L, 1, "flags"); if (lua_isstring(L, -1)) - params->flags &= ~readFlagString(lua_tostring(L, -1), flagdesc_mapgen, NULL); + settingsmgr->setMapSetting("mg_flags", lua_tostring(L, -1), true); + + return 0; +} + +// get_mapgen_setting(name) +int ModApiMapgen::l_get_mapgen_setting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; - if (getflagsfield(L, 1, "flags", flagdesc_mapgen, &flags, &flagmask)) { - params->flags &= ~flagmask; - params->flags |= flags; + std::string value; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + if (!settingsmgr->getMapSetting(name, &value)) + return 0; + + lua_pushstring(L, value.c_str()); + return 1; +} + +// get_mapgen_setting_noiseparams(name) +int ModApiMapgen::l_get_mapgen_setting_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + NoiseParams np; + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + if (!settingsmgr->getMapSettingNoiseParams(name, &np)) + return 0; + + push_noiseparams(L, &np); + return 1; +} + +// set_mapgen_setting(name, value, override_meta) +// set mapgen config values +int ModApiMapgen::l_set_mapgen_setting(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + const char *value = luaL_checkstring(L, 2); + bool override_meta = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false; + + if (!settingsmgr->setMapSetting(name, value, override_meta)) { + errorstream << "set_mapgen_setting: cannot set '" + << name << "' after initialization" << std::endl; + } + + return 0; +} + + +// set_mapgen_setting_noiseparams(name, noiseparams, set_default) +// set mapgen config values for noise parameters +int ModApiMapgen::l_set_mapgen_setting_noiseparams(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + MapSettingsManager *settingsmgr = + getServer(L)->getEmergeManager()->map_settings_mgr; + + const char *name = luaL_checkstring(L, 1); + + NoiseParams np; + if (!read_noiseparams(L, 2, &np)) { + errorstream << "set_mapgen_setting_noiseparams: cannot set '" << name + << "'; invalid noiseparams table" << std::endl; + return 0; + } + + bool override_meta = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false; + + if (!settingsmgr->setMapSettingNoiseParams(name, &np, override_meta)) { + errorstream << "set_mapgen_setting_noiseparams: cannot set '" + << name << "' after initialization" << std::endl; } return 0; @@ -683,8 +772,11 @@ int ModApiMapgen::l_set_noiseparams(lua_State *L) const char *name = luaL_checkstring(L, 1); NoiseParams np; - if (!read_noiseparams(L, 2, &np)) + if (!read_noiseparams(L, 2, &np)) { + errorstream << "set_noiseparams: cannot set '" << name + << "'; invalid noiseparams table" << std::endl; return 0; + } bool set_default = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : true; @@ -1143,7 +1235,7 @@ int ModApiMapgen::l_generate_ores(lua_State *L) EmergeManager *emerge = getServer(L)->getEmergeManager(); Mapgen mg; - mg.seed = emerge->params.seed; + mg.seed = emerge->mgparams->seed; mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; mg.ndef = getServer(L)->getNodeDefManager(); @@ -1169,7 +1261,7 @@ int ModApiMapgen::l_generate_decorations(lua_State *L) EmergeManager *emerge = getServer(L)->getEmergeManager(); Mapgen mg; - mg.seed = emerge->params.seed; + mg.seed = emerge->mgparams->seed; mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; mg.ndef = getServer(L)->getNodeDefManager(); @@ -1393,6 +1485,10 @@ void ModApiMapgen::Initialize(lua_State *L, int top) API_FCT(get_mapgen_params); API_FCT(set_mapgen_params); + API_FCT(get_mapgen_setting); + API_FCT(set_mapgen_setting); + API_FCT(get_mapgen_setting_noiseparams); + API_FCT(set_mapgen_setting_noiseparams); API_FCT(set_noiseparams); API_FCT(get_noiseparams); API_FCT(set_gen_notify); diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h index 9751c0db6..bb94575c7 100644 --- a/src/script/lua_api/l_mapgen.h +++ b/src/script/lua_api/l_mapgen.h @@ -40,6 +40,18 @@ private: // set mapgen parameters static int l_set_mapgen_params(lua_State *L); + // get_mapgen_setting(name) + static int l_get_mapgen_setting(lua_State *L); + + // set_mapgen_setting(name, value, override_meta) + static int l_set_mapgen_setting(lua_State *L); + + // get_mapgen_setting_noiseparams(name) + static int l_get_mapgen_setting_noiseparams(lua_State *L); + + // set_mapgen_setting_noiseparams(name, value, override_meta) + static int l_set_mapgen_setting_noiseparams(lua_State *L); + // set_noiseparam_defaults(name, noiseparams, set_default) static int l_set_noiseparams(lua_State *L); diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index f13866408..0d8123acd 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -190,7 +190,7 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L) Mapgen mg; mg.vm = vm; mg.ndef = ndef; - mg.water_level = emerge->params.water_level; + mg.water_level = emerge->mgparams->water_level; mg.calcLighting(pmin, pmax, fpmin, fpmax, propagate_shadow); diff --git a/src/server.cpp b/src/server.cpp index f7f698d50..97a53f189 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -266,9 +266,6 @@ Server::Server( //lock environment MutexAutoLock envlock(m_env_mutex); - // Load mapgen params from Settings - m_emerge->loadMapgenParams(); - // Create the Map (loads map_meta.txt, overriding configured mapgen params) ServerMap *servermap = new ServerMap(path_world, this, m_emerge); @@ -331,8 +328,11 @@ Server::Server( m_clients.setEnv(m_env); + if (!servermap->settings_mgr.makeMapgenParams()) + FATAL_ERROR("Couldn't create any mapgen type"); + // Initialize mapgens - m_emerge->initMapgens(); + m_emerge->initMapgens(servermap->getMapgenParams()); m_enable_rollback_recording = g_settings->getBool("enable_rollback_recording"); if (m_enable_rollback_recording) { @@ -402,11 +402,8 @@ Server::~Server() m_emerge->stopThreads(); // Delete things in the reverse order of creation - delete m_env; - - // N.B. the EmergeManager should be deleted after the Environment since Map - // depends on EmergeManager to write its current params to the map meta delete m_emerge; + delete m_env; delete m_rollback; delete m_banmanager; delete m_event; @@ -655,7 +652,7 @@ void Server::AsyncRunStep(bool initial_step) m_env->getGameTime(), m_lag, m_gamespec.id, - m_emerge->params.mg_name, + Mapgen::getMapgenName(m_emerge->mgparams->mgtype), m_mods); counter = 0.01; } diff --git a/src/subgame.cpp b/src/subgame.cpp index 7e9a0b368..55bbd3954 100644 --- a/src/subgame.cpp +++ b/src/subgame.cpp @@ -313,8 +313,8 @@ bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamesp Settings conf; MapgenParams params; - params.load(*g_settings); - params.save(conf); + params.readParams(g_settings); + params.writeParams(&conf); conf.writeLines(oss); oss << "[end_of_params]\n"; diff --git a/src/unittest/CMakeLists.txt b/src/unittest/CMakeLists.txt index a07ed8ba5..34de99e12 100644 --- a/src/unittest/CMakeLists.txt +++ b/src/unittest/CMakeLists.txt @@ -6,6 +6,7 @@ set (UNITTEST_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/test_connection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_filepath.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_inventory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_map_settings_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_mapnode.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_nodedef.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_noderesolver.cpp diff --git a/src/unittest/test_map_settings_manager.cpp b/src/unittest/test_map_settings_manager.cpp new file mode 100644 index 000000000..b2ad53192 --- /dev/null +++ b/src/unittest/test_map_settings_manager.cpp @@ -0,0 +1,255 @@ + /* +Minetest +Copyright (C) 2010-2014 kwolekr, Ryan Kwolek + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "test.h" + +#include "noise.h" +#include "settings.h" +#include "mapgen_v5.h" +#include "util/sha1.h" +#include "map_settings_manager.h" + +class TestMapSettingsManager : public TestBase { +public: + TestMapSettingsManager() { TestManager::registerTestModule(this); } + const char *getName() { return "TestMapSettingsManager"; } + + void makeUserConfig(Settings *conf); + std::string makeMetaFile(bool make_corrupt); + + void runTests(IGameDef *gamedef); + + void testMapSettingsManager(); + void testMapMetaSaveLoad(); + void testMapMetaFailures(); +}; + +static TestMapSettingsManager g_test_instance; + +void TestMapSettingsManager::runTests(IGameDef *gamedef) +{ + TEST(testMapSettingsManager); + TEST(testMapMetaSaveLoad); + TEST(testMapMetaFailures); +} + +//////////////////////////////////////////////////////////////////////////////// + + +void check_noise_params(const NoiseParams *np1, const NoiseParams *np2) +{ + UASSERTEQ(float, np1->offset, np2->offset); + UASSERTEQ(float, np1->scale, np2->scale); + UASSERT(np1->spread == np2->spread); + UASSERTEQ(s32, np1->seed, np2->seed); + UASSERTEQ(u16, np1->octaves, np2->octaves); + UASSERTEQ(float, np1->persist, np2->persist); + UASSERTEQ(float, np1->lacunarity, np2->lacunarity); + UASSERTEQ(u32, np1->flags, np2->flags); +} + + +std::string read_file_to_string(const std::string &filepath) +{ + std::string buf; + FILE *f = fopen(filepath.c_str(), "rb"); + if (!f) + return ""; + + fseek(f, 0, SEEK_END); + + long filesize = ftell(f); + if (filesize == -1) + return ""; + rewind(f); + + buf.resize(filesize); + + fread(&buf[0], 1, filesize, f); + + fclose(f); + return buf; +} + + +void TestMapSettingsManager::makeUserConfig(Settings *conf) +{ + conf->set("mg_name", "v7"); + conf->set("seed", "5678"); + conf->set("water_level", "20"); + conf->set("mgv5_np_factor", "0, 12, (500, 250, 500), 920382, 5, 0.45, 3.0"); + conf->set("mgv5_np_height", "0, 15, (500, 250, 500), 841746, 5, 0.5, 3.0"); + conf->set("mgv5_np_filler_depth", "20, 1, (150, 150, 150), 261, 4, 0.7, 1.0"); + conf->set("mgv5_np_ground", "-43, 40, (80, 80, 80), 983240, 4, 0.55, 2.0"); +} + + +std::string TestMapSettingsManager::makeMetaFile(bool make_corrupt) +{ + std::string metafile = getTestTempFile(); + + const char *metafile_contents = + "mg_name = v5\n" + "seed = 1234\n" + "mg_flags = light\n" + "mgv5_np_filler_depth = 20, 1, (150, 150, 150), 261, 4, 0.7, 1.0\n" + "mgv5_np_height = 20, 10, (250, 250, 250), 84174, 4, 0.5, 1.0\n"; + + FILE *f = fopen(metafile.c_str(), "wb"); + UASSERT(f != NULL); + + fputs(metafile_contents, f); + if (!make_corrupt) + fputs("[end_of_params]\n", f); + + fclose(f); + + return metafile; +} + + +void TestMapSettingsManager::testMapSettingsManager() +{ + Settings user_settings; + makeUserConfig(&user_settings); + + std::string test_mapmeta_path = makeMetaFile(false); + + MapSettingsManager mgr(&user_settings, test_mapmeta_path); + std::string value; + + UASSERT(mgr.getMapSetting("mg_name", &value)); + UASSERT(value == "v7"); + + // Pretend we're initializing the ServerMap + UASSERT(mgr.loadMapMeta()); + + // Pretend some scripts are requesting mapgen params + UASSERT(mgr.getMapSetting("mg_name", &value)); + UASSERT(value == "v5"); + UASSERT(mgr.getMapSetting("seed", &value)); + UASSERT(value == "1234"); + UASSERT(mgr.getMapSetting("water_level", &value)); + UASSERT(value == "20"); + + // Pretend we have some mapgen settings configured from the scripting + UASSERT(mgr.setMapSetting("water_level", "15")); + UASSERT(mgr.setMapSetting("seed", "02468")); + UASSERT(mgr.setMapSetting("mg_flags", "nolight", true)); + + NoiseParams script_np_filler_depth(0, 100, v3f(200, 100, 200), 261, 4, 0.7, 2.0); + NoiseParams script_np_factor(0, 100, v3f(50, 50, 50), 920381, 3, 0.45, 2.0); + NoiseParams script_np_height(0, 100, v3f(450, 450, 450), 84174, 4, 0.5, 2.0); + NoiseParams meta_np_height(20, 10, v3f(250, 250, 250), 84174, 4, 0.5, 1.0); + NoiseParams user_np_ground(-43, 40, v3f(80, 80, 80), 983240, 4, 0.55, 2.0, NOISE_FLAG_EASED); + + mgr.setMapSettingNoiseParams("mgv5_np_filler_depth", &script_np_filler_depth, true); + mgr.setMapSettingNoiseParams("mgv5_np_height", &script_np_height); + mgr.setMapSettingNoiseParams("mgv5_np_factor", &script_np_factor); + + // Now make our Params and see if the values are correctly sourced + MapgenParams *params = mgr.makeMapgenParams(); + UASSERT(params->mgtype == MAPGEN_V5); + UASSERT(params->chunksize == 5); + UASSERT(params->water_level == 15); + UASSERT(params->seed == 1234); + UASSERT((params->flags & MG_LIGHT) == 0); + + MapgenV5Params *v5params = (MapgenV5Params *)params; + + check_noise_params(&v5params->np_filler_depth, &script_np_filler_depth); + check_noise_params(&v5params->np_factor, &script_np_factor); + check_noise_params(&v5params->np_height, &meta_np_height); + check_noise_params(&v5params->np_ground, &user_np_ground); + + UASSERT(mgr.setMapSetting("foobar", "25") == false); + + // Pretend the ServerMap is shutting down + UASSERT(mgr.saveMapMeta()); + + // Make sure our interface expectations are met + UASSERT(mgr.mapgen_params == params); + UASSERT(mgr.makeMapgenParams() == params); + + // Load the resulting map_meta.txt and make sure it contains what we expect + unsigned char expected_contents_hash[20] = { + 0xf6, 0x44, 0x90, 0xb7, 0xab, 0xd8, 0x91, 0xf4, 0x08, 0x96, + 0xfc, 0x7e, 0xed, 0x01, 0xc5, 0x9a, 0xfd, 0x2f, 0x2d, 0x79 + }; + + SHA1 ctx; + std::string metafile_contents = read_file_to_string(test_mapmeta_path); + ctx.addBytes(&metafile_contents[0], metafile_contents.size()); + unsigned char *sha1_result = ctx.getDigest(); + int resultdiff = memcmp(sha1_result, expected_contents_hash, 20); + free(sha1_result); + + UASSERT(!resultdiff); +} + + +void TestMapSettingsManager::testMapMetaSaveLoad() +{ + Settings conf; + std::string path = getTestTempDirectory() + + DIR_DELIM + "foobar" + DIR_DELIM + "map_meta.txt"; + + // Create a set of mapgen params and save them to map meta + conf.set("seed", "12345"); + conf.set("water_level", "5"); + MapSettingsManager mgr1(&conf, path); + MapgenParams *params1 = mgr1.makeMapgenParams(); + UASSERT(params1); + UASSERT(mgr1.saveMapMeta()); + + // Now try loading the map meta to mapgen params + conf.set("seed", "67890"); + conf.set("water_level", "32"); + MapSettingsManager mgr2(&conf, path); + UASSERT(mgr2.loadMapMeta()); + MapgenParams *params2 = mgr2.makeMapgenParams(); + UASSERT(params2); + + // Check that both results are correct + UASSERTEQ(u64, params1->seed, 12345); + UASSERTEQ(s16, params1->water_level, 5); + UASSERTEQ(u64, params2->seed, 12345); + UASSERTEQ(s16, params2->water_level, 5); +} + + +void TestMapSettingsManager::testMapMetaFailures() +{ + std::string test_mapmeta_path; + Settings conf; + + // Check to see if it'll fail on a non-existent map meta file + test_mapmeta_path = "woobawooba/fgdfg/map_meta.txt"; + UASSERT(!fs::PathExists(test_mapmeta_path)); + + MapSettingsManager mgr1(&conf, test_mapmeta_path); + UASSERT(!mgr1.loadMapMeta()); + + // Check to see if it'll fail on a corrupt map meta file + test_mapmeta_path = makeMetaFile(true); + UASSERT(fs::PathExists(test_mapmeta_path)); + + MapSettingsManager mgr2(&conf, test_mapmeta_path); + UASSERT(!mgr2.loadMapMeta()); +} -- cgit v1.2.3 From bc3980e1d69ca9f848f80eb7386525fa4fb326cd Mon Sep 17 00:00:00 2001 From: paramat Date: Fri, 16 Sep 2016 04:59:25 +0100 Subject: Mgv7: Add optional floatlands, disabled by default --- builtin/settingtypes.txt | 24 +++++- minetest.conf.example | 29 ++++++- src/mapgen_v7.cpp | 212 ++++++++++++++++++++++++++++++++++------------- src/mapgen_v7.h | 24 +++++- 4 files changed, 221 insertions(+), 68 deletions(-) (limited to 'src/mapgen_v7.h') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index e48fc9bc5..b1f31054e 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -963,23 +963,39 @@ mgv6_np_apple_trees (Mapgen v6 apple trees noise parameters) noise_params 0, 1, [***Mapgen v7] # Map generation attributes specific to Mapgen v7. -# The 'ridges' flag controls the rivers. +# The 'ridges' flag enables the rivers. +# Floatlands are currently experimental and subject to change. # Flags that are not specified in the flag string are not modified from the default. # Flags starting with 'no' are used to explicitly disable them. -mgv7_spflags (Mapgen v7 flags) flags mountains,ridges mountains,ridges,nomountains,noridges +mgv7_spflags (Mapgen v7 flags) flags mountains,ridges mountains,ridges,floatlands,nomountains,noridges,nofloatlands # Controls width of tunnels, a smaller value creates wider tunnels. mgv7_cave_width (Mapgen v7 cave width) float 0.2 +# Controls the density of floatland mountain terrain. +# Is an offset added to the 'np_mountain' noise value. +mgv7_float_mount_density (Mapgen v7 floatland mountain density) float 0.6 + +# Typical maximum height, above and below midpoint, of floatland mountain terrain. +mgv7_float_mount_height (Mapgen v7 floatland mountain height) float 128.0 + +# Y-level of floatland midpoint and lake surface. +mgv7_floatland_level (Mapgen v7 floatland level) int 1280 + +# Y-level to which floatland shadows extend. +mgv7_shadow_limit (Mapgen v7 shadow limit) int 1024 + mgv7_np_terrain_base (Mapgen v7 terrain base noise parameters) noise_params 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0 mgv7_np_terrain_alt (Mapgen v7 terrain altitude noise parameters) noise_params 4, 25, (600, 600, 600), 5934, 5, 0.6, 2.0 mgv7_np_terrain_persist (Mapgen v7 terrain persistation noise parameters) noise_params 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0 mgv7_np_height_select (Mapgen v7 height select noise parameters) noise_params -8, 16, (500, 500, 500), 4213, 6, 0.7, 2.0 mgv7_np_filler_depth (Mapgen v7 filler depth noise parameters) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0 mgv7_np_mount_height (Mapgen v7 mount height noise parameters) noise_params 256, 112, (1000, 1000, 1000), 72449, 3, 0.6, 2.0 -mgv7_np_ridge_uwater (Mapgen v7 ridge water noise parameters) noise_params 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0 +mgv7_np_ridge_uwater (Mapgen v7 river course noise parameters) noise_params 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0 +mgv7_np_floatland_base (Mapgen v7 floatland base terrain noise parameters) noise_params -0.6, 1.5, (600, 600, 600), 114, 5, 0.6, 2.0 +mgv7_np_float_base_height (Mapgen v7 floatland base terrain height noise parameters) noise_params 48, 24, (300, 300, 300), 907, 4, 0.7, 2.0 mgv7_np_mountain (Mapgen v7 mountain noise parameters) noise_params -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0 -mgv7_np_ridge (Mapgen v7 ridge noise parameters) noise_params 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0 +mgv7_np_ridge (Mapgen v7 river channel wall noise parameters) noise_params 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0 mgv7_np_cave1 (Mapgen v7 cave1 noise parameters) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0 mgv7_np_cave2 (Mapgen v7 cave2 noise parameters) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0 diff --git a/minetest.conf.example b/minetest.conf.example index 02f31779f..361311ba0 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -1239,16 +1239,35 @@ #### Mapgen v7 # Map generation attributes specific to Mapgen v7. -# The 'ridges' flag controls the rivers. +# The 'ridges' flag enables the rivers. +# Floatlands are currently experimental and subject to change. # Flags that are not specified in the flag string are not modified from the default. # Flags starting with 'no' are used to explicitly disable them. -# type: flags possible values: mountains, ridges, nomountains, noridges +# type: flags possible values: mountains, ridges, floatlands, +# nomountains, noridges, nofloatlands # mgv7_spflags = mountains,ridges # Controls width of tunnels, a smaller value creates wider tunnels. # type: float # mgv7_cave_width = 0.2 +# Controls the density of floatland mountain terrain. +# Is an offset added to the 'np_mountain' noise value. +# type: float +# mgv7_float_mount_density = 0.6 + +# Typical maximum height, above and below midpoint, of floatland mountain terrain. +# type: float +# mgv7_float_mount_height = 128.0 + +# Y-level of floatland midpoint and lake surface. +# type: int +# mgv7_floatland_level = 1280 + +# Y-level to which floatland shadows extend. +# type: int +# mgv7_shadow_limit = 1024 + # type: noise_params # mgv7_np_terrain_base = 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0 @@ -1270,6 +1289,12 @@ # type: noise_params # mgv7_np_ridge_uwater = 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0 +# type: noise_params +# mgv7_np_floatland_base = -0.6, 1.5, (600, 600, 600), 114, 5, 0.6, 2.0 + +# type: noise_params +# mgv7_np_float_base_height = 48, 24, (300, 300, 300), 907, 4, 0.7, 2.0 + # type: noise_params # mgv7_np_mountain = -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0 diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 86f559af3..c4fa024a8 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -41,9 +41,10 @@ with this program; if not, write to the Free Software Foundation, Inc., FlagDesc flagdesc_mapgen_v7[] = { - {"mountains", MGV7_MOUNTAINS}, - {"ridges", MGV7_RIDGES}, - {NULL, 0} + {"mountains", MGV7_MOUNTAINS}, + {"ridges", MGV7_RIDGES}, + {"floatlands", MGV7_FLOATLANDS}, + {NULL, 0} }; @@ -53,17 +54,23 @@ FlagDesc flagdesc_mapgen_v7[] = { MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge) : MapgenBasic(mapgenid, params, emerge) { - this->spflags = params->spflags; - this->cave_width = params->cave_width; + this->spflags = params->spflags; + this->cave_width = params->cave_width; + this->float_mount_density = params->float_mount_density; + this->float_mount_height = params->float_mount_height; + this->floatland_level = params->floatland_level; + this->shadow_limit = params->shadow_limit; //// Terrain noise - noise_terrain_base = new Noise(¶ms->np_terrain_base, seed, csize.X, csize.Z); - noise_terrain_alt = new Noise(¶ms->np_terrain_alt, seed, csize.X, csize.Z); - noise_terrain_persist = new Noise(¶ms->np_terrain_persist, seed, csize.X, csize.Z); - noise_height_select = new Noise(¶ms->np_height_select, seed, csize.X, csize.Z); - noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); - noise_mount_height = new Noise(¶ms->np_mount_height, seed, csize.X, csize.Z); - noise_ridge_uwater = new Noise(¶ms->np_ridge_uwater, seed, csize.X, csize.Z); + noise_terrain_base = new Noise(¶ms->np_terrain_base, seed, csize.X, csize.Z); + noise_terrain_alt = new Noise(¶ms->np_terrain_alt, seed, csize.X, csize.Z); + noise_terrain_persist = new Noise(¶ms->np_terrain_persist, seed, csize.X, csize.Z); + noise_height_select = new Noise(¶ms->np_height_select, seed, csize.X, csize.Z); + noise_filler_depth = new Noise(¶ms->np_filler_depth, seed, csize.X, csize.Z); + noise_mount_height = new Noise(¶ms->np_mount_height, seed, csize.X, csize.Z); + noise_ridge_uwater = new Noise(¶ms->np_ridge_uwater, seed, csize.X, csize.Z); + noise_floatland_base = new Noise(¶ms->np_floatland_base, seed, csize.X, csize.Z); + noise_float_base_height = new Noise(¶ms->np_float_base_height, seed, csize.X, csize.Z); //// 3d terrain noise // 1-up 1-down overgeneration @@ -84,6 +91,8 @@ MapgenV7::~MapgenV7() delete noise_filler_depth; delete noise_mount_height; delete noise_ridge_uwater; + delete noise_floatland_base; + delete noise_float_base_height; delete noise_mountain; delete noise_ridge; } @@ -91,58 +100,76 @@ MapgenV7::~MapgenV7() MapgenV7Params::MapgenV7Params() { - spflags = MGV7_MOUNTAINS | MGV7_RIDGES; - cave_width = 0.2; - - np_terrain_base = NoiseParams(4, 70, v3f(600, 600, 600), 82341, 5, 0.6, 2.0); - np_terrain_alt = NoiseParams(4, 25, v3f(600, 600, 600), 5934, 5, 0.6, 2.0); - np_terrain_persist = NoiseParams(0.6, 0.1, v3f(2000, 2000, 2000), 539, 3, 0.6, 2.0); - np_height_select = NoiseParams(-8, 16, v3f(500, 500, 500), 4213, 6, 0.7, 2.0); - np_filler_depth = NoiseParams(0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0); - np_mount_height = NoiseParams(256, 112, v3f(1000, 1000, 1000), 72449, 3, 0.6, 2.0); - np_ridge_uwater = NoiseParams(0, 1, v3f(1000, 1000, 1000), 85039, 5, 0.6, 2.0); - np_mountain = NoiseParams(-0.6, 1, v3f(250, 350, 250), 5333, 5, 0.63, 2.0); - np_ridge = NoiseParams(0, 1, v3f(100, 100, 100), 6467, 4, 0.75, 2.0); - np_cave1 = NoiseParams(0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0); - np_cave2 = NoiseParams(0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0); + spflags = MGV7_MOUNTAINS | MGV7_RIDGES; + cave_width = 0.2; + float_mount_density = 0.6; + float_mount_height = 128.0; + floatland_level = 1280; + shadow_limit = 1024; + + np_terrain_base = NoiseParams(4, 70, v3f(600, 600, 600), 82341, 5, 0.6, 2.0); + np_terrain_alt = NoiseParams(4, 25, v3f(600, 600, 600), 5934, 5, 0.6, 2.0); + np_terrain_persist = NoiseParams(0.6, 0.1, v3f(2000, 2000, 2000), 539, 3, 0.6, 2.0); + np_height_select = NoiseParams(-8, 16, v3f(500, 500, 500), 4213, 6, 0.7, 2.0); + np_filler_depth = NoiseParams(0, 1.2, v3f(150, 150, 150), 261, 3, 0.7, 2.0); + np_mount_height = NoiseParams(256, 112, v3f(1000, 1000, 1000), 72449, 3, 0.6, 2.0); + np_ridge_uwater = NoiseParams(0, 1, v3f(1000, 1000, 1000), 85039, 5, 0.6, 2.0); + np_floatland_base = NoiseParams(-0.6, 1.5, v3f(600, 600, 600), 114, 5, 0.6, 2.0); + np_float_base_height = NoiseParams(48, 24, v3f(300, 300, 300), 907, 4, 0.7, 2.0); + np_mountain = NoiseParams(-0.6, 1, v3f(250, 350, 250), 5333, 5, 0.63, 2.0); + np_ridge = NoiseParams(0, 1, v3f(100, 100, 100), 6467, 4, 0.75, 2.0); + np_cave1 = NoiseParams(0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0); + np_cave2 = NoiseParams(0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0); } void MapgenV7Params::readParams(const Settings *settings) { - settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7); - settings->getFloatNoEx("mgv7_cave_width", cave_width); - - settings->getNoiseParams("mgv7_np_terrain_base", np_terrain_base); - settings->getNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); - settings->getNoiseParams("mgv7_np_terrain_persist", np_terrain_persist); - settings->getNoiseParams("mgv7_np_height_select", np_height_select); - settings->getNoiseParams("mgv7_np_filler_depth", np_filler_depth); - settings->getNoiseParams("mgv7_np_mount_height", np_mount_height); - settings->getNoiseParams("mgv7_np_ridge_uwater", np_ridge_uwater); - settings->getNoiseParams("mgv7_np_mountain", np_mountain); - settings->getNoiseParams("mgv7_np_ridge", np_ridge); - settings->getNoiseParams("mgv7_np_cave1", np_cave1); - settings->getNoiseParams("mgv7_np_cave2", np_cave2); + settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7); + settings->getFloatNoEx("mgv7_cave_width", cave_width); + settings->getFloatNoEx("mgv7_float_mount_density", float_mount_density); + settings->getFloatNoEx("mgv7_float_mount_height", float_mount_height); + settings->getS16NoEx("mgv7_floatland_level", floatland_level); + settings->getS16NoEx("mgv7_shadow_limit", shadow_limit); + + settings->getNoiseParams("mgv7_np_terrain_base", np_terrain_base); + settings->getNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); + settings->getNoiseParams("mgv7_np_terrain_persist", np_terrain_persist); + settings->getNoiseParams("mgv7_np_height_select", np_height_select); + settings->getNoiseParams("mgv7_np_filler_depth", np_filler_depth); + settings->getNoiseParams("mgv7_np_mount_height", np_mount_height); + settings->getNoiseParams("mgv7_np_ridge_uwater", np_ridge_uwater); + settings->getNoiseParams("mgv7_np_floatland_base", np_floatland_base); + settings->getNoiseParams("mgv7_np_float_base_height", np_float_base_height); + settings->getNoiseParams("mgv7_np_mountain", np_mountain); + settings->getNoiseParams("mgv7_np_ridge", np_ridge); + settings->getNoiseParams("mgv7_np_cave1", np_cave1); + settings->getNoiseParams("mgv7_np_cave2", np_cave2); } void MapgenV7Params::writeParams(Settings *settings) const { - settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, U32_MAX); - settings->setFloat("mgv7_cave_width", cave_width); - - settings->setNoiseParams("mgv7_np_terrain_base", np_terrain_base); - settings->setNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); - settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist); - settings->setNoiseParams("mgv7_np_height_select", np_height_select); - settings->setNoiseParams("mgv7_np_filler_depth", np_filler_depth); - settings->setNoiseParams("mgv7_np_mount_height", np_mount_height); - settings->setNoiseParams("mgv7_np_ridge_uwater", np_ridge_uwater); - settings->setNoiseParams("mgv7_np_mountain", np_mountain); - settings->setNoiseParams("mgv7_np_ridge", np_ridge); - settings->setNoiseParams("mgv7_np_cave1", np_cave1); - settings->setNoiseParams("mgv7_np_cave2", np_cave2); + settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, U32_MAX); + settings->setFloat("mgv7_cave_width", cave_width); + settings->setFloat("mgv7_float_mount_density", float_mount_density); + settings->setFloat("mgv7_float_mount_height", float_mount_height); + settings->setS16("mgv7_floatland_level", floatland_level); + settings->setS16("mgv7_shadow_limit", shadow_limit); + + settings->setNoiseParams("mgv7_np_terrain_base", np_terrain_base); + settings->setNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); + settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist); + settings->setNoiseParams("mgv7_np_height_select", np_height_select); + settings->setNoiseParams("mgv7_np_filler_depth", np_filler_depth); + settings->setNoiseParams("mgv7_np_mount_height", np_mount_height); + settings->setNoiseParams("mgv7_np_ridge_uwater", np_ridge_uwater); + settings->setNoiseParams("mgv7_np_floatland_base", np_floatland_base); + settings->setNoiseParams("mgv7_np_float_base_height", np_float_base_height); + settings->setNoiseParams("mgv7_np_mountain", np_mountain); + settings->setNoiseParams("mgv7_np_ridge", np_ridge); + settings->setNoiseParams("mgv7_np_cave1", np_cave1); + settings->setNoiseParams("mgv7_np_cave2", np_cave2); } @@ -249,9 +276,13 @@ void MapgenV7::makeChunk(BlockMakeData *data) updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); + // Limit floatland shadow + bool propagate_shadow = !((spflags & MGV7_FLOATLANDS) && + node_min.Y <= shadow_limit && node_max.Y >= shadow_limit); + if (flags & MG_LIGHT) calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), - full_node_min, full_node_max); + full_node_min, full_node_max, propagate_shadow); //setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE, // node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF); @@ -313,6 +344,47 @@ bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y) } +bool MapgenV7::getFloatlandMountainFromMap(int idx_xyz, int idx_xz, s16 y) +{ + float density_gradient = + -pow(fabs((float)(y - floatland_level) / float_mount_height), 0.8f); + float floatn = noise_mountain->result[idx_xyz] + float_mount_density; + + return floatn + density_gradient >= 0.0f; +} + + +void MapgenV7::floatBaseExtentFromMap(s16 *float_base_min, s16 *float_base_max, int idx_xz) +{ + // '+1' to avoid a layer of stone at y = MAX_MAP_GENERATION_LIMIT + s16 base_min = MAX_MAP_GENERATION_LIMIT + 1; + s16 base_max = MAX_MAP_GENERATION_LIMIT; + + float n_base = noise_floatland_base->result[idx_xz]; + if (n_base > 0.0f) { + float n_base_height = + MYMAX(noise_float_base_height->result[idx_xz], 0.0f); + float amp = n_base * n_base_height; + float ridge = n_base_height / 3.0f; + base_min = floatland_level - amp / 2.0f; + + if (amp > ridge * 2.0f) { + // Lake bed + base_max = floatland_level - (amp - ridge * 2.0f) / 2.0f; + } else { + // Hills and ridges + float diff = fabs(amp - ridge) / ridge; + // Smooth ridges using the 'smoothstep function' + float smooth_diff = diff * diff * (3.0f - 2.0f * diff); + base_max = floatland_level + ridge - smooth_diff * ridge; + } + } + + *float_base_min = base_min; + *float_base_max = base_max; +} + + int MapgenV7::generateTerrain() { MapNode n_air(CONTENT_AIR); @@ -327,11 +399,19 @@ int MapgenV7::generateTerrain() noise_terrain_alt->perlinMap2D(node_min.X, node_min.Z, persistmap); noise_height_select->perlinMap2D(node_min.X, node_min.Z); - if (spflags & MGV7_MOUNTAINS) { + if ((spflags & MGV7_MOUNTAINS) || (spflags & MGV7_FLOATLANDS)) { noise_mountain->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); + } + + if (spflags & MGV7_MOUNTAINS) { noise_mount_height->perlinMap2D(node_min.X, node_min.Z); } + if (spflags & MGV7_FLOATLANDS) { + noise_floatland_base->perlinMap2D(node_min.X, node_min.Z); + noise_float_base_height->perlinMap2D(node_min.X, node_min.Z); + } + //// Place nodes v3s16 em = vm->m_area.getExtent(); s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; @@ -340,10 +420,16 @@ int MapgenV7::generateTerrain() for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { s16 surface_y = baseTerrainLevelFromMap(index2d); - if (surface_y > stone_surface_max_y) stone_surface_max_y = surface_y; + // Get extent of floatland base terrain + // '+1' to avoid a layer of stone at y = MAX_MAP_GENERATION_LIMIT + s16 float_base_min = MAX_MAP_GENERATION_LIMIT + 1; + s16 float_base_max = MAX_MAP_GENERATION_LIMIT; + if (spflags & MGV7_FLOATLANDS) + floatBaseExtentFromMap(&float_base_min, &float_base_max, index2d); + u32 vi = vm->m_area.index(x, node_min.Y - 1, z); u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X); @@ -356,8 +442,16 @@ int MapgenV7::generateTerrain() vm->m_data[vi] = n_stone; // Mountain terrain if (y > stone_surface_max_y) stone_surface_max_y = y; + } else if ((spflags & MGV7_FLOATLANDS) && + ((y >= float_base_min && y <= float_base_max) || + getFloatlandMountainFromMap(index3d, index2d, y))) { + vm->m_data[vi] = n_stone; // Floatland terrain + stone_surface_max_y = node_max.Y; } else if (y <= water_level) { - vm->m_data[vi] = n_water; + vm->m_data[vi] = n_water; // Ground level water + } else if ((spflags & MGV7_FLOATLANDS) && + (y >= float_base_max && y <= floatland_level)) { + vm->m_data[vi] = n_water; // Floatland water } else { vm->m_data[vi] = n_air; } @@ -373,7 +467,7 @@ int MapgenV7::generateTerrain() void MapgenV7::generateRidgeTerrain() { - if (node_max.Y < water_level - 16) + if ((node_max.Y < water_level - 16) || (node_max.Y > shadow_limit)) return; noise_ridge->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index 3a6bc0801..3972387a7 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -23,9 +23,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen.h" -/////////////////// Mapgen V7 flags -#define MGV7_MOUNTAINS 0x01 -#define MGV7_RIDGES 0x02 +////////////// Mapgen V7 flags +#define MGV7_MOUNTAINS 0x01 +#define MGV7_RIDGES 0x02 +#define MGV7_FLOATLANDS 0x04 class BiomeManager; @@ -35,6 +36,11 @@ extern FlagDesc flagdesc_mapgen_v7[]; struct MapgenV7Params : public MapgenParams { u32 spflags; float cave_width; + float float_mount_density; + float float_mount_height; + s16 floatland_level; + s16 shadow_limit; + NoiseParams np_terrain_base; NoiseParams np_terrain_alt; NoiseParams np_terrain_persist; @@ -42,6 +48,8 @@ struct MapgenV7Params : public MapgenParams { NoiseParams np_filler_depth; NoiseParams np_mount_height; NoiseParams np_ridge_uwater; + NoiseParams np_floatland_base; + NoiseParams np_float_base_height; NoiseParams np_mountain; NoiseParams np_ridge; NoiseParams np_cave1; @@ -68,16 +76,26 @@ public: float baseTerrainLevelFromMap(int index); bool getMountainTerrainAtPoint(s16 x, s16 y, s16 z); bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y); + bool getFloatlandMountainFromMap(int idx_xyz, int idx_xz, s16 y); + void floatBaseExtentFromMap(s16 *float_base_min, s16 *float_base_max, int idx_xz); + int generateTerrain(); void generateRidgeTerrain(); private: + float float_mount_density; + float float_mount_height; + s16 floatland_level; + s16 shadow_limit; + Noise *noise_terrain_base; Noise *noise_terrain_alt; Noise *noise_terrain_persist; Noise *noise_height_select; Noise *noise_mount_height; Noise *noise_ridge_uwater; + Noise *noise_floatland_base; + Noise *noise_float_base_height; Noise *noise_mountain; Noise *noise_ridge; }; -- cgit v1.2.3