From 97260d09a8e658b6ded7d9100b0aa1040fcfe50f Mon Sep 17 00:00:00 2001
From: kwolekr <mirrorisim@gmail.com>
Date: Tue, 5 Feb 2013 15:01:33 -0500
Subject: [PATCH] Add flag string settings, flat map option

---
 src/defaultsettings.cpp |  2 +-
 src/map.cpp             |  9 +-----
 src/mapgen.cpp          | 22 ++++++++++++++-
 src/mapgen.h            |  2 ++
 src/mapgen_v6.cpp       | 62 ++++++++++++++++++++++++-----------------
 src/porting.h           |  1 +
 src/settings.h          | 11 ++++++++
 src/util/string.cpp     | 40 ++++++++++++++++++++++++++
 src/util/string.h       |  7 +++++
 9 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index e6526d3d7..a164d0693 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -177,7 +177,7 @@ void set_default_settings(Settings *settings)
 	settings->setDefault("mg_name", "v6");
 	settings->setDefault("water_level", "1");
 	settings->setDefault("chunksize", "5");
-	settings->setDefault("mg_flags", "19");
+	settings->setDefault("mg_flags", "trees, caves, v6_biome_blend");
 	settings->setDefault("mgv6_freq_desert", "0.45");
 	settings->setDefault("mgv6_freq_beach", "0.15");
 
diff --git a/src/map.cpp b/src/map.cpp
index ab9cb25dd..717b0cf9b 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -3078,14 +3078,7 @@ void ServerMap::saveMapMeta()
 
 	Settings params;
 
-	params.set("mg_name", m_emerge->params->mg_name);
-	params.setU64("seed", m_emerge->params->seed);
-	params.setS16("water_level", m_emerge->params->water_level);
-	params.setS16("chunksize", m_emerge->params->chunksize);
-	params.setS32("mg_flags", m_emerge->params->flags);
-
-	m_emerge->params->writeParams(&params);
-
+	m_emerge->setParamsToSettings(&params);
 	params.writeLines(os);
 
 	os<<"[end_of_params]\n";
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index f2745bdb4..5a78a541e 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -35,6 +35,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "treegen.h"
 #include "mapgen_v6.h"
 
+FlagDesc flagdesc_mapgen[] = {
+	{"trees",          MG_TREES},
+	{"caves",          MG_CAVES},
+	{"dungeons",       MG_DUNGEONS},
+	{"v6_forests",     MGV6_FORESTS},
+	{"v6_biome_blend", MGV6_BIOME_BLEND},
+	{"flat",           MG_FLAT},
+	{NULL,			   0}
+};
 
 ///////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// Emerge Manager ////////////////////////////////
