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
This commit is contained in:
PatR
2021-10-16 11:35:11 -07:00
parent 07b1d9d396
commit 91b4e4570d
3 changed files with 81 additions and 70 deletions

View File

@@ -377,6 +377,7 @@ extern int back_to_glyph(xchar, xchar);
extern int zapdir_to_glyph(int, int, int); extern int zapdir_to_glyph(int, int, int);
extern int glyph_at(xchar, xchar); extern int glyph_at(xchar, xchar);
extern void reglyph_darkroom(void); extern void reglyph_darkroom(void);
extern void xy_set_wall_state(int, int);
extern void set_wall_state(void); extern void set_wall_state(void);
extern void unset_seenv(struct rm *, int, int, int, int); extern void unset_seenv(struct rm *, int, int, int, int);
extern int warning_of(struct monst *); extern int warning_of(struct monst *);

View File

@@ -2799,13 +2799,66 @@ set_crosswall(int x, int y)
return wmode; return wmode;
} }
/* called for every <x,y> by set_wall_state() and for specific <x,y> 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. */ /* Called from mklev. Scan the level and set the wall modes. */
void void
set_wall_state(void) set_wall_state(void)
{ {
int x, y; int x, y;
int wmode;
struct rm *lev;
#ifdef WA_VERBOSE #ifdef WA_VERBOSE
for (x = 0; x < MAX_TYPE; x++) for (x = 0; x < MAX_TYPE; x++)
@@ -2813,57 +2866,8 @@ set_wall_state(void)
#endif #endif
for (x = 0; x < COLNO; x++) for (x = 0; x < COLNO; x++)
for (lev = &levl[x][0], y = 0; y < ROWNO; y++, lev++) { for (y = 0; y < ROWNO; y++)
switch (lev->typ) { xy_set_wall_state(x, y);
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;
}
#ifdef WA_VERBOSE #ifdef WA_VERBOSE
/* check if any bad positions found */ /* check if any bad positions found */

View File

@@ -306,7 +306,7 @@ invault(void)
if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) { if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) {
/* if time ok and no guard now. */ /* if time ok and no guard now. */
char buf[BUFSZ]; char buf[BUFSZ];
register int x, y, gx, gy; int x, y, gx, gy, typ;
xchar rx, ry; xchar rx, ry;
long umoney; long umoney;
@@ -319,15 +319,15 @@ invault(void)
x = u.ux; x = u.ux;
y = u.uy; y = u.uy;
if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */ 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; x = x + 1;
else if (levl[x][y + 1].typ == ROOM) } else if (levl[x][y + 1].typ == ROOM) {
y = y + 1; y = y + 1;
else if (levl[x - 1][y].typ == ROOM) } else if (levl[x - 1][y].typ == ROOM) {
x = x - 1; x = x - 1;
else if (levl[x][y - 1].typ == ROOM) } else if (levl[x][y - 1].typ == ROOM) {
y = y - 1; y = y - 1;
else if (levl[x + 1][y + 1].typ == ROOM) { } else if (levl[x + 1][y + 1].typ == ROOM) {
x = x + 1; x = x + 1;
y = y + 1; y = y + 1;
} else if (levl[x - 1][y - 1].typ == ROOM) { } else if (levl[x - 1][y - 1].typ == ROOM) {
@@ -507,14 +507,14 @@ invault(void)
EGD(guard)->fcbeg = 0; EGD(guard)->fcbeg = 0;
EGD(guard)->fakecorr[0].fx = x; EGD(guard)->fakecorr[0].fx = x;
EGD(guard)->fakecorr[0].fy = y; EGD(guard)->fakecorr[0].fy = y;
EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ; typ = levl[x][y].typ;
EGD(guard)->fakecorr[0].flags = levl[x][y].flags; if (!IS_WALL(typ)) {
if (!IS_WALL(levl[x][y].typ)) { /* guard arriving at non-wall implies a door; vault wall was
/* the initial guard location happens to be a dug door */ 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; int vlt = EGD(guard)->vroom;
xchar lowx = g.rooms[vlt].lx, hix = g.rooms[vlt].hx; xchar lowx = g.rooms[vlt].lx, hix = g.rooms[vlt].hx;
xchar lowy = g.rooms[vlt].ly, hiy = g.rooms[vlt].hy; xchar lowy = g.rooms[vlt].ly, hiy = g.rooms[vlt].hy;
int typ = levl[x][y].typ;
if (x == lowx - 1 && y == lowy - 1) if (x == lowx - 1 && y == lowy - 1)
typ = TLCORNER; typ = TLCORNER;
@@ -529,11 +529,18 @@ invault(void)
else if (x == lowx - 1 || x == hix + 1) else if (x == lowx - 1 || x == hix + 1)
typ = VWALL; 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].typ = DOOR;
levl[x][y].doormask = D_NODOOR; 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)->fcend = 1;
EGD(guard)->warncnt = 1; EGD(guard)->warncnt = 1;
} }
@@ -595,11 +602,10 @@ wallify_vault(struct monst *grd)
: VWALL; : VWALL;
else /* not left or right side, must be top or bottom */ else /* not left or right side, must be top or bottom */
typ = HWALL; typ = HWALL;
levl[x][y].typ = typ; levl[x][y].typ = typ;
/* FIXME? both rm.doormask and rm.wall_info overlay levl[x][y].wall_info = 0;
rm.flags, so clearing doormask clobbers wall_info xy_set_wall_state(x, y); /* set WA_MASK bits in .wall_info */
rather than reset it to the proper value. Do we care? */
levl[x][y].doormask = 0;
/* /*
* hack: player knows walls are restored because of the * hack: player knows walls are restored because of the
* message, below, so show this on the screen. * message, below, so show this on the screen.