home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume2 / umoria / part14 / generate.c < prev   
C/C++ Source or Header  |  1987-11-05  |  27KB  |  1,054 lines

  1. #include "constants.h"
  2. #include "types.h"
  3. #include "externs.h"
  4.  
  5. typedef struct coords {
  6.   int x, y;
  7. } coords;
  8.  
  9. coords doorstk[100];
  10. int doorptr;
  11.  
  12.  
  13. /* Always picks a correct direction        */
  14. correct_dir(rdir, cdir, y1, x1, y2, x2)
  15. int *rdir, *cdir;
  16. int y1, x1, y2, x2;
  17. {
  18.   if (y1 < y2) 
  19.     *rdir =  1;
  20.   else if (y1 == y2) 
  21.     *rdir =  0;
  22.   else
  23.     *rdir = -1;
  24.   if (x1 < x2) 
  25.     *cdir =  1;
  26.   else if (x1 == x2) 
  27.     *cdir =  0;
  28.   else
  29.     *cdir = -1;
  30.   if ((*rdir != 0) && (*cdir != 0)) 
  31.     switch(randint(2))
  32.       {
  33.       case 1:
  34.     *rdir = 0;
  35.     break;
  36.       case 2:
  37.     *cdir = 0;
  38.     break;
  39.       }
  40. }
  41.  
  42.  
  43. /* Chance of wandering direction            */
  44. rand_dir(rdir, cdir, y1, x1, y2, x2, chance)
  45. int *rdir, *cdir;
  46. int y1, x1, y2, x2;
  47. int chance;
  48. {
  49.   switch(randint(chance))
  50.     {
  51.     case 1:
  52.       *rdir = -1;
  53.       *cdir =  0;
  54.       break;
  55.     case 2:
  56.       *rdir =  1;
  57.       *cdir =  0;
  58.       break;
  59.     case 3:
  60.       *rdir =  0;
  61.       *cdir = -1;
  62.       break;
  63.     case 4:
  64.       *rdir =  0;
  65.       *cdir =  1;
  66.       break;
  67.     default:
  68.       correct_dir(rdir, cdir, y1, x1, y2, x2);
  69.       break;
  70.     }
  71. }
  72.     
  73.  
  74. /* Blanks out entire cave                -RAK-    */
  75. blank_cave()
  76. {
  77.   int i, j;
  78.  
  79.   for (i = 0; i < MAX_HEIGHT; i++)
  80.     for (j = 0; j < MAX_WIDTH; j++)
  81.       cave[i][j] = blank_floor;
  82. }
  83.  
  84.  
  85. /* Fills in empty spots with desired rock        -RAK-    */
  86. /* Note: 9 is a temporary value.                */
  87. fill_cave(fill)
  88. floor_type fill;
  89. {
  90.   int i, j;
  91.   cave_type *c_ptr;
  92.  
  93.   for (i = 1; i < cur_height-1; i++)
  94.     for (j = 1; j < cur_width-1; j++)
  95.       {
  96.     c_ptr = &cave[i][j];
  97.     if ((c_ptr->fval == 0) || (c_ptr->fval == 8) || (c_ptr->fval == 9))
  98.       {
  99.         c_ptr->fval = fill.ftval;
  100.         c_ptr->fopen = fill.ftopen;
  101.       }
  102.       }
  103. }
  104.  
  105.  
  106. /* Places indestructible rock around edges of dungeon    -RAK-    */
  107. place_boundary()
  108. {
  109.   int i;
  110.  
  111.   for (i = 0; i < cur_height; i++)
  112.     {
  113.       cave[i][0].fval            = boundary_wall.ftval;
  114.       cave[i][0].fopen           = boundary_wall.ftopen;
  115.       cave[i][cur_width-1].fval  = boundary_wall.ftval;
  116.       cave[i][cur_width-1].fopen = boundary_wall.ftopen;
  117.     }
  118.   for (i = 0; i < cur_width; i++)
  119.     {
  120.       cave[0][i].fval             = boundary_wall.ftval;
  121.       cave[0][i].fopen            = boundary_wall.ftopen;
  122.       cave[cur_height-1][i].fval  = boundary_wall.ftval;
  123.       cave[cur_height-1][i].fopen = boundary_wall.ftopen;
  124.     }
  125. }
  126.  
  127.  
  128. /* Places "streamers" of rock through dungeon        -RAK-    */
  129. place_streamer(rock, treas_chance)
  130. floor_type rock;
  131. int treas_chance;
  132. {
  133.   int i, y, x, dir, ty, tx, t1, t2;
  134.   int flag;
  135.   cave_type *c_ptr;
  136.  
  137.   /* Choose starting point and direction        */
  138.   y = (cur_height/2.0) + 11 - randint(23);
  139.   x = (cur_width/2.0)  + 16 - randint(33);
  140.  
  141.   dir = randint(8);    /* Number 1-4, 6-9    */
  142.   if (dir > 4)
  143.     dir = dir + 1;
  144.  
  145.   /* Place streamer into dungeon            */
  146.   flag = FALSE;    /* Set to true when y, x are out-of-bounds*/
  147.   t1 = 2*DUN_STR_RNG + 1;    /* Constants    */
  148.   t2 =   DUN_STR_RNG + 1;
  149.   do
  150.     {
  151.       for (i = 0; i < DUN_STR_DEN; i++)
  152.     {
  153.       ty = y + randint(t1) - t2;
  154.       tx = x + randint(t1) - t2;
  155.       if (in_bounds(ty, tx)) 
  156.         {
  157.           c_ptr = &cave[ty][tx];
  158.           if (c_ptr->fval == rock_wall1.ftval) 
  159.         {
  160.           c_ptr->fval = rock.ftval;
  161.           c_ptr->fopen = rock.ftopen;
  162.           if (randint(treas_chance) == 1) 
  163.             place_gold(ty, tx);
  164.         }
  165.         }
  166.     }
  167.       if (!move(dir, &y, &x))
  168.     flag = TRUE;
  169.     }
  170.   while (!flag);
  171. }
  172.  
  173.  
  174. /* Place a trap with a given displacement of point    -RAK-    */
  175. vault_trap(y, x, yd, xd, num)
  176. int y, x, yd, xd, num;
  177. {
  178.   int count, y1, x1, i;
  179.   int flag;
  180.   cave_type *c_ptr;
  181.  
  182.   for (i = 0; i < num; i++)
  183.     {
  184.       flag = FALSE;
  185.       count = 0;
  186.       do
  187.     {
  188.       y1 = y - yd - 1 + randint(2*yd+1);
  189.       x1 = x - xd - 1 + randint(2*xd+1);
  190.       c_ptr = &cave[y1][x1];
  191.       if ((c_ptr->fval > 0) && (c_ptr->fval < 8) && (c_ptr->fval != 3))
  192.         if (c_ptr->tptr == 0) 
  193.           {
  194.         place_trap(y1, x1, 1, randint(MAX_TRAPA));
  195.         flag = TRUE;
  196.           }
  197.       count++;
  198.     }
  199.       while ((!flag) && (count <= 5));
  200.     }
  201. }
  202.  
  203.  
  204. /* Place a trap with a given displacement of point    -RAK-    */
  205. vault_monster(y, x, num)
  206. int y, x, num;
  207. {
  208.   int i, y1, x1;
  209.  
  210.   for (i = 0; i < num; i++)
  211.     {
  212.       y1 = y;
  213.       x1 = x;
  214.       (void) summon_monster(&y1, &x1, TRUE);
  215.     }
  216. }
  217.  
  218.  
  219. /* Builds a room at a row, column coordinate        -RAK-    */
  220. build_room(yval, xval)
  221. int yval, xval;
  222. {
  223.   int y_height, y_depth;
  224.   int x_left, x_right;
  225.   int i, j;
  226.   floor_type cur_floor;
  227.  
  228.   if (dun_level <= randint(25)) 
  229.     cur_floor = lopen_floor;    /* Floor with light    */
  230.   else
  231.     cur_floor = dopen_floor;    /* Dark floor        */
  232.   y_height = yval - randint(4);
  233.   y_depth  = yval + randint(3);
  234.   x_left   = xval - randint(11);
  235.   x_right  = xval + randint(11);
  236.   for (i = y_height; i <= y_depth; i++)
  237.     for (j = x_left; j <= x_right; j++)
  238.       {
  239.     cave[i][j].fval  = cur_floor.ftval;
  240.     cave[i][j].fopen = cur_floor.ftopen;
  241.       }
  242.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  243.     {
  244.       cave[i][x_left-1].fval   = rock_wall1.ftval;
  245.       cave[i][x_left-1].fopen  = rock_wall1.ftopen;
  246.       cave[i][x_right+1].fval  = rock_wall1.ftval;
  247.       cave[i][x_right+1].fopen = rock_wall1.ftopen;
  248.     }
  249.   for (i = x_left; i <= x_right; i++)
  250.     {
  251.       cave[y_height-1][i].fval  = rock_wall1.ftval;
  252.       cave[y_height-1][i].fopen = rock_wall1.ftopen;
  253.       cave[y_depth+1][i].fval   = rock_wall1.ftval;
  254.       cave[y_depth+1][i].fopen  = rock_wall1.ftopen;
  255.     }
  256. }
  257.  
  258.  
  259. /* Builds a room at a row, column coordinate        -RAK-    */
  260. /* Type 1 unusual rooms are several overlapping rectangular ones    */
  261. build_type1(yval, xval)
  262. int yval, xval;
  263. {
  264.   int y_height, y_depth;
  265.   int x_left, x_right;
  266.   int i0, i, j;
  267.   floor_type cur_floor;
  268.   cave_type *c_ptr;
  269.  
  270.   if (dun_level <= randint(25)) 
  271.     cur_floor = lopen_floor;    /* Floor with light    */
  272.   else
  273.     cur_floor = dopen_floor;    /* Dark floor        */
  274.   for (i0 = 0; i0 < (1 + randint(2)); i0++)
  275.     {
  276.       y_height = yval - randint(4);
  277.       y_depth  = yval + randint(3);
  278.       x_left   = xval - randint(11);
  279.       x_right  = xval + randint(11);
  280.       for (i = y_height; i <= y_depth; i++)
  281.     for (j = x_left; j <= x_right; j++)
  282.       {
  283.         cave[i][j].fval  = cur_floor.ftval;
  284.         cave[i][j].fopen = cur_floor.ftopen;
  285.       }
  286.       for (i = (y_height - 1); i <= (y_depth + 1); i++)
  287.     {
  288.       c_ptr = &cave[i][x_left-1];
  289.       if (c_ptr->fval != cur_floor.ftval) 
  290.         {
  291.           c_ptr->fval  = rock_wall1.ftval;
  292.           c_ptr->fopen = rock_wall1.ftopen;
  293.         }
  294.       c_ptr = &cave[i][x_right+1];
  295.         if (c_ptr->fval != cur_floor.ftval) 
  296.           {
  297.         c_ptr->fval  = rock_wall1.ftval;
  298.         c_ptr->fopen = rock_wall1.ftopen;
  299.           }
  300.     }
  301.       for (i = x_left; i <= x_right; i++)
  302.     {
  303.       c_ptr = &cave[y_height-1][i];
  304.       if (c_ptr->fval != cur_floor.ftval) 
  305.         {
  306.           c_ptr->fval  = rock_wall1.ftval;
  307.           c_ptr->fopen = rock_wall1.ftopen;
  308.         }
  309.       c_ptr = &cave[y_depth+1][i];
  310.         if (c_ptr->fval != cur_floor.ftval) 
  311.           {
  312.         c_ptr->fval  = rock_wall1.ftval;
  313.         c_ptr->fopen = rock_wall1.ftopen;
  314.           }
  315.     }
  316.     }
  317. }
  318.  
  319.  
  320. /* Builds an unusual room at a row, column coordinate    -RAK-    */
  321. /* Type 2 unusual rooms all have an inner room:            */
  322. /*   1 - Just an inner room with one door            */
  323. /*   2 - An inner room within an inner room            */
  324. /*   3 - An inner room with pillar(s)                */
  325. /*   4 - Inner room has a maze                    */
  326. /*   5 - A set of four inner rooms                */
  327. build_type2(yval, xval)
  328. int yval, xval;
  329. {
  330.   int y_height, y_depth;
  331.   int x_left, x_right;
  332.   int i, j;
  333.   floor_type cur_floor;
  334.  
  335.   if (dun_level <= randint(30)) 
  336.     cur_floor = lopen_floor;    /* Floor with light    */
  337.   else
  338.     cur_floor = dopen_floor;    /* Dark floor        */
  339.   y_height = yval - 4;
  340.   y_depth  = yval + 4;
  341.   x_left   = xval - 11;
  342.   x_right  = xval + 11;
  343.   for (i = y_height; i <= y_depth; i++)
  344.     for (j = x_left; j <= x_right; j++)
  345.       {
  346.     cave[i][j].fval  = cur_floor.ftval;
  347.     cave[i][j].fopen = cur_floor.ftopen;
  348.       }
  349.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  350.     {
  351.       cave[i][x_left-1].fval   = rock_wall1.ftval;
  352.       cave[i][x_left-1].fopen  = rock_wall1.ftopen;
  353.       cave[i][x_right+1].fval  = rock_wall1.ftval;
  354.       cave[i][x_right+1].fopen = rock_wall1.ftopen;
  355.     }
  356.   for (i = x_left; i <= x_right; i++)
  357.     {
  358.       cave[y_height-1][i].fval  = rock_wall1.ftval;
  359.       cave[y_height-1][i].fopen = rock_wall1.ftopen;
  360.       cave[y_depth+1][i].fval   = rock_wall1.ftval;
  361.       cave[y_depth+1][i].fopen  = rock_wall1.ftopen;
  362.     }
  363.   /* The inner room        */
  364.   y_height = y_height + 2;
  365.   y_depth  = y_depth  - 2;
  366.   x_left   = x_left   + 2;
  367.   x_right  = x_right  - 2;
  368.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  369.     {
  370.       cave[i][x_left-1].fval   = 8;
  371.       cave[i][x_right+1].fval  = 8;
  372.     }
  373.   for (i = x_left; i <= x_right; i++)
  374.     {
  375.       cave[y_height-1][i].fval  = 8;
  376.       cave[y_depth+1][i].fval   = 8;
  377.     }
  378.   /* Inner room variations        */
  379.   switch(randint(5))
  380.     {
  381.     case 1:    /* Just an inner room...    */
  382.       switch(randint(4))     /* Place a door    */
  383.     {
  384.     case 1:    place_secret_door(y_height-1, xval); break;
  385.     case 2:    place_secret_door(y_depth+1, xval); break;
  386.     case 3:    place_secret_door(yval, x_left-1); break;
  387.     case 4:    place_secret_door(yval, x_right+1); break;
  388.     }
  389.       vault_monster(yval, xval, 1);
  390.       break;
  391.     case 2:    /* Treasure Vault    */
  392.       switch(randint(4))    /* Place a door    */
  393.     {
  394.     case 1:    place_secret_door(y_height-1, xval); break;
  395.     case 2:    place_secret_door(y_depth+1, xval); break;
  396.     case 3:    place_secret_door(yval, x_left-1); break;
  397.     case 4:    place_secret_door(yval, x_right+1); break;
  398.     }
  399.       for (i = yval-1; i <= yval+1; i++)
  400.     {
  401.       cave[i][xval-1].fval   = 8;
  402.       cave[i][xval+1].fval   = 8;
  403.     }
  404.       cave[yval-1][xval].fval  = 8;
  405.       cave[yval+1][xval].fval  = 8;
  406.       switch(randint(4))    /* Place a door    */
  407.     {
  408.     case 1:    place_locked_door(yval-1, xval); break;
  409.     case 2:    place_locked_door(yval+1, xval); break;
  410.     case 3:    place_locked_door(yval, xval-1); break;
  411.     case 4:    place_locked_door(yval, xval+1); break;
  412.     }
  413.       /* Place an object in the treasure vault    */
  414.       switch(randint(10))
  415.     {
  416.     case 1: place_up_stairs(yval, xval); break;
  417.     case 2: place_down_stairs(yval, xval); break;
  418.     default: place_object(yval, xval); break;
  419.     }
  420.       /* Guard the treasure well        */
  421.       vault_monster(yval, xval, 2+randint(3));
  422.       /* If the monsters don't get 'em...    */
  423.       vault_trap(yval, xval, 4, 10, 2+randint(3));
  424.       break;
  425.     case 3:    /* Inner pillar(s)...    */
  426.       switch(randint(4))  /* Place a door    */
  427.     {
  428.     case 1:    place_secret_door(y_height-1, xval); break;
  429.     case 2:    place_secret_door(y_depth+1, xval); break;
  430.     case 3:    place_secret_door(yval, x_left-1); break;
  431.     case 4:    place_secret_door(yval, x_right+1); break;
  432.     }
  433.       for (i = yval-1; i <= yval+1; i++)
  434.     for (j = xval-1; j <= xval+1; j++)
  435.       cave[i][j].fval   = 8;
  436.       if (randint(2) == 1) 
  437.     {
  438.       switch(randint(2))
  439.         {
  440.         case 1:
  441.           for (i = yval-1; i <= yval+1; i++)
  442.         for (j = xval-6; j <= xval-4; j++)
  443.           cave[i][j].fval   = 8;
  444.           for (i = yval-1; i <= yval+1; i++)
  445.         for (j = xval+4; j <= xval+6; j++)
  446.           cave[i][j].fval   = 8;
  447.           break;
  448.         case 2:
  449.           for (i = yval-1; i <= yval+1; i++)
  450.         for (j = xval-7; j <= xval-5; j++)
  451.           cave[i][j].fval   = 8;
  452.           for (i = yval-1; i <= yval+1; i++)
  453.         for (j = xval+5; j <= xval+7; j++)
  454.           cave[i][j].fval   = 8;
  455.           break;
  456.         }
  457.     }
  458.       if (randint(3) == 1)     /* Inner rooms    */
  459.     {
  460.       for (i = xval-5; i <= xval+5; i++)
  461.         {
  462.           cave[yval-1][i].fval = 8;
  463.           cave[yval+1][i].fval = 8;
  464.         }
  465.       cave[yval][xval-5].fval = 8;
  466.       cave[yval][xval+5].fval = 8;
  467.       switch(randint(2))
  468.         {
  469.         case 1: place_secret_door(yval+1, xval-3); break;
  470.         case 2: place_secret_door(yval-1, xval-3); break;
  471.         }
  472.       switch(randint(2))
  473.         {
  474.         case 1: place_secret_door(yval+1, xval+3); break;
  475.         case 2: place_secret_door(yval-1, xval+3); break;
  476.         }
  477.       if (randint(3) == 1)  place_object(yval, xval-2);
  478.       if (randint(3) == 1)  place_object(yval, xval+2);
  479.       vault_monster(yval, xval-2, randint(2));
  480.       vault_monster(yval, xval+2, randint(2));
  481.     }
  482.       break;
  483.     case 4:    /* Maze inside...    */
  484.       switch(randint(4))    /* Place a door    */
  485.     {
  486.     case 1:    place_secret_door(y_height-1, xval); break;
  487.     case 2:    place_secret_door(y_depth+1, xval); break;
  488.     case 3:    place_secret_door(yval, x_left-1); break;
  489.     case 4:    place_secret_door(yval, x_right+1); break;
  490.     }
  491.       for (i = y_height; i <= y_depth; i++)
  492.     for (j = x_left; j <= x_right; j++)
  493.       if (0x1 & (j+i)) 
  494.         cave[i][j].fval = 8;
  495.       /* Monsters just love mazes...        */
  496.       vault_monster(yval, xval-5, randint(3));
  497.       vault_monster(yval, xval+5, randint(3));
  498.       /* Traps make them entertaining...    */
  499.       vault_trap(yval, xval-3, 2, 8, randint(3));
  500.       vault_trap(yval, xval+3, 2, 8, randint(3));
  501.       /* Mazes should have some treasure too..    */
  502.       for (i = 0; i < 3; i++)
  503.     random_object(yval, xval, 1);
  504.       break;
  505.     case 5:    /* Four small rooms...    */
  506.       for (i = y_height; i <= y_depth; i++)
  507.     cave[i][xval].fval = 8;
  508.       for (i = x_left; i <= x_right; i++)
  509.     cave[yval][i].fval = 8;
  510.       switch(randint(2))
  511.     {
  512.     case 1:
  513.       i = randint(10);
  514.       place_secret_door(y_height-1, xval-i);
  515.       place_secret_door(y_height-1, xval+i);
  516.       place_secret_door(y_depth+1, xval-i);
  517.       place_secret_door(y_depth+1, xval+i);
  518.       break;
  519.     case 2:
  520.       i = randint(3);
  521.       place_secret_door(yval+i, x_left-1);
  522.       place_secret_door(yval-i, x_left-1);
  523.       place_secret_door(yval+i, x_right+1);
  524.       place_secret_door(yval-i, x_right+1);
  525.       break;
  526.     }
  527.       /* Treasure in each one...        */
  528.       random_object(yval, xval, 2+randint(2));
  529.       /* Gotta have some monsters...        */
  530.       vault_monster(yval+2, xval-4, randint(2));
  531.       vault_monster(yval+2, xval+4, randint(2));
  532.       vault_monster(yval-2, xval-4, randint(2));
  533.       vault_monster(yval-2, xval+4, randint(2));
  534.       break;
  535.     }
  536. }
  537.  
  538.  
  539. /* Builds a room at a row, column coordinate        -RAK-    */
  540. /* Type 3 unusual rooms are cross shaped                */
  541. build_type3(yval, xval)
  542. int yval, xval;
  543. {
  544.   int y_height, y_depth;
  545.   int x_left, x_right;
  546.   int i0, i, j;
  547.   floor_type cur_floor;
  548.   cave_type *c_ptr;
  549.  
  550.   if (dun_level <= randint(25)) 
  551.     cur_floor = lopen_floor;    /* Floor with light    */
  552.   else
  553.     cur_floor = dopen_floor;    /* Dark floor        */
  554.   i0 = 2 + randint(2);
  555.   y_height = yval - i0;
  556.   y_depth  = yval + i0;
  557.   x_left   = xval - 1;
  558.   x_right  = xval + 1;
  559.   for (i = y_height; i <= y_depth; i++)
  560.     for (j = x_left; j <= x_right; j++)
  561.       {
  562.     cave[i][j].fval  = cur_floor.ftval;
  563.     cave[i][j].fopen = cur_floor.ftopen;
  564.       }
  565.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  566.     {
  567.       c_ptr = &cave[i][x_left-1];
  568.       c_ptr->fval  = rock_wall1.ftval;
  569.       c_ptr->fopen = rock_wall1.ftopen;
  570.       c_ptr = &cave[i][x_right+1];
  571.       c_ptr->fval  = rock_wall1.ftval;
  572.       c_ptr->fopen = rock_wall1.ftopen;
  573.     }
  574.   for (i = x_left; i <= x_right; i++)
  575.     {
  576.       c_ptr = &cave[y_height-1][i];
  577.       c_ptr->fval  = rock_wall1.ftval;
  578.       c_ptr->fopen = rock_wall1.ftopen;
  579.       c_ptr = &cave[y_depth+1][i];
  580.       c_ptr->fval  = rock_wall1.ftval;
  581.       c_ptr->fopen = rock_wall1.ftopen;
  582.     }
  583.   i0 = 2 + randint(9);
  584.   y_height = yval - 1;
  585.   y_depth  = yval + 1;
  586.   x_left   = xval - i0;
  587.   x_right  = xval + i0;
  588.   for (i = y_height; i <= y_depth; i++)
  589.     for (j = x_left; j <= x_right; j++)
  590.       {
  591.     cave[i][j].fval  = cur_floor.ftval;
  592.     cave[i][j].fopen = cur_floor.ftopen;
  593.       }
  594.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  595.     {
  596.       c_ptr = &cave[i][x_left-1];
  597.       if (c_ptr->fval != cur_floor.ftval) 
  598.     {
  599.       c_ptr->fval  = rock_wall1.ftval;
  600.       c_ptr->fopen = rock_wall1.ftopen;
  601.     }
  602.       c_ptr = &cave[i][x_right+1];
  603.       if (c_ptr->fval != cur_floor.ftval) 
  604.     {
  605.       c_ptr->fval  = rock_wall1.ftval;
  606.       c_ptr->fopen = rock_wall1.ftopen;
  607.     }
  608.     }
  609.   for (i = x_left; i <= x_right; i++)
  610.     {
  611.       c_ptr = &cave[y_height-1][i];
  612.       if (c_ptr->fval != cur_floor.ftval) 
  613.     {
  614.       c_ptr->fval  = rock_wall1.ftval;
  615.       c_ptr->fopen = rock_wall1.ftopen;
  616.     }
  617.       c_ptr = &cave[y_depth+1][i];
  618.       if (c_ptr->fval != cur_floor.ftval) 
  619.     {
  620.       c_ptr->fval  = rock_wall1.ftval;
  621.       c_ptr->fopen = rock_wall1.ftopen;
  622.     }
  623.     }
  624.   /* Special features...            */
  625.   switch(randint(4))
  626.     {
  627.     case 1:    /* Large middle pillar        */
  628.       for (i = yval-1; i <= yval+1; i++)
  629.     for (j = xval-1; j <= xval+1; j++)
  630.       cave[i][j].fval = 8;
  631.       break;
  632.     case 2:    /* Inner treasure vault        */
  633.       for (i = yval-1; i <= yval+1; i++)
  634.     {
  635.       cave[i][xval-1].fval   = 8;
  636.       cave[i][xval+1].fval   = 8;
  637.     }
  638.       cave[yval-1][xval].fval  = 8;
  639.       cave[yval+1][xval].fval  = 8;
  640.       switch(randint(4))    /* Place a door    */
  641.     {
  642.     case 1:    place_secret_door(yval-1, xval); break;
  643.     case 2:    place_secret_door(yval+1, xval); break;
  644.     case 3:    place_secret_door(yval, xval-1); break;
  645.     case 4:    place_secret_door(yval, xval+1); break;
  646.     }
  647.       /* Place a treasure in the vault        */
  648.       place_object(yval, xval);
  649.       /* Let's guard the treasure well...    */
  650.       vault_monster(yval, xval, 2+randint(2));
  651.       /* Traps naturally            */
  652.       vault_trap(yval, xval, 4, 4, 1+randint(3));
  653.       break;
  654.     case 3:
  655.       if (randint(3) == 1) 
  656.     {
  657.       cave[yval-1][xval-2].fval = 8;
  658.       cave[yval+1][xval-2].fval = 8;
  659.       cave[yval-1][xval+2].fval = 8;
  660.       cave[yval-1][xval+2].fval = 8;
  661.       cave[yval-2][xval-1].fval = 8;
  662.       cave[yval-2][xval+1].fval = 8;
  663.       cave[yval+2][xval-1].fval = 8;
  664.       cave[yval+2][xval+1].fval = 8;
  665.       if (randint(3) == 1) 
  666.         {
  667.           place_secret_door(yval, xval-2);
  668.           place_secret_door(yval, xval+2);
  669.           place_secret_door(yval-2, xval);
  670.           place_secret_door(yval+2, xval);
  671.         }
  672.     }
  673.       else if (randint(3) == 1) 
  674.     {
  675.       cave[yval][xval].fval = 8;
  676.       cave[yval-1][xval].fval = 8;
  677.       cave[yval+1][xval].fval = 8;
  678.       cave[yval][xval-1].fval = 8;
  679.       cave[yval][xval+1].fval = 8;
  680.     }
  681.       else if (randint(3) == 1) 
  682.     cave[yval][xval].fval = 8;
  683.       break;
  684.     case 4:
  685.       break;
  686.     }
  687. }
  688.  
  689.  
  690. /* Constructs a tunnel between two points        */
  691. build_tunnel(row1, col1, row2, col2)
  692. int row1, col1, row2, col2;
  693. {
  694.   int tmp_row, tmp_col;
  695.   int row_dir, col_dir;
  696.   int i, j;
  697.   coords tunstk[1000];
  698.   coords wallstk[1000];
  699.   int tunptr;
  700.   int wallptr;
  701.   int stop_flag, door_flag;
  702.   cave_type *c_ptr, *d_ptr;
  703.  
  704.   /* Main procedure for Tunnel            */
  705.   /* Note: 9 is a temporary value        */
  706.   stop_flag = FALSE;
  707.   door_flag = FALSE;
  708.   tunptr    = 0;
  709.   wallptr   = 0;
  710.   correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  711.   do
  712.     {
  713.       if (randint(100) > DUN_TUN_CHG) 
  714.     rand_dir(&row_dir, &col_dir, row1, col1, row2, col2, DUN_TUN_RND);
  715.       tmp_row = row1 + row_dir;
  716.       tmp_col = col1 + col_dir;
  717.       while (!in_bounds(tmp_row, tmp_col))
  718.     {
  719.       rand_dir(&row_dir, &col_dir, row1, col1, row2, col2, DUN_TUN_RND);
  720.       tmp_row = row1 + row_dir;
  721.       tmp_col = col1 + col_dir;
  722.     }
  723.       c_ptr = &cave[tmp_row][tmp_col];
  724.       if (c_ptr->fval == rock_wall1.ftval)
  725.     {
  726.       row1 = tmp_row;
  727.       col1 = tmp_col;
  728.       wallstk[wallptr].y = row1;
  729.       wallstk[wallptr].x = col1;
  730.       if (wallptr < 1000) 
  731.         wallptr++;
  732.       for (i = row1-1; i <= row1+1; i++)
  733.         for (j = col1-1; j <= col1+1; j++)
  734.           if (in_bounds(i, j)) 
  735.         {
  736.           d_ptr = &cave[i][j];
  737.           if ((d_ptr->fval >= 10) && (d_ptr->fval <= 12))
  738.             d_ptr->fval = 9;
  739.         }
  740.     }
  741.       else if (c_ptr->fval == corr_floor1.ftval) 
  742.     {
  743.       row1 = tmp_row;
  744.       col1 = tmp_col;
  745.       if (!door_flag) 
  746.         {
  747.           if (doorptr <= 100) 
  748.         {
  749.           doorstk[doorptr].y = row1;
  750.           doorstk[doorptr].x = col1;
  751.           doorptr++;
  752.         }
  753.           door_flag = TRUE;
  754.         }
  755.       if (randint(100) > DUN_TUN_CON) 
  756.         stop_flag = TRUE;
  757.     }
  758.       else if (c_ptr->fval == 0) 
  759.     {
  760.       row1 = tmp_row;
  761.       col1 = tmp_col;
  762.       tunstk[tunptr].y = row1;
  763.       tunstk[tunptr].x = col1;
  764.       if (tunptr < 1000) 
  765.         tunptr++;
  766.       door_flag = FALSE;
  767.     }
  768.       else if (c_ptr->fval != 9) 
  769.     {
  770.       row1 = tmp_row;
  771.       col1 = tmp_col;
  772.     }
  773.     }
  774.   while (((row1 != row2) || (col1 != col2)) && (!stop_flag));
  775.   for (i = 0; i < tunptr; i++)
  776.     {
  777.       cave[tunstk[i].y][tunstk[i].x].fval  = corr_floor1.ftval;
  778.       cave[tunstk[i].y][tunstk[i].x].fopen = corr_floor1.ftopen;
  779.     }
  780.   for (i = 0; i < wallptr; i++)
  781.     {
  782.       c_ptr = &cave[wallstk[i].y][wallstk[i].x];
  783.       if (c_ptr->fval == 9) 
  784.     {
  785.       if (randint(100) < DUN_TUN_PEN) 
  786.         place_door(wallstk[i].y, wallstk[i].x);
  787.       else
  788.         {
  789.           c_ptr->fval  = corr_floor2.ftval;
  790.           c_ptr->fopen = corr_floor2.ftopen;
  791.         }
  792.     }
  793.     }
  794. }
  795.  
  796.  
  797. int next_to(y, x)
  798. int y, x;
  799. {
  800.   int next;
  801.  
  802.   if (next_to8(y, x, 4, 5, 6) > 2) 
  803.     if (((cave[y-1][x].fval >= 10) && (cave[y-1][x].fval <= 12)) && 
  804.     ((cave[y+1][x].fval >= 10) && (cave[y+1][x].fval <= 12)))
  805.       next = TRUE;
  806.     else if (((cave[y][x-1].fval >= 10) && (cave[y][x-1].fval <= 12)) &&
  807.          ((cave[y][x+1].fval >= 10) && (cave[y][x+1].fval <= 12)))
  808.       next = TRUE;
  809.     else
  810.       next = FALSE;
  811.   else
  812.     next = FALSE;
  813.   return(next);
  814. }
  815.  
  816. /* Places door at y, x position if at least 2 walls found    */
  817. try_door(y, x)
  818. int y, x;
  819. {
  820.   if (randint(100) > DUN_TUN_JCT) 
  821.     if (cave[y][x].fval == corr_floor1.ftval) 
  822.       if (next_to(y, x)) 
  823.     place_door(y, x);
  824. }
  825.  
  826.  
  827. /* Cave logic flow for generation of new dungeon        */
  828. cave_gen()
  829. {
  830.   struct spot_type
  831.     {
  832.       int endx;
  833.       int endy;
  834.     };
  835.   int room_map[20][20];
  836.   int i, j, k, l;
  837.   int y1, x1, y2, x2;
  838.   int pick1, pick2;
  839.   int row_rooms, col_rooms;
  840.   int alloc_level;
  841.   worlint yloc[400];
  842.   worlint xloc[400];
  843.  
  844.   int set_1_2();
  845.   int set_1_2_4();
  846.   int set_4();
  847.  
  848.   row_rooms = 2*(cur_height/SCREEN_HEIGHT);
  849.   col_rooms = 2*(cur_width /SCREEN_WIDTH);
  850.   for (i = 0; i < row_rooms; i++)
  851.     for (j = 0; j < col_rooms; j++)
  852.       room_map[i][j] = FALSE;
  853.   for (i = 0; i < randnor(DUN_ROO_MEA, 2); i++)
  854.     room_map[randint(row_rooms)-1][randint(col_rooms)-1] = TRUE;
  855.   k = 0;
  856.   for (i = 0; i < row_rooms; i++)
  857.     for (j = 0; j < col_rooms; j++)
  858.       if (room_map[i][j] == TRUE) 
  859.     {
  860.       yloc[k] = i * (quart_height * 2 + 1) + quart_height;
  861.       xloc[k] = j * (quart_width * 2 + 1) + quart_width;
  862.       if (dun_level > randint(DUN_UNUSUAL)) 
  863.         switch(randint(3))
  864.           {
  865.           case 1: build_type1(yloc[k], xloc[k]); break;
  866.           case 2: build_type2(yloc[k], xloc[k]); break;
  867.           case 3: build_type3(yloc[k], xloc[k]); break;
  868.           }
  869.       else
  870.         build_room(yloc[k], xloc[k]);
  871.       k++;
  872.     }
  873.   for (l = 0; l < k; l++)
  874.     {
  875.       pick1 = randint(k) - 1;
  876.       pick2 = randint(k) - 1;
  877.       y1 = yloc[pick1];
  878.       x1 = xloc[pick1];
  879.       yloc[pick1] = yloc[pick2];
  880.       xloc[pick1] = xloc[pick2];
  881.       yloc[pick2] = y1;
  882.       xloc[pick2] = x1;
  883.       }
  884.   doorptr = 0;
  885.   for (l = 0; l < k-1; l++)
  886.     {
  887.       y1 = yloc[l];
  888.       x1 = xloc[l];
  889.       y2 = yloc[l+1];
  890.       x2 = xloc[l+1];
  891.       build_tunnel(y2, x2, y1, x1);
  892.       }
  893.   fill_cave(rock_wall1);
  894.   for (i = 0; i < DUN_STR_MAG; i++)
  895.     place_streamer(rock_wall2, DUN_STR_MC);
  896.   for (i = 0; i < DUN_STR_QUA; i++)
  897.     place_streamer(rock_wall3, DUN_STR_QC);
  898.   place_boundary();
  899.   /* Place intersection doors    */
  900.   for (i = 0; i < doorptr; i++)
  901.     {
  902.       try_door(doorstk[i].y, doorstk[i].x-1);
  903.       try_door(doorstk[i].y, doorstk[i].x+1);
  904.       try_door(doorstk[i].y-1, doorstk[i].x);
  905.       try_door(doorstk[i].y+1, doorstk[i].x);
  906.     }
  907.   alloc_level = (dun_level/3);
  908.   if (alloc_level < 2) 
  909.     alloc_level = 2;
  910.   else if (alloc_level > 10) 
  911.     alloc_level = 10;
  912.   place_stairs(2, randint(2)+2, 3);
  913.   place_stairs(1, randint(2), 3);
  914.   alloc_monster(set_1_2, (randint(8)+MIN_MALLOC_LEVEL+alloc_level), 0, TRUE);
  915.   alloc_object(set_4, 3, randint(alloc_level));
  916.   alloc_object(set_1_2, 5, randnor(TREAS_ROOM_ALLOC, 3));
  917.   alloc_object(set_1_2_4, 5, randnor(TREAS_ANY_ALLOC, 3));
  918.   alloc_object(set_1_2_4, 4, randnor(TREAS_GOLD_ALLOC, 3));
  919.   alloc_object(set_1_2_4, 1, randint(alloc_level));
  920.   if (dun_level >= WIN_MON_APPEAR)  place_win_monster();
  921. }
  922.  
  923.  
  924. /* Builds a store at a row, column coordinate            */
  925. build_store(store_num, y, x)
  926. int store_num, y, x;
  927. {
  928.   int yval, y_height, y_depth;
  929.   int xval, x_left, x_right;
  930.   int i, j, cur_pos;
  931.   cave_type *c_ptr;
  932.  
  933.   yval       = y*10 + 5;
  934.   xval     = x*16 + 16;
  935.   y_height = yval - randint(3);
  936.   y_depth  = yval + randint(4);
  937.   x_left   = xval - randint(6);
  938.   x_right  = xval + randint(6);
  939.   for (i = y_height; i <= y_depth; i++)
  940.     for (j = x_left; j <= x_right; j++)
  941.       {
  942.     cave[i][j].fval  = boundary_wall.ftval;
  943.     cave[i][j].fopen = boundary_wall.ftopen;
  944.       }
  945.   switch(randint(4))
  946.     {
  947.     case 1:
  948.       i = randint(y_depth-y_height) + y_height - 1;
  949.       j = x_left;
  950.       break;
  951.     case 2:
  952.       i = randint(y_depth-y_height) + y_height - 1;
  953.       j = x_right;
  954.       break;
  955.     case 3:
  956.       i = y_depth;
  957.       j = randint(x_right-x_left) + x_left - 1;
  958.       break;
  959.     case 4:
  960.       i = y_height;
  961.       j = randint(x_right-x_left) + x_left - 1;
  962.       break;
  963.     }
  964.   c_ptr = &cave[i][j];
  965.   c_ptr->fval  = corr_floor3.ftval;
  966.   c_ptr->fopen = corr_floor3.ftopen;
  967.   popt(&cur_pos);
  968.   c_ptr->tptr = cur_pos;
  969.   t_list[cur_pos] = store_door[store_num];
  970. }
  971.  
  972.  
  973. /* Town logic flow for generation of new town        */
  974. town_gen()
  975. {
  976.   int i, j, k, l, m;
  977.   int rooms[6];
  978.  
  979.   int set_1_2();
  980.  
  981.   set_seed(town_state, town_seed);
  982.   for (i = 0; i < 6; i++)
  983.     rooms[i] = i;
  984.   l = 6;
  985.   for (i = 0; i < 2; i++)
  986.     for (j = 0; j < 3; j++)
  987.       {
  988.     k = randint(l) - 1;
  989.     build_store(rooms[k], i, j);
  990.     for (m = k; m < l-1; m++)
  991.       rooms[m] = rooms[m+1];
  992.     l--;
  993.       }
  994.   fill_cave(dopen_floor);
  995.   place_boundary();
  996.   reset_seed();
  997.   if (0x1 & (turn / 5000)) 
  998.     {        /* Night    */
  999.       for (i = 0; i < cur_height; i++)
  1000.     for (j = 0; j < cur_width; j++)
  1001.       if (cave[i][j].fval != dopen_floor.ftval) 
  1002.         cave[i][j].pl = TRUE;
  1003.       place_stairs(2, 1, 0);
  1004.       alloc_monster(set_1_2, MIN_MALLOC_TN, 3, TRUE);
  1005.       store_maint();
  1006.     }
  1007.   else
  1008.     {        /* Day    */
  1009.       for (i = 0; i < cur_height; i++)
  1010.     for (j = 0; j < cur_width; j++)
  1011.       cave[i][j].pl = TRUE;
  1012.       place_stairs(2, 1, 0);
  1013.       alloc_monster(set_1_2, MIN_MALLOC_TD, 3, TRUE);
  1014.       store_maint();
  1015.     }
  1016. }
  1017.  
  1018.  
  1019. /* Generates a random dungeon level            -RAK-    */
  1020. generate_cave()
  1021. {
  1022.   panel_row_min    = 0;
  1023.   panel_row_max    = 0;
  1024.   panel_col_min    = 0;
  1025.   panel_col_max    = 0;
  1026.   char_row        = -1;
  1027.   char_col        = -1;
  1028.  
  1029.   tlink();
  1030.   mlink();
  1031.   blank_cave();
  1032.  
  1033.   if (dun_level == 0) 
  1034.     {
  1035.       cur_height = SCREEN_HEIGHT;
  1036.       cur_width  = SCREEN_WIDTH;
  1037.       max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1038.       max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1039.       panel_row = max_panel_rows;
  1040.       panel_col = max_panel_cols;
  1041.       town_gen();
  1042.     }
  1043.   else
  1044.     {
  1045.       cur_height = MAX_HEIGHT;
  1046.       cur_width  = MAX_WIDTH;
  1047.       max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1048.       max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1049.       panel_row = max_panel_rows;
  1050.       panel_col = max_panel_cols;
  1051.       cave_gen();
  1052.     }
  1053. }
  1054.