diff --git a/src/mapgen/mapgen_valleys.cpp b/src/mapgen/mapgen_valleys.cpp index af8845615..543d926a5 100644 --- a/src/mapgen/mapgen_valleys.cpp +++ b/src/mapgen/mapgen_valleys.cpp @@ -72,13 +72,15 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenValleysParams *params, EmergeMa spflags = params->spflags; altitude_chill = params->altitude_chill; - large_cave_depth = params->large_cave_depth; - lava_features_lim = rangelim(params->lava_features, 0, 10); - massive_cave_depth = params->massive_cave_depth; river_depth_bed = params->river_depth + 1.f; river_size_factor = params->river_size / 100.f; - water_features_lim = rangelim(params->water_features, 0, 10); + cave_width = params->cave_width; + large_cave_depth = params->large_cave_depth; + lava_depth = params->lava_depth; + cavern_limit = params->cavern_limit; + cavern_taper = params->cavern_taper; + cavern_threshold = params->cavern_threshold; dungeon_ymin = params->dungeon_ymin; dungeon_ymax = params->dungeon_ymax; @@ -94,50 +96,39 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenValleysParams *params, EmergeMa // 1-up 1-down overgeneration 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(¶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); + MapgenBasic::np_cave1 = params->np_cave1; + MapgenBasic::np_cave2 = params->np_cave2; + MapgenBasic::np_cavern = params->np_cavern; humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS); use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL); humidity_adjust = bp->np_humidity.offset - 50.f; - - // a small chance of overflows if the settings are very high - cave_water_max_height = water_level + MYMAX(0, water_features_lim - 4) * 50; - lava_max_height = water_level + MYMAX(0, lava_features_lim - 4) * 50; - - tcave_cache = new float[csize.Y + 2]; } MapgenValleys::~MapgenValleys() { - delete noise_cave1; - delete noise_cave2; delete noise_filler_depth; delete noise_inter_valley_fill; delete noise_inter_valley_slope; delete noise_rivers; - delete noise_massive_caves; delete noise_terrain_height; delete noise_valley_depth; delete noise_valley_profile; - - delete[] tcave_cache; } MapgenValleysParams::MapgenValleysParams(): - np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), - np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), np_filler_depth (0.f, 1.2f, v3f(256, 256, 256), 1605, 3, 0.5f, 2.f), np_inter_valley_fill (0.f, 1.f, v3f(256, 512, 256), 1993, 6, 0.8f, 2.f), np_inter_valley_slope (0.5f, 0.5f, v3f(128, 128, 128), 746, 1, 1.f, 2.f), np_rivers (0.f, 1.f, v3f(256, 256, 256), -6050, 5, 0.6f, 2.f), - np_massive_caves (0.f, 1.f, v3f(768, 256, 768), 59033, 6, 0.63f, 2.f), np_terrain_height (-10.f, 50.f, v3f(1024, 1024, 1024), 5202, 6, 0.4f, 2.f), np_valley_depth (5.f, 4.f, v3f(512, 512, 512), -1914, 1, 1.f, 2.f), - np_valley_profile (0.6f, 0.5f, v3f(512, 512, 512), 777, 1, 1.f, 2.f) + np_valley_profile (0.6f, 0.5f, v3f(512, 512, 512), 777, 1, 1.f, 2.f), + np_cave1 (0, 12, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), + np_cave2 (0, 12, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), + np_cavern (0.f, 1.f, v3f(768, 256, 768), 59033, 6, 0.63f, 2.f) { } @@ -147,25 +138,27 @@ void MapgenValleysParams::readParams(const Settings *settings) settings->getFlagStrNoEx("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys); settings->getU16NoEx("mgvalleys_altitude_chill", altitude_chill); settings->getS16NoEx("mgvalleys_large_cave_depth", large_cave_depth); - settings->getU16NoEx("mgvalleys_lava_features", lava_features); - settings->getS16NoEx("mgvalleys_massive_cave_depth", massive_cave_depth); + settings->getS16NoEx("mgvalleys_lava_depth", lava_depth); settings->getU16NoEx("mgvalleys_river_depth", river_depth); settings->getU16NoEx("mgvalleys_river_size", river_size); - settings->getU16NoEx("mgvalleys_water_features", water_features); settings->getFloatNoEx("mgvalleys_cave_width", cave_width); + settings->getS16NoEx("mgvalleys_cavern_limit", cavern_limit); + settings->getS16NoEx("mgvalleys_cavern_taper", cavern_taper); + settings->getFloatNoEx("mgvalleys_cavern_threshold", cavern_threshold); settings->getS16NoEx("mgvalleys_dungeon_ymin", dungeon_ymin); settings->getS16NoEx("mgvalleys_dungeon_ymax", dungeon_ymax); - settings->getNoiseParams("mgvalleys_np_cave1", np_cave1); - settings->getNoiseParams("mgvalleys_np_cave2", np_cave2); settings->getNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); settings->getNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); settings->getNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); settings->getNoiseParams("mgvalleys_np_rivers", np_rivers); - settings->getNoiseParams("mgvalleys_np_massive_caves", np_massive_caves); settings->getNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); settings->getNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); settings->getNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); + + settings->getNoiseParams("mgvalleys_np_cave1", np_cave1); + settings->getNoiseParams("mgvalleys_np_cave2", np_cave2); + settings->getNoiseParams("mgvalleys_np_cavern", np_cavern); } @@ -174,25 +167,27 @@ void MapgenValleysParams::writeParams(Settings *settings) const settings->setFlagStr("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX); settings->setU16("mgvalleys_altitude_chill", altitude_chill); settings->setS16("mgvalleys_large_cave_depth", large_cave_depth); - settings->setU16("mgvalleys_lava_features", lava_features); - settings->setS16("mgvalleys_massive_cave_depth", massive_cave_depth); + settings->setS16("mgvalleys_lava_depth", lava_depth); settings->setU16("mgvalleys_river_depth", river_depth); settings->setU16("mgvalleys_river_size", river_size); - settings->setU16("mgvalleys_water_features", water_features); settings->setFloat("mgvalleys_cave_width", cave_width); + settings->setS16("mgvalleys_cavern_limit", cavern_limit); + settings->setS16("mgvalleys_cavern_taper", cavern_taper); + settings->setFloat("mgvalleys_cavern_threshold", cavern_threshold); settings->setS16("mgvalleys_dungeon_ymin", dungeon_ymin); settings->setS16("mgvalleys_dungeon_ymax", dungeon_ymax); - settings->setNoiseParams("mgvalleys_np_cave1", np_cave1); - settings->setNoiseParams("mgvalleys_np_cave2", np_cave2); settings->setNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); settings->setNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); settings->setNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); settings->setNoiseParams("mgvalleys_np_rivers", np_rivers); - settings->setNoiseParams("mgvalleys_np_massive_caves", np_massive_caves); settings->setNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); settings->setNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); settings->setNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); + + settings->setNoiseParams("mgvalleys_np_cave1", np_cave1); + settings->setNoiseParams("mgvalleys_np_cave2", np_cave2); + settings->setNoiseParams("mgvalleys_np_cavern", np_cavern); } @@ -244,9 +239,20 @@ void MapgenValleys::makeChunk(BlockMakeData *data) // Place biome-specific nodes and build biomemap generateBiomes(); - // Cave creation. - if (flags & MG_CAVES) - generateCaves(stone_surface_max_y, large_cave_depth); + // Generate caverns, tunnels and classic caves + if (flags & MG_CAVES) { + bool near_cavern = false; + // Generate caverns + near_cavern = generateCaverns(stone_surface_max_y); + // Generate tunnels and classic caves + if (near_cavern) + // Disable classic caves in this mapchunk by setting + // 'large cave depth' to world base. Avoids excessive liquid in + // large caverns and floating blobs of overgenerated liquid. + generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); + else + generateCaves(stone_surface_max_y, large_cave_depth); + } // Dungeon creation if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && @@ -587,165 +593,3 @@ int MapgenValleys::generateTerrain() return surface_max_y; } - -void MapgenValleys::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); - - PseudoRandom ps(blockseed + 72202); - - MapNode n_air(CONTENT_AIR); - MapNode n_lava(c_lava_source); - MapNode n_water(c_river_water_source); - - const v3s16 &em = vm->m_area.getExtent(); - - // Cave blend distance near YMIN, YMAX - const float massive_cave_blend = 128.f; - // noise threshold for massive caves - const float massive_cave_threshold = 0.6f; - // mct: 1 = small rare caves, 0.5 1/3rd ground volume, 0 = 1/2 ground volume. - - float yblmin = -mapgen_limit + massive_cave_blend * 1.5f; - float yblmax = massive_cave_depth - massive_cave_blend * 1.5f; - bool made_a_big_one = false; - - // Cache the tcave values as they only vary by altitude. - if (node_max.Y <= massive_cave_depth) { - noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - - for (s16 y = node_min.Y - 1; y <= node_max.Y; y++) { - float tcave = massive_cave_threshold; - - if (y < yblmin) { - float t = (yblmin - y) / massive_cave_blend; - tcave += MYSQUARE(t); - } else if (y > yblmax) { - float t = (y - yblmax) / massive_cave_blend; - tcave += MYSQUARE(t); - } - - tcave_cache[y - node_min.Y + 1] = tcave; - } - } - - // lava_depth varies between one and ten as you approach - // the bottom of the world. - s16 lava_depth = std::ceil((lava_max_height - node_min.Y + 1) * 10.f / mapgen_limit); - // This allows random lava spawns to be less common at the surface. - s16 lava_chance = MYCUBE(lava_features_lim) * lava_depth; - // water_depth varies between ten and one on the way down. - s16 water_depth = std::ceil((mapgen_limit - std::abs(node_min.Y) + 1) * 10.f / - mapgen_limit); - // This allows random water spawns to be more common at the surface. - s16 water_chance = MYCUBE(water_features_lim) * water_depth; - - // Reduce the odds of overflows even further. - if (node_max.Y > water_level) { - lava_chance /= 3; - water_chance /= 3; - } - - 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 *)m_bmgr->getRaw(biomemap[index_2d]); - bool tunnel_air_above = false; - bool is_under_river = false; - bool underground = false; - u32 index_data = vm->m_area.index(x, node_max.Y, z); - u32 index_3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X); - - // Dig caves on down loop to check for air above. - // 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--, - index_3d -= ystride, - VoxelArea::add_y(em, index_data, -1)) { - - float terrain = noise_terrain_height->result[index_2d]; - - // Saves some time. - if (y > terrain + 10) - continue; - - if (y < terrain - 40) - underground = true; - - // Dig massive caves. - if (node_max.Y <= massive_cave_depth - && noise_massive_caves->result[index_3d] - > tcave_cache[y - node_min.Y + 1]) { - vm->m_data[index_data] = n_air; - made_a_big_one = true; - continue; - } - - content_t c = vm->m_data[index_data].getContent(); - // Detect river water to place riverbed nodes in tunnels - if (c == biome->c_river_water) - is_under_river = true; - - float d1 = contour(noise_cave1->result[index_3d]); - float d2 = contour(noise_cave2->result[index_3d]); - - if (d1 * d2 > cave_width && ndef->get(c).is_ground_content) { - // in a tunnel - vm->m_data[index_data] = n_air; - tunnel_air_above = true; - } else if (c == biome->c_filler || c == biome->c_stone) { - if (tunnel_air_above) { - // at the tunnel floor - s16 sr = ps.range(0, 39); - u32 j = index_data; - VoxelArea::add_y(em, j, 1); - - if (sr > terrain - y) { - // Put biome nodes in tunnels near the surface - if (is_under_river) - vm->m_data[index_data] = MapNode(biome->c_riverbed); - else if (underground) - vm->m_data[index_data] = MapNode(biome->c_filler); - else - vm->m_data[index_data] = MapNode(biome->c_top); - } else if (sr < 3 && underground) { - sr = abs(ps.next()); - if (lava_features_lim > 0 && y <= lava_max_height - && c == biome->c_stone && sr < lava_chance) - vm->m_data[j] = n_lava; - - sr -= lava_chance; - - // If sr < 0 then we should have already placed lava -- - // don't immediately dump water on it. - if (water_features_lim > 0 && y <= cave_water_max_height - && sr >= 0 && sr < water_chance) - vm->m_data[j] = n_water; - } - } - - tunnel_air_above = false; - underground = true; - } else { - tunnel_air_above = false; - } - } - } - - if (node_max.Y <= large_cave_depth && !made_a_big_one) { - u32 bruises_count = ps.range(0, 2); - for (u32 i = 0; i < bruises_count; i++) { - CavesRandomWalk cave(ndef, &gennotify, seed, water_level, - c_water_source, c_lava_source, lava_max_height, biomegen); - - cave.makeCave(vm, node_min, node_max, &ps, true, max_stone_y, - heightmap); - } - } -} diff --git a/src/mapgen/mapgen_valleys.h b/src/mapgen/mapgen_valleys.h index b44439030..c4d92239c 100644 --- a/src/mapgen/mapgen_valleys.h +++ b/src/mapgen/mapgen_valleys.h @@ -46,28 +46,31 @@ class BiomeGenOriginal; struct MapgenValleysParams : public MapgenParams { u32 spflags = MGVALLEYS_HUMID_RIVERS | MGVALLEYS_ALT_CHILL; - s16 large_cave_depth = -33; - s16 massive_cave_depth = -256; // highest altitude of massive caves u16 altitude_chill = 90; // The altitude at which temperature drops by 20C. - u16 lava_features = 0; // How often water will occur in caves. u16 river_depth = 4; // How deep to carve river channels. u16 river_size = 5; // How wide to make rivers. - u16 water_features = 0; // How often water will occur in caves. + float cave_width = 0.09f; + s16 large_cave_depth = -33; + s16 lava_depth = 1; + s16 cavern_limit = -256; + s16 cavern_taper = 192; + float cavern_threshold = 0.6f; s16 dungeon_ymin = -31000; s16 dungeon_ymax = 63; // No higher than surface mapchunks - NoiseParams np_cave1; - NoiseParams np_cave2; NoiseParams np_filler_depth; NoiseParams np_inter_valley_fill; NoiseParams np_inter_valley_slope; NoiseParams np_rivers; - NoiseParams np_massive_caves; NoiseParams np_terrain_height; NoiseParams np_valley_depth; NoiseParams np_valley_profile; + NoiseParams np_cave1; + NoiseParams np_cave2; + NoiseParams np_cavern; + MapgenValleysParams(); ~MapgenValleysParams() = default; @@ -97,33 +100,23 @@ public: virtual void makeChunk(BlockMakeData *data); int getSpawnLevelAtPoint(v2s16 p); - s16 large_cave_depth; - private: BiomeGenOriginal *m_bgen; float altitude_chill; - s16 massive_cave_depth; - s16 dungeon_ymin; - s16 dungeon_ymax; - bool humid_rivers; bool use_altitude_chill; float humidity_adjust; - s16 cave_water_max_height; - s16 lava_max_height; - s16 lava_features_lim; float river_depth_bed; float river_size_factor; - float *tcave_cache; - s16 water_features_lim; + + s16 large_cave_depth; + s16 dungeon_ymin; + s16 dungeon_ymax; 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; Noise *noise_valley_profile; @@ -135,6 +128,4 @@ private: virtual int generateTerrain(); float terrainLevelFromNoise(TerrainNoise *tn); float adjustedTerrainLevelFromNoise(TerrainNoise *tn); - - virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth); };