OSDN Git Service

set trivial flags
[jnethack/source.git] / src / mklev.c
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. */
5
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. */
10
11 #include "hack.h"
12
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 */
16
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,
31                                           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,
35                                            int, int, BOOLEAN_P,
36                                            SCHAR_P, BOOLEAN_P, BOOLEAN_P));
37 STATIC_DCL void NDECL(makerooms);
38 STATIC_DCL void FDECL(finddpos, (coord *, XCHAR_P, XCHAR_P,
39                                  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));
42
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 */
48
49 /* Args must be (const genericptr) so that qsort will always be happy. */
50
51 STATIC_PTR int CFDECLSPEC
52 do_comp(vx, vy)
53 const genericptr vx;
54 const genericptr vy;
55 {
56 #ifdef LINT
57     /* lint complains about possible pointer alignment problems, but we know
58        that vx and vy are always properly aligned. Hence, the following
59        bogus definition:
60     */
61     return (vx == vy) ? 0 : -1;
62 #else
63     register const struct mkroom *x, *y;
64
65     x = (const struct mkroom *) vx;
66     y = (const struct mkroom *) vy;
67     if (x->lx < y->lx)
68         return -1;
69     return (x->lx > y->lx);
70 #endif /* LINT */
71 }
72
73 STATIC_OVL void
74 finddpos(cc, xl, yl, xh, yh)
75 coord *cc;
76 xchar xl, yl, xh, yh;
77 {
78     register xchar x, y;
79
80     x = rn1(xh - xl + 1, xl);
81     y = rn1(yh - yl + 1, yl);
82     if (okdoor(x, y))
83         goto gotit;
84
85     for (x = xl; x <= xh; x++)
86         for (y = yl; y <= yh; y++)
87             if (okdoor(x, y))
88                 goto gotit;
89
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)
93                 goto gotit;
94     /* cannot find something reasonable -- strange */
95     x = xl;
96     y = yh;
97  gotit:
98     cc->x = x;
99     cc->y = y;
100     return;
101 }
102
103 void
104 sort_rooms()
105 {
106 #if defined(SYSV) || defined(DGUX)
107 #define CAST_nroom (unsigned) nroom
108 #else
109 #define CAST_nroom nroom /*as-is*/
110 #endif
111     qsort((genericptr_t) rooms, CAST_nroom, sizeof (struct mkroom), do_comp);
112 #undef CAST_nroom
113 }
114
115 STATIC_OVL void
116 do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room)
117 register struct mkroom *croom;
118 int lowx, lowy;
119 register int hix, hiy;
120 boolean lit;
121 schar rtype;
122 boolean special;
123 boolean is_room;
124 {
125     register int x, y;
126     struct rm *lev;
127
128     /* locations might bump level edges in wall-less rooms */
129     /* add/subtract 1 to allow for edge locations */
130     if (!lowx)
131         lowx++;
132     if (!lowy)
133         lowy++;
134     if (hix >= COLNO - 1)
135         hix = COLNO - 2;
136     if (hiy >= ROWNO - 1)
137         hiy = ROWNO - 2;
138
139     if (lit) {
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++)
143                 lev++->lit = 1;
144         }
145         croom->rlit = 1;
146     } else
147         croom->rlit = 0;
148
149     croom->lx = lowx;
150     croom->hx = hix;
151     croom->ly = lowy;
152     croom->hy = hiy;
153     croom->rtype = rtype;
154     croom->doorct = 0;
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
158      */
159     croom->fdoor = doorindex;
160     croom->irregular = FALSE;
161
162     croom->nsubrooms = 0;
163     croom->sbrooms[0] = (struct mkroom *) 0;
164     if (!special) {
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. */
169             }
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. */
174             }
175         for (x = lowx; x <= hix; x++) {
176             lev = &levl[x][lowy];
177             for (y = lowy; y <= hiy; y++)
178                 lev++->typ = ROOM;
179         }
180         if (is_room) {
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);
187         }
188     }
189 }
190
191 void
192 add_room(lowx, lowy, hix, hiy, lit, rtype, special)
193 int lowx, lowy, hix, hiy;
194 boolean lit;
195 schar rtype;
196 boolean special;
197 {
198     register struct mkroom *croom;
199
200     croom = &rooms[nroom];
201     do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
202                        (boolean) TRUE);
203     croom++;
204     croom->hx = -1;
205     nroom++;
206 }
207
208 void
209 add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special)
210 struct mkroom *proom;
211 int lowx, lowy, hix, hiy;
212 boolean lit;
213 schar rtype;
214 boolean special;
215 {
216     register struct mkroom *croom;
217
218     croom = &subrooms[nsubroom];
219     do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special,
220                        (boolean) FALSE);
221     proom->sbrooms[proom->nsubrooms++] = croom;
222     croom++;
223     croom->hx = -1;
224     nsubroom++;
225 }
226
227 STATIC_OVL void
228 makerooms()
229 {
230     boolean tried_vault = FALSE;
231
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) {
236             tried_vault = TRUE;
237             if (create_vault()) {
238                 vault_x = rooms[nroom].lx;
239                 vault_y = rooms[nroom].ly;
240                 rooms[nroom].hx = -1;
241             }
242         } else if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
243             return;
244     }
245     return;
246 }
247
248 STATIC_OVL void
249 join(a, b, nxcor)
250 register int a, b;
251 boolean nxcor;
252 {
253     coord cc, tt, org, dest;
254     register xchar tx, ty, xx, yy;
255     register struct mkroom *croom, *troom;
256     register int dx, dy;
257
258     croom = &rooms[a];
259     troom = &rooms[b];
260
261     /* find positions cc and tt for doors in croom and troom
262        and direction for a corridor between them */
263
264     if (troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX)
265         return;
266     if (troom->lx > croom->hx) {
267         dx = 1;
268         dy = 0;
269         xx = croom->hx + 1;
270         tx = troom->lx - 1;
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) {
274         dy = -1;
275         dx = 0;
276         yy = croom->ly - 1;
277         finddpos(&cc, croom->lx, yy, croom->hx, yy);
278         ty = troom->hy + 1;
279         finddpos(&tt, troom->lx, ty, troom->hx, ty);
280     } else if (troom->hx < croom->lx) {
281         dx = -1;
282         dy = 0;
283         xx = croom->lx - 1;
284         tx = troom->hx + 1;
285         finddpos(&cc, xx, croom->ly, xx, croom->hy);
286         finddpos(&tt, tx, troom->ly, tx, troom->hy);
287     } else {
288         dy = 1;
289         dx = 0;
290         yy = croom->hy + 1;
291         ty = troom->ly - 1;
292         finddpos(&cc, croom->lx, yy, croom->hx, yy);
293         finddpos(&tt, troom->lx, ty, troom->hx, ty);
294     }
295     xx = cc.x;
296     yy = cc.y;
297     tx = tt.x - dx;
298     ty = tt.y - dy;
299     if (nxcor && levl[xx + dx][yy + dy].typ)
300         return;
301     if (okdoor(xx, yy) || !nxcor)
302         dodoor(xx, yy, croom);
303
304     org.x = xx + dx;
305     org.y = yy + dy;
306     dest.x = tx;
307     dest.y = ty;
308
309     if (!dig_corridor(&org, &dest, nxcor, level.flags.arboreal ? ROOM : CORR,
310                       STONE))
311         return;
312
313     /* we succeeded in digging the corridor */
314     if (okdoor(tt.x, tt.y) || !nxcor)
315         dodoor(tt.x, tt.y, troom);
316
317     if (smeq[a] < smeq[b])
318         smeq[b] = smeq[a];
319     else
320         smeq[a] = smeq[b];
321 }
322
323 void
324 makecorridors()
325 {
326     int a, b, i;
327     boolean any = TRUE;
328
329     for (a = 0; a < nroom - 1; a++) {
330         join(a, a + 1, FALSE);
331         if (!rn2(50))
332             break; /* allow some randomness */
333     }
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++) {
338         any = FALSE;
339         for (b = 0; b < nroom; b++)
340             if (smeq[a] != smeq[b]) {
341                 join(a, b, FALSE);
342                 any = TRUE;
343             }
344     }
345     if (nroom > 2)
346         for (i = rn2(nroom) + 4; i; i--) {
347             a = rn2(nroom);
348             b = rn2(nroom - 2);
349             if (b >= a)
350                 b += 2;
351             join(a, b, TRUE);
352         }
353 }
354
355 void
356 add_door(x, y, aroom)
357 register int x, y;
358 register struct mkroom *aroom;
359 {
360     register struct mkroom *broom;
361     register int tmp;
362     int i;
363
364     if (aroom->doorct == 0)
365         aroom->fdoor = doorindex;
366
367     aroom->doorct++;
368
369     for (tmp = doorindex; tmp > aroom->fdoor; tmp--)
370         doors[tmp] = doors[tmp - 1];
371
372     for (i = 0; i < nroom; i++) {
373         broom = &rooms[i];
374         if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
375             broom->fdoor++;
376     }
377     for (i = 0; i < nsubroom; i++) {
378         broom = &subrooms[i];
379         if (broom != aroom && broom->doorct && broom->fdoor >= aroom->fdoor)
380             broom->fdoor++;
381     }
382
383     doorindex++;
384     doors[aroom->fdoor].x = x;
385     doors[aroom->fdoor].y = y;
386 }
387
388 STATIC_OVL void
389 dosdoor(x, y, aroom, type)
390 register xchar x, y;
391 struct mkroom *aroom;
392 int type;
393 {
394     boolean shdoor = *in_rooms(x, y, SHOPBASE) ? TRUE : FALSE;
395
396     if (!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */
397         type = DOOR;
398     levl[x][y].typ = type;
399     if (type == DOOR) {
400         if (!rn2(3)) { /* is it a locked door, closed, or a doorway? */
401             if (!rn2(5))
402                 levl[x][y].doormask = D_ISOPEN;
403             else if (!rn2(6))
404                 levl[x][y].doormask = D_LOCKED;
405             else
406                 levl[x][y].doormask = D_CLOSED;
407
408             if (levl[x][y].doormask != D_ISOPEN && !shdoor
409                 && level_difficulty() >= 5 && !rn2(25))
410                 levl[x][y].doormask |= D_TRAPPED;
411         } else {
412 #ifdef STUPID
413             if (shdoor)
414                 levl[x][y].doormask = D_ISOPEN;
415             else
416                 levl[x][y].doormask = D_NODOOR;
417 #else
418             levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
419 #endif
420         }
421
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;
426
427         if (levl[x][y].doormask & D_TRAPPED) {
428             struct monst *mtmp;
429
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);
437                 if (mtmp)
438                     set_mimic_sym(mtmp);
439             }
440         }
441         /* newsym(x,y); */
442     } else { /* SDOOR */
443         if (shdoor || !rn2(5))
444             levl[x][y].doormask = D_LOCKED;
445         else
446             levl[x][y].doormask = D_CLOSED;
447
448         if (!shdoor && level_difficulty() >= 4 && !rn2(20))
449             levl[x][y].doormask |= D_TRAPPED;
450     }
451
452     add_door(x, y, aroom);
453 }
454
455 STATIC_OVL boolean
456 place_niche(aroom, dy, xx, yy)
457 register struct mkroom *aroom;
458 int *dy, *xx, *yy;
459 {
460     coord dd;
461
462     if (rn2(2)) {
463         *dy = 1;
464         finddpos(&dd, aroom->lx, aroom->hy + 1, aroom->hx, aroom->hy + 1);
465     } else {
466         *dy = -1;
467         finddpos(&dd, aroom->lx, aroom->ly - 1, aroom->hx, aroom->ly - 1);
468     }
469     *xx = dd.x;
470     *yy = dd.y;
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)));
476 }
477
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 */
484 /*JP
485     "Vlad was here", "ad aerarium", "ad aerarium", (char *) 0, (char *) 0,
486 */
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,
489 };
490
491 STATIC_OVL void
492 makeniche(trap_type)
493 int trap_type;
494 {
495     register struct mkroom *aroom;
496     struct rm *rm;
497     int vct = 8;
498     int dy, xx, yy;
499     struct trap *ttmp;
500
501     if (doorindex < DOORMAX) {
502         while (vct--) {
503             aroom = &rooms[rn2(nroom)];
504             if (aroom->rtype != OROOM)
505                 continue; /* not an ordinary room */
506             if (aroom->doorct == 1 && rn2(5))
507                 continue;
508             if (!place_niche(aroom, &dy, &xx, &yy))
509                 continue;
510
511             rm = &levl[xx][yy + dy];
512             if (trap_type || !rn2(4)) {
513                 rm->typ = SCORR;
514                 if (trap_type) {
515                     if (is_hole(trap_type) && !Can_fall_thru(&u.uz))
516                         trap_type = ROCKTRAP;
517                     ttmp = maketrap(xx, yy + dy, trap_type);
518                     if (ttmp) {
519                         if (trap_type != ROCKTRAP)
520                             ttmp->once = 1;
521                         if (trap_engravings[trap_type]) {
522                             make_engr_at(xx, yy - dy,
523                                          trap_engravings[trap_type], 0L,
524                                          DUST);
525                             wipe_engr_at(xx, yy - dy, 5,
526                                          FALSE); /* age it a little */
527                         }
528                     }
529                 }
530                 dosdoor(xx, yy, aroom, SDOOR);
531             } else {
532                 rm->typ = CORR;
533                 if (rn2(7))
534                     dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
535                 else {
536                     /* inaccessible niches occasionally have iron bars */
537                     if (!rn2(5) && IS_WALL(levl[xx][yy].typ)) {
538                         levl[xx][yy].typ = IRONBARS;
539                         if (rn2(3))
540                             (void) mkcorpstat(CORPSE, (struct monst *) 0,
541                                               mkclass(S_HUMAN, 0), xx,
542                                               yy + dy, TRUE);
543                     }
544                     if (!level.flags.noteleport)
545                         (void) mksobj_at(SCR_TELEPORTATION, xx, yy + dy, TRUE,
546                                          FALSE);
547                     if (!rn2(3))
548                         (void) mkobj_at(0, xx, yy + dy, TRUE);
549                 }
550             }
551             return;
552         }
553     }
554 }
555
556 STATIC_OVL void
557 make_niches()
558 {
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);
562
563     while (ct--) {
564         if (ltptr && !rn2(6)) {
565             ltptr = FALSE;
566             makeniche(LEVEL_TELEP);
567         } else if (vamp && !rn2(6)) {
568             vamp = FALSE;
569             makeniche(TRAPDOOR);
570         } else
571             makeniche(NO_TRAP);
572     }
573 }
574
575 STATIC_OVL void
576 makevtele()
577 {
578     makeniche(TELEP_TRAP);
579 }
580
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.
585  */
586 STATIC_OVL void
587 clear_level_structures()
588 {
589     static struct rm zerorm = { cmap_to_glyph(S_stone),
590                                 0, 0, 0, 0, 0, 0, 0, 0, 0 };
591     register int x, y;
592     register struct rm *lev;
593
594     for (x = 0; x < COLNO; x++) {
595         lev = &levl[x][0];
596         for (y = 0; y < ROWNO; y++) {
597             *lev++ = zerorm;
598             /*
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.
604              */
605             level.objects[x][y] = (struct obj *) 0;
606             level.monsters[x][y] = (struct monst *) 0;
607         }
608     }
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;
614
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;
637
638     nroom = 0;
639     rooms[0].hx = -1;
640     nsubroom = 0;
641     subrooms[0].hx = -1;
642     doorindex = 0;
643     init_rect();
644     init_vault();
645     xdnstair = ydnstair = xupstair = yupstair = 0;
646     sstairs.sx = sstairs.sy = 0;
647     xdnladder = ydnladder = xupladder = yupladder = 0;
648     made_branch = FALSE;
649     clear_regions();
650 }
651
652 STATIC_OVL void
653 makelevel()
654 {
655     register struct mkroom *croom, *troom;
656     register int tryct;
657     register int x, y;
658     struct monst *tmonst; /* always put a web with a spider */
659     branch *branchp;
660     int room_threshold;
661
662     if (wiz1_level.dlevel == 0)
663         init_dungeons();
664     oinit(); /* assign level dependent obj probabilities */
665     clear_level_structures();
666
667     {
668         register s_level *slev = Is_special(&u.uz);
669
670         /* check for special levels */
671         if (slev && !Is_rogue_level(&u.uz)) {
672             makemaz(slev->proto);
673             return;
674         } else if (dungeons[u.uz.dnum].proto[0]) {
675             makemaz("");
676             return;
677         } else if (In_mines(&u.uz)) {
678             makemaz("minefill");
679             return;
680         } else if (In_quest(&u.uz)) {
681             char fillname[9];
682             s_level *loc_lev;
683
684             Sprintf(fillname, "%s-loca", urole.filecode);
685             loc_lev = find_level(fillname);
686
687             Sprintf(fillname, "%s-fil", urole.filecode);
688             Strcat(fillname,
689                    (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
690             makemaz(fillname);
691             return;
692         } else if (In_hell(&u.uz)
693                    || (rn2(5) && u.uz.dnum == medusa_level.dnum
694                        && depth(&u.uz) > depth(&medusa_level))) {
695             makemaz("");
696             return;
697         }
698     }
699
700     /* otherwise, fall through - it's a "regular" level. */
701
702     if (Is_rogue_level(&u.uz)) {
703         makeroguerooms();
704         makerogueghost();
705     } else
706         makerooms();
707     sort_rooms();
708
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 */
713     if (nroom > 1) {
714         troom = croom;
715         croom = &rooms[rn2(nroom - 1)];
716         if (croom == troom)
717             croom++;
718     }
719
720     if (u.uz.dlevel != 1) {
721         xchar sx, sy;
722         do {
723             sx = somex(croom);
724             sy = somey(croom);
725         } while (occupied(sx, sy));
726         mkstairs(sx, sy, 1, croom); /* up */
727     }
728
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))
733         goto skip0;
734     makecorridors();
735     make_niches();
736
737     /* make a secret treasure vault, not connected to the rest */
738     if (do_vault()) {
739         xchar w, h;
740
741         debugpline0("trying to make a vault...");
742         w = 1;
743         h = 1;
744         if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) {
745  fill_vault:
746             add_room(vault_x, vault_y, vault_x + w, vault_y + h, TRUE, VAULT,
747                      FALSE);
748             level.flags.has_vault = 1;
749             ++room_threshold;
750             fill_room(&rooms[nroom - 1], FALSE);
751             mk_knox_portal(vault_x + w, vault_y + h);
752             if (!level.flags.noteleport && !rn2(3))
753                 makevtele();
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))
758                 goto fill_vault;
759             else
760                 rooms[nroom].hx = -1;
761         }
762     }
763
764     {
765         register int u_depth = depth(&u.uz);
766
767         if (wizard && nh_getenv("SHOPTYPE"))
768             mkroom(SHOPBASE);
769         else if (u_depth > 1 && u_depth < depth(&medusa_level)
770                  && nroom >= room_threshold && rn2(u_depth) < 3)
771             mkroom(SHOPBASE);
772         else if (u_depth > 4 && !rn2(6))
773             mkroom(COURT);
774         else if (u_depth > 5 && !rn2(8)
775                  && !(mvitals[PM_LEPRECHAUN].mvflags & G_GONE))
776             mkroom(LEPREHALL);
777         else if (u_depth > 6 && !rn2(7))
778             mkroom(ZOO);
779         else if (u_depth > 8 && !rn2(5))
780             mkroom(TEMPLE);
781         else if (u_depth > 9 && !rn2(5)
782                  && !(mvitals[PM_KILLER_BEE].mvflags & G_GONE))
783             mkroom(BEEHIVE);
784         else if (u_depth > 11 && !rn2(6))
785             mkroom(MORGUE);
786         else if (u_depth > 12 && !rn2(8) && antholemon())
787             mkroom(ANTHOLE);
788         else if (u_depth > 14 && !rn2(4)
789                  && !(mvitals[PM_SOLDIER].mvflags & G_GONE))
790             mkroom(BARRACKS);
791         else if (u_depth > 15 && !rn2(6))
792             mkroom(SWAMP);
793         else if (u_depth > 16 && !rn2(8)
794                  && !(mvitals[PM_COCKATRICE].mvflags & G_GONE))
795             mkroom(COCKNEST);
796     }
797
798  skip0:
799     /* Place multi-dungeon branch. */
800     place_branch(branchp, 0, 0);
801
802     /* for each room: put things inside */
803     for (croom = rooms; croom->hx > 0; croom++) {
804         if (croom->rtype != OROOM)
805             continue;
806
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. */
812
813         if (u.uhave.amulet || !rn2(3)) {
814             x = somex(croom);
815             y = somey(croom);
816             tmonst = makemon((struct permonst *) 0, x, y, MM_NOGRP);
817             if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]
818                 && !occupied(x, y))
819                 (void) maketrap(x, y, WEB);
820         }
821         /* put traps and mimics inside */
822         x = 8 - (level_difficulty() / 6);
823         if (x <= 1)
824             x = 2;
825         while (!rn2(x))
826             mktrap(0, 0, croom, (coord *) 0);
827         if (!rn2(3))
828             (void) mkgold(0L, somex(croom), somey(croom));
829         if (Is_rogue_level(&u.uz))
830             goto skip_nonrogue;
831         if (!rn2(10))
832             mkfount(0, croom);
833         if (!rn2(60))
834             mksink(croom);
835         if (!rn2(60))
836             mkaltar(croom);
837         x = 80 - (depth(&u.uz) * 2);
838         if (x < 2)
839             x = 2;
840         if (!rn2(x))
841             mkgrave(croom);
842
843         /* put statues inside */
844         if (!rn2(20))
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.
852          */
853         if (!rn2(nroom * 5 / 2))
854             (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, somex(croom),
855                              somey(croom), TRUE, FALSE);
856
857         /* maybe make some graffiti */
858         if (!rn2(27 + 3 * abs(depth(&u.uz)))) {
859             char buf[BUFSZ];
860             const char *mesg = random_engraving(buf);
861
862             if (mesg) {
863                 do {
864                     x = somex(croom);
865                     y = somey(croom);
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);
870             }
871         }
872
873  skip_nonrogue:
874         if (!rn2(3)) {
875             (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
876             tryct = 0;
877             while (!rn2(5)) {
878                 if (++tryct > 100) {
879                     impossible("tryct overflow4");
880                     break;
881                 }
882                 (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
883             }
884         }
885     }
886 }
887
888 /*
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
893  */
894 void
895 mineralize(kelp_pool, kelp_moat, goldprob, gemprob, skip_lvl_checks)
896 int kelp_pool, kelp_moat, goldprob, gemprob;
897 boolean skip_lvl_checks;
898 {
899     s_level *sp;
900     struct obj *otmp;
901     int x, y, cnt;
902
903     if (kelp_pool < 0)
904         kelp_pool = 10;
905     if (kelp_moat < 0)
906         kelp_moat = 30;
907
908     /* Place kelp, except on the plane of water */
909     if (!skip_lvl_checks && In_endgame(&u.uz))
910         return;
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);
916
917     /* determine if it is even allowed;
918        almost all special levels are excluded */
919     if (!skip_lvl_checks
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))))
924         return;
925
926     /* basic level-related probabilities */
927     if (goldprob < 0)
928         goldprob = 20 + depth(&u.uz) / 3;
929     if (gemprob < 0)
930         gemprob = goldprob / 4;
931
932     /* mines have ***MORE*** goodies - otherwise why mine? */
933     if (!skip_lvl_checks) {
934         if (In_mines(&u.uz)) {
935             goldprob *= 2;
936             gemprob *= 3;
937         } else if (In_quest(&u.uz)) {
938             goldprob /= 4;
939             gemprob /= 6;
940         }
941     }
942
943     /*
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.
947      */
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);
967                         if (!rn2(3))
968                             add_to_buried(otmp);
969                         else
970                             place_object(otmp, x, y);
971                     }
972                 }
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 */
978                             } else {
979                                 otmp->ox = x, otmp->oy = y;
980                                 if (!rn2(3))
981                                     add_to_buried(otmp);
982                                 else
983                                     place_object(otmp, x, y);
984                             }
985                         }
986                 }
987             }
988 }
989
990 void
991 mklev()
992 {
993     struct mkroom *croom;
994     int ridx;
995
996     reseed_random(rn2);
997     reseed_random(rn2_on_display_rng);
998
999     init_mapseen(&u.uz);
1000     if (getbones())
1001         return;
1002
1003     in_mklev = TRUE;
1004     makelevel();
1005     bound_digging();
1006     mineralize(-1, -1, -1, -1, FALSE);
1007     in_mklev = 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);
1017 #else
1018             topologize(croom);
1019 #endif
1020     }
1021     set_wall_state();
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;
1026
1027     reseed_random(rn2);
1028     reseed_random(rn2_on_display_rng);
1029 }
1030
1031 void
1032 #ifdef SPECIALIZATION
1033 topologize(croom, do_ordinary)
1034 struct mkroom *croom;
1035 boolean do_ordinary;
1036 #else
1037 topologize(croom)
1038 struct mkroom *croom;
1039 #endif
1040 {
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;
1046 #endif
1047     int subindex, nsubrooms = croom->nsubrooms;
1048
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)
1052         return;
1053 #ifdef SPECIALIZATION
1054     if (Is_rogue_level(&u.uz))
1055         do_ordinary = TRUE; /* vision routine helper */
1056     if ((rtype != OROOM) || do_ordinary)
1057 #endif
1058         {
1059         /* do innards first */
1060         for (x = lowx; x <= hix; x++)
1061             for (y = lowy; y <= hiy; y++)
1062 #ifdef SPECIALIZATION
1063                 if (rtype == OROOM)
1064                     levl[x][y].roomno = NO_ROOM;
1065                 else
1066 #endif
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;
1074                 else
1075                     levl[x][y].roomno = roomno;
1076             }
1077         /* sides */
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;
1083                 else
1084                     levl[x][y].roomno = roomno;
1085             }
1086     }
1087     /* subrooms */
1088     for (subindex = 0; subindex < nsubrooms; subindex++)
1089 #ifdef SPECIALIZATION
1090         topologize(croom->sbrooms[subindex], (boolean) (rtype != OROOM));
1091 #else
1092         topologize(croom->sbrooms[subindex]);
1093 #endif
1094 }
1095
1096 /* Find an unused room for a branch location. */
1097 STATIC_OVL struct mkroom *
1098 find_branch_room(mp)
1099 coord *mp;
1100 {
1101     struct mkroom *croom = 0;
1102
1103     if (nroom == 0) {
1104         mazexy(mp); /* already verifies location */
1105     } else {
1106         /* not perfect - there may be only one stairway */
1107         if (nroom > 2) {
1108             int tryct = 0;
1109
1110             do
1111                 croom = &rooms[rn2(nroom)];
1112             while ((croom == dnstairs_room || croom == upstairs_room
1113                     || croom->rtype != OROOM) && (++tryct < 100));
1114         } else
1115             croom = &rooms[rn2(nroom)];
1116
1117         do {
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));
1123     }
1124     return croom;
1125 }
1126
1127 /* Find the room for (x,y).  Return null if not in a room. */
1128 STATIC_OVL struct mkroom *
1129 pos_to_room(x, y)
1130 xchar x, y;
1131 {
1132     int i;
1133     struct mkroom *curr;
1134
1135     for (curr = rooms, i = 0; i < nroom; curr++, i++)
1136         if (inside_room(curr, x, y))
1137             return curr;
1138     ;
1139     return (struct mkroom *) 0;
1140 }
1141
1142 /* If given a branch, randomly place a special stair or portal. */
1143 void
1144 place_branch(br, x, y)
1145 branch *br; /* branch to place */
1146 xchar x, y; /* location */
1147 {
1148     coord m;
1149     d_level *dest;
1150     boolean make_stairs;
1151     struct mkroom *br_room;
1152
1153     /*
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.
1158      */
1159     if (!br || made_branch)
1160         return;
1161
1162     if (!x) { /* find random coordinates for branch */
1163         br_room = find_branch_room(&m);
1164         x = m.x;
1165         y = m.y;
1166     } else {
1167         br_room = pos_to_room(x, y);
1168     }
1169
1170     if (on_level(&br->end1, &u.uz)) {
1171         /* we're on end1 */
1172         make_stairs = br->type != BR_NO_END1;
1173         dest = &br->end2;
1174     } else {
1175         /* we're on end2 */
1176         make_stairs = br->type != BR_NO_END2;
1177         dest = &br->end1;
1178     }
1179
1180     if (br->type == BR_PORTAL) {
1181         mkportal(x, y, dest->dnum, dest->dlevel);
1182     } else if (make_stairs) {
1183         sstairs.sx = x;
1184         sstairs.sy = y;
1185         sstairs.up =
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;
1189
1190         levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN;
1191         levl[x][y].typ = STAIRS;
1192     }
1193     /*
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
1197      * next call.
1198      */
1199     made_branch = TRUE;
1200 }
1201
1202 STATIC_OVL boolean
1203 bydoor(x, y)
1204 register xchar x, y;
1205 {
1206     register int typ;
1207
1208     if (isok(x + 1, y)) {
1209         typ = levl[x + 1][y].typ;
1210         if (IS_DOOR(typ) || typ == SDOOR)
1211             return TRUE;
1212     }
1213     if (isok(x - 1, y)) {
1214         typ = levl[x - 1][y].typ;
1215         if (IS_DOOR(typ) || typ == SDOOR)
1216             return TRUE;
1217     }
1218     if (isok(x, y + 1)) {
1219         typ = levl[x][y + 1].typ;
1220         if (IS_DOOR(typ) || typ == SDOOR)
1221             return TRUE;
1222     }
1223     if (isok(x, y - 1)) {
1224         typ = levl[x][y - 1].typ;
1225         if (IS_DOOR(typ) || typ == SDOOR)
1226             return TRUE;
1227     }
1228     return FALSE;
1229 }
1230
1231 /* see whether it is allowable to create a door at [x,y] */
1232 int
1233 okdoor(x, y)
1234 xchar x, y;
1235 {
1236     boolean near_door = bydoor(x, y);
1237
1238     return ((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL)
1239             && doorindex < DOORMAX && !near_door);
1240 }
1241
1242 void
1243 dodoor(x, y, aroom)
1244 int x, y;
1245 struct mkroom *aroom;
1246 {
1247     if (doorindex >= DOORMAX) {
1248         impossible("DOORMAX exceeded?");
1249         return;
1250     }
1251
1252     dosdoor(x, y, aroom, rn2(8) ? DOOR : SDOOR);
1253 }
1254
1255 boolean
1256 occupied(x, y)
1257 register xchar x, y;
1258 {
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));
1262 }
1263
1264 /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
1265 /* if tm != null, make trap at that location */
1266 void
1267 mktrap(num, mazeflag, croom, tm)
1268 int num, mazeflag;
1269 struct mkroom *croom;
1270 coord *tm;
1271 {
1272     register int kind;
1273     struct trap *t;
1274     unsigned lvl = level_difficulty();
1275     coord m;
1276
1277     /* no traps in pools */
1278     if (tm && is_pool(tm->x, tm->y))
1279         return;
1280
1281     if (num > 0 && num < TRAPNUM) {
1282         kind = num;
1283     } else if (Is_rogue_level(&u.uz)) {
1284         switch (rn2(7)) {
1285         default:
1286             kind = BEAR_TRAP;
1287             break; /* 0 */
1288         case 1:
1289             kind = ARROW_TRAP;
1290             break;
1291         case 2:
1292             kind = DART_TRAP;
1293             break;
1294         case 3:
1295             kind = TRAPDOOR;
1296             break;
1297         case 4:
1298             kind = PIT;
1299             break;
1300         case 5:
1301             kind = SLP_GAS_TRAP;
1302             break;
1303         case 6:
1304             kind = RUST_TRAP;
1305             break;
1306         }
1307     } else if (Inhell && !rn2(5)) {
1308         /* bias the frequency of fire traps in Gehennom */
1309         kind = FIRE_TRAP;
1310     } else {
1311         do {
1312             kind = rnd(TRAPNUM - 1);
1313             /* reject "too hard" traps */
1314             switch (kind) {
1315             case MAGIC_PORTAL:
1316             case VIBRATING_SQUARE:
1317                 kind = NO_TRAP;
1318                 break;
1319             case ROLLING_BOULDER_TRAP:
1320             case SLP_GAS_TRAP:
1321                 if (lvl < 2)
1322                     kind = NO_TRAP;
1323                 break;
1324             case LEVEL_TELEP:
1325                 if (lvl < 5 || level.flags.noteleport)
1326                     kind = NO_TRAP;
1327                 break;
1328             case SPIKED_PIT:
1329                 if (lvl < 5)
1330                     kind = NO_TRAP;
1331                 break;
1332             case LANDMINE:
1333                 if (lvl < 6)
1334                     kind = NO_TRAP;
1335                 break;
1336             case WEB:
1337                 if (lvl < 7)
1338                     kind = NO_TRAP;
1339                 break;
1340             case STATUE_TRAP:
1341             case POLY_TRAP:
1342                 if (lvl < 8)
1343                     kind = NO_TRAP;
1344                 break;
1345             case FIRE_TRAP:
1346                 if (!Inhell)
1347                     kind = NO_TRAP;
1348                 break;
1349             case TELEP_TRAP:
1350                 if (level.flags.noteleport)
1351                     kind = NO_TRAP;
1352                 break;
1353             case HOLE:
1354                 /* make these much less often than other traps */
1355                 if (rn2(7))
1356                     kind = NO_TRAP;
1357                 break;
1358             }
1359         } while (kind == NO_TRAP);
1360     }
1361
1362     if (is_hole(kind) && !Can_fall_thru(&u.uz))
1363         kind = ROCKTRAP;
1364
1365     if (tm) {
1366         m = *tm;
1367     } else {
1368         register int tryct = 0;
1369         boolean avoid_boulder = (is_pit(kind) || is_hole(kind));
1370
1371         do {
1372             if (++tryct > 200)
1373                 return;
1374             if (mazeflag)
1375                 mazexy(&m);
1376             else if (!somexy(croom, &m))
1377                 return;
1378         } while (occupied(m.x, m.y)
1379                  || (avoid_boulder && sobj_at(BOULDER, m.x, m.y)));
1380     }
1381
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;
1386
1387     if (kind == WEB)
1388         (void) makemon(&mons[PM_GIANT_SPIDER], m.x, m.y, NO_MM_FLAGS);
1389
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).
1394
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.
1403
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 */
1424
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. */
1427         switch (kind) {
1428         case ARROW_TRAP:
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... */
1433             break;
1434         case DART_TRAP:
1435             otmp = mksobj(DART, TRUE, FALSE);
1436             break;
1437         case ROCKTRAP:
1438             otmp = mksobj(ROCK, TRUE, FALSE);
1439             break;
1440         default:
1441             /* no item dropped by the trap */
1442             break;
1443         }
1444         if (otmp) {
1445             place_object(otmp, m.x, m.y);
1446         }
1447
1448         /* now otmp is reused for other items we're placing */
1449
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. */
1453         do {
1454             int poss_class = RANDOM_CLASS; /* init => lint suppression */
1455
1456             switch (rn2(4)) {
1457             case 0:
1458                 poss_class = WEAPON_CLASS;
1459                 break;
1460             case 1:
1461                 poss_class = TOOL_CLASS;
1462                 break;
1463             case 2:
1464                 poss_class = FOOD_CLASS;
1465                 break;
1466             case 3:
1467                 poss_class = GEM_CLASS;
1468                 break;
1469             }
1470
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) */
1475             if (otmp) {
1476                 otmp->blessed = 0;
1477                 otmp->cursed = 1;
1478                 otmp->owt = weight(otmp);
1479                 place_object(otmp, m.x, m.y);
1480             }
1481
1482             /* 20% chance of placing an additional item, recursively */
1483         } while (!rn2(5));
1484
1485         /* Place a corpse. */
1486         switch (rn2(15)) {
1487         case 0:
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
1493                flip */
1494             if (kind == SLP_GAS_TRAP && !(lvl <= 2 && rn2(2)))
1495                 victim_mnum = PM_HUMAN;
1496             break;
1497         case 1: case 2:
1498             victim_mnum = PM_DWARF;
1499             break;
1500         case 3: case 4: case 5:
1501             victim_mnum = PM_ORC;
1502             break;
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 */
1507             if (!rn2(10)) {
1508                 otmp = mksobj(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE,
1509                               TRUE, FALSE);
1510                 otmp->quan = 1;
1511                 otmp->blessed = 0;
1512                 otmp->cursed = 1;
1513                 otmp->owt = weight(otmp);
1514                 place_object(otmp, m.x, m.y);
1515             }
1516             break;
1517         default:
1518             /* the most common race */
1519             victim_mnum = PM_HUMAN;
1520             break;
1521         }
1522         otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], m.x, m.y,
1523                           CORPSTAT_INIT);
1524         if (otmp)
1525             otmp->age -= 51; /* died too long ago to eat */
1526     }
1527 }
1528
1529 void
1530 mkstairs(x, y, up, croom)
1531 xchar x, y;
1532 char up;
1533 struct mkroom *croom;
1534 {
1535     if (!x) {
1536         impossible("mkstairs:  bogus stair attempt at <%d,%d>", x, y);
1537         return;
1538     }
1539
1540     /*
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.
1544      */
1545     if ((dunlev(&u.uz) == 1 && up)
1546         || (dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up))
1547         return;
1548
1549     if (up) {
1550         xupstair = x;
1551         yupstair = y;
1552         upstairs_room = croom;
1553     } else {
1554         xdnstair = x;
1555         ydnstair = y;
1556         dnstairs_room = croom;
1557     }
1558
1559     levl[x][y].typ = STAIRS;
1560     levl[x][y].ladder = up ? LA_UP : LA_DOWN;
1561 }
1562
1563 STATIC_OVL void
1564 mkfount(mazeflag, croom)
1565 int mazeflag;
1566 struct mkroom *croom;
1567 {
1568     coord m;
1569     register int tryct = 0;
1570
1571     do {
1572         if (++tryct > 200)
1573             return;
1574         if (mazeflag)
1575             mazexy(&m);
1576         else if (!somexy(croom, &m))
1577             return;
1578     } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1579
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) */
1583     if (!rn2(7))
1584         levl[m.x][m.y].blessedftn = 1;
1585
1586     level.flags.nfountains++;
1587 }
1588
1589 STATIC_OVL void
1590 mksink(croom)
1591 struct mkroom *croom;
1592 {
1593     coord m;
1594     register int tryct = 0;
1595
1596     do {
1597         if (++tryct > 200)
1598             return;
1599         if (!somexy(croom, &m))
1600             return;
1601     } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1602
1603     /* Put a sink at m.x, m.y */
1604     levl[m.x][m.y].typ = SINK;
1605
1606     level.flags.nsinks++;
1607 }
1608
1609 STATIC_OVL void
1610 mkaltar(croom)
1611 struct mkroom *croom;
1612 {
1613     coord m;
1614     register int tryct = 0;
1615     aligntyp al;
1616
1617     if (croom->rtype != OROOM)
1618         return;
1619
1620     do {
1621         if (++tryct > 200)
1622             return;
1623         if (!somexy(croom, &m))
1624             return;
1625     } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1626
1627     /* Put an altar at m.x, m.y */
1628     levl[m.x][m.y].typ = ALTAR;
1629
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);
1633 }
1634
1635 static void
1636 mkgrave(croom)
1637 struct mkroom *croom;
1638 {
1639     coord m;
1640     register int tryct = 0;
1641     register struct obj *otmp;
1642     boolean dobell = !rn2(10);
1643
1644     if (croom->rtype != OROOM)
1645         return;
1646
1647     do {
1648         if (++tryct > 200)
1649             return;
1650         if (!somexy(croom, &m))
1651             return;
1652     } while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1653
1654     /* Put a grave at <m.x,m.y> */
1655 /*JP
1656     make_grave(m.x, m.y, dobell ? "Saved by the bell!" : (char *) 0);
1657 */
1658     make_grave(m.x, m.y, dobell ? "\83x\83\8b\82É\8b~\82í\82ê\82½\81I" : (char *) 0);
1659
1660     /* Possibly fill it with objects */
1661     if (!rn2(3)) {
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);
1668
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);
1673     }
1674     for (tryct = rn2(5); tryct; tryct--) {
1675         otmp = mkobj(RANDOM_CLASS, TRUE);
1676         if (!otmp)
1677             return;
1678         curse(otmp);
1679         otmp->ox = m.x;
1680         otmp->oy = m.y;
1681         add_to_buried(otmp);
1682     }
1683
1684     /* Leave a bell, in case we accidentally buried someone alive */
1685     if (dobell)
1686         (void) mksobj_at(BELL, m.x, m.y, TRUE, FALSE);
1687     return;
1688 }
1689
1690 /* maze levels have slightly different constraints from normal levels */
1691 #define x_maze_min 2
1692 #define y_maze_min 2
1693
1694 /*
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.
1701  */
1702 void
1703 mkinvokearea()
1704 {
1705     int dist;
1706     xchar xmin = inv_pos.x, xmax = inv_pos.x;
1707     xchar ymin = inv_pos.y, ymax = inv_pos.y;
1708     register xchar i;
1709
1710 /*JP
1711     pline_The("floor shakes violently under you!");
1712 */
1713     pline("\82 \82È\82½\82Ì\89º\82Ì\8f°\82ª\93Ë\91R\97h\82ê\82½\81I");
1714 /*JP
1715     pline_The("walls around you begin to bend and crumble!");
1716 */
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);
1719
1720     /* any trap hero is stuck in will be going away now */
1721     if (u.utrap) {
1722         if (u.utraptype == TT_BURIEDBALL)
1723             buried_ball_to_punishment();
1724         reset_utrap(FALSE);
1725     }
1726     mkinvpos(xmin, ymin, 0); /* middle, before placing stairs */
1727
1728     for (dist = 1; dist < 7; dist++) {
1729         xmin--;
1730         xmax++;
1731
1732         /* top and bottom */
1733         if (dist != 3) { /* the area is wider that it is high */
1734             ymin--;
1735             ymax++;
1736             for (i = xmin + 1; i < xmax; i++) {
1737                 mkinvpos(i, ymin, dist);
1738                 mkinvpos(i, ymax, dist);
1739             }
1740         }
1741
1742         /* left and right */
1743         for (i = ymin; i <= ymax; i++) {
1744             mkinvpos(xmin, i, dist);
1745             mkinvpos(xmax, i, dist);
1746         }
1747
1748         flush_screen(1); /* make sure the new glyphs shows up */
1749         delay_output();
1750     }
1751
1752 /*JP
1753     You("are standing at the top of a stairwell leading down!");
1754 */
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 */
1757     newsym(u.ux, u.uy);
1758     vision_full_recalc = 1; /* everything changed */
1759 }
1760
1761 /* Change level topology.  Boulders in the vicinity are eliminated.
1762  * Temporarily overrides vision in the name of a nice effect.
1763  */
1764 STATIC_OVL void
1765 mkinvpos(x, y, dist)
1766 xchar x, y;
1767 int dist;
1768 {
1769     struct trap *ttmp;
1770     struct obj *otmp;
1771     boolean make_rocks;
1772     register struct rm *lev = &levl[x][y];
1773     struct monst *mon;
1774
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
1779          */
1780         if (dist < (7 - 2))
1781             panic("mkinvpos: <%d,%d> (%d) off map edge!", x, y, dist);
1782         return;
1783     }
1784
1785     /* clear traps */
1786     if ((ttmp = t_at(x, y)) != 0)
1787         deltrap(ttmp);
1788
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) {
1792         if (make_rocks) {
1793             fracture_rock(otmp);
1794             make_rocks = FALSE; /* don't bother with more rocks */
1795         } else {
1796             obj_extract_self(otmp);
1797             obfree(otmp, (struct obj *) 0);
1798         }
1799     }
1800
1801     /* fake out saved state */
1802     lev->seenv = 0;
1803     lev->doormask = 0;
1804     if (dist < 6)
1805         lev->lit = TRUE;
1806     lev->waslit = TRUE;
1807     lev->horizontal = FALSE;
1808     /* short-circuit vision recalc */
1809     viz_array[y][x] = (dist < 6) ? (IN_SIGHT | COULD_SEE) : COULD_SEE;
1810
1811     switch (dist) {
1812     case 1: /* fire traps */
1813         if (is_pool(x, y))
1814             break;
1815         lev->typ = ROOM;
1816         ttmp = maketrap(x, y, FIRE_TRAP);
1817         if (ttmp)
1818             ttmp->tseen = TRUE;
1819         break;
1820     case 0: /* lit room locations */
1821     case 2:
1822     case 3:
1823     case 6: /* unlit room locations */
1824         lev->typ = ROOM;
1825         break;
1826     case 4: /* pools (aka a wide moat) */
1827     case 5:
1828         lev->typ = MOAT;
1829         /* No kelp! */
1830         break;
1831     default:
1832         impossible("mkinvpos called with dist %d", dist);
1833         break;
1834     }
1835
1836     if ((mon = m_at(x, y)) != 0) {
1837         /* wake up mimics, don't want to deal with them blocking vision */
1838         if (mon->m_ap_type)
1839             seemimic(mon);
1840
1841         if ((ttmp = t_at(x, y)) != 0)
1842             (void) mintrap(mon);
1843         else
1844             (void) minliquid(mon);
1845     }
1846
1847     if (!does_block(x, y, lev))
1848         unblock_point(x, y); /* make sure vision knows this location is open */
1849
1850     /* display new value of position; could have a monster/object on it */
1851     newsym(x, y);
1852 }
1853
1854 /*
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).
1859  *
1860  * Ludios will remain isolated until the branch is corrected by this function.
1861  */
1862 STATIC_OVL void
1863 mk_knox_portal(x, y)
1864 xchar x, y;
1865 {
1866     extern int n_dgns; /* from dungeon.c */
1867     d_level *source;
1868     branch *br;
1869     schar u_depth;
1870
1871 /*JP
1872     br = dungeon_branch("Fort Ludios");
1873 */
1874     br = dungeon_branch("\83\8d\81[\83f\83B\83I\83X\8dÔ");
1875     if (on_level(&knox_level, &br->end1)) {
1876         source = &br->end2;
1877     } else {
1878         /* disallow Knox branch on a level with one branch already */
1879         if (Is_branchlev(&u.uz))
1880             return;
1881         source = &br->end1;
1882     }
1883
1884     /* Already set or 2/3 chance of deferring until a later level. */
1885     if (source->dnum < n_dgns || (rn2(3) && !wizard))
1886         return;
1887
1888     if (!(u.uz.dnum == oracle_level.dnum      /* in main dungeon */
1889 #if 0 /*JP:T*/
1890           && !at_dgn_entrance("The Quest")    /* but not Quest's entry */
1891 #else
1892           && !at_dgn_entrance("\83N\83G\83X\83g")     /* but not Quest's entry */
1893 #endif
1894           && (u_depth = depth(&u.uz)) > 10    /* beneath 10 */
1895           && u_depth < depth(&medusa_level))) /* and above Medusa */
1896         return;
1897
1898     /* Adjust source to be current level and re-insert branch. */
1899     *source = u.uz;
1900     insert_branch(br, TRUE);
1901
1902     debugpline0("Made knox portal.");
1903     place_branch(br, x, y);
1904 }
1905
1906 /*mklev.c*/