1 /* NetHack 3.6 mklev.c $NHDT-Date: 1446191876 2015/10/30 07:57:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.44 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 /* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
13 /* croom->lx etc are schar (width <= int), so % arith ensures that */
14 /* conversion of result to int is reasonable */
16 STATIC_DCL void FDECL(mkfount, (int, struct mkroom *));
17 STATIC_DCL void FDECL(mksink, (struct mkroom *));
18 STATIC_DCL void FDECL(mkaltar, (struct mkroom *));
19 STATIC_DCL void FDECL(mkgrave, (struct mkroom *));
20 STATIC_DCL void NDECL(makevtele);
21 STATIC_DCL void NDECL(clear_level_structures);
22 STATIC_DCL void NDECL(makelevel);
23 STATIC_DCL boolean FDECL(bydoor, (XCHAR_P, XCHAR_P));
24 STATIC_DCL struct mkroom *FDECL(find_branch_room, (coord *));
25 STATIC_DCL struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P));
26 STATIC_DCL boolean FDECL(place_niche, (struct mkroom *, int *, int *, int *));
27 STATIC_DCL void FDECL(makeniche, (int));
28 STATIC_DCL void NDECL(make_niches);
29 STATIC_PTR int FDECL(CFDECLSPEC do_comp, (const genericptr,
31 STATIC_DCL void FDECL(dosdoor, (XCHAR_P, XCHAR_P, struct mkroom *, int));
32 STATIC_DCL void FDECL(join, (int, int, BOOLEAN_P));
33 STATIC_DCL void FDECL(do_room_or_subroom, (struct mkroom *, int, int,
35 SCHAR_P, BOOLEAN_P, BOOLEAN_P));
36 STATIC_DCL void NDECL(makerooms);
37 STATIC_DCL void FDECL(finddpos, (coord *, XCHAR_P, XCHAR_P,
39 STATIC_DCL void FDECL(mkinvpos, (XCHAR_P, XCHAR_P, int));
40 STATIC_DCL void FDECL(mk_knox_portal, (XCHAR_P, XCHAR_P));
42 #define create_vault() create_room(-1, -1, 2, 2, -1, -1, VAULT, TRUE)
43 #define init_vault() vault_x = -1
44 #define do_vault() (vault_x != -1)
45 static xchar vault_x, vault_y;
46 static boolean made_branch; /* used only during level creation */
48 /* Args must be (const genericptr) so that qsort will always be happy. */
50 STATIC_PTR int CFDECLSPEC
56 /* lint complains about possible pointer alignment problems, but we know
57 that vx and vy are always properly aligned. Hence, the following
60 return (vx == vy) ? 0 : -1;
62 register const struct mkroom *x, *y;
64 x = (const struct mkroom *) vx;
65 y = (const struct mkroom *) vy;
68 return (x->lx > y->lx);
73 finddpos(cc, xl, yl, xh, yh)
79 x = rn1(xh - xl + 1, xl);
80 y = rn1(yh - yl + 1, yl);
84 for (x = xl; x <= xh; x++)
85 for (y = yl; y <= yh; y++)
89 for (x = xl; x <= xh; x++)
90 for (y = yl; y <= yh; y++)
91 if (IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
93 /* cannot find something reasonable -- strange */
105 #if defined(SYSV) || defined(DGUX)
106 qsort((genericptr_t) rooms, (unsigned) nroom, sizeof(struct mkroom),
109 qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), do_comp);
114 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room)
115 register struct mkroom *croom;
117 register int hix, hiy;
126 /* locations might bump level edges in wall-less rooms */
127 /* add/subtract 1 to allow for edge locations */
132 if (hix >= COLNO - 1)
134 if (hiy >= ROWNO - 1)
138 for (x = lowx - 1; x <= hix + 1; x++) {
139 lev = &levl[x][max(lowy - 1, 0)];
140 for (y = lowy - 1; y <= hiy + 1; y++)
151 croom->rtype = rtype;
153 /* if we're not making a vault, doorindex will still be 0
154 * if we are, we'll have problems adding niches to the previous room
155 * unless fdoor is at least doorindex
157 croom->fdoor = doorindex;
158 croom->irregular = FALSE;
160 croom->nsubrooms = 0;
161 croom->sbrooms[0] = (struct mkroom *) 0;
163 for (x = lowx - 1; x <= hix + 1; x++)
164 for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
165 levl[x][y].typ = HWALL;
166 levl[x][y].horizontal = 1; /* For open/secret doors. */
168 for (x = lowx - 1; x <= hix + 1; x += (hix - lowx + 2))
169 for (y = lowy; y <= hiy; y++) {
170 levl[x][y].typ = VWALL;
171 levl[x][y].horizontal = 0; /* For open/secret doors. */
173 for (x = lowx; x <= hix; x++) {
174 lev = &levl[x][lowy];
175 for (y = lowy; y <= hiy; y++)
179 levl[lowx - 1][lowy - 1].typ = TLCORNER;
180 levl[hix + 1][lowy - 1].typ = TRCORNER;
181 levl[lowx - 1][hiy + 1].typ = BLCORNER;
182 levl[hix + 1][hiy + 1].typ = BRCORNER;
183 } else { /* a subroom */
184 wallification(lowx - 1, lowy - 1, hix + 1, hiy + 1);
190 add_room(lowx, lowy, hix, hiy, lit, rtype, special)
191 int lowx, lowy, hix, hiy;
196 register struct mkroom *croom;
198 croom = &rooms[nroom];
199 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
207 add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special)
208 struct mkroom *proom;
209 int lowx, lowy, hix, hiy;
214 register struct mkroom *croom;
216 croom = &subrooms[nsubroom];
217 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
219 proom->sbrooms[proom->nsubrooms++] = croom;
228 boolean tried_vault = FALSE;
230 /* make rooms until satisfied */
231 /* rnd_rect() will returns 0 if no more rects are available... */
232 while (nroom < MAXNROFROOMS && rnd_rect()) {
233 if (nroom >= (MAXNROFROOMS / 6) && rn2(2) && !tried_vault) {
235 if (create_vault()) {
236 vault_x = rooms[nroom].lx;
237 vault_y = rooms[nroom].ly;
238 rooms[nroom].hx = -1;
240 } else if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
251 coord cc, tt, org, dest;
252 register xchar tx, ty, xx, yy;
253 register struct mkroom *croom, *troom;
259 /* find positions cc and tt for doors in croom and troom
260 and direction for a corridor between them */
262 if (troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX)
264 if (troom->lx > croom->hx) {
269 finddpos(&cc, xx, croom->ly, xx, croom->hy);
270 finddpos(&tt, tx, troom->ly, tx, troom->hy);
271 } else if (troom->hy < croom->ly) {
275 finddpos(&cc, croom->lx, yy, croom->hx, yy);
277 finddpos(&tt, troom->lx, ty, troom->hx, ty);
278 } else if (troom->hx < croom->lx) {
283 finddpos(&cc, xx, croom->ly, xx, croom->hy);
284 finddpos(&tt, tx, troom->ly, tx, troom->hy);
290 finddpos(&cc, croom->lx, yy, croom->hx, yy);
291 finddpos(&tt, troom->lx, ty, troom->hx, ty);
297 if (nxcor && levl[xx + dx][yy + dy].typ)
299 if (okdoor(xx, yy) || !nxcor)
300 dodoor(xx, yy, croom);
307 if (!dig_corridor(&org, &dest, nxcor, level.flags.arboreal ? ROOM : CORR,
311 /* we succeeded in digging the corridor */
312 if (okdoor(tt.x, tt.y) || !nxcor)
313 dodoor(tt.x, tt.y, troom);
315 if (smeq[a] < smeq[b])
327 for (a = 0; a < nroom - 1; a++) {
328 join(a, a + 1, FALSE);
330 break; /* allow some randomness */
332 for (a = 0; a < nroom - 2; a++)
333 if (smeq[a] != smeq[a + 2])
334 join(a, a + 2, FALSE);
335 for (a = 0; any && a < nroom; a++) {
337 for (b = 0; b < nroom; b++)
338 if (smeq[a] != smeq[b]) {
344 for (i = rn2(nroom) + 4; i; i--) {
354 add_door(x, y, aroom)
356 register struct mkroom *aroom;
358 register struct mkroom *broom;
362 if (aroom->doorct == 0)
363 aroom->fdoor = doorindex;
367 for (tmp = doorindex; tmp > aroom->fdoor; tmp--)
368 doors[tmp] = doors[tmp - 1];
370 for (i = 0; i < nroom; i++) {
372 if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
375 for (i = 0; i < nsubroom; i++) {
376 broom = &subrooms[i];
377 if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
382 doors[aroom->fdoor].x = x;
383 doors[aroom->fdoor].y = y;
387 dosdoor(x, y, aroom, type)
389 struct mkroom *aroom;
392 boolean shdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE;
394 if (!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */
396 levl[x][y].typ = type;
398 if (!rn2(3)) { /* is it a locked door, closed, or a doorway? */
400 levl[x][y].doormask = D_ISOPEN;
402 levl[x][y].doormask = D_LOCKED;
404 levl[x][y].doormask = D_CLOSED;
406 if (levl[x][y].doormask != D_ISOPEN && !shdoor
407 && level_difficulty() >= 5 && !rn2(25))
408 levl[x][y].doormask |= D_TRAPPED;
412 levl[x][y].doormask = D_ISOPEN;
414 levl[x][y].doormask = D_NODOOR;
416 levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
420 /* also done in roguecorr(); doing it here first prevents
421 making mimics in place of trapped doors on rogue level */
422 if (Is_rogue_level(&u.uz))
423 levl[x][y].doormask = D_NODOOR;
425 if (levl[x][y].doormask & D_TRAPPED) {
428 if (level_difficulty() >= 9 && !rn2(5)
429 && !((mvitals[PM_SMALL_MIMIC].mvflags & G_GONE)
430 && (mvitals[PM_LARGE_MIMIC].mvflags & G_GONE)
431 && (mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) {
432 /* make a mimic instead */
433 levl[x][y].doormask = D_NODOOR;
434 mtmp = makemon(mkclass(S_MIMIC, 0), x, y, NO_MM_FLAGS);
441 if (shdoor || !rn2(5))
442 levl[x][y].doormask = D_LOCKED;
444 levl[x][y].doormask = D_CLOSED;
446 if (!shdoor && level_difficulty() >= 4 && !rn2(20))
447 levl[x][y].doormask |= D_TRAPPED;
450 add_door(x, y, aroom);
454 place_niche(aroom, dy, xx, yy)
455 register struct mkroom *aroom;
462 finddpos(&dd, aroom->lx, aroom->hy + 1, aroom->hx, aroom->hy + 1);
465 finddpos(&dd, aroom->lx, aroom->ly - 1, aroom->hx, aroom->ly - 1);
469 return (boolean) ((isok(*xx, *yy + *dy)
470 && levl[*xx][*yy + *dy].typ == STONE)
471 && (isok(*xx, *yy - *dy)
472 && !IS_POOL(levl[*xx][*yy - *dy].typ)
473 && !IS_FURNITURE(levl[*xx][*yy - *dy].typ)));
476 /* there should be one of these per trap, in the same order as trap.h */
477 static NEARDATA const char *trap_engravings[TRAPNUM] = {
478 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
479 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
480 (char *) 0, (char *) 0, (char *) 0, (char *) 0,
481 /* 14..16: trap door, teleport, level-teleport */
483 "Vlad was here", "ad aerarium", "ad aerarium", (char *) 0, (char *) 0,
485 "
\83\94\83\89\83h
\82Í
\82±
\82±
\82É
\82¢
\82é", "ad aerarium", "ad aerarium", (char *) 0, (char *) 0,
486 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
493 register struct mkroom *aroom;
499 if (doorindex < DOORMAX) {
501 aroom = &rooms[rn2(nroom)];
502 if (aroom->rtype != OROOM)
503 continue; /* not an ordinary room */
504 if (aroom->doorct == 1 && rn2(5))
506 if (!place_niche(aroom, &dy, &xx, &yy))
509 rm = &levl[xx][yy + dy];
510 if (trap_type || !rn2(4)) {
513 if ((trap_type == HOLE || trap_type == TRAPDOOR)
514 && !Can_fall_thru(&u.uz))
515 trap_type = ROCKTRAP;
516 ttmp = maketrap(xx, yy + dy, trap_type);
518 if (trap_type != ROCKTRAP)
520 if (trap_engravings[trap_type]) {
521 make_engr_at(xx, yy - dy,
522 trap_engravings[trap_type], 0L,
524 wipe_engr_at(xx, yy - dy, 5,
525 FALSE); /* age it a little */
529 dosdoor(xx, yy, aroom, SDOOR);
533 dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
535 /* inaccessible niches occasionally have iron bars */
536 if (!rn2(5) && IS_WALL(levl[xx][yy].typ)) {
537 levl[xx][yy].typ = IRONBARS;
539 (void) mkcorpstat(CORPSE, (struct monst *) 0,
540 mkclass(S_HUMAN, 0), xx,
543 if (!level.flags.noteleport)
544 (void) mksobj_at(SCR_TELEPORTATION, xx, yy + dy, TRUE,
547 (void) mkobj_at(0, xx, yy + dy, TRUE);
558 int ct = rnd((nroom >> 1) + 1), dep = depth(&u.uz);
559 boolean ltptr = (!level.flags.noteleport && dep > 15),
560 vamp = (dep > 5 && dep < 25);
563 if (ltptr && !rn2(6)) {
565 makeniche(LEVEL_TELEP);
566 } else if (vamp && !rn2(6)) {
577 makeniche(TELEP_TRAP);
580 /* clear out various globals that keep information on the current level.
581 * some of this is only necessary for some types of levels (maze, normal,
582 * special) but it's easier to put it all in one place than make sure
583 * each type initializes what it needs to separately.
586 clear_level_structures()
588 static struct rm zerorm = { cmap_to_glyph(S_stone),
589 0, 0, 0, 0, 0, 0, 0, 0, 0 };
591 register struct rm *lev;
593 for (x = 0; x < COLNO; x++) {
595 for (y = 0; y < ROWNO; y++) {
598 * These used to be '#if MICROPORT_BUG',
599 * with use of memset(0) for '#if !MICROPORT_BUG' below,
600 * but memset is not appropriate for initializing pointers,
601 * so do these level.objects[][] and level.monsters[][]
602 * initializations unconditionally.
604 level.objects[x][y] = (struct obj *) 0;
605 level.monsters[x][y] = (struct monst *) 0;
608 level.objlist = (struct obj *) 0;
609 level.buriedobjlist = (struct obj *) 0;
610 level.monlist = (struct monst *) 0;
611 level.damagelist = (struct damage *) 0;
612 level.bonesinfo = (struct cemetery *) 0;
614 level.flags.nfountains = 0;
615 level.flags.nsinks = 0;
616 level.flags.has_shop = 0;
617 level.flags.has_vault = 0;
618 level.flags.has_zoo = 0;
619 level.flags.has_court = 0;
620 level.flags.has_morgue = level.flags.graveyard = 0;
621 level.flags.has_beehive = 0;
622 level.flags.has_barracks = 0;
623 level.flags.has_temple = 0;
624 level.flags.has_swamp = 0;
625 level.flags.noteleport = 0;
626 level.flags.hardfloor = 0;
627 level.flags.nommap = 0;
628 level.flags.hero_memory = 1;
629 level.flags.shortsighted = 0;
630 level.flags.sokoban_rules = 0;
631 level.flags.is_maze_lev = 0;
632 level.flags.is_cavernous_lev = 0;
633 level.flags.arboreal = 0;
634 level.flags.wizard_bones = 0;
635 level.flags.corrmaze = 0;
644 xdnstair = ydnstair = xupstair = yupstair = 0;
645 sstairs.sx = sstairs.sy = 0;
646 xdnladder = ydnladder = xupladder = yupladder = 0;
654 register struct mkroom *croom, *troom;
657 struct monst *tmonst; /* always put a web with a spider */
661 if (wiz1_level.dlevel == 0)
663 oinit(); /* assign level dependent obj probabilities */
664 clear_level_structures();
667 register s_level *slev = Is_special(&u.uz);
669 /* check for special levels */
670 if (slev && !Is_rogue_level(&u.uz)) {
671 makemaz(slev->proto);
673 } else if (dungeons[u.uz.dnum].proto[0]) {
676 } else if (In_mines(&u.uz)) {
679 } else if (In_quest(&u.uz)) {
683 Sprintf(fillname, "%s-loca", urole.filecode);
684 loc_lev = find_level(fillname);
686 Sprintf(fillname, "%s-fil", urole.filecode);
688 (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
691 } else if (In_hell(&u.uz)
692 || (rn2(5) && u.uz.dnum == medusa_level.dnum
693 && depth(&u.uz) > depth(&medusa_level))) {
699 /* otherwise, fall through - it's a "regular" level. */
701 if (Is_rogue_level(&u.uz)) {
708 /* construct stairs (up and down in different rooms if possible) */
709 croom = &rooms[rn2(nroom)];
710 if (!Is_botlevel(&u.uz))
711 mkstairs(somex(croom), somey(croom), 0, croom); /* down */
714 croom = &rooms[rn2(nroom - 1)];
719 if (u.uz.dlevel != 1) {
724 } while (occupied(sx, sy));
725 mkstairs(sx, sy, 1, croom); /* up */
728 branchp = Is_branchlev(&u.uz); /* possible dungeon branch */
729 room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed
730 to allow a random special room */
731 if (Is_rogue_level(&u.uz))
736 /* make a secret treasure vault, not connected to the rest */
739 debugpline0("trying to make a vault...");
742 if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) {
744 add_room(vault_x, vault_y, vault_x + w, vault_y + h, TRUE, VAULT,
746 level.flags.has_vault = 1;
748 fill_room(&rooms[nroom - 1], FALSE);
749 mk_knox_portal(vault_x + w, vault_y + h);
750 if (!level.flags.noteleport && !rn2(3))
752 } else if (rnd_rect() && create_vault()) {
753 vault_x = rooms[nroom].lx;
754 vault_y = rooms[nroom].ly;
755 if (check_room(&vault_x, &w, &vault_y, &h, TRUE))
758 rooms[nroom].hx = -1;
763 register int u_depth = depth(&u.uz);
765 if (wizard && nh_getenv("SHOPTYPE"))
767 else if (u_depth > 1 && u_depth < depth(&medusa_level)
768 && nroom >= room_threshold && rn2(u_depth) < 3)
770 else if (u_depth > 4 && !rn2(6))
772 else if (u_depth > 5 && !rn2(8)
773 && !(mvitals[PM_LEPRECHAUN].mvflags & G_GONE))
775 else if (u_depth > 6 && !rn2(7))
777 else if (u_depth > 8 && !rn2(5))
779 else if (u_depth > 9 && !rn2(5)
780 && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
782 else if (u_depth > 11 && !rn2(6))
784 else if (u_depth > 12 && !rn2(8) && antholemon())
786 else if (u_depth > 14 && !rn2(4)
787 && !(mvitals[PM_SOLDIER].mvflags & G_GONE))
789 else if (u_depth > 15 && !rn2(6))
791 else if (u_depth > 16 && !rn2(8)
792 && !(mvitals[PM_COCKATRICE].mvflags & G_GONE))
797 /* Place multi-dungeon branch. */
798 place_branch(branchp, 0, 0);
800 /* for each room: put things inside */
801 for (croom = rooms; croom->hx > 0; croom++) {
802 if (croom->rtype != OROOM)
805 /* put a sleeping monster inside */
806 /* Note: monster may be on the stairs. This cannot be
807 avoided: maybe the player fell through a trap door
808 while a monster was on the stairs. Conclusion:
809 we have to check for monsters on the stairs anyway. */
811 if (u.uhave.amulet || !rn2(3)) {
814 tmonst = makemon((struct permonst *) 0, x, y, NO_MM_FLAGS);
815 if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]
817 (void) maketrap(x, y, WEB);
819 /* put traps and mimics inside */
820 x = 8 - (level_difficulty() / 6);
824 mktrap(0, 0, croom, (coord *) 0);
826 (void) mkgold(0L, somex(croom), somey(croom));
827 if (Is_rogue_level(&u.uz))
835 x = 80 - (depth(&u.uz) * 2);
841 /* put statues inside */
843 (void) mkcorpstat(STATUE, (struct monst *) 0,
844 (struct permonst *) 0, somex(croom),
845 somey(croom), CORPSTAT_INIT);
846 /* put box/chest inside;
847 * 40% chance for at least 1 box, regardless of number
848 * of rooms; about 5 - 7.5% for 2 boxes, least likely
849 * when few rooms; chance for 3 or more is negligible.
851 if (!rn2(nroom * 5 / 2))
852 (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, somex(croom),
853 somey(croom), TRUE, FALSE);
855 /* maybe make some graffiti */
856 if (!rn2(27 + 3 * abs(depth(&u.uz)))) {
858 const char *mesg = random_engraving(buf);
863 } while (levl[x][y].typ != ROOM && !rn2(40));
864 if (!(IS_POOL(levl[x][y].typ)
865 || IS_FURNITURE(levl[x][y].typ)))
866 make_engr_at(x, y, mesg, 0L, MARK);
872 (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
876 impossible("tryct overflow4");
879 (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
886 * Place deposits of minerals (gold and misc gems) in the stone
887 * surrounding the rooms on the map.
888 * Also place kelp in water.
889 * mineralize(-1, -1, -1, -1, FALSE); => "default" behaviour
892 mineralize(kelp_pool, kelp_moat, goldprob, gemprob, skip_lvl_checks)
893 int kelp_pool, kelp_moat, goldprob, gemprob;
894 boolean skip_lvl_checks;
905 /* Place kelp, except on the plane of water */
906 if (!skip_lvl_checks && In_endgame(&u.uz))
908 for (x = 2; x < (COLNO - 2); x++)
909 for (y = 1; y < (ROWNO - 1); y++)
910 if ((kelp_pool && levl[x][y].typ == POOL && !rn2(kelp_pool))
911 || (kelp_moat && levl[x][y].typ == MOAT && !rn2(kelp_moat)))
912 (void) mksobj_at(KELP_FROND, x, y, TRUE, FALSE);
914 /* determine if it is even allowed;
915 almost all special levels are excluded */
917 && (In_hell(&u.uz) || In_V_tower(&u.uz) || Is_rogue_level(&u.uz)
918 || level.flags.arboreal
919 || ((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz)
920 && (!In_mines(&u.uz) || sp->flags.town))))
923 /* basic level-related probabilities */
925 goldprob = 20 + depth(&u.uz) / 3;
927 gemprob = goldprob / 4;
929 /* mines have ***MORE*** goodies - otherwise why mine? */
930 if (!skip_lvl_checks) {
931 if (In_mines(&u.uz)) {
934 } else if (In_quest(&u.uz)) {
941 * Seed rock areas with gold and/or gems.
942 * We use fairly low level object handling to avoid unnecessary
943 * overhead from placing things in the floor chain prior to burial.
945 for (x = 2; x < (COLNO - 2); x++)
946 for (y = 1; y < (ROWNO - 1); y++)
947 if (levl[x][y + 1].typ != STONE) { /* <x,y> spot not eligible */
948 y += 2; /* next two spots aren't eligible either */
949 } else if (levl[x][y].typ != STONE) { /* this spot not eligible */
950 y += 1; /* next spot isn't eligible either */
951 } else if (!(levl[x][y].wall_info & W_NONDIGGABLE)
952 && levl[x][y - 1].typ == STONE
953 && levl[x + 1][y - 1].typ == STONE
954 && levl[x - 1][y - 1].typ == STONE
955 && levl[x + 1][y].typ == STONE
956 && levl[x - 1][y].typ == STONE
957 && levl[x + 1][y + 1].typ == STONE
958 && levl[x - 1][y + 1].typ == STONE) {
959 if (rn2(1000) < goldprob) {
960 if ((otmp = mksobj(GOLD_PIECE, FALSE, FALSE)) != 0) {
961 otmp->ox = x, otmp->oy = y;
962 otmp->quan = 1L + rnd(goldprob * 3);
963 otmp->owt = weight(otmp);
967 place_object(otmp, x, y);
970 if (rn2(1000) < gemprob) {
971 for (cnt = rnd(2 + dunlev(&u.uz) / 3); cnt > 0; cnt--)
972 if ((otmp = mkobj(GEM_CLASS, FALSE)) != 0) {
973 if (otmp->otyp == ROCK) {
974 dealloc_obj(otmp); /* discard it */
976 otmp->ox = x, otmp->oy = y;
980 place_object(otmp, x, y);
990 struct mkroom *croom;
1000 mineralize(-1, -1, -1, -1, FALSE);
1002 /* has_morgue gets cleared once morgue is entered; graveyard stays
1003 set (graveyard might already be set even when has_morgue is clear
1004 [see fixup_special()], so don't update it unconditionally) */
1005 if (level.flags.has_morgue)
1006 level.flags.graveyard = 1;
1007 if (!level.flags.is_maze_lev) {
1008 for (croom = &rooms[0]; croom != &rooms[nroom]; croom++)
1009 #ifdef SPECIALIZATION
1010 topologize(croom, FALSE);
1016 /* for many room types, rooms[].rtype is zeroed once the room has been
1017 entered; rooms[].orig_rtype always retains original rtype value */
1018 for (ridx = 0; ridx < SIZE(rooms); ridx++)
1019 rooms[ridx].orig_rtype = rooms[ridx].rtype;
1023 #ifdef SPECIALIZATION
1024 topologize(croom, do_ordinary)
1025 struct mkroom *croom;
1026 boolean do_ordinary;
1029 struct mkroom *croom;
1032 register int x, y, roomno = (int) ((croom - rooms) + ROOMOFFSET);
1033 int lowx = croom->lx, lowy = croom->ly;
1034 int hix = croom->hx, hiy = croom->hy;
1035 #ifdef SPECIALIZATION
1036 schar rtype = croom->rtype;
1038 int subindex, nsubrooms = croom->nsubrooms;
1040 /* skip the room if already done; i.e. a shop handled out of order */
1041 /* also skip if this is non-rectangular (it _must_ be done already) */
1042 if ((int) levl[lowx][lowy].roomno == roomno || croom->irregular)
1044 #ifdef SPECIALIZATION
1045 if (Is_rogue_level(&u.uz))
1046 do_ordinary = TRUE; /* vision routine helper */
1047 if ((rtype != OROOM) || do_ordinary)
1050 /* do innards first */
1051 for (x = lowx; x <= hix; x++)
1052 for (y = lowy; y <= hiy; y++)
1053 #ifdef SPECIALIZATION
1055 levl[x][y].roomno = NO_ROOM;
1058 levl[x][y].roomno = roomno;
1059 /* top and bottom edges */
1060 for (x = lowx - 1; x <= hix + 1; x++)
1061 for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
1062 levl[x][y].edge = 1;
1063 if (levl[x][y].roomno)
1064 levl[x][y].roomno = SHARED;
1066 levl[x][y].roomno = roomno;
1069 for (x = lowx - 1; x <= hix + 1; x += (hix - lowx + 2))
1070 for (y = lowy; y <= hiy; y++) {
1071 levl[x][y].edge = 1;
1072 if (levl[x][y].roomno)
1073 levl[x][y].roomno = SHARED;
1075 levl[x][y].roomno = roomno;
1079 for (subindex = 0; subindex < nsubrooms; subindex++)
1080 #ifdef SPECIALIZATION
1081 topologize(croom->sbrooms[subindex], (boolean) (rtype != OROOM));
1083 topologize(croom->sbrooms[subindex]);
1087 /* Find an unused room for a branch location. */
1088 STATIC_OVL struct mkroom *
1089 find_branch_room(mp)
1092 struct mkroom *croom = 0;
1095 mazexy(mp); /* already verifies location */
1097 /* not perfect - there may be only one stairway */
1102 croom = &rooms[rn2(nroom)];
1103 while ((croom == dnstairs_room || croom == upstairs_room
1104 || croom->rtype != OROOM) && (++tryct < 100));
1106 croom = &rooms[rn2(nroom)];
1109 if (!somexy(croom, mp))
1110 impossible("Can't place branch!");
1111 } while (occupied(mp->x, mp->y)
1112 || (levl[mp->x][mp->y].typ != CORR
1113 && levl[mp->x][mp->y].typ != ROOM));
1118 /* Find the room for (x,y). Return null if not in a room. */
1119 STATIC_OVL struct mkroom *
1124 struct mkroom *curr;
1126 for (curr = rooms, i = 0; i < nroom; curr++, i++)
1127 if (inside_room(curr, x, y))
1130 return (struct mkroom *) 0;
1133 /* If given a branch, randomly place a special stair or portal. */
1135 place_branch(br, x, y)
1136 branch *br; /* branch to place */
1137 xchar x, y; /* location */
1141 boolean make_stairs;
1142 struct mkroom *br_room;
1145 * Return immediately if there is no branch to make or we have
1146 * already made one. This routine can be called twice when
1147 * a special level is loaded that specifies an SSTAIR location
1148 * as a favored spot for a branch.
1150 if (!br || made_branch)
1153 if (!x) { /* find random coordinates for branch */
1154 br_room = find_branch_room(&m);
1158 br_room = pos_to_room(x, y);
1161 if (on_level(&br->end1, &u.uz)) {
1163 make_stairs = br->type != BR_NO_END1;
1167 make_stairs = br->type != BR_NO_END2;
1171 if (br->type == BR_PORTAL) {
1172 mkportal(x, y, dest->dnum, dest->dlevel);
1173 } else if (make_stairs) {
1177 (char) on_level(&br->end1, &u.uz) ? br->end1_up : !br->end1_up;
1178 assign_level(&sstairs.tolev, dest);
1179 sstairs_room = br_room;
1181 levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN;
1182 levl[x][y].typ = STAIRS;
1185 * Set made_branch to TRUE even if we didn't make a stairwell (i.e.
1186 * make_stairs is false) since there is currently only one branch
1187 * per level, if we failed once, we're going to fail again on the
1195 register xchar x, y;
1199 if (isok(x + 1, y)) {
1200 typ = levl[x + 1][y].typ;
1201 if (IS_DOOR(typ) || typ == SDOOR)
1204 if (isok(x - 1, y)) {
1205 typ = levl[x - 1][y].typ;
1206 if (IS_DOOR(typ) || typ == SDOOR)
1209 if (isok(x, y + 1)) {
1210 typ = levl[x][y + 1].typ;
1211 if (IS_DOOR(typ) || typ == SDOOR)
1214 if (isok(x, y - 1)) {
1215 typ = levl[x][y - 1].typ;
1216 if (IS_DOOR(typ) || typ == SDOOR)
1222 /* see whether it is allowable to create a door at [x,y] */
1227 boolean near_door = bydoor(x, y);
1229 return ((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL)
1230 && doorindex < DOORMAX && !near_door);
1236 struct mkroom *aroom;
1238 if (doorindex >= DOORMAX) {
1239 impossible("DOORMAX exceeded?");
1243 dosdoor(x, y, aroom, rn2(8) ? DOOR : SDOOR);
1248 register xchar x, y;
1250 return (boolean) (t_at(x, y) || IS_FURNITURE(levl[x][y].typ)
1251 || is_lava(x, y) || is_pool(x, y)
1252 || invocation_pos(x, y));
1255 /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
1256 /* if tm != null, make trap at that location */
1258 mktrap(num, mazeflag, croom, tm)
1260 struct mkroom *croom;
1266 /* no traps in pools */
1267 if (tm && is_pool(tm->x, tm->y))
1270 if (num > 0 && num < TRAPNUM) {
1272 } else if (Is_rogue_level(&u.uz)) {
1290 kind = SLP_GAS_TRAP;
1296 } else if (Inhell && !rn2(5)) {
1297 /* bias the frequency of fire traps in Gehennom */
1300 unsigned lvl = level_difficulty();
1303 kind = rnd(TRAPNUM - 1);
1304 /* reject "too hard" traps */
1307 case VIBRATING_SQUARE:
1310 case ROLLING_BOULDER_TRAP:
1316 if (lvl < 5 || level.flags.noteleport)
1341 if (level.flags.noteleport)
1345 /* make these much less often than other traps */
1350 } while (kind == NO_TRAP);
1353 if ((kind == TRAPDOOR || kind == HOLE) && !Can_fall_thru(&u.uz))
1359 register int tryct = 0;
1360 boolean avoid_boulder = (kind == PIT || kind == SPIKED_PIT
1361 || kind == TRAPDOOR || kind == HOLE);
1368 else if (!somexy(croom, &m))
1370 } while (occupied(m.x, m.y)
1371 || (avoid_boulder && sobj_at(BOULDER, m.x, m.y)));
1374 (void) maketrap(m.x, m.y, kind);
1376 (void) makemon(&mons[PM_GIANT_SPIDER], m.x, m.y, NO_MM_FLAGS);
1380 mkstairs(x, y, up, croom)
1383 struct mkroom *croom;
1386 impossible("mkstairs: bogus stair attempt at <%d,%d>", x, y);
1391 * We can't make a regular stair off an end of the dungeon. This
1392 * attempt can happen when a special level is placed at an end and
1393 * has an up or down stair specified in its description file.
1395 if ((dunlev(&u.uz) == 1 && up)
1396 || (dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up))
1402 upstairs_room = croom;
1406 dnstairs_room = croom;
1409 levl[x][y].typ = STAIRS;
1410 levl[x][y].ladder = up ? LA_UP : LA_DOWN;
1414 mkfount(mazeflag, croom)
1416 struct mkroom *croom;
1419 register int tryct = 0;
1426 else if (!somexy(croom, &m))
1428 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1430 /* Put a fountain at m.x, m.y */
1431 levl[m.x][m.y].typ = FOUNTAIN;
1432 /* Is it a "blessed" fountain? (affects drinking from fountain) */
1434 levl[m.x][m.y].blessedftn = 1;
1436 level.flags.nfountains++;
1441 struct mkroom *croom;
1444 register int tryct = 0;
1449 if (!somexy(croom, &m))
1451 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1453 /* Put a sink at m.x, m.y */
1454 levl[m.x][m.y].typ = SINK;
1456 level.flags.nsinks++;
1461 struct mkroom *croom;
1464 register int tryct = 0;
1467 if (croom->rtype != OROOM)
1473 if (!somexy(croom, &m))
1475 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1477 /* Put an altar at m.x, m.y */
1478 levl[m.x][m.y].typ = ALTAR;
1480 /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
1481 al = rn2((int) A_LAWFUL + 2) - 1;
1482 levl[m.x][m.y].altarmask = Align2amask(al);
1487 struct mkroom *croom;
1490 register int tryct = 0;
1491 register struct obj *otmp;
1492 boolean dobell = !rn2(10);
1494 if (croom->rtype != OROOM)
1500 if (!somexy(croom, &m))
1502 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1504 /* Put a grave at m.x, m.y */
1506 make_grave(m.x, m.y, dobell ? "Saved by the bell!" : (char *) 0);
1508 make_grave(m.x, m.y, dobell ? "
\83x
\83\8b\82É
\8b~
\82í
\82ê
\82½
\81I" : (char *) 0);
1510 /* Possibly fill it with objects */
1512 (void) mkgold(0L, m.x, m.y);
1513 for (tryct = rn2(5); tryct; tryct--) {
1514 otmp = mkobj(RANDOM_CLASS, TRUE);
1520 add_to_buried(otmp);
1523 /* Leave a bell, in case we accidentally buried someone alive */
1525 (void) mksobj_at(BELL, m.x, m.y, TRUE, FALSE);
1529 /* maze levels have slightly different constraints from normal levels */
1530 #define x_maze_min 2
1531 #define y_maze_min 2
1534 * Major level transmutation: add a set of stairs (to the Sanctum) after
1535 * an earthquake that leaves behind a a new topology, centered at inv_pos.
1536 * Assumes there are no rooms within the invocation area and that inv_pos
1537 * is not too close to the edge of the map. Also assume the hero can see,
1538 * which is guaranteed for normal play due to the fact that sight is needed
1539 * to read the Book of the Dead.
1545 xchar xmin = inv_pos.x, xmax = inv_pos.x;
1546 xchar ymin = inv_pos.y, ymax = inv_pos.y;
1550 pline_The("floor shakes violently under you!");
1552 pline("
\82 \82È
\82½
\82Ì
\89º
\82Ì
\8f°
\82ª
\93Ë
\91R
\97h
\82ê
\82½
\81I");
1554 pline_The("walls around you begin to bend and crumble!");
1556 pline("
\82»
\82µ
\82Ä
\82Ü
\82í
\82è
\82Ì
\95Ç
\82ª
\82Ë
\82¶
\82ê
\81C
\8dÓ
\82¯
\82½
\81I");
1557 display_nhwindow(WIN_MESSAGE, TRUE);
1559 /* any trap hero is stuck in will be going away now */
1562 if (u.utraptype == TT_BURIEDBALL)
1563 buried_ball_to_punishment();
1565 mkinvpos(xmin, ymin, 0); /* middle, before placing stairs */
1567 for (dist = 1; dist < 7; dist++) {
1571 /* top and bottom */
1572 if (dist != 3) { /* the area is wider that it is high */
1575 for (i = xmin + 1; i < xmax; i++) {
1576 mkinvpos(i, ymin, dist);
1577 mkinvpos(i, ymax, dist);
1581 /* left and right */
1582 for (i = ymin; i <= ymax; i++) {
1583 mkinvpos(xmin, i, dist);
1584 mkinvpos(xmax, i, dist);
1587 flush_screen(1); /* make sure the new glyphs shows up */
1592 You("are standing at the top of a stairwell leading down!");
1594 You("
\89º
\82É
\91±
\82
\90\81\82«
\94²
\82¯
\8aK
\92i
\82Ì
\8fã
\82É
\97§
\82Á
\82Ä
\82¢
\82é
\81I");
1595 mkstairs(u.ux, u.uy, 0, (struct mkroom *) 0); /* down */
1597 vision_full_recalc = 1; /* everything changed */
1600 /* Change level topology. Boulders in the vicinity are eliminated.
1601 * Temporarily overrides vision in the name of a nice effect.
1604 mkinvpos(x, y, dist)
1611 register struct rm *lev = &levl[x][y];
1613 /* clip at existing map borders if necessary */
1614 if (!within_bounded_area(x, y, x_maze_min + 1, y_maze_min + 1,
1615 x_maze_max - 1, y_maze_max - 1)) {
1616 /* only outermost 2 columns and/or rows may be truncated due to edge
1619 panic("mkinvpos: <%d,%d> (%d) off map edge!", x, y, dist);
1624 if ((ttmp = t_at(x, y)) != 0)
1627 /* clear boulders; leave some rocks for non-{moat|trap} locations */
1628 make_rocks = (dist != 1 && dist != 4 && dist != 5) ? TRUE : FALSE;
1629 while ((otmp = sobj_at(BOULDER, x, y)) != 0) {
1631 fracture_rock(otmp);
1632 make_rocks = FALSE; /* don't bother with more rocks */
1634 obj_extract_self(otmp);
1635 obfree(otmp, (struct obj *) 0);
1638 unblock_point(x, y); /* make sure vision knows this location is open */
1640 /* fake out saved state */
1646 lev->horizontal = FALSE;
1647 /* short-circuit vision recalc */
1648 viz_array[y][x] = (dist < 6) ? (IN_SIGHT | COULD_SEE) : COULD_SEE;
1651 case 1: /* fire traps */
1655 ttmp = maketrap(x, y, FIRE_TRAP);
1659 case 0: /* lit room locations */
1662 case 6: /* unlit room locations */
1665 case 4: /* pools (aka a wide moat) */
1671 impossible("mkinvpos called with dist %d", dist);
1675 /* display new value of position; could have a monster/object on it */
1680 * The portal to Ludios is special. The entrance can only occur within a
1681 * vault in the main dungeon at a depth greater than 10. The Ludios branch
1682 * structure reflects this by having a bogus "source" dungeon: the value
1683 * of n_dgns (thus, Is_branchlev() will never find it).
1685 * Ludios will remain isolated until the branch is corrected by this function.
1688 mk_knox_portal(x, y)
1691 extern int n_dgns; /* from dungeon.c */
1697 br = dungeon_branch("Fort Ludios");
1699 br = dungeon_branch("
\83\8d\81[
\83f
\83B
\83I
\83X
\8dÔ");
1700 if (on_level(&knox_level, &br->end1)) {
1703 /* disallow Knox branch on a level with one branch already */
1704 if (Is_branchlev(&u.uz))
1709 /* Already set or 2/3 chance of deferring until a later level. */
1710 if (source->dnum < n_dgns || (rn2(3) && !wizard))
1713 if (!(u.uz.dnum == oracle_level.dnum /* in main dungeon */
1715 && !at_dgn_entrance("The Quest") /* but not Quest's entry */
1717 && !at_dgn_entrance("
\83N
\83G
\83X
\83g") /* but not Quest's entry */
1719 && (u_depth = depth(&u.uz)) > 10 /* beneath 10 */
1720 && u_depth < depth(&medusa_level))) /* and above Medusa */
1723 /* Adjust source to be current level and re-insert branch. */
1725 insert_branch(br, TRUE);
1727 debugpline0("Made knox portal.");
1728 place_branch(br, x, y);