From 83bafbe08b508266d31a6a76f1ffc2cddc662390 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 8 Feb 2014 17:50:26 -0500 Subject: [PATCH] Make flag strings clear specified flag with 'no' prefix Remove flagmask field from set_mapgen_params table Add small bits of needed documentation --- doc/lua_api.txt | 7 +++-- minetest.conf.example | 10 ++++--- src/defaultsettings.cpp | 2 +- src/emerge.cpp | 3 +-- src/mapgen.cpp | 12 ++++----- src/mapgen.h | 6 ++--- src/mapgen_math.cpp | 2 +- src/mapgen_singlenode.cpp | 2 +- src/mapgen_v6.cpp | 18 ++++++------- src/mapgen_v6.h | 6 ++--- src/mapgen_v7.cpp | 16 ++++++------ src/porting.h | 1 + src/script/common/c_content.cpp | 11 ++++---- src/script/common/c_content.h | 2 +- src/script/cpp_api/s_env.cpp | 3 ++- src/script/lua_api/l_mapgen.cpp | 21 ++++++++++----- src/settings.h | 28 +++++++++++++++----- src/util/string.cpp | 46 +++++++++++++++++++++++---------- src/util/string.h | 4 +-- 19 files changed, 122 insertions(+), 78 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 5536d0bfd..aef17bec8 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1360,11 +1360,10 @@ minetest.get_mapgen_object(objectname) minetest.set_mapgen_params(MapgenParams) ^ Set map generation parameters ^ Function cannot be called after the registration period; only initialization and on_mapgen_init -^ Takes a table as an argument with the fields mgname, seed, water_level, flags, and flagmask. +^ Takes a table as an argument with the fields mgname, seed, water_level, and flags. ^ Leave field unset to leave that parameter unchanged -^ flagmask field must be set to all mapgen flags that are being modified -^ flags contains only the flags that are being set -^ flags and flagmask are in the same format and have the same options as 'mgflags' in minetest.conf +^ flags contains a comma-delimited string of flags to set, or if the prefix "no" is attached, clears instead. +^ flags is in the same format and has the same options as 'mg_flags' in minetest.conf minetest.clear_objects() ^ clear all objects in the environments minetest.line_of_sight(pos1, pos2, stepsize) -> true/false, pos diff --git a/minetest.conf.example b/minetest.conf.example index df70e013f..580395596 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -381,10 +381,12 @@ #water_level = 1 # Size of chunks to be generated. #chunksize = 5 -# Map generation attributes. Currently supported: trees, caves, flat, dungeons, nolight +# Map generation attributes. Currently supported: trees, caves, flat, dungeons, light +# Flags that are not specified in the flag string are not modified from the default. +# To explicitly turn off a flag, prepend "no" to the beginning, e.g. nolight. #mg_flags = trees, caves -# Map generation attributes specific to Mapgen V6. Currently supported: v6_biome_blend, v6_jungles, v6_nomudflow -#mgv6_spflags = v6_biome_blend +# Map generation attributes specific to Mapgen V6. Currently supported: biomeblend, jungles, mudflow +#mgv6_spflags = biomeblend # How large deserts and beaches are #mgv6_freq_desert = 0.45 #mgv6_freq_beach = 0.15 @@ -402,7 +404,7 @@ #mgv6_np_trees = 0, 1, (125, 125, 125), 2, 4, 0.66 #mgv6_np_apple_trees = 0, 1, (100, 100, 100), 342902, 3, 0.45 -#mgv7_spflags = v7_mountains, v7_ridges +#mgv7_spflags = mountains, ridges #mgv7_np_terrain = 10, 12, (350, 350, 350), 82341, 5, 0.6 #mgv7_np_bgroup = 0.5, 0.3125, (350, 350, 350), 5923, 2, 0.6 #mgv7_np_heat = 25, 50, (500, 500, 500), 35293, 1, 0 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 9d1aadad9..80edd0711 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -249,7 +249,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", "trees, caves"); + settings->setDefault("mg_flags", ""); settings->setDefault("mgmath_generator", "mandelbox"); diff --git a/src/emerge.cpp b/src/emerge.cpp index 88bb3a1e6..9760839c8 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -372,7 +372,6 @@ void EmergeManager::loadParamsFromSettings(Settings *settings) { params.sparams = createMapgenParams(params.mg_name); if (params.sparams) params.sparams->readParams(settings); - } @@ -381,7 +380,7 @@ void EmergeManager::saveParamsToSettings(Settings *settings) { 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); + settings->setFlagStr("mg_flags", params.flags, flagdesc_mapgen, (u32)-1); if (params.sparams) params.sparams->writeParams(settings); diff --git a/src/mapgen.cpp b/src/mapgen.cpp index d97c3e609..95a2f4029 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -41,12 +41,12 @@ with this program; if not, write to the Free Software Foundation, Inc., FlagDesc flagdesc_mapgen[] = { - {"trees", MG_TREES}, - {"caves", MG_CAVES}, - {"dungeons", MG_DUNGEONS}, - {"flat", MG_FLAT}, - {"nolight", MG_NOLIGHT}, - {NULL, 0} + {"trees", MG_TREES}, + {"caves", MG_CAVES}, + {"dungeons", MG_DUNGEONS}, + {"flat", MG_FLAT}, + {"light", MG_LIGHT}, + {NULL, 0} }; FlagDesc flagdesc_ore[] = { diff --git a/src/mapgen.h b/src/mapgen.h index 4cee3c2aa..037cdd1f9 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define MG_CAVES 0x02 #define MG_DUNGEONS 0x04 #define MG_FLAT 0x08 -#define MG_NOLIGHT 0x10 +#define MG_LIGHT 0x10 /////////////////// Ore generation flags // Use absolute value of height to determine ore placement @@ -114,11 +114,11 @@ struct MapgenParams { MapgenSpecificParams *sparams; MapgenParams() { - mg_name = "v6"; + mg_name = DEFAULT_MAPGEN; seed = 0; water_level = 1; chunksize = 5; - flags = MG_TREES | MG_CAVES; + flags = MG_TREES | MG_CAVES | MG_LIGHT; sparams = NULL; } }; diff --git a/src/mapgen_math.cpp b/src/mapgen_math.cpp index aee2b0d2a..62b81c8ef 100644 --- a/src/mapgen_math.cpp +++ b/src/mapgen_math.cpp @@ -169,7 +169,7 @@ void MapgenMathParams::writeParams(Settings *settings) { MapgenMath::MapgenMath(int mapgenid, MapgenParams *params_, EmergeManager *emerge) : MapgenV7(mapgenid, params_, emerge) { mg_params = (MapgenMathParams *)params_; - this->flags |= MG_NOLIGHT; + this->flags &= ~MG_LIGHT; Json::Value & params = mg_params->params; invert = params["invert"].empty() ? 1 : params["invert"].asBool(); //params["invert"].empty()?1:params["invert"].asBool(); diff --git a/src/mapgen_singlenode.cpp b/src/mapgen_singlenode.cpp index 5288a1f08..1471e064b 100644 --- a/src/mapgen_singlenode.cpp +++ b/src/mapgen_singlenode.cpp @@ -89,7 +89,7 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data) { updateLiquid(&data->transforming_liquid, node_min, node_max); // Calculate lighting - if (!(flags & MG_NOLIGHT)) + if (flags & MG_LIGHT) calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE, node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE); diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 92ae7dff0..a212496a8 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -38,10 +38,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen_v6.h" FlagDesc flagdesc_mapgen_v6[] = { - {"v6_jungles", MGV6_JUNGLES}, - {"v6_biome_blend", MGV6_BIOME_BLEND}, - {"v6_nomudflow", MGV6_NOMUDFLOW}, - {NULL, 0} + {"jungles", MGV6_JUNGLES}, + {"biomeblend", MGV6_BIOMEBLEND}, + {"mudflow", MGV6_MUDFLOW}, + {NULL, 0} }; /////////////////////////////////////////////////////////////////////////////// @@ -93,7 +93,7 @@ MapgenV6::~MapgenV6() { MapgenV6Params::MapgenV6Params() { - spflags = MGV6_BIOME_BLEND; + spflags = MGV6_BIOMEBLEND | MGV6_MUDFLOW; freq_desert = 0.45; freq_beach = 0.15; @@ -131,7 +131,7 @@ void MapgenV6Params::readParams(Settings *settings) { void MapgenV6Params::writeParams(Settings *settings) { - settings->setFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6); + settings->setFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6, (u32)-1); settings->setFloat("mgv6_freq_desert", freq_desert); settings->setFloat("mgv6_freq_beach", freq_beach); @@ -365,7 +365,7 @@ BiomeType MapgenV6::getBiome(int index, v2s16 p) if (d > freq_desert) return BT_DESERT; - if ((spflags & MGV6_BIOME_BLEND) && + if ((spflags & MGV6_BIOMEBLEND) && (d > freq_desert - 0.10) && ((noise2d(p.X, p.Y, seed) + 1.0) > (freq_desert - d) * 20.0)) return BT_DESERT; @@ -481,7 +481,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) { addDirtGravelBlobs(); // Flow mud away from steep edges - if (!(spflags & MGV6_NOMUDFLOW)) + if (spflags & MGV6_MUDFLOW) flowMud(mudflow_minpos, mudflow_maxpos); } @@ -543,7 +543,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) { } // Calculate lighting - if (!(flags & MG_NOLIGHT)) + if (flags & MG_LIGHT) calcLighting(node_min - v3s16(1, 1, 1) * MAP_BLOCKSIZE, node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE); diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h index 07d79f6a6..fa9ea3b1b 100644 --- a/src/mapgen_v6.h +++ b/src/mapgen_v6.h @@ -25,9 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #define AVERAGE_MUD_AMOUNT 4 /////////////////// Mapgen V6 flags -#define MGV6_JUNGLES 0x01 -#define MGV6_BIOME_BLEND 0x02 -#define MGV6_NOMUDFLOW 0x04 +#define MGV6_JUNGLES 0x01 +#define MGV6_BIOMEBLEND 0x02 +#define MGV6_MUDFLOW 0x04 extern FlagDesc flagdesc_mapgen_v6[]; diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 835915164..a9547fdb0 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -39,9 +39,9 @@ with this program; if not, write to the Free Software Foundation, Inc., FlagDesc flagdesc_mapgen_v7[] = { - {"v7_mountains", MGV7_MOUNTAINS}, - {"v7_ridges", MGV7_RIDGES}, - {NULL, 0} + {"mountains", MGV7_MOUNTAINS}, + {"ridges", MGV7_RIDGES}, + {NULL, 0} }; /////////////////////////////////////////////////////////////////////////////// @@ -53,10 +53,10 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) { this->emerge = emerge; this->bmgr = emerge->biomedef; - this->seed = (int)params->seed; + this->seed = (int)params->seed; this->water_level = params->water_level; - this->flags = params->flags | MGV7_MOUNTAINS | MGV7_RIDGES; - this->gennotify = emerge->gennotify; + this->flags = params->flags; + this->gennotify = emerge->gennotify; this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE; @@ -141,7 +141,7 @@ void MapgenV7Params::readParams(Settings *settings) { void MapgenV7Params::writeParams(Settings *settings) { - settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7); + settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, (u32)-1); settings->setNoiseParams("mgv7_np_terrain_base", np_terrain_base); settings->setNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); @@ -262,7 +262,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) { updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); - if (!(flags & MG_NOLIGHT)) + if (flags & MG_LIGHT) calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE, node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE); //setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE, diff --git a/src/porting.h b/src/porting.h index 7cd4cf031..4cfac21d1 100644 --- a/src/porting.h +++ b/src/porting.h @@ -87,6 +87,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #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) + #define strncasecmp(x, y, n) strnicmp(x, y, n) #else #define ALIGNOF(x) __alignof__(x) #endif diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 0d1f7aa03..d1e182f9f 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -839,12 +839,11 @@ void push_hit_params(lua_State *L,const HitParams ¶ms) } /******************************************************************************/ -u32 getflagsfield(lua_State *L, int table, - const char *fieldname, FlagDesc *flagdesc) { - std::string flagstring; - - flagstring = getstringfield_default(L, table, fieldname, ""); - return readFlagString(flagstring, flagdesc); +u32 getflagsfield(lua_State *L, int table, const char *fieldname, + FlagDesc *flagdesc, u32 *flagmask) +{ + std::string flagstring = getstringfield_default(L, table, fieldname, ""); + return readFlagString(flagstring, flagdesc, flagmask); } /******************************************************************************/ diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 163e803db..a89de1aad 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -121,7 +121,7 @@ int getenumfield (lua_State *L, u32 getflagsfield (lua_State *L, int table, const char *fieldname, - FlagDesc *flagdesc); + FlagDesc *flagdesc, u32 *flagmask); void push_items (lua_State *L, const std::vector &items); diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp index 2c2198edf..b0de675ec 100644 --- a/src/script/cpp_api/s_env.cpp +++ b/src/script/cpp_api/s_env.cpp @@ -78,7 +78,8 @@ void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams) lua_pushinteger(L, mgparams->water_level); lua_setfield(L, -2, "water_level"); - std::string flagstr = writeFlagString(mgparams->flags, flagdesc_mapgen); + std::string flagstr = writeFlagString(mgparams->flags, + flagdesc_mapgen, (u32)-1); lua_pushstring(L, flagstr.c_str()); lua_setfield(L, -2, "flags"); diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 709c7de35..4c6bca74e 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -210,13 +210,20 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L) lua_getfield(L, 1, "flagmask"); if (lua_isstring(L, -1)) { flagstr = lua_tostring(L, -1); - emerge->params.flags &= ~readFlagString(flagstr, flagdesc_mapgen); + emerge->params.flags &= ~readFlagString(flagstr, flagdesc_mapgen, NULL); + errorstream << "set_mapgen_params(): flagmask field is deprecated, " + "see lua_api.txt" << std::endl; } lua_getfield(L, 1, "flags"); if (lua_isstring(L, -1)) { + u32 flags, flagmask; + flagstr = lua_tostring(L, -1); - emerge->params.flags |= readFlagString(flagstr, flagdesc_mapgen); + flags = readFlagString(flagstr, flagdesc_mapgen, &flagmask); + + emerge->params.flags &= ~flagmask; + emerge->params.flags |= flags; } return 0; @@ -227,7 +234,8 @@ int ModApiMapgen::l_set_gen_notify(lua_State *L) { if (lua_isstring(L, 1)) { EmergeManager *emerge = getServer(L)->getEmergeManager(); - emerge->gennotify = readFlagString(lua_tostring(L, 1), flagdesc_gennotify); + emerge->gennotify = readFlagString(lua_tostring(L, 1), + flagdesc_gennotify, NULL); } return 0; } @@ -371,9 +379,10 @@ int ModApiMapgen::l_register_decoration(lua_State *L) break; } case DECO_SCHEMATIC: { DecoSchematic *dschem = (DecoSchematic *)deco; - dschem->flags = getflagsfield(L, index, "flags", flagdesc_deco_schematic); + dschem->flags = getflagsfield(L, index, "flags", + flagdesc_deco_schematic, NULL); dschem->rotation = (Rotation)getenumfield(L, index, - "rotation", es_Rotation, ROTATE_0); + "rotation", es_Rotation, ROTATE_0); lua_getfield(L, index, "replacements"); if (lua_istable(L, -1)) { @@ -445,7 +454,7 @@ int ModApiMapgen::l_register_ore(lua_State *L) ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->height_min = getintfield_default(L, index, "height_min", 0); ore->height_max = getintfield_default(L, index, "height_max", 0); - ore->flags = getflagsfield(L, index, "flags", flagdesc_ore); + ore->flags = getflagsfield(L, index, "flags", flagdesc_ore, NULL); ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.); lua_getfield(L, index, "wherein"); diff --git a/src/settings.h b/src/settings.h index cf698b0eb..2aa03074b 100644 --- a/src/settings.h +++ b/src/settings.h @@ -572,12 +572,15 @@ public: return value; } - u32 getFlagStr(std::string name, FlagDesc *flagdesc) + u32 getFlagStr(std::string name, FlagDesc *flagdesc, u32 *flagmask) { std::string val = get(name); - return (isdigit(val[0])) ? stoi(val) : readFlagString(val, flagdesc); + return (isdigit(val[0])) ? stoi(val) : + readFlagString(val, flagdesc, flagmask); } + // N.B. if getStruct() is used to read a non-POD aggregate type, + // the behavior is undefined. bool getStruct(std::string name, std::string format, void *out, size_t olen) { size_t len = olen; @@ -755,10 +758,19 @@ fail: } } + // N.B. getFlagStrNoEx() does not set val, but merely modifies it. Thus, + // val must be initialized before using getFlagStrNoEx(). The intention of + // this is to simplify modifying a flags field from a default value. bool getFlagStrNoEx(std::string name, u32 &val, FlagDesc *flagdesc) { try { - val = getFlagStr(name, flagdesc); + u32 flags, flagmask; + + flags = getFlagStr(name, flagdesc, &flagmask); + + val &= ~flagmask; + val |= flags; + return true; } catch (SettingNotFoundException &e) { return false; @@ -856,6 +868,9 @@ fail: } //////////// Set setting + + // N.B. if setStruct() is used to write a non-POD aggregate type, + // the behavior is undefined. bool setStruct(std::string name, std::string format, void *value) { char sbuf[2048]; @@ -959,10 +974,11 @@ fail: set(name, std::string(sbuf)); return true; } - - void setFlagStr(std::string name, u32 flags, FlagDesc *flagdesc) + + void setFlagStr(std::string name, u32 flags, + FlagDesc *flagdesc, u32 flagmask) { - set(name, writeFlagString(flags, flagdesc)); + set(name, writeFlagString(flags, flagdesc, flagmask)); } void setBool(std::string name, bool value) diff --git a/src/util/string.cpp b/src/util/string.cpp index 925d0ea35..afe40610c 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -108,46 +108,63 @@ std::string urldecode(std::string str) return oss.str(); } -u32 readFlagString(std::string str, FlagDesc *flagdesc) { - u32 result = 0; +u32 readFlagString(std::string str, FlagDesc *flagdesc, u32 *flagmask) +{ + u32 result = 0, mask = 0; char *s = &str[0]; char *flagstr, *strpos = NULL; - + while ((flagstr = strtok_r(s, ",", &strpos))) { s = NULL; - + while (*flagstr == ' ' || *flagstr == '\t') flagstr++; - + + bool flagset = true; + if (!strncasecmp(flagstr, "no", 2)) { + flagset = false; + flagstr += 2; + } + for (int i = 0; flagdesc[i].name; i++) { if (!strcasecmp(flagstr, flagdesc[i].name)) { - result |= flagdesc[i].flag; + mask |= flagdesc[i].flag; + if (flagset) + result |= flagdesc[i].flag; break; } } } - + + if (flagmask) + *flagmask = mask; + return result; } -std::string writeFlagString(u32 flags, FlagDesc *flagdesc) { +std::string writeFlagString(u32 flags, FlagDesc *flagdesc, u32 flagmask) +{ std::string result; - + for (int i = 0; flagdesc[i].name; i++) { - if (flags & flagdesc[i].flag) { + if (flagmask & flagdesc[i].flag) { + if (!(flags & flagdesc[i].flag)) + result += "no"; + 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 *mystrtok_r(char *s, const char *sep, char **lasts) +{ char *t; if (!s) @@ -172,7 +189,8 @@ char *mystrtok_r(char *s, const char *sep, char **lasts) { return s; } -u64 read_seed(const char *str) { +u64 read_seed(const char *str) +{ char *endptr; u64 num; diff --git a/src/util/string.h b/src/util/string.h index e5a60bc47..d6a9926ab 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -319,8 +319,8 @@ inline std::string unescape_string(std::string &s) std::string translatePassword(std::string playername, std::wstring password); std::string urlencode(std::string str); std::string urldecode(std::string str); -u32 readFlagString(std::string str, FlagDesc *flagdesc); -std::string writeFlagString(u32 flags, FlagDesc *flagdesc); +u32 readFlagString(std::string str, FlagDesc *flagdesc, u32 *flagmask); +std::string writeFlagString(u32 flags, FlagDesc *flagdesc, u32 flagmask); char *mystrtok_r(char *s, const char *sep, char **lasts); u64 read_seed(const char *str);