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