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