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