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