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;
// 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)
{
}
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);
}
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);
}
// 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 &&
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);
- }
- }
-}