]> granicus.if.org Git - nethack/commitdiff
Fix selection "random" grow direction, and other code cleanup
authorcopperwater <aosdict@gmail.com>
Tue, 15 Mar 2022 00:54:23 +0000 (20:54 -0400)
committerPasi Kallinen <paxed@alt.org>
Tue, 15 Mar 2022 05:44:56 +0000 (07:44 +0200)
Noticed that when I set a selection to grow in a random direction, it
instead grew in all directions, which is not what I wanted. Turns out
the -1 random dir ended up being passed straight to the code which
checks bitmasks, without any form of randomizing among directions.

So this adds code to do that, and defines W_RANDOM as -1 rather than
using a magic number. In the process I also noticed that specifying
"random" as the wall for a door in a room made it rerandomize the
direction every iteration of its loop, essentially rolling two rn2(4)s
and only proceeding if they matched. That was pointless so I cleaned it
up a bit.

Also added safety checks in the form of an impossible for des.corridor()
being called with "random" as either walldir, because this is not
implemented currently.

And lastly, I noticed that create_secret_door was entirely unused
(secret door creation is handled in create_door), so I deleted it.

The only behavior change caused by this is that the Valkyrie quest lava
pools will be a little smaller, which is the only place grow is
currently used. If it's desired to keep them the same, that should be
changed to "all".

include/extern.h
include/sp_lev.h
src/nhlsel.c
src/sp_lev.c

index 448acc20ff4df43bd7073ec7fd4acc471d9aece4..f05f1eff1ed3ebc0c272cb8c12ec483376da16e5 100644 (file)
@@ -2496,7 +2496,6 @@ extern void flip_level_rnd(int, boolean);
 extern boolean check_room(xchar *, xchar *, xchar *, xchar *, boolean);
 extern boolean create_room(xchar, xchar, xchar, xchar, xchar, xchar, xchar,
                            xchar);
-extern void create_secret_door(struct mkroom *, xchar);
 extern boolean dig_corridor(coord *, coord *, boolean, schar, schar);
 extern void fill_special_room(struct mkroom *);
 extern void wallify_map(int, int, int, int);
index 77c4dbd5cf382079702fa3319a79b7a91796a92e..1d9a95d79bb56625b01b91db7b37ec1ad1838bc7 100644 (file)
@@ -6,6 +6,7 @@
 #define SP_LEV_H
 
 /* wall directions */
+#define W_RANDOM -1
 #define W_NORTH 1
 #define W_SOUTH 2
 #define W_EAST 4
