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