Lua: improve level testing

Add des.finalize_level() used for testing in conjunction with
des.reset_level().
Add nhc.DLB to return 0 or 1 if DLB was defined at compile-time.
Change the test_lev.lua to give more informative messages instead of
just lua error when required file doesn't exist.
Add bigrm-11 to the level tests.
This commit is contained in:
Pasi Kallinen
2021-07-24 10:28:35 +03:00
parent 93b66ff8da
commit 7f39d53ad3
9 changed files with 120 additions and 66 deletions

View File

@@ -352,6 +352,14 @@ Example:
des.feature({ type = "throne", coord = {4, 6}, looted = true });
des.feature({ type = "tree", coord = {4, 6}, looted = true, swarm = false });
=== finalize_level
Only used for testing purposes. See also <<_reset_level>>.
Example:
des.finalize_level();
=== gold
Create a pile of gold.
@@ -613,7 +621,7 @@ Example:
=== reset_level
Only used for testing purposes.
Only used for testing purposes. See also <<_finalize_level>>.
Example:

View File

@@ -1251,6 +1251,7 @@ extern void free_luathemes(boolean);
extern void makecorridors(void);
extern void add_door(int, int, struct mkroom *);
extern void clear_level_structures(void);
extern void level_finalize_topology(void);
extern void mklev(void);
#ifdef SPECIALIZATION
extern void topologize(struct mkroom *, boolean));
@@ -2450,6 +2451,8 @@ extern void selection_do_ellipse(struct selectionvar *, int, int, int, int,
int);
extern void selection_do_gradient(struct selectionvar *, long, long, long,
long, long, long, long, long);
extern int lspo_reset_level(lua_State *);
extern int lspo_finalize_level(lua_State *);
extern void update_croom(void);
extern const char *get_trapname_bytype(int);
extern void l_register_des(lua_State *);

View File

