]> granicus.if.org Git - nethack/commitdiff
Lua: improve level testing
authorPasi Kallinen <paxed@alt.org>
Sat, 24 Jul 2021 07:28:35 +0000 (10:28 +0300)
committerPasi Kallinen <paxed@alt.org>
Sat, 24 Jul 2021 07:49:06 +0000 (10:49 +0300)
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
include/extern.h
include/flag.h
src/cmd.c
src/mklev.c
src/nhlua.c
src/save.c
src/sp_lev.c
test/test_lev.lua

index ffd320520531c41a26aba032d46cf734fa5925c3..8d71cdd5a68f9d242bf043681d9bebf85cd011b1 100644 (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:
 
index b47a6ac583af392222555a6b289b3cf5f2afe6d9..f512bd581cc60f6341d7d898ce852e6b944ef7fe 100644 (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 *);
index 1e75ffe7ed69d8fca0ec6a3612d0747fd4cd9931..f403569dea81f3760c782f50e5065e2d7c2cb8ff 100644 (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 */
index ad03bff665417a12c17b1c58f140265c332a35ca..f93df99048c4ca6652cf2fc2e909d5dfd20843b7 100644 (file)
--- 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;
index 4da35b6e896b8ab2a3166d7ff5bf76d5e20f165d..6c639ded05f14de2e4e262c05e7771ddf326bd45 100644 (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);
index 45700a4909b09c77edf4b50ed13ea7685a99f718..96aca7484584472c8f7231160f253d8dbad37f86 100644 (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 },
 };
 
index 21a46cbb10c2529c2f027b56bb0127f3fef614ed..6334edee06fdabf84ce53b8caed444d0d6efe594 100644 (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;
 }
 
index 1cba620a4a6e6fba7c6dce9f2f79be49b19e724f..b0659c2719fa9448a043afca81492cb82c2c3fc1 100755 (executable)
@@ -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 }
index 076689a2627dfbe01015f09f46c9148223a47cbf..b6dd280b66f88099ae5efa5e3d2e37c0ae0013fa 100644 (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