Skip to content

Commit

Permalink
Add capability to read table flag fields from Lua API
Browse files Browse the repository at this point in the history
  • Loading branch information
kwolekr committed Feb 9, 2014
1 parent 5771052 commit 2a01050
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 3 deletions.
22 changes: 22 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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):
Expand Down
5 changes: 5 additions & 0 deletions src/porting.h
Expand Up @@ -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
Expand Down
41 changes: 39 additions & 2 deletions src/script/common/c_content.cpp
Expand Up @@ -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;
}

/******************************************************************************/
Expand Down
3 changes: 3 additions & 0 deletions src/script/common/c_content.h
Expand Up @@ -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);

Expand Down
1 change: 0 additions & 1 deletion src/script/lua_api/l_mapgen.cpp
Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions src/util/string.cpp
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/util/string.h
Expand Up @@ -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);

Expand Down

0 comments on commit 2a01050

Please sign in to comment.