summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSmallJoker <SmallJoker@users.noreply.github.com>2020-01-25 16:56:54 +0100
committerGitHub <noreply@github.com>2020-01-25 16:56:54 +0100
commitcde2a7f6f24f638421238ead4e61b155322fefc8 (patch)
tree96b6b1dd00a0c14660eea6f3f518b5d832dc1bd8
parent9cb3219f34be983e1b84a62a64c25e137d587365 (diff)
downloadminetest-cde2a7f6f24f638421238ead4e61b155322fefc8.tar.gz
minetest-cde2a7f6f24f638421238ead4e61b155322fefc8.tar.bz2
minetest-cde2a7f6f24f638421238ead4e61b155322fefc8.zip
Settings: Add get_flags API for mapgen flags (mg_flags, mgv6_spflags, ...) (#9284)
Unified flags handling in C++ and Lua Settings API -> Reading only, for now. Writing can be implemented later, if needed. API function to read the currently active flags -> was impossible from Lua Co-authored-by: Wuzzy <wuzzy2@mail.ru>
-rw-r--r--doc/lua_api.txt4
-rw-r--r--src/defaultsettings.cpp3
-rw-r--r--src/mapgen/mapgen.cpp13
-rw-r--r--src/mapgen/mapgen.h7
-rw-r--r--src/mapgen/mapgen_carpathian.cpp8
-rw-r--r--src/mapgen/mapgen_carpathian.h2
-rw-r--r--src/mapgen/mapgen_flat.cpp8
-rw-r--r--src/mapgen/mapgen_flat.h2
-rw-r--r--src/mapgen/mapgen_fractal.cpp9
-rw-r--r--src/mapgen/mapgen_fractal.h2
-rw-r--r--src/mapgen/mapgen_v5.cpp11
-rw-r--r--src/mapgen/mapgen_v5.h2
-rw-r--r--src/mapgen/mapgen_v6.cpp10
-rw-r--r--src/mapgen/mapgen_v6.h3
-rw-r--r--src/mapgen/mapgen_v7.cpp9
-rw-r--r--src/mapgen/mapgen_v7.h2
-rw-r--r--src/mapgen/mapgen_valleys.cpp13
-rw-r--r--src/mapgen/mapgen_valleys.h3
-rw-r--r--src/script/lua_api/l_settings.cpp25
-rw-r--r--src/script/lua_api/l_settings.h3
-rw-r--r--src/settings.cpp65
-rw-r--r--src/settings.h20
-rw-r--r--src/unittest/test_settings.cpp37
23 files changed, 222 insertions, 39 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 551aa50b5..1857ce541 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -6069,6 +6069,10 @@ It can be created via `Settings(filename)`.
* `default` is the value returned if `key` is not found.
* Returns `nil` if `key` is not found and `default` not specified.
* `get_np_group(key)`: returns a NoiseParams table
+* `get_flags(key)`:
+ * Returns `{flag = true/false, ...}` according to the set flags.
+ * Is currently limited to mapgen flags `mg_flags` and mapgen-specific
+ flags like `mgv5_spflags`.
* `set(key, value)`
* Setting names can't contain whitespace or any of `="{}#`.
* Setting values can't contain the sequence `\n"""`.
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index 1ab4a333e..754ce3547 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "config.h"
#include "constants.h"
#include "porting.h"
+#include "mapgen/mapgen.h" // Mapgen::setDefaultSettings
#include "util/string.h"
void set_default_settings(Settings *settings)
@@ -426,10 +427,10 @@ void set_default_settings(Settings *settings)
settings->setDefault("water_level", "1");
settings->setDefault("mapgen_limit", "31000");
settings->setDefault("chunksize", "5");
- settings->setDefault("mg_flags", "caves,dungeons,light,decorations,biomes");
settings->setDefault("fixed_map_seed", "");
settings->setDefault("max_block_generate_distance", "8");
settings->setDefault("enable_mapgen_debug_info", "false");
+ Mapgen::setDefaultSettings(settings);
// Server list announcing
settings->setDefault("server_announce", "false");
diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp
index 81ccf1f8d..79c429ff6 100644
--- a/src/mapgen/mapgen.cpp
+++ b/src/mapgen/mapgen.cpp
@@ -215,6 +215,17 @@ void Mapgen::getMapgenNames(std::vector<const char *> *mgnames, bool include_hid
}
}
+void Mapgen::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mg_flags", flagdesc_mapgen,
+ MG_CAVES | MG_DUNGEONS | MG_LIGHT | MG_DECORATIONS | MG_BIOMES);
+
+ for (int i = 0; i < (int)MAPGEN_INVALID; ++i) {
+ MapgenParams *params = createMapgenParams((MapgenType)i);
+ params->setDefaultSettings(settings);
+ delete params;
+ }
+}
u32 Mapgen::getBlockSeed(v3s16 p, s32 seed)
{
@@ -1068,7 +1079,7 @@ void MapgenParams::writeParams(Settings *settings) const
settings->setS16("water_level", water_level);
settings->setS16("mapgen_limit", mapgen_limit);
settings->setS16("chunksize", chunksize);
- settings->setFlagStr("mg_flags", flags, flagdesc_mapgen, U32_MAX);
+ settings->setFlagStr("mg_flags", flags, flagdesc_mapgen);
if (bparams)
bparams->writeParams(settings);
diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h
index 1473d41a6..dc325c791 100644
--- a/src/mapgen/mapgen.h
+++ b/src/mapgen/mapgen.h
@@ -124,7 +124,9 @@ struct MapgenParams {
u64 seed = 0;
s16 water_level = 1;
s16 mapgen_limit = MAX_MAP_GENERATION_LIMIT;
- u32 flags = MG_CAVES | MG_LIGHT | MG_DECORATIONS | MG_BIOMES;
+ // Flags set in readParams
+ u32 flags = 0;
+ u32 spflags = 0;
BiomeParams *bparams = nullptr;
@@ -133,6 +135,8 @@ struct MapgenParams {
virtual void readParams(const Settings *settings);
virtual void writeParams(Settings *settings) const;
+ // Default settings for g_settings such as flags
+ virtual void setDefaultSettings(Settings *settings) {};
s32 getSpawnRangeMax();
@@ -214,6 +218,7 @@ public:
EmergeManager *emerge);
static MapgenParams *createMapgenParams(MapgenType mgtype);
static void getMapgenNames(std::vector<const char *> *mgnames, bool include_hidden);
+ static void setDefaultSettings(Settings *settings);
private:
// isLiquidHorizontallyFlowable() is a helper function for updateLiquid()
diff --git a/src/mapgen/mapgen_carpathian.cpp b/src/mapgen/mapgen_carpathian.cpp
index 67f542c0d..0dc1d33be 100644
--- a/src/mapgen/mapgen_carpathian.cpp
+++ b/src/mapgen/mapgen_carpathian.cpp
@@ -187,7 +187,7 @@ void MapgenCarpathianParams::readParams(const Settings *settings)
void MapgenCarpathianParams::writeParams(Settings *settings) const
{
- settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX);
+ settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian);
settings->setFloat("mgcarpathian_base_level", base_level);
settings->setFloat("mgcarpathian_river_width", river_width);
@@ -227,6 +227,12 @@ void MapgenCarpathianParams::writeParams(Settings *settings) const
}
+void MapgenCarpathianParams::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mgcarpathian_spflags", flagdesc_mapgen_carpathian,
+ MGCARPATHIAN_CAVERNS);
+}
+
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/mapgen/mapgen_carpathian.h b/src/mapgen/mapgen_carpathian.h
index ef49df213..acd379958 100644
--- a/src/mapgen/mapgen_carpathian.h
+++ b/src/mapgen/mapgen_carpathian.h
@@ -37,7 +37,6 @@ struct MapgenCarpathianParams : public MapgenParams
float river_depth = 24.0f;
float valley_width = 0.25f;
- u32 spflags = MGCARPATHIAN_CAVERNS;
float cave_width = 0.09f;
s16 large_cave_depth = -33;
u16 small_cave_num_min = 0;
@@ -74,6 +73,7 @@ struct MapgenCarpathianParams : public MapgenParams
void readParams(const Settings *settings);
void writeParams(Settings *settings) const;
+ void setDefaultSettings(Settings *settings);
};
class MapgenCarpathian : public MapgenBasic
diff --git a/src/mapgen/mapgen_flat.cpp b/src/mapgen/mapgen_flat.cpp
index 656e7d72c..879435948 100644
--- a/src/mapgen/mapgen_flat.cpp
+++ b/src/mapgen/mapgen_flat.cpp
@@ -126,7 +126,7 @@ void MapgenFlatParams::readParams(const Settings *settings)
void MapgenFlatParams::writeParams(Settings *settings) const
{
- settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat, U32_MAX);
+ settings->setFlagStr("mgflat_spflags", spflags, flagdesc_mapgen_flat);
settings->setS16("mgflat_ground_level", ground_level);
settings->setS16("mgflat_large_cave_depth", large_cave_depth);
settings->setU16("mgflat_small_cave_num_min", small_cave_num_min);
@@ -150,6 +150,12 @@ void MapgenFlatParams::writeParams(Settings *settings) const
}
+void MapgenFlatParams::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mgflat_spflags", flagdesc_mapgen_flat, 0);
+}
+
+
/////////////////////////////////////////////////////////////////
diff --git a/src/mapgen/mapgen_flat.h b/src/mapgen/mapgen_flat.h
index 2ff87c0db..c314c7605 100644
--- a/src/mapgen/mapgen_flat.h
+++ b/src/mapgen/mapgen_flat.h
@@ -32,7 +32,6 @@ extern FlagDesc flagdesc_mapgen_flat[];
struct MapgenFlatParams : public MapgenParams
{
- u32 spflags = 0;
s16 ground_level = 8;
s16 large_cave_depth = -33;
u16 small_cave_num_min = 0;
@@ -59,6 +58,7 @@ struct MapgenFlatParams : public MapgenParams
void readParams(const Settings *settings);
void writeParams(Settings *settings) const;
+ void setDefaultSettings(Settings *settings);
};
class MapgenFlat : public MapgenBasic
diff --git a/src/mapgen/mapgen_fractal.cpp b/src/mapgen/mapgen_fractal.cpp
index 1ac57cede..cabe0b850 100644
--- a/src/mapgen/mapgen_fractal.cpp
+++ b/src/mapgen/mapgen_fractal.cpp
@@ -139,7 +139,7 @@ void MapgenFractalParams::readParams(const Settings *settings)
void MapgenFractalParams::writeParams(Settings *settings) const
{
- settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal, U32_MAX);
+ settings->setFlagStr("mgfractal_spflags", spflags, flagdesc_mapgen_fractal);
settings->setFloat("mgfractal_cave_width", cave_width);
settings->setS16("mgfractal_large_cave_depth", large_cave_depth);
settings->setU16("mgfractal_small_cave_num_min", small_cave_num_min);
@@ -167,6 +167,13 @@ void MapgenFractalParams::writeParams(Settings *settings) const
}
+void MapgenFractalParams::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mgfractal_spflags", flagdesc_mapgen_fractal,
+ MGFRACTAL_TERRAIN);
+}
+
+
/////////////////////////////////////////////////////////////////
diff --git a/src/mapgen/mapgen_fractal.h b/src/mapgen/mapgen_fractal.h
index 0654d0360..971dfd822 100644
--- a/src/mapgen/mapgen_fractal.h
+++ b/src/mapgen/mapgen_fractal.h
@@ -35,7 +35,6 @@ extern FlagDesc flagdesc_mapgen_fractal[];
struct MapgenFractalParams : public MapgenParams
{
- u32 spflags = MGFRACTAL_TERRAIN;
float cave_width = 0.09f;
s16 large_cave_depth = -33;
u16 small_cave_num_min = 0;
@@ -66,6 +65,7 @@ struct MapgenFractalParams : public MapgenParams
void readParams(const Settings *settings);
void writeParams(Settings *settings) const;
+ void setDefaultSettings(Settings *settings);
};
diff --git a/src/mapgen/mapgen_v5.cpp b/src/mapgen/mapgen_v5.cpp
index c003c27d6..447fe8c50 100644
--- a/src/mapgen/mapgen_v5.cpp
+++ b/src/mapgen/mapgen_v5.cpp
@@ -129,7 +129,7 @@ void MapgenV5Params::readParams(const Settings *settings)
void MapgenV5Params::writeParams(Settings *settings) const
{
- settings->setFlagStr("mgv5_spflags", spflags, flagdesc_mapgen_v5, U32_MAX);
+ settings->setFlagStr("mgv5_spflags", spflags, flagdesc_mapgen_v5);
settings->setFloat("mgv5_cave_width", cave_width);
settings->setS16("mgv5_large_cave_depth", large_cave_depth);
settings->setU16("mgv5_small_cave_num_min", small_cave_num_min);
@@ -154,6 +154,15 @@ void MapgenV5Params::writeParams(Settings *settings) const
}
+void MapgenV5Params::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mgv5_spflags", flagdesc_mapgen_v5, MGV5_CAVERNS);
+}
+
+
+/////////////////////////////////////////////////////////////////
+
+
int MapgenV5::getSpawnLevelAtPoint(v2s16 p)
{
diff --git a/src/mapgen/mapgen_v5.h b/src/mapgen/mapgen_v5.h
index ecdcdaf41..17bc466f0 100644
--- a/src/mapgen/mapgen_v5.h
+++ b/src/mapgen/mapgen_v5.h
@@ -31,7 +31,6 @@ extern FlagDesc flagdesc_mapgen_v5[];
struct MapgenV5Params : public MapgenParams
{
- u32 spflags = MGV5_CAVERNS;
float cave_width = 0.09f;
s16 large_cave_depth = -256;
u16 small_cave_num_min = 0;
@@ -59,6 +58,7 @@ struct MapgenV5Params : public MapgenParams
void readParams(const Settings *settings);
void writeParams(Settings *settings) const;
+ void setDefaultSettings(Settings *settings);
};
class MapgenV5 : public MapgenBasic
diff --git a/src/mapgen/mapgen_v6.cpp b/src/mapgen/mapgen_v6.cpp
index 4e876fc53..653adc8ec 100644
--- a/src/mapgen/mapgen_v6.cpp
+++ b/src/mapgen/mapgen_v6.cpp
@@ -190,7 +190,7 @@ void MapgenV6Params::readParams(const Settings *settings)
void MapgenV6Params::writeParams(Settings *settings) const
{
- settings->setFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6, U32_MAX);
+ settings->setFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6);
settings->setFloat("mgv6_freq_desert", freq_desert);
settings->setFloat("mgv6_freq_beach", freq_beach);
settings->setS16("mgv6_dungeon_ymin", dungeon_ymin);
@@ -210,8 +210,16 @@ void MapgenV6Params::writeParams(Settings *settings) const
}
+void MapgenV6Params::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mgv6_spflags", flagdesc_mapgen_v6, MGV6_JUNGLES |
+ MGV6_SNOWBIOMES | MGV6_TREES | MGV6_BIOMEBLEND | MGV6_MUDFLOW);
+}
+
+
//////////////////////// Some helper functions for the map generator
+
// Returns Y one under area minimum if not found
s16 MapgenV6::find_stone_level(v2s16 p2d)
{
diff --git a/src/mapgen/mapgen_v6.h b/src/mapgen/mapgen_v6.h
index 7d5229559..d8cdcb26f 100644
--- a/src/mapgen/mapgen_v6.h
+++ b/src/mapgen/mapgen_v6.h
@@ -55,8 +55,6 @@ enum BiomeV6Type
struct MapgenV6Params : public MapgenParams {
- u32 spflags = MGV6_JUNGLES | MGV6_SNOWBIOMES | MGV6_TREES |
- MGV6_BIOMEBLEND | MGV6_MUDFLOW;
float freq_desert = 0.45f;
float freq_beach = 0.15f;
s16 dungeon_ymin = -31000;
@@ -79,6 +77,7 @@ struct MapgenV6Params : public MapgenParams {
void readParams(const Settings *settings);
void writeParams(Settings *settings) const;
+ void setDefaultSettings(Settings *settings);
};
diff --git a/src/mapgen/mapgen_v7.cpp b/src/mapgen/mapgen_v7.cpp
index 23cbd4e0a..325c4957a 100644
--- a/src/mapgen/mapgen_v7.cpp
+++ b/src/mapgen/mapgen_v7.cpp
@@ -183,7 +183,7 @@ void MapgenV7Params::readParams(const Settings *settings)
void MapgenV7Params::writeParams(Settings *settings) const
{
- settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7, U32_MAX);
+ settings->setFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7);
settings->setS16("mgv7_mount_zero_level", mount_zero_level);
settings->setFloat("mgv7_cave_width", cave_width);
settings->setS16("mgv7_large_cave_depth", large_cave_depth);
@@ -214,6 +214,13 @@ void MapgenV7Params::writeParams(Settings *settings) const
}
+void MapgenV7Params::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mgv7_spflags", flagdesc_mapgen_v7,
+ MGV7_MOUNTAINS | MGV7_RIDGES | MGV7_CAVERNS);
+}
+
+
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/mapgen/mapgen_v7.h b/src/mapgen/mapgen_v7.h
index 6ca39f164..0605c5c97 100644
--- a/src/mapgen/mapgen_v7.h
+++ b/src/mapgen/mapgen_v7.h
@@ -35,7 +35,6 @@ extern FlagDesc flagdesc_mapgen_v7[];
struct MapgenV7Params : public MapgenParams {
- u32 spflags = MGV7_MOUNTAINS | MGV7_RIDGES | MGV7_CAVERNS;
s16 mount_zero_level = 0;
float cave_width = 0.09f;
@@ -70,6 +69,7 @@ struct MapgenV7Params : public MapgenParams {
void readParams(const Settings *settings);
void writeParams(Settings *settings) const;
+ void setDefaultSettings(Settings *settings);
};
diff --git a/src/mapgen/mapgen_valleys.cpp b/src/mapgen/mapgen_valleys.cpp
index 3c6045105..2b8703fa5 100644
--- a/src/mapgen/mapgen_valleys.cpp
+++ b/src/mapgen/mapgen_valleys.cpp
@@ -162,7 +162,7 @@ void MapgenValleysParams::readParams(const Settings *settings)
void MapgenValleysParams::writeParams(Settings *settings) const
{
- settings->setFlagStr("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys, U32_MAX);
+ settings->setFlagStr("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys);
settings->setU16("mgvalleys_altitude_chill", altitude_chill);
settings->setS16("mgvalleys_large_cave_depth", large_cave_depth);
settings->setU16("mgvalleys_small_cave_num_min", small_cave_num_min);
@@ -194,6 +194,17 @@ void MapgenValleysParams::writeParams(Settings *settings) const
}
+void MapgenValleysParams::setDefaultSettings(Settings *settings)
+{
+ settings->setDefault("mgvalleys_spflags", flagdesc_mapgen_valleys,
+ MGVALLEYS_ALT_CHILL | MGVALLEYS_HUMID_RIVERS |
+ MGVALLEYS_VARY_RIVER_DEPTH | MGVALLEYS_ALT_DRY);
+}
+
+
+/////////////////////////////////////////////////////////////////
+
+
void MapgenValleys::makeChunk(BlockMakeData *data)
{
// Pre-conditions
diff --git a/src/mapgen/mapgen_valleys.h b/src/mapgen/mapgen_valleys.h
index be97f0763..1aec68842 100644
--- a/src/mapgen/mapgen_valleys.h
+++ b/src/mapgen/mapgen_valleys.h
@@ -41,8 +41,6 @@ extern FlagDesc flagdesc_mapgen_valleys[];
struct MapgenValleysParams : public MapgenParams {
- u32 spflags = MGVALLEYS_ALT_CHILL | MGVALLEYS_HUMID_RIVERS |
- MGVALLEYS_VARY_RIVER_DEPTH | MGVALLEYS_ALT_DRY;
u16 altitude_chill = 90;
u16 river_depth = 4;
u16 river_size = 5;
@@ -78,6 +76,7 @@ struct MapgenValleysParams : public MapgenParams {
void readParams(const Settings *settings);
void writeParams(Settings *settings) const;
+ void setDefaultSettings(Settings *settings);
};
diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp
index cc2c73789..33eb02392 100644
--- a/src/script/lua_api/l_settings.cpp
+++ b/src/script/lua_api/l_settings.cpp
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_settings.h"
#include "lua_api/l_internal.h"
#include "cpp_api/s_security.h"
+#include "util/string.h" // FlagDesc
#include "settings.h"
#include "noise.h"
#include "log.h"
@@ -128,6 +129,29 @@ int LuaSettings::l_get_np_group(lua_State *L)
return 1;
}
+int LuaSettings::l_get_flags(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ LuaSettings *o = checkobject(L, 1);
+ std::string key = std::string(luaL_checkstring(L, 2));
+
+ u32 flags = 0;
+ auto flagdesc = o->m_settings->getFlagDescFallback(key);
+ if (o->m_settings->getFlagStrNoEx(key, flags, flagdesc)) {
+ lua_newtable(L);
+ int table = lua_gettop(L);
+ for (size_t i = 0; flagdesc[i].name; ++i) {
+ lua_pushboolean(L, flags & flagdesc[i].flag);
+ lua_setfield(L, table, flagdesc[i].name);
+ }
+ lua_pushvalue(L, table);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
// set(self, key, value)
int LuaSettings::l_set(lua_State* L)
{
@@ -305,6 +329,7 @@ const luaL_Reg LuaSettings::methods[] = {
luamethod(LuaSettings, get),
luamethod(LuaSettings, get_bool),
luamethod(LuaSettings, get_np_group),
+ luamethod(LuaSettings, get_flags),
luamethod(LuaSettings, set),
luamethod(LuaSettings, set_bool),
luamethod(LuaSettings, set_np_group),
diff --git a/src/script/lua_api/l_settings.h b/src/script/lua_api/l_settings.h
index dcf39a89e..67d7b342b 100644
--- a/src/script/lua_api/l_settings.h
+++ b/src/script/lua_api/l_settings.h
@@ -42,6 +42,9 @@ private:
// get_np_group(self, key) -> noiseparam
static int l_get_np_group(lua_State *L);
+ // get_flags(self, key) -> key/value table
+ static int l_get_flags(lua_State *L);
+
// set(self, key, value)
static int l_set(lua_State *L);
diff --git a/src/settings.cpp b/src/settings.cpp
index c1fe41fa3..3728fabf2 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -484,12 +484,33 @@ v3f Settings::getV3F(const std::string &name) const
u32 Settings::getFlagStr(const std::string &name, const FlagDesc *flagdesc,
u32 *flagmask) const
{
- std::string val = get(name);
- return std::isdigit(val[0])
- ? stoi(val)
- : readFlagString(val, flagdesc, flagmask);
-}
+ u32 flags = 0;
+ u32 mask_default = 0;
+
+ std::string value;
+ // Read default value (if there is any)
+ if (getDefaultNoEx(name, value)) {
+ flags = std::isdigit(value[0])
+ ? stoi(value)
+ : readFlagString(value, flagdesc, &mask_default);
+ }
+
+ // Apply custom flags "on top"
+ value = get(name);
+ u32 flags_user;
+ u32 mask_user = U32_MAX;
+ flags_user = std::isdigit(value[0])
+ ? stoi(value) // Override default
+ : readFlagString(value, flagdesc, &mask_user);
+ flags &= ~mask_user;
+ flags |= flags_user;
+
+ if (flagmask)
+ *flagmask = mask_default | mask_user;
+
+ return flags;
+}
// N.B. if getStruct() is used to read a non-POD aggregate type,
// the behavior is undefined.
@@ -736,19 +757,16 @@ bool Settings::getV3FNoEx(const std::string &name, v3f &val) const
}
-// 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 Settings::getFlagStrNoEx(const std::string &name, u32 &val,
- FlagDesc *flagdesc) const
+ const FlagDesc *flagdesc) const
{
- try {
- u32 flags, flagmask;
-
- flags = getFlagStr(name, flagdesc, &flagmask);
+ if (!flagdesc) {
+ if (!(flagdesc = getFlagDescFallback(name)))
+ return false; // Not found
+ }
- val &= ~flagmask;
- val |= flags;
+ try {
+ val = getFlagStr(name, flagdesc, nullptr);
return true;
} catch (SettingNotFoundException &e) {
@@ -873,6 +891,11 @@ bool Settings::setV3F(const std::string &name, v3f value)
bool Settings::setFlagStr(const std::string &name, u32 flags,
const FlagDesc *flagdesc, u32 flagmask)
{
+ if (!flagdesc) {
+ if (!(flagdesc = getFlagDescFallback(name)))
+ return false; // Not found
+ }
+
return set(name, writeFlagString(flags, flagdesc, flagmask));
}
@@ -1018,6 +1041,18 @@ void Settings::clearDefaultsNoLock()
m_defaults.clear();
}
+void Settings::setDefault(const std::string &name, const FlagDesc *flagdesc,
+ u32 flags)
+{
+ m_flags[name] = flagdesc;
+ setDefault(name, writeFlagString(flags, flagdesc, U32_MAX));
+}
+
+const FlagDesc *Settings::getFlagDescFallback(const std::string &name) const
+{
+ auto it = m_flags.find(name);
+ return it == m_flags.end() ? nullptr : it->second;
+}
void Settings::registerChangedCallback(const std::string &name,
SettingsChangedCallback cbf, void *userdata)
diff --git a/src/settings.h b/src/settings.h
index 329a61140..b42e36d10 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -174,10 +174,12 @@ public:
bool getFloatNoEx(const std::string &name, float &val) const;
bool getV2FNoEx(const std::string &name, v2f &val) const;
bool getV3FNoEx(const std::string &name, v3f &val) const;
- // 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(const std::string &name, u32 &val, FlagDesc *flagdesc) const;
+
+ // Like other getters, but handling each flag individualy:
+ // 1) Read default flags (or 0)
+ // 2) Override using user-defined flags
+ bool getFlagStrNoEx(const std::string &name, u32 &val,
+ const FlagDesc *flagdesc) const;
/***********
@@ -201,7 +203,7 @@ public:
bool setV2F(const std::string &name, v2f value);
bool setV3F(const std::string &name, v3f value);
bool setFlagStr(const std::string &name, u32 flags,
- const FlagDesc *flagdesc, u32 flagmask);
+ const FlagDesc *flagdesc = nullptr, u32 flagmask = U32_MAX);
bool setNoiseParams(const std::string &name, const NoiseParams &np,
bool set_default=false);
// N.B. if setStruct() is used to write a non-POD aggregate type,
@@ -215,6 +217,13 @@ public:
void updateValue(const Settings &other, const std::string &name);
void update(const Settings &other);
+ /**************
+ * Miscellany *
+ **************/
+
+ void setDefault(const std::string &name, const FlagDesc *flagdesc, u32 flags);
+ const FlagDesc *getFlagDescFallback(const std::string &name) const;
+
void registerChangedCallback(const std::string &name,
SettingsChangedCallback cbf, void *userdata = NULL);
void deregisterChangedCallback(const std::string &name,
@@ -229,6 +238,7 @@ private:
SettingEntries m_settings;
SettingEntries m_defaults;
+ std::unordered_map<std::string, const FlagDesc *> m_flags;
SettingsCallbackMap m_callbacks;
diff --git a/src/unittest/test_settings.cpp b/src/unittest/test_settings.cpp
index b2666559e..aa56f3e06 100644
--- a/src/unittest/test_settings.cpp
+++ b/src/unittest/test_settings.cpp
@@ -31,6 +31,7 @@ public:
void runTests(IGameDef *gamedef);
void testAllSettings();
+ void testFlagDesc();
static const char *config_text_before;
static const std::string config_text_after;
@@ -41,6 +42,7 @@ static TestSettings g_test_instance;
void TestSettings::runTests(IGameDef *gamedef)
{
TEST(testAllSettings);
+ TEST(testFlagDesc);
}
////////////////////////////////////////////////////////////////////////////////
@@ -206,3 +208,38 @@ void TestSettings::testAllSettings()
UASSERT(!"Setting not found!");
}
}
+
+void TestSettings::testFlagDesc()
+{
+ Settings s;
+ FlagDesc flagdesc[] = {
+ { "biomes", 0x01 },
+ { "trees", 0x02 },
+ { "jungles", 0x04 },
+ { "oranges", 0x08 },
+ { "tables", 0x10 },
+ { nullptr, 0 }
+ };
+
+ // Enabled: biomes, jungles, oranges (default)
+ s.setDefault("test_desc", flagdesc, readFlagString(
+ "biomes,notrees,jungles,oranges", flagdesc, nullptr));
+ UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == (0x01 | 0x04 | 0x08));
+
+ // Enabled: jungles, oranges, tables
+ s.set("test_desc", "nobiomes,tables");
+ UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == (0x04 | 0x08 | 0x10));
+
+ // Enabled: (nothing)
+ s.set("test_desc", "nobiomes,nojungles,nooranges,notables");
+ UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == 0x00);
+
+ // Numeric flag tests (override)
+ // Enabled: trees, tables
+ s.setDefault("test_flags", flagdesc, 0x02 | 0x10);
+ UASSERT(s.getFlagStr("test_flags", flagdesc, nullptr) == (0x02 | 0x10));
+
+ // Enabled: tables
+ s.set("test_flags", "16");
+ UASSERT(s.getFlagStr("test_flags", flagdesc, nullptr) == 0x10);
+}