Mapgen caves: Re-order generation to fix cavern bug

Previously, caverns confused tunnel generation causing biome top and filler
nodes to appear in caverns.
Split 'generateCaves()' into 2 functions to separate tunnel and large
randomwalk cave generation.
In each mapgen re-order cave generation to generate tunnels before caverns.
This commit is contained in:
Paramat 2018-04-29 07:20:46 +01:00 committed by GitHub
parent bb3baef30f
commit 54606e103d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 73 additions and 39 deletions

@ -824,21 +824,26 @@ void MapgenBasic::dustTopNodes()
} }
void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth) void MapgenBasic::generateCavesNoiseIntersection(s16 max_stone_y)
{ {
if (max_stone_y < node_min.Y) if (node_min.Y > max_stone_y)
return; return;
CavesNoiseIntersection caves_noise(ndef, m_bmgr, csize, CavesNoiseIntersection caves_noise(ndef, m_bmgr, csize,
&np_cave1, &np_cave2, seed, cave_width); &np_cave1, &np_cave2, seed, cave_width);
caves_noise.generateCaves(vm, node_min, node_max, biomemap); caves_noise.generateCaves(vm, node_min, node_max, biomemap);
}
if (node_max.Y > large_cave_depth)
void MapgenBasic::generateCavesRandomWalk(s16 max_stone_y, s16 large_cave_depth)
{
if (node_min.Y > max_stone_y || node_max.Y > large_cave_depth)
return; return;
PseudoRandom ps(blockseed + 21343); PseudoRandom ps(blockseed + 21343);
u32 bruises_count = ps.range(0, 2); u32 bruises_count = ps.range(0, 2);
for (u32 i = 0; i < bruises_count; i++) { for (u32 i = 0; i < bruises_count; i++) {
CavesRandomWalk cave(ndef, &gennotify, seed, water_level, CavesRandomWalk cave(ndef, &gennotify, seed, water_level,
c_water_source, c_lava_source, lava_depth, biomegen); c_water_source, c_lava_source, lava_depth, biomegen);
@ -849,7 +854,7 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth)
} }
bool MapgenBasic::generateCaverns(s16 max_stone_y) bool MapgenBasic::generateCavernsNoise(s16 max_stone_y)
{ {
if (node_min.Y > max_stone_y || node_min.Y > cavern_limit) if (node_min.Y > max_stone_y || node_min.Y > cavern_limit)
return false; return false;

@ -238,11 +238,12 @@ public:
MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge); MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge);
virtual ~MapgenBasic(); virtual ~MapgenBasic();
virtual void generateCaves(s16 max_stone_y, s16 large_cave_depth);
virtual bool generateCaverns(s16 max_stone_y);
virtual void generateDungeons(s16 max_stone_y);
virtual void generateBiomes(); virtual void generateBiomes();
virtual void dustTopNodes(); virtual void dustTopNodes();
virtual void generateCavesNoiseIntersection(s16 max_stone_y);
virtual void generateCavesRandomWalk(s16 max_stone_y, s16 large_cave_depth);
virtual bool generateCavernsNoise(s16 max_stone_y);
virtual void generateDungeons(s16 max_stone_y);
protected: protected:
EmergeManager *m_emerge; EmergeManager *m_emerge;

@ -250,20 +250,25 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min); biomegen->calcBiomeNoise(node_min);
generateBiomes(); generateBiomes();
// Generate caverns, tunnels and classic caves // Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) { if (flags & MG_CAVES) {
bool has_cavern = false; // Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);
// Generate caverns // Generate caverns
bool near_cavern = false;
if (spflags & MGCARPATHIAN_CAVERNS) if (spflags & MGCARPATHIAN_CAVERNS)
has_cavern = generateCaverns(stone_surface_max_y); near_cavern = generateCavernsNoise(stone_surface_max_y);
// Generate tunnels and classic caves
if (has_cavern) // Generate large randomwalk caves
// Disable classic caves in this mapchunk by setting if (near_cavern)
// Disable large randomwalk caves in this mapchunk by setting
// 'large cave depth' to world base. Avoids excessive liquid in // 'large cave depth' to world base. Avoids excessive liquid in
// large caverns and floating blobs of overgenerated liquid. // large caverns and floating blobs of overgenerated liquid.
generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); generateCavesRandomWalk(stone_surface_max_y,
-MAX_MAP_GENERATION_LIMIT);
else else
generateCaves(stone_surface_max_y, large_cave_depth); generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
} }
// Generate dungeons // Generate dungeons

