Add capability to read table flag fields from Lua API

master
kwolekr 2014-02-09 12:38:50 -05:00
parent 57710520dc
commit 2a01050a0c
7 changed files with 83 additions and 3 deletions

View File

@ -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):

View File

@ -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

View File

@ -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;
}
/******************************************************************************/

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);