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