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