1 /* NetHack 3.6 mklev.c $NHDT-Date: 1511681724 2017/11/26 07:35:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.47 $ */
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-2018 */
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 qsort((genericptr_t) rooms, (unsigned) nroom, sizeof(struct mkroom),
110 qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), do_comp);
115 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room)
116 register struct mkroom *croom;
118 register int hix, hiy;
127 /* locations might bump level edges in wall-less rooms */
128 /* add/subtract 1 to allow for edge locations */
133 if (hix >= COLNO - 1)
135 if (hiy >= ROWNO - 1)
139 for (x = lowx - 1; x <= hix + 1; x++) {
140 lev = &levl[x][max(lowy - 1, 0)];
141 for (y = lowy - 1; y <= hiy + 1; y++)
152 croom->rtype = rtype;
154 /* if we're not making a vault, doorindex will still be 0
155 * if we are, we'll have problems adding niches to the previous room
156 * unless fdoor is at least doorindex
158 croom->fdoor = doorindex;
159 croom->irregular = FALSE;
161 croom->nsubrooms = 0;
162 croom->sbrooms[0] = (struct mkroom *) 0;
164 for (x = lowx - 1; x <= hix + 1; x++)
165 for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
166 levl[x][y].typ = HWALL;
167 levl[x][y].horizontal = 1; /* For open/secret doors. */
169 for (x = lowx - 1; x <= hix + 1; x += (hix - lowx + 2))
170 for (y = lowy; y <= hiy; y++) {
171 levl[x][y].typ = VWALL;
172 levl[x][y].horizontal = 0; /* For open/secret doors. */
174 for (x = lowx; x <= hix; x++) {
175 lev = &levl[x][lowy];
176 for (y = lowy; y <= hiy; y++)
180 levl[lowx - 1][lowy - 1].typ = TLCORNER;
181 levl[hix + 1][lowy - 1].typ = TRCORNER;
182 levl[lowx - 1][hiy + 1].typ = BLCORNER;
183 levl[hix + 1][hiy + 1].typ = BRCORNER;
184 } else { /* a subroom */
185 wallification(lowx - 1, lowy - 1, hix + 1, hiy + 1);
191 add_room(lowx, lowy, hix, hiy, lit, rtype, special)
192 int lowx, lowy, hix, hiy;
197 register struct mkroom *croom;
199 croom = &rooms[nroom];
200 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
208 add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special)
209 struct mkroom *proom;
210 int lowx, lowy, hix, hiy;
215 register struct mkroom *croom;
217 croom = &subrooms[nsubroom];
218 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
220 proom->sbrooms[proom->nsubrooms++] = croom;
229 boolean tried_vault = FALSE;
231 /* make rooms until satisfied */
232 /* rnd_rect() will returns 0 if no more rects are available... */
233 while (nroom < MAXNROFROOMS && rnd_rect()) {
234 if (nroom >= (MAXNROFROOMS / 6) && rn2(2) && !tried_vault) {
236 if (create_vault()) {
237 vault_x = rooms[nroom].lx;
238 vault_y = rooms[nroom].ly;
239 rooms[nroom].hx = -1;
241 } else if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
252 coord cc, tt, org, dest;
253 register xchar tx, ty, xx, yy;
254 register struct mkroom *croom, *troom;
260 /* find positions cc and tt for doors in croom and troom
261 and direction for a corridor between them */
263 if (troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX)
265 if (troom->lx > croom->hx) {
270 finddpos(&cc, xx, croom->ly, xx, croom->hy);
271 finddpos(&tt, tx, troom->ly, tx, troom->hy);
272 } else if (troom->hy < croom->ly) {
276 finddpos(&cc, croom->lx, yy, croom->hx, yy);
278 finddpos(&tt, troom->lx, ty, troom->hx, ty);
279 } else if (troom->hx < croom->lx) {
284 finddpos(&cc, xx, croom->ly, xx, croom->hy);
285 finddpos(&tt, tx, troom->ly, tx, troom->hy);
291 finddpos(&cc, croom->lx, yy, croom->hx, yy);
292 finddpos(&tt, troom->lx, ty, troom->hx, ty);
298 if (nxcor && levl[xx + dx][yy + dy].typ)
300 if (okdoor(xx, yy) || !nxcor)
301 dodoor(xx, yy, croom);
308 if (!dig_corridor(&org, &dest, nxcor, level.flags.arboreal ? ROOM : CORR,
312 /* we succeeded in digging the corridor */
313 if (okdoor(tt.x, tt.y) || !nxcor)
314 dodoor(tt.x, tt.y, troom);
316 if (smeq[a] < smeq[b])
328 for (a = 0; a < nroom - 1; a++) {
329 join(a, a + 1, FALSE);
331 break; /* allow some randomness */
333 for (a = 0; a < nroom - 2; a++)
334 if (smeq[a] != smeq[a + 2])
335 join(a, a + 2, FALSE);
336 for (a = 0; any && a < nroom; a++) {
338 for (b = 0; b < nroom; b++)
339 if (smeq[a] != smeq[b]) {
345 for (i = rn2(nroom) + 4; i; i--) {
355 add_door(x, y, aroom)
357 register struct mkroom *aroom;
359 register struct mkroom *broom;
363 if (aroom->doorct == 0)
364 aroom->fdoor = doorindex;
368 for (tmp = doorindex; tmp > aroom->fdoor; tmp--)
369 doors[tmp] = doors[tmp - 1];
371 for (i = 0; i < nroom; i++) {
373 if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
376 for (i = 0; i < nsubroom; i++) {
377 broom = &subrooms[i];
378 if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
383 doors[aroom->fdoor].x = x;
384 doors[aroom->fdoor].y = y;
388 dosdoor(x, y, aroom, type)
390 struct mkroom *aroom;
393 boolean shdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE;
395 if (!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */
397 levl[x][y].typ = type;
399 if (!rn2(3)) { /* is it a locked door, closed, or a doorway? */
401 levl[x][y].doormask = D_ISOPEN;
403 levl[x][y].doormask = D_LOCKED;
405 levl[x][y].doormask = D_CLOSED;
407 if (levl[x][y].doormask != D_ISOPEN && !shdoor
408 && level_difficulty() >= 5 && !rn2(25))
409 levl[x][y].doormask |= D_TRAPPED;
413 levl[x][y].doormask = D_ISOPEN;
415 levl[x][y].doormask = D_NODOOR;
417 levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
421 /* also done in roguecorr(); doing it here first prevents
422 making mimics in place of trapped doors on rogue level */
423 if (Is_rogue_level(&u.uz))
424 levl[x][y].doormask = D_NODOOR;
426 if (levl[x][y].doormask & D_TRAPPED) {
429 if (level_difficulty() >= 9 && !rn2(5)
430 && !((mvitals[PM_SMALL_MIMIC].mvflags & G_GONE)
431 && (mvitals[PM_LARGE_MIMIC].mvflags & G_GONE)
432 && (mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) {
433 /* make a mimic instead */
434 levl[x][y].doormask = D_NODOOR;
435 mtmp = makemon(mkclass(S_MIMIC, 0), x, y, NO_MM_FLAGS);
442 if (shdoor || !rn2(5))
443 levl[x][y].doormask = D_LOCKED;
445 levl[x][y].doormask = D_CLOSED;
447 if (!shdoor && level_difficulty() >= 4 && !rn2(20))
448 levl[x][y].doormask |= D_TRAPPED;
451 add_door(x, y, aroom);
455 place_niche(aroom, dy, xx, yy)
456 register struct mkroom *aroom;
463 finddpos(&dd, aroom->lx, aroom->hy + 1, aroom->hx, aroom->hy + 1);
466 finddpos(&dd, aroom->lx, aroom->ly - 1, aroom->hx, aroom->ly - 1);
470 return (boolean) ((isok(*xx, *yy + *dy)
471 && levl[*xx][*yy + *dy].typ == STONE)
472 && (isok(*xx, *yy - *dy)
473 && !IS_POOL(levl[*xx][*yy - *dy].typ)
474 && !IS_FURNITURE(levl[*xx][*yy - *dy].typ)));
477 /* there should be one of these per trap, in the same order as trap.h */
478 static NEARDATA const char *trap_engravings[TRAPNUM] = {
479 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
480 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
481 (char *) 0, (char *) 0, (char *) 0, (char *) 0,
482 /* 14..16: trap door, teleport, level-teleport */
484 "Vlad was here", "ad aerarium", "ad aerarium", (char *) 0, (char *) 0,
486 "
\83\94\83\89\83h
\82Í
\82±
\82±
\82É
\82¢
\82é", "ad aerarium", "ad aerarium", (char *) 0, (char *) 0,
487 (char *) 0, (char *) 0, (char *) 0, (char *) 0, (char *) 0,
494 register struct mkroom *aroom;
500 if (doorindex < DOORMAX) {
502 aroom = &rooms[rn2(nroom)];
503 if (aroom->rtype != OROOM)
504 continue; /* not an ordinary room */
505 if (aroom->doorct == 1 && rn2(5))
507 if (!place_niche(aroom, &dy, &xx, &yy))
510 rm = &levl[xx][yy + dy];
511 if (trap_type || !rn2(4)) {
514 if ((trap_type == HOLE || trap_type == TRAPDOOR)
515 && !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 */
740 debugpline0("trying to make a vault...");
743 if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) {
745 add_room(vault_x, vault_y, vault_x + w, vault_y + h, TRUE, VAULT,
747 level.flags.has_vault = 1;
749 fill_room(&rooms[nroom - 1], FALSE);
750 mk_knox_portal(vault_x + w, vault_y + h);
751 if (!level.flags.noteleport && !rn2(3))
753 } else if (rnd_rect() && create_vault()) {
754 vault_x = rooms[nroom].lx;
755 vault_y = rooms[nroom].ly;
756 if (check_room(&vault_x, &w, &vault_y, &h, TRUE))
759 rooms[nroom].hx = -1;
764 register int u_depth = depth(&u.uz);
766 if (wizard && nh_getenv("SHOPTYPE"))
768 else if (u_depth > 1 && u_depth < depth(&medusa_level)
769 && nroom >= room_threshold && rn2(u_depth) < 3)
771 else if (u_depth > 4 && !rn2(6))
773 else if (u_depth > 5 && !rn2(8)
774 && !(mvitals[PM_LEPRECHAUN].mvflags & G_GONE))
776 else if (u_depth > 6 && !rn2(7))
778 else if (u_depth > 8 && !rn2(5))
780 else if (u_depth > 9 && !rn2(5)
781 && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
783 else if (u_depth > 11 && !rn2(6))
785 else if (u_depth > 12 && !rn2(8) && antholemon())
787 else if (u_depth > 14 && !rn2(4)
788 && !(mvitals[PM_SOLDIER].mvflags & G_GONE))
790 else if (u_depth > 15 && !rn2(6))
792 else if (u_depth > 16 && !rn2(8)
793 && !(mvitals[PM_COCKATRICE].mvflags & G_GONE))
798 /* Place multi-dungeon branch. */
799 place_branch(branchp, 0, 0);
801 /* for each room: put things inside */
802 for (croom = rooms; croom->hx > 0; croom++) {
803 if (croom->rtype != OROOM)
806 /* put a sleeping monster inside */
807 /* Note: monster may be on the stairs. This cannot be
808 avoided: maybe the player fell through a trap door
809 while a monster was on the stairs. Conclusion:
810 we have to check for monsters on the stairs anyway. */
812 if (u.uhave.amulet || !rn2(3)) {
815 tmonst = makemon((struct permonst *) 0, x, y, NO_MM_FLAGS);
816 if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]
818 (void) maketrap(x, y, WEB);
820 /* put traps and mimics inside */
821 x = 8 - (level_difficulty() / 6);
825 mktrap(0, 0, croom, (coord *) 0);
827 (void) mkgold(0L, somex(croom), somey(croom));
828 if (Is_rogue_level(&u.uz))
836 x = 80 - (depth(&u.uz) * 2);
842 /* put statues inside */
844 (void) mkcorpstat(STATUE, (struct monst *) 0,
845 (struct permonst *) 0, somex(croom),
846 somey(croom), CORPSTAT_INIT);
847 /* put box/chest inside;
848 * 40% chance for at least 1 box, regardless of number
849 * of rooms; about 5 - 7.5% for 2 boxes, least likely
850 * when few rooms; chance for 3 or more is negligible.
852 if (!rn2(nroom * 5 / 2))
853 (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, somex(croom),
854 somey(croom), TRUE, FALSE);
856 /* maybe make some graffiti */
857 if (!rn2(27 + 3 * abs(depth(&u.uz)))) {
859 const char *mesg = random_engraving(buf);
864 } while (levl[x][y].typ != ROOM && !rn2(40));
865 if (!(IS_POOL(levl[x][y].typ)
866 || IS_FURNITURE(levl[x][y].typ)))
867 make_engr_at(x, y, mesg, 0L, MARK);
873 (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
877 impossible("tryct overflow4");
880 (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
887 * Place deposits of minerals (gold and misc gems) in the stone
888 * surrounding the rooms on the map.
889 * Also place kelp in water.
890 * mineralize(-1, -1, -1, -1, FALSE); => "default" behaviour
893 mineralize(kelp_pool, kelp_moat, goldprob, gemprob, skip_lvl_checks)
894 int kelp_pool, kelp_moat, goldprob, gemprob;
895 boolean skip_lvl_checks;
906 /* Place kelp, except on the plane of water */
907 if (!skip_lvl_checks && In_endgame(&u.uz))
909 for (x = 2; x < (COLNO - 2); x++)
910 for (y = 1; y < (ROWNO - 1); y++)
911 if ((kelp_pool && levl[x][y].typ == POOL && !rn2(kelp_pool))
912 || (kelp_moat && levl[x][y].typ == MOAT && !rn2(kelp_moat)))
913 (void) mksobj_at(KELP_FROND, x, y, TRUE, FALSE);
915 /* determine if it is even allowed;
916 almost all special levels are excluded */
918 && (In_hell(&u.uz) || In_V_tower(&u.uz) || Is_rogue_level(&u.uz)
919 || level.flags.arboreal
920 || ((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz)
921 && (!In_mines(&u.uz) || sp->flags.town))))
924 /* basic level-related probabilities */
926 goldprob = 20 + depth(&u.uz) / 3;
928 gemprob = goldprob / 4;
930 /* mines have ***MORE*** goodies - otherwise why mine? */
931 if (!skip_lvl_checks) {
932 if (In_mines(&u.uz)) {
935 } else if (In_quest(&u.uz)) {
942 * Seed rock areas with gold and/or gems.
943 * We use fairly low level object handling to avoid unnecessary
944 * overhead from placing things in the floor chain prior to burial.
946 for (x = 2; x < (COLNO - 2); x++)
947 for (y = 1; y < (ROWNO - 1); y++)
948 if (levl[x][y + 1].typ != STONE) { /* <x,y> spot not eligible */
949 y += 2; /* next two spots aren't eligible either */
950 } else if (levl[x][y].typ != STONE) { /* this spot not eligible */
951 y += 1; /* next spot isn't eligible either */
952 } else if (!(levl[x][y].wall_info & W_NONDIGGABLE)
953 && levl[x][y - 1].typ == STONE
954 && levl[x + 1][y - 1].typ == STONE
955 && levl[x - 1][y - 1].typ == STONE
956 && levl[x + 1][y].typ == STONE
957 && levl[x - 1][y].typ == STONE
958 && levl[x + 1][y + 1].typ == STONE
959 && levl[x - 1][y + 1].typ == STONE) {
960 if (rn2(1000) < goldprob) {
961 if ((otmp = mksobj(GOLD_PIECE, FALSE, FALSE)) != 0) {
962 otmp->ox = x, otmp->oy = y;
963 otmp->quan = 1L + rnd(goldprob * 3);
964 otmp->owt = weight(otmp);
968 place_object(otmp, x, y);
971 if (rn2(1000) < gemprob) {
972 for (cnt = rnd(2 + dunlev(&u.uz) / 3); cnt > 0; cnt--)
973 if ((otmp = mkobj(GEM_CLASS, FALSE)) != 0) {
974 if (otmp->otyp == ROCK) {
975 dealloc_obj(otmp); /* discard it */
977 otmp->ox = x, otmp->oy = y;
981 place_object(otmp, x, y);
991 struct mkroom *croom;
1001 mineralize(-1, -1, -1, -1, FALSE);
1003 /* has_morgue gets cleared once morgue is entered; graveyard stays
1004 set (graveyard might already be set even when has_morgue is clear
1005 [see fixup_special()], so don't update it unconditionally) */
1006 if (level.flags.has_morgue)
1007 level.flags.graveyard = 1;
1008 if (!level.flags.is_maze_lev) {
1009 for (croom = &rooms[0]; croom != &rooms[nroom]; croom++)
1010 #ifdef SPECIALIZATION
1011 topologize(croom, FALSE);
1017 /* for many room types, rooms[].rtype is zeroed once the room has been
1018 entered; rooms[].orig_rtype always retains original rtype value */
1019 for (ridx = 0; ridx < SIZE(rooms); ridx++)
1020 rooms[ridx].orig_rtype = rooms[ridx].rtype;
1024 #ifdef SPECIALIZATION
1025 topologize(croom, do_ordinary)
1026 struct mkroom *croom;
1027 boolean do_ordinary;
1030 struct mkroom *croom;
1033 register int x, y, roomno = (int) ((croom - rooms) + ROOMOFFSET);
1034 int lowx = croom->lx, lowy = croom->ly;
1035 int hix = croom->hx, hiy = croom->hy;
1036 #ifdef SPECIALIZATION
1037 schar rtype = croom->rtype;
1039 int subindex, nsubrooms = croom->nsubrooms;
1041 /* skip the room if already done; i.e. a shop handled out of order */
1042 /* also skip if this is non-rectangular (it _must_ be done already) */
1043 if ((int) levl[lowx][lowy].roomno == roomno || croom->irregular)
1045 #ifdef SPECIALIZATION
1046 if (Is_rogue_level(&u.uz))
1047 do_ordinary = TRUE; /* vision routine helper */
1048 if ((rtype != OROOM) || do_ordinary)
1051 /* do innards first */
1052 for (x = lowx; x <= hix; x++)
1053 for (y = lowy; y <= hiy; y++)
1054 #ifdef SPECIALIZATION
1056 levl[x][y].roomno = NO_ROOM;
1059 levl[x][y].roomno = roomno;
1060 /* top and bottom edges */
1061 for (x = lowx - 1; x <= hix + 1; x++)
1062 for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) {
1063 levl[x][y].edge = 1;
1064 if (levl[x][y].roomno)
1065 levl[x][y].roomno = SHARED;
1067 levl[x][y].roomno = roomno;
1070 for (x = lowx - 1; x <= hix + 1; x += (hix - lowx + 2))
1071 for (y = lowy; y <= hiy; y++) {
1072 levl[x][y].edge = 1;
1073 if (levl[x][y].roomno)
1074 levl[x][y].roomno = SHARED;
1076 levl[x][y].roomno = roomno;
1080 for (subindex = 0; subindex < nsubrooms; subindex++)
1081 #ifdef SPECIALIZATION
1082 topologize(croom->sbrooms[subindex], (boolean) (rtype != OROOM));
1084 topologize(croom->sbrooms[subindex]);
1088 /* Find an unused room for a branch location. */
1089 STATIC_OVL struct mkroom *
1090 find_branch_room(mp)
1093 struct mkroom *croom = 0;
1096 mazexy(mp); /* already verifies location */
1098 /* not perfect - there may be only one stairway */
1103 croom = &rooms[rn2(nroom)];
1104 while ((croom == dnstairs_room || croom == upstairs_room
1105 || croom->rtype != OROOM) && (++tryct < 100));
1107 croom = &rooms[rn2(nroom)];
1110 if (!somexy(croom, mp))
1111 impossible("Can't place branch!");
1112 } while (occupied(mp->x, mp->y)
1113 || (levl[mp->x][mp->y].typ != CORR
1114 && levl[mp->x][mp->y].typ != ROOM));
1119 /* Find the room for (x,y). Return null if not in a room. */
1120 STATIC_OVL struct mkroom *
1125 struct mkroom *curr;
1127 for (curr = rooms, i = 0; i < nroom; curr++, i++)
1128 if (inside_room(curr, x, y))
1131 return (struct mkroom *) 0;
1134 /* If given a branch, randomly place a special stair or portal. */
1136 place_branch(br, x, y)
1137 branch *br; /* branch to place */
1138 xchar x, y; /* location */
1142 boolean make_stairs;
1143 struct mkroom *br_room;
1146 * Return immediately if there is no branch to make or we have
1147 * already made one. This routine can be called twice when
1148 * a special level is loaded that specifies an SSTAIR location
1149 * as a favored spot for a branch.
1151 if (!br || made_branch)
1154 if (!x) { /* find random coordinates for branch */
1155 br_room = find_branch_room(&m);
1159 br_room = pos_to_room(x, y);
1162 if (on_level(&br->end1, &u.uz)) {
1164 make_stairs = br->type != BR_NO_END1;
1168 make_stairs = br->type != BR_NO_END2;
1172 if (br->type == BR_PORTAL) {
1173 mkportal(x, y, dest->dnum, dest->dlevel);
1174 } else if (make_stairs) {
1178 (char) on_level(&br->end1, &u.uz) ? br->end1_up : !br->end1_up;
1179 assign_level(&sstairs.tolev, dest);
1180 sstairs_room = br_room;
1182 levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN;
1183 levl[x][y].typ = STAIRS;
1186 * Set made_branch to TRUE even if we didn't make a stairwell (i.e.
1187 * make_stairs is false) since there is currently only one branch
1188 * per level, if we failed once, we're going to fail again on the
1196 register xchar x, y;
1200 if (isok(x + 1, y)) {
1201 typ = levl[x + 1][y].typ;
1202 if (IS_DOOR(typ) || typ == SDOOR)
1205 if (isok(x - 1, y)) {
1206 typ = levl[x - 1][y].typ;
1207 if (IS_DOOR(typ) || typ == SDOOR)
1210 if (isok(x, y + 1)) {
1211 typ = levl[x][y + 1].typ;
1212 if (IS_DOOR(typ) || typ == SDOOR)
1215 if (isok(x, y - 1)) {
1216 typ = levl[x][y - 1].typ;
1217 if (IS_DOOR(typ) || typ == SDOOR)
1223 /* see whether it is allowable to create a door at [x,y] */
1228 boolean near_door = bydoor(x, y);
1230 return ((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL)
1231 && doorindex < DOORMAX && !near_door);
1237 struct mkroom *aroom;
1239 if (doorindex >= DOORMAX) {
1240 impossible("DOORMAX exceeded?");
1244 dosdoor(x, y, aroom, rn2(8) ? DOOR : SDOOR);
1249 register xchar x, y;
1251 return (boolean) (t_at(x, y) || IS_FURNITURE(levl[x][y].typ)
1252 || is_lava(x, y) || is_pool(x, y)
1253 || invocation_pos(x, y));
1256 /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
1257 /* if tm != null, make trap at that location */
1259 mktrap(num, mazeflag, croom, tm)
1261 struct mkroom *croom;
1265 unsigned lvl = level_difficulty();
1268 /* no traps in pools */
1269 if (tm && is_pool(tm->x, tm->y))
1272 if (num > 0 && num < TRAPNUM) {
1274 } else if (Is_rogue_level(&u.uz)) {
1292 kind = SLP_GAS_TRAP;
1298 } else if (Inhell && !rn2(5)) {
1299 /* bias the frequency of fire traps in Gehennom */
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);
1378 /* The hero isn't the only person who's entered the dungeon in
1379 search of treasure. On the very shallowest levels, there's a
1380 chance that a created trap will have killed something already
1381 (and this is guaranteed on the first level).
1383 This isn't meant to give any meaningful treasure (in fact, any
1384 items we drop here are typically cursed, other than ammo fired
1385 by the trap). Rather, it's mostly just for flavour and to give
1386 players on very early levels a sufficient chance to avoid traps
1387 that may end up killing them before they have a fair chance to
1388 build max HP. Including cursed items gives the same fair chance
1389 to the starting pet, and fits the rule that possessions of the
1390 dead are normally cursed.
1392 Some types of traps are excluded because they're entirely
1393 nonlethal, even indirectly. We also exclude all of the
1394 later/fancier traps because they tend to have special
1395 considerations (e.g. webs, portals), often are indirectly
1396 lethal, and tend not to generate on shallower levels anyway.
1397 Finally, pits are excluded because it's weird to see an item
1398 in a pit and yet not be able to identify that the pit is there. */
1399 if (lvl <= (unsigned) rnd(4)
1400 && kind != SQKY_BOARD && kind != RUST_TRAP
1401 && kind != PIT && kind != SPIKED_PIT && kind < HOLE) {
1402 /* Object generated by the trap; initially NULL, stays NULL if
1403 we fail to generate an object or if the trap doesn't
1404 generate objects. */
1405 struct obj *otmp = NULL;
1406 int victim_mnum; /* race of the victim */
1408 /* Not all trap types have special handling here; only the ones
1409 that kill in a specific way that's obvious after the fact. */
1412 otmp = mksobj(ARROW, TRUE, FALSE);
1413 otmp->opoisoned = 0;
1414 /* don't adjust the quantity; maybe the trap shot multiple
1415 times, there was an untrapping attempt, etc... */
1418 otmp = mksobj(DART, TRUE, FALSE);
1421 otmp = mksobj(ROCK, TRUE, FALSE);
1424 /* no item dropped by the trap */
1428 place_object(otmp, m.x, m.y);
1431 /* now otmp is reused for other items we're placing */
1433 /* Place a random possession. This could be a weapon, tool,
1434 food, or gem, i.e. the item classes that are typically
1435 nonmagical and not worthless. */
1437 int poss_class = RANDOM_CLASS; /* init => lint suppression */
1441 poss_class = WEAPON_CLASS;
1444 poss_class = TOOL_CLASS;
1447 poss_class = FOOD_CLASS;
1450 poss_class = GEM_CLASS;
1454 otmp = mkobj(poss_class, FALSE);
1455 /* these items are always cursed, both for flavour (owned
1456 by a dead adventurer, bones-pile-style) and for balance
1457 (less useful to use, and encourage pets to avoid the trap) */
1461 otmp->owt = weight(otmp);
1462 place_object(otmp, m.x, m.y);
1465 /* 20% chance of placing an additional item, recursively */
1468 /* Place a corpse. */
1471 /* elf corpses are the rarest as they're the most useful */
1472 victim_mnum = PM_ELF;
1473 /* elven adventurers get sleep resistance early; so don't
1474 generate elf corpses on sleeping gas traps unless a)
1475 we're on dlvl 2 (1 is impossible) and b) we pass a coin
1477 if (kind == SLP_GAS_TRAP && !(lvl <= 2 && rn2(2)))
1478 victim_mnum = PM_HUMAN;
1481 victim_mnum = PM_DWARF;
1483 case 3: case 4: case 5:
1484 victim_mnum = PM_ORC;
1486 case 6: case 7: case 8: case 9:
1487 /* more common as they could have come from the Mines */
1488 victim_mnum = PM_GNOME;
1489 /* 10% chance of a candle too */
1491 otmp = mksobj(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE,
1496 otmp->owt = weight(otmp);
1497 place_object(otmp, m.x, m.y);
1501 /* the most common race */
1502 victim_mnum = PM_HUMAN;
1505 otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], m.x, m.y,
1508 otmp->age -= 51; /* died too long ago to eat */
1513 mkstairs(x, y, up, croom)
1516 struct mkroom *croom;
1519 impossible("mkstairs: bogus stair attempt at <%d,%d>", x, y);
1524 * We can't make a regular stair off an end of the dungeon. This
1525 * attempt can happen when a special level is placed at an end and
1526 * has an up or down stair specified in its description file.
1528 if ((dunlev(&u.uz) == 1 && up)
1529 || (dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up))
1535 upstairs_room = croom;
1539 dnstairs_room = croom;
1542 levl[x][y].typ = STAIRS;
1543 levl[x][y].ladder = up ? LA_UP : LA_DOWN;
1547 mkfount(mazeflag, croom)
1549 struct mkroom *croom;
1552 register int tryct = 0;
1559 else if (!somexy(croom, &m))
1561 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1563 /* Put a fountain at m.x, m.y */
1564 levl[m.x][m.y].typ = FOUNTAIN;
1565 /* Is it a "blessed" fountain? (affects drinking from fountain) */
1567 levl[m.x][m.y].blessedftn = 1;
1569 level.flags.nfountains++;
1574 struct mkroom *croom;
1577 register int tryct = 0;
1582 if (!somexy(croom, &m))
1584 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1586 /* Put a sink at m.x, m.y */
1587 levl[m.x][m.y].typ = SINK;
1589 level.flags.nsinks++;
1594 struct mkroom *croom;
1597 register int tryct = 0;
1600 if (croom->rtype != OROOM)
1606 if (!somexy(croom, &m))
1608 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1610 /* Put an altar at m.x, m.y */
1611 levl[m.x][m.y].typ = ALTAR;
1613 /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
1614 al = rn2((int) A_LAWFUL + 2) - 1;
1615 levl[m.x][m.y].altarmask = Align2amask(al);
1620 struct mkroom *croom;
1623 register int tryct = 0;
1624 register struct obj *otmp;
1625 boolean dobell = !rn2(10);
1627 if (croom->rtype != OROOM)
1633 if (!somexy(croom, &m))
1635 } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1637 /* Put a grave at m.x, m.y */
1639 make_grave(m.x, m.y, dobell ? "Saved by the bell!" : (char *) 0);
1641 make_grave(m.x, m.y, dobell ? "
\83x
\83\8b\82É
\8b~
\82í
\82ê
\82½
\81I" : (char *) 0);
1643 /* Possibly fill it with objects */
1645 (void) mkgold(0L, m.x, m.y);
1646 for (tryct = rn2(5); tryct; tryct--) {
1647 otmp = mkobj(RANDOM_CLASS, TRUE);
1653 add_to_buried(otmp);
1656 /* Leave a bell, in case we accidentally buried someone alive */
1658 (void) mksobj_at(BELL, m.x, m.y, TRUE, FALSE);
1662 /* maze levels have slightly different constraints from normal levels */
1663 #define x_maze_min 2
1664 #define y_maze_min 2
1667 * Major level transmutation: add a set of stairs (to the Sanctum) after
1668 * an earthquake that leaves behind a a new topology, centered at inv_pos.
1669 * Assumes there are no rooms within the invocation area and that inv_pos
1670 * is not too close to the edge of the map. Also assume the hero can see,
1671 * which is guaranteed for normal play due to the fact that sight is needed
1672 * to read the Book of the Dead.
1678 xchar xmin = inv_pos.x, xmax = inv_pos.x;
1679 xchar ymin = inv_pos.y, ymax = inv_pos.y;
1683 pline_The("floor shakes violently under you!");
1685 pline("
\82 \82È
\82½
\82Ì
\89º
\82Ì
\8f°
\82ª
\93Ë
\91R
\97h
\82ê
\82½
\81I");
1687 pline_The("walls around you begin to bend and crumble!");
1689 pline("
\82»
\82µ
\82Ä
\82Ü
\82í
\82è
\82Ì
\95Ç
\82ª
\82Ë
\82¶
\82ê
\81C
\8dÓ
\82¯
\82½
\81I");
1690 display_nhwindow(WIN_MESSAGE, TRUE);
1692 /* any trap hero is stuck in will be going away now */
1695 if (u.utraptype == TT_BURIEDBALL)
1696 buried_ball_to_punishment();
1698 mkinvpos(xmin, ymin, 0); /* middle, before placing stairs */
1700 for (dist = 1; dist < 7; dist++) {
1704 /* top and bottom */
1705 if (dist != 3) { /* the area is wider that it is high */
1708 for (i = xmin + 1; i < xmax; i++) {
1709 mkinvpos(i, ymin, dist);
1710 mkinvpos(i, ymax, dist);
1714 /* left and right */
1715 for (i = ymin; i <= ymax; i++) {
1716 mkinvpos(xmin, i, dist);
1717 mkinvpos(xmax, i, dist);
1720 flush_screen(1); /* make sure the new glyphs shows up */
1725 You("are standing at the top of a stairwell leading down!");
1727 You("
\89º
\82É
\91±
\82
\90\81\82«
\94²
\82¯
\8aK
\92i
\82Ì
\8fã
\82É
\97§
\82Á
\82Ä
\82¢
\82é
\81I");
1728 mkstairs(u.ux, u.uy, 0, (struct mkroom *) 0); /* down */
1730 vision_full_recalc = 1; /* everything changed */
1733 /* Change level topology. Boulders in the vicinity are eliminated.
1734 * Temporarily overrides vision in the name of a nice effect.
1737 mkinvpos(x, y, dist)
1744 register struct rm *lev = &levl[x][y];
1746 /* clip at existing map borders if necessary */
1747 if (!within_bounded_area(x, y, x_maze_min + 1, y_maze_min + 1,
1748 x_maze_max - 1, y_maze_max - 1)) {
1749 /* only outermost 2 columns and/or rows may be truncated due to edge
1752 panic("mkinvpos: <%d,%d> (%d) off map edge!", x, y, dist);
1757 if ((ttmp = t_at(x, y)) != 0)
1760 /* clear boulders; leave some rocks for non-{moat|trap} locations */
1761 make_rocks = (dist != 1 && dist != 4 && dist != 5) ? TRUE : FALSE;
1762 while ((otmp = sobj_at(BOULDER, x, y)) != 0) {
1764 fracture_rock(otmp);
1765 make_rocks = FALSE; /* don't bother with more rocks */
1767 obj_extract_self(otmp);
1768 obfree(otmp, (struct obj *) 0);
1771 unblock_point(x, y); /* make sure vision knows this location is open */
1773 /* fake out saved state */
1779 lev->horizontal = FALSE;
1780 /* short-circuit vision recalc */
1781 viz_array[y][x] = (dist < 6) ? (IN_SIGHT | COULD_SEE) : COULD_SEE;
1784 case 1: /* fire traps */
1788 ttmp = maketrap(x, y, FIRE_TRAP);
1792 case 0: /* lit room locations */
1795 case 6: /* unlit room locations */
1798 case 4: /* pools (aka a wide moat) */
1804 impossible("mkinvpos called with dist %d", dist);
1808 /* display new value of position; could have a monster/object on it */
1813 * The portal to Ludios is special. The entrance can only occur within a
1814 * vault in the main dungeon at a depth greater than 10. The Ludios branch
1815 * structure reflects this by having a bogus "source" dungeon: the value
1816 * of n_dgns (thus, Is_branchlev() will never find it).
1818 * Ludios will remain isolated until the branch is corrected by this function.
1821 mk_knox_portal(x, y)
1824 extern int n_dgns; /* from dungeon.c */
1830 br = dungeon_branch("Fort Ludios");
1832 br = dungeon_branch("
\83\8d\81[
\83f
\83B
\83I
\83X
\8dÔ");
1833 if (on_level(&knox_level, &br->end1)) {
1836 /* disallow Knox branch on a level with one branch already */
1837 if (Is_branchlev(&u.uz))
1842 /* Already set or 2/3 chance of deferring until a later level. */
1843 if (source->dnum < n_dgns || (rn2(3) && !wizard))
1846 if (!(u.uz.dnum == oracle_level.dnum /* in main dungeon */
1848 && !at_dgn_entrance("The Quest") /* but not Quest's entry */
1850 && !at_dgn_entrance("
\83N
\83G
\83X
\83g") /* but not Quest's entry */
1852 && (u_depth = depth(&u.uz)) > 10 /* beneath 10 */
1853 && u_depth < depth(&medusa_level))) /* and above Medusa */
1856 /* Adjust source to be current level and re-insert branch. */
1858 insert_branch(br, TRUE);
1860 debugpline0("Made knox portal.");
1861 place_branch(br, x, y);