Initial import from FreeBSD RELENG_4:
[dragonfly.git] / games / hack / hack.mklev.c
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.mklev.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.mklev.c,v 1.6 1999/11/16 10:26:36 marcel Exp $ */
4
5 #include <stdlib.h>
6 #include <unistd.h>
7
8 #include "hack.h"
9
10 extern struct monst *makemon();
11 extern struct obj *mkobj_at();
12 extern struct trap *maketrap();
13
14 #define somex() ((random()%(croom->hx-croom->lx+1))+croom->lx)
15 #define somey() ((random()%(croom->hy-croom->ly+1))+croom->ly)
16
17 #include "def.mkroom.h"
18 #define XLIM    4       /* define minimum required space around a room */
19 #define YLIM    3
20 boolean secret;         /* TRUE while making a vault: increase [XY]LIM */
21 struct mkroom rooms[MAXNROFROOMS+1];
22 int smeq[MAXNROFROOMS+1];
23 coord doors[DOORMAX];
24 int doorindex;
25 struct rm zerorm;
26 int comp();
27 schar nxcor;
28 boolean goldseen;
29 int nroom;
30 xchar xdnstair,xupstair,ydnstair,yupstair;
31
32 /* Definitions used by makerooms() and addrs() */
33 #define MAXRS   50      /* max lth of temp rectangle table - arbitrary */
34 struct rectangle {
35         xchar rlx,rly,rhx,rhy;
36 } rs[MAXRS+1];
37 int rscnt,rsmax;        /* 0..rscnt-1: currently under consideration */
38                         /* rscnt..rsmax: discarded */
39
40 makelevel()
41 {
42         struct mkroom *croom, *troom;
43         unsigned tryct;
44         int x,y;
45
46         nroom = 0;
47         doorindex = 0;
48         rooms[0].hx = -1;       /* in case we are in a maze */
49
50         for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
51                 levl[x][y] = zerorm;
52
53         oinit();        /* assign level dependent obj probabilities */
54
55         if(dlevel >= rn1(3, 26)) {      /* there might be several mazes */
56                 makemaz();
57                 return;
58         }
59
60         /* construct the rooms */
61         nroom = 0;
62         secret = FALSE;
63         (void) makerooms();
64
65         /* construct stairs (up and down in different rooms if possible) */
66         croom = &rooms[rn2(nroom)];
67         xdnstair = somex();
68         ydnstair = somey();
69         levl[xdnstair][ydnstair].scrsym ='>';
70         levl[xdnstair][ydnstair].typ = STAIRS;
71         if(nroom > 1) {
72                 troom = croom;
73                 croom = &rooms[rn2(nroom-1)];
74                 if(croom >= troom) croom++;
75         }
76         xupstair = somex();     /* %% < and > might be in the same place */
77         yupstair = somey();
78         levl[xupstair][yupstair].scrsym ='<';
79         levl[xupstair][yupstair].typ = STAIRS;
80
81         /* for each room: put things inside */
82         for(croom = rooms; croom->hx > 0; croom++) {
83
84                 /* put a sleeping monster inside */
85                 /* Note: monster may be on the stairs. This cannot be
86                    avoided: maybe the player fell through a trapdoor
87                    while a monster was on the stairs. Conclusion:
88                    we have to check for monsters on the stairs anyway. */
89                 if(!rn2(3)) (void)
90                         makemon((struct permonst *) 0, somex(), somey());
91
92                 /* put traps and mimics inside */
93                 goldseen = FALSE;
94                 while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
95                 if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey());
96                 if(!rn2(3)) {
97                         (void) mkobj_at(0, somex(), somey());
98                         tryct = 0;
99                         while(!rn2(5)) {
100                                 if(++tryct > 100){
101                                         printf("tryct overflow4\n");
102                                         break;
103                                 }
104                                 (void) mkobj_at(0, somex(), somey());
105                         }
106                 }
107         }
108
109         qsort((char *) rooms, nroom, sizeof(struct mkroom), comp);
110         makecorridors();
111         make_niches();
112
113         /* make a secret treasure vault, not connected to the rest */
114         if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) {
115                 troom = &rooms[nroom];
116                 secret = TRUE;
117                 if(makerooms()) {
118                         troom->rtype = VAULT;           /* treasure vault */
119                         for(x = troom->lx; x <= troom->hx; x++)
120                         for(y = troom->ly; y <= troom->hy; y++)
121                                 mkgold((long)(rnd(dlevel*100) + 50), x, y);
122                         if(!rn2(3))
123                                 makevtele();
124                 }
125         }
126
127 #ifndef QUEST
128 #ifdef WIZARD
129         if(wizard && getenv("SHOPTYPE")) mkshop(); else
130 #endif WIZARD
131         if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop();
132         else
133         if(dlevel > 6 && !rn2(7)) mkzoo(ZOO);
134         else
135         if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE);
136         else
137         if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE);
138         else
139         if(dlevel > 18 && !rn2(6)) mkswamp();
140 #endif QUEST
141 }
142
143 makerooms() {
144 struct rectangle *rsp;
145 int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
146 int tryct = 0, xlim, ylim;
147
148         /* init */
149         xlim = XLIM + secret;
150         ylim = YLIM + secret;
151         if(nroom == 0) {
152                 rsp = rs;
153                 rsp->rlx = rsp->rly = 0;
154                 rsp->rhx = COLNO-1;
155                 rsp->rhy = ROWNO-1;
156                 rsmax = 1;
157         }
158         rscnt = rsmax;
159
160         /* make rooms until satisfied */
161         while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
162                 if(!secret && nroom > (MAXNROFROOMS/3) &&
163                    !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
164                         return(0);
165
166                 /* pick a rectangle */
167                 rsp = &rs[rn2(rscnt)];
168                 hx = rsp->rhx;
169                 hy = rsp->rhy;
170                 lx = rsp->rlx;
171                 ly = rsp->rly;
172
173                 /* find size of room */
174                 if(secret)
175                         dx = dy = 1;
176                 else {
177                         dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
178                         dy = 2 + rn2(4);
179                         if(dx*dy > 50)
180                                 dy = 50/dx;
181                 }
182
183                 /* look whether our room will fit */
184                 if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) {
185                                         /* no, too small */
186                                         /* maybe we throw this area out */
187                         if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
188                                 rscnt--;
189                                 rs[rsmax] = *rsp;
190                                 *rsp = rs[rscnt];
191                                 rs[rscnt] = rs[rsmax];
192                                 tryct = 0;
193                         } else
194                                 tryct++;
195                         continue;
196                 }
197
198                 lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
199                 lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
200                 hix = lowx + dx;
201                 hiy = lowy + dy;
202
203                 if(maker(lowx, dx, lowy, dy)) {
204                         if(secret)
205                                 return(1);
206                         addrs(lowx-1, lowy-1, hix+1, hiy+1);
207                         tryct = 0;
208                 } else
209                         if(tryct++ > 100)
210                                 break;
211         }
212         return(0);      /* failed to make vault - very strange */
213 }
214
215 addrs(lowx,lowy,hix,hiy)
216 int lowx,lowy,hix,hiy;
217 {
218         struct rectangle *rsp;
219         int lx,ly,hx,hy,xlim,ylim;
220         boolean discarded;
221
222         xlim = XLIM + secret;
223         ylim = YLIM + secret;
224
225         /* walk down since rscnt and rsmax change */
226         for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
227
228                 if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
229                    (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
230                         continue;
231                 if((discarded = (rsp >= &rs[rscnt]))) {
232                         *rsp = rs[--rsmax];
233                 } else {
234                         rsmax--;
235                         rscnt--;
236                         *rsp = rs[rscnt];
237                         if(rscnt != rsmax)
238                                 rs[rscnt] = rs[rsmax];
239                 }
240                 if(lowy - ly > 2*ylim + 4)
241                         addrsx(lx,ly,hx,lowy-2,discarded);
242                 if(lowx - lx > 2*xlim + 4)
243                         addrsx(lx,ly,lowx-2,hy,discarded);
244                 if(hy - hiy > 2*ylim + 4)
245                         addrsx(lx,hiy+2,hx,hy,discarded);
246                 if(hx - hix > 2*xlim + 4)
247                         addrsx(hix+2,ly,hx,hy,discarded);
248         }
249 }
250
251 addrsx(lx,ly,hx,hy,discarded)
252 int lx,ly,hx,hy;
253 boolean discarded;              /* piece of a discarded area */
254 {
255         struct rectangle *rsp;
256
257         /* check inclusions */
258         for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
259                 if(lx >= rsp->rlx && hx <= rsp->rhx &&
260                    ly >= rsp->rly && hy <= rsp->rhy)
261                         return;
262         }
263
264         /* make a new entry */
265         if(rsmax >= MAXRS) {
266 #ifdef WIZARD
267                 if(wizard) pline("MAXRS may be too small.");
268 #endif WIZARD
269                 return;
270         }
271         rsmax++;
272         if(!discarded) {
273                 *rsp = rs[rscnt];
274                 rsp = &rs[rscnt];
275                 rscnt++;
276         }
277         rsp->rlx = lx;
278         rsp->rly = ly;
279         rsp->rhx = hx;
280         rsp->rhy = hy;
281 }
282
283 comp(x,y)
284 struct mkroom *x,*y;
285 {
286         if(x->lx < y->lx) return(-1);
287         return(x->lx > y->lx);
288 }
289
290 coord
291 finddpos(xl,yl,xh,yh) {
292         coord ff;
293         int x,y;
294
295         x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
296         y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
297         if(okdoor(x, y))
298                 goto gotit;
299
300         for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
301                 if(okdoor(x, y))
302                         goto gotit;
303
304         for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
305                 if(levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR)
306                         goto gotit;
307         /* cannot find something reasonable -- strange */
308         x = xl;
309         y = yh;
310 gotit:
311         ff.x = x;
312         ff.y = y;
313         return(ff);
314 }
315
316 /* see whether it is allowable to create a door at [x,y] */
317 okdoor(x,y)
318 int x,y;
319 {
320         if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||
321            levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||
322            levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||
323            levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||
324            (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||
325            doorindex >= DOORMAX)
326                 return(0);
327         return(1);
328 }
329
330 dodoor(x,y,aroom)
331 int x,y;
332 struct mkroom *aroom;
333 {
334         if(doorindex >= DOORMAX) {
335                 impossible("DOORMAX exceeded?");
336                 return;
337         }
338         if(!okdoor(x,y) && nxcor)
339                 return;
340         dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
341 }
342
343 dosdoor(x,y,aroom,type)
344 int x,y;
345 struct mkroom *aroom;
346 int type;
347 {
348         struct mkroom *broom;
349         int tmp;
350
351         if(!IS_WALL(levl[x][y].typ))    /* avoid SDOORs with '+' as scrsym */
352                 type = DOOR;
353         levl[x][y].typ = type;
354         if(type == DOOR)
355                 levl[x][y].scrsym = '+';
356         aroom->doorct++;
357         broom = aroom+1;
358         if(broom->hx < 0) tmp = doorindex; else
359         for(tmp = doorindex; tmp > broom->fdoor; tmp--)
360                 doors[tmp] = doors[tmp-1];
361         doorindex++;
362         doors[tmp].x = x;
363         doors[tmp].y = y;
364         for( ; broom->hx >= 0; broom++) broom->fdoor++;
365 }
366
367 /* Only called from makerooms() */
368 maker(lowx,ddx,lowy,ddy)
369 schar lowx,ddx,lowy,ddy;
370 {
371         struct mkroom *croom;
372         int x, y, hix = lowx+ddx, hiy = lowy+ddy;
373         int xlim = XLIM + secret, ylim = YLIM + secret;
374
375         if(nroom >= MAXNROFROOMS) return(0);
376         if(lowx < XLIM) lowx = XLIM;
377         if(lowy < YLIM) lowy = YLIM;
378         if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
379         if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
380 chk:
381         if(hix <= lowx || hiy <= lowy) return(0);
382
383         /* check area around room (and make room smaller if necessary) */
384         for(x = lowx - xlim; x <= hix + xlim; x++) {
385                 for(y = lowy - ylim; y <= hiy + ylim; y++) {
386                         if(levl[x][y].typ) {
387 #ifdef WIZARD
388                             if(wizard && !secret)
389                                 pline("Strange area [%d,%d] in maker().",x,y);
390 #endif WIZARD
391                                 if(!rn2(3)) return(0);
392                                 if(x < lowx)
393                                         lowx = x+xlim+1;
394                                 else
395                                         hix = x-xlim-1;
396                                 if(y < lowy)
397                                         lowy = y+ylim+1;
398                                 else
399                                         hiy = y-ylim-1;
400                                 goto chk;
401                         }
402                 }
403         }
404
405         croom = &rooms[nroom];
406
407         /* on low levels the room is lit (usually) */
408         /* secret vaults are always lit */
409         if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) {
410                 for(x = lowx-1; x <= hix+1; x++)
411                         for(y = lowy-1; y <= hiy+1; y++)
412                                 levl[x][y].lit = 1;
413                 croom->rlit = 1;
414         } else
415                 croom->rlit = 0;
416         croom->lx = lowx;
417         croom->hx = hix;
418         croom->ly = lowy;
419         croom->hy = hiy;
420         croom->rtype = croom->doorct = croom->fdoor = 0;
421
422         for(x = lowx-1; x <= hix+1; x++)
423             for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
424                 levl[x][y].scrsym = '-';
425                 levl[x][y].typ = HWALL;
426         }
427         for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
428             for(y = lowy; y <= hiy; y++) {
429                 levl[x][y].scrsym = '|';
430                 levl[x][y].typ = VWALL;
431         }
432         for(x = lowx; x <= hix; x++)
433             for(y = lowy; y <= hiy; y++) {
434                 levl[x][y].scrsym = '.';
435                 levl[x][y].typ = ROOM;
436         }
437
438         smeq[nroom] = nroom;
439         croom++;
440         croom->hx = -1;
441         nroom++;
442         return(1);
443 }
444
445 makecorridors() {
446         int a,b;
447
448         nxcor = 0;
449         for(a = 0; a < nroom-1; a++)
450                 join(a, a+1);
451         for(a = 0; a < nroom-2; a++)
452             if(smeq[a] != smeq[a+2])
453                 join(a, a+2);
454         for(a = 0; a < nroom; a++)
455             for(b = 0; b < nroom; b++)
456                 if(smeq[a] != smeq[b])
457                     join(a, b);
458         if(nroom > 2)
459             for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
460                 a = rn2(nroom);
461                 b = rn2(nroom-2);
462                 if(b >= a) b += 2;
463                 join(a, b);
464             }
465 }
466
467 join(a,b)
468 int a,b;
469 {
470         coord cc,tt;
471         int tx, ty, xx, yy;
472         struct rm *crm;
473         struct mkroom *croom, *troom;
474         int dx, dy, dix, diy, cct;
475
476         croom = &rooms[a];
477         troom = &rooms[b];
478
479         /* find positions cc and tt for doors in croom and troom
480            and direction for a corridor between them */
481
482         if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
483         if(troom->lx > croom->hx) {
484                 dx = 1;
485                 dy = 0;
486                 xx = croom->hx+1;
487                 tx = troom->lx-1;
488                 cc = finddpos(xx,croom->ly,xx,croom->hy);
489                 tt = finddpos(tx,troom->ly,tx,troom->hy);
490         } else if(troom->hy < croom->ly) {
491                 dy = -1;
492                 dx = 0;
493                 yy = croom->ly-1;
494                 cc = finddpos(croom->lx,yy,croom->hx,yy);
495                 ty = troom->hy+1;
496                 tt = finddpos(troom->lx,ty,troom->hx,ty);
497         } else if(troom->hx < croom->lx) {
498                 dx = -1;
499                 dy = 0;
500                 xx = croom->lx-1;
501                 tx = troom->hx+1;
502                 cc = finddpos(xx,croom->ly,xx,croom->hy);
503                 tt = finddpos(tx,troom->ly,tx,troom->hy);
504         } else {
505                 dy = 1;
506                 dx = 0;
507                 yy = croom->hy+1;
508                 ty = troom->ly-1;
509                 cc = finddpos(croom->lx,yy,croom->hx,yy);
510                 tt = finddpos(troom->lx,ty,troom->hx,ty);
511         }
512         xx = cc.x;
513         yy = cc.y;
514         tx = tt.x - dx;
515         ty = tt.y - dy;
516         if(nxcor && levl[xx+dx][yy+dy].typ)
517                 return;
518         dodoor(xx,yy,croom);
519
520         cct = 0;
521         while(xx != tx || yy != ty) {
522             xx += dx;
523             yy += dy;
524
525             /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
526             if(cct++ > 500 || (nxcor && !rn2(35)))
527                 return;
528
529             if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
530                 return;         /* impossible */
531
532             crm = &levl[xx][yy];
533             if(!(crm->typ)) {
534                 if(rn2(100)) {
535                         crm->typ = CORR;
536                         crm->scrsym = CORR_SYM;
537                         if(nxcor && !rn2(50))
538                                 (void) mkobj_at(ROCK_SYM, xx, yy);
539                 } else {
540                         crm->typ = SCORR;
541                         crm->scrsym = ' ';
542                 }
543             } else
544             if(crm->typ != CORR && crm->typ != SCORR) {
545                 /* strange ... */
546                 return;
547             }
548
549             /* find next corridor position */
550             dix = abs(xx-tx);
551             diy = abs(yy-ty);
552
553             /* do we have to change direction ? */
554             if(dy && dix > diy) {
555                 int ddx = (xx > tx) ? -1 : 1;
556
557                 crm = &levl[xx+ddx][yy];
558                 if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
559                     dx = ddx;
560                     dy = 0;
561                     continue;
562                 }
563             } else if(dx && diy > dix) {
564                 int ddy = (yy > ty) ? -1 : 1;
565
566                 crm = &levl[xx][yy+ddy];
567                 if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
568                     dy = ddy;
569                     dx = 0;
570                     continue;
571                 }
572             }
573
574             /* continue straight on? */
575             crm = &levl[xx+dx][yy+dy];
576             if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
577                 continue;
578
579             /* no, what must we do now?? */
580             if(dx) {
581                 dx = 0;
582                 dy = (ty < yy) ? -1 : 1;
583                 crm = &levl[xx+dx][yy+dy];
584                 if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
585                     continue;
586                 dy = -dy;
587                 continue;
588             } else {
589                 dy = 0;
590                 dx = (tx < xx) ? -1 : 1;
591                 crm = &levl[xx+dx][yy+dy];
592                 if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
593                     continue;
594                 dx = -dx;
595                 continue;
596             }
597         }
598
599         /* we succeeded in digging the corridor */
600         dodoor(tt.x, tt.y, troom);
601
602         if(smeq[a] < smeq[b])
603                 smeq[b] = smeq[a];
604         else
605                 smeq[a] = smeq[b];
606 }
607
608 make_niches()
609 {
610         int ct = rnd(nroom/2 + 1);
611         while(ct--) makeniche(FALSE);
612 }
613
614 makevtele()
615 {
616         makeniche(TRUE);
617 }
618
619 makeniche(with_trap)
620 boolean with_trap;
621 {
622         struct mkroom *aroom;
623         struct rm *rm;
624         int vct = 8;
625         coord dd;
626         int dy,xx,yy;
627         struct trap *ttmp;
628
629         if(doorindex < DOORMAX)
630           while(vct--) {
631             aroom = &rooms[rn2(nroom-1)];
632             if(aroom->rtype != 0) continue;     /* not an ordinary room */
633             if(aroom->doorct == 1 && rn2(5)) continue;
634             if(rn2(2)) {
635                 dy = 1;
636                 dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1);
637             } else {
638                 dy = -1;
639                 dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1);
640             }
641             xx = dd.x;
642             yy = dd.y;
643             if((rm = &levl[xx][yy+dy])->typ) continue;
644             if(with_trap || !rn2(4)) {
645                 rm->typ = SCORR;
646                 rm->scrsym = ' ';
647                 if(with_trap) {
648                     ttmp = maketrap(xx, yy+dy, TELEP_TRAP);
649                     ttmp->once = 1;
650                     make_engr_at(xx, yy-dy, "ad ae?ar um");
651                 }
652                 dosdoor(xx, yy, aroom, SDOOR);
653             } else {
654                 rm->typ = CORR;
655                 rm->scrsym = CORR_SYM;
656                 if(rn2(7))
657                     dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
658                 else {
659                     mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
660                     if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
661                 }
662             }
663             return;
664         }
665 }
666
667 /* make a trap somewhere (in croom if mazeflag = 0) */
668 mktrap(num,mazeflag,croom)
669 int num,mazeflag;
670 struct mkroom *croom;
671 {
672         struct trap *ttmp;
673         int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0;
674         xchar mx,my;
675         extern char fut_geno[];
676
677         if(!num || num >= TRAPNUM) {
678                 nopierc = (dlevel < 4) ? 1 : 0;
679                 nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
680                 if(index(fut_geno, 'M')) nomimic = 1;
681                 kind = rn2(TRAPNUM - nopierc - nomimic);
682                 /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */
683         } else kind = num;
684
685         if(kind == MIMIC) {
686                 struct monst *mtmp;
687
688                 fakedoor = (!rn2(3) && !mazeflag);
689                 fakegold = (!fakedoor && !rn2(2));
690                 if(fakegold) goldseen = TRUE;
691                 do {
692                         if(++tryct > 200) return;
693                         if(fakedoor) {
694                                 /* note: fakedoor maybe on actual door */
695                                 if(rn2(2)){
696                                         if(rn2(2))
697                                                 mx = croom->hx+1;
698                                         else mx = croom->lx-1;
699                                         my = somey();
700                                 } else {
701                                         if(rn2(2))
702                                                 my = croom->hy+1;
703                                         else my = croom->ly-1;
704                                         mx = somex();
705                                 }
706                         } else if(mazeflag) {
707                                 extern coord mazexy();
708                                 coord mm;
709                                 mm = mazexy();
710                                 mx = mm.x;
711                                 my = mm.y;
712                         } else {
713                                 mx = somex();
714                                 my = somey();
715                         }
716                 } while(m_at(mx,my) || levl[mx][my].typ == STAIRS);
717                 if(mtmp = makemon(PM_MIMIC,mx,my)) {
718                     mtmp->mimic = 1;
719                     mtmp->mappearance =
720                         fakegold ? '$' : fakedoor ? '+' :
721                         (mazeflag && rn2(2)) ? AMULET_SYM :
722                         "=/)%?![<>" [ rn2(9) ];
723                 }
724                 return;
725         }
726
727         do {
728                 if(++tryct > 200)
729                         return;
730                 if(mazeflag){
731                         extern coord mazexy();
732                         coord mm;
733                         mm = mazexy();
734                         mx = mm.x;
735                         my = mm.y;
736                 } else {
737                         mx = somex();
738                         my = somey();
739                 }
740         } while(t_at(mx, my) || levl[mx][my].typ == STAIRS);
741         ttmp = maketrap(mx, my, kind);
742         if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC)
743                 ttmp->tseen = 1;
744 }