mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Mapgen V7: Huge rewrite, also tweaks to cavegen et al.
This commit is contained in:
		@@ -43,9 +43,9 @@ BiomeDefManager::BiomeDefManager() {
 | 
			
		||||
	b->flags = 0;
 | 
			
		||||
 | 
			
		||||
	b->c_top         = CONTENT_AIR;
 | 
			
		||||
	b->top_depth     = 0;
 | 
			
		||||
	b->c_filler      = b->c_top;
 | 
			
		||||
	b->filler_height = MAP_GENERATION_LIMIT;
 | 
			
		||||
	b->depth_top     = 0;
 | 
			
		||||
	b->c_filler      = CONTENT_AIR;
 | 
			
		||||
	b->depth_filler  = 0;
 | 
			
		||||
 | 
			
		||||
	b->height_min     = -MAP_GENERATION_LIMIT;
 | 
			
		||||
	b->height_max     = MAP_GENERATION_LIMIT;
 | 
			
		||||
@@ -101,27 +101,42 @@ void BiomeDefManager::resolveNodeNames(INodeDefManager *ndef) {
 | 
			
		||||
	
 | 
			
		||||
	biome_registration_finished = true;
 | 
			
		||||
	
 | 
			
		||||
	for (size_t i = 0; i != biomes.size(); i++) {
 | 
			
		||||
	for (size_t i = 1; i < biomes.size(); i++) {
 | 
			
		||||
		b = biomes[i];
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		b->c_top = ndef->getId(b->nname_top);
 | 
			
		||||
		if (b->c_top == CONTENT_IGNORE) {
 | 
			
		||||
			b->c_top = ndef->getId(b->top_nodename);
 | 
			
		||||
			if (b->c_top == CONTENT_IGNORE) {
 | 
			
		||||
				errorstream << "BiomeDefManager::resolveNodeNames: node '"
 | 
			
		||||
					<< b->top_nodename << "' not defined" << std::endl;
 | 
			
		||||
				b->c_top = CONTENT_AIR;
 | 
			
		||||
				b->top_depth = 0;
 | 
			
		||||
			}
 | 
			
		||||
			errorstream << "BiomeDefManager::resolveNodeNames: node '"
 | 
			
		||||
				<< b->nname_top << "' not defined" << std::endl;
 | 
			
		||||
			b->c_top     = CONTENT_AIR;
 | 
			
		||||
			b->depth_top = 0;
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
		b->c_filler = ndef->getId(b->nname_filler);
 | 
			
		||||
		if (b->c_filler == CONTENT_IGNORE) {
 | 
			
		||||
			errorstream << "BiomeDefManager::resolveNodeNames: node '"
 | 
			
		||||
				<< b->nname_filler << "' not defined" << std::endl;
 | 
			
		||||
			b->c_filler     = CONTENT_AIR;
 | 
			
		||||
			b->depth_filler = 0;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (b->c_filler == CONTENT_IGNORE) {
 | 
			
		||||
			b->c_filler = ndef->getId(b->filler_nodename);
 | 
			
		||||
			if (b->c_filler == CONTENT_IGNORE) {
 | 
			
		||||
				errorstream << "BiomeDefManager::resolveNodeNames: node '"
 | 
			
		||||
					<< b->filler_nodename << "' not defined" << std::endl;
 | 
			
		||||
				b->c_filler = CONTENT_AIR;
 | 
			
		||||
				b->filler_height = MAP_GENERATION_LIMIT;
 | 
			
		||||
			}
 | 
			
		||||
		b->c_water = ndef->getId(b->nname_water);
 | 
			
		||||
		if (b->c_water == CONTENT_IGNORE) {
 | 
			
		||||
			errorstream << "BiomeDefManager::resolveNodeNames: node '"
 | 
			
		||||
				<< b->nname_water << "' not defined" << std::endl;
 | 
			
		||||
			b->c_water = CONTENT_AIR;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		b->c_dust = ndef->getId(b->nname_dust);
 | 
			
		||||
		if (b->c_dust == CONTENT_IGNORE) {
 | 
			
		||||
			errorstream << "BiomeDefManager::resolveNodeNames: node '"
 | 
			
		||||
				<< b->nname_dust << "' not defined" << std::endl;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		b->c_dust_water = ndef->getId(b->nname_dust_water);
 | 
			
		||||
		if (b->c_dust_water == CONTENT_IGNORE) {
 | 
			
		||||
			errorstream << "BiomeDefManager::resolveNodeNames: node '"
 | 
			
		||||
				<< b->nname_dust_water << "' not defined" << std::endl;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								src/biome.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/biome.h
									
									
									
									
									
								
							@@ -45,14 +45,20 @@ public:
 | 
			
		||||
	std::string name;
 | 
			
		||||
	u32 flags;
 | 
			
		||||
	
 | 
			
		||||
	std::string top_nodename;
 | 
			
		||||
	std::string filler_nodename;
 | 
			
		||||
	std::string nname_top;
 | 
			
		||||
	std::string nname_filler;
 | 
			
		||||
	std::string nname_water;
 | 
			
		||||
	std::string nname_dust;
 | 
			
		||||
	std::string nname_dust_water;
 | 
			
		||||
 | 
			
		||||
	content_t c_top;
 | 
			
		||||
	s16 top_depth;
 | 
			
		||||
 | 
			
		||||
	content_t c_filler;
 | 
			
		||||
	s16 filler_height;
 | 
			
		||||
	content_t c_water;
 | 
			
		||||
	content_t c_dust;
 | 
			
		||||
	content_t c_dust_water;
 | 
			
		||||
	
 | 
			
		||||
	s16 depth_top;
 | 
			
		||||
	s16 depth_filler;
 | 
			
		||||
	
 | 
			
		||||
	s16 height_min;
 | 
			
		||||
	s16 height_max;
 | 
			
		||||
 
 | 
			
		||||
@@ -275,6 +275,7 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
 | 
			
		||||
	this->ps = ps;
 | 
			
		||||
	this->c_water_source = mg->c_water_source;
 | 
			
		||||
	this->c_lava_source  = mg->c_lava_source;
 | 
			
		||||
	this->c_ice          = mg->c_ice;
 | 
			
		||||
	this->np_caveliquids = &nparams_caveliquids;
 | 
			
		||||
 | 
			
		||||
	dswitchint = ps->range(1, 14);
 | 
			
		||||
@@ -454,8 +455,9 @@ void CaveV7::makeTunnel(bool dirswitch) {
 | 
			
		||||
	bool randomize_xz = (ps->range(1, 2) == 1);
 | 
			
		||||
 | 
			
		||||
	// Make a ravine every once in a while if it's long enough
 | 
			
		||||
	float xylen = vec.X * vec.X + vec.Z * vec.Z;
 | 
			
		||||
	bool is_ravine = (xylen > 500.0) && !large_cave && (ps->range(1, 8) == 1);
 | 
			
		||||
	//float xylen = vec.X * vec.X + vec.Z * vec.Z;
 | 
			
		||||
	//disable ravines for now
 | 
			
		||||
	bool is_ravine = false; //(xylen > 500.0) && !large_cave && (ps->range(1, 8) == 1);
 | 
			
		||||
 | 
			
		||||
	// Carve routes
 | 
			
		||||
	for (float f = 0; f < 1.0; f += 1.0 / veclen)
 | 
			
		||||
@@ -490,6 +492,7 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
 | 
			
		||||
	bool should_make_cave_hole = ps->range(1, 10) == 1;
 | 
			
		||||
	
 | 
			
		||||
	for (s16 z0 = d0; z0 <= d1; z0++) {
 | 
			
		||||
		s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
 | 
			
		||||
@@ -513,10 +516,10 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
 | 
			
		||||
				v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
 | 
			
		||||
				p += of;
 | 
			
		||||
				
 | 
			
		||||
				if (!is_ravine && mg->heightmap) {
 | 
			
		||||
				if (!is_ravine && mg->heightmap && should_make_cave_hole) {
 | 
			
		||||
					int maplen = node_max.X - node_min.X + 1;
 | 
			
		||||
					int idx = (p.Z - node_min.Z) * maplen + (p.X - node_min.X);
 | 
			
		||||
					if (p.Y >= mg->heightmap[idx])
 | 
			
		||||
					if (p.Y >= mg->heightmap[idx] - 2)
 | 
			
		||||
						continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@@ -525,9 +528,10 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
 | 
			
		||||
 | 
			
		||||
				u32 i = vm->m_area.index(p);
 | 
			
		||||
				
 | 
			
		||||
				// Don't replace air or water or lava
 | 
			
		||||
				// Don't replace air, water, lava, or ice
 | 
			
		||||
				content_t c = vm->m_data[i].getContent();
 | 
			
		||||
				if (c == CONTENT_AIR || c == c_water_source || c == c_lava_source)
 | 
			
		||||
				if (c == CONTENT_AIR   || c == c_water_source ||
 | 
			
		||||
					c == c_lava_source || c == c_ice)
 | 
			
		||||
					continue;
 | 
			
		||||
					
 | 
			
		||||
				if (large_cave) {
 | 
			
		||||
@@ -541,6 +545,9 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
 | 
			
		||||
					else
 | 
			
		||||
						vm->m_data[i] = airnode;
 | 
			
		||||
				} else {
 | 
			
		||||
					if (c == CONTENT_IGNORE)
 | 
			
		||||
						continue;
 | 
			
		||||
					
 | 
			
		||||
					vm->m_data[i] = airnode;
 | 
			
		||||
					vm->m_flags[i] |= VMANIP_FLAG_CAVE;
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,7 @@ public:
 | 
			
		||||
	
 | 
			
		||||
	content_t c_water_source;
 | 
			
		||||
	content_t c_lava_source;
 | 
			
		||||
	content_t c_ice;
 | 
			
		||||
	
 | 
			
		||||
	int water_level;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -235,12 +235,15 @@ void set_default_settings(Settings *settings)
 | 
			
		||||
	settings->setDefault("mgv6_np_trees",          "0, 1, (125, 125, 125), 2, 4, 0.66");
 | 
			
		||||
	settings->setDefault("mgv6_np_apple_trees",    "0, 1, (100, 100, 100), 342902, 3, 0.45");
 | 
			
		||||
 | 
			
		||||
	settings->setDefault("mgv7_np_terrain_base",     "0, 80, (250, 250, 250), 82341, 5, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_terrain_alt",      "0, 20, (250, 250, 250), 5934, 5, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_terrain_mod",      "0, 1, (350, 350, 350), 85039, 5, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_terrain_persist",  "0, 1, (500, 500, 500), 539, 3, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_height_select",    "0.5, 0.5, (250, 250, 250), 4213, 5, 0.69");
 | 
			
		||||
	settings->setDefault("mgv7_np_ridge",            "0, 1, (100, 100, 100), 6467, 4, 0.75");
 | 
			
		||||
	settings->setDefault("mgv7_np_terrain_base",     "4, 70, (300, 300, 300), 82341, 6, 0.7");
 | 
			
		||||
	settings->setDefault("mgv7_np_terrain_alt",      "4, 25, (600, 600, 600), 5934, 5, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_terrain_persist",  "0.6, 0.1, (500, 500, 500), 539, 3, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_height_select",    "-0.5, 1, (250, 250, 250), 4213, 5, 0.69");
 | 
			
		||||
	settings->setDefault("mgv7_np_filler_depth",     "0, 1.2, (150, 150, 150), 261, 4, 0.7");	
 | 
			
		||||
	settings->setDefault("mgv7_np_mount_height",     "100, 30, (500, 500, 500), 72449, 4, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_ridge_uwater",     "0, 1, (500, 500, 500), 85039, 4, 0.6");
 | 
			
		||||
	settings->setDefault("mgv7_np_mountain",         "0, 1, (250, 350, 250), 5333, 5, 0.68");
 | 
			
		||||
	settings->setDefault("mgv7_np_ridge",            "0, 1, (100, 120, 100), 6467, 4, 0.75");
 | 
			
		||||
 | 
			
		||||
	settings->setDefault("mgindev_np_terrain_base",   "-4,   20,  (250, 250, 250), 82341, 5, 0.6,  10,  10");
 | 
			
		||||
	settings->setDefault("mgindev_np_terrain_higher", "20,   16,  (500, 500, 500), 85039, 5, 0.6,  10,  10");
 | 
			
		||||
 
 | 
			
		||||
@@ -291,7 +291,7 @@ void Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			int height = getHeight();
 | 
			
		||||
			int max_y = nmax.Y + MAP_BLOCKSIZE;
 | 
			
		||||
			int max_y = nmax.Y;// + MAP_BLOCKSIZE - 1;
 | 
			
		||||
			if (y + 1 + height > max_y) {
 | 
			
		||||
				continue;
 | 
			
		||||
#if 0
 | 
			
		||||
@@ -859,9 +859,16 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) {
 | 
			
		||||
	//TimeTaker t("Mapgen::updateHeightmap", NULL, PRECISION_MICRO);
 | 
			
		||||
	int index = 0;
 | 
			
		||||
	for (s16 z = nmin.Z; z <= nmax.Z; z++) {
 | 
			
		||||
		for (s16 x = nmin.X; x <= nmax.X; x++) {
 | 
			
		||||
		for (s16 x = nmin.X; x <= nmax.X; x++, index++) {
 | 
			
		||||
			s16 y = findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y);
 | 
			
		||||
			heightmap[index++] = y;
 | 
			
		||||
 | 
			
		||||
			// if the values found are out of range, trust the old heightmap
 | 
			
		||||
			if (y == nmax.Y && heightmap[index] > nmax.Y)
 | 
			
		||||
				continue;
 | 
			
		||||
			if (y == nmin.Y - 1 && heightmap[index] < nmin.Y)
 | 
			
		||||
				continue;
 | 
			
		||||
				
 | 
			
		||||
			heightmap[index] = y;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//printf("updateHeightmap: %dus\n", t.stop());
 | 
			
		||||
@@ -1060,9 +1067,12 @@ bool MapgenV7Params::readParams(Settings *settings) {
 | 
			
		||||
	bool success = 
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_terrain_base",    np_terrain_base)    &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt)     &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_terrain_mod",     np_terrain_mod)     &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_terrain_persist", np_terrain_persist) &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_height_select",   np_height_select)   &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_filler_depth",    np_filler_depth)    &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_mount_height",    np_mount_height)    &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater)    &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_mountain",        np_mountain)        &&
 | 
			
		||||
		settings->getNoiseParams("mgv7_np_ridge",           np_ridge);
 | 
			
		||||
	return success;
 | 
			
		||||
}
 | 
			
		||||
@@ -1071,9 +1081,12 @@ bool MapgenV7Params::readParams(Settings *settings) {
 | 
			
		||||
void MapgenV7Params::writeParams(Settings *settings) {
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_terrain_base",    np_terrain_base);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_terrain_alt",     np_terrain_alt);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_terrain_mod",     np_terrain_mod);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_terrain_persist", np_terrain_persist);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_height_select",   np_height_select);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_filler_depth",    np_filler_depth);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_mount_height",    np_mount_height);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_ridge_uwater",    np_ridge_uwater);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_mountain",        np_mountain);
 | 
			
		||||
	settings->setNoiseParams("mgv7_np_ridge",           np_ridge);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#define MGV6_BIOME_BLEND 0x10
 | 
			
		||||
#define MG_FLAT          0x20
 | 
			
		||||
#define MG_NOLIGHT       0x40
 | 
			
		||||
#define MGV7_MOUNTAINS   0x80
 | 
			
		||||
#define MGV7_RIDGES      0x100
 | 
			
		||||
 | 
			
		||||
/////////////////// Ore generation flags
 | 
			
		||||
// Use absolute value of height to determine ore placement
 | 
			
		||||
 
 | 
			
		||||
@@ -172,7 +172,6 @@ void MapgenMathParams::writeParams(Settings *settings) {
 | 
			
		||||
MapgenMath::MapgenMath(int mapgenid, MapgenMathParams *params_, EmergeManager *emerge) : MapgenV7(mapgenid, params_, emerge) {
 | 
			
		||||
	mg_params = params_;
 | 
			
		||||
	this->flags |= MG_NOLIGHT;
 | 
			
		||||
	this->ridges = 0;
 | 
			
		||||
 | 
			
		||||
	Json::Value & params = mg_params->params;
 | 
			
		||||
	invert = params["invert"].empty() ? 1 : params["invert"].asBool(); //params["invert"].empty()?1:params["invert"].asBool();
 | 
			
		||||
@@ -238,7 +237,7 @@ MapgenMath::~MapgenMath() {
 | 
			
		||||
 | 
			
		||||
//////////////////////// Map generator
 | 
			
		||||
 | 
			
		||||
void MapgenMath::generateTerrain() {
 | 
			
		||||
int MapgenMath::generateTerrain() {
 | 
			
		||||
 | 
			
		||||
	MapNode n_air(CONTENT_AIR, LIGHT_SUN), n_water_source(c_water_source, LIGHT_SUN);
 | 
			
		||||
	MapNode n_stone(c_stone, LIGHT_SUN);
 | 
			
		||||
@@ -263,9 +262,9 @@ void MapgenMath::generateTerrain() {
 | 
			
		||||
				double d = (*func)(vec.X, vec.Y, vec.Z, distance, iterations);
 | 
			
		||||
				if ((!invert && d > 0) || (invert && d == 0)  ) {
 | 
			
		||||
					if (vm->m_data[i].getContent() == CONTENT_IGNORE)
 | 
			
		||||
						vm->m_data[i] = (y > water_level + biome->filler_height) ?
 | 
			
		||||
						                MapNode(biome->c_filler) : n_stone;
 | 
			
		||||
//						vm->m_data[i] = n_stone;
 | 
			
		||||
	//					vm->m_data[i] = (y > water_level + biome->filler) ?
 | 
			
		||||
		//				                MapNode(biome->c_filler) : n_stone;
 | 
			
		||||
						vm->m_data[i] = n_stone;
 | 
			
		||||
				} else if (y <= water_level) {
 | 
			
		||||
					vm->m_data[i] = n_water_source;
 | 
			
		||||
				} else {
 | 
			
		||||
@@ -361,7 +360,7 @@ void MapgenMath::generateTerrain() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MapgenMath::getGroundLevelAtPoint(v2s16 p) {
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ class MapgenMath : public MapgenV7 {
 | 
			
		||||
		MapgenMath(int mapgenid, MapgenMathParams *mg_params, EmergeManager *emerge);
 | 
			
		||||
		~MapgenMath();
 | 
			
		||||
 | 
			
		||||
		void generateTerrain();
 | 
			
		||||
		int generateTerrain();
 | 
			
		||||
		int getGroundLevelAtPoint(v2s16 p);
 | 
			
		||||
 | 
			
		||||
		bool invert;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,10 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "mapblock.h"
 | 
			
		||||
#include "mapnode.h"
 | 
			
		||||
#include "map.h"
 | 
			
		||||
//#include "serverobject.h"
 | 
			
		||||
#include "content_sao.h"
 | 
			
		||||
#include "nodedef.h"
 | 
			
		||||
#include "content_mapnode.h" // For content_mapnode_get_new_name
 | 
			
		||||
#include "voxelalgorithms.h"
 | 
			
		||||
#include "profiler.h"
 | 
			
		||||
#include "settings.h" // For g_settings
 | 
			
		||||
@@ -42,29 +40,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 | 
			
		||||
/////////////////// Mapgen V7 perlin noise default values
 | 
			
		||||
NoiseParams nparams_v7_def_terrain_base =
 | 
			
		||||
	{0, 80.0, v3f(250.0, 250.0, 250.0), 82341, 5, 0.6};
 | 
			
		||||
	{4, 70, v3f(300, 300, 300), 82341, 6, 0.7};
 | 
			
		||||
NoiseParams nparams_v7_def_terrain_alt =
 | 
			
		||||
	{0, 20.0, v3f(250.0, 250.0, 250.0), 5934, 5, 0.6};
 | 
			
		||||
NoiseParams nparams_v7_def_terrain_mod =
 | 
			
		||||
	{0, 1.0, v3f(350.0, 350.0, 350.0), 85039, 5, 0.6};
 | 
			
		||||
	{4, 25, v3f(600, 600, 600), 5934, 5, 0.6};
 | 
			
		||||
NoiseParams nparams_v7_def_terrain_persist =
 | 
			
		||||
	{0, 1.0, v3f(500.0, 500.0, 500.0), 539, 3, 0.6};
 | 
			
		||||
	{0.6, 0.1, v3f(500, 500, 500), 539, 3, 0.6};
 | 
			
		||||
NoiseParams nparams_v7_def_height_select =
 | 
			
		||||
	{0.5, 0.5, v3f(250.0, 250.0, 250.0), 4213, 5, 0.69};
 | 
			
		||||
	{-0.5, 1, v3f(250, 250, 250), 4213, 5, 0.69};
 | 
			
		||||
	
 | 
			
		||||
NoiseParams nparams_v7_def_filler_depth =
 | 
			
		||||
	{0, 1.2, v3f(150, 150, 150), 261, 4, 0.7};
 | 
			
		||||
 | 
			
		||||
NoiseParams nparams_v7_def_mount_height =
 | 
			
		||||
	{100, 30, v3f(500, 500, 500), 72449, 4, 0.6};	
 | 
			
		||||
NoiseParams nparams_v7_def_ridge_uwater =
 | 
			
		||||
	{0, 1, v3f(500, 500, 500), 85039, 4, 0.6};
 | 
			
		||||
NoiseParams nparams_v7_def_mountain =
 | 
			
		||||
	{0, 1, v3f(250, 350, 250), 5333, 5, 0.68};
 | 
			
		||||
NoiseParams nparams_v7_def_ridge =
 | 
			
		||||
	{0, 1.0, v3f(100.0, 100.0, 100.0), 6467, 4, 0.75};
 | 
			
		||||
/*
 | 
			
		||||
NoiseParams nparams_v6_def_beach =
 | 
			
		||||
	{0.0, 1.0, v3f(250.0, 250.0, 250.0), 59420, 3, 0.50};
 | 
			
		||||
NoiseParams nparams_v6_def_cave =
 | 
			
		||||
	{6.0, 6.0, v3f(250.0, 250.0, 250.0), 34329, 3, 0.50};
 | 
			
		||||
NoiseParams nparams_v6_def_humidity =
 | 
			
		||||
	{0.5, 0.5, v3f(500.0, 500.0, 500.0), 72384, 4, 0.66};
 | 
			
		||||
NoiseParams nparams_v6_def_trees =
 | 
			
		||||
	{0.0, 1.0, v3f(125.0, 125.0, 125.0), 2, 4, 0.66};
 | 
			
		||||
NoiseParams nparams_v6_def_apple_trees =
 | 
			
		||||
	{0.0, 1.0, v3f(100.0, 100.0, 100.0), 342902, 3, 0.45};
 | 
			
		||||
*/
 | 
			
		||||
	{0, 1, v3f(100, 100, 100), 6467, 4, 0.75};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -76,11 +72,14 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
 | 
			
		||||
 | 
			
		||||
	this->seed     = (int)params->seed;
 | 
			
		||||
	this->water_level = params->water_level;
 | 
			
		||||
	this->flags    = params->flags;
 | 
			
		||||
	this->ridges   = 1;
 | 
			
		||||
	this->flags    = params->flags | MGV7_MOUNTAINS | MGV7_RIDGES;
 | 
			
		||||
 | 
			
		||||
	this->csize   = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
 | 
			
		||||
	this->ystride = csize.X; //////fix this
 | 
			
		||||
 | 
			
		||||
	// amount of elements to skip for the next index
 | 
			
		||||
	// for noise/height/biome maps (not vmanip)
 | 
			
		||||
	this->ystride = csize.X;
 | 
			
		||||
	this->zstride = csize.X * csize.Y;
 | 
			
		||||
 | 
			
		||||
	this->biomemap  = new u8[csize.X * csize.Z];
 | 
			
		||||
	this->heightmap = new s16[csize.X * csize.Z];
 | 
			
		||||
@@ -89,10 +88,15 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
 | 
			
		||||
	// Terrain noise
 | 
			
		||||
	noise_terrain_base    = new Noise(¶ms->np_terrain_base,    seed, csize.X, csize.Z);
 | 
			
		||||
	noise_terrain_alt     = new Noise(¶ms->np_terrain_alt,     seed, csize.X, csize.Z);
 | 
			
		||||
	noise_terrain_mod     = new Noise(¶ms->np_terrain_mod,     seed, csize.X, csize.Z);
 | 
			
		||||
	noise_terrain_persist = new Noise(¶ms->np_terrain_persist, seed, csize.X, csize.Z);
 | 
			
		||||
	noise_height_select   = new Noise(¶ms->np_height_select,   seed, csize.X, csize.Z);
 | 
			
		||||
	noise_ridge           = new Noise(¶ms->np_ridge, seed, csize.X, csize.Y, csize.Z);
 | 
			
		||||
	noise_filler_depth    = new Noise(¶ms->np_filler_depth,    seed, csize.X, csize.Z);
 | 
			
		||||
	noise_mount_height    = new Noise(¶ms->np_mount_height,    seed, csize.X, csize.Z);
 | 
			
		||||
	noise_ridge_uwater    = new Noise(¶ms->np_ridge_uwater,    seed, csize.X, csize.Z);
 | 
			
		||||
	
 | 
			
		||||
	// 3d terrain noise
 | 
			
		||||
	noise_mountain = new Noise(¶ms->np_mountain, seed, csize.X, csize.Y, csize.Z);
 | 
			
		||||
	noise_ridge    = new Noise(¶ms->np_ridge,    seed, csize.X, csize.Y, csize.Z);
 | 
			
		||||
	
 | 
			
		||||
	// Biome noise
 | 
			
		||||
	noise_heat     = new Noise(bmgr->np_heat,     seed, csize.X, csize.Z);
 | 
			
		||||
@@ -102,11 +106,15 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
 | 
			
		||||
 | 
			
		||||
MapgenV7::~MapgenV7() {
 | 
			
		||||
	delete noise_terrain_base;
 | 
			
		||||
	delete noise_terrain_mod;
 | 
			
		||||
	delete noise_terrain_persist;
 | 
			
		||||
	delete noise_height_select;
 | 
			
		||||
	delete noise_terrain_alt;
 | 
			
		||||
	delete noise_filler_depth;
 | 
			
		||||
	delete noise_mount_height;
 | 
			
		||||
	delete noise_ridge_uwater;
 | 
			
		||||
	delete noise_mountain;
 | 
			
		||||
	delete noise_ridge;
 | 
			
		||||
 | 
			
		||||
	delete noise_heat;
 | 
			
		||||
	delete noise_humidity;
 | 
			
		||||
	
 | 
			
		||||
@@ -117,25 +125,28 @@ MapgenV7::~MapgenV7() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
 | 
			
		||||
	s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Y);
 | 
			
		||||
	float heat      = NoisePerlin2D(bmgr->np_heat, p.X, p.Y, seed);
 | 
			
		||||
	float humidity  = NoisePerlin2D(bmgr->np_humidity, p.X, p.Y, seed);
 | 
			
		||||
	Biome *b = bmgr->getBiome(heat, humidity, groundlevel);
 | 
			
		||||
	// Base terrain calculation
 | 
			
		||||
	s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
 | 
			
		||||
	
 | 
			
		||||
	s16 y = groundlevel;
 | 
			
		||||
	int iters = 1024; // don't even bother iterating more than 64 times..
 | 
			
		||||
	// Ridge/river terrain calculation
 | 
			
		||||
	float width = 0.3;
 | 
			
		||||
	float uwatern = NoisePerlin2DNoTxfm(noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
 | 
			
		||||
	// actually computing the depth of the ridge is much more expensive;
 | 
			
		||||
	// if inside a river, simply guess
 | 
			
		||||
	if (uwatern >= -width && uwatern <= width)
 | 
			
		||||
		return water_level - 10;
 | 
			
		||||
	
 | 
			
		||||
	// Mountain terrain calculation
 | 
			
		||||
	int iters = 128; // don't even bother iterating more than 128 times..
 | 
			
		||||
	while (iters--) {
 | 
			
		||||
		if (y <= water_level)
 | 
			
		||||
			break;
 | 
			
		||||
		
 | 
			
		||||
		float ridgenoise = NoisePerlin3D(noise_ridge->np, p.X, y, p.Y, seed);
 | 
			
		||||
		if (ridgenoise * (float)(y * y) < 15.0)
 | 
			
		||||
			break;
 | 
			
		||||
		//current point would have been air
 | 
			
		||||
		if (!getMountainTerrainAtPoint(p.X, y, p.Y))
 | 
			
		||||
			return y;
 | 
			
		||||
			
 | 
			
		||||
		y--;
 | 
			
		||||
		y++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return y + b->top_depth;
 | 
			
		||||
	return y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -162,20 +173,6 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
 | 
			
		||||
	full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
 | 
			
		||||
 | 
			
		||||
	blockseed = emerge->getBlockSeed(full_node_min);  //////use getBlockSeed2()!
 | 
			
		||||
 | 
			
		||||
	// Make some noise
 | 
			
		||||
	calculateNoise();
 | 
			
		||||
 | 
			
		||||
	// Calculate height map
 | 
			
		||||
	s16 stone_surface_max_y = calcHeightMap();
 | 
			
		||||
	
 | 
			
		||||
	// Calculate biomes
 | 
			
		||||
	BiomeNoiseInput binput;
 | 
			
		||||
	binput.mapsize       = v2s16(csize.X, csize.Z);
 | 
			
		||||
	binput.heat_map      = noise_heat->result;
 | 
			
		||||
	binput.humidity_map  = noise_humidity->result;
 | 
			
		||||
	binput.height_map    = heightmap;
 | 
			
		||||
	bmgr->calcBiomes(&binput, biomemap);
 | 
			
		||||
	
 | 
			
		||||
	c_stone           = ndef->getId("mapgen_stone");
 | 
			
		||||
	c_dirt            = ndef->getId("mapgen_dirt");
 | 
			
		||||
@@ -183,17 +180,31 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
 | 
			
		||||
	c_sand            = ndef->getId("mapgen_sand");
 | 
			
		||||
	c_water_source    = ndef->getId("mapgen_water_source");
 | 
			
		||||
	c_lava_source     = ndef->getId("mapgen_lava_source");
 | 
			
		||||
	c_ice             = ndef->getId("default:ice");
 | 
			
		||||
	if (c_ice == CONTENT_IGNORE)
 | 
			
		||||
		c_ice = CONTENT_AIR;
 | 
			
		||||
	
 | 
			
		||||
	generateTerrain();
 | 
			
		||||
	if (this->ridges)
 | 
			
		||||
		carveRidges();
 | 
			
		||||
	// Make some noise
 | 
			
		||||
	calculateNoise();
 | 
			
		||||
	
 | 
			
		||||
	// Generate base terrain, mountains, and ridges with initial heightmaps
 | 
			
		||||
	s16 stone_surface_max_y = generateTerrain();
 | 
			
		||||
	
 | 
			
		||||
	updateHeightmap(node_min, node_max);
 | 
			
		||||
	
 | 
			
		||||
	// Calculate biomes
 | 
			
		||||
	BiomeNoiseInput binput;
 | 
			
		||||
	binput.mapsize      = v2s16(csize.X, csize.Z);
 | 
			
		||||
	binput.heat_map     = noise_heat->result;
 | 
			
		||||
	binput.humidity_map = noise_humidity->result;
 | 
			
		||||
	binput.height_map   = heightmap;
 | 
			
		||||
	bmgr->calcBiomes(&binput, biomemap);
 | 
			
		||||
	
 | 
			
		||||
	// Actually place the biome-specific nodes and what not
 | 
			
		||||
	generateBiomes();
 | 
			
		||||
 | 
			
		||||
	if (flags & MG_CAVES)
 | 
			
		||||
		generateCaves(stone_surface_max_y);
 | 
			
		||||
	
 | 
			
		||||
	addTopNodes();
 | 
			
		||||
	
 | 
			
		||||
	updateHeightmap(node_min, node_max);
 | 
			
		||||
 | 
			
		||||
	if (flags & MG_DUNGEONS) {
 | 
			
		||||
		DungeonGen dgen(ndef, data->seed, water_level);
 | 
			
		||||
@@ -210,6 +221,9 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
 | 
			
		||||
		ore->placeOre(this, blockseed + i, node_min, node_max);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// Sprinkle some dust on top after everything else was generated
 | 
			
		||||
	dustTopNodes();
 | 
			
		||||
	
 | 
			
		||||
	//printf("makeChunk: %dms\n", t.stop());
 | 
			
		||||
	
 | 
			
		||||
	updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
 | 
			
		||||
@@ -219,7 +233,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
 | 
			
		||||
					 node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
 | 
			
		||||
	//setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
 | 
			
		||||
	//			node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	this->generating = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -230,15 +244,14 @@ void MapgenV7::calculateNoise() {
 | 
			
		||||
	int y = node_min.Y;
 | 
			
		||||
	int z = node_min.Z;
 | 
			
		||||
	
 | 
			
		||||
	noise_terrain_mod->perlinMap2D(x, z);
 | 
			
		||||
	
 | 
			
		||||
	noise_height_select->perlinMap2D(x, z);
 | 
			
		||||
	noise_height_select->transformNoiseMap();
 | 
			
		||||
	
 | 
			
		||||
	noise_terrain_persist->perlinMap2D(x, z);
 | 
			
		||||
	noise_terrain_persist->transformNoiseMap();
 | 
			
		||||
	float *persistmap = noise_terrain_persist->result;
 | 
			
		||||
	for (int i = 0; i != csize.X * csize.Z; i++)
 | 
			
		||||
		persistmap[i] = abs(persistmap[i]);
 | 
			
		||||
		persistmap[i] = rangelim(persistmap[i], 0.4, 0.9);
 | 
			
		||||
	
 | 
			
		||||
	noise_terrain_base->perlinMap2DModulated(x, z, persistmap);
 | 
			
		||||
	noise_terrain_base->transformNoiseMap();
 | 
			
		||||
@@ -246,10 +259,20 @@ void MapgenV7::calculateNoise() {
 | 
			
		||||
	noise_terrain_alt->perlinMap2DModulated(x, z, persistmap);
 | 
			
		||||
	noise_terrain_alt->transformNoiseMap();
 | 
			
		||||
	
 | 
			
		||||
	noise_ridge->perlinMap3D(x, y, z);
 | 
			
		||||
	noise_filler_depth->perlinMap2D(x, z);
 | 
			
		||||
	
 | 
			
		||||
	if (flags & MGV7_MOUNTAINS) {
 | 
			
		||||
		noise_mountain->perlinMap3D(x, y, z);
 | 
			
		||||
		noise_mount_height->perlinMap2D(x, z);
 | 
			
		||||
		noise_mount_height->transformNoiseMap();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (flags & MGV7_RIDGES) {
 | 
			
		||||
		noise_ridge->perlinMap3D(x, y, z);
 | 
			
		||||
		noise_ridge_uwater->perlinMap2D(x, z);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	noise_heat->perlinMap2D(x, z);
 | 
			
		||||
	
 | 
			
		||||
	noise_humidity->perlinMap2D(x, z);
 | 
			
		||||
	
 | 
			
		||||
	//printf("calculateNoise: %dus\n", t.stop());
 | 
			
		||||
@@ -264,36 +287,56 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
 | 
			
		||||
	return bmgr->getBiome(heat, humidity, groundlevel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//needs to be updated
 | 
			
		||||
float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
 | 
			
		||||
	float terrain_mod = NoisePerlin2DNoTxfm(noise_terrain_mod->np, x, z, seed);
 | 
			
		||||
	float hselect     = NoisePerlin2D(noise_height_select->np, x, z, seed);
 | 
			
		||||
	float persist     = abs(NoisePerlin2DNoTxfm(noise_terrain_persist->np, x, z, seed));
 | 
			
		||||
	float hselect = NoisePerlin2D(noise_height_select->np, x, z, seed);
 | 
			
		||||
	hselect = rangelim(hselect, 0.0, 1.0);
 | 
			
		||||
	
 | 
			
		||||
	float persist = NoisePerlin2D(noise_terrain_persist->np, x, z, seed);
 | 
			
		||||
	persist = rangelim(persist, 0.4, 0.9);
 | 
			
		||||
 | 
			
		||||
	noise_terrain_base->np->persist = persist;
 | 
			
		||||
	float terrain_base = NoisePerlin2D(noise_terrain_base->np, x, z, seed);
 | 
			
		||||
	float height_base  = terrain_base * terrain_mod;
 | 
			
		||||
	float height_base = NoisePerlin2D(noise_terrain_base->np, x, z, seed);
 | 
			
		||||
 | 
			
		||||
	noise_terrain_alt->np->persist = persist;
 | 
			
		||||
	float height_alt = NoisePerlin2D(noise_terrain_alt->np, x, z, seed);
 | 
			
		||||
 | 
			
		||||
	if (height_alt > height_base)
 | 
			
		||||
		return height_alt;
 | 
			
		||||
		
 | 
			
		||||
	return (height_base * hselect) + (height_alt * (1.0 - hselect));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
float MapgenV7::baseTerrainLevelFromMap(int index) {
 | 
			
		||||
	float terrain_mod  = noise_terrain_mod->result[index];
 | 
			
		||||
	float hselect      = noise_height_select->result[index];
 | 
			
		||||
	float terrain_base = noise_terrain_base->result[index];
 | 
			
		||||
	float height_base  = terrain_base * terrain_mod;
 | 
			
		||||
	float height_alt   = noise_terrain_alt->result[index];
 | 
			
		||||
	float hselect     = rangelim(noise_height_select->result[index], 0.0, 1.0);
 | 
			
		||||
	float height_base = noise_terrain_base->result[index];
 | 
			
		||||
	float height_alt  = noise_terrain_alt->result[index];
 | 
			
		||||
	
 | 
			
		||||
	if (height_alt > height_base)
 | 
			
		||||
		return height_alt;
 | 
			
		||||
 | 
			
		||||
	return (height_base * hselect) + (height_alt * (1.0 - hselect));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool MapgenV7::getMountainTerrainAtPoint(int x, int y, int z) {
 | 
			
		||||
	float mnt_h_n = NoisePerlin2D(noise_mount_height->np, x, z, seed);
 | 
			
		||||
	float height_modifier = -((float)y / rangelim(mnt_h_n, 80.0, 150.0));
 | 
			
		||||
	float mnt_n = NoisePerlin3D(noise_mountain->np, x, y, z, seed);
 | 
			
		||||
 | 
			
		||||
	return mnt_n + height_modifier >= 0.6;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, int y) {
 | 
			
		||||
	float mounthn = noise_mount_height->result[idx_xz];
 | 
			
		||||
	float height_modifier = -((float)y / rangelim(mounthn, 80.0, 150.0));
 | 
			
		||||
	return (noise_mountain->result[idx_xyz] + height_modifier >= 0.6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
// Crap code to test log rivers as a proof-of-concept.  Didn't work out too well.
 | 
			
		||||
void MapgenV7::carveRivers() {
 | 
			
		||||
	MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
 | 
			
		||||
	MapNode n_stone(c_stone);
 | 
			
		||||
@@ -328,8 +371,26 @@ void MapgenV7::carveRivers() {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int MapgenV7::calcHeightMap() {
 | 
			
		||||
int MapgenV7::generateTerrain() {
 | 
			
		||||
	int ymax = generateBaseTerrain();
 | 
			
		||||
 | 
			
		||||
	if (flags & MGV7_MOUNTAINS)
 | 
			
		||||
		generateMountainTerrain();
 | 
			
		||||
 | 
			
		||||
	if (flags & MGV7_RIDGES)
 | 
			
		||||
		generateRidgeTerrain();
 | 
			
		||||
		
 | 
			
		||||
	return ymax;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int MapgenV7::generateBaseTerrain() {
 | 
			
		||||
	MapNode n_air(CONTENT_AIR);
 | 
			
		||||
	MapNode n_stone(c_stone);
 | 
			
		||||
	MapNode n_water(c_water_source);
 | 
			
		||||
	
 | 
			
		||||
	int stone_surface_max_y = -MAP_GENERATION_LIMIT;
 | 
			
		||||
	v3s16 em = vm->m_area.getExtent();
 | 
			
		||||
	u32 index = 0;
 | 
			
		||||
	
 | 
			
		||||
	for (s16 z = node_min.Z; z <= node_max.Z; z++)
 | 
			
		||||
@@ -342,46 +403,50 @@ int MapgenV7::calcHeightMap() {
 | 
			
		||||
		
 | 
			
		||||
		if (surface_y > stone_surface_max_y)
 | 
			
		||||
			stone_surface_max_y = surface_y;
 | 
			
		||||
 | 
			
		||||
		u32 i = vm->m_area.index(x, node_min.Y, z);		
 | 
			
		||||
		for (s16 y = node_min.Y; y <= node_max.Y; y++) {
 | 
			
		||||
			if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
 | 
			
		||||
				if (y <= surface_y)
 | 
			
		||||
					vm->m_data[i] = n_stone;
 | 
			
		||||
				else if (y <= water_level)
 | 
			
		||||
					vm->m_data[i] = n_water;
 | 
			
		||||
				else
 | 
			
		||||
					vm->m_data[i] = n_air;
 | 
			
		||||
			}
 | 
			
		||||
			vm->m_area.add_y(em, i, 1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	
 | 
			
		||||
	return stone_surface_max_y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void MapgenV7::generateTerrain() {
 | 
			
		||||
	MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
 | 
			
		||||
void MapgenV7::generateMountainTerrain() {
 | 
			
		||||
	if (node_max.Y <= water_level)
 | 
			
		||||
		return;
 | 
			
		||||
		
 | 
			
		||||
	MapNode n_stone(c_stone);
 | 
			
		||||
 | 
			
		||||
	v3s16 em = vm->m_area.getExtent();
 | 
			
		||||
	u32 index = 0;
 | 
			
		||||
	
 | 
			
		||||
	for (s16 z = node_min.Z; z <= node_max.Z; z++)
 | 
			
		||||
	for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
 | 
			
		||||
		s16 surface_y = heightmap[index];
 | 
			
		||||
		Biome *biome = bmgr->biomes[biomemap[index]];
 | 
			
		||||
		
 | 
			
		||||
		u32 i = vm->m_area.index(x, node_min.Y, z);
 | 
			
		||||
		for (s16 y = node_min.Y; y <= node_max.Y; y++) {
 | 
			
		||||
			if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
 | 
			
		||||
				if (y <= surface_y) {
 | 
			
		||||
					vm->m_data[i] = (y > water_level + biome->filler_height) ?
 | 
			
		||||
						MapNode(biome->c_filler) : n_stone;
 | 
			
		||||
				} else if (y <= water_level) {
 | 
			
		||||
					vm->m_data[i] = n_water_source;
 | 
			
		||||
				} else {
 | 
			
		||||
					vm->m_data[i] = n_air;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			vm->m_area.add_y(em, i, 1);
 | 
			
		||||
	for (s16 y = node_min.Y; y <= node_max.Y; y++) {
 | 
			
		||||
		u32 vi = vm->m_area.index(node_min.X, y, z);
 | 
			
		||||
		for (s16 x = node_min.X; x <= node_max.X; x++) {
 | 
			
		||||
			int j = (z - node_min.Z) * csize.X + (x - node_min.X);
 | 
			
		||||
 | 
			
		||||
			if (getMountainTerrainFromMap(index, j, y))
 | 
			
		||||
				vm->m_data[vi] = n_stone;
 | 
			
		||||
				
 | 
			
		||||
			vi++;
 | 
			
		||||
			index++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void MapgenV7::carveRidges() {
 | 
			
		||||
	if (node_max.Y <= water_level)
 | 
			
		||||
		return;
 | 
			
		||||
		
 | 
			
		||||
void MapgenV7::generateRidgeTerrain() {
 | 
			
		||||
	MapNode n_water(c_water_source);
 | 
			
		||||
	MapNode n_air(CONTENT_AIR);
 | 
			
		||||
	u32 index = 0;
 | 
			
		||||
	
 | 
			
		||||
@@ -389,37 +454,150 @@ void MapgenV7::carveRidges() {
 | 
			
		||||
	for (s16 y = node_min.Y; y <= node_max.Y; y++) {
 | 
			
		||||
		u32 vi = vm->m_area.index(node_min.X, y, z);
 | 
			
		||||
		for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) {
 | 
			
		||||
			// Removing this check will create huge underwater caverns,
 | 
			
		||||
			// which are interesting but not desirable for gameplay
 | 
			
		||||
			if (y <= water_level)
 | 
			
		||||
			int j = (z - node_min.Z) * csize.X + (x - node_min.X);
 | 
			
		||||
			
 | 
			
		||||
			if (heightmap[j] < water_level - 4)
 | 
			
		||||
				continue;
 | 
			
		||||
				
 | 
			
		||||
			if (noise_ridge->result[index] * (float)(y * y) < 15.0)
 | 
			
		||||
			
 | 
			
		||||
			float widthn = (noise_terrain_persist->result[j] - 0.6) / 0.1;
 | 
			
		||||
			//widthn = rangelim(widthn, -0.05, 0.5);
 | 
			
		||||
			
 | 
			
		||||
			float width = 0.3; // TODO: figure out acceptable perlin noise values
 | 
			
		||||
			float uwatern = noise_ridge_uwater->result[j] * 2;
 | 
			
		||||
			if (uwatern < -width || uwatern > width)
 | 
			
		||||
				continue;
 | 
			
		||||
			
 | 
			
		||||
			float height_mod = (float)(y + 17) / 2.5;
 | 
			
		||||
			float width_mod  = (width - fabs(uwatern));
 | 
			
		||||
			float nridge = noise_ridge->result[index] * (float)y / 7.0;
 | 
			
		||||
 | 
			
		||||
			int j = (z - node_min.Z) * csize.Z + (x - node_min.X); //////obviously just temporary
 | 
			
		||||
			if (y < water_level)
 | 
			
		||||
				nridge = -fabs(nridge) * 3.0 * widthn * 0.3;
 | 
			
		||||
			
 | 
			
		||||
			if (nridge + width_mod * height_mod < 0.6)
 | 
			
		||||
				continue;
 | 
			
		||||
			
 | 
			
		||||
			if (y < ridge_heightmap[j])
 | 
			
		||||
				ridge_heightmap[j] = y - 1; 
 | 
			
		||||
 | 
			
		||||
			vm->m_data[vi] = n_air;
 | 
			
		||||
			vm->m_data[vi] = (y > water_level) ? n_air : n_water;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
void MapgenV7::testBiomes() {
 | 
			
		||||
 | 
			
		||||
void MapgenV7::generateBiomes() {
 | 
			
		||||
	if (node_max.Y < water_level)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	MapNode n_air(CONTENT_AIR);
 | 
			
		||||
	MapNode n_stone(c_stone);
 | 
			
		||||
	MapNode n_water(c_water_source);
 | 
			
		||||
 | 
			
		||||
	v3s16 em = vm->m_area.getExtent();
 | 
			
		||||
	u32 index = 0;
 | 
			
		||||
	
 | 
			
		||||
	for (s16 z = node_min.Z; z <= node_min.Z; z++)
 | 
			
		||||
	for (s16 x = node_min.X; x <= node_min.X; x++) {;
 | 
			
		||||
		Biome *b = bmgr->getBiome(heat, humidity, 0);
 | 
			
		||||
	for (s16 z = node_min.Z; z <= node_max.Z; z++)
 | 
			
		||||
	for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
 | 
			
		||||
		Biome *biome  = bmgr->biomes[biomemap[index]];
 | 
			
		||||
		s16 dfiller   = biome->depth_filler + noise_filler_depth->result[index];
 | 
			
		||||
		s16 y0_top    = biome->depth_top;
 | 
			
		||||
		s16 y0_filler = biome->depth_filler + biome->depth_top + dfiller;
 | 
			
		||||
		
 | 
			
		||||
		s16 nplaced = 0;
 | 
			
		||||
		u32 i = vm->m_area.index(x, node_max.Y, z);	
 | 
			
		||||
 | 
			
		||||
		content_t c_above = vm->m_data[i + em.X].getContent();
 | 
			
		||||
		bool have_air = c_above == CONTENT_AIR;
 | 
			
		||||
		
 | 
			
		||||
		for (s16 y = node_max.Y; y >= node_min.Y; y--) {
 | 
			
		||||
			content_t c = vm->m_data[i].getContent();
 | 
			
		||||
			
 | 
			
		||||
			// It could be the case that the elevation is equal to the chunk
 | 
			
		||||
			// boundary, but the chunk above has not been generated yet
 | 
			
		||||
			if (y == node_max.Y && c_above == CONTENT_IGNORE &&
 | 
			
		||||
				y == heightmap[index] && c == c_stone) {
 | 
			
		||||
				int j = z * zstride + y * ystride + x;
 | 
			
		||||
				have_air = !getMountainTerrainFromMap(j, index, y);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (c == c_stone && have_air) {
 | 
			
		||||
				content_t c_below = vm->m_data[i - em.X].getContent();
 | 
			
		||||
				
 | 
			
		||||
				if (c_below != CONTENT_AIR) {
 | 
			
		||||
					if (nplaced < y0_top) {
 | 
			
		||||
						// A hack to prevent dirt_with_grass from being
 | 
			
		||||
						// placed below water.  TODO: fix later
 | 
			
		||||
						content_t c_place = ((y < water_level) &&
 | 
			
		||||
								(biome->c_top == c_dirt_with_grass)) ?
 | 
			
		||||
								 c_dirt : biome->c_top;
 | 
			
		||||
						
 | 
			
		||||
						vm->m_data[i] = MapNode(c_place);
 | 
			
		||||
						nplaced++;
 | 
			
		||||
					} else if (nplaced < y0_filler && nplaced >= y0_top) {
 | 
			
		||||
						vm->m_data[i] = MapNode(biome->c_filler);
 | 
			
		||||
						nplaced++;
 | 
			
		||||
					} else {
 | 
			
		||||
						have_air = false;
 | 
			
		||||
						nplaced  = 0;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else if (c == c_water_source) {
 | 
			
		||||
				have_air = true;
 | 
			
		||||
				nplaced = 0;
 | 
			
		||||
				vm->m_data[i] = MapNode(biome->c_water);
 | 
			
		||||
			} else if (c == CONTENT_AIR) {
 | 
			
		||||
				have_air = true;
 | 
			
		||||
				nplaced = 0;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			vm->m_area.add_y(em, i, -1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// make an 80x80 grid with axes heat/humidity as a voroni diagram for biomes
 | 
			
		||||
	// clear out y space for it first with air
 | 
			
		||||
	// use absolute positioning, each chunk will be a +1 height
 | 
			
		||||
}*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void MapgenV7::dustTopNodes() {
 | 
			
		||||
	v3s16 em = vm->m_area.getExtent();
 | 
			
		||||
	u32 index = 0;
 | 
			
		||||
	
 | 
			
		||||
	if (water_level > node_max.Y)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (s16 z = node_min.Z; z <= node_max.Z; z++)
 | 
			
		||||
	for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
 | 
			
		||||
		Biome *biome = bmgr->biomes[biomemap[index]];
 | 
			
		||||
	
 | 
			
		||||
		if (biome->c_dust == CONTENT_IGNORE)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		s16 y = node_max.Y;
 | 
			
		||||
		u32 vi = vm->m_area.index(x, y, z);
 | 
			
		||||
		for (; y >= node_min.Y; y--) {
 | 
			
		||||
			if (vm->m_data[vi].getContent() != CONTENT_AIR)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			vm->m_area.add_y(em, vi, -1);
 | 
			
		||||
		}
 | 
			
		||||
			
 | 
			
		||||
		content_t c = vm->m_data[vi].getContent();
 | 
			
		||||
		if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
 | 
			
		||||
			if (y < node_min.Y)
 | 
			
		||||
				continue;
 | 
			
		||||
				
 | 
			
		||||
			vm->m_data[vi] = MapNode(biome->c_dust_water);
 | 
			
		||||
		} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE) {
 | 
			
		||||
			if (y == node_max.Y)
 | 
			
		||||
				continue;
 | 
			
		||||
				
 | 
			
		||||
			vm->m_area.add_y(em, vi, 1);
 | 
			
		||||
			vm->m_data[vi] = MapNode(biome->c_dust);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
void MapgenV7::addTopNodes() {
 | 
			
		||||
	v3s16 em = vm->m_area.getExtent();
 | 
			
		||||
	s16 ntopnodes;
 | 
			
		||||
@@ -511,6 +689,7 @@ void MapgenV7::addTopNodes() {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "mapgen_v6.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -24,25 +24,34 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 | 
			
		||||
extern NoiseParams nparams_v7_def_terrain_base;
 | 
			
		||||
extern NoiseParams nparams_v7_def_terrain_alt;
 | 
			
		||||
extern NoiseParams nparams_v7_def_terrain_mod;
 | 
			
		||||
extern NoiseParams nparams_v7_def_terrain_persist;
 | 
			
		||||
extern NoiseParams nparams_v7_def_height_select;
 | 
			
		||||
extern NoiseParams nparams_v7_def_filler_depth;
 | 
			
		||||
extern NoiseParams nparams_v7_def_mount_height;
 | 
			
		||||
extern NoiseParams nparams_v7_def_ridge_uwater;
 | 
			
		||||
extern NoiseParams nparams_v7_def_mountain;
 | 
			
		||||
extern NoiseParams nparams_v7_def_ridge;
 | 
			
		||||
 | 
			
		||||
struct MapgenV7Params : public MapgenParams {
 | 
			
		||||
	NoiseParams np_terrain_base;
 | 
			
		||||
	NoiseParams np_terrain_alt;
 | 
			
		||||
	NoiseParams np_terrain_mod;
 | 
			
		||||
	NoiseParams np_terrain_persist;
 | 
			
		||||
	NoiseParams np_height_select;
 | 
			
		||||
	NoiseParams np_filler_depth;
 | 
			
		||||
	NoiseParams np_mount_height;
 | 
			
		||||
	NoiseParams np_ridge_uwater;
 | 
			
		||||
	NoiseParams np_mountain;
 | 
			
		||||
	NoiseParams np_ridge;
 | 
			
		||||
	
 | 
			
		||||
	MapgenV7Params() {
 | 
			
		||||
		np_terrain_base    = nparams_v7_def_terrain_base;
 | 
			
		||||
		np_terrain_alt     = nparams_v7_def_terrain_alt;
 | 
			
		||||
		np_terrain_mod     = nparams_v7_def_terrain_mod;
 | 
			
		||||
		np_terrain_persist = nparams_v7_def_terrain_persist;
 | 
			
		||||
		np_height_select   = nparams_v7_def_height_select;
 | 
			
		||||
		np_filler_depth    = nparams_v7_def_filler_depth;
 | 
			
		||||
		np_mount_height    = nparams_v7_def_mount_height;
 | 
			
		||||
		np_ridge_uwater    = nparams_v7_def_ridge_uwater;
 | 
			
		||||
		np_mountain        = nparams_v7_def_mountain;
 | 
			
		||||
		np_ridge           = nparams_v7_def_ridge;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -58,8 +67,8 @@ public:
 | 
			
		||||
	BiomeDefManager *bmgr;
 | 
			
		||||
 | 
			
		||||
	int ystride;
 | 
			
		||||
	int zstride;
 | 
			
		||||
	u32 flags;
 | 
			
		||||
	bool ridges;
 | 
			
		||||
 | 
			
		||||
	u32 blockseed;
 | 
			
		||||
	v3s16 node_min;
 | 
			
		||||
@@ -71,10 +80,12 @@ public:
 | 
			
		||||
	
 | 
			
		||||
	Noise *noise_terrain_base;
 | 
			
		||||
	Noise *noise_terrain_alt;
 | 
			
		||||
	Noise *noise_terrain_mod;
 | 
			
		||||
	Noise *noise_terrain_persist;
 | 
			
		||||
	Noise *noise_height_select;
 | 
			
		||||
	
 | 
			
		||||
	Noise *noise_filler_depth;
 | 
			
		||||
	Noise *noise_mount_height;
 | 
			
		||||
	Noise *noise_ridge_uwater;
 | 
			
		||||
	Noise *noise_mountain;
 | 
			
		||||
	Noise *noise_ridge;
 | 
			
		||||
	
 | 
			
		||||
	Noise *noise_heat;
 | 
			
		||||
@@ -86,6 +97,7 @@ public:
 | 
			
		||||
	content_t c_sand;
 | 
			
		||||
	content_t c_water_source;
 | 
			
		||||
	content_t c_lava_source;
 | 
			
		||||
	content_t c_ice;
 | 
			
		||||
	content_t c_gravel;
 | 
			
		||||
	content_t c_cobble;
 | 
			
		||||
	content_t c_desert_sand;
 | 
			
		||||
@@ -100,15 +112,20 @@ public:
 | 
			
		||||
 | 
			
		||||
	float baseTerrainLevelAtPoint(int x, int z);
 | 
			
		||||
	float baseTerrainLevelFromMap(int index);
 | 
			
		||||
	bool getMountainTerrainAtPoint(int x, int y, int z);
 | 
			
		||||
	bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, int y);
 | 
			
		||||
	
 | 
			
		||||
	void calculateNoise();
 | 
			
		||||
	int calcHeightMap();
 | 
			
		||||
	
 | 
			
		||||
	virtual void generateTerrain();
 | 
			
		||||
	void carveRidges();
 | 
			
		||||
	//void carveRivers(); //experimental
 | 
			
		||||
	virtual int generateTerrain();
 | 
			
		||||
	int generateBaseTerrain();
 | 
			
		||||
	void generateMountainTerrain();
 | 
			
		||||
	void generateRidgeTerrain();
 | 
			
		||||
	
 | 
			
		||||
	void testBiomes();
 | 
			
		||||
	void addTopNodes();
 | 
			
		||||
	void generateBiomes();
 | 
			
		||||
	void dustTopNodes();
 | 
			
		||||
	
 | 
			
		||||
	//void addTopNodes();
 | 
			
		||||
	
 | 
			
		||||
	void generateCaves(int max_stone_y);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -204,19 +204,33 @@ int ModApiBasic::l_register_biome(lua_State *L)
 | 
			
		||||
				"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
 | 
			
		||||
	Biome *b = bmgr->createBiome(terrain);
 | 
			
		||||
 | 
			
		||||
	b->name            = getstringfield_default(L, index, "name", "");
 | 
			
		||||
	b->top_nodename    = getstringfield_default(L, index, "top_node", "");
 | 
			
		||||
	b->top_depth       = getintfield_default(L, index, "top_depth", 0);
 | 
			
		||||
	b->filler_nodename = getstringfield_default(L, index, "filler_node", "");
 | 
			
		||||
	b->filler_height   = getintfield_default(L, index, "filler_height", 0);
 | 
			
		||||
	b->height_min      = getintfield_default(L, index, "height_min", 0);
 | 
			
		||||
	b->height_max      = getintfield_default(L, index, "height_max", 0);
 | 
			
		||||
	b->heat_point      = getfloatfield_default(L, index, "heat_point", 0.);
 | 
			
		||||
	b->humidity_point  = getfloatfield_default(L, index, "humidity_point", 0.);
 | 
			
		||||
	b->name         = getstringfield_default(L, index, "name",
 | 
			
		||||
												"<no name>");
 | 
			
		||||
	b->nname_top    = getstringfield_default(L, index, "node_top",
 | 
			
		||||
												"mapgen_dirt_with_grass");
 | 
			
		||||
	b->nname_filler = getstringfield_default(L, index, "node_filler",
 | 
			
		||||
												"mapgen_dirt");
 | 
			
		||||
	b->nname_water  = getstringfield_default(L, index, "node_water",
 | 
			
		||||
												"mapgen_water_source");
 | 
			
		||||
	b->nname_dust   = getstringfield_default(L, index, "node_dust",
 | 
			
		||||
												"air");
 | 
			
		||||
	b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
 | 
			
		||||
												"mapgen_water_source");
 | 
			
		||||
	
 | 
			
		||||
	b->depth_top      = getintfield_default(L, index, "depth_top",    1);
 | 
			
		||||
	b->depth_filler   = getintfield_default(L, index, "depth_filler", 3);
 | 
			
		||||
	b->height_min     = getintfield_default(L, index, "height_min",   0);
 | 
			
		||||
	b->height_max     = getintfield_default(L, index, "height_max",   0);
 | 
			
		||||
	b->heat_point     = getfloatfield_default(L, index, "heat_point",     0.);
 | 
			
		||||
	b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
 | 
			
		||||
 | 
			
		||||
	b->flags    = 0; //reserved
 | 
			
		||||
	b->c_top    = CONTENT_IGNORE;
 | 
			
		||||
	b->c_filler = CONTENT_IGNORE;
 | 
			
		||||
	b->flags        = 0; //reserved
 | 
			
		||||
	b->c_top        = CONTENT_IGNORE;
 | 
			
		||||
	b->c_filler     = CONTENT_IGNORE;
 | 
			
		||||
	b->c_water      = CONTENT_IGNORE;
 | 
			
		||||
	b->c_dust       = CONTENT_IGNORE;
 | 
			
		||||
	b->c_dust_water = CONTENT_IGNORE;
 | 
			
		||||
	
 | 
			
		||||
	verbosestream << "register_biome: " << b->name << std::endl;
 | 
			
		||||
	bmgr->addBiome(b);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user