index e2059cbccd5f6db8ebeac683050784ec444b6d09..04d63c739258368a519b44ff7499aff2e936b769 100644 (file)
@@ -507,7 +507,7 @@ l_selection_grow(lua_State *L)
 {
     int argc = lua_gettop(L);
     const char *const growdirs[] = { "all", "random", "north", "west", "east", "south", NULL };
-    const int growdirs2i[] = { W_ANY, -1, W_NORTH, W_WEST, W_EAST, W_SOUTH, 0 };
+    const int growdirs2i[] = { W_ANY, W_RANDOM, W_NORTH, W_WEST, W_EAST, W_SOUTH, 0 };
 
     struct selectionvar *sel = l_selection_check(L, 1);
     int dir = growdirs2i[luaL_checkoption(L, 2, "all", growdirs)];
index 4b96399b40f1ce115c08a1bb6698d7ce93a32d0e..97f2ec936ed6c7c1dedcb2782e095a4368f75d0b 100644 (file)
@@ -99,6 +99,7 @@ static void get_table_xy_or_coord(lua_State *, int *, int *);
 static int get_table_region(lua_State *, const char *, int *, int *, int *,
                             int *, boolean);
 static void set_wallprop_in_selection(lua_State *, int);
+static xchar random_wdir(void);
 static int floodfillchk_match_under(int, int);
 static int floodfillchk_match_accessible(int, int);
 static boolean sel_flood_havepoint(int, int, xchar *, xchar *, int);
@@ -1582,6 +1583,9 @@ create_door(room_door *dd, struct mkroom *broom)
     if (dd->secret == -1)
         dd->secret = rn2(2);
 
+    if (dd->wall == W_RANDOM)
+        dd->wall = W_ANY; /* speeds things up in the below loop */
+
     if (dd->mask == -1) {
         /* is it a locked door, closed, or a doorway? */
         if (!dd->secret) {
@@ -1608,13 +1612,7 @@ create_door(room_door *dd, struct mkroom *broom)
     }
 
     for (trycnt = 0; trycnt < 100; ++trycnt) {
-        int dwall, dpos;
-
-        dwall = dd->wall;
-        if (dwall == -1) /* The wall is RANDOM */
-            dwall = 1 << rn2(4);
-
-        dpos = dd->pos;
+        int dwall = dd->wall, dpos = dd->pos;
 
         /* Convert wall and pos into an absolute coordinate! */
         switch (rn2(4)) {
@@ -1670,54 +1668,6 @@ create_door(room_door *dd, struct mkroom *broom)
     levl[x][y].doormask = dd->mask;
 }
 
-/*
- * Create a secret door in croom on any one of the specified walls.
- */
-void
-create_secret_door(
-    struct mkroom *croom,
-    xchar walls) /* any of W_NORTH | W_SOUTH | W_EAST | W_WEST (or W_ANY) */
-{
-    xchar sx, sy; /* location of the secret door */
-    int count;
-
-    for (count = 0; count < 100; count++) {
-        sx = rn1(croom->hx - croom->lx + 1, croom->lx);
-        sy = rn1(croom->hy - croom->ly + 1, croom->ly);
-
-        switch (rn2(4)) {
-        case 0: /* top */
-            if (!(walls & W_NORTH))
-                continue;
-            sy = croom->ly - 1;
-            break;
-        case 1: /* bottom */
-            if (!(walls & W_SOUTH))
-                continue;
-            sy = croom->hy + 1;
-            break;
-        case 2: /* left */
-            if (!(walls & W_EAST))
-                continue;
-            sx = croom->lx - 1;
-            break;
-        case 3: /* right */
-            if (!(walls & W_WEST))
-                continue;
-            sx = croom->hx + 1;
-            break;
-        }
-
-        if (okdoor(sx, sy)) {
-            levl[sx][sy].typ = SDOOR;
-            levl[sx][sy].doormask = D_CLOSED;
-            return;
-        }
-    }
-
-    impossible("couldn't create secret door on any walls 0x%x", walls);
-}
-
 /*
  * Create a trap in a room.
  */
@@ -2550,6 +2500,14 @@ create_corridor(corridor *c)
         return;
     }
 
+    /* Safety railings - if there's ever a case where des.corridor() needs to be
+     * called with src/destwall="random", that logic first needs to be
+     * implemented in search_door. */
+    if (c->src.wall == W_ANY || c->src.wall == W_RANDOM
+        || c->dest.wall == W_ANY || c->dest.wall == W_RANDOM) {
+        impossible("create_corridor to/from a random wall");
+        return;
+    }
     if (!search_door(&g.rooms[c->src.room], &org.x, &org.y, c->src.wall,
                      c->src.door))
         return;
@@ -4208,7 +4166,7 @@ lspo_corridor(lua_State *L)
         "all", "random", "north", "west", "east", "south", NULL
     };
     static const int walldirs2i[] = {
-        W_ANY, -1, W_NORTH, W_WEST, W_EAST, W_SOUTH, 0
+        W_ANY, W_RANDOM, W_NORTH, W_WEST, W_EAST, W_SOUTH, 0
     };
     corridor tc;
 
@@ -4398,6 +4356,14 @@ selection_rndcoord(struct selectionvar* ov, xchar *x, xchar *y, boolean removeit
     return 0;
 }
 
+/* Choose a single random W_* direction. */
+static xchar
+random_wdir(void)
+{
+    static const xchar wdirs[4] = { W_NORTH, W_SOUTH, W_EAST, W_WEST };
+    return wdirs[rn2(4)];
+}
+
 void
 selection_do_grow(struct selectionvar* ov, int dir)
 {
@@ -4407,6 +4373,9 @@ selection_do_grow(struct selectionvar* ov, int dir)
     if (!ov || !tmp)
         return;
 
+    if (dir == W_RANDOM)
+        dir = random_wdir();
+
     for (x = 1; x < ov->wid; x++)
         for (y = 0; y < ov->hei; y++) {
             /* note:  dir is a mask of multiple directions, but the only
@@ -4909,6 +4878,8 @@ lspo_door(lua_State *L)
         static const char *const walldirs[] = {
             "all", "random", "north", "west", "east", "south", NULL
         };
+        /* Note that "random" is also W_ANY, because create_door just wants a
+         * mask of acceptable walls */
         static const int walldirs2i[] = {
             W_ANY, W_ANY, W_NORTH, W_WEST, W_EAST, W_SOUTH, 0
         };
@@ -5723,7 +5694,7 @@ lspo_mazewalk(lua_State *L)
     static const char *const mwdirs[] = {
         "north", "south", "east", "west", "random", NULL
     };
-    static const int mwdirs2i[] = { W_NORTH, W_SOUTH, W_EAST, W_WEST, -1, -2 };
+    static const int mwdirs2i[] = { W_NORTH, W_SOUTH, W_EAST, W_WEST, W_RANDOM, -2 };
     xchar x, y;
     int mx, my;
     xchar ftyp = ROOM;
@@ -5759,8 +5730,8 @@ lspo_mazewalk(lua_State *L)
         ftyp = g.level.flags.corrmaze ? CORR : ROOM;
     }
 
-    if (dir == -1)
-        dir = mwdirs2i[rn2(4)];
+    if (dir == W_RANDOM)
+        dir = random_wdir();
 
     /* don't use move() - it doesn't use W_NORTH, etc. */
     switch (dir) {