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.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index b3c9380a0..e269bf454 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -76,10 +76,9 @@ Mapgen::Mapgen() vm = NULL; ndef = NULL; - heightmap = NULL; + biomegen = NULL; biomemap = NULL; - heatmap = NULL; - humidmap = NULL; + heightmap = NULL; } @@ -94,11 +93,10 @@ Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) : csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE); vm = NULL; - ndef = NULL; - heightmap = NULL; + ndef = emerge->ndef; + biomegen = NULL; biomemap = NULL; - heatmap = NULL; - humidmap = NULL; + heightmap = NULL; } @@ -444,6 +442,14 @@ void GenerateNotifier::getEvents( //// MapgenParams //// + +MapgenParams::~MapgenParams() +{ + delete bparams; + delete sparams; +} + + void MapgenParams::load(const Settings &settings) { std::string seed_str; @@ -458,10 +464,13 @@ void MapgenParams::load(const Settings &settings) settings.getS16NoEx("water_level", water_level); settings.getS16NoEx("chunksize", chunksize); settings.getFlagStrNoEx("mg_flags", flags, flagdesc_mapgen); - settings.getNoiseParams("mg_biome_np_heat", np_biome_heat); - settings.getNoiseParams("mg_biome_np_heat_blend", np_biome_heat_blend); - settings.getNoiseParams("mg_biome_np_humidity", np_biome_humidity); - settings.getNoiseParams("mg_biome_np_humidity_blend", np_biome_humidity_blend); + + delete bparams; + bparams = BiomeManager::createBiomeParams(BIOMEGEN_ORIGINAL); + if (bparams) { + bparams->readParams(&settings); + bparams->seed = seed; + } delete sparams; MapgenFactory *mgfactory = EmergeManager::getMapgenFactory(mg_name); @@ -479,10 +488,9 @@ void MapgenParams::save(Settings &settings) const settings.setS16("water_level", water_level); settings.setS16("chunksize", chunksize); settings.setFlagStr("mg_flags", flags, flagdesc_mapgen, U32_MAX); - settings.setNoiseParams("mg_biome_np_heat", np_biome_heat); - settings.setNoiseParams("mg_biome_np_heat_blend", np_biome_heat_blend); - settings.setNoiseParams("mg_biome_np_humidity", np_biome_humidity); - settings.setNoiseParams("mg_biome_np_humidity_blend", np_biome_humidity_blend); + + if (bparams) + bparams->writeParams(&settings); if (sparams) sparams->writeParams(&settings); -- 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.cpp') 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 9b5c492be57945c2df63e84ce8dbf057f45b2754 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Mon, 2 May 2016 02:45:59 -0400 Subject: Fix MgStoneType and BiomeType enum names --- src/mapgen.cpp | 6 +++--- src/mapgen.h | 6 +++--- src/mapgen_flat.cpp | 6 +++--- src/mapgen_fractal.cpp | 6 +++--- src/mapgen_v5.cpp | 6 +++--- src/mapgen_v7.cpp | 6 +++--- src/mapgen_valleys.cpp | 6 +++--- src/mg_biome.h | 14 +++++++------- src/script/lua_api/l_mapgen.cpp | 12 ++++++------ 9 files changed, 34 insertions(+), 34 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index f491ed9eb..01593718b 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -384,7 +384,7 @@ MgStoneType MapgenBasic::generateBiomes() { v3s16 em = vm->m_area.getExtent(); u32 index = 0; - MgStoneType stone_type = STONE; + MgStoneType stone_type = MGSTONE_STONE; for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, index++) { @@ -429,9 +429,9 @@ MgStoneType MapgenBasic::generateBiomes() // 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; + stone_type = MGSTONE_DESERT_STONE; else if (biome->c_stone == c_sandstone) - stone_type = SANDSTONE; + stone_type = MGSTONE_SANDSTONE; } if (c == c_stone) { diff --git a/src/mapgen.h b/src/mapgen.h index bee8e786a..3ec148296 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -76,9 +76,9 @@ enum GenNotifyType { // TODO(hmmmm/paramat): make stone type selection dynamic enum MgStoneType { - STONE, - DESERT_STONE, - SANDSTONE, + MGSTONE_STONE, + MGSTONE_DESERT_STONE, + MGSTONE_SANDSTONE, }; struct GenNotifyEvent { diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index 97f1c4b2a..2cbf9ace0 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -257,7 +257,7 @@ void MapgenFlat::makeChunk(BlockMakeData *data) dp.np_density = nparams_dungeon_density; dp.np_wetness = nparams_dungeon_wetness; dp.c_water = c_water_source; - if (stone_type == STONE) { + if (stone_type == MGSTONE_STONE) { dp.c_cobble = c_cobble; dp.c_moss = c_mossycobble; dp.c_stair = c_stair_cobble; @@ -267,7 +267,7 @@ void MapgenFlat::makeChunk(BlockMakeData *data) dp.holesize = v3s16(1, 2, 1); dp.roomsize = v3s16(0, 0, 0); dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == DESERT_STONE) { + } 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; @@ -277,7 +277,7 @@ void MapgenFlat::makeChunk(BlockMakeData *data) dp.holesize = v3s16(2, 3, 2); dp.roomsize = v3s16(2, 5, 2); dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == SANDSTONE) { + } else if (stone_type == MGSTONE_SANDSTONE) { dp.c_cobble = c_sandstonebrick; dp.c_moss = c_sandstonebrick; dp.c_stair = c_sandstonebrick; diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 81e162072..3217d52e2 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -273,7 +273,7 @@ void MapgenFractal::makeChunk(BlockMakeData *data) dp.np_density = nparams_dungeon_density; dp.np_wetness = nparams_dungeon_wetness; dp.c_water = c_water_source; - if (stone_type == STONE) { + if (stone_type == MGSTONE_STONE) { dp.c_cobble = c_cobble; dp.c_moss = c_mossycobble; dp.c_stair = c_stair_cobble; @@ -283,7 +283,7 @@ void MapgenFractal::makeChunk(BlockMakeData *data) dp.holesize = v3s16(1, 2, 1); dp.roomsize = v3s16(0, 0, 0); dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == DESERT_STONE) { + } 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; @@ -293,7 +293,7 @@ void MapgenFractal::makeChunk(BlockMakeData *data) dp.holesize = v3s16(2, 3, 2); dp.roomsize = v3s16(2, 5, 2); dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == SANDSTONE) { + } else if (stone_type == MGSTONE_SANDSTONE) { dp.c_cobble = c_sandstonebrick; dp.c_moss = c_sandstonebrick; dp.c_stair = c_sandstonebrick; diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 7698af825..6c1441bc2 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -255,7 +255,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) dp.np_density = nparams_dungeon_density; dp.np_wetness = nparams_dungeon_wetness; dp.c_water = c_water_source; - if (stone_type == STONE) { + if (stone_type == MGSTONE_STONE) { dp.c_cobble = c_cobble; dp.c_moss = c_mossycobble; dp.c_stair = c_stair_cobble; @@ -265,7 +265,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) dp.holesize = v3s16(1, 2, 1); dp.roomsize = v3s16(0, 0, 0); dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == DESERT_STONE) { + } 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; @@ -275,7 +275,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) dp.holesize = v3s16(2, 3, 2); dp.roomsize = v3s16(2, 5, 2); dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == SANDSTONE) { + } else if (stone_type == MGSTONE_SANDSTONE) { dp.c_cobble = c_sandstonebrick; dp.c_moss = c_sandstonebrick; dp.c_stair = c_sandstonebrick; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index ee609bc95..e6801a24b 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -285,7 +285,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) dp.np_density = nparams_dungeon_density; dp.np_wetness = nparams_dungeon_wetness; dp.c_water = c_water_source; - if (stone_type == STONE) { + if (stone_type == MGSTONE_STONE) { dp.c_cobble = c_cobble; dp.c_moss = c_mossycobble; dp.c_stair = c_stair_cobble; @@ -295,7 +295,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) dp.holesize = v3s16(1, 2, 1); dp.roomsize = v3s16(0, 0, 0); dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == DESERT_STONE) { + } 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; @@ -305,7 +305,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) dp.holesize = v3s16(2, 3, 2); dp.roomsize = v3s16(2, 5, 2); dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == SANDSTONE) { + } else if (stone_type == MGSTONE_SANDSTONE) { dp.c_cobble = c_sandstonebrick; dp.c_moss = c_sandstonebrick; dp.c_stair = c_sandstonebrick; diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index fa790677a..d424ca068 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -312,7 +312,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) dp.np_density = nparams_dungeon_density; dp.np_wetness = nparams_dungeon_wetness; dp.c_water = c_water_source; - if (stone_type == STONE) { + if (stone_type == MGSTONE_STONE) { dp.c_cobble = c_cobble; dp.c_moss = c_mossycobble; dp.c_stair = c_stair_cobble; @@ -322,7 +322,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) dp.holesize = v3s16(1, 2, 1); dp.roomsize = v3s16(0, 0, 0); dp.notifytype = GENNOTIFY_DUNGEON; - } else if (stone_type == DESERT_STONE) { + } 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; @@ -332,7 +332,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) dp.holesize = v3s16(2, 3, 2); dp.roomsize = v3s16(2, 5, 2); dp.notifytype = GENNOTIFY_TEMPLE; - } else if (stone_type == SANDSTONE) { + } else if (stone_type == MGSTONE_SANDSTONE) { dp.c_cobble = c_sandstonebrick; dp.c_moss = c_sandstonebrick; dp.c_stair = c_sandstonebrick; diff --git a/src/mg_biome.h b/src/mg_biome.h index e9378fd79..e78e90e5f 100644 --- a/src/mg_biome.h +++ b/src/mg_biome.h @@ -33,13 +33,13 @@ class BiomeManager; #define BIOME_NONE ((u8)0) -enum BiomeType -{ - BIOME_NORMAL, - BIOME_LIQUID, - BIOME_NETHER, - BIOME_AETHER, - BIOME_FLAT +// TODO(hmmmm): Decide whether this is obsolete or will be used in the future +enum BiomeType { + BIOMETYPE_NORMAL, + BIOMETYPE_LIQUID, + BIOMETYPE_NETHER, + BIOMETYPE_AETHER, + BIOMETYPE_FLAT, }; class Biome : public ObjDef, public NodeResolver { diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 405b93b86..6baf217af 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -39,11 +39,11 @@ with this program; if not, write to the Free Software Foundation, Inc., struct EnumString ModApiMapgen::es_BiomeTerrainType[] = { - {BIOME_NORMAL, "normal"}, - {BIOME_LIQUID, "liquid"}, - {BIOME_NETHER, "nether"}, - {BIOME_AETHER, "aether"}, - {BIOME_FLAT, "flat"}, + {BIOMETYPE_NORMAL, "normal"}, + {BIOMETYPE_LIQUID, "liquid"}, + {BIOMETYPE_NETHER, "nether"}, + {BIOMETYPE_AETHER, "aether"}, + {BIOMETYPE_FLAT, "flat"}, {0, NULL}, }; @@ -371,7 +371,7 @@ Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) return NULL; BiomeType biometype = (BiomeType)getenumfield(L, index, "type", - ModApiMapgen::es_BiomeTerrainType, BIOME_NORMAL); + ModApiMapgen::es_BiomeTerrainType, BIOMETYPE_NORMAL); Biome *b = BiomeManager::create(biometype); b->name = getstringfield_default(L, index, "name", ""); -- cgit v1.2.3 From 1bb5eb1da2c2e34c4413c01b45c63f6a67b214a2 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Tue, 10 May 2016 00:01:37 -0400 Subject: Cavegen: Merge CaveV5 and CaveV7 into CavesRandomWalk --- src/cavegen.cpp | 270 +++---------------------------------------------- src/cavegen.h | 57 +---------- src/mapgen.cpp | 2 +- src/mapgen_valleys.cpp | 2 +- 4 files changed, 20 insertions(+), 311 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/cavegen.cpp b/src/cavegen.cpp index b8abfbca5..59274101e 100644 --- a/src/cavegen.cpp +++ b/src/cavegen.cpp @@ -31,7 +31,7 @@ NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0 ///////////////////////////////////////// Caves V5 -CaveV5::CaveV5(Mapgen *mg, PseudoRandom *ps) +CavesRandomWalk::CavesRandomWalk(Mapgen *mg, PseudoRandom *ps) { this->mg = mg; this->vm = mg->vm; @@ -43,7 +43,8 @@ CaveV5::CaveV5(Mapgen *mg, PseudoRandom *ps) c_ice = ndef->getId("mapgen_ice"); this->np_caveliquids = &nparams_caveliquids; this->ystride = mg->csize.X; - + this->lava_depth = DEFAULT_LAVA_DEPTH; + if (c_ice == CONTENT_IGNORE) c_ice = CONTENT_AIR; @@ -59,7 +60,7 @@ CaveV5::CaveV5(Mapgen *mg, PseudoRandom *ps) } -void CaveV5::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) +void CavesRandomWalk::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) { node_min = nmin; node_max = nmax; @@ -84,12 +85,12 @@ void CaveV5::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) // Limit maximum to area route_y_max = rangelim(route_y_max, 0, ar.Y - 1); - s16 min = 0; - if (node_min.Y < water_level && node_max.Y > water_level) { - min = water_level - max_tunnel_diameter/3 - of.Y; - route_y_max = water_level + max_tunnel_diameter/3 - of.Y; - } - route_y_min = ps->range(min, min + max_tunnel_diameter); + s16 minpos = 0; + if (node_min.Y < water_level && node_max.Y > water_level) { + minpos = water_level - max_tunnel_diameter / 3 - of.Y; + route_y_max = water_level + max_tunnel_diameter / 3 - of.Y; + } + route_y_min = ps->range(minpos, minpos + max_tunnel_diameter); route_y_min = rangelim(route_y_min, 0, route_y_max); s16 route_start_y_min = route_y_min; @@ -121,7 +122,7 @@ void CaveV5::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) } -void CaveV5::makeTunnel(bool dirswitch) +void CavesRandomWalk::makeTunnel(bool dirswitch) { // Randomize size s16 min_d = min_tunnel_diameter; @@ -207,7 +208,7 @@ void CaveV5::makeTunnel(bool dirswitch) } -void CaveV5::carveRoute(v3f vec, float f, bool randomize_xz) +void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz) { MapNode airnode(CONTENT_AIR); MapNode waternode(c_water_source); @@ -218,7 +219,7 @@ void CaveV5::carveRoute(v3f vec, float f, bool randomize_xz) float nval = NoisePerlin3D(np_caveliquids, startp.X, startp.Y, startp.Z, mg->seed); - MapNode liquidnode = (nval < 0.40 && node_max.Y < MGV5_LAVA_DEPTH) ? + MapNode liquidnode = (nval < 0.40 && node_max.Y < lava_depth) ? lavanode : waternode; v3f fp = orp + vec * f; @@ -567,248 +568,3 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz, bool tunnel_above_g } } } - - -///////////////////////////////////////// Caves V7 - - -CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps) -{ - this->mg = mg; - this->vm = mg->vm; - this->ndef = mg->ndef; - this->water_level = mg->water_level; - this->ps = ps; - this->c_water_source = mg->c_water_source; - this->c_lava_source = mg->c_lava_source; - this->c_ice = mg->c_ice; - this->np_caveliquids = &nparams_caveliquids; - - dswitchint = ps->range(1, 14); - flooded = ps->range(1, 2) == 2; - - part_max_length_rs = ps->range(2, 4); - tunnel_routepoints = ps->range(5, ps->range(15, 30)); - min_tunnel_diameter = 5; - max_tunnel_diameter = ps->range(7, ps->range(8, 24)); - - large_cave_is_flat = (ps->range(0, 1) == 0); -} - - -void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) -{ - node_min = nmin; - node_max = nmax; - max_stone_y = max_stone_height; - main_direction = v3f(0, 0, 0); - - // Allowed route area size in nodes - ar = node_max - node_min + v3s16(1, 1, 1); - // Area starting point in nodes - of = node_min; - - // Allow a bit more - //(this should be more than the maximum radius of the tunnel) - s16 insure = 10; - s16 more = MYMAX(MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1); - ar += v3s16(1,0,1) * more * 2; - of -= v3s16(1,0,1) * more; - - route_y_min = 0; - // Allow half a diameter + 7 over stone surface - route_y_max = -of.Y + max_stone_y + max_tunnel_diameter / 2 + 7; - - // Limit maximum to area - route_y_max = rangelim(route_y_max, 0, ar.Y - 1); - - s16 min = 0; - if (node_min.Y < water_level && node_max.Y > water_level) { - min = water_level - max_tunnel_diameter/3 - of.Y; - route_y_max = water_level + max_tunnel_diameter/3 - of.Y; - } - route_y_min = ps->range(min, min + max_tunnel_diameter); - route_y_min = rangelim(route_y_min, 0, route_y_max); - - s16 route_start_y_min = route_y_min; - s16 route_start_y_max = route_y_max; - - route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1); - route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1); - - // Randomize starting position - orp = v3f( - (float)(ps->next() % ar.X) + 0.5, - (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5, - (float)(ps->next() % ar.Z) + 0.5 - ); - - // Add generation notify begin event - v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN; - mg->gennotify.addEvent(notifytype, abs_pos); - - // Generate some tunnel starting from orp - for (u16 j = 0; j < tunnel_routepoints; j++) - makeTunnel(j % dswitchint == 0); - - // Add generation notify end event - abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - notifytype = GENNOTIFY_LARGECAVE_END; - mg->gennotify.addEvent(notifytype, abs_pos); -} - - -void CaveV7::makeTunnel(bool dirswitch) -{ - // Randomize size - s16 min_d = min_tunnel_diameter; - s16 max_d = max_tunnel_diameter; - rs = ps->range(min_d, max_d); - s16 rs_part_max_length_rs = rs * part_max_length_rs; - - v3s16 maxlen; - maxlen = v3s16( - rs_part_max_length_rs, - rs_part_max_length_rs / 2, - rs_part_max_length_rs - ); - - v3f vec; - // Jump downward sometimes - vec = v3f( - (float)(ps->next() % maxlen.X) - (float)maxlen.X / 2, - (float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2, - (float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2 - ); - - // Do not make caves that are above ground. - // It is only necessary to check the startpoint and endpoint. - v3s16 orpi(orp.X, orp.Y, orp.Z); - v3s16 veci(vec.X, vec.Y, vec.Z); - v3s16 p; - - p = orpi + veci + of + rs / 2; - if (p.Z >= node_min.Z && p.Z <= node_max.Z && - p.X >= node_min.X && p.X <= node_max.X) { - u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X); - s16 h = mg->ridge_heightmap[index]; - if (h < p.Y) - return; - } else if (p.Y > water_level) { - return; // If it's not in our heightmap, use a simple heuristic - } - - p = orpi + of + rs / 2; - if (p.Z >= node_min.Z && p.Z <= node_max.Z && - p.X >= node_min.X && p.X <= node_max.X) { - u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X); - s16 h = mg->ridge_heightmap[index]; - if (h < p.Y) - return; - } else if (p.Y > water_level) { - return; - } - - vec += main_direction; - - v3f rp = orp + vec; - if (rp.X < 0) - rp.X = 0; - else if (rp.X >= ar.X) - rp.X = ar.X - 1; - - if (rp.Y < route_y_min) - rp.Y = route_y_min; - else if (rp.Y >= route_y_max) - rp.Y = route_y_max - 1; - - if (rp.Z < 0) - rp.Z = 0; - else if (rp.Z >= ar.Z) - rp.Z = ar.Z - 1; - - vec = rp - orp; - - float veclen = vec.getLength(); - if (veclen < 0.05) - veclen = 1.0; - - // Every second section is rough - bool randomize_xz = (ps->range(1, 2) == 1); - - // Carve routes - for (float f = 0; f < 1.0; f += 1.0 / veclen) - carveRoute(vec, f, randomize_xz); - - orp = rp; -} - - -void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz) -{ - MapNode airnode(CONTENT_AIR); - MapNode waternode(c_water_source); - MapNode lavanode(c_lava_source); - - v3s16 startp(orp.X, orp.Y, orp.Z); - startp += of; - - float nval = NoisePerlin3D(np_caveliquids, startp.X, - startp.Y, startp.Z, mg->seed); - MapNode liquidnode = (nval < 0.40 && node_max.Y < MGV7_LAVA_DEPTH) ? - lavanode : waternode; - - v3f fp = orp + vec * f; - fp.X += 0.1 * ps->range(-10, 10); - fp.Z += 0.1 * ps->range(-10, 10); - v3s16 cp(fp.X, fp.Y, fp.Z); - - s16 d0 = -rs/2; - s16 d1 = d0 + rs; - if (randomize_xz) { - d0 += ps->range(-1, 1); - d1 += ps->range(-1, 1); - } - - for (s16 z0 = d0; z0 <= d1; z0++) { - s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1); - for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) { - s16 maxabsxz = MYMAX(abs(x0), abs(z0)); - - s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1); - - for (s16 y0 = -si2; y0 <= si2; y0++) { - if (large_cave_is_flat) { - // Make large caves not so tall - if (rs > 7 && abs(y0) >= rs / 3) - continue; - } - - v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0); - p += of; - - if (vm->m_area.contains(p) == false) - continue; - - u32 i = vm->m_area.index(p); - content_t c = vm->m_data[i].getContent(); - if (!ndef->get(c).is_ground_content) - continue; - - int full_ymin = node_min.Y - MAP_BLOCKSIZE; - int full_ymax = node_max.Y + MAP_BLOCKSIZE; - - if (flooded && full_ymin < water_level && - full_ymax > water_level) - vm->m_data[i] = (p.Y <= water_level) ? - waternode : airnode; - else if (flooded && full_ymax < water_level) - vm->m_data[i] = (p.Y < startp.Y - 4) ? - liquidnode : airnode; - else - vm->m_data[i] = airnode; - } - } - } -} diff --git a/src/cavegen.h b/src/cavegen.h index a1124711b..c907fe294 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -21,19 +21,18 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CAVEGEN_HEADER #define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1 -#define MGV5_LAVA_DEPTH -256 -#define MGV7_LAVA_DEPTH -256 +#define DEFAULT_LAVA_DEPTH (-256) -class MapgenV5; class MapgenV6; -class MapgenV7; -class CaveV5 { +class CavesRandomWalk { public: Mapgen *mg; MMVManip *vm; INodeDefManager *ndef; + // variables + int lava_depth; NoiseParams *np_caveliquids; s16 min_tunnel_diameter; @@ -67,8 +66,7 @@ public: int water_level; int ystride; - CaveV5() {} - CaveV5(Mapgen *mg, PseudoRandom *ps); + CavesRandomWalk(Mapgen *mg, PseudoRandom *ps); void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); void makeTunnel(bool dirswitch); void carveRoute(v3f vec, float f, bool randomize_xz); @@ -118,49 +116,4 @@ public: void carveRoute(v3f vec, float f, bool randomize_xz, bool tunnel_above_ground); }; -class CaveV7 { -public: - MapgenV7 *mg; - MMVManip *vm; - INodeDefManager *ndef; - - NoiseParams *np_caveliquids; - - s16 min_tunnel_diameter; - s16 max_tunnel_diameter; - u16 tunnel_routepoints; - int dswitchint; - int part_max_length_rs; - - bool large_cave_is_flat; - bool flooded; - - s16 max_stone_y; - v3s16 node_min; - v3s16 node_max; - - v3f orp; // starting point, relative to caved space - v3s16 of; // absolute coordinates of caved space - v3s16 ar; // allowed route area - s16 rs; // tunnel radius size - v3f main_direction; - - s16 route_y_min; - s16 route_y_max; - - PseudoRandom *ps; - - content_t c_water_source; - content_t c_lava_source; - content_t c_ice; - - int water_level; - - CaveV7() {} - CaveV7(MapgenV7 *mg, PseudoRandom *ps); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); - void makeTunnel(bool dirswitch); - void carveRoute(v3f vec, float f, bool randomize_xz); -}; - #endif diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 01593718b..43ac6e51a 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -599,7 +599,7 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth) 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! + CavesRandomWalk cave(this, &ps); cave.makeCave(node_min, node_max, max_stone_y); } } diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index d424ca068..77fa1ed06 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -841,7 +841,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth) if (node_max.Y <= large_cave_depth && !made_a_big_one) { u32 bruises_count = ps.range(0, 2); for (u32 i = 0; i < bruises_count; i++) { - CaveV5 cave(this, &ps); + CavesRandomWalk cave(this, &ps); cave.makeCave(node_min, node_max, max_stone_y); } } -- cgit v1.2.3 From db1b4dc8908c83aef5560718af7466d95d86e44f Mon Sep 17 00:00:00 2001 From: kwolekr Date: Tue, 10 May 2016 22:56:03 -0400 Subject: Cavegen: Remove CavesRandomWalk dependency on Mapgen --- src/cavegen.cpp | 79 +++++++++++++++++++++++++++++++++----------------- src/cavegen.h | 45 +++++++++++++++++++++++----- src/mapgen.cpp | 6 ++-- src/mapgen_valleys.cpp | 6 ++-- 4 files changed, 98 insertions(+), 38 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/cavegen.cpp b/src/cavegen.cpp index 59878c890..25e8473bc 100644 --- a/src/cavegen.cpp +++ b/src/cavegen.cpp @@ -31,23 +31,52 @@ NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0 //// CavesRandomWalk //// -CavesRandomWalk::CavesRandomWalk(Mapgen *mg, PseudoRandom *ps) +CavesRandomWalk::CavesRandomWalk( + INodeDefManager *ndef, + GenerateNotifier *gennotify, + int seed, + int water_level, + content_t water_source, + content_t lava_source) { - this->mg = mg; - this->vm = mg->vm; - this->ndef = mg->ndef; - this->water_level = mg->water_level; - this->ps = ps; - c_water_source = ndef->getId("mapgen_water_source"); - c_lava_source = ndef->getId("mapgen_lava_source"); - c_ice = ndef->getId("mapgen_ice"); + assert(ndef); + + this->ndef = ndef; + this->gennotify = gennotify; + this->seed = seed; + this->water_level = water_level; this->np_caveliquids = &nparams_caveliquids; - this->ystride = mg->csize.X; this->lava_depth = DEFAULT_LAVA_DEPTH; - if (c_ice == CONTENT_IGNORE) - c_ice = CONTENT_AIR; + c_water_source = water_source; + if (c_water_source == CONTENT_IGNORE) + c_water_source = ndef->getId("mapgen_water_source"); + if (c_water_source == CONTENT_IGNORE) + c_water_source = CONTENT_AIR; + c_lava_source = lava_source; + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = ndef->getId("mapgen_lava_source"); + if (c_lava_source == CONTENT_IGNORE) + c_lava_source = CONTENT_AIR; +} + + +void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, + PseudoRandom *ps, int max_stone_height, s16 *heightmap) +{ + assert(vm); + assert(ps); + + this->vm = vm; + this->ps = ps; + this->node_min = nmin; + this->node_max = nmax; + this->heightmap = heightmap; + + this->ystride = nmax.X - nmin.X + 1; + + // Set initial parameters from randomness dswitchint = ps->range(1, 14); flooded = ps->range(1, 2) == 2; @@ -57,13 +86,7 @@ CavesRandomWalk::CavesRandomWalk(Mapgen *mg, PseudoRandom *ps) max_tunnel_diameter = ps->range(7, ps->range(8, 24)); large_cave_is_flat = (ps->range(0, 1) == 0); -} - -void CavesRandomWalk::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) -{ - node_min = nmin; - node_max = nmax; main_direction = v3f(0, 0, 0); // Allowed route area size in nodes @@ -107,18 +130,22 @@ void CavesRandomWalk::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) ); // Add generation notify begin event - v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN; - mg->gennotify.addEvent(notifytype, abs_pos); + if (gennotify) { + v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); + GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN; + gennotify->addEvent(notifytype, abs_pos); + } // Generate some tunnel starting from orp for (u16 j = 0; j < tunnel_routepoints; j++) makeTunnel(j % dswitchint == 0); // Add generation notify end event - abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - notifytype = GENNOTIFY_LARGECAVE_END; - mg->gennotify.addEvent(notifytype, abs_pos); + if (gennotify) { + v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); + GenNotifyType notifytype = GENNOTIFY_LARGECAVE_END; + gennotify->addEvent(notifytype, abs_pos); + } } @@ -197,7 +224,7 @@ void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz) startp += of; float nval = NoisePerlin3D(np_caveliquids, startp.X, - startp.Y, startp.Z, mg->seed); + startp.Y, startp.Z, seed); MapNode liquidnode = (nval < 0.40 && node_max.Y < lava_depth) ? lavanode : waternode; @@ -388,7 +415,7 @@ void CavesV6::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, // Add generation notify end event if (gennotify != NULL) { - v3s16 abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); + v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); GenNotifyType notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END; gennotify->addEvent(notifytype, abs_pos); diff --git a/src/cavegen.h b/src/cavegen.h index 5a41966fe..2db5e9d4f 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -25,17 +25,35 @@ with this program; if not, write to the Free Software Foundation, Inc., class GenerateNotifier; +/* + CavesRandomWalk is an implementation of a cave-digging algorithm that + operates on the principle of a "random walk" to approximate the stochiastic + activity of cavern development. + + In summary, this algorithm works by carving a randomly sized tunnel in a + random direction a random amount of times, randomly varying in width. + All randomness here is uniformly distributed; alternative distributions have + not yet been implemented. + + This algorithm is very fast, executing in less than 1ms on average for an + 80x80x80 chunk of map on a modern processor. +*/ class CavesRandomWalk { public: - Mapgen *mg; MMVManip *vm; INodeDefManager *ndef; + GenerateNotifier *gennotify; s16 *heightmap; - // variables + // configurable parameters + int seed; + int water_level; int lava_depth; NoiseParams *np_caveliquids; + // intermediate state variables + u16 ystride; + s16 min_tunnel_diameter; s16 max_tunnel_diameter; u16 tunnel_routepoints; @@ -62,17 +80,26 @@ public: content_t c_water_source; content_t c_lava_source; - content_t c_ice; - int water_level; - u16 ystride; + // ndef is a mandatory parameter. + // If gennotify is NULL, generation events are not logged. + CavesRandomWalk(INodeDefManager *ndef, + GenerateNotifier *gennotify = NULL, + int seed = 0, + int water_level = 1, + content_t water_source = CONTENT_IGNORE, + content_t lava_source = CONTENT_IGNORE); - CavesRandomWalk(Mapgen *mg, PseudoRandom *ps); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); + // vm and ps are mandatory parameters. + // If heightmap is NULL, the surface level at all points is assumed to + // be water_level. + void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, + PseudoRandom *ps, int max_stone_height, s16 *heightmap); + +private: void makeTunnel(bool dirswitch); void carveRoute(v3f vec, float f, bool randomize_xz); -private: inline bool isPosAboveSurface(v3s16 p); }; @@ -97,11 +124,13 @@ public: PseudoRandom *ps; PseudoRandom *ps2; + // configurable parameters s16 *heightmap; content_t c_water_source; content_t c_lava_source; int water_level; + // intermediate state variables u16 ystride; s16 min_tunnel_diameter; diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 43ac6e51a..7e74ad642 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -599,8 +599,10 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth) PseudoRandom ps(blockseed + 21343); u32 bruises_count = ps.range(0, 2); for (u32 i = 0; i < bruises_count; i++) { - CavesRandomWalk cave(this, &ps); - cave.makeCave(node_min, node_max, max_stone_y); + CavesRandomWalk cave(ndef, &gennotify, seed, water_level, + c_water_source, CONTENT_IGNORE); + + cave.makeCave(vm, node_min, node_max, &ps, max_stone_y, heightmap); } } diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 77fa1ed06..af7a8b153 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -841,8 +841,10 @@ void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth) if (node_max.Y <= large_cave_depth && !made_a_big_one) { u32 bruises_count = ps.range(0, 2); for (u32 i = 0; i < bruises_count; i++) { - CavesRandomWalk cave(this, &ps); - cave.makeCave(node_min, node_max, max_stone_y); + CavesRandomWalk cave(ndef, &gennotify, seed, water_level, + c_water_source, c_lava_source); + + cave.makeCave(vm, node_min, node_max, &ps, max_stone_y, heightmap); } } } -- cgit v1.2.3 From 5b05f75a272ede582d7f86d8dbbbf7bc81e81970 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Wed, 11 May 2016 00:00:05 -0400 Subject: Cavegen: Re-add small caves to CavesRandomWalk --- src/cavegen.cpp | 121 +++++++++++++++++++++++++++++++++++-------------- src/cavegen.h | 5 +- src/mapgen.cpp | 2 +- src/mapgen_valleys.cpp | 2 +- 4 files changed, 91 insertions(+), 39 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/cavegen.cpp b/src/cavegen.cpp index 25e8473bc..1beac6f27 100644 --- a/src/cavegen.cpp +++ b/src/cavegen.cpp @@ -63,16 +63,17 @@ CavesRandomWalk::CavesRandomWalk( void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, - PseudoRandom *ps, int max_stone_height, s16 *heightmap) + PseudoRandom *ps, bool is_large_cave, int max_stone_height, s16 *heightmap) { assert(vm); assert(ps); - this->vm = vm; - this->ps = ps; - this->node_min = nmin; - this->node_max = nmax; - this->heightmap = heightmap; + this->vm = vm; + this->ps = ps; + this->node_min = nmin; + this->node_max = nmax; + this->heightmap = heightmap; + this->large_cave = is_large_cave; this->ystride = nmax.X - nmin.X + 1; @@ -80,10 +81,17 @@ void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, dswitchint = ps->range(1, 14); flooded = ps->range(1, 2) == 2; - part_max_length_rs = ps->range(2, 4); - tunnel_routepoints = ps->range(5, ps->range(15, 30)); - min_tunnel_diameter = 5; - max_tunnel_diameter = ps->range(7, ps->range(8, 24)); + if (large_cave) { + part_max_length_rs = ps->range(2, 4); + tunnel_routepoints = ps->range(5, ps->range(15, 30)); + min_tunnel_diameter = 5; + max_tunnel_diameter = ps->range(7, ps->range(8, 24)); + } else { + part_max_length_rs = ps->range(2, 9); + tunnel_routepoints = ps->range(10, ps->range(15, 30)); + min_tunnel_diameter = 2; + max_tunnel_diameter = ps->range(2, 6); + } large_cave_is_flat = (ps->range(0, 1) == 0); @@ -108,13 +116,15 @@ void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, // Limit maximum to area route_y_max = rangelim(route_y_max, 0, ar.Y - 1); - s16 minpos = 0; - if (node_min.Y < water_level && node_max.Y > water_level) { - minpos = water_level - max_tunnel_diameter / 3 - of.Y; - route_y_max = water_level + max_tunnel_diameter / 3 - of.Y; + if (large_cave) { + s16 minpos = 0; + if (node_min.Y < water_level && node_max.Y > water_level) { + minpos = water_level - max_tunnel_diameter / 3 - of.Y; + route_y_max = water_level + max_tunnel_diameter / 3 - of.Y; + } + route_y_min = ps->range(minpos, minpos + max_tunnel_diameter); + route_y_min = rangelim(route_y_min, 0, route_y_max); } - route_y_min = ps->range(minpos, minpos + max_tunnel_diameter); - route_y_min = rangelim(route_y_min, 0, route_y_max); s16 route_start_y_min = route_y_min; s16 route_start_y_max = route_y_max; @@ -132,7 +142,8 @@ void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, // Add generation notify begin event if (gennotify) { v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN; + GenNotifyType notifytype = large_cave ? + GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN; gennotify->addEvent(notifytype, abs_pos); } @@ -143,7 +154,8 @@ void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, // Add generation notify end event if (gennotify) { v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - GenNotifyType notifytype = GENNOTIFY_LARGECAVE_END; + GenNotifyType notifytype = large_cave ? + GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END; gennotify->addEvent(notifytype, abs_pos); } } @@ -151,6 +163,15 @@ void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, void CavesRandomWalk::makeTunnel(bool dirswitch) { + if (dirswitch && !large_cave) { + main_direction = v3f( + ((float)(ps->next() % 20) - (float)10) / 10, + ((float)(ps->next() % 20) - (float)10) / 30, + ((float)(ps->next() % 20) - (float)10) / 10 + ); + main_direction *= (float)ps->range(0, 10) / 10; + } + // Randomize size s16 min_d = min_tunnel_diameter; s16 max_d = max_tunnel_diameter; @@ -158,19 +179,35 @@ void CavesRandomWalk::makeTunnel(bool dirswitch) s16 rs_part_max_length_rs = rs * part_max_length_rs; v3s16 maxlen; - maxlen = v3s16( - rs_part_max_length_rs, - rs_part_max_length_rs / 2, - rs_part_max_length_rs - ); + if (large_cave) { + maxlen = v3s16( + rs_part_max_length_rs, + rs_part_max_length_rs / 2, + rs_part_max_length_rs + ); + } else { + maxlen = v3s16( + rs_part_max_length_rs, + ps->range(1, rs_part_max_length_rs), + rs_part_max_length_rs + ); + } v3f vec; // Jump downward sometimes - vec = v3f( - (float)(ps->next() % maxlen.X) - (float)maxlen.X / 2, - (float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2, - (float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2 - ); + if (!large_cave && ps->range(0, 12) == 0) { + vec = v3f( + (float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2, + (float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y, + (float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2 + ); + } else { + vec = v3f( + (float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2, + (float)(ps->next() % (maxlen.Y * 1)) - (float)maxlen.Y / 2, + (float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2 + ); + } // Do not make caves that are above ground. // It is only necessary to check the startpoint and endpoint. @@ -240,6 +277,8 @@ void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz) d1 += ps->range(-1, 1); } + bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2; + for (s16 z0 = d0; z0 <= d1; z0++) { s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1); for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) { @@ -248,6 +287,10 @@ void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz) s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1); for (s16 y0 = -si2; y0 <= si2; y0++) { + // Make better floors in small caves + if (flat_cave_floor && y0 <= -rs / 2 && rs <= 7) + continue; + if (large_cave_is_flat) { // Make large caves not so tall if (rs > 7 && abs(y0) >= rs / 3) @@ -265,15 +308,23 @@ void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz) if (!ndef->get(c).is_ground_content) continue; - int full_ymin = node_min.Y - MAP_BLOCKSIZE; - int full_ymax = node_max.Y + MAP_BLOCKSIZE; + if (large_cave) { + int full_ymin = node_min.Y - MAP_BLOCKSIZE; + int full_ymax = node_max.Y + MAP_BLOCKSIZE; + + if (flooded && full_ymin < water_level && full_ymax > water_level) + vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode; + else if (flooded && full_ymax < water_level) + vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode; + else + vm->m_data[i] = airnode; + } else { + if (c == CONTENT_IGNORE) + continue; - if (flooded && full_ymin < water_level && full_ymax > water_level) - vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode; - else if (flooded && full_ymax < water_level) - vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode; - else vm->m_data[i] = airnode; + vm->m_flags[i] |= VMANIP_FLAG_CAVE; + } } } } diff --git a/src/cavegen.h b/src/cavegen.h index 2db5e9d4f..e250ad452 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -60,6 +60,7 @@ public: int dswitchint; int part_max_length_rs; + bool large_cave; bool large_cave_is_flat; bool flooded; @@ -93,8 +94,8 @@ public: // vm and ps are mandatory parameters. // If heightmap is NULL, the surface level at all points is assumed to // be water_level. - void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, - PseudoRandom *ps, int max_stone_height, s16 *heightmap); + void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, PseudoRandom *ps, + bool is_large_cave, int max_stone_height, s16 *heightmap); private: void makeTunnel(bool dirswitch); diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 7e74ad642..09671d845 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -602,7 +602,7 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth) CavesRandomWalk cave(ndef, &gennotify, seed, water_level, c_water_source, CONTENT_IGNORE); - cave.makeCave(vm, node_min, node_max, &ps, max_stone_y, heightmap); + cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap); } } diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index af7a8b153..699554ecd 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -844,7 +844,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth) CavesRandomWalk cave(ndef, &gennotify, seed, water_level, c_water_source, c_lava_source); - cave.makeCave(vm, node_min, node_max, &ps, max_stone_y, heightmap); + cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, heightmap); } } } -- cgit v1.2.3 From 548d99bb456931192609e8c6fa1eb4c80679af42 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Thu, 19 May 2016 03:40:22 -0400 Subject: Cavegen: Move V5-style caves to CavesNoiseIntersection --- src/cavegen.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/cavegen.h | 37 +++++++++++++++++++ src/mapgen.cpp | 52 ++------------------------- src/mapgen.h | 5 ++- src/mapgen_flat.cpp | 10 ++---- src/mapgen_fractal.cpp | 10 ++---- src/mapgen_v5.cpp | 10 ++---- src/mapgen_v7.cpp | 10 ++---- src/mapgen_valleys.h | 3 ++ 9 files changed, 151 insertions(+), 82 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/cavegen.cpp b/src/cavegen.cpp index 5f0af9699..51309ad60 100644 --- a/src/cavegen.cpp +++ b/src/cavegen.cpp @@ -23,10 +23,106 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen_v5.h" #include "mapgen_v6.h" #include "mapgen_v7.h" +#include "mg_biome.h" #include "cavegen.h" NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0); + +//// +//// CavesNoiseIntersection +//// + +CavesNoiseIntersection::CavesNoiseIntersection( + INodeDefManager *nodedef, BiomeManager *biomemgr, v3s16 chunksize, + NoiseParams *np_cave1, NoiseParams *np_cave2, int seed, float cave_width) +{ + assert(nodedef); + assert(biomemgr); + + m_ndef = nodedef; + m_bmgr = biomemgr; + + m_csize = chunksize; + m_cave_width = cave_width; + + m_ystride = m_csize.X; + m_zstride_1d = m_csize.X * (m_csize.Y + 1); + + // Noises are created using 1-down overgeneration + // A Nx-by-1-by-Nz-sized plane is at the bottom of the desired for + // re-carving the solid overtop placed for blocking sunlight + noise_cave1 = new Noise(np_cave1, seed, m_csize.X, m_csize.Y + 1, m_csize.Z); + noise_cave2 = new Noise(np_cave2, seed, m_csize.X, m_csize.Y + 1, m_csize.Z); +} + + +CavesNoiseIntersection::~CavesNoiseIntersection() +{ + delete noise_cave1; + delete noise_cave2; +} + + +void CavesNoiseIntersection::generateCaves(MMVManip *vm, + v3s16 nmin, v3s16 nmax, u8 *biomemap) +{ + assert(vm); + assert(biomemap); + + noise_cave1->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z); + noise_cave2->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z); + + v3s16 em = vm->m_area.getExtent(); + u32 index2d = 0; + + for (s16 z = nmin.Z; z <= nmax.Z; z++) + for (s16 x = nmin.X; x <= nmax.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, nmax.Y, z); + u32 index3d = (z - nmin.Z) * m_zstride_1d + m_csize.Y * m_ystride + + (x - nmin.X); + // Biome of column + Biome *biome = (Biome *)m_bmgr->getRaw(biomemap[index2d]); + + // Don't excavate the overgenerated stone at nmax.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 = nmax.Y; y >= nmin.Y - 1; y--, + index3d -= m_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 > m_cave_width && m_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; + } + } + } +} + + //// //// CavesRandomWalk //// diff --git a/src/cavegen.h b/src/cavegen.h index 68e0c8bc5..da0894635 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -25,6 +25,43 @@ with this program; if not, write to the Free Software Foundation, Inc., class GenerateNotifier; +/* + CavesNoiseIntersection is a cave digging algorithm that carves smooth, + web-like, continuous tunnels at points where the density of the intersection + between two separate 3d noises is above a certain value. This value, + cave_width, can be modified to set the effective width of these tunnels. + + This algorithm is relatively heavyweight, taking ~80ms to generate an + 80x80x80 chunk of map on a modern processor. Use sparingly! + + TODO(hmmmm): Remove dependency on biomes + TODO(hmmmm): Find alternative to overgeneration as solution for sunlight issue +*/ +class CavesNoiseIntersection { +public: + CavesNoiseIntersection(INodeDefManager *nodedef, BiomeManager *biomemgr, + v3s16 chunksize, NoiseParams *np_cave1, NoiseParams *np_cave2, + int seed, float cave_width); + ~CavesNoiseIntersection(); + + void generateCaves(MMVManip *vm, v3s16 nmin, v3s16 nmax, u8 *biomemap); + +private: + INodeDefManager *m_ndef; + BiomeManager *m_bmgr; + + // configurable parameters + v3s16 m_csize; + float m_cave_width; + + // intermediate state variables + u16 m_ystride; + u16 m_zstride_1d; + + Noise *noise_cave1; + Noise *noise_cave2; +}; + /* CavesRandomWalk is an implementation of a cave-digging algorithm that operates on the principle of a "random walk" to approximate the stochiastic diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 09671d845..7e959533d 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -542,56 +542,10 @@ 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); + CavesNoiseIntersection caves_noise(ndef, bmgr, csize, + &np_cave1, &np_cave2, seed, cave_width); - 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; - } - } - } + caves_noise.generateCaves(vm, node_min, node_max, biomemap); if (node_max.Y > large_cave_depth) return; diff --git a/src/mapgen.h b/src/mapgen.h index 3ec148296..8db01f5c1 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -220,8 +220,6 @@ public: BiomeManager *bmgr; Noise *noise_filler_depth; - Noise *noise_cave1; - Noise *noise_cave2; v3s16 node_min; v3s16 node_max; @@ -235,7 +233,8 @@ public: content_t c_sandstone; int ystride; - int zstride_1d; + NoiseParams np_cave1; + NoiseParams np_cave2; float cave_width; MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge); diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index 2cbf9ace0..a541a54f3 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -58,8 +58,6 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge //// amount of elements to skip for the next index //// for noise/height/biome maps (not vmanip) this->ystride = csize.X; - // 1-down overgeneration - this->zstride_1d = csize.X * (csize.Y + 1); this->heightmap = new s16[csize.X * csize.Z]; @@ -78,10 +76,8 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge 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); - //// 3D noise - // 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); + MapgenBasic::np_cave1 = sp->np_cave1; + MapgenBasic::np_cave2 = sp->np_cave2; //// Initialize biome generator biomegen = emerge->biomemgr->createBiomeGen( @@ -119,8 +115,6 @@ MapgenFlat::~MapgenFlat() { delete noise_terrain; delete noise_filler_depth; - delete noise_cave1; - delete noise_cave2; delete biomegen; diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index 3217d52e2..dca10d253 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -56,8 +56,6 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * //// amount of elements to skip for the next index //// for noise/height/biome maps (not vmanip) this->ystride = csize.X; - // 1-down overgeneration - this->zstride_1d = csize.X * (csize.Y + 1); this->heightmap = new s16[csize.X * csize.Z]; @@ -79,10 +77,8 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager * 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); - //// 3D terrain noise - // 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); + MapgenBasic::np_cave1 = sp->np_cave1; + MapgenBasic::np_cave2 = sp->np_cave2; //// Initialize biome generator biomegen = emerge->biomemgr->createBiomeGen( @@ -123,8 +119,6 @@ MapgenFractal::~MapgenFractal() { delete noise_seabed; delete noise_filler_depth; - delete noise_cave1; - delete noise_cave2; delete biomegen; diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 6c1441bc2..0c063dc6f 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -54,8 +54,6 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) // amount of elements to skip for the next index // for noise/height/biome maps (not vmanip) this->ystride = csize.X; - // 1-down overgeneration - this->zstride_1d = csize.X * (csize.Y + 1); this->heightmap = new s16[csize.X * csize.Z]; @@ -72,9 +70,9 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) // 3D terrain noise // 1-up 1-down overgeneration noise_ground = new Noise(&sp->np_ground, 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); + + MapgenBasic::np_cave1 = sp->np_cave1; + MapgenBasic::np_cave2 = sp->np_cave2; //// Initialize biome generator biomegen = emerge->biomemgr->createBiomeGen( @@ -113,8 +111,6 @@ MapgenV5::~MapgenV5() delete noise_filler_depth; delete noise_factor; delete noise_height; - delete noise_cave1; - delete noise_cave2; delete noise_ground; delete biomegen; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index e6801a24b..e297a1d3e 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -61,8 +61,6 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) this->ystride = csize.X; // 1-up 1-down overgeneration this->zstride_1u1d = csize.X * (csize.Y + 2); - // 1-down overgeneration - this->zstride_1d = csize.X * (csize.Y + 1); this->heightmap = new s16[csize.X * csize.Z]; this->ridge_heightmap = new s16[csize.X * csize.Z]; @@ -85,9 +83,9 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) // 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); - // 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); + + 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 @@ -133,8 +131,6 @@ MapgenV7::~MapgenV7() delete noise_ridge_uwater; delete noise_mountain; delete noise_ridge; - delete noise_cave1; - delete noise_cave2; delete biomegen; diff --git a/src/mapgen_valleys.h b/src/mapgen_valleys.h index 2ab253430..4f87be6b6 100644 --- a/src/mapgen_valleys.h +++ b/src/mapgen_valleys.h @@ -100,6 +100,7 @@ private: BiomeGenOriginal *m_bgen; int zstride; + int zstride_1d; float map_gen_limit; @@ -120,6 +121,8 @@ private: Noise *noise_inter_valley_fill; Noise *noise_inter_valley_slope; Noise *noise_rivers; + Noise *noise_cave1; + Noise *noise_cave2; Noise *noise_massive_caves; Noise *noise_terrain_height; Noise *noise_valley_depth; -- 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.cpp') 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.cpp') 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.cpp') 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 c8fd232678698b8be469b3792e7acc9418231a38 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 22 May 2016 16:50:43 -0400 Subject: Dungeongen: Remove dependency on Mapgen --- src/dungeongen.cpp | 37 +++++++++++++++++++++++-------------- src/dungeongen.h | 19 +++++++++++++------ src/mapgen.cpp | 7 +++++-- src/mapgen_v6.cpp | 6 ++++-- 4 files changed, 45 insertions(+), 24 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/dungeongen.cpp b/src/dungeongen.cpp index f7f9b8b50..6be7e9086 100644 --- a/src/dungeongen.cpp +++ b/src/dungeongen.cpp @@ -38,22 +38,27 @@ NoiseParams nparams_dungeon_density(0.0, 1.0, v3f(2.5, 2.5, 2.5), 0, 2, 1.4, 2.0 /////////////////////////////////////////////////////////////////////////////// -DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams) +DungeonGen::DungeonGen(INodeDefManager *ndef, + GenerateNotifier *gennotify, DungeonParams *dparams) { - this->mg = mapgen; - this->vm = mapgen->vm; + assert(ndef); + + this->ndef = ndef; + this->gennotify = gennotify; #ifdef DGEN_USE_TORCHES - c_torch = mg->ndef->getId("default:torch"); + c_torch = ndef->getId("default:torch"); #endif if (dparams) { memcpy(&dp, dparams, sizeof(dp)); } else { - dp.c_water = mg->ndef->getId("mapgen_water_source"); - dp.c_cobble = mg->ndef->getId("mapgen_cobble"); - dp.c_moss = mg->ndef->getId("mapgen_mossycobble"); - dp.c_stair = mg->ndef->getId("mapgen_stair_cobble"); + dp.seed = 0; + + dp.c_water = ndef->getId("mapgen_water_source"); + dp.c_cobble = ndef->getId("mapgen_cobble"); + dp.c_moss = ndef->getId("mapgen_mossycobble"); + dp.c_stair = ndef->getId("mapgen_stair_cobble"); dp.diagonal_dirs = false; dp.mossratio = 3.0; @@ -67,18 +72,21 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams) } // For mapgens using river water - dp.c_river_water = mg->ndef->getId("mapgen_river_water_source"); + dp.c_river_water = ndef->getId("mapgen_river_water_source"); if (dp.c_river_water == CONTENT_IGNORE) - dp.c_river_water = mg->ndef->getId("mapgen_water_source"); + dp.c_river_water = ndef->getId("mapgen_water_source"); } -void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) +void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax) { + assert(vm); + //TimeTaker t("gen dungeons"); - if (NoisePerlin3D(&dp.np_rarity, nmin.X, nmin.Y, nmin.Z, mg->seed) < 0.2) + if (NoisePerlin3D(&dp.np_rarity, nmin.X, nmin.Y, nmin.Z, dp.seed) < 0.2) return; + this->vm = vm; this->blockseed = bseed; random.seed(bseed + 2); @@ -109,7 +117,7 @@ void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) u32 i = vm->m_area.index(nmin.X, y, z); for (s16 x = nmin.X; x <= nmax.X; x++) { if (vm->m_data[i].getContent() == dp.c_cobble) { - float wetness = NoisePerlin3D(&dp.np_wetness, x, y, z, mg->seed); + float wetness = NoisePerlin3D(&dp.np_wetness, x, y, z, dp.seed); float density = NoisePerlin3D(&dp.np_density, x, y, z, blockseed); if (density < wetness / dp.mossratio) vm->m_data[i].setContent(dp.c_moss); @@ -187,7 +195,8 @@ void DungeonGen::makeDungeon(v3s16 start_padding) makeRoom(roomsize, roomplace); v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); - mg->gennotify.addEvent(dp.notifytype, room_center); + if (gennotify) + gennotify->addEvent(dp.notifytype, room_center); #ifdef DGEN_USE_TORCHES // Place torch at room center (for testing) diff --git a/src/dungeongen.h b/src/dungeongen.h index d209dd4bf..f0a5e5ba8 100644 --- a/src/dungeongen.h +++ b/src/dungeongen.h @@ -39,6 +39,8 @@ int dir_to_facedir(v3s16 d); struct DungeonParams { + int seed; + content_t c_water; content_t c_river_water; content_t c_cobble; @@ -59,7 +61,9 @@ struct DungeonParams { class DungeonGen { public: MMVManip *vm; - Mapgen *mg; + INodeDefManager *ndef; + GenerateNotifier *gennotify; + u32 blockseed; PseudoRandom random; v3s16 csize; @@ -67,17 +71,20 @@ public: content_t c_torch; DungeonParams dp; - //RoomWalker + // RoomWalker v3s16 m_pos; v3s16 m_dir; - DungeonGen(Mapgen *mg, DungeonParams *dparams); - void generate(u32 bseed, v3s16 full_node_min, v3s16 full_node_max); + DungeonGen(INodeDefManager *ndef, + GenerateNotifier *gennotify, DungeonParams *dparams); + + void generate(MMVManip *vm, u32 bseed, + v3s16 full_node_min, v3s16 full_node_max); void makeDungeon(v3s16 start_padding); void makeRoom(v3s16 roomsize, v3s16 roomplace); void makeCorridor(v3s16 doorplace, v3s16 doordir, - v3s16 &result_place, v3s16 &result_dir); + v3s16 &result_place, v3s16 &result_dir); void makeDoor(v3s16 doorplace, v3s16 doordir); void makeFill(v3s16 place, v3s16 size, u8 avoid_flags, MapNode n, u8 or_flags); void makeHole(v3s16 place); @@ -86,7 +93,7 @@ public: bool findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace, v3s16 &result_doordir, v3s16 &result_roomplace); - void randomizeDir() + inline void randomizeDir() { m_dir = rand_ortho_dir(random, dp.diagonal_dirs); } diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 56fe34e16..041356e3d 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -639,10 +639,13 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, MgStoneType stone_type) DungeonParams dp; + dp.seed = seed; + 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: @@ -680,8 +683,8 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, MgStoneType stone_type) break; } - DungeonGen dgen(this, &dp); - dgen.generate(blockseed, full_node_min, full_node_max); + DungeonGen dgen(ndef, &gennotify, &dp); + dgen.generate(vm, blockseed, full_node_min, full_node_max); } diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 65acfaf93..103120b6a 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -559,6 +559,8 @@ void MapgenV6::makeChunk(BlockMakeData *data) if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) { DungeonParams dp; + dp.seed = seed; + dp.np_rarity = nparams_dungeon_rarity; dp.np_density = nparams_dungeon_density; dp.np_wetness = nparams_dungeon_wetness; @@ -585,8 +587,8 @@ void MapgenV6::makeChunk(BlockMakeData *data) dp.notifytype = GENNOTIFY_DUNGEON; } - DungeonGen dgen(this, &dp); - dgen.generate(blockseed, full_node_min, full_node_max); + DungeonGen dgen(ndef, &gennotify, &dp); + dgen.generate(vm, blockseed, full_node_min, full_node_max); } // Add top and bottom side of water to transforming_liquid queue -- cgit v1.2.3 From dfbdb5bcd7bc48efb21d585d5c22454a9d5f0f1e Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 4 Jun 2016 01:35:37 -0400 Subject: Change internal type for seeds to s32 This fixes value truncation (and therefore incompatibility) on platforms with an LP32 data model, such as VAX or MS-DOS. --- src/cavegen.cpp | 4 ++-- src/cavegen.h | 6 +++--- src/dungeongen.h | 2 +- src/mapgen.cpp | 20 +++++++++++++++++--- src/mapgen.h | 6 +++--- src/mg_biome.h | 2 +- src/noise.cpp | 26 +++++++++++++------------- src/noise.h | 32 ++++++++++++++++---------------- src/script/lua_api/l_env.cpp | 2 +- src/script/lua_api/l_noise.cpp | 2 +- src/script/lua_api/l_noise.h | 4 ++-- src/treegen.cpp | 8 ++++---- src/treegen.h | 8 ++++---- 13 files changed, 68 insertions(+), 54 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/cavegen.cpp b/src/cavegen.cpp index 1c25ce711..dc7355fe0 100644 --- a/src/cavegen.cpp +++ b/src/cavegen.cpp @@ -35,7 +35,7 @@ static NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0 CavesNoiseIntersection::CavesNoiseIntersection( INodeDefManager *nodedef, BiomeManager *biomemgr, v3s16 chunksize, - NoiseParams *np_cave1, NoiseParams *np_cave2, int seed, float cave_width) + NoiseParams *np_cave1, NoiseParams *np_cave2, s32 seed, float cave_width) { assert(nodedef); assert(biomemgr); @@ -130,7 +130,7 @@ void CavesNoiseIntersection::generateCaves(MMVManip *vm, CavesRandomWalk::CavesRandomWalk( INodeDefManager *ndef, GenerateNotifier *gennotify, - int seed, + s32 seed, int water_level, content_t water_source, content_t lava_source) diff --git a/src/cavegen.h b/src/cavegen.h index da0894635..2bf503d47 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -41,7 +41,7 @@ class CavesNoiseIntersection { public: CavesNoiseIntersection(INodeDefManager *nodedef, BiomeManager *biomemgr, v3s16 chunksize, NoiseParams *np_cave1, NoiseParams *np_cave2, - int seed, float cave_width); + s32 seed, float cave_width); ~CavesNoiseIntersection(); void generateCaves(MMVManip *vm, v3s16 nmin, v3s16 nmax, u8 *biomemap); @@ -83,7 +83,7 @@ public: s16 *heightmap; // configurable parameters - int seed; + s32 seed; int water_level; int lava_depth; NoiseParams *np_caveliquids; @@ -122,7 +122,7 @@ public: // If gennotify is NULL, generation events are not logged. CavesRandomWalk(INodeDefManager *ndef, GenerateNotifier *gennotify = NULL, - int seed = 0, + s32 seed = 0, int water_level = 1, content_t water_source = CONTENT_IGNORE, content_t lava_source = CONTENT_IGNORE); diff --git a/src/dungeongen.h b/src/dungeongen.h index f0a5e5ba8..898627483 100644 --- a/src/dungeongen.h +++ b/src/dungeongen.h @@ -39,7 +39,7 @@ int dir_to_facedir(v3s16 d); struct DungeonParams { - int seed; + s32 seed; content_t c_water; content_t c_river_water; diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 041356e3d..32f7e29eb 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -89,11 +89,25 @@ Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) : { generating = false; id = mapgenid; - seed = (int)params->seed; water_level = params->water_level; flags = params->flags; csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE); + /* + We are losing half our entropy by doing this, but it is necessary to + preserve reverse compatibility. If the top half of our current 64 bit + seeds ever starts getting used, existing worlds will break due to a + different hash outcome and no way to differentiate between versions. + + A solution could be to add a new bit to designate that the top half of + the seed value should be used, essentially a 1-bit version code, but + this would require increasing the total size of a seed to 9 bytes (yuck) + + It's probably okay if this never gets fixed. 4.2 billion possibilities + ought to be enough for anyone. + */ + seed = (s32)params->seed; + vm = NULL; ndef = emerge->ndef; biomegen = NULL; @@ -107,7 +121,7 @@ Mapgen::~Mapgen() } -u32 Mapgen::getBlockSeed(v3s16 p, int seed) +u32 Mapgen::getBlockSeed(v3s16 p, s32 seed) { return (u32)seed + p.Z * 38134234 + @@ -116,7 +130,7 @@ u32 Mapgen::getBlockSeed(v3s16 p, int seed) } -u32 Mapgen::getBlockSeed2(v3s16 p, int seed) +u32 Mapgen::getBlockSeed2(v3s16 p, s32 seed) { u32 n = 1619 * p.X + 31337 * p.Y + 52591 * p.Z + 1013 * seed; n = (n >> 13) ^ n; diff --git a/src/mapgen.h b/src/mapgen.h index 10595fafc..0342fd46e 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -150,7 +150,7 @@ struct MapgenParams { */ class Mapgen { public: - int seed; + s32 seed; int water_level; u32 flags; bool generating; @@ -171,8 +171,8 @@ public: Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge); virtual ~Mapgen(); - static u32 getBlockSeed(v3s16 p, int seed); - static u32 getBlockSeed2(v3s16 p, int seed); + static u32 getBlockSeed(v3s16 p, s32 seed); + static u32 getBlockSeed2(v3s16 p, s32 seed); s16 findGroundLevelFull(v2s16 p2d); s16 findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax); s16 findLiquidSurface(v2s16 p2d, s16 ymin, s16 ymax); diff --git a/src/mg_biome.h b/src/mg_biome.h index e78e90e5f..389b7664f 100644 --- a/src/mg_biome.h +++ b/src/mg_biome.h @@ -80,7 +80,7 @@ struct BiomeParams { virtual void writeParams(Settings *settings) const = 0; virtual ~BiomeParams() {} - int seed; + s32 seed; }; class BiomeGen { diff --git a/src/noise.cpp b/src/noise.cpp index 2ddc3926f..c57c98ccb 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -156,7 +156,7 @@ s32 PcgRandom::randNormalDist(s32 min, s32 max, int num_trials) /////////////////////////////////////////////////////////////////////////////// -float noise2d(int x, int y, int seed) +float noise2d(int x, int y, s32 seed) { unsigned int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y + NOISE_MAGIC_SEED * seed) & 0x7fffffff; @@ -166,7 +166,7 @@ float noise2d(int x, int y, int seed) } -float noise3d(int x, int y, int z, int seed) +float noise3d(int x, int y, int z, s32 seed) { unsigned int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y + NOISE_MAGIC_Z * z + NOISE_MAGIC_SEED * seed) & 0x7fffffff; @@ -235,7 +235,7 @@ float triLinearInterpolationNoEase( return linearInterpolation(u, v, z); } -float noise2d_gradient(float x, float y, int seed, bool eased) +float noise2d_gradient(float x, float y, s32 seed, bool eased) { // Calculate the integer coordinates int x0 = myfloor(x); @@ -256,7 +256,7 @@ float noise2d_gradient(float x, float y, int seed, bool eased) } -float noise3d_gradient(float x, float y, float z, int seed, bool eased) +float noise3d_gradient(float x, float y, float z, s32 seed, bool eased) { // Calculate the integer coordinates int x0 = myfloor(x); @@ -290,7 +290,7 @@ float noise3d_gradient(float x, float y, float z, int seed, bool eased) } -float noise2d_perlin(float x, float y, int seed, +float noise2d_perlin(float x, float y, s32 seed, int octaves, float persistence, bool eased) { float a = 0; @@ -306,7 +306,7 @@ float noise2d_perlin(float x, float y, int seed, } -float noise2d_perlin_abs(float x, float y, int seed, +float noise2d_perlin_abs(float x, float y, s32 seed, int octaves, float persistence, bool eased) { float a = 0; @@ -321,7 +321,7 @@ float noise2d_perlin_abs(float x, float y, int seed, } -float noise3d_perlin(float x, float y, float z, int seed, +float noise3d_perlin(float x, float y, float z, s32 seed, int octaves, float persistence, bool eased) { float a = 0; @@ -336,7 +336,7 @@ float noise3d_perlin(float x, float y, float z, int seed, } -float noise3d_perlin_abs(float x, float y, float z, int seed, +float noise3d_perlin_abs(float x, float y, float z, s32 seed, int octaves, float persistence, bool eased) { float a = 0; @@ -363,7 +363,7 @@ float contour(float v) ///////////////////////// [ New noise ] //////////////////////////// -float NoisePerlin2D(NoiseParams *np, float x, float y, int seed) +float NoisePerlin2D(NoiseParams *np, float x, float y, s32 seed) { float a = 0; float f = 1.0; @@ -389,7 +389,7 @@ float NoisePerlin2D(NoiseParams *np, float x, float y, int seed) } -float NoisePerlin3D(NoiseParams *np, float x, float y, float z, int seed) +float NoisePerlin3D(NoiseParams *np, float x, float y, float z, s32 seed) { float a = 0; float f = 1.0; @@ -416,7 +416,7 @@ float NoisePerlin3D(NoiseParams *np, float x, float y, float z, int seed) } -Noise::Noise(NoiseParams *np_, int seed, u32 sx, u32 sy, u32 sz) +Noise::Noise(NoiseParams *np_, s32 seed, u32 sx, u32 sy, u32 sz) { memcpy(&np, np_, sizeof(np)); this->seed = seed; @@ -543,7 +543,7 @@ void Noise::resizeNoiseBuf(bool is3d) void Noise::gradientMap2D( float x, float y, float step_x, float step_y, - int seed) + s32 seed) { float v00, v01, v10, v11, u, v, orig_u; u32 index, i, j, noisex, noisey; @@ -607,7 +607,7 @@ void Noise::gradientMap2D( void Noise::gradientMap3D( float x, float y, float z, float step_x, float step_y, float step_z, - int seed) + s32 seed) { float v000, v010, v100, v110; float v001, v011, v101, v111; diff --git a/src/noise.h b/src/noise.h index 0e4252dd4..41b93ae01 100644 --- a/src/noise.h +++ b/src/noise.h @@ -148,7 +148,7 @@ struct NoiseParams { class Noise { public: NoiseParams np; - int seed; + s32 seed; u32 sx; u32 sy; u32 sz; @@ -157,7 +157,7 @@ public: float *persist_buf; float *result; - Noise(NoiseParams *np, int seed, u32 sx, u32 sy, u32 sz=1); + Noise(NoiseParams *np, s32 seed, u32 sx, u32 sy, u32 sz=1); ~Noise(); void setSize(u32 sx, u32 sy, u32 sz=1); @@ -167,11 +167,11 @@ public: void gradientMap2D( float x, float y, float step_x, float step_y, - int seed); + s32 seed); void gradientMap3D( float x, float y, float z, float step_x, float step_y, float step_z, - int seed); + s32 seed); float *perlinMap2D(float x, float y, float *persistence_map=NULL); float *perlinMap3D(float x, float y, float z, float *persistence_map=NULL); @@ -202,11 +202,11 @@ private: }; -float NoisePerlin2D(NoiseParams *np, float x, float y, int seed); -float NoisePerlin3D(NoiseParams *np, float x, float y, float z, int seed); +float NoisePerlin2D(NoiseParams *np, float x, float y, s32 seed); +float NoisePerlin3D(NoiseParams *np, float x, float y, float z, s32 seed); inline float NoisePerlin2D_PO(NoiseParams *np, float x, float xoff, - float y, float yoff, int seed) + float y, float yoff, s32 seed) { return NoisePerlin2D(np, x + xoff * np->spread.X, @@ -215,7 +215,7 @@ inline float NoisePerlin2D_PO(NoiseParams *np, float x, float xoff, } inline float NoisePerlin3D_PO(NoiseParams *np, float x, float xoff, - float y, float yoff, float z, float zoff, int seed) + float y, float yoff, float z, float zoff, s32 seed) { return NoisePerlin3D(np, x + xoff * np->spread.X, @@ -225,22 +225,22 @@ inline float NoisePerlin3D_PO(NoiseParams *np, float x, float xoff, } // Return value: -1 ... 1 -float noise2d(int x, int y, int seed); -float noise3d(int x, int y, int z, int seed); +float noise2d(int x, int y, s32 seed); +float noise3d(int x, int y, int z, s32 seed); -float noise2d_gradient(float x, float y, int seed, bool eased=true); -float noise3d_gradient(float x, float y, float z, int seed, bool eased=false); +float noise2d_gradient(float x, float y, s32 seed, bool eased=true); +float noise3d_gradient(float x, float y, float z, s32 seed, bool eased=false); -float noise2d_perlin(float x, float y, int seed, +float noise2d_perlin(float x, float y, s32 seed, int octaves, float persistence, bool eased=true); -float noise2d_perlin_abs(float x, float y, int seed, +float noise2d_perlin_abs(float x, float y, s32 seed, int octaves, float persistence, bool eased=true); -float noise3d_perlin(float x, float y, float z, int seed, +float noise3d_perlin(float x, float y, float z, s32 seed, int octaves, float persistence, bool eased=false); -float noise3d_perlin_abs(float x, float y, float z, int seed, +float noise3d_perlin_abs(float x, float y, float z, s32 seed, int octaves, float persistence, bool eased=false); inline float easeCurve(float t) diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 8284c3fcb..ebdea09e4 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -758,7 +758,7 @@ int ModApiEnvMod::l_get_perlin_map(lua_State *L) return 0; v3s16 size = read_v3s16(L, 2); - int seed = (int)(env->getServerMap().getSeed()); + s32 seed = (s32)(env->getServerMap().getSeed()); LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(&np, seed, size); *(void **)(lua_newuserdata(L, sizeof(void *))) = n; luaL_getmetatable(L, "PerlinNoiseMap"); diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp index 04dc6048f..e0039371f 100644 --- a/src/script/lua_api/l_noise.cpp +++ b/src/script/lua_api/l_noise.cpp @@ -146,7 +146,7 @@ const luaL_reg LuaPerlinNoise::methods[] = { LuaPerlinNoiseMap */ -LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, int seed, v3s16 size) +LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, s32 seed, v3s16 size) { m_is3d = size.Z > 1; np = *params; diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h index 492eb7550..40bfd1315 100644 --- a/src/script/lua_api/l_noise.h +++ b/src/script/lua_api/l_noise.h @@ -79,7 +79,7 @@ class LuaPerlinNoiseMap : public ModApiBase { static int l_getMapSlice(lua_State *L); public: - LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size); + LuaPerlinNoiseMap(NoiseParams *np, s32 seed, v3s16 size); ~LuaPerlinNoiseMap(); @@ -111,7 +111,7 @@ private: static int l_next(lua_State *L); public: - LuaPseudoRandom(int seed) : + LuaPseudoRandom(s32 seed) : m_pseudo(seed) {} // LuaPseudoRandom(seed) diff --git a/src/treegen.cpp b/src/treegen.cpp index 208f34552..36d387c57 100644 --- a/src/treegen.cpp +++ b/src/treegen.cpp @@ -31,7 +31,7 @@ namespace treegen { void make_tree(MMVManip &vmanip, v3s16 p0, - bool is_apple_tree, INodeDefManager *ndef, int seed) + bool is_apple_tree, INodeDefManager *ndef, s32 seed) { /* NOTE: Tree-placing code is currently duplicated in the engine @@ -149,7 +149,7 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition) { MapNode dirtnode(ndef->getId("mapgen_dirt")); - int seed; + s32 seed; if (tree_definition.explicit_seed) seed = tree_definition.seed + 14002; else @@ -649,7 +649,7 @@ v3f transposeMatrix(irr::core::matrix4 M, v3f v) } -void make_jungletree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, int seed) +void make_jungletree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, s32 seed) { /* NOTE: Tree-placing code is currently duplicated in the engine @@ -748,7 +748,7 @@ void make_jungletree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, int seed } -void make_pine_tree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, int seed) +void make_pine_tree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, s32 seed) { /* NOTE: Tree-placing code is currently duplicated in the engine diff --git a/src/treegen.h b/src/treegen.h index 4b0089d1e..4e6f95e67 100644 --- a/src/treegen.h +++ b/src/treegen.h @@ -54,19 +54,19 @@ namespace treegen { bool thin_branches; MapNode fruitnode; int fruit_chance; - int seed; + s32 seed; bool explicit_seed; }; // Add default tree void make_tree(MMVManip &vmanip, v3s16 p0, - bool is_apple_tree, INodeDefManager *ndef, int seed); + bool is_apple_tree, INodeDefManager *ndef, s32 seed); // Add jungle tree void make_jungletree(MMVManip &vmanip, v3s16 p0, - INodeDefManager *ndef, int seed); + INodeDefManager *ndef, s32 seed); // Add pine tree void make_pine_tree(MMVManip &vmanip, v3s16 p0, - INodeDefManager *ndef, int seed); + INodeDefManager *ndef, s32 seed); // Add L-Systems tree (used by engine) treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, -- cgit v1.2.3 From 7841f1c5098d73b7538623cf898ca1e32ac6773d Mon Sep 17 00:00:00 2001 From: MillersMan Date: Sun, 5 Jun 2016 01:30:36 +0200 Subject: Mapgen: Performance improvement and fixes for updateLiquid (#4065) - Adds only ~100 nodes per chunk to trans_liquid with similar processing time - Adds liquid nodes themselves instead of potential solid nodes below them - CONTENT_IGNORE nodes are interpreted as if they continue their neighborhood - This allows liquid columns to span multiple chunks without being interrupted - NOTE: Expects an one-node border in generation chunk without liquid changes --- src/mapgen.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++---------- src/mapgen.h | 4 +++ 2 files changed, 77 insertions(+), 14 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 32f7e29eb..b5c48a471 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -213,27 +213,86 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) //printf("updateHeightmap: %dus\n", t.stop()); } +inline bool Mapgen::isLiquidHorizontallyFlowable(u32 vi, v3s16 em) +{ + u32 vi_neg_x = vi; + vm->m_area.add_x(em, vi_neg_x, -1); + if (vm->m_data[vi_neg_x].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_nx = ndef->get(vm->m_data[vi_neg_x]); + if (c_nx.floodable && !c_nx.isLiquid()) + return true; + } + u32 vi_pos_x = vi; + vm->m_area.add_x(em, vi_pos_x, +1); + if (vm->m_data[vi_pos_x].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_px = ndef->get(vm->m_data[vi_pos_x]); + if (c_px.floodable && !c_px.isLiquid()) + return true; + } + u32 vi_neg_z = vi; + vm->m_area.add_z(em, vi_neg_z, -1); + if (vm->m_data[vi_neg_z].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_nz = ndef->get(vm->m_data[vi_neg_z]); + if (c_nz.floodable && !c_nz.isLiquid()) + return true; + } + u32 vi_pos_z = vi; + vm->m_area.add_z(em, vi_pos_z, +1); + if (vm->m_data[vi_pos_z].getContent() != CONTENT_IGNORE) { + const ContentFeatures &c_pz = ndef->get(vm->m_data[vi_pos_z]); + if (c_pz.floodable && !c_pz.isLiquid()) + return true; + } + return false; +} void Mapgen::updateLiquid(UniqueQueue *trans_liquid, v3s16 nmin, v3s16 nmax) { - bool isliquid, wasliquid; + bool isignored, isliquid, wasignored, wasliquid, waschecked, waspushed; v3s16 em = vm->m_area.getExtent(); - for (s16 z = nmin.Z; z <= nmax.Z; z++) { - for (s16 x = nmin.X; x <= nmax.X; x++) { - wasliquid = true; - - u32 i = vm->m_area.index(x, nmax.Y, z); - for (s16 y = nmax.Y; y >= nmin.Y; y--) { - isliquid = ndef->get(vm->m_data[i]).isLiquid(); - - // there was a change between liquid and nonliquid, add to queue. - if (isliquid != wasliquid) + for (s16 z = nmin.Z + 1; z <= nmax.Z - 1; z++) + for (s16 x = nmin.X + 1; x <= nmax.X - 1; x++) { + wasignored = true; + wasliquid = false; + waschecked = false; + waspushed = false; + + u32 vi = vm->m_area.index(x, nmax.Y, z); + for (s16 y = nmax.Y; y >= nmin.Y; y--) { + isignored = vm->m_data[vi].getContent() == CONTENT_IGNORE; + isliquid = ndef->get(vm->m_data[vi]).isLiquid(); + + if (isignored || wasignored || isliquid == wasliquid) { + // Neither topmost node of liquid column nor topmost node below column + waschecked = false; + waspushed = false; + } else if (isliquid) { + // This is the topmost node in the column + bool ispushed = false; + if (isLiquidHorizontallyFlowable(vi, em)) { trans_liquid->push_back(v3s16(x, y, z)); - - wasliquid = isliquid; - vm->m_area.add_y(em, i, -1); + ispushed = true; + } + // Remember waschecked and waspushed to avoid repeated + // checks/pushes in case the column consists of only this node + waschecked = true; + waspushed = ispushed; + } else { + // This is the topmost node below a liquid column + u32 vi_above = vi; + vm->m_area.add_y(em, vi_above, 1); + if (!waspushed && (ndef->get(vm->m_data[vi]).floodable || + (!waschecked && isLiquidHorizontallyFlowable(vi_above, em)))) { + // Push back the lowest node in the column which is one + // node above this one + trans_liquid->push_back(v3s16(x, y + 1, z)); + } } + + wasliquid = isliquid; + wasignored = isignored; + vm->m_area.add_y(em, vi, -1); } } } diff --git a/src/mapgen.h b/src/mapgen.h index f673007b5..90ac84bd8 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -199,6 +199,10 @@ public: virtual int getSpawnLevelAtPoint(v2s16 p) { return 0; } private: + // isLiquidHorizontallyFlowable() is a helper function for updateLiquid() + // that checks whether there are floodable nodes without liquid beneath + // the node at index vi. + inline bool isLiquidHorizontallyFlowable(u32 vi, v3s16 em); DISABLE_CLASS_COPY(Mapgen); }; -- cgit v1.2.3 From d24f3841740b471eff384c8bd6e8bbfdfd03a3e2 Mon Sep 17 00:00:00 2001 From: paramat Date: Fri, 3 Jun 2016 12:58:50 +0100 Subject: Biome API: Add per-biome riverbed material and depth Mgvalleys: Remove riverbed sand placement from base terrain generation Riverbed material placement moved to MapgenBasic::generateBiomes() Document fields and add note that the biome API is still unstable --- doc/lua_api.txt | 6 ++++++ src/mapgen.cpp | 24 ++++++++++++++++++------ src/mapgen_valleys.cpp | 13 ++----------- src/mg_biome.cpp | 3 +++ src/mg_biome.h | 2 ++ src/script/lua_api/l_mapgen.cpp | 2 ++ 6 files changed, 33 insertions(+), 17 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f348f5103..30f4d87df 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3723,6 +3723,9 @@ Definition tables ### Biome definition (`register_biome`) +**Note** +The biome API is still in an experimental phase and subject to change. + { name = "tundra", node_dust = "default:snow", @@ -3742,6 +3745,9 @@ Definition tables -- ^ Node that replaces all seawater nodes not in the defined surface layer. node_river_water = "default:ice", -- ^ Node that replaces river water in mapgens that use default:river_water. + node_riverbed = "default:gravel", + depth_riverbed = 2, + -- ^ Node placed under river water and thickness of this layer. y_min = 1, y_max = 31000, -- ^ Lower and upper limits for biome. diff --git a/src/mapgen.cpp b/src/mapgen.cpp index b5c48a471..66892a574 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -536,13 +536,15 @@ MgStoneType MapgenBasic::generateBiomes() u16 depth_top = 0; u16 base_filler = 0; u16 depth_water_top = 0; + u16 depth_riverbed = 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); + bool river_water_above = c_above == c_river_water_source; + bool water_above = c_above == c_water_source || river_water_above; // 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. @@ -564,10 +566,11 @@ MgStoneType MapgenBasic::generateBiomes() 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); + base_filler = MYMAX(depth_top + + biome->depth_filler + + noise_filler_depth->result[index], 0.f); depth_water_top = biome->depth_water_top; + depth_riverbed = biome->depth_riverbed; // Detect stone type for dungeons during every biome calculation. // This is more efficient than detecting per-node and will not @@ -590,7 +593,15 @@ MgStoneType MapgenBasic::generateBiomes() || c_below == c_river_water_source) nplaced = U16_MAX; - if (nplaced < depth_top) { + if (river_water_above) { + if (nplaced < depth_riverbed) { + vm->m_data[vi] = MapNode(biome->c_riverbed); + nplaced++; + } else { + nplaced = U16_MAX; // Disable top/filler placement + river_water_above = false; + } + } else if (nplaced < depth_top) { vm->m_data[vi] = MapNode(biome->c_top); nplaced++; } else if (nplaced < base_filler) { @@ -610,9 +621,10 @@ MgStoneType MapgenBasic::generateBiomes() 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 + nplaced = 0; // Enable riverbed placement for next surface air_above = false; water_above = true; + river_water_above = true; } else if (c == CONTENT_AIR) { nplaced = 0; // Enable top/filler placement for next surface air_above = true; diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 2cd733d36..6581b792f 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -114,11 +114,6 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager * // Resolve content to be used 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_sand == CONTENT_IGNORE) - c_sand = c_stone; } @@ -493,7 +488,6 @@ int MapgenValleys::generateTerrain() MapNode n_air(CONTENT_AIR); MapNode n_river_water(c_river_water_source); - MapNode n_sand(c_sand); MapNode n_stone(c_stone); MapNode n_water(c_water_source); @@ -537,10 +531,7 @@ int MapgenValleys::generateTerrain() float surface_delta = (float)y - surface_y; bool river = y + 1 < river_y; - if (fabs(surface_delta) <= 0.5f && y > water_level && river) { - // river bottom - vm->m_data[index_data] = n_sand; - } else if (slope * fill > surface_delta) { + if (slope * fill > surface_delta) { // ground vm->m_data[index_data] = n_stone; if (y > heightmap[index_2d]) @@ -553,7 +544,7 @@ int MapgenValleys::generateTerrain() } else if (river) { // river vm->m_data[index_data] = n_river_water; - } else { + } else { // air vm->m_data[index_data] = n_air; } } diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp index df728af33..78034bf6c 100644 --- a/src/mg_biome.cpp +++ b/src/mg_biome.cpp @@ -46,6 +46,7 @@ BiomeManager::BiomeManager(IGameDef *gamedef) : b->depth_top = 0; b->depth_filler = -MAX_MAP_GENERATION_LIMIT; b->depth_water_top = 0; + b->depth_riverbed = 0; b->y_min = -MAX_MAP_GENERATION_LIMIT; b->y_max = MAX_MAP_GENERATION_LIMIT; b->heat_point = 0.0; @@ -57,6 +58,7 @@ BiomeManager::BiomeManager(IGameDef *gamedef) : b->m_nodenames.push_back("mapgen_water_source"); b->m_nodenames.push_back("mapgen_water_source"); b->m_nodenames.push_back("mapgen_river_water_source"); + b->m_nodenames.push_back("mapgen_stone"); b->m_nodenames.push_back("ignore"); m_ndef->pendNodeResolve(b); @@ -237,5 +239,6 @@ void Biome::resolveNodeNames() getIdFromNrBacklog(&c_water_top, "mapgen_water_source", CONTENT_AIR); getIdFromNrBacklog(&c_water, "mapgen_water_source", CONTENT_AIR); getIdFromNrBacklog(&c_river_water, "mapgen_river_water_source", CONTENT_AIR); + getIdFromNrBacklog(&c_riverbed, "mapgen_stone", CONTENT_AIR); getIdFromNrBacklog(&c_dust, "ignore", CONTENT_IGNORE); } diff --git a/src/mg_biome.h b/src/mg_biome.h index 568d0b1ac..eb0a18a2f 100644 --- a/src/mg_biome.h +++ b/src/mg_biome.h @@ -54,11 +54,13 @@ public: content_t c_water_top; content_t c_water; content_t c_river_water; + content_t c_riverbed; content_t c_dust; s16 depth_top; s16 depth_filler; s16 depth_water_top; + s16 depth_riverbed; s16 y_min; s16 y_max; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 6baf217af..dc188f8a4 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -378,6 +378,7 @@ Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) b->depth_top = getintfield_default(L, index, "depth_top", 0); b->depth_filler = getintfield_default(L, index, "depth_filler", -31000); b->depth_water_top = getintfield_default(L, index, "depth_water_top", 0); + b->depth_riverbed = getintfield_default(L, index, "depth_riverbed", 0); b->y_min = getintfield_default(L, index, "y_min", -31000); b->y_max = getintfield_default(L, index, "y_max", 31000); b->heat_point = getfloatfield_default(L, index, "heat_point", 0.f); @@ -391,6 +392,7 @@ Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef) nn.push_back(getstringfield_default(L, index, "node_water_top", "")); nn.push_back(getstringfield_default(L, index, "node_water", "")); nn.push_back(getstringfield_default(L, index, "node_river_water", "")); + nn.push_back(getstringfield_default(L, index, "node_riverbed", "")); nn.push_back(getstringfield_default(L, index, "node_dust", "")); ndef->pendNodeResolve(b); -- cgit v1.2.3 From d4457ef42061435a1ccf6f5e056f37bac9b30c02 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 4 Jun 2016 20:24:07 -0400 Subject: Mapgen: Optimize biomemap creation by combining with generateBiomes --- src/mapgen.cpp | 20 +++++++++++++++++--- src/mapgen_flat.cpp | 1 - src/mapgen_fractal.cpp | 1 - src/mapgen_v5.cpp | 1 - src/mapgen_v7.cpp | 1 - src/mapgen_valleys.cpp | 5 +---- 6 files changed, 18 insertions(+), 11 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 66892a574..576fb219a 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -524,6 +524,10 @@ MapgenBasic::~MapgenBasic() MgStoneType MapgenBasic::generateBiomes() { + // can't generate biomes without a biome generator! + assert(biomegen); + assert(biomemap); + v3s16 em = vm->m_area.getExtent(); u32 index = 0; MgStoneType stone_type = MGSTONE_STONE; @@ -546,6 +550,8 @@ MgStoneType MapgenBasic::generateBiomes() bool river_water_above = c_above == c_river_water_source; bool water_above = c_above == c_water_source || river_water_above; + biomemap[index] = BIOME_NONE; + // 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; @@ -560,11 +566,19 @@ MgStoneType MapgenBasic::generateBiomes() // 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))) { + bool is_stone_surface = (c == c_stone) && + (air_above || water_above || !biome); + + bool is_water_surface = + (c == c_water_source || c == c_river_water_source) && + (air_above || !biome); + + if (is_stone_surface || is_water_surface) { biome = biomegen->getBiomeAtIndex(index, y); + if (biomemap[index] == BIOME_NONE && is_stone_surface) + biomemap[index] = biome->index; + depth_top = biome->depth_top; base_filler = MYMAX(depth_top + biome->depth_filler + diff --git a/src/mapgen_flat.cpp b/src/mapgen_flat.cpp index 724f06825..7cc6aad5c 100644 --- a/src/mapgen_flat.cpp +++ b/src/mapgen_flat.cpp @@ -192,7 +192,6 @@ void MapgenFlat::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - biomegen->getBiomes(heightmap); MgStoneType stone_type = generateBiomes(); if (flags & MG_CAVES) diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index b613bf358..c47a7bfdc 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -208,7 +208,6 @@ void MapgenFractal::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - biomegen->getBiomes(heightmap); MgStoneType stone_type = generateBiomes(); if (flags & MG_CAVES) diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index 3e10ec2a5..74d5e1ee3 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -190,7 +190,6 @@ void MapgenV5::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - biomegen->getBiomes(heightmap); MgStoneType stone_type = generateBiomes(); // Generate caves diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 7327facae..35dcdcd94 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -219,7 +219,6 @@ void MapgenV7::makeChunk(BlockMakeData *data) // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); - biomegen->getBiomes(heightmap); MgStoneType stone_type = generateBiomes(); if (flags & MG_CAVES) diff --git a/src/mapgen_valleys.cpp b/src/mapgen_valleys.cpp index 6581b792f..bbf20719d 100644 --- a/src/mapgen_valleys.cpp +++ b/src/mapgen_valleys.cpp @@ -250,10 +250,7 @@ void MapgenValleys::makeChunk(BlockMakeData *data) // Generate base terrain with initial heightmaps s16 stone_surface_max_y = generateTerrain(); - // Build biomemap - m_bgen->getBiomes(heightmap); - - // Place biome-specific nodes + // Place biome-specific nodes and build biomemap MgStoneType stone_type = generateBiomes(); // Cave creation. -- cgit v1.2.3 From 04fb10914c0d03ee77dafe610f336f23c58949ab Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 12 Jun 2016 03:11:26 +0100 Subject: Dungeons: Generalise use, add capabilities, various modifications - Generalise node names to c_wall and c_alt_wall - Remove 'mossratio' and instead disable alt_wall loop if c_alt_wall == CONTENT_IGNORE - Use one generalised 3D noise for alternative wall nodes and in mgv6 create moss distribution similar to the previous - Rename rarity noise to density noise and enable the option of multiple dungeons per chunk determined by the value. Recreate previous distribution - Add parameters for min and max rooms per dungeon - Add dungeon y limits - Integrate river water properly Generalisation is needed now that we have sandstone and desert stone dungeons by default and can choose any node for alternative structure. The current code is based around cobble dungeons with mossycobble alternative nodes, the 2 noises controlling the alternative nodes are based on wetness. Enabling multiple dungeons per chunk with definable number of rooms allows the option of very dense and complex underground structures that could interconnect to create megastructures. Y limits are added to be consistent with other mapgen elements, and enable locaton of dungeon or megastructure realms as part of our 'stacked realms' philosophy. --- src/dungeongen.cpp | 100 ++++++++++++++++++++++++++++------------------------- src/dungeongen.h | 17 ++++----- src/mapgen.cpp | 36 +++++++++---------- src/mapgen_v6.cpp | 26 +++++++------- 4 files changed, 93 insertions(+), 86 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/dungeongen.cpp b/src/dungeongen.cpp index 6be7e9086..78573da04 100644 --- a/src/dungeongen.cpp +++ b/src/dungeongen.cpp @@ -30,9 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc., //#define DGEN_USE_TORCHES -NoiseParams nparams_dungeon_rarity(0.0, 1.0, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0); -NoiseParams nparams_dungeon_wetness(0.0, 1.0, v3f(40.0, 40.0, 40.0), 32474, 4, 1.1, 2.0); -NoiseParams nparams_dungeon_density(0.0, 1.0, v3f(2.5, 2.5, 2.5), 0, 2, 1.4, 2.0); +NoiseParams nparams_dungeon_density(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0); +NoiseParams nparams_dungeon_alt_wall(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); /////////////////////////////////////////////////////////////////////////////// @@ -55,26 +54,27 @@ DungeonGen::DungeonGen(INodeDefManager *ndef, } else { dp.seed = 0; - dp.c_water = ndef->getId("mapgen_water_source"); - dp.c_cobble = ndef->getId("mapgen_cobble"); - dp.c_moss = ndef->getId("mapgen_mossycobble"); - dp.c_stair = ndef->getId("mapgen_stair_cobble"); + dp.c_water = ndef->getId("mapgen_water_source"); + dp.c_river_water = ndef->getId("mapgen_river_water_source"); + dp.c_wall = ndef->getId("mapgen_cobble"); + dp.c_alt_wall = ndef->getId("mapgen_mossycobble"); + dp.c_stair = ndef->getId("mapgen_stair_cobble"); + + if (dp.c_river_water == CONTENT_IGNORE) + dp.c_river_water = ndef->getId("mapgen_water_source"); dp.diagonal_dirs = false; - dp.mossratio = 3.0; dp.holesize = v3s16(1, 2, 1); dp.roomsize = v3s16(0, 0, 0); + dp.rooms_min = 2; + dp.rooms_max = 16; + dp.y_min = -MAX_MAP_GENERATION_LIMIT; + dp.y_max = MAX_MAP_GENERATION_LIMIT; dp.notifytype = GENNOTIFY_DUNGEON; - dp.np_rarity = nparams_dungeon_rarity; - dp.np_wetness = nparams_dungeon_wetness; - dp.np_density = nparams_dungeon_density; + dp.np_density = nparams_dungeon_density; + dp.np_alt_wall = nparams_dungeon_alt_wall; } - - // For mapgens using river water - dp.c_river_water = ndef->getId("mapgen_river_water_source"); - if (dp.c_river_water == CONTENT_IGNORE) - dp.c_river_water = ndef->getId("mapgen_water_source"); } @@ -83,7 +83,11 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax) assert(vm); //TimeTaker t("gen dungeons"); - if (NoisePerlin3D(&dp.np_rarity, nmin.X, nmin.Y, nmin.Z, dp.seed) < 0.2) + if (nmin.Y < dp.y_min || nmax.Y > dp.y_max) + return; + + float nval_density = NoisePerlin3D(&dp.np_density, nmin.X, nmin.Y, nmin.Z, dp.seed); + if (nval_density < 1.0f) return; this->vm = vm; @@ -107,23 +111,23 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax) } } - // Add it - makeDungeon(v3s16(1, 1, 1) * MAP_BLOCKSIZE); + // Add them + for (u32 i = 0; i < floor(nval_density); i++) + makeDungeon(v3s16(1, 1, 1) * MAP_BLOCKSIZE); - // Convert some cobble to mossy cobble - if (dp.mossratio != 0.0) { - for (s16 z = nmin.Z; z <= nmax.Z; z++) - for (s16 y = nmin.Y; y <= nmax.Y; y++) { - u32 i = vm->m_area.index(nmin.X, y, z); - for (s16 x = nmin.X; x <= nmax.X; x++) { - if (vm->m_data[i].getContent() == dp.c_cobble) { - float wetness = NoisePerlin3D(&dp.np_wetness, x, y, z, dp.seed); - float density = NoisePerlin3D(&dp.np_density, x, y, z, blockseed); - if (density < wetness / dp.mossratio) - vm->m_data[i].setContent(dp.c_moss); - } - i++; + // Optionally convert some structure to alternative structure + if (dp.c_alt_wall == CONTENT_IGNORE) + return; + + for (s16 z = nmin.Z; z <= nmax.Z; z++) + for (s16 y = nmin.Y; y <= nmax.Y; y++) { + u32 i = vm->m_area.index(nmin.X, y, z); + for (s16 x = nmin.X; x <= nmax.X; x++) { + if (vm->m_data[i].getContent() == dp.c_wall) { + if (NoisePerlin3D(&dp.np_alt_wall, x, y, z, blockseed) > 0.0f) + vm->m_data[i].setContent(dp.c_alt_wall); } + i++; } } @@ -189,7 +193,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding) */ v3s16 last_room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); - u32 room_count = random.range(2, 16); + u32 room_count = random.range(dp.rooms_min, dp.rooms_max); for (u32 i = 0; i < room_count; i++) { // Make a room to the determined place makeRoom(roomsize, roomplace); @@ -265,7 +269,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding) void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) { - MapNode n_cobble(dp.c_cobble); + MapNode n_wall(dp.c_wall); MapNode n_air(CONTENT_AIR); // Make +-X walls @@ -278,7 +282,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) u32 vi = vm->m_area.index(p); if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) continue; - vm->m_data[vi] = n_cobble; + vm->m_data[vi] = n_wall; } { v3s16 p = roomplace + v3s16(roomsize.X - 1, y, z); @@ -287,7 +291,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) u32 vi = vm->m_area.index(p); if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) continue; - vm->m_data[vi] = n_cobble; + vm->m_data[vi] = n_wall; } } @@ -301,7 +305,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) u32 vi = vm->m_area.index(p); if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) continue; - vm->m_data[vi] = n_cobble; + vm->m_data[vi] = n_wall; } { v3s16 p = roomplace + v3s16(x, y, roomsize.Z - 1); @@ -310,7 +314,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) u32 vi = vm->m_area.index(p); if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) continue; - vm->m_data[vi] = n_cobble; + vm->m_data[vi] = n_wall; } } @@ -324,7 +328,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) u32 vi = vm->m_area.index(p); if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) continue; - vm->m_data[vi] = n_cobble; + vm->m_data[vi] = n_wall; } { v3s16 p = roomplace + v3s16(x,roomsize. Y - 1, z); @@ -333,7 +337,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace) u32 vi = vm->m_area.index(p); if (vm->m_flags[vi] & VMANIP_FLAG_DUNGEON_UNTOUCHABLE) continue; - vm->m_data[vi] = n_cobble; + vm->m_data[vi] = n_wall; } } @@ -417,7 +421,7 @@ void DungeonGen::makeCorridor(v3s16 doorplace, v3s16 doordir, makeFill(p + v3s16(-1, -1, -1), dp.holesize + v3s16(2, 3, 2), VMANIP_FLAG_DUNGEON_UNTOUCHABLE, - MapNode(dp.c_cobble), + MapNode(dp.c_wall), 0); makeHole(p); makeHole(p - dir); @@ -435,18 +439,18 @@ void DungeonGen::makeCorridor(v3s16 doorplace, v3s16 doordir, int facedir = dir_to_facedir(dir * make_stairs); u32 vi = vm->m_area.index(p.X - dir.X, p.Y - 1, p.Z - dir.Z); - if (vm->m_data[vi].getContent() == dp.c_cobble) + if (vm->m_data[vi].getContent() == dp.c_wall) vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir); vi = vm->m_area.index(p.X, p.Y, p.Z); - if (vm->m_data[vi].getContent() == dp.c_cobble) + if (vm->m_data[vi].getContent() == dp.c_wall) vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir); } } else { makeFill(p + v3s16(-1, -1, -1), dp.holesize + v3s16(2, 2, 2), VMANIP_FLAG_DUNGEON_UNTOUCHABLE, - MapNode(dp.c_cobble), + MapNode(dp.c_wall), 0); makeHole(p); } @@ -488,8 +492,8 @@ bool DungeonGen::findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir) randomizeDir(); continue; } - if (vm->getNodeNoExNoEmerge(p).getContent() == dp.c_cobble && - vm->getNodeNoExNoEmerge(p1).getContent() == dp.c_cobble) { + if (vm->getNodeNoExNoEmerge(p).getContent() == dp.c_wall && + vm->getNodeNoExNoEmerge(p1).getContent() == dp.c_wall) { // Found wall, this is a good place! result_place = p; result_dir = m_dir; @@ -502,7 +506,7 @@ bool DungeonGen::findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir) */ // Jump one up if the actual space is there if (vm->getNodeNoExNoEmerge(p + - v3s16(0, 0, 0)).getContent() == dp.c_cobble && + v3s16(0, 0, 0)).getContent() == dp.c_wall && vm->getNodeNoExNoEmerge(p + v3s16(0, 1, 0)).getContent() == CONTENT_AIR && vm->getNodeNoExNoEmerge(p + @@ -510,7 +514,7 @@ bool DungeonGen::findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir) p += v3s16(0,1,0); // Jump one down if the actual space is there if (vm->getNodeNoExNoEmerge(p + - v3s16(0, 1, 0)).getContent() == dp.c_cobble && + v3s16(0, 1, 0)).getContent() == dp.c_wall && vm->getNodeNoExNoEmerge(p + v3s16(0, 0, 0)).getContent() == CONTENT_AIR && vm->getNodeNoExNoEmerge(p + diff --git a/src/dungeongen.h b/src/dungeongen.h index 898627483..30786b9f3 100644 --- a/src/dungeongen.h +++ b/src/dungeongen.h @@ -43,19 +43,21 @@ struct DungeonParams { content_t c_water; content_t c_river_water; - content_t c_cobble; - content_t c_moss; + content_t c_wall; + content_t c_alt_wall; content_t c_stair; - GenNotifyType notifytype; bool diagonal_dirs; - float mossratio; v3s16 holesize; v3s16 roomsize; + u16 rooms_min; + u16 rooms_max; + s16 y_min; + s16 y_max; + GenNotifyType notifytype; - NoiseParams np_rarity; - NoiseParams np_wetness; NoiseParams np_density; + NoiseParams np_alt_wall; }; class DungeonGen { @@ -99,8 +101,7 @@ public: } }; -extern NoiseParams nparams_dungeon_rarity; -extern NoiseParams nparams_dungeon_wetness; extern NoiseParams nparams_dungeon_density; +extern NoiseParams nparams_dungeon_alt_wall; #endif diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 576fb219a..1e0e3aa44 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -738,44 +738,44 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, MgStoneType stone_type) DungeonParams dp; - dp.seed = seed; - - dp.np_rarity = nparams_dungeon_rarity; - dp.np_density = nparams_dungeon_density; - dp.np_wetness = nparams_dungeon_wetness; - dp.c_water = c_water_source; + dp.seed = seed; + dp.c_water = c_water_source; + dp.c_river_water = c_river_water_source; + dp.rooms_min = 2; + dp.rooms_max = 16; + dp.y_min = -MAX_MAP_GENERATION_LIMIT; + dp.y_max = MAX_MAP_GENERATION_LIMIT; + dp.np_density = nparams_dungeon_density; + dp.np_alt_wall = nparams_dungeon_alt_wall; switch (stone_type) { default: case MGSTONE_STONE: - dp.c_cobble = c_cobble; - dp.c_moss = c_mossycobble; - dp.c_stair = c_stair_cobble; + dp.c_wall = c_cobble; + dp.c_alt_wall = 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.c_wall = c_desert_stone; + dp.c_alt_wall = CONTENT_IGNORE; + 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.c_wall = c_sandstonebrick; + dp.c_alt_wall = CONTENT_IGNORE; + 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; diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 103120b6a..caa64827e 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -560,28 +560,30 @@ void MapgenV6::makeChunk(BlockMakeData *data) DungeonParams dp; dp.seed = seed; + dp.c_water = c_water_source; + dp.c_river_water = c_water_source; + dp.rooms_min = 2; + dp.rooms_max = 16; + dp.y_min = -MAX_MAP_GENERATION_LIMIT; + dp.y_max = MAX_MAP_GENERATION_LIMIT; + dp.np_density = NoiseParams(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0); + dp.np_alt_wall = NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0); - 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 (getBiome(0, v2s16(node_min.X, node_min.Z)) == BT_DESERT) { - dp.c_cobble = c_desert_stone; - dp.c_moss = c_desert_stone; - dp.c_stair = c_desert_stone; + dp.c_wall = c_desert_stone; + dp.c_alt_wall = CONTENT_IGNORE; + 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 { - dp.c_cobble = c_cobble; - dp.c_moss = c_mossycobble; - dp.c_stair = c_stair_cobble; + dp.c_wall = c_cobble; + dp.c_alt_wall = 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; -- 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.cpp') 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.cpp') 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 ea12da939fdb0a8fd13de885d104af3031ffc3ac Mon Sep 17 00:00:00 2001 From: paramat Date: Fri, 29 Jul 2016 03:44:58 +0100 Subject: Mapgen: Remove unused 'flat' and 'trees' flags from mg_flags When the 'flat' and 'trees' flags were moved into mgv6_spflags they were left in mg_flags in an attempt to support old mgv6 worlds. However their appearence in mg_flags causes confusion, also, later, old-world support was found to be broken for mgv6 worlds with 'notrees'. This commit cleans up the mess and comes a month after a thread warning of the change, and explaining the required action, was posted in the news subforum. Only old mgv6 worlds with 'flat' or 'notrees' are affected, a small minority of worlds, the required action being correctly setting these flags in mgv6_spflags. Disable a section of the 'map settings manager' unit test which is to be changed as it is causing problems for pull requests. --- src/mapgen.cpp | 2 -- src/mapgen.h | 4 ++-- src/mapgen_v6.cpp | 10 +++++----- src/unittest/test_map_settings_manager.cpp | 8 ++++++-- 4 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/mapgen.cpp') diff --git a/src/mapgen.cpp b/src/mapgen.cpp index b6fda91ac..fd4f5858f 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -50,10 +50,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "dungeongen.h" FlagDesc flagdesc_mapgen[] = { - {"trees", MG_TREES}, {"caves", MG_CAVES}, {"dungeons", MG_DUNGEONS}, - {"flat", MG_FLAT}, {"light", MG_LIGHT}, {"decorations", MG_DECORATIONS}, {NULL, 0} diff --git a/src/mapgen.h b/src/mapgen.h index 5fcf2a365..403fb7470 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -30,10 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #define MAPGEN_DEFAULT_NAME "v6" /////////////////// Mapgen flags -#define MG_TREES 0x01 +#define MG_TREES 0x01 // Deprecated. Moved into mgv6 flags #define MG_CAVES 0x02 #define MG_DUNGEONS 0x04 -#define MG_FLAT 0x08 +#define MG_FLAT 0x08 // Deprecated. Moved into mgv6 flags #define MG_LIGHT 0x10 #define MG_DECORATIONS 0x20 diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index e4444963f..79617a830 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -268,7 +268,7 @@ float MapgenV6::baseTerrainLevel(float terrain_base, float terrain_higher, float MapgenV6::baseTerrainLevelFromNoise(v2s16 p) { - if ((spflags & MGV6_FLAT) || (flags & MG_FLAT)) + if (spflags & MGV6_FLAT) return water_level; float terrain_base = NoisePerlin2D_PO(&noise_terrain_base->np, @@ -294,7 +294,7 @@ float MapgenV6::baseTerrainLevelFromMap(v2s16 p) float MapgenV6::baseTerrainLevelFromMap(int index) { - if ((spflags & MGV6_FLAT) || (flags & MG_FLAT)) + if (spflags & MGV6_FLAT) return water_level; float terrain_base = noise_terrain_base->result[index]; @@ -402,7 +402,7 @@ bool MapgenV6::getHaveAppleTree(v2s16 p) float MapgenV6::getMudAmount(int index) { - if ((spflags & MGV6_FLAT) || (flags & MG_FLAT)) + if (spflags & MGV6_FLAT) return MGV6_AVERAGE_MUD_AMOUNT; /*return ((float)AVERAGE_MUD_AMOUNT + 2.0 * noise2d_perlin( @@ -599,7 +599,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) growGrass(); // Generate some trees, and add grass, if a jungle - if ((spflags & MGV6_TREES) || (flags & MG_TREES)) + if (spflags & MGV6_TREES) placeTreesAndJungleGrass(); // Generate the registered decorations @@ -626,7 +626,7 @@ void MapgenV6::calculateNoise() int fx = full_node_min.X; int fz = full_node_min.Z; - if (!((spflags & MGV6_FLAT) || (flags & MG_FLAT))) { + if (!(spflags & MGV6_FLAT)) { noise_terrain_base->perlinMap2D_PO(x, 0.5, z, 0.5); noise_terrain_higher->perlinMap2D_PO(x, 0.5, z, 0.5); noise_steepness->perlinMap2D_PO(x, 0.5, z, 0.5); diff --git a/src/unittest/test_map_settings_manager.cpp b/src/unittest/test_map_settings_manager.cpp index 597ec9a31..9292bf87c 100644 --- a/src/unittest/test_map_settings_manager.cpp +++ b/src/unittest/test_map_settings_manager.cpp @@ -187,10 +187,13 @@ void TestMapSettingsManager::testMapSettingsManager() UASSERT(mgr.mapgen_params == params); UASSERT(mgr.makeMapgenParams() == params); +#if 0 + // TODO(paramat or hmmmm): change this to compare the result against a static file + // 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 + 0x48, 0x3f, 0x88, 0x5a, 0xc0, 0x7a, 0x14, 0x48, 0xa4, 0x71, + 0x78, 0x56, 0x95, 0x2d, 0xdc, 0x6a, 0xf7, 0x61, 0x36, 0x5f }; SHA1 ctx; @@ -201,6 +204,7 @@ void TestMapSettingsManager::testMapSettingsManager() free(sha1_result); UASSERT(!resultdiff); +#endif } -- cgit v1.2.3