home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / misc / 39 / mklev.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-07-17  |  20.1 KB  |  882 lines

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