mkstairs() sanity check
Complain during level creation if stairs are placed on top of anything other than the expected room/corridor/ice terrain. This won't prevent the bug of upstairs and downstairs existing on the same spot (github issue #702, also a newsgroup posting by a hardfought player) but might at least warn players if/when that happens.
This commit is contained in:
+36
-21
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 mklev.c $NHDT-Date: 1613085478 2021/02/11 23:17:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */
|
/* NetHack 3.7 mklev.c $NHDT-Date: 1648066813 2022/03/23 20:20:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Alex Smith, 2017. */
|
/*-Copyright (c) Alex Smith, 2017. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -1227,8 +1227,9 @@ pos_to_room(xchar x, xchar y)
|
|||||||
|
|
||||||
/* If given a branch, randomly place a special stair or portal. */
|
/* If given a branch, randomly place a special stair or portal. */
|
||||||
void
|
void
|
||||||
place_branch(branch *br, /* branch to place */
|
place_branch(
|
||||||
xchar x, xchar y) /* location */
|
branch *br, /* branch to place */
|
||||||
|
xchar x, xchar y) /* location */
|
||||||
{
|
{
|
||||||
coord m = {0};
|
coord m = {0};
|
||||||
d_level *dest;
|
d_level *dest;
|
||||||
@@ -1337,7 +1338,7 @@ dodoor(int x, int y, struct mkroom *aroom)
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
occupied(register xchar x, register xchar y)
|
occupied(xchar x, xchar y)
|
||||||
{
|
{
|
||||||
return (boolean) (t_at(x, y) || IS_FURNITURE(levl[x][y].typ)
|
return (boolean) (t_at(x, y) || IS_FURNITURE(levl[x][y].typ)
|
||||||
|| is_lava(x, y) || is_pool(x, y)
|
|| is_lava(x, y) || is_pool(x, y)
|
||||||
@@ -1347,7 +1348,11 @@ occupied(register xchar x, register xchar y)
|
|||||||
/* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
|
/* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
|
||||||
/* if tm != null, make trap at that location */
|
/* if tm != null, make trap at that location */
|
||||||
void
|
void
|
||||||
mktrap(int num, int mktrapflags, struct mkroom *croom, coord *tm)
|
mktrap(
|
||||||
|
int num,
|
||||||
|
int mktrapflags,
|
||||||
|
struct mkroom *croom,
|
||||||
|
coord *tm)
|
||||||
{
|
{
|
||||||
register int kind;
|
register int kind;
|
||||||
struct trap *t;
|
struct trap *t;
|
||||||
@@ -1611,44 +1616,54 @@ mktrap(int num, int mktrapflags, struct mkroom *croom, coord *tm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mkstairs(xchar x, xchar y,
|
mkstairs(
|
||||||
char up, /* [why 'char' when usage is boolean?] */
|
xchar x, xchar y,
|
||||||
struct mkroom *croom UNUSED)
|
char up, /* [why 'char' when usage is boolean?] */
|
||||||
|
struct mkroom *croom UNUSED)
|
||||||
{
|
{
|
||||||
|
int ltyp;
|
||||||
d_level dest;
|
d_level dest;
|
||||||
|
|
||||||
if (!x) {
|
if (!x || !isok(x, y)) {
|
||||||
impossible("mkstairs: bogus stair attempt at <%d,%d>", x, y);
|
impossible("mkstairs: bogus stair attempt at <%d,%d>", x, y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ltyp = levl[x][y].typ; /* somexyspace() allows ice */
|
||||||
|
if (ltyp != ROOM && ltyp != CORR && ltyp != ICE) {
|
||||||
|
int glyph = back_to_glyph(x, y),
|
||||||
|
sidx = glyph_to_cmap(glyph);
|
||||||
|
|
||||||
|
impossible("mkstairs: placing stairs %s on %s at <%d,%d>",
|
||||||
|
up ? "up" : "down", defsyms[sidx].explanation, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can't make a regular stair off an end of the dungeon. This
|
* We can't make a regular stair off an end of the dungeon. This
|
||||||
* attempt can happen when a special level is placed at an end and
|
* attempt can happen when a special level is placed at an end and
|
||||||
* has an up or down stair specified in its description file.
|
* has an up or down stair specified in its description file.
|
||||||
*/
|
*/
|
||||||
if ((dunlev(&u.uz) == 1 && up)
|
if (dunlev(&u.uz) == (up ? 1 : dunlevs_in_dungeon(&u.uz)))
|
||||||
|| (dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dest.dnum = u.uz.dnum;
|
dest.dnum = u.uz.dnum;
|
||||||
dest.dlevel = u.uz.dlevel + (up ? -1 : 1);
|
dest.dlevel = u.uz.dlevel + (up ? -1 : 1);
|
||||||
stairway_add(x, y, up ? TRUE : FALSE, FALSE, &dest);
|
stairway_add(x, y, up ? TRUE : FALSE, FALSE, &dest);
|
||||||
|
|
||||||
(void) set_levltyp(x,y, STAIRS);
|
(void) set_levltyp(x, y, STAIRS);
|
||||||
levl[x][y].ladder = up ? LA_UP : LA_DOWN;
|
levl[x][y].ladder = up ? LA_UP : LA_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is room a good one to generate up or down stairs in? */
|
/* is room a good one to generate up or down stairs in? */
|
||||||
/* phase values, smaller allows for more relaxed criteria:
|
|
||||||
2 == no relaxed criteria
|
|
||||||
1 == allow a themed room
|
|
||||||
0 == allow same room as existing up/downstairs
|
|
||||||
-1 == allow an unjoined room
|
|
||||||
*/
|
|
||||||
static boolean
|
static boolean
|
||||||
generate_stairs_room_good(struct mkroom *croom, int phase)
|
generate_stairs_room_good(struct mkroom *croom, int phase)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* phase values, smaller allows for more relaxed criteria:
|
||||||
|
* 2 == no relaxed criteria;
|
||||||
|
* 1 == allow a themed room;
|
||||||
|
* 0 == allow same room as existing up/downstairs;
|
||||||
|
* -1 == allow an unjoined room.
|
||||||
|
*/
|
||||||
return (croom && (croom->needjoining || (phase < 0))
|
return (croom && (croom->needjoining || (phase < 0))
|
||||||
&& ((!has_dnstairs(croom) && !has_upstairs(croom))
|
&& ((!has_dnstairs(croom) && !has_upstairs(croom))
|
||||||
|| phase < 1)
|
|| phase < 1)
|
||||||
@@ -1669,9 +1684,9 @@ generate_stairs_find_room(void)
|
|||||||
for (phase = 2; phase > -1; phase--) {
|
for (phase = 2; phase > -1; phase--) {
|
||||||
do {
|
do {
|
||||||
croom = &g.rooms[rn2(g.nroom)];
|
croom = &g.rooms[rn2(g.nroom)];
|
||||||
} while (!generate_stairs_room_good(croom, phase) && (tryct++ < 50));
|
if (generate_stairs_room_good(croom, phase))
|
||||||
if (tryct < 50)
|
return croom;
|
||||||
return croom;
|
} while (tryct++ < 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (phase = 2; phase > -2; phase--) {
|
for (phase = 2; phase > -2; phase--) {
|
||||||
|
|||||||
Reference in New Issue
Block a user