]> granicus.if.org Git - nethack/commitdiff
fix another 'wonky secret door'
authorPatR <rankin@nethack.org>
Mon, 2 Apr 2018 20:35:41 +0000 (13:35 -0700)
committerPatR <rankin@nethack.org>
Mon, 2 Apr 2018 20:35:41 +0000 (13:35 -0700)
The cavemen quest description includes an 'S' in the lower right
corner of the MAP...ENDMAP section of the locate level.  It produced
a secret door as intended but did not have horizontal vs vertical set
because the latter was only being done for DOOR directives.  Instead
of adding an explicit directive, make the loading code set horizontal
vs vertical for all doors.

This fixes the orientation of that secret door in the Cav locate
level, but I noticed that it showed up an a visible horizontal wall
when the spots on either side were still blank.  It's behaving as
if the door is on a lit spot and the adjacent walls are unlit (this
misbehavior was already present before the current change; it was
just shown incorrectly as a visible vertical wall before).

doc/fixes36.1
src/sp_lev.c

index 9c1b935d188ca8f3d8a8d245aa055acaa21b8e95..8b53024cd6a4b4b5bddcd3148a475e9f92f7fb54 100644 (file)
@@ -605,6 +605,9 @@ the fix for secret doors on special levels always having vertical orientation
 and the previous fix for the for secret doors didn't work if the level hadn't
        been wallified yet (Cav quest) so horizontal wall with secret door
        mis-displayed as a vertical wall segment could occur
+and both the previous fixes only worked if the level description contained
+       an explicit DOOR directive rather than just '+' or 'S' on the map
+       (as with lower right area of Cav 'locate' level)
 the fix intended for "a shop object stolen from outside the shop (via
        grappling hook) would be left marked as 'unpaid'" broke normal pickup,
        preventing any picked up item from merging with compatible stack
index 5140dd2dab4963d1e74f8f37f4c41cdd102669ee..abc2eaa315572e762e33ed79f530f395cbaeceb1 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 sp_lev.c        $NHDT-Date: 1519399521 2018/02/23 15:25:21 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.96 $ */
+/* NetHack 3.6 sp_lev.c        $NHDT-Date: 1522701334 2018/04/02 20:35:34 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.97 $ */
 /*      Copyright (c) 1989 by Jean-Christophe Collet */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -52,6 +52,7 @@ STATIC_DCL void FDECL(set_wall_property, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P,
 STATIC_DCL void NDECL(shuffle_alignments);
 STATIC_DCL void NDECL(count_features);
 STATIC_DCL void NDECL(remove_boundary_syms);
+STATIC_DCL void FDECL(set_door_orientation, (int, int));
 STATIC_DCL void FDECL(maybe_add_door, (int, int, struct mkroom *));
 STATIC_DCL void NDECL(link_doors_rooms);
 STATIC_DCL void NDECL(fill_rooms);
@@ -702,7 +703,55 @@ remove_boundary_syms()
     }
 }
 
-void
+/* used by sel_set_door() and link_doors_rooms() */
+STATIC_OVL void
+set_door_orientation(x, y)
+int x, y;
+{
+    boolean wleft, wright, wup, wdown;
+
+    /* If there's a wall or door on either the left side or right
+     * side (or both) of this secret door, make it be horizontal.
+     *
+     * It is feasible to put SDOOR in a corner, tee, or crosswall
+     * position, although once the door is found and opened it won't
+     * make a lot sense (diagonal access required).  Still, we try to
+     * handle that as best as possible.  For top or bottom tee, using
+     * horizontal is the best we can do.  For corner or crosswall,
+     * either horizontal or vertical are just as good as each other;
+     * we produce horizontal for corners and vertical for crosswalls.
+     * For left or right tee, using vertical is best.
+     *
+     * A secret door with no adjacent walls is also feasible and makes
+     * even less sense.  It will be displayed as a vertical wall while
+     * hidden and become a vertical door when found.  Before resorting
+     * to that, we check for solid rock which hasn't been wallified
+     * yet (cf lower leftside of leader's room in Cav quest).
+     */
+    wleft  = (isok(x - 1, y) && (IS_WALL(levl[x - 1][y].typ)
+                                 || IS_DOOR(levl[x - 1][y].typ)
+                                 || levl[x - 1][y].typ == SDOOR));
+    wright = (isok(x + 1, y) && (IS_WALL(levl[x + 1][y].typ)
+                                 || IS_DOOR(levl[x + 1][y].typ)
+                                 || levl[x + 1][y].typ == SDOOR));
+    wup    = (isok(x, y - 1) && (IS_WALL(levl[x][y - 1].typ)
+                                 || IS_DOOR(levl[x][y - 1].typ)
+                                 || levl[x][y - 1].typ == SDOOR));
+    wdown  = (isok(x, y + 1) && (IS_WALL(levl[x][y + 1].typ)
+                                 || IS_DOOR(levl[x][y + 1].typ)
+                                 || levl[x][y + 1].typ == SDOOR));
+    if (!wleft && !wright && !wup && !wdown) {
+        /* out of bounds is treated as implicit wall; should be academic
+           because we don't expect to have doors so near the level's edge */
+        wleft  = (!isok(x - 1, y) || IS_DOORJOIN(levl[x - 1][y].typ));
+        wright = (!isok(x + 1, y) || IS_DOORJOIN(levl[x + 1][y].typ));
+        wup    = (!isok(x, y - 1) || IS_DOORJOIN(levl[x][y - 1].typ));
+        wdown  = (!isok(x, y + 1) || IS_DOORJOIN(levl[x][y + 1].typ));
+    }
+    levl[x][y].horizontal = ((wleft || wright) && !(wup && wdown)) ? 1 : 0;
+}
+
+STATIC_OVL void
 maybe_add_door(x, y, droom)
 int x, y;
 struct mkroom *droom;
