diff --git a/doc/fixes35.0 b/doc/fixes35.0 index a15bebcdd..b613b902f 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -319,6 +319,7 @@ prevent temple priests and minions from wearing helms of opposite alignment were inside containers pearl rings shouldn't rust shouldn't be able to read a worn T-shirt when it's covered by a worn suit +simplify hero placement on Castle level when climbing up stairs from Valley Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 089d1efae..f92e455b7 100644 --- a/include/extern.h +++ b/include/extern.h @@ -547,7 +547,8 @@ E boolean FDECL(on_level, (d_level *,d_level *)); E void FDECL(next_level, (BOOLEAN_P)); E void FDECL(prev_level, (BOOLEAN_P)); E void FDECL(u_on_newpos, (int,int)); -E void NDECL(u_on_sstairs); +E void FDECL(u_on_rndspot, (int)); +E void FDECL(u_on_sstairs, (int)); E void NDECL(u_on_upstairs); E void NDECL(u_on_dnstairs); E boolean FDECL(On_stairs, (XCHAR_P,XCHAR_P)); diff --git a/src/do.c b/src/do.c index 56b990be6..3132030cd 100644 --- a/src/do.c +++ b/src/do.c @@ -1162,22 +1162,12 @@ boolean at_stairs, falling, portal; u_on_newpos(ttrap->tx, ttrap->ty); } else if (at_stairs && !In_endgame(&u.uz)) { if (up) { - if (at_ladder) { + if (at_ladder) u_on_newpos(xdnladder, ydnladder); - } else { - if (newdungeon) { - if (Is_stronghold(&u.uz)) { - register xchar x, y; - - do { - x = (COLNO - 2 - rnd(5)); - y = rn1(ROWNO - 4, 3); - } while(occupied(x, y) || - IS_WALL(levl[x][y].typ)); - u_on_newpos(x, y); - } else u_on_sstairs(); - } else u_on_dnstairs(); - } + else if (newdungeon) + u_on_sstairs(1); + else + u_on_dnstairs(); /* you climb up the {stairs|ladder}; fly up the stairs; fly up along the ladder */ pline("%s %s up%s the %s.", @@ -1187,12 +1177,12 @@ boolean at_stairs, falling, portal; (Flying && at_ladder) ? " along" : "", at_ladder ? "ladder" : "stairs"); } else { /* down */ - if (at_ladder) { + if (at_ladder) u_on_newpos(xupladder, yupladder); - } else { - if (newdungeon) u_on_sstairs(); - else u_on_upstairs(); - } + else if (newdungeon) + u_on_sstairs(0); + else + u_on_upstairs(); if (!u.dz) { ; /* stayed on same level? (no transit effects) */ } else if (Flying) { @@ -1232,24 +1222,7 @@ boolean at_stairs, falling, portal; } } } else { /* trap door or level_tele or In_endgame */ - if (was_in_W_tower && On_W_tower_level(&u.uz)) - /* Stay inside the Wizard's tower when feasible. */ - /* Note: up vs down doesn't really matter in this case. */ - place_lregion(dndest.nlx, dndest.nly, - dndest.nhx, dndest.nhy, - 0,0, 0,0, LR_DOWNTELE, (d_level *) 0); - else if (up) - place_lregion(updest.lx, updest.ly, - updest.hx, updest.hy, - updest.nlx, updest.nly, - updest.nhx, updest.nhy, - LR_UPTELE, (d_level *) 0); - else - place_lregion(dndest.lx, dndest.ly, - dndest.hx, dndest.hy, - dndest.nlx, dndest.nly, - dndest.nhx, dndest.nhy, - LR_DOWNTELE, (d_level *) 0); + u_on_rndspot((up ? 1 : 0) | (was_in_W_tower ? 2 : 0)); if (falling) { if (Punished) ballfall(); selftouch("Falling, you"); diff --git a/src/dungeon.c b/src/dungeon.c index 798a59ed1..c02e762f3 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1155,47 +1155,61 @@ int x, y; } void -u_on_sstairs() /* place you on the special staircase */ +u_on_rndspot(upflag) /* place you on a random location */ +int upflag; { - if (sstairs.sx) { + int up = (upflag & 1), + was_in_W_tower = (upflag & 2); + + /* + * Place the hero at a random location within the relevant region. + * place_lregion(xTELE) -> put_lregion_here(xTELE) -> u_on_newpos() + * Unspecified region (.lx == 0) defaults to entire level. + */ + if (was_in_W_tower && On_W_tower_level(&u.uz)) + /* Stay inside the Wizard's tower when feasible. + We use the W Tower's exclusion region for the + destination instead of its enclosing region. + Note: up vs down doesn't matter in this case + because both specify the same exclusion area. */ + place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, + 0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0); + else if (up) + place_lregion(updest.lx, updest.ly, updest.hx, updest.hy, + updest.nlx, updest.nly, updest.nhx, updest.nhy, + LR_UPTELE, (d_level *)0); + else + place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy, + dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy, + LR_DOWNTELE, (d_level *)0); +} + +void +u_on_sstairs(upflag) /* place you on the special staircase */ +int upflag; +{ + if (sstairs.sx) u_on_newpos(sstairs.sx, sstairs.sy); - } else { - /* code stolen from goto_level */ - int trycnt = 0; - xchar x, y; -#ifdef DEBUG - pline("u_on_sstairs: picking random spot"); -#endif -#define badspot(x,y) ((levl[x][y].typ != ROOM && levl[x][y].typ != CORR) || MON_AT(x, y)) - do { - x = rnd(COLNO-1); - y = rn2(ROWNO); - if (!badspot(x, y)) { - u_on_newpos(x, y); - return; - } - } while (++trycnt <= 500); - panic("u_on_sstairs: could not relocate player!"); -#undef badspot - } + else + u_on_rndspot(upflag); } void u_on_upstairs() /* place you on upstairs (or special equivalent) */ { - if (xupstair) { - u_on_newpos(xupstair, yupstair); - } else - u_on_sstairs(); + if (xupstair) + u_on_newpos(xupstair, yupstair); + else + u_on_sstairs(0); /* destination upstairs implies moving down */ } void u_on_dnstairs() /* place you on dnstairs (or special equivalent) */ { - if (xdnstair) { - u_on_newpos(xdnstair, ydnstair); - } else - u_on_sstairs(); + if (xdnstair) + u_on_newpos(xdnstair, ydnstair); + else + u_on_sstairs(1); /* destination dnstairs implies moving up */ } boolean