mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	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:
		@@ -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);
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -238,11 +238,12 @@ public:
 | 
			
		||||
	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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user