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