@@ -149,7 +158,7 @@ MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) {
 	mgparams->seed        = settings->getU64(settings == g_settings ? "fixed_map_seed" : "seed");
 	mgparams->water_level = settings->getS16("water_level");
 	mgparams->chunksize   = settings->getS16("chunksize");
-	mgparams->flags       = settings->getS32("mg_flags");
+	mgparams->flags       = settings->getFlagStr("mg_flags", flagdesc_mapgen);
 
 	if (!mgparams->readParams(settings)) {
 		delete mgparams;
@@ -159,6 +168,17 @@ MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) {
 }
 
 
+void EmergeManager::setParamsToSettings(Settings *settings) {
+	settings->set("mg_name",         params->mg_name);
+	settings->setU64("seed",         params->seed);
+	settings->setS16("water_level",  params->water_level);
+	settings->setS16("chunksize",    params->chunksize);
+	settings->setFlagStr("mg_flags", params->flags, flagdesc_mapgen);
+
+	params->writeParams(settings);
+}
+
+
 bool EmergeManager::registerMapgen(std::string mgname, MapgenFactory *mgfactory) {
 	mglist.insert(std::make_pair(mgname, mgfactory));
 	infostream << "EmergeManager: registered mapgen " << mgname << std::endl;
diff --git a/src/mapgen.h b/src/mapgen.h
index 728290ffc..febf37e63 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MG_DUNGEONS      0x04
 #define MGV6_FORESTS     0x08
 #define MGV6_BIOME_BLEND 0x10
+#define MG_FLAT          0x20
 
 class BiomeDefManager;
 class Biome;
@@ -123,6 +124,7 @@ class EmergeManager {
 	
 	bool registerMapgen(std::string name, MapgenFactory *mgfactory);
 	MapgenParams *getParamsFromSettings(Settings *settings);
+	void setParamsToSettings(Settings *settings);
 	
 	//mapgen helper methods
 	Biome *getBiomeAtPoint(v3s16 p);
diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp
index 30df1673c..3a5e10930 100644
--- a/src/mapgen_v6.cpp
+++ b/src/mapgen_v6.cpp
@@ -278,6 +278,9 @@ bool MapgenV6::block_is_underground(u64 seed, v3s16 blockpos)
 
 double MapgenV6::base_rock_level_2d(u64 seed, v2s16 p)
 {
+	if (flags & MG_FLAT)
+		return water_level;
+	
 	int index = (p.Y - node_min.Z) * ystride + (p.X - node_min.X);
 
 	// The base ground level
@@ -333,6 +336,9 @@ double MapgenV6::base_rock_level_2d(u64 seed, v2s16 p)
 }
 
 double MapgenV6::baseRockLevelFromNoise(v2s16 p) {
+	if (flags & MG_FLAT)
+		return water_level;
+	
 	double base = water_level + 
 		NoisePerlin2DPosOffset(noise_terrain_base->np, p.X, 0.5, p.Y, 0.5, seed);
 	double higher = water_level +
@@ -370,6 +376,9 @@ s16 MapgenV6::find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision)
 
 double MapgenV6::get_mud_add_amount(u64 seed, v2s16 p)
 {
+	if (flags & MG_FLAT)
+		return AVERAGE_MUD_AMOUNT;
+		
 	/*return ((float)AVERAGE_MUD_AMOUNT + 2.0 * noise2d_perlin(
 			0.5+(float)p.X/200, 0.5+(float)p.Y/200,
 			seed+91013, 3, 0.55));*/
@@ -491,34 +500,37 @@ void MapgenV6::makeChunk(BlockMakeData *data)
 		int z = node_min.Z;
 
 		// Need to adjust for the original implementation's +.5 offset...
-		noise_terrain_base->perlinMap2D(
-			x + 0.5 * noise_terrain_base->np->spread.X,
-			z + 0.5 * noise_terrain_base->np->spread.Z);
-		noise_terrain_base->transformNoiseMap();
-
-		noise_terrain_higher->perlinMap2D(
-			x + 0.5 * noise_terrain_higher->np->spread.X,
-			z + 0.5 * noise_terrain_higher->np->spread.Z);
-		noise_terrain_higher->transformNoiseMap();
-
-		noise_steepness->perlinMap2D(
-			x + 0.5 * noise_steepness->np->spread.X,
-			z + 0.5 * noise_steepness->np->spread.Z);
-		noise_steepness->transformNoiseMap();
-
-		noise_height_select->perlinMap2D(
-			x + 0.5 * noise_height_select->np->spread.X,
-			z + 0.5 * noise_height_select->np->spread.Z);
-
+		if (!(flags & MG_FLAT)) {
+			noise_terrain_base->perlinMap2D(
+				x + 0.5 * noise_terrain_base->np->spread.X,
+				z + 0.5 * noise_terrain_base->np->spread.Z);
+			noise_terrain_base->transformNoiseMap();
+
+			noise_terrain_higher->perlinMap2D(
+				x + 0.5 * noise_terrain_higher->np->spread.X,
+				z + 0.5 * noise_terrain_higher->np->spread.Z);
+			noise_terrain_higher->transformNoiseMap();
+
+			noise_steepness->perlinMap2D(
+				x + 0.5 * noise_steepness->np->spread.X,
+				z + 0.5 * noise_steepness->np->spread.Z);
+			noise_steepness->transformNoiseMap();
+
+			noise_height_select->perlinMap2D(
+				x + 0.5 * noise_height_select->np->spread.X,
+				z + 0.5 * noise_height_select->np->spread.Z);
+		}
+		
 		noise_trees->perlinMap2D(
 			x + 0.5 * noise_trees->np->spread.X,
 			z + 0.5 * noise_trees->np->spread.Z);
-
-		noise_mud->perlinMap2D(
-			x + 0.5 * noise_mud->np->spread.X,
-			z + 0.5 * noise_mud->np->spread.Z);
-		noise_mud->transformNoiseMap();
-
+			
+		if (!(flags & MG_FLAT)) {
+			noise_mud->perlinMap2D(
+				x + 0.5 * noise_mud->np->spread.X,
+				z + 0.5 * noise_mud->np->spread.Z);
+			noise_mud->transformNoiseMap();
+		}
 		noise_beach->perlinMap2D(
 			x + 0.2 * noise_beach->np->spread.X,
 			z + 0.7 * noise_beach->np->spread.Z);
diff --git a/src/porting.h b/src/porting.h
index c8d19154c..9ba3394bb 100644
--- a/src/porting.h
+++ b/src/porting.h
@@ -56,6 +56,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 	#define strtof(x, y) (float)strtod(x, y)
 	#define strtoll(x, y, z) _strtoi64(x, y, z)
 	#define strtoull(x, y, z) _strtoui64(x, y, z)
+	#define strcasecmp(x, y) stricmp(x, y)
 #else
 	#define ALIGNOF(x) __alignof__(x)
 #endif
diff --git a/src/settings.h b/src/settings.h
index 2b46676c6..addd9980c 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -569,6 +569,12 @@ class Settings
 		return value;
 	}
 
+	u32 getFlagStr(std::string name, FlagDesc *flagdesc)
+	{
+		std::string val = get(name);
+		return (isdigit(val[0])) ? stoi(val) : readFlagString(val, flagdesc);
+	}
+
 	template <class T> T *getStruct(std::string name, std::string format)
 	{
 		size_t len = sizeof(T);
@@ -831,6 +837,11 @@ class Settings
 		set(name, std::string(sbuf));
 		return true;
 	}
+	
+	void setFlagStr(std::string name, u32 flags, FlagDesc *flagdesc)
+	{
+		set(name, writeFlagString(flags, flagdesc));
+	}
 
 	void setBool(std::string name, bool value)
 	{
diff --git a/src/util/string.cpp b/src/util/string.cpp
index c10755ae1..61b307c60 100644
--- a/src/util/string.cpp
+++ b/src/util/string.cpp
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "../sha1.h"
 #include "../base64.h"
+#include "../porting.h"
 
 // Get an sha-1 hash of the player's name combined with
 // the password entered. That's what the server uses as
@@ -48,6 +49,45 @@ size_t curl_write_data(char *ptr, size_t size, size_t nmemb, void *userdata) {
     return count;
 }
 
+u32 readFlagString(std::string str, FlagDesc *flagdesc) {
+	u32 result = 0;
+	char *s = &str[0];
+	char *flagstr, *strpos = NULL;
+	
+	while ((flagstr = strtok_r(s, ",", &strpos))) {
+		s = NULL;
+		
+		while (*flagstr == ' ' || *flagstr == '\t')
+			flagstr++;
+		
+		for (int i = 0; flagdesc[i].name; i++) {
+			if (!strcasecmp(flagstr, flagdesc[i].name)) {
+				result |= flagdesc[i].flag;
+				break;
+			}
+		}
+	}
+	
+	return result;
+}
+
+std::string writeFlagString(u32 flags, FlagDesc *flagdesc) {
+	std::string result;
+	
+	for (int i = 0; flagdesc[i].name; i++) {
+		if (flags & flagdesc[i].flag) {
+			result += flagdesc[i].name;
+			result += ", ";
+		}
+	}
+	
+	size_t len = result.length();
+	if (len >= 2)
+		result.erase(len - 2, 2);
+	
+	return result;
+}
+
 char *mystrtok_r(char *s, const char *sep, char **lasts) {
 	char *t;
 
diff --git a/src/util/string.h b/src/util/string.h
index d081b365b..a469a074a 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -28,6 +28,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <vector>
 #include <sstream>
 
+struct FlagDesc {
+	const char *name;
+	u32 flag;
+};
+
 static inline std::string padStringRight(std::string s, size_t len)
 {
 	if(len > s.size())
@@ -283,6 +288,8 @@ inline std::string wrap_rows(const std::string &from, u32 rowlen)
 
 std::string translatePassword(std::string playername, std::wstring password);
 size_t curl_write_data(char *ptr, size_t size, size_t nmemb, void *userdata);
+u32 readFlagString(std::string str, FlagDesc *flagdesc);
+std::string writeFlagString(u32 flags, FlagDesc *flagdesc);
 char *mystrtok_r(char *s, const char *sep, char **lasts);
 
 #endif
-- 
GitLab