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_v5.cpp | 46 ++++++++++++---------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) (limited to 'src/mapgen_v5.cpp') diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp index b98acb928..829a1f432 100644 --- a/src/mapgen_v5.cpp +++ b/src/mapgen_v5.cpp @@ -57,10 +57,7 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) // 1-down overgeneration this->zstride_1d = csize.X * (csize.Y + 1); - this->biomemap = new u8[csize.X * csize.Z]; this->heightmap = new s16[csize.X * csize.Z]; - this->heatmap = NULL; - this->humidmap = NULL; MapgenV5Params *sp = (MapgenV5Params *)params->sparams; @@ -79,15 +76,12 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge) 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); - // Biome noise - noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z); - noise_humidity = new Noise(¶ms->np_biome_humidity, seed, csize.X, csize.Z); - noise_heat_blend = new Noise(¶ms->np_biome_heat_blend, seed, csize.X, csize.Z); - noise_humidity_blend = new Noise(¶ms->np_biome_humidity_blend, seed, csize.X, csize.Z); + //// Initialize biome generator + biomegen = emerge->biomemgr->createBiomeGen( + BIOMEGEN_ORIGINAL, params->bparams, csize); + biomemap = biomegen->biomemap; //// Resolve nodes to be used - INodeDefManager *ndef = emerge->ndef; - c_stone = ndef->getId("mapgen_stone"); c_water_source = ndef->getId("mapgen_water_source"); c_lava_source = ndef->getId("mapgen_lava_source"); @@ -123,13 +117,9 @@ MapgenV5::~MapgenV5() delete noise_cave2; delete noise_ground; - delete noise_heat; - delete noise_humidity; - delete noise_heat_blend; - delete noise_humidity_blend; + delete biomegen; delete[] heightmap; - delete[] biomemap; } @@ -248,12 +238,10 @@ void MapgenV5::makeChunk(BlockMakeData *data) // Create heightmap updateHeightmap(node_min, node_max); - // Create biomemap at heightmap surface - bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result, - noise_humidity->result, heightmap, biomemap); - - // Actually place the biome-specific nodes - MgStoneType stone_type = generateBiomes(noise_heat->result, noise_humidity->result); + // Init biome generator, place biome-specific nodes, and build biomemap + biomegen->calcBiomeNoise(node_min); + biomegen->getBiomes(heightmap); + MgStoneType stone_type = generateBiomes(); // Generate caves if ((flags & MG_CAVES) && (stone_surface_max_y >= node_min.Y)) @@ -343,18 +331,7 @@ void MapgenV5::calculateNoise() // only if solid terrain is present in mapchunk noise_filler_depth->perlinMap2D(x, z); - noise_heat->perlinMap2D(x, z); - noise_humidity->perlinMap2D(x, z); - noise_heat_blend->perlinMap2D(x, z); - noise_humidity_blend->perlinMap2D(x, z); - - for (s32 i = 0; i < csize.X * csize.Z; i++) { - noise_heat->result[i] += noise_heat_blend->result[i]; - noise_humidity->result[i] += noise_humidity_blend->result[i]; - } - heatmap = noise_heat->result; - humidmap = noise_humidity->result; //printf("calculateNoise: %dus\n", t.stop()); } @@ -416,7 +393,7 @@ int MapgenV5::generateBaseTerrain() } -MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map) +MgStoneType MapgenV5::generateBiomes() { v3s16 em = vm->m_area.getExtent(); u32 index = 0; @@ -452,7 +429,8 @@ MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map) // 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 = bmgr->getBiome(heat_map[index], humidity_map[index], y); + biome = biomegen->getBiomeAtIndex(index, y); + depth_top = biome->depth_top; base_filler = MYMAX(depth_top + biome->depth_filler + noise_filler_depth->result[index], 0); -- 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_v5.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_v5.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 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_v5.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_v5.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_v5.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_v5.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 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_v5.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 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_v5.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