summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt22
-rw-r--r--src/porting.h5
-rw-r--r--src/script/common/c_content.cpp41
-rw-r--r--src/script/common/c_content.h3
-rw-r--r--src/script/lua_api/l_mapgen.cpp1
-rw-r--r--src/util/string.cpp13
-rw-r--r--src/util/string.h1
7 files changed, 83 insertions, 3 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index aef17bec8..eb2820e27 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -410,6 +410,7 @@ All default ores are of the uniformly-distributed scatter type.
Ore attributes
-------------------
+See section Flag Specifier Format.
Currently supported flags: absheight
- absheight
Also produce this same ore between the height range of -height_max and -height_min.
@@ -451,6 +452,7 @@ Important note: Node aliases cannot be used for a raw schematic provided when re
Schematic attributes
---------------------
+See section Flag Specifier Format.
Currently supported flags: place_center_x, place_center_y, place_center_z
- place_center_x
Placement of this decoration is centered along the X axis.
@@ -525,6 +527,26 @@ pointed_thing:
{type="node", under=pos, above=pos}
{type="object", ref=ObjectRef}
+Flag Specifier Format
+-----------------------
+Flags using the standardized flag specifier format can be specified in either of two ways, by string or table.
+The string format is a comma-delimited set of flag names; whitespace and unrecognized flag fields are ignored.
+Specifying a flag in the string sets the flag, and specifying a flag prefixed by the string "no" explicitly
+clears the flag from whatever the default may be.
+In addition to the standard string flag format, the schematic flags field can also be a table of flag names
+to boolean values representing whether or not the flag is set. Additionally, if a field with the flag name
+prefixed with "no" is present, mapped to a boolean of any value, the specified flag is unset.
+
+e.g. A flag field of value
+ {place_center_x = true, place_center_y=false, place_center_z=true}
+is equivalent to
+ {place_center_x = true, noplace_center_y=true, place_center_z=true}
+which is equivalent to
+ "place_center_x, noplace_center_y, place_center_z"
+or even
+ "place_center_x, place_center_z"
+since, by default, no schematic attributes are set.
+
Items
------
Node (register_node):
diff --git a/src/porting.h b/src/porting.h
index 4cfac21d1..0f2007fa7 100644
--- a/src/porting.h
+++ b/src/porting.h
@@ -88,6 +88,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#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)
+
+ // We can't simply alias strlcpy() to MSVC's strcpy_s(), since strcpy_s
+ // by default raises an assertion error and aborts the program if the
+ // buffer is too small. So we need to define our own.
+ #define strlcpy(x, y, n) mystrlcpy(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 d1e182f9f..4e26dc245 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -842,8 +842,45 @@ void push_hit_params(lua_State *L,const HitParams &params)
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);
+ u32 flags = 0;
+
+ lua_getfield(L, table, fieldname);
+
+ if (lua_isstring(L, -1)) {
+ std::string flagstr = lua_tostring(L, -1);
+ flags = readFlagString(flagstr, flagdesc, flagmask);
+ } else if (lua_istable(L, -1)) {
+ flags = read_flags_table(L, -1, flagdesc, flagmask);
+ }
+
+ lua_pop(L, 1);
+
+ return flags;
+}
+
+u32 read_flags_table(lua_State *L, int table, FlagDesc *flagdesc, u32 *flagmask)
+{
+ u32 flags = 0, mask = 0;
+ char fnamebuf[64] = "no";
+
+ for (int i = 0; flagdesc[i].name; i++) {
+ bool result;
+
+ if (getboolfield(L, table, flagdesc[i].name, result)) {
+ mask |= flagdesc[i].flag;
+ if (result)
+ flags |= flagdesc[i].flag;
+ }
+
+ strlcpy(fnamebuf + 2, flagdesc[i].name, sizeof(fnamebuf) - 2);
+ if (getboolfield(L, table, fnamebuf, result))
+ mask |= flagdesc[i].flag;
+ }
+
+ if (flagmask)
+ *flagmask = mask;
+
+ return flags;
}
/******************************************************************************/
diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h
index a89de1aad..61617d7ab 100644
--- a/src/script/common/c_content.h
+++ b/src/script/common/c_content.h
@@ -123,6 +123,9 @@ u32 getflagsfield (lua_State *L, int table,
const char *fieldname,
FlagDesc *flagdesc, u32 *flagmask);
+u32 read_flags_table (lua_State *L, int table,
+ FlagDesc *flagdesc, u32 *flagmask);
+
void push_items (lua_State *L,
const std::vector<ItemStack> &items);
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index 4c6bca74e..2e6d848b3 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -456,7 +456,6 @@ int ModApiMapgen::l_register_ore(lua_State *L)
ore->height_max = getintfield_default(L, index, "height_max", 0);
ore->flags = getflagsfield(L, index, "flags", flagdesc_ore, NULL);
ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.);
-
lua_getfield(L, index, "wherein");
if (lua_istable(L, -1)) {
int i = lua_gettop(L);
diff --git a/src/util/string.cpp b/src/util/string.cpp
index afe40610c..a3888c9ce 100644
--- a/src/util/string.cpp
+++ b/src/util/string.cpp
@@ -163,6 +163,19 @@ std::string writeFlagString(u32 flags, FlagDesc *flagdesc, u32 flagmask)
return result;
}
+size_t mystrlcpy(char *dst, const char *src, size_t size)
+{
+ size_t srclen = strlen(src) + 1;
+ size_t copylen = MYMIN(srclen, size);
+
+ if (copylen > 0) {
+ memcpy(dst, src, copylen);
+ dst[copylen - 1] = '\0';
+ }
+
+ return srclen;
+}
+
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 d6a9926ab..9bb89f14a 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -321,6 +321,7 @@ std::string urlencode(std::string str);
std::string urldecode(std::string str);
u32 readFlagString(std::string str, FlagDesc *flagdesc, u32 *flagmask);
std::string writeFlagString(u32 flags, FlagDesc *flagdesc, u32 flagmask);
+size_t mystrlcpy(char *dst, const char *src, size_t size);
char *mystrtok_r(char *s, const char *sep, char **lasts);
u64 read_seed(const char *str);