Skip to content

Commit

Permalink
Xorns in stone outside Sokobon and other special levels
Browse files Browse the repository at this point in the history
First reported 12/13/2003, I think, but my archives contain more recent reports
too.  Special level specs like NON_PASSWALL and NON_DIGGABLE only apply
to the map sections for which they are specified.  So, on special levels of
Sokobon, the large surrounding area is stone, but have no special flags set.
So, it was possible to teleport a Xorn and have it appear in this outer area.

Addressed this by checking the perimeter of the map(s) and if all are
nondiggable and nonpassable, propagate this to the surrounding stone.
This appears to be the intent on such levels, so there is no need to
force the affected special levels to explicitly specify this.
  • Loading branch information
cohrs committed Feb 4, 2006
1 parent 0bec6ce commit a1b0e08
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doc/fixes34.4
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ make gender of quest leaders and nemeses consistent with data.base and
Orion and Norn should be giant sized
Orion, Norn, Cyclops and Lord Surtur should be able to tear webs
typo in Gnome King cellar message
ensure monsters cannot teleport to or be created outside nonpassable bounds
of special levels


Platform- and/or Interface-Specific Fixes
Expand Down
50 changes: 50 additions & 0 deletions src/sp_lev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2114,6 +2114,7 @@ dlb *fd;
xchar mustfill[(MAXNROFROOMS+1)*2];
struct trap *badtrap;
boolean has_bounds;
boolean bounds_nodigpass;

(void) memset((genericptr_t)&Map[0][0], 0, sizeof Map);
load_common_data(fd, SP_LEV_MAZE);
Expand All @@ -2135,6 +2136,9 @@ dlb *fd;
}
}

/* if filling with stone, surrounding stone may all be nondig, nonpass */
bounds_nodigpass = (filling == STONE);

/* Start reading the file */
Fread((genericptr_t) &numpart, 1, sizeof(numpart), fd);
/* Number of parts */
Expand Down Expand Up @@ -2184,6 +2188,7 @@ dlb *fd;
ystart = 0;
xsize = COLNO-1;
ysize = ROWNO;
bounds_nodigpass = FALSE;
} else {
/* Load the map */
for(y = ystart; y < ystart+ysize; y++)
Expand Down Expand Up @@ -2445,6 +2450,38 @@ dlb *fd;
tmpdig.x2, tmpdig.y2, W_NONPASSWALL);
}

/* walk bounds, reset bounds_nodigpass diggable or passable */
if (bounds_nodigpass) {
for (x = xstart; x < xstart+xsize; x++) {
if (!IS_STWALL(levl[x][ystart].typ) ||
(levl[x][ystart].wall_info &
(W_NONDIGGABLE|W_NONPASSWALL)) !=
(W_NONDIGGABLE|W_NONPASSWALL) ||
!IS_STWALL(levl[x][ystart+ysize-1].typ) ||
(levl[x][ystart+ysize-1].wall_info &
(W_NONDIGGABLE|W_NONPASSWALL)) !=
(W_NONDIGGABLE|W_NONPASSWALL)) {
bounds_nodigpass = FALSE;
break;
}
}
}
if (bounds_nodigpass) {
for(y = ystart; y < ystart+ysize; y++) {
if (!IS_STWALL(levl[xstart][y].typ) ||
(levl[xstart][y].wall_info &
(W_NONDIGGABLE|W_NONPASSWALL)) !=
(W_NONDIGGABLE|W_NONPASSWALL) ||
!IS_STWALL(levl[xstart+xsize-1][y].typ) ||
(levl[xstart+xsize-1][y].wall_info &
(W_NONDIGGABLE|W_NONPASSWALL)) !=
(W_NONDIGGABLE|W_NONPASSWALL)) {
bounds_nodigpass = FALSE;
break;
}
}
}

Fread((genericptr_t) &n, 1, sizeof(n), fd);
/* Number of ladders */
while(n--) {
Expand Down Expand Up @@ -2643,6 +2680,19 @@ dlb *fd;
(void) maketrap(mm.x, mm.y, trytrap);
}
}

/*
* If bounds_nodigpass, and no mazewalks, mark all locations outside
* the map are mapped as nodig and nopass as well. This avoids passwall
* monsters like Xorns from appearing outside the accessible area.
*/
if (bounds_nodigpass && !nwalk_sav) {
for(x = 1; x < COLNO; x++)
for(y = 0; y < ROWNO; y++)
if(!Map[x][y])
levl[x][y].wall_info |= W_NONDIGGABLE|W_NONPASSWALL;
}

return TRUE;
}

Expand Down

0 comments on commit a1b0e08

Please sign in to comment.