Lua tests: generation of each object

Test generation of every object, both via des.object and obj.new.
Expose FIRST_OBJECT and LAST_OBJECT numbers to lua.
Add lua nh.int_to_objname, a function to convert integer value to
object base name and class.
Allow creating new nethack lua object by specifying id and class.
This commit is contained in:
Pasi Kallinen
2026-01-26 17:49:45 +02:00
parent b5ca1a3ed8
commit 11bed1f55b
7 changed files with 122 additions and 16 deletions

View File

@@ -345,12 +345,13 @@ DISABLE_WARNING_UNREACHABLE_CODE
/* create a new object via wishing routine */
/* local o = obj.new("rock"); */
/* local o = obj.new({ id = "food ration", class = "%" }); */
staticfn int
l_obj_new_readobjnam(lua_State *L)
{
int argc = lua_gettop(L);
if (argc == 1) {
if (argc == 1 && lua_type(L, 1) == LUA_TSTRING) {
char buf[BUFSZ];
struct obj *otmp;
@@ -360,6 +361,22 @@ l_obj_new_readobjnam(lua_State *L)
otmp = NULL;
(void) l_obj_push(L, otmp);
return 1;
} else if (argc == 1 && lua_type(L, 1) == LUA_TTABLE) {
short id = get_table_objtype(L);
xint16 class = get_table_objclass(L);
struct obj *otmp;
if (id >= FIRST_OBJECT) {
otmp = mksobj(id, TRUE, FALSE);
} else {
class = def_char_to_objclass(class);
if (class >= MAXOCLASSES)
class = RANDOM_CLASS;
otmp = mkobj(class, FALSE);
}
lua_pop(L, 1);
(void) l_obj_push(L, otmp);
return 1;
} else
nhl_error(L, "l_obj_new_readobjname: Wrong args");
/*NOTREACHED*/

View File

@@ -32,6 +32,7 @@ staticfn int nhl_dump_fmtstr(lua_State *);
#endif /* DUMPLOG */
staticfn int nhl_dnum_name(lua_State *);
staticfn int nhl_int_to_pm_name(lua_State *);
staticfn int nhl_int_to_obj_name(lua_State *);
staticfn int nhl_stairways(lua_State *);
staticfn int nhl_pushkey(lua_State *);
staticfn int nhl_doturn(lua_State *);
@@ -1185,6 +1186,31 @@ nhl_int_to_pm_name(lua_State *L)
return 1;
}
/* convert integer to object type name and class */
/* local oname,oclass = int_to_objname(25); */
staticfn int
nhl_int_to_obj_name(lua_State *L)
{
int argc = lua_gettop(L);
if (argc == 1) {
char buf[8];
lua_Integer i = luaL_checkinteger(L, 1);
if (i >= 0 && i < NUM_OBJECTS && OBJ_NAME(objects[i])) {
lua_pushstring(L, OBJ_NAME(objects[i]));
buf[0] = def_oc_syms[(int)objects[i].oc_class].sym;
buf[1] = '\0';
lua_pushstring(L, buf);
} else {
lua_pushstring(L, "");
lua_pushstring(L, "");
}
} else
nhl_error(L, "Expected an integer parameter");
return 2;
}
DISABLE_WARNING_UNREACHABLE_CODE
/* because nhl_error() does not return */
@@ -1858,6 +1884,7 @@ static const struct luaL_Reg nhl_functions[] = {
#endif /* DUMPLOG */
{ "dnum_name", nhl_dnum_name },
{ "int_to_pmname", nhl_int_to_pm_name },
{ "int_to_objname", nhl_int_to_obj_name },
{ "variable", nhl_variable },
{ "stairways", nhl_stairways },
{ "pushkey", nhl_pushkey },
@@ -1876,6 +1903,8 @@ static const struct {
{ "NUMMONS", NUMMONS },
{ "LOW_PM", LOW_PM },
{ "HIGH_PM", HIGH_PM },
{ "FIRST_OBJECT", FIRST_OBJECT },
{ "LAST_OBJECT", NUM_OBJECTS-1 },
#ifdef DLB
{ "DLB", 1 },
#else

View File

@@ -117,9 +117,7 @@ staticfn int find_montype(lua_State *, const char *, int *);
staticfn int get_table_montype(lua_State *, int *);
staticfn lua_Integer get_table_int_or_random(lua_State *, const char *, int);
staticfn int get_table_buc(lua_State *);
staticfn int get_table_objclass(lua_State *);
staticfn int find_objtype(lua_State *, const char *);
staticfn int get_table_objtype(lua_State *);
staticfn int find_objtype(lua_State *, const char *, char);
staticfn const char *get_mkroom_name(int) NONNULL;
staticfn int get_table_roomtype_opt(lua_State *, const char *, int);
staticfn int get_table_traptype_opt(lua_State *, const char *, int);
@@ -3443,7 +3441,7 @@ get_table_buc(lua_State *L)
return curse_state;
}
staticfn int
int
get_table_objclass(lua_State *L)
{
char *s = get_table_str_opt(L, "class", NULL);
@@ -3455,13 +3453,14 @@ get_table_objclass(lua_State *L)
return ret;
}
/* find object otyp by text s (optionally considering oclass) */
staticfn int
find_objtype(lua_State *L, const char *s)
find_objtype(lua_State *L, const char *s, char oclass)
{
if (s && *s) {
int i;
const char *objname;
char class = 0;
char class = def_char_to_objclass(oclass);
/* In objects.h, some item classes are defined without prefixes
(such as "scroll of ") in their names, making some names (such
@@ -3479,6 +3478,9 @@ find_objtype(lua_State *L, const char *s)
{ NULL, 0 }
};
if (class == MAXOCLASSES)
class = 0;
if (strstri(s, " of ")) {
for (i = 0; class_prefixes[i].prefix; i++) {
const char *p = class_prefixes[i].prefix;
@@ -3523,11 +3525,12 @@ find_objtype(lua_State *L, const char *s)
return STRANGE_OBJECT;
}
staticfn int
int
get_table_objtype(lua_State *L)
{
char *s = get_table_str_opt(L, "id", NULL);
int ret = find_objtype(L, s);
char oclass = get_table_objclass(L);
int ret = find_objtype(L, s, oclass);
Free(s);
return ret;
@@ -3586,7 +3589,7 @@ lspo_object(lua_State *L)
tmpobj.id = STRANGE_OBJECT;
} else {
tmpobj.class = -1;
tmpobj.id = find_objtype(L, paramstr);
tmpobj.id = find_objtype(L, paramstr, -1);
}
} else if (argc == 2 && lua_type(L, 1) == LUA_TSTRING
&& lua_type(L, 2) == LUA_TTABLE) {
@@ -3599,7 +3602,7 @@ lspo_object(lua_State *L)
tmpobj.id = STRANGE_OBJECT;
} else {
tmpobj.class = -1;
tmpobj.id = find_objtype(L, paramstr);
tmpobj.id = find_objtype(L, paramstr, -1);
}
} else if (argc == 3 && lua_type(L, 2) == LUA_TNUMBER
&& lua_type(L, 3) == LUA_TNUMBER) {
@@ -3613,7 +3616,7 @@ lspo_object(lua_State *L)
tmpobj.id = STRANGE_OBJECT;
} else {
tmpobj.class = -1;
tmpobj.id = find_objtype(L, paramstr);
tmpobj.id = find_objtype(L, paramstr, -1);
}
} else {
lcheck_param_table(L);