Skip to content

Commit

Permalink
Mapgen caves: Re-order generation to fix cavern bug
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
paramat committed Apr 29, 2018
1 parent bb3baef commit 54606e1
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 39 deletions.
13 changes: 9 additions & 4 deletions src/mapgen/mapgen.cpp
Expand Up @@ -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;

CavesNoiseIntersection caves_noise(ndef, m_bmgr, csize,
&np_cave1, &np_cave2, seed, cave_width);

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;

PseudoRandom ps(blockseed + 21343);
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_depth, biomegen);
Expand All @@ -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)
return false;
Expand Down
7 changes: 4 additions & 3 deletions src/mapgen/mapgen.h
Expand Up @@ -238,11 +238,12 @@ class MapgenBasic : public Mapgen {
MapgenBasic(int mapgenid, MapgenParams *params, EmergeManager *emerge);
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 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:
EmergeManager *m_emerge;
Expand Down
21 changes: 13 additions & 8 deletions src/mapgen/mapgen_carpathian.cpp
Expand Up @@ -250,20 +250,25 @@ void MapgenCarpathian::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min);
generateBiomes();

// Generate caverns, tunnels and classic caves
// Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) {
bool has_cavern = false;
// Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);

// Generate caverns
bool near_cavern = false;
if (spflags & MGCARPATHIAN_CAVERNS)
has_cavern = generateCaverns(stone_surface_max_y);
// Generate tunnels and classic caves
if (has_cavern)
// Disable classic caves in this mapchunk by setting
near_cavern = generateCavernsNoise(stone_surface_max_y);

// Generate large randomwalk caves
if (near_cavern)
// Disable large randomwalk 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);
generateCavesRandomWalk(stone_surface_max_y,
-MAX_MAP_GENERATION_LIMIT);
else
generateCaves(stone_surface_max_y, large_cave_depth);
generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
}

// Generate dungeons
Expand Down
8 changes: 6 additions & 2 deletions src/mapgen/mapgen_flat.cpp
Expand Up @@ -198,8 +198,12 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min);
generateBiomes();

if (flags & MG_CAVES)
generateCaves(stone_surface_max_y, large_cave_depth);
if (flags & MG_CAVES) {
// 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 &&
full_node_max.Y <= dungeon_ymax)
Expand Down
8 changes: 6 additions & 2 deletions src/mapgen/mapgen_fractal.cpp
Expand Up @@ -209,8 +209,12 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min);
generateBiomes();

if (flags & MG_CAVES)
generateCaves(stone_surface_max_y, large_cave_depth);
if (flags & MG_CAVES) {
// 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 &&
full_node_max.Y <= dungeon_ymax)
Expand Down
19 changes: 12 additions & 7 deletions src/mapgen/mapgen_v5.cpp
Expand Up @@ -209,20 +209,25 @@ void MapgenV5::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min);
generateBiomes();

// Generate caverns, tunnels and classic caves
// Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) {
bool near_cavern = false;
// Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);

// Generate caverns
bool near_cavern = false;
if (spflags & MGV5_CAVERNS)
near_cavern = generateCaverns(stone_surface_max_y);
// Generate tunnels and classic caves
near_cavern = generateCavernsNoise(stone_surface_max_y);

// Generate large randomwalk caves
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 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
generateCaves(stone_surface_max_y, large_cave_depth);
generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
}

// Generate dungeons and desert temples
Expand Down
19 changes: 12 additions & 7 deletions src/mapgen/mapgen_v7.cpp
Expand Up @@ -313,20 +313,25 @@ void MapgenV7::makeChunk(BlockMakeData *data)
biomegen->calcBiomeNoise(node_min);
generateBiomes();

// Generate caverns, tunnels and classic caves
// Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) {
bool near_cavern = false;
// Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);

// Generate caverns
bool near_cavern = false;
if (spflags & MGV7_CAVERNS)
near_cavern = generateCaverns(stone_surface_max_y);
// Generate tunnels and classic caves
near_cavern = generateCavernsNoise(stone_surface_max_y);

// Generate large randomwalk caves
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 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
generateCaves(stone_surface_max_y, large_cave_depth);
generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
}

// Generate dungeons
Expand Down
17 changes: 11 additions & 6 deletions src/mapgen/mapgen_valleys.cpp
Expand Up @@ -233,18 +233,23 @@ void MapgenValleys::makeChunk(BlockMakeData *data)
// Place biome-specific nodes and build biomemap
generateBiomes();

// Generate caverns, tunnels and classic caves
// Generate tunnels, caverns and large randomwalk caves
if (flags & MG_CAVES) {
// Generate tunnels first as caverns confuse them
generateCavesNoiseIntersection(stone_surface_max_y);

// Generate caverns
bool near_cavern = generateCaverns(stone_surface_max_y);
// Generate tunnels and classic caves
bool near_cavern = generateCavernsNoise(stone_surface_max_y);

// Generate large randomwalk caves
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 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
generateCaves(stone_surface_max_y, large_cave_depth);
generateCavesRandomWalk(stone_surface_max_y, large_cave_depth);
}

// Dungeon creation
Expand Down

0 comments on commit 54606e1

Please sign in to comment.