1 /* NetHack 3.6 mklev.c $NHDT-Date: 1550800390 2019/02/22 01:53:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Alex Smith, 2017. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 /* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
14 /* croom->lx etc are schar (width <= int), so % arith ensures that */
15 /* conversion of result to int is reasonable */
17 STATIC_DCL void FDECL(mkfount, (int, struct mkroom *));
18 STATIC_DCL void FDECL(mksink, (struct mkroom *));
19 STATIC_DCL void FDECL(mkaltar, (struct mkroom *));
20 STATIC_DCL void FDECL(mkgrave, (struct mkroom *));
21 STATIC_DCL void NDECL(makevtele);
22 STATIC_DCL void NDECL(clear_level_structures);
23 STATIC_DCL void NDECL(makelevel);
24 STATIC_DCL boolean FDECL(bydoor, (XCHAR_P, XCHAR_P));
25 STATIC_DCL struct mkroom *FDECL(find_branch_room, (coord *));
26 STATIC_DCL struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P));
27 STATIC_DCL boolean FDECL(place_niche, (struct mkroom *, int *, int *, int *));
28 STATIC_DCL void FDECL(makeniche, (int));
29 STATIC_DCL void NDECL(make_niches);
30 STATIC_PTR int FDECL(CFDECLSPEC do_comp, (const genericptr,
32 STATIC_DCL void FDECL(dosdoor, (XCHAR_P, XCHAR_P, struct mkroom *, int));
33 STATIC_DCL void FDECL(join, (int, int, BOOLEAN_P));
34 STATIC_DCL void FDECL(do_room_or_subroom, (struct mkroom *, int, int,
36 SCHAR_P, BOOLEAN_P, BOOLEAN_P));
37 STATIC_DCL void NDECL(makerooms);
38 STATIC_DCL void FDECL(finddpos, (coord *, XCHAR_P, XCHAR_P,
40 STATIC_DCL void FDECL(mkinvpos, (XCHAR_P, XCHAR_P, int));
41 STATIC_DCL void FDECL(mk_knox_portal, (XCHAR_P, XCHAR_P));
43 #define create_vault() create_room(-1, -1, 2, 2, -1, -1, VAULT, TRUE)
44 #define init_vault() vault_x = -1
45 #define do_vault() (vault_x != -1)
46 static xchar vault_x, vault_y;
47 static boolean made_branch; /* used only during level creation */
49 /* Args must be (const genericptr) so that qsort will always be happy. */
51 STATIC_PTR int CFDECLSPEC
57 /* lint complains about possible pointer alignment problems, but we know
58 that vx and vy are always properly aligned. Hence, the following
61 return (vx == vy) ? 0 : -1;
63 register const struct mkroom *x, *y;
65 x = (const struct mkroom *) vx;
66 y = (const struct mkroom *) vy;
69 return (x->lx > y->lx);
74 finddpos(cc, xl, yl, xh, yh)
80 x = rn1(xh - xl + 1, xl);
81 y = rn1(yh - yl + 1, yl);
85 for (x = xl; x <= xh; x++)
86 for (y = yl; y <= yh; y++)
90 for (x = xl; x <= xh; x++)
91 for (y = yl; y <= yh; y++)
92 if (IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
94 /* cannot find something reasonable -- strange */
106 #if defined(SYSV) || defined(DGUX)
107 #define CAST_nroom (unsigned) nroom
109 #define CAST_nroom nroom /*as-is*/
111 qsort((genericptr_t) rooms, CAST_nroom, sizeof (struct mkroom), do_comp);
116 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room)
117 register struct mkroom *croom;
119 register int hix, hiy;
128 /* locations might bump level edges in wall-less rooms */
129 /* add/subtract 1 to allow for edge locations */
134 if (hix >= COLNO - 1)
136 if (hiy >= ROWNO - 1)
140 for (x = lowx - 1; x <= hix + 1; x++) {
141 lev = &levl[x][max(lowy - 1, 0)];
142 for (y = lowy - 1; y <= hiy + 1; y++)
153 croom->rtype = rtype;
155 /* if we're not making a vault, doorindex will still be 0
156 * if we are, we'll have problems adding niches to the previous room
157 * unless fdoor is at least doorindex
159 croom->fdoor = doorindex;
160 croom->irregular = FALSE;
162 croom->nsubrooms = 0;
163 croom->sbrooms[0] = (struct mkroom *) 0;
165 for (x = lowx - 1; x <= hix + 1; x++)
166 for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
167 levl[x][y].typ = HWALL;
168 levl[x][y].horizontal = 1; /* For open/secret doors. */
170 for (x = lowx - 1; x <= hix + 1; x += (hix - lowx + 2))
171 for (y = lowy; y <= hiy; y++) {
172 levl[x][y].typ = VWALL;
173 levl[x][y].horizontal = 0; /* For open/secret doors. */
175 for (x = lowx; x <= hix; x++) {
176 lev = &levl[x][lowy];
177 for (y = lowy; y <= hiy; y++)
181 levl[lowx - 1][lowy - 1].typ = TLCORNER;
182 levl[hix + 1][lowy - 1].typ = TRCORNER;
183 levl[lowx - 1][hiy + 1].typ = BLCORNER;
184 levl[hix + 1][hiy + 1].typ = BRCORNER;
185 } else { /* a subroom */
186 wallification(lowx - 1, lowy - 1, hix + 1, hiy + 1);
192 add_room(lowx, lowy, hix, hiy, lit, rtype, special)
193 int lowx, lowy, hix, hiy;
198 register struct mkroom *croom;
200 croom = &rooms[nroom];
201 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
209 add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special)
210 struct mkroom *proom;
211 int lowx, lowy, hix, hiy;
216 register struct mkroom *croom;
218 croom = &subrooms[nsubroom];
219 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
221 proom->sbrooms[proom->nsubrooms++] = croom;
230 boolean tried_vault = FALSE;
232 /* make rooms until satisfied */
233 /* rnd_rect() will returns 0 if no more rects are available... */
234 while (nroom < MAXNROFROOMS && rnd_rect()) {
235 if (nroom >= (MAXNROFROOMS / 6) && rn2(2) && !tried_vault) {
237 if (create_vault()) {
238 vault_x = rooms[nroom].lx;
239 vault_y = rooms[nroom].ly;
240 rooms[nroom].hx = -1;
242 } else if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
253 coord cc, tt, org, dest;
254 register xchar tx, ty, xx, yy;
255 register struct mkroom *croom, *troom;
261 /* find positions cc and tt for doors in croom and troom
262 and direction for a corridor between them */
264 if (troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX)
266 if (troom->lx > croom->hx) {
271 finddpos(&cc, xx, croom->ly, xx, croom->hy);
272 finddpos(&tt, tx, troom->ly, tx, troom->hy);
273 } else if (troom->hy < croom->ly) {
277 finddpos(&cc, croom->lx, yy, croom->hx, yy);
279 finddpos(&tt, troom->lx, ty, troom->hx, ty);
280 } else if (troom->hx < croom->lx) {
285 finddpos(&cc, xx, croom->ly, xx, croom->hy);
286 finddpos(&tt, tx, troom->ly, tx, troom->hy);
292 finddpos(&cc, croom->lx, yy, croom->hx, yy);
293 finddpos(&tt, troom->lx, ty, troom->hx, ty);
299 if (nxcor && levl[xx + dx][yy + dy].typ)
301 if (okdoor(xx, yy) || !nxcor)
302 dodoor(xx, yy, croom);
309 if (!dig_corridor(&org, &dest, nxcor, level.flags.arboreal ? ROOM : CORR,
313 /* we succeeded in digging the corridor */
314 if (okdoor(tt.x, tt.y) || !nxcor)
315 dodoor(tt.x, tt.y, troom);
317 if (smeq[a] < smeq[b])
329 for (a = 0; a < nroom - 1; a++) {
330 join(a, a + 1, FALSE);
332 break; /* allow some randomness */
334 for (a = 0; a < nroom - 2; a++)
335 if (smeq[a] != smeq[a + 2])
336 join(a, a + 2, FALSE);
337 for (a = 0; any && a < nroom; a++) {
339 for (b = 0; b < nroom; b++)
340 if (smeq[a] != smeq[b]) {
346 for (i = rn2(nroom) + 4; i; i--) {
356 add_door(x, y, aroom)
358 register struct mkroom *aroom;
360 register struct mkroom *broom;
364 if (aroom->doorct == 0)
365 aroom->fdoor = doorindex;
369 for (tmp = doorindex; tmp > aroom->fdoor; tmp--)
370 doors[tmp] = doors[tmp - 1];
372 for (i = 0; i < nroom; i++) {
374 if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
377 for (i = 0; i < nsubroom; i++) {
378 broom = &subrooms[i];
379 if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
384 doors[aroom->fdoor].x = x;
385 doors[aroom->fdoor].y = y;
389 dosdoor(x, y, aroom, type)
391 struct mkroom *aroom;
394 boolean shdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE;
396 if (!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */
398 levl[x][y].typ = type;
400 if (!rn2(3)) { /* is it a locked door, closed, or a doorway? */
402 levl[x][y].doormask = D_ISOPEN;
404 levl[x][y].doormask = D_LOCKED;
406 levl[x][y].doormask = D_CLOSED;
408 if (levl[x][y].doormask != D_ISOPEN && !shdoor
409 && level_difficulty() >= 5 && !rn2(25))
410 levl[x][y].doormask |= D_TRAPPED;
414 levl[x][y].doormask = D_ISOPEN;
416 levl[x][y].doormask = D_NODOOR;
418 levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
422 /* also done in roguecorr(); doing it here first prevents
423 making mimics in place of trapped doors on rogue level */
424 if (Is_rogue_level(&u.uz))
425 levl[x][y].doormask = D_NODOOR;
427 if (levl[x][y].doormask & D_TRAPPED) {
430 if (level_difficulty() >= 9 && !rn2(5)
431 && !((mvitals[PM_SMALL_MIMIC].mvflags & G_GONE)
432 && (mvitals[PM_LARGE_MIMIC].mvflags & G_GONE)
433 && (mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) {
434 /* make a mimic instead */
435 levl[x][y].doormask = D_NODOOR;
436 mtmp = makemon(mkclass(S_MIMIC, 0), x, y, NO_MM_FLAGS);
443 if (shdoor || !rn2(5))
444 levl[x][y].doormask = D_LOCKED;
446 levl[x][y].doormask = D_CLOSED;
448 if (!shdoor && level_difficulty() >= 4 && !rn2(20))
449 levl[x][y].doormask |= D_TRAPPED;
452 add_door(x, y, aroom);
456 place_niche(aroom, dy, xx, yy)
457 register struct mkroom *aroom;
464 finddpos(&dd, aroom->lx, aroom->hy + 1, aroom->hx, aroom->hy + 1);
467 finddpos(&dd, aroom->lx, aroom->ly - 1, aroom->hx, aroom->ly - 1);
471 return (boolean) ((isok(*xx, *yy + *dy)
472 && levl[*xx][*yy + *dy].typ == STONE)
473 && (isok(*xx, *yy - *dy)
474 && !IS_POOL(levl[*xx][*yy - *dy].typ)
475 && !IS_FURNITURE(levl[*xx][*yy - *dy].typ)));
478 /* there should be one of these per trap, in the same order as trap.h */
479 static NEARDATA const char *trap_engravings[TRAPNUM] = {
480 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
481 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
482 (char *) 0, (char *) 0, (char *) 0, (char *) 0,
483 /* 14..16: trap door, teleport, level-teleport */
485 "Vlad was here", "ad aerarium", "ad aerarium", (char *) 0, (char *) 0,
487 "
\83\94\83\89\83h
\82Í
\82±
\82±
\82É
\82¢
\82é", "ad aerarium", "ad aerarium", (char *) 0, (char *) 0,
488 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
495 register struct mkroom *aroom;
501 if (doorindex < DOORMAX) {
503 aroom = &rooms[rn2(nroom)];
504 if (aroom->rtype != OROOM)
505 continue; /* not an ordinary room */
506 if (aroom->doorct == 1 && rn2(5))
508 if (!place_niche(aroom, &dy, &xx, &yy))
511 rm = &levl[xx][yy + dy];
512 if (trap_type || !rn2(4)) {
515 if (is_hole(trap_type) && !Can_fall_thru(&u.uz))
516 trap_type = ROCKTRAP;
517 ttmp = maketrap(xx, yy + dy, trap_type);
519 if (trap_type != ROCKTRAP)
521 if (trap_engravings[trap_type]) {
522 make_engr_at(xx, yy - dy,
523 trap_engravings[trap_type], 0L,
525 wipe_engr_at(xx, yy - dy, 5,
526 FALSE); /* age it a little */
530 dosdoor(xx, yy, aroom, SDOOR);
534 dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
536 /* inaccessible niches occasionally have iron bars */
537 if (!rn2(5) && IS_WALL(levl[xx][yy].typ)) {
538 levl[xx][yy].typ = IRONBARS;
540 (void) mkcorpstat(CORPSE, (struct monst *) 0,
541 mkclass(S_HUMAN, 0), xx,
544 if (!level.flags.noteleport)
545 (void) mksobj_at(SCR_TELEPORTATION, xx, yy + dy, TRUE,
548 (void) mkobj_at(0, xx, yy + dy, TRUE);
559 int ct = rnd((nroom >> 1) + 1), dep = depth(&u.uz);
560 boolean ltptr = (!level.flags.noteleport && dep > 15),
561 vamp = (dep > 5 && dep < 25);
564 if (ltptr && !rn2(6)) {
566 makeniche(LEVEL_TELEP);
567 } else if (vamp && !rn2(6)) {
578 makeniche(TELEP_TRAP);
581 /* clear out various globals that keep information on the current level.
582 * some of this is only necessary for some types of levels (maze, normal,
583 * special) but it's easier to put it all in one place than make sure
584 * each type initializes what it needs to separately.
587 clear_level_structures()
589 static struct rm zerorm = { cmap_to_glyph(S_stone),
590 0, 0, 0, 0, 0, 0, 0, 0, 0 };
592 register struct rm *lev;
594 for (x = 0; x < COLNO; x++) {
596 for (y = 0; y < ROWNO; y++) {
599 * These used to be '#if MICROPORT_BUG',
600 * with use of memset(0) for '#if !MICROPORT_BUG' below,
601 * but memset is not appropriate for initializing pointers,
602 * so do these level.objects[][] and level.monsters[][]
603 * initializations unconditionally.
605 level.objects[x][y] = (struct obj *) 0;
606 level.monsters[x][y] = (struct monst *) 0;
609 level.objlist = (struct obj *) 0;
610 level.buriedobjlist = (struct obj *) 0;
611 level.monlist = (struct monst *) 0;
612 level.damagelist = (struct damage *) 0;
613 level.bonesinfo = (struct cemetery *) 0;
615 level.flags.nfountains = 0;
616 level.flags.nsinks = 0;
617 level.flags.has_shop = 0;
618 level.flags.has_vault = 0;
619 level.flags.has_zoo = 0;
620 level.flags.has_court = 0;
621 level.flags.has_morgue = level.flags.graveyard = 0;
622 level.flags.has_beehive = 0;
623 level.flags.has_barracks = 0;
624 level.flags.has_temple = 0;
625 level.flags.has_swamp = 0;
626 level.flags.noteleport = 0;
627 level.flags.hardfloor = 0;
628 level.flags.nommap = 0;
629 level.flags.hero_memory = 1;
630 level.flags.shortsighted = 0;
631 level.flags.sokoban_rules = 0;
632 level.flags.is_maze_lev = 0;
633 level.flags.is_cavernous_lev = 0;
634 level.flags.arboreal = 0;
635 level.flags.wizard_bones = 0;
636 level.flags.corrmaze = 0;
645 xdnstair = ydnstair = xupstair = yupstair = 0;
646 sstairs.sx = sstairs.sy = 0;
647 xdnladder = ydnladder = xupladder = yupladder = 0;
655 register struct mkroom *croom, *troom;
658 struct monst *tmonst; /* always put a web with a spider */
662 if (wiz1_level.dlevel == 0)
664 oinit(); /* assign level dependent obj probabilities */
665 clear_level_structures();
668 register s_level *slev = Is_special(&u.uz);
670 /* check for special levels */
671 if (slev && !Is_rogue_level(&u.uz)) {
672 makemaz(slev->proto);
674 } else if (dungeons[u.uz.dnum].proto[0]) {
677 } else if (In_mines(&u.uz)) {
680 } else if (In_quest(&u.uz)) {
684 Sprintf(fillname, "%s-loca", urole.filecode);
685 loc_lev = find_level(fillname);
687 Sprintf(fillname, "%s-fil", urole.filecode);
689 (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
692 } else if (In_hell(&u.uz)
693 || (rn2(5) && u.uz.dnum == medusa_level.dnum
694 && depth(&u.uz) > depth(&medusa_level))) {
700 /* otherwise, fall through - it's a "regular" level. */
702 if (Is_rogue_level(&u.uz)) {
709 /* construct stairs (up and down in different rooms if possible) */
710 croom = &rooms[rn2(nroom)];
711 if (!Is_botlevel(&u.uz))
712 mkstairs(somex(croom), somey(croom), 0, croom); /* down */
715 croom = &rooms[rn2(nroom - 1)];
720 if (u.uz.dlevel != 1) {
725 } while (occupied(sx, sy));
726 mkstairs(sx, sy, 1, croom); /* up */
729 branchp = Is_branchlev(&u.uz); /* possible dungeon branch */
730 room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed
731 to allow a random special room */
732 if (Is_rogue_level(&u.uz))
737 /* make a secret treasure vault, not connected to the rest */
741 debugpline0("trying to make a vault...");
744 if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) {
746 add_room(vault_x, vault_y, vault_x + w, vault_y + h, TRUE, VAULT,
748 level.flags.has_vault = 1;
750 fill_room(&rooms[nroom - 1], FALSE);
751 mk_knox_portal(vault_x + w, vault_y + h);
752 if (!level.flags.noteleport && !rn2(3))
754 } else if (rnd_rect() && create_vault()) {
755 vault_x = rooms[nroom].lx;
756 vault_y = rooms[nroom].ly;
757 if (check_room(&vault_x, &w, &vault_y, &h, TRUE))
760 rooms[nroom].hx = -1;
765 register int u_depth = depth(&u.uz);
767 if (wizard && nh_getenv("SHOPTYPE"))
769 else if (u_depth > 1 && u_depth < depth(&medusa_level)
770 && nroom >= room_threshold && rn2(u_depth) < 3)
772 else if (u_depth > 4 && !rn2(6))
774 else if (u_depth > 5 && !rn2(8)
775 && !(mvitals[PM_LEPRECHAUN].mvflags & G_GONE))
777 else if (u_depth > 6 && !rn2(7))
779 else if (u_depth > 8 && !rn2(5))
781 else if (u_depth > 9 && !rn2(5)
782 && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
784 else if (u_depth > 11 && !rn2(6))
786 else if (u_depth > 12 && !rn2(8) && antholemon())
788 else if (u_depth > 14 && !rn2(4)
789 && !(mvitals[PM_SOLDIER].mvflags & G_GONE))
791 else if (u_depth > 15 && !rn2(6))
793 else if (u_depth > 16 && !rn2(8)
794 && !(mvitals[PM_COCKATRICE].mvflags & G_GONE))
799 /* Place multi-dungeon branch. */
800 place_branch(branchp, 0, 0);
802 /* for each room: put things inside */
803 for (croom = rooms; croom->hx > 0; croom++) {
804 if (croom->rtype != OROOM)
807 /* put a sleeping monster inside */
808 /* Note: monster may be on the stairs. This cannot be
809 avoided: maybe the player fell through a trap door
810 while a monster was on the stairs. Conclusion:
811 we have to check for monsters on the stairs anyway. */
813 if (u.uhave.amulet || !rn2(3)) {
816 tmonst = makemon((struct permonst *) 0, x, y, MM_NOGRP);
817 if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]
819 (void) maketrap(x, y, WEB);
821 /* put traps and mimics inside */
822 x = 8 - (level_difficulty() / 6);
826 mktrap(0, 0, croom, (coord *) 0);
828 (void) mkgold(0L, somex(croom), somey(croom));
829 if (Is_rogue_level(&u.uz))
837 x = 80 - (depth(&u.uz) * 2);
843 /* put statues inside */
845 (void) mkcorpstat(STATUE, (struct monst *) 0,
846 (struct permonst *) 0, somex(croom),
847 somey(croom), CORPSTAT_INIT);
848 /* put box/chest inside;
849 * 40% chance for at least 1 box, regardless of number
850 * of rooms; about 5 - 7.5% for 2 boxes, least likely
851 * when few rooms; chance for 3 or more is negligible.
853 if (!rn2(nroom * 5 / 2))
854 (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, somex(croom),
855 somey(croom), TRUE, FALSE);
857 /* maybe make some graffiti */
858 if (!rn2(27 + 3 * abs(depth(&u.uz)))) {
860 const char *mesg = random_engraving(buf);
866 } while (levl[x][y].typ != ROOM && !rn2(40));
867 if (!(IS_POOL(levl[x][y].typ)
868 || IS_FURNITURE(levl[x][y].typ)))
869 make_engr_at(x, y, mesg, 0L, MARK);
875 (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
879 impossible("tryct overflow4");
882 (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
889 * Place deposits of minerals (gold and misc gems) in the stone
890 * surrounding the rooms on the map.
891 * Also place kelp in water.
892 * mineralize(-1, -1, -1, -1, FALSE); => "default" behaviour
895 mineralize(kelp_pool, kelp_moat, goldprob, gemprob, skip_lvl_checks)
896 int kelp_pool, kelp_moat, goldprob, gemprob;
897 boolean skip_lvl_checks;
908 /* Place kelp, except on the plane of water */
909 if (!skip_lvl_checks && In_endgame(&u.uz))
911 for (x = 2; x < (COLNO - 2); x++)
912 for (y = 1; y < (ROWNO - 1); y++)
913 if ((kelp_pool && levl[x][y].typ == POOL && !rn2(kelp_pool))
914 || (kelp_moat && levl[x][y].typ == MOAT && !rn2(kelp_moat)))
915 (void) mksobj_at(KELP_FROND, x, y, TRUE, FALSE);
917 /* determine if it is even allowed;
918 almost all special levels are excluded */
920 && (In_hell(&u.uz) || In_V_tower(&u.uz) || Is_rogue_level(&u.uz)
921 || level.flags.arboreal
922 || ((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz)
923 && (!In_mines(&u.uz) || sp->flags.town))))
926 /* basic level-related probabilities */
928 goldprob = 20 + depth(&u.uz) / 3;
930 gemprob = goldprob / 4;
932 /* mines have ***MORE*** goodies - otherwise why mine? */
933 if (!skip_lvl_checks) {
934 if (In_mines(&u.uz)) {
937 } else if (In_quest(&u.uz)) {
944 * Seed rock areas with gold and/or gems.
945 * We use fairly low level object handling to avoid unnecessary
946 * overhead from placing things in the floor chain prior to burial.
948 for (x = 2; x < (COLNO - 2); x++)
949 for (y = 1; y < (ROWNO - 1); y++)
950 if (levl[x][y + 1].typ != STONE) { /* <x,y> spot not eligible */
951 y += 2; /* next two spots aren't eligible either */
952 } else if (levl[x][y].typ != STONE) { /* this spot not eligible */
953 y += 1; /* next spot isn't eligible either */
954 } else if (!(levl[x][y].wall_info & W_NONDIGGABLE)
955 && levl[x][y - 1].typ == STONE
956 && levl[x + 1][y - 1].typ == STONE
957 && levl[x - 1][y - 1].typ == STONE
958 && levl[x + 1][y].typ == STONE
959 && levl[x - 1][y].typ == STONE
960 && levl[x + 1][y + 1].typ == STONE
961 && levl[x - 1][y + 1].typ == STONE) {
962 if (rn2(1000) < goldprob) {
963 if ((otmp = mksobj(GOLD_PIECE, FALSE, FALSE)) != 0) {
964 otmp->ox = x, otmp->oy = y;
965 otmp->quan = 1L + rnd(goldprob * 3);
966 otmp->owt = weight(otmp);
970 place_object(otmp, x, y);
973 if (rn2(1000) < gemprob) {
974 for (cnt = rnd(2 + dunlev(&u.uz) / 3); cnt > 0; cnt--)
975 if ((otmp = mkobj(GEM_CLASS, FALSE)) != 0) {
976 if (otmp->otyp == ROCK) {
977 dealloc_obj(otmp); /* discard it */
979 otmp->ox = x, otmp->oy = y;
983 place_object(otmp, x, y);
993 struct mkroom *croom;
997 reseed_random(rn2_on_display_rng);
1006 mineralize(-1, -1, -1, -1, FALSE);
1008 /* has_morgue gets cleared once morgue is entered; graveyard stays
1009 set (graveyard might already be set even when has_morgue is clear
1010 [see fixup_special()], so don't update it unconditionally) */
1011 if (level.flags.has_morgue)
1012 level.flags.graveyard = 1;
1013 if (!level.flags.is_maze_lev) {
1014 for (croom = &rooms[0]; croom != &rooms[nroom]; croom++)
1015 #ifdef SPECIALIZATION
1016 topologize(croom, FALSE);
1022 /* for many room types, rooms[].rtype is zeroed once the room has been
1023 entered; rooms[].orig_rtype always retains original rtype value */
1024 for (ridx = 0; ridx < SIZE(rooms); ridx++)
1025 rooms[ridx].orig_rtype = rooms[ridx].rtype;
1028 reseed_random(rn2_on_display_rng);
1032 #ifdef SPECIALIZATION
1033 topologize(croom, do_ordinary)
1034 struct mkroom *croom;
1035 boolean do_ordinary;
1038 struct mkroom *croom;
1041 register int x, y, roomno = (int) ((croom - rooms) + ROOMOFFSET);
1042 int lowx = croom->lx, lowy = croom->ly;
1043 int hix = croom->hx, hiy = croom->hy;
1044 #ifdef SPECIALIZATION
1045 schar rtype = croom->rtype;
1047 int subindex, nsubrooms = croom->nsubrooms;
1049 /* skip the room if already done; i.e. a shop handled out of order */
1050 /* also skip if this is non-rectangular (it _must_ be done already) */
1051 if ((int) levl[lowx][lowy].roomno == roomno || croom->irregular)
1053 #ifdef SPECIALIZATION
1054 if (Is_rogue_level(&u.uz))
1055 do_ordinary = TRUE; /* vision routine helper */
1056 if ((rtype != OROOM) || do_ordinary)
1059 /* do innards first */
1060 for (x = lowx; x <= hix; x++)
1061 for (y = lowy; y <= hiy; y++)
1062 #ifdef SPECIALIZATION
1064 levl[x][y].roomno = NO_ROOM;
1067 levl[x][y].roomno = roomno;
1068 /* top and bottom edges */
1069 for (x = lowx - 1; x <= hix + 1; x++)
1070 for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
1071 levl[x][y].edge = 1;
1072 if (levl[x][y].roomno)
1073 levl[x][y].roomno = SHARED;
1075 levl[x][y].roomno = roomno;
1078 for (x = lowx - 1; x <= hix + 1; x += (hix - lowx + 2))
1079 for (y = lowy; y <= hiy; y++) {
1080 levl[x][y].edge = 1;
1081 if (levl[x][y].roomno)
1082 levl[x][y].roomno = SHARED;
1084 levl[x][y].roomno = roomno;
1088 for (subindex = 0; subindex < nsubrooms; subindex++)
1089 #ifdef SPECIALIZATION
1090 topologize(croom->sbrooms[subindex], (boolean) (rtype != OROOM));
1092 topologize(croom->sbrooms[subindex]);
1096 /* Find an unused room for a branch location. */
1097 STATIC_OVL struct mkroom *
1098 find_branch_room(mp)
1101 struct mkroom *croom = 0;
1104 mazexy(mp); /* already verifies location */
1106 /* not perfect - there may be only one stairway */
1111 croom = &rooms[rn2(nroom)];
1112 while ((croom == dnstairs_room || croom == upstairs_room
1113 || croom->rtype != OROOM) && (++tryct < 100));
1115 croom = &rooms[rn2(nroom)];
1118 if (!somexy(croom, mp))
1119 impossible("Can't place branch!");
1120 } while (occupied(mp->x, mp->y)
1121 || (levl[mp->x][mp->y].typ != CORR
1122 && levl[mp->x][mp->y].typ != ROOM));
1127 /* Find the room for (x,y). Return null if not in a room. */
1128 STATIC_OVL struct mkroom *
1133 struct mkroom *curr;
1135 for (curr = rooms, i = 0; i < nroom; curr++, i++)
1136 if (inside_room(curr, x, y))
1139 return (struct mkroom *) 0;
1142 /* If given a branch, randomly place a special stair or portal. */
1144 place_branch(br, x, y)
1145 branch *br; /* branch to place */
1146 xchar x, y; /* location */
1150 boolean make_stairs;
1151 struct mkroom *br_room;
1154 * Return immediately if there is no branch to make or we have
1155 * already made one. This routine can be called twice when
1156 * a special level is loaded that specifies an SSTAIR location
1157 * as a favored spot for a branch.
1159 if (!br || made_branch)
1162 if (!x) { /* find random coordinates for branch */
1163 br_room = find_branch_room(&m);
1167 br_room = pos_to_room(x, y);
1170 if (on_level(&br->end1, &u.uz)) {
1172 make_stairs = br->type != BR_NO_END1;
1176 make_stairs = br->type != BR_NO_END2;
1180 if (br->type == BR_PORTAL) {
1181 mkportal(x, y, dest->dnum, dest->dlevel);
1182 } else if (make_stairs) {
1186 (char) on_level(&br->end1, &u.uz) ? br->end1_up : !br->end1_up;
1187 assign_level(&sstairs.tolev, dest);
1188 sstairs_room = br_room;
1190 levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN;
1191 levl[x][y].typ = STAIRS;
1194 * Set made_branch to TRUE even if we didn't make a stairwell (i.e.
1195 * make_stairs is false) since there is currently only one branch
1196 * per level, if we failed once, we're going to fail again on the
1204 register xchar x, y;
1208 if (isok(x + 1, y)) {
1209 typ = levl[x + 1][y].typ;
1210 if (IS_DOOR(typ) || typ == SDOOR)
1213 if (isok(x - 1, y)) {
1214 typ = levl[x - 1][y].typ;
1215 if (IS_DOOR(typ) || typ == SDOOR)
1218 if (isok(x, y + 1)) {
1219 typ = levl[x][y + 1].typ;
1220 if (IS_DOOR(typ) || typ == SDOOR)
1223 if (isok(x, y - 1)) {
1224 typ = levl[x][y - 1].typ;
1225 if (IS_DOOR(typ) || typ == SDOOR)
1231 /* see whether it is allowable to create a door at [x,y] */
1236 boolean near_door = bydoor(x, y);
1238 return ((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL)
1239 && doorindex < DOORMAX && !near_door);
1245 struct mkroom *aroom;
1247 if (doorindex >= DOORMAX) {
1248 impossible("DOORMAX exceeded?");
1252 dosdoor(x, y, aroom, rn2(8) ? DOOR : SDOOR);
1257 register xchar x, y;
1259 return (boolean) (t_at(x, y) || IS_FURNITURE(levl[x][y].typ)
1260 || is_lava(x, y) || is_pool(x, y)
1261 || invocation_pos(x, y));
1264 /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
1265 /* if tm != null, make trap at that location */
1267 mktrap(num, mazeflag, croom, tm)
1269 struct mkroom *croom;
1274 unsigned lvl = level_difficulty();
1277 /* no traps in pools */
1278 if (tm && is_pool(tm->x, tm->y))
1281 if (num > 0 && num < TRAPNUM) {
1283 } else if (Is_rogue_level(&u.uz)) {
1301 kind = SLP_GAS_TRAP;
1307 } else if (Inhell && !rn2(5)) {
1308 /* bias the frequency of fire traps in Gehennom */
1312 kind = rnd(TRAPNUM - 1);
1313 /* reject "too hard" traps */
1316 case VIBRATING_SQUARE:
1319 case ROLLING_BOULDER_TRAP:
1325 if (lvl < 5 || level.flags.noteleport)
1350 if (level.flags.noteleport)
1354 /* make these much less often than other traps */
1359 } while (kind == NO_TRAP);
1362 if (is_hole(kind) && !Can_fall_thru(&u.uz))
1368 register int tryct = 0;
1369 boolean avoid_boulder = (is_pit(kind) || is_hole(kind));
1376 else if (!somexy(croom, &m))
1378 } while (occupied(m.x, m.y)
1379 || (avoid_boulder && sobj_at(BOULDER, m.x, m.y)));
1382 t = maketrap(m.x, m.y, kind);
1383 /* we should always get type of trap we're asking for (occupied() test
1384 should prevent cases where that might not happen) but be paranoid */
1385 kind = t ? t->ttyp : NO_TRAP;
1388 (void) makemon(&mons[PM_GIANT_SPIDER], m.x, m.y, NO_MM_FLAGS);
1390 /* The hero isn't the only person who's entered the dungeon in
1391 search of treasure. On the very shallowest levels, there's a
1392 chance that a created trap will have killed something already
1393 (and this is guaranteed on the first level).
1395 This isn't meant to give any meaningful treasure (in fact, any
1396 items we drop here are typically cursed, other than ammo fired
1397 by the trap). Rather, it's mostly just for flavour and to give
1398 players on very early levels a sufficient chance to avoid traps
1399 that may end up killing them before they have a fair chance to
1400 build max HP. Including cursed items gives the same fair chance
1401 to the starting pet, and fits the rule that possessions of the
1402 dead are normally cursed.
1404 Some types of traps are excluded because they're entirely
1405 nonlethal, even indirectly. We also exclude all of the
1406 later/fancier traps because they tend to have special
1407 considerations (e.g. webs, portals), often are indirectly
1408 lethal, and tend not to generate on shallower levels anyway.
1409 Finally, pits are excluded because it's weird to see an item
1410 in a pit and yet not be able to identify that the pit is there. */
1411 if (kind != NO_TRAP && lvl <= (unsigned) rnd(4)
1412 && kind != SQKY_BOARD && kind != RUST_TRAP
1413 /* rolling boulder trap might not have a boulder if there was no
1414 viable path (such as when placed in the corner of a room), in
1415 which case tx,ty==launch.x,y; no boulder => no dead predecessor */
1416 && !(kind == ROLLING_BOULDER_TRAP
1417 && t->launch.x == t->tx && t->launch.y == t->ty)
1418 && !is_pit(kind) && kind < HOLE) {
1419 /* Object generated by the trap; initially NULL, stays NULL if
1420 we fail to generate an object or if the trap doesn't
1421 generate objects. */
1422 struct obj *otmp = NULL;
1423 int victim_mnum; /* race of the victim */
1425 /* Not all trap types have special handling here; only the ones
1426 that kill in a specific way that's obvious after the fact. */
1429 otmp = mksobj(ARROW, TRUE, FALSE);
1430 otmp->opoisoned = 0;
1431 /* don't adjust the quantity; maybe the trap shot multiple
1432 times, there was an untrapping attempt, etc... */
1435 otmp = mksobj(DART, TRUE, FALSE);
1438 otmp = mksobj(ROCK, TRUE, FALSE);
1441 /* no item dropped by the trap */
1445 place_object(otmp, m.x, m.y);
1448 /* now otmp is reused for other items we're placing */
1450 /* Place a random possession. This could be a weapon, tool,
1451 food, or gem, i.e. the item classes that are typically
1452 nonmagical and not worthless. */
1454 int poss_class = RANDOM_CLASS; /* init => lint suppression */
1458 poss_class = WEAPON_CLASS;
1461 poss_class = TOOL_CLASS;
1464 poss_class = FOOD_CLASS;
1467 poss_class = GEM_CLASS;
1471 otmp = mkobj(poss_class, FALSE);
1472 /* these items are always cursed, both for flavour (owned
1473 by a dead adventurer, bones-pile-style) and for balance
1474 (less useful to use, and encourage pets to avoid the trap) */
1478 otmp->owt = weight(otmp);
1479 place_object(otmp, m.x, m.y);
1482 /* 20% chance of placing an additional item, recursively */
1485 /* Place a corpse. */
1488 /* elf corpses are the rarest as they're the most useful */
1489 victim_mnum = PM_ELF;
1490 /* elven adventurers get sleep resistance early; so don't
1491 generate elf corpses on sleeping gas traps unless a)
1492 we're on dlvl 2 (1 is impossible) and b) we pass a coin
1494 if (kind == SLP_GAS_TRAP && !(lvl <= 2 && rn2(2)))
1495 victim_mnum = PM_HUMAN;
1498 victim_mnum = PM_DWARF;
1500 case 3: case 4: case 5:
1501 victim_mnum = PM_ORC;
1503 case 6: case 7: case 8: case 9:
1504 /* more common as they could have come from the Mines */
1505 victim_mnum = PM_GNOME;
1506 /* 10% chance of a candle too */
1508 otmp = mksobj(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE,
1513 otmp->owt = weight(otmp);
1514 place_object(otmp, m.x, m.y);
1518 /* the most common race */
1519 victim_mnum = PM_HUMAN;
1522 otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], m.x, m.y,
1525 otmp->age -= 51; /* died too long ago to eat */
1530 mkstairs(x, y, up, croom)
1533 struct mkroom *croom;
1536 impossible("mkstairs: bogus stair attempt at <%d,%d>", x, y);
1541 * We can't make a regular stair off an end of the dungeon. This
1542 * attempt can happen when a special level is placed at an end and
1543 * has an up or down stair specified in its description file.
1545 if ((dunlev(&u.uz) == 1 && up)
1546 || (dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up))
1552 upstairs_room = croom;
1556 dnstairs_room = croom;
1559 levl[x][y].typ = STAIRS;
1560 levl[x][y].ladder = up ? LA_UP : LA_DOWN;
1564 mkfount(mazeflag, croom)
1566 struct mkroom *croom;
1569 register int tryct = 0;
1576 else if (!somexy(croom, &m))
1578 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1580 /* Put a fountain at m.x, m.y */
1581 levl[m.x][m.y].typ = FOUNTAIN;
1582 /* Is it a "blessed" fountain? (affects drinking from fountain) */
1584 levl[m.x][m.y].blessedftn = 1;
1586 level.flags.nfountains++;
1591 struct mkroom *croom;
1594 register int tryct = 0;
1599 if (!somexy(croom, &m))
1601 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1603 /* Put a sink at m.x, m.y */
1604 levl[m.x][m.y].typ = SINK;
1606 level.flags.nsinks++;
1611 struct mkroom *croom;
1614 register int tryct = 0;
1617 if (croom->rtype != OROOM)
1623 if (!somexy(croom, &m))
1625 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1627 /* Put an altar at m.x, m.y */
1628 levl[m.x][m.y].typ = ALTAR;
1630 /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
1631 al = rn2((int) A_LAWFUL + 2) - 1;
1632 levl[m.x][m.y].altarmask = Align2amask(al);
1637 struct mkroom *croom;
1640 register int tryct = 0;
1641 register struct obj *otmp;
1642 boolean dobell = !rn2(10);
1644 if (croom->rtype != OROOM)
1650 if (!somexy(croom, &m))
1652 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1654 /* Put a grave at <m.x,m.y> */
1656 make_grave(m.x, m.y, dobell ? "Saved by the bell!" : (char *) 0);
1658 make_grave(m.x, m.y, dobell ? "
\83x
\83\8b\82É
\8b~
\82í
\82ê
\82½
\81I" : (char *) 0);
1660 /* Possibly fill it with objects */
1662 /* this used to use mkgold(), which puts a stack of gold on
1663 the ground (or merges it with an existing one there if
1664 present), and didn't bother burying it; now we create a
1665 loose, easily buriable, stack but we make no attempt to
1666 replicate mkgold()'s level-based formula for the amount */
1667 struct obj *gold = mksobj(GOLD_PIECE, TRUE, FALSE);
1669 gold->quan = (long) (rnd(20) + level_difficulty() * rnd(5));
1670 gold->owt = weight(gold);
1671 gold->ox = m.x, gold->oy = m.y;
1672 add_to_buried(gold);
1674 for (tryct = rn2(5); tryct; tryct--) {
1675 otmp = mkobj(RANDOM_CLASS, TRUE);
1681 add_to_buried(otmp);
1684 /* Leave a bell, in case we accidentally buried someone alive */
1686 (void) mksobj_at(BELL, m.x, m.y, TRUE, FALSE);
1690 /* maze levels have slightly different constraints from normal levels */
1691 #define x_maze_min 2
1692 #define y_maze_min 2
1695 * Major level transmutation: add a set of stairs (to the Sanctum) after
1696 * an earthquake that leaves behind a a new topology, centered at inv_pos.
1697 * Assumes there are no rooms within the invocation area and that inv_pos
1698 * is not too close to the edge of the map. Also assume the hero can see,
1699 * which is guaranteed for normal play due to the fact that sight is needed
1700 * to read the Book of the Dead.
1706 xchar xmin = inv_pos.x, xmax = inv_pos.x;
1707 xchar ymin = inv_pos.y, ymax = inv_pos.y;
1711 pline_The("floor shakes violently under you!");
1713 pline("
\82 \82È
\82½
\82Ì
\89º
\82Ì
\8f°
\82ª
\93Ë
\91R
\97h
\82ê
\82½
\81I");
1715 pline_The("walls around you begin to bend and crumble!");
1717 pline("
\82»
\82µ
\82Ä
\82Ü
\82í
\82è
\82Ì
\95Ç
\82ª
\82Ë
\82¶
\82ê
\81C
\8dÓ
\82¯
\82½
\81I");
1718 display_nhwindow(WIN_MESSAGE, TRUE);
1720 /* any trap hero is stuck in will be going away now */
1722 if (u.utraptype == TT_BURIEDBALL)
1723 buried_ball_to_punishment();
1726 mkinvpos(xmin, ymin, 0); /* middle, before placing stairs */
1728 for (dist = 1; dist < 7; dist++) {
1732 /* top and bottom */
1733 if (dist != 3) { /* the area is wider that it is high */
1736 for (i = xmin + 1; i < xmax; i++) {
1737 mkinvpos(i, ymin, dist);
1738 mkinvpos(i, ymax, dist);
1742 /* left and right */
1743 for (i = ymin; i <= ymax; i++) {
1744 mkinvpos(xmin, i, dist);
1745 mkinvpos(xmax, i, dist);
1748 flush_screen(1); /* make sure the new glyphs shows up */
1753 You("are standing at the top of a stairwell leading down!");
1755 You("
\89º
\82É
\91±
\82
\90\81\82«
\94²
\82¯
\8aK
\92i
\82Ì
\8fã
\82É
\97§
\82Á
\82Ä
\82¢
\82é
\81I");
1756 mkstairs(u.ux, u.uy, 0, (struct mkroom *) 0); /* down */
1758 vision_full_recalc = 1; /* everything changed */
1761 /* Change level topology. Boulders in the vicinity are eliminated.
1762 * Temporarily overrides vision in the name of a nice effect.
1765 mkinvpos(x, y, dist)
1772 register struct rm *lev = &levl[x][y];
1775 /* clip at existing map borders if necessary */
1776 if (!within_bounded_area(x, y, x_maze_min + 1, y_maze_min + 1,
1777 x_maze_max - 1, y_maze_max - 1)) {
1778 /* only outermost 2 columns and/or rows may be truncated due to edge
1781 panic("mkinvpos: <%d,%d> (%d) off map edge!", x, y, dist);
1786 if ((ttmp = t_at(x, y)) != 0)
1789 /* clear boulders; leave some rocks for non-{moat|trap} locations */
1790 make_rocks = (dist != 1 && dist != 4 && dist != 5) ? TRUE : FALSE;
1791 while ((otmp = sobj_at(BOULDER, x, y)) != 0) {
1793 fracture_rock(otmp);
1794 make_rocks = FALSE; /* don't bother with more rocks */
1796 obj_extract_self(otmp);
1797 obfree(otmp, (struct obj *) 0);
1801 /* fake out saved state */
1807 lev->horizontal = FALSE;
1808 /* short-circuit vision recalc */
1809 viz_array[y][x] = (dist < 6) ? (IN_SIGHT | COULD_SEE) : COULD_SEE;
1812 case 1: /* fire traps */
1816 ttmp = maketrap(x, y, FIRE_TRAP);
1820 case 0: /* lit room locations */
1823 case 6: /* unlit room locations */
1826 case 4: /* pools (aka a wide moat) */
1832 impossible("mkinvpos called with dist %d", dist);
1836 if ((mon = m_at(x, y)) != 0) {
1837 /* wake up mimics, don't want to deal with them blocking vision */
1841 if ((ttmp = t_at(x, y)) != 0)
1842 (void) mintrap(mon);
1844 (void) minliquid(mon);
1847 if (!does_block(x, y, lev))
1848 unblock_point(x, y); /* make sure vision knows this location is open */
1850 /* display new value of position; could have a monster/object on it */
1855 * The portal to Ludios is special. The entrance can only occur within a
1856 * vault in the main dungeon at a depth greater than 10. The Ludios branch
1857 * structure reflects this by having a bogus "source" dungeon: the value
1858 * of n_dgns (thus, Is_branchlev() will never find it).
1860 * Ludios will remain isolated until the branch is corrected by this function.
1863 mk_knox_portal(x, y)
1866 extern int n_dgns; /* from dungeon.c */
1872 br = dungeon_branch("Fort Ludios");
1874 br = dungeon_branch("
\83\8d\81[
\83f
\83B
\83I
\83X
\8dÔ");
1875 if (on_level(&knox_level, &br->end1)) {
1878 /* disallow Knox branch on a level with one branch already */
1879 if (Is_branchlev(&u.uz))
1884 /* Already set or 2/3 chance of deferring until a later level. */
1885 if (source->dnum < n_dgns || (rn2(3) && !wizard))
1888 if (!(u.uz.dnum == oracle_level.dnum /* in main dungeon */
1890 && !at_dgn_entrance("The Quest") /* but not Quest's entry */
1892 && !at_dgn_entrance("
\83N
\83G
\83X
\83g") /* but not Quest's entry */
1894 && (u_depth = depth(&u.uz)) > 10 /* beneath 10 */
1895 && u_depth < depth(&medusa_level))) /* and above Medusa */
1898 /* Adjust source to be current level and re-insert branch. */
1900 insert_branch(br, TRUE);
1902 debugpline0("Made knox portal.");
1903 place_branch(br, x, y);