From 7f39d53ad3c3b0b18e22ebcfac89163923efe381 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 24 Jul 2021 10:28:35 +0300 Subject: [PATCH] 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. --- doc/lua.adoc | 10 +++++++- include/extern.h | 3 +++ include/flag.h | 1 + src/cmd.c | 32 ++---------------------- src/mklev.c | 27 +++++++++++++-------- src/nhlua.c | 5 ++++ src/save.c | 27 +++++---------------- src/sp_lev.c | 62 +++++++++++++++++++++++++++++++++++++++++++++-- test/test_lev.lua | 19 +++++++++++++-- 9 files changed, 120 insertions(+), 66 deletions(-) diff --git a/doc/lua.adoc b/doc/lua.adoc index ffd320520..8d71cdd5a 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -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: diff --git a/include/extern.h b/include/extern.h index b47a6ac58..f512bd581 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *); diff --git a/include/flag.h b/include/flag.h index 1e75ffe7e..f403569de 100644 --- a/include/flag.h +++ b/include/flag.h @@ -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 */ diff --git a/src/cmd.c b/src/cmd.c index ad03bff66..f93df9904 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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; diff --git a/src/mklev.c b/src/mklev.c index 4da35b6e8..6c639ded0 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -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); diff --git a/src/nhlua.c b/src/nhlua.c index 45700a490..96aca7484 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -976,6 +976,11 @@ static const struct { } nhl_consts[] = { { "COLNO", COLNO }, { "ROWNO", ROWNO }, +#ifdef DLB + { "DLB", 1}, +#else + { "DLB", 0}, +#endif /* DLB */ { NULL, 0 }, }; diff --git a/src/save.c b/src/save.c index 21a46cbb1..6334edee0 100644 --- a/src/save.c +++ b/src/save.c @@ -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; } diff --git a/src/sp_lev.c b/src/sp_lev.c index 1cba620a4..b0659c271 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -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 } diff --git a/test/test_lev.lua b/test/test_lev.lua index 076689a26..b6dd280b6 100644 --- a/test/test_lev.lua +++ b/test/test_lev.lua @@ -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 -- 2.50.1