@@ -711,7 +760,7 @@ struct mkroom *droom;
         add_door(x, y, droom);
 }
 
-void
+STATIC_OVL void
 link_doors_rooms()
 {
     int x, y;
@@ -720,6 +769,11 @@ link_doors_rooms()
     for (y = 0; y < ROWNO; y++)
         for (x = 0; x < COLNO; x++)
             if (IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR) {
+                /* in case this door was a '+' or 'S' from the
+                   MAP...ENDMAP section without an explicit DOOR
+                   directive, set/clear levl[][].horizontal for it */
+                set_door_orientation(x, y);
+
                 for (tmpi = 0; tmpi < nroom; tmpi++) {
                     maybe_add_door(x, y, &rooms[tmpi]);
                     for (m = 0; m < rooms[tmpi].nsubrooms; m++) {
@@ -4207,7 +4261,6 @@ genericptr_t arg;
 {
     xchar typ = *(xchar *) arg;
     xchar x = dx, y = dy;
-    boolean wleft, wright, wup, wdown;
 
     if (!IS_DOOR(levl[x][y].typ) && levl[x][y].typ != SDOOR)
         levl[x][y].typ = (typ & D_SECRET) ? SDOOR : DOOR;
@@ -4216,46 +4269,7 @@ genericptr_t arg;
         if (typ < D_CLOSED)
             typ = D_CLOSED;
     }
-
-    /* If there's a wall or door on either the left side or right
-     * side (or both) of this secret door, make it be horizontal.
-     *
-     * It is feasible to put SDOOR in a corner, tee, or crosswall
-     * position, although once the door is found and opened it won't
-     * make a lot sense (diagonal access required).  Still, we try to
-     * handle that as best as possible.  For top or bottom tee, using
-     * horizontal is the best we can do.  For corner or crosswall,
-     * either horizontal or vertical are just as good as each other;
-     * we produce horizontal for corners and vertical for crosswalls.
-     * For left or right tee, using vertical is best.
-     *
-     * A secret door with no adjacent walls is also feasible and makes
-     * even less sense.  It will be displayed as a vertical wall while
-     * hidden and become a vertical door when found.  Before resorting
-     * to that, we check for solid rock which hasn't been wallified
-     * yet (cf lower leftside of leader's room in Cav quest).
-     */
-    wleft  = (isok(x - 1, y) && (IS_WALL(levl[x - 1][y].typ)
-                                 || IS_DOOR(levl[x - 1][y].typ)
-                                 || levl[x - 1][y].typ == SDOOR));
-    wright = (isok(x + 1, y) && (IS_WALL(levl[x + 1][y].typ)
-                                 || IS_DOOR(levl[x + 1][y].typ)
-                                 || levl[x + 1][y].typ == SDOOR));
-    wup    = (isok(x, y - 1) && (IS_WALL(levl[x][y - 1].typ)
-                                 || IS_DOOR(levl[x][y - 1].typ)
-                                 || levl[x][y - 1].typ == SDOOR));
-    wdown  = (isok(x, y + 1) && (IS_WALL(levl[x][y + 1].typ)
-                                 || IS_DOOR(levl[x][y + 1].typ)
-                                 || levl[x][y + 1].typ == SDOOR));
-    if (!wleft && !wright && !wup && !wdown) {
-        /* out of bounds is treated as implicit wall; should be academic
-           because we don't expect to have doors so near the level's edge */
-        wleft  = (!isok(x - 1, y) || IS_DOORJOIN(levl[x - 1][y].typ));
-        wright = (!isok(x + 1, y) || IS_DOORJOIN(levl[x + 1][y].typ));
-        wup    = (!isok(x, y - 1) || IS_DOORJOIN(levl[x][y - 1].typ));
-        wdown  = (!isok(x, y + 1) || IS_DOORJOIN(levl[x][y + 1].typ));
-    }
-    levl[x][y].horizontal = ((wleft || wright) && !(wup && wdown)) ? 1 : 0;
+    set_door_orientation(x, y); /* set/clear levl[x][y].horizontal */
     levl[x][y].doormask = typ;
     SpLev_Map[x][y] = 1;
 }