@@ -173,6 +173,7 @@ struct instance_flags {
* behaviour of various NetHack functions and probably warrant
* a structure of their own elsewhere some day.
*/
boolean lua_testing; /* doing lua tests */
boolean debug_fuzzer; /* fuzz testing */
boolean in_lua; /* executing a lua script */
boolean defer_plname; /* X11 hack: askname() might not set g.plname */

View File

@@ -1078,9 +1078,7 @@ static int
wiz_load_splua(void)
{
if (wizard) {
boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
char buf[BUFSZ];
int ridx;
buf[0] = '\0';
getlin("Load which des lua file?", buf);
@@ -1088,37 +1086,11 @@ wiz_load_splua(void)
return 0;
if (!strchr(buf, '.'))
strcat(buf, ".lua");
makemap_prepost(TRUE, was_in_W_tower);
/* TODO: need to split some of this out of mklev(), makelevel(),
makemaz() */
g.in_mklev = TRUE;
oinit(); /* assign level dependent obj probabilities */
clear_level_structures();
lspo_reset_level(NULL);
(void) load_special(buf);
lspo_finalize_level(NULL);
bound_digging();
mineralize(-1, -1, -1, -1, FALSE);
g.in_mklev = FALSE;
if (g.level.flags.has_morgue)
g.level.flags.graveyard = 1;
if (!g.level.flags.is_maze_lev) {
struct mkroom *croom;
for (croom = &g.rooms[0]; croom != &g.rooms[g.nroom]; croom++)
#ifdef SPECIALIZATION
topologize(croom, FALSE);
#else
topologize(croom);
#endif
}
set_wall_state();
/* for many room types, rooms[].rtype is zeroed once the room has been
entered; rooms[].orig_rtype always retains original rtype value */
for (ridx = 0; ridx < SIZE(g.rooms); ridx++)
g.rooms[ridx].orig_rtype = g.rooms[ridx].rtype;
makemap_prepost(FALSE, was_in_W_tower);
} else
pline("Unavailable command 'wiz_load_splua'.");
return 0;

View File

@@ -1067,20 +1067,11 @@ mineralize(int kelp_pool, int kelp_moat, int goldprob, int gemprob,
}
void
mklev(void)
level_finalize_topology(void)
{
struct mkroom *croom;
int ridx;
reseed_random(rn2);
reseed_random(rn2_on_display_rng);
init_mapseen(&u.uz);
if (getbones())
return;
g.in_mklev = TRUE;
makelevel();
bound_digging();
mineralize(-1, -1, -1, -1, FALSE);
g.in_mklev = FALSE;
@@ -1102,6 +1093,22 @@ mklev(void)
entered; g.rooms[].orig_rtype always retains original rtype value */
for (ridx = 0; ridx < SIZE(g.rooms); ridx++)
g.rooms[ridx].orig_rtype = g.rooms[ridx].rtype;
}
void
mklev(void)
{
reseed_random(rn2);
reseed_random(rn2_on_display_rng);
init_mapseen(&u.uz);
if (getbones())
return;
g.in_mklev = TRUE;
makelevel();
level_finalize_topology();
reseed_random(rn2);
reseed_random(rn2_on_display_rng);

View File

@@ -976,6 +976,11 @@ static const struct {
} nhl_consts[] = {
{ "COLNO", COLNO },
{ "ROWNO", ROWNO },
#ifdef DLB
{ "DLB", 1},
#else
{ "DLB", 0},
#endif /* DLB */
{ NULL, 0 },
};

View File

@@ -505,27 +505,6 @@ savelev(NHFILE* nhfp, xchar lev)
saveobjchn(nhfp, &fobj);
saveobjchn(nhfp, &g.level.buriedobjlist);
saveobjchn(nhfp, &g.billobjs);
if (release_data(nhfp)) {
int x,y;
/* TODO: maybe use clear_level_structures() */
for (y = 0; y < ROWNO; y++)
for (x = 0; x < COLNO; x++) {
g.level.monsters[x][y] = 0;
g.level.objects[x][y] = 0;
levl[x][y].seenv = 0;
levl[x][y].glyph = GLYPH_UNEXPLORED;
}
fmon = 0;
g.ftrap = 0;
fobj = 0;
g.level.buriedobjlist = 0;
g.billobjs = 0;
stairway_free_all();
(void) memset(g.rooms, 0, sizeof(g.rooms));
g.nroom = g.nsubroom = 0;
g.rooms[0].hx = g.subrooms[0].hx = -1;
/* level.bonesinfo = 0; -- handled by savecemetery() */
}
save_engravings(nhfp);
savedamage(nhfp); /* pending shop wall and/or floor repair */
save_regions(nhfp);
@@ -534,6 +513,12 @@ savelev(NHFILE* nhfp, xchar lev)
bflush(nhfp->fd);
}
g.program_state.saving--;
if (release_data(nhfp)) {
clear_level_structures();
g.ftrap = 0;
g.billobjs = 0;
(void) memset(g.rooms, 0, sizeof(g.rooms));
}
return;
}

View File

@@ -146,6 +146,7 @@ int lspo_random_corridors(lua_State *);
int lspo_region(lua_State *);
int lspo_replace_terrain(lua_State *);
int lspo_reset_level(lua_State *);
int lspo_finalize_level(lua_State *);
int lspo_room(lua_State *);
int lspo_stair(lua_State *);
int lspo_teleport_region(lua_State *);
@@ -2285,7 +2286,7 @@ create_object(object* o, struct mkroom* croom)
} else {
impossible(prize_warning, "sokoban end");
}
} else {
} else if (!iflags.lua_testing) {
char lbuf[QBUFSZ];
(void) describe_level(lbuf); /* always has a trailing space */
@@ -5906,12 +5907,68 @@ lspo_reset_level(lua_State *L UNUSED)
{
boolean wtower = In_W_tower(u.ux, u.uy, &u.uz);
create_des_coder();
iflags.lua_testing = TRUE;
if (L)
create_des_coder();
makemap_prepost(TRUE, wtower);
g.in_mklev = TRUE;
oinit(); /* assign level dependent obj probabilities */
clear_level_structures();
return 0;
}
/* finalize_level is only needed for testing purposes */
int
lspo_finalize_level(lua_State *L UNUSED)
{
boolean wtower = In_W_tower(u.ux, u.uy, &u.uz);
int i;
if (L)
create_des_coder();
link_doors_rooms();
remove_boundary_syms();
/* TODO: ensure_way_out() needs rewrite */
if (L && g.coder->check_inaccessibles)
ensure_way_out();
/* FIXME: Ideally, we want this call to only cover areas of the map
* which were not inserted directly by the special level file (see
* the insect legs on Baalzebub's level, for instance). Since that
* is currently not possible, we overload the corrmaze flag for this
* purpose.
*/
if (!g.level.flags.corrmaze)
wallification(1, 0, COLNO - 1, ROWNO - 1);
if (L)
flip_level_rnd(g.coder->allow_flips, FALSE);
count_features();
if (L && g.coder->solidify)
solidify_map();
/* This must be done before sokoban_detect(),
* otherwise branch stairs won't be premapped. */
fixup_special();
if (L && g.coder->premapped)
sokoban_detect();
level_finalize_topology();
for (i = 0; i < g.nroom; ++i) {
fill_special_room(&g.rooms[i]);
}
makemap_prepost(FALSE, wtower);
iflags.lua_testing = FALSE;
return 0;
}
/* map({ x = 10, y = 10, map = [[...]] }); */
/* map({ coord = {10, 10}, map = [[...]] }); */
/* map({ halign = "center", valign = "center", map = [[...]] }); */
@@ -6258,6 +6315,7 @@ static const struct luaL_Reg nhl_functions[] = {
{ "non_passwall", lspo_non_passwall },
{ "teleport_region", lspo_teleport_region },
{ "reset_level", lspo_reset_level },
{ "finalize_level", lspo_finalize_level },
/* TODO: { "branch", lspo_branch }, */
/* TODO: { "portal", lspo_portal }, */
{ NULL, NULL }

View File

@@ -1,12 +1,22 @@
-- Test all of the special levels
function saferequire(file)
if (not pcall(require, file)) then
nh.pline("Cannot load level file '" .. file .. "'.");
if (nhc.DLB == 1) then
nh.pline("Maybe due to compile-time option DLB.")
end
return false;
end
return true;
end;
local special_levels = {
"air",
"asmodeus",
"astral",
"baalz",
"bigrm-10",
"bigrm-1",
"bigrm-2",
"bigrm-3",
@@ -16,6 +26,8 @@ local special_levels = {
"bigrm-7",
"bigrm-8",
"bigrm-9",
"bigrm-10",
"bigrm-11",
"castle",
"earth",
"fakewiz1",
@@ -71,5 +83,8 @@ end
for _,lev in ipairs(special_levels) do
des.reset_level();
require(lev)
if (not saferequire(lev)) then
error("Cannot load a required file.");
end
des.finalize_level();
end