From 91b4e4570d4708dfb3ec61bc6166cbbb32d81b53 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 16 Oct 2021 11:35:11 -0700 Subject: [PATCH] more github issue #606 - wall repair vs doors Fix the vault repair issue that could lead to "wall_angle: unknown" warning. Unlike shop repair, the original wall info isn't available so this recreates it. The extra 'flags' field added yesterday could be eliminated but this leaves it in place. Fixes #606 --- include/extern.h | 1 + src/display.c | 110 ++++++++++++++++++++++++----------------------- src/vault.c | 40 +++++++++-------- 3 files changed, 81 insertions(+), 70 deletions(-) diff --git a/include/extern.h b/include/extern.h index 42ab9dacf..cc85dca67 100644 --- a/include/extern.h +++ b/include/extern.h @@ -377,6 +377,7 @@ extern int back_to_glyph(xchar, xchar); extern int zapdir_to_glyph(int, int, int); extern int glyph_at(xchar, xchar); extern void reglyph_darkroom(void); +extern void xy_set_wall_state(int, int); extern void set_wall_state(void); extern void unset_seenv(struct rm *, int, int, int, int); extern int warning_of(struct monst *); diff --git a/src/display.c b/src/display.c index 60b140bb3..95d0cfdfe 100644 --- a/src/display.c +++ b/src/display.c @@ -2799,13 +2799,66 @@ set_crosswall(int x, int y) return wmode; } +/* called for every by set_wall_state() and for specific during + vault wall repair */ +void +xy_set_wall_state(int x, int y) +{ + int wmode; + struct rm *lev = &levl[x][y]; + + switch (lev->typ) { + case SDOOR: + wmode = set_wall(x, y, (int) lev->horizontal); + break; + case VWALL: + wmode = set_wall(x, y, 0); + break; + case HWALL: + wmode = set_wall(x, y, 1); + break; + case TDWALL: + wmode = set_twall(x, y, x, y - 1, x - 1, y + 1, x + 1, y + 1); + break; + case TUWALL: + wmode = set_twall(x, y, x, y + 1, x + 1, y - 1, x - 1, y - 1); + break; + case TLWALL: + wmode = set_twall(x, y, x + 1, y, x - 1, y - 1, x - 1, y + 1); + break; + case TRWALL: + wmode = set_twall(x, y, x - 1, y, x + 1, y + 1, x + 1, y - 1); + break; + case TLCORNER: + wmode = set_corn(x - 1, y - 1, x, y - 1, x - 1, y, x + 1, y + 1); + break; + case TRCORNER: + wmode = set_corn(x, y - 1, x + 1, y - 1, x + 1, y, x - 1, y + 1); + break; + case BLCORNER: + wmode = set_corn(x, y + 1, x - 1, y + 1, x - 1, y, x + 1, y - 1); + break; + case BRCORNER: + wmode = set_corn(x + 1, y, x + 1, y + 1, x, y + 1, x - 1, y - 1); + break; + case CROSSWALL: + wmode = set_crosswall(x, y); + break; + + default: + wmode = -1; /* don't set wall info */ + break; + } + + if (wmode >= 0) + lev->wall_info = (lev->wall_info & ~WM_MASK) | wmode; +} + /* Called from mklev. Scan the level and set the wall modes. */ void set_wall_state(void) { int x, y; - int wmode; - struct rm *lev; #ifdef WA_VERBOSE for (x = 0; x < MAX_TYPE; x++) @@ -2813,57 +2866,8 @@ set_wall_state(void) #endif for (x = 0; x < COLNO; x++) - for (lev = &levl[x][0], y = 0; y < ROWNO; y++, lev++) { - switch (lev->typ) { - case SDOOR: - wmode = set_wall(x, y, (int) lev->horizontal); - break; - case VWALL: - wmode = set_wall(x, y, 0); - break; - case HWALL: - wmode = set_wall(x, y, 1); - break; - case TDWALL: - wmode = set_twall(x, y, x, y - 1, x - 1, y + 1, x + 1, y + 1); - break; - case TUWALL: - wmode = set_twall(x, y, x, y + 1, x + 1, y - 1, x - 1, y - 1); - break; - case TLWALL: - wmode = set_twall(x, y, x + 1, y, x - 1, y - 1, x - 1, y + 1); - break; - case TRWALL: - wmode = set_twall(x, y, x - 1, y, x + 1, y + 1, x + 1, y - 1); - break; - case TLCORNER: - wmode = - set_corn(x - 1, y - 1, x, y - 1, x - 1, y, x + 1, y + 1); - break; - case TRCORNER: - wmode = - set_corn(x, y - 1, x + 1, y - 1, x + 1, y, x - 1, y + 1); - break; - case BLCORNER: - wmode = - set_corn(x, y + 1, x - 1, y + 1, x - 1, y, x + 1, y - 1); - break; - case BRCORNER: - wmode = - set_corn(x + 1, y, x + 1, y + 1, x, y + 1, x - 1, y - 1); - break; - case CROSSWALL: - wmode = set_crosswall(x, y); - break; - - default: - wmode = -1; /* don't set wall info */ - break; - } - - if (wmode >= 0) - lev->wall_info = (lev->wall_info & ~WM_MASK) | wmode; - } + for (y = 0; y < ROWNO; y++) + xy_set_wall_state(x, y); #ifdef WA_VERBOSE /* check if any bad positions found */ diff --git a/src/vault.c b/src/vault.c index 69e81d90c..125cf90da 100644 --- a/src/vault.c +++ b/src/vault.c @@ -306,7 +306,7 @@ invault(void) if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) { /* if time ok and no guard now. */ char buf[BUFSZ]; - register int x, y, gx, gy; + int x, y, gx, gy, typ; xchar rx, ry; long umoney; @@ -319,15 +319,15 @@ invault(void) x = u.ux; y = u.uy; if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */ - if (levl[x + 1][y].typ == ROOM) + if (levl[x + 1][y].typ == ROOM) { x = x + 1; - else if (levl[x][y + 1].typ == ROOM) + } else if (levl[x][y + 1].typ == ROOM) { y = y + 1; - else if (levl[x - 1][y].typ == ROOM) + } else if (levl[x - 1][y].typ == ROOM) { x = x - 1; - else if (levl[x][y - 1].typ == ROOM) + } else if (levl[x][y - 1].typ == ROOM) { y = y - 1; - else if (levl[x + 1][y + 1].typ == ROOM) { + } else if (levl[x + 1][y + 1].typ == ROOM) { x = x + 1; y = y + 1; } else if (levl[x - 1][y - 1].typ == ROOM) { @@ -507,14 +507,14 @@ invault(void) EGD(guard)->fcbeg = 0; EGD(guard)->fakecorr[0].fx = x; EGD(guard)->fakecorr[0].fy = y; - EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ; - EGD(guard)->fakecorr[0].flags = levl[x][y].flags; - if (!IS_WALL(levl[x][y].typ)) { - /* the initial guard location happens to be a dug door */ + typ = levl[x][y].typ; + if (!IS_WALL(typ)) { + /* guard arriving at non-wall implies a door; vault wall was + dug into an empty doorway (which could subsequently have + been plugged with an intact door by use of locking magic) */ int vlt = EGD(guard)->vroom; xchar lowx = g.rooms[vlt].lx, hix = g.rooms[vlt].hx; xchar lowy = g.rooms[vlt].ly, hiy = g.rooms[vlt].hy; - int typ = levl[x][y].typ; if (x == lowx - 1 && y == lowy - 1) typ = TLCORNER; @@ -529,11 +529,18 @@ invault(void) else if (x == lowx - 1 || x == hix + 1) typ = VWALL; - EGD(guard)->fakecorr[0].ftyp = typ; + /* we lack access to the original wall_info bit mask for this + former wall location so recreate it */ + levl[x][y].typ = typ; /* wall; will be changed to door below */ + levl[x][y].wall_info = 0; /* will be reset too via doormask */ + xy_set_wall_state(x, y); /* set WA_MASK bits in .wall_info */ } + EGD(guard)->fakecorr[0].ftyp = typ; + EGD(guard)->fakecorr[0].flags = levl[x][y].flags; + /* guard's entry point where confrontation with hero takes place */ levl[x][y].typ = DOOR; levl[x][y].doormask = D_NODOOR; - unblock_point(x, y); /* doesn't block light */ + unblock_point(x, y); /* empty doorway doesn't block light */ EGD(guard)->fcend = 1; EGD(guard)->warncnt = 1; } @@ -595,11 +602,10 @@ wallify_vault(struct monst *grd) : VWALL; else /* not left or right side, must be top or bottom */ typ = HWALL; + levl[x][y].typ = typ; - /* FIXME? both rm.doormask and rm.wall_info overlay - rm.flags, so clearing doormask clobbers wall_info - rather than reset it to the proper value. Do we care? */ - levl[x][y].doormask = 0; + levl[x][y].wall_info = 0; + xy_set_wall_state(x, y); /* set WA_MASK bits in .wall_info */ /* * hack: player knows walls are restored because of the * message, below, so show this on the screen.