@ -198,8 +198,12 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min); biomegen->calcBiomeNoise(node_min);
generateBiomes(); generateBiomes();
if (flags & MG_CAVES) if (flags & MG_CAVES) {
generateCaves(stone_surface_max_y, large_cave_depth); // Generate tunnels
generateCavesNoiseIntersection(stone_surface_max_y);
// Generate large randomwalk caves
generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
}
if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
full_node_max.Y <= dungeon_ymax) full_node_max.Y <= dungeon_ymax)

@ -209,8 +209,12 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min); biomegen->calcBiomeNoise(node_min);
generateBiomes(); generateBiomes();
if (flags & MG_CAVES) if (flags & MG_CAVES) {
generateCaves(stone_surface_max_y, large_cave_depth); // Generate tunnels
generateCavesNoiseIntersection(stone_surface_max_y);
// Generate large randomwalk caves
generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
}
if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin &&
full_node_max.Y <= dungeon_ymax) full_node_max.Y <= dungeon_ymax)

@ -209,20 +209,25 @@ void MapgenV5::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min); biomegen->calcBiomeNoise(node_min);
generateBiomes(); generateBiomes();
// Generate caverns, tunnels and classic caves // Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) { if (flags & MG_CAVES) {
bool near_cavern = false; // Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);
// Generate caverns // Generate caverns
bool near_cavern = false;
if (spflags & MGV5_CAVERNS) if (spflags & MGV5_CAVERNS)
near_cavern = generateCaverns(stone_surface_max_y); near_cavern = generateCavernsNoise(stone_surface_max_y);
// Generate tunnels and classic caves
// Generate large randomwalk caves
if (near_cavern) if (near_cavern)
// Disable classic caves in this mapchunk by setting // Disable large randomwalk caves in this mapchunk by setting
// 'large cave depth' to world base. Avoids excessive liquid in // 'large cave depth' to world base. Avoids excessive liquid in
// large caverns and floating blobs of overgenerated liquid. // large caverns and floating blobs of overgenerated liquid.
generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); generateCavesRandomWalk(stone_surface_max_y,
-MAX_MAP_GENERATION_LIMIT);
else else
generateCaves(stone_surface_max_y, large_cave_depth); generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
} }
// Generate dungeons and desert temples // Generate dungeons and desert temples

@ -313,20 +313,25 @@ void MapgenV7::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min); biomegen->calcBiomeNoise(node_min);
generateBiomes(); generateBiomes();
// Generate caverns, tunnels and classic caves // Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) { if (flags & MG_CAVES) {
bool near_cavern = false; // Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);
// Generate caverns // Generate caverns
bool near_cavern = false;
if (spflags & MGV7_CAVERNS) if (spflags & MGV7_CAVERNS)
near_cavern = generateCaverns(stone_surface_max_y); near_cavern = generateCavernsNoise(stone_surface_max_y);
// Generate tunnels and classic caves
// Generate large randomwalk caves
if (near_cavern) if (near_cavern)
// Disable classic caves in this mapchunk by setting // Disable large randomwalk caves in this mapchunk by setting
// 'large cave depth' to world base. Avoids excessive liquid in // 'large cave depth' to world base. Avoids excessive liquid in
// large caverns and floating blobs of overgenerated liquid. // large caverns and floating blobs of overgenerated liquid.
generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); generateCavesRandomWalk(stone_surface_max_y,
-MAX_MAP_GENERATION_LIMIT);
else else
generateCaves(stone_surface_max_y, large_cave_depth); generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
} }
// Generate dungeons // Generate dungeons

@ -233,18 +233,23 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
// Place biome-specific nodes and build biomemap // Place biome-specific nodes and build biomemap
generateBiomes(); generateBiomes();
// Generate caverns, tunnels and classic caves // Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) { if (flags & MG_CAVES) {
// Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);
// Generate caverns // Generate caverns
bool near_cavern = generateCaverns(stone_surface_max_y); bool near_cavern = generateCavernsNoise(stone_surface_max_y);
// Generate tunnels and classic caves
// Generate large randomwalk caves
if (near_cavern) if (near_cavern)
// Disable classic caves in this mapchunk by setting // Disable large randomwalk caves in this mapchunk by setting
// 'large cave depth' to world base. Avoids excessive liquid in // 'large cave depth' to world base. Avoids excessive liquid in
// large caverns and floating blobs of overgenerated liquid. // large caverns and floating blobs of overgenerated liquid.
generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); generateCavesRandomWalk(stone_surface_max_y,
-MAX_MAP_GENERATION_LIMIT);
else else
generateCaves(stone_surface_max_y, large_cave_depth); generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
} }
// Dungeon creation // Dungeon creation