home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 1 / src / mklev.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-07-26  |  16.4 KB  |  740 lines

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