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