From: PatR Date: Mon, 2 Apr 2018 20:35:41 +0000 (-0700) Subject: fix another 'wonky secret door' X-Git-Tag: NetHack-3.6.1_RC01~81 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6faff71a17420206b0aac1b89a1efc099a4e604b;p=nethack fix another 'wonky secret door' 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). --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 9c1b935d1..8b53024cd 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -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 diff --git a/src/sp_lev.c b/src/sp_lev.c index 5140dd2da..abc2eaa31 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -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; }