home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / XBD2_SRC.ZIP / XBD2_SRC / FIELD.C < prev    next >
C/C++ Source or Header  |  1991-02-10  |  15KB  |  631 lines

  1. /*********************************************/
  2. /* you just keep on pushing my luck over the */
  3. /*           BOULDER        DASH             */
  4. /*                                           */
  5. /*     Jeroen Houttuin, ETH Zurich, 1990     */
  6. /*                                           */
  7. /*                                           */
  8. /*      PC-VGA version from :                */
  9. /*                                           */
  10. /*        Herve SOULARD, Paris, 1990        */
  11. /*                                           */
  12. /*********************************************/
  13.  
  14. #include <stdio.h>
  15. #include <signal.h>
  16. #include <time.h>
  17. #include <sys/timeb.h>
  18.  
  19. #include "xbd.h"
  20.  
  21. #define blink(i,j)    field[i][j].changed = TRUE;
  22.  
  23.  
  24. void move_cell(i, j, ii, jj)
  25. int    i, j, ii, jj;
  26. {
  27.     field[ii][jj] = field[i][j];
  28.     field[ii][jj].speed = 1;
  29.     field[ii][jj].changed = TRUE;
  30.     field[ii][jj].dir = ((ii - i) == 1) ? S : ((i - ii) == 1) ? 
  31.                                          N : ((jj - j) == 1) ? E : W;
  32.     set_cell(i, j, SPACE);
  33. }
  34.  
  35.  
  36. void    explode(a, b, stage)
  37. int    a, b, stage;
  38. {
  39.   if (field[a][b].content != STEEL) {
  40.       set_cell(a, b, EXPLOSION);
  41.       field[a][b].stage = stage;/* dirty fix, not what stage was meant for */
  42.   }
  43. }
  44.  
  45.  
  46. Bool move_nucbal(i, j, t)
  47. int    i, j, t;
  48. {
  49.     ii = (!t) ? (i + y - 1) % y : i;
  50.     if (!t)
  51.         jj = j;
  52.     else
  53.         switch (field[i][j].dir) {
  54.             case E:
  55.                 jj = (t == 1) ? (j + x - 1) % x : (j + 1) % x;
  56.                 break;
  57.             case W:
  58.             default:
  59.                 jj = (t == 2) ? (j + x - 1) % x : (j + 1) % x;
  60.                 break;
  61.         }
  62.     switch (field[ii][jj].content) {
  63.         case SPACE:
  64.             move_cell(i, j, ii, jj);
  65.             return (TRUE);
  66.         case NUCBAL:
  67.             explode(i, j, DIAEXPLO);
  68.             explode(ii, jj, DIAEXPLO);
  69.             return (TRUE);
  70.         default:
  71.             if (field[i][j].dir == N)
  72.                 field[i][j].dir = E;
  73.             else
  74.                 field[i][j].dir = ((field[i][j].dir + 2) % 4);
  75.             return (FALSE);
  76.     }
  77. }
  78.  
  79.  
  80. Bool move_monster(content, direction)
  81. char    content, direction;
  82. {
  83.     switch (direction) {
  84.         case N:    
  85.             ii = (i + y - 1) % y;
  86.             jj    = j;
  87.             break;
  88.         case E:
  89.             jj = (j + 1) % x;
  90.             ii = i;
  91.             break;
  92.         case S:
  93.             ii = (i + 1) % y;
  94.             jj = j;
  95.             break;
  96.         default:
  97.             jj = (j + x - 1) % x;
  98.             ii = i;
  99.             break;            /* default must be SOMEthing, West */
  100.     }
  101.     switch (field[ii][jj].content) {
  102.         case SPACE:
  103.             if (!field[ii][jj].changed) {
  104.                 move_cell(i, j, ii, jj);
  105.                 field[ii][jj].dir = direction;
  106.                 return (TRUE);
  107.             } 
  108.             else
  109.                 return (FALSE);
  110.             break;
  111.         case BOULDER:
  112.         case DIAMOND:
  113.             if ((direction == N) && (field[ii][jj].speed != 0))
  114.                 if (content == RMONSTER) {
  115.                     explode(i, j, DIAEXPLO);
  116.                     return (TRUE);
  117.                 } 
  118.                 else 
  119.                     if (content == LMONSTER) {
  120.                         explode(i, j, SPACEEXPLO);
  121.                         return (TRUE);
  122.                     } 
  123.                     else
  124.                         return (FALSE);
  125.             else
  126.                 return (FALSE);
  127.             break;
  128.         default:
  129.             return (FALSE);
  130.             break;
  131.     }
  132.     return (FALSE);
  133. }
  134.  
  135.  
  136. Bool search_destroy(content)
  137. char    content;
  138. {
  139.     ii = (i + y - 1) % y;
  140.     jj = (j + x - 1) % x;
  141.     if (field[i][jj].content == PLAYER || field[i][jj].content == BLOB) {
  142.         set_cell(i, j, SPACE);
  143.         if (field[i][jj].content == PLAYER) {
  144.             lives--;
  145.             scoreobs = TRUE;
  146.         }
  147.         if (content == RMONSTER)
  148.             explode(i, jj, DIAEXPLO);
  149.         else
  150.             explode(i, jj, SPACEEXPLO);
  151.         return (TRUE);
  152.     } 
  153.     else 
  154.         if (field[ii][j].content == PLAYER || field[ii][j].content == BLOB) {
  155.             set_cell(i, j, SPACE);
  156.             if (field[ii][j].content == PLAYER) {
  157.                 lives--;
  158.                 scoreobs = TRUE;
  159.             }
  160.             if (content == RMONSTER)
  161.                 explode(ii, j, DIAEXPLO);
  162.             else
  163.                 explode(ii, j, SPACEEXPLO);
  164.             return (TRUE);
  165.         }
  166.         else {
  167.             ii = (i + 1) % y;
  168.             jj = (j + 1) % x;
  169.             if (field[i][jj].content == PLAYER || field[i][jj].content == BLOB) {
  170.                 set_cell(i, j, SPACE);
  171.                 if (field[i][jj].content == PLAYER) {
  172.                     lives--;
  173.                     scoreobs = TRUE;
  174.                 }
  175.                 if (content == RMONSTER)
  176.                     explode(i, jj, DIAEXPLO);
  177.                 else
  178.                     explode(i, jj, SPACEEXPLO);
  179.                 return (TRUE);
  180.             } 
  181.             else 
  182.                 if (field[ii][j].content == PLAYER || field[ii][j].content == BLOB) {
  183.                     set_cell(i, j, SPACE);
  184.                     if (field[ii][j].content == PLAYER) {
  185.                         lives--;
  186.                         scoreobs = TRUE;
  187.                     }
  188.                     if (content == RMONSTER)
  189.                         explode(ii, j, DIAEXPLO);
  190.                     else
  191.                         explode(ii, j, SPACEEXPLO);
  192.                     return (TRUE);
  193.                 } 
  194.                 else
  195.                     return (FALSE);
  196.             }
  197.     }
  198.  
  199. void propagate(i, j, dias)
  200. int             i, j;
  201. Bool            dias;
  202. {
  203.     int    t, it, jt;
  204.     if (dias)
  205.         set_cell(i, j, DIAMOND);
  206.     else {
  207.         field[i][j].checked = PROPAGATED;
  208.         field[i][j].caught = TRUE;
  209.     }
  210.     for (t = 0; (t < 4); ++t) {
  211.         it = (t == 1) ? (i + y - 1) % y : (t == 3) ? (i + 1) % y : i;
  212.         jt = (t == 2) ? (j + x - 1) % x : (t == 0) ? (j + 1) % x : j;    
  213.         switch (field[it][jt].content) {
  214.             case BLOB:
  215.                 if (field[it][jt].checked != PROPAGATED)
  216.                     propagate(it, jt, dias);
  217.                 break;
  218.             case SPACE:
  219.             case GRASS:
  220.                 if (!(rand() % (blobbreak + 1))) {
  221.                     set_cell(it, jt, BLOB);
  222.                     field[it][jt].checked = PROPAGATED;
  223.                     field[it][jt].caught = TRUE;
  224.                 }
  225.                 break;
  226.             default:
  227.                 break;
  228.         }
  229.     }    
  230. }
  231.  
  232.  
  233. Bool caught(i, j)
  234. int    i, j;
  235. {
  236.     Bool    Free;
  237.     int    t, it, jt;
  238.  
  239.     field[i][j].checked = 1;
  240.     Free = FALSE;
  241.  
  242.     for (t = 0; ((t < 4) && !Free); ++t) {
  243.         it = (t == 1) ? (i + y - 1) % y : (t == 3) ? (i + 1) % y : i;
  244.         jt = (t == 2) ? (j + x - 1) % x : (t == 0) ? (j + 1) % x : j;
  245.         
  246.         switch (field[it][jt].content) {
  247.             case SPACE:
  248.             case GRASS:
  249.             case RMONSTER:
  250.             case LMONSTER:
  251.             case EATER:
  252.                 Free = TRUE;
  253.                 break;
  254.             case BLOB:
  255.                 Free = (Free || ((field[it][jt].checked == 1) ? 
  256.                                  !field[i][j].caught : !caught(it, jt)));
  257.                 break;
  258.             default:
  259.                 break;
  260.         }
  261.     }
  262.     field[i][j].caught != Free;
  263.     return (!Free);
  264. }
  265.  
  266.  
  267. void diaboulderproc(i, j)
  268. int    i, j;
  269. {
  270.     
  271.     if (field[i][j].content == DIAMOND)
  272.         blink(i, j);
  273.     
  274.     ii = (ii + 1) % y;
  275.     field[i][j].dir = NODIR;
  276.     switch (field[ii][j].content) {
  277.         case SPACE:            /* directly underneath */
  278.             move_cell(i, j, ii, j);
  279.             field[ii][j].speed = 1;
  280.             break;
  281.         case PLAYER:
  282.             if (field[i][j].speed) {
  283.                 set_cell(i, j, SPACE);
  284.                 explode(ii, j, SPACEEXPLO);
  285.                 lives--;
  286.                 scoreobs = TRUE;
  287.             }
  288.             break;
  289.         case LMONSTER:
  290.         case EATER:
  291.             if (field[i][j].speed) {
  292.                 set_cell(i, j, SPACE);
  293.                 explode(ii, j, SPACEEXPLO);
  294.             }
  295.             break;
  296.         case RMONSTER:
  297.             if (field[i][j].speed) {
  298.                 set_cell(i, j, SPACE);
  299.                 explode(ii, j, DIAEXPLO);
  300.             }
  301.             break;
  302.         case TINKLE:
  303.             if (field[i][j].speed) {
  304.                 tinkact = TRUE;
  305.                 field[ii][j].stage = field[i][j].content;
  306.                 field[ii][j].speed = 1;
  307.                 set_cell(i, j, SPACE);
  308.                 break;
  309.             }
  310.             break;
  311.         case WALL:
  312.         case BOULDER:
  313.         case DIAMOND:
  314.         case EXPLOSION:
  315.             jj = (j + 1) % x;
  316.             if (field[i][jj].content == SPACE && field[ii][jj].content == SPACE) {
  317.                 move_cell(i, j, i, jj);
  318.                 field[i][jj].speed = 0;
  319.             } 
  320.             else {
  321.                 jj = (j - 1) % x;
  322.                 if (field[i][jj].content == SPACE && field[ii][jj].content == SPACE) {
  323.                     move_cell(i, j, i, jj);
  324.                     field[i][jj].speed = 0;
  325.                 }
  326.                 else
  327.                     field[i][j].speed = 0;
  328.             }
  329.             break;
  330.         default:
  331.             field[i][j].speed = 0;
  332.             break;
  333.     }
  334. }
  335.  
  336.  
  337. void calculate_field()
  338. {
  339.     players = 0;
  340.  
  341.     /* Iterate through each horizontal line */
  342.     if (!curtime)
  343.         curorder = KILL;
  344.     for (i = y - 1; i >= 0; --i) {
  345.         for (j = 0; j < x; ++j) {
  346.             if (!(field[i][j].changed)) {
  347.                 ii = i;
  348.                 jj = j;
  349.                 switch (field[i][j].content) {
  350.                     case PLAYER:
  351.                         players++;
  352.                         switch (curorder) {
  353.                             case STAND:
  354.                                 break;
  355.                             case UP:
  356.                                 ii = (i + y - 1) % y;
  357.                                 break;
  358.                             case DOWN:
  359.                                 ii = (i + 1) % y;
  360.                                 break;
  361.                             case LEFT:
  362.                                 jj = (j + x - 1) % x;
  363.                                 break;
  364.                             case RIGHT:
  365.                                 jj = (j + 1) % x;
  366.                                 break;
  367.                         }
  368.                         if (!(curorder == STAND) && !(field[i][j].changed)) {
  369.                             if (curorder == KILL) {
  370.                                 set_cell(i, j, EXPLOSION);
  371.                                 lives--;
  372.                                 scoreobs = TRUE;
  373.                                 break;
  374.                             }
  375.                             switch (field[ii][jj].content) {
  376.                                 case SPACE:
  377.                                 case GRASS:
  378.                                 case DIAMOND:
  379.                                     if (field[ii][jj].content == DIAMOND) {
  380.                                         playSound(sndWhizz);
  381.                                         if (curorder == UP && field[ii][jj].speed)
  382.                                             break;
  383.                                         score += diapoints;
  384.                                         if (diareq)
  385.                                             diareq--;
  386.                                         scoreobs = TRUE;
  387.                                     }
  388.                                     if (steal)
  389.                                         set_cell(ii, jj, SPACE);
  390.                                     else
  391.                                         move_cell(i, j, ii, jj);
  392.                                     break;
  393.                                 case BOULDER:
  394.                                     jjj = (2 * jj - j + x) % x;
  395.                                     if (field[i][jjj].content == SPACE && 
  396.                                         ((rand() % 2) == 0) &&    
  397.                                         !(field[ii][jj].dir == E))    {
  398.                                         move_cell(i, jj, i, jjj);
  399.                                         field[i][jjj].speed = 0;
  400.                                         if (!steal) {
  401.                                             move_cell(i, j, i, jj);
  402.                                         }
  403.                                     }
  404.                                     break;
  405.                                 case EXIT:
  406.                                     if (diareq < 1) {
  407.                                         if (!steal)
  408.                                             move_cell(i, j, ii, jj);
  409.                                         else
  410.                                             set_cell(ii, jj, SPACE);
  411.                                         if (!levincreased) {
  412.                                             playSound(sndYahoo);
  413.                                             levelnum++;
  414.                                             lives++;
  415.                                             levincreased = TRUE;
  416.                                             for (jj = curtime / 10; jj > 0; --jj) {
  417.                                                 score += 10;
  418.                                                 draw_score();
  419.                                             }
  420.                                         }
  421.                                         gamestop = TRUE;
  422.                                         stoplevel = TRUE;
  423.                                     }
  424.                                     break;
  425.                             }
  426.                         }
  427.                         blink(i, j);
  428.                         break;
  429.                     case DIAMOND:
  430.                     case BOULDER:
  431.                         diaboulderproc(i, j);
  432.                         break;
  433.                     case EATER:
  434.                         if (!field[i][j].speed) {
  435.                             for (jjj = 0; ((!field[i][j].changed) && (jjj < 4)); ++jjj) {
  436.                                 ii = (jjj == 2) ? (i + 1) % y : (jjj == 0) ? (i + y - 1) % y : i;
  437.                                 jj = (jjj == 1) ? (j + 1) % x : (jjj == 3) ? (j + x - 1) % x : j;
  438.                                 switch (field[ii][jj].content) {
  439.                                     case PLAYER:
  440.                                         lives--;
  441.                                         scoreobs = TRUE;
  442.                                     case DIAMOND:
  443.                                         if (field[ii][jj].speed && (ii == i - 1) && (jj == j))
  444.                                             break;
  445.                                     case BLOB:
  446.                                     case LMONSTER:
  447.                                     case RMONSTER:
  448.                                     case NUCBAL:
  449.                                         move_cell(i, j, ii, jj);
  450.                                         break;
  451.                                     default:
  452.                                         break;
  453.                                 }
  454.                             }
  455.                         }
  456.                         else {
  457.                             jjj = field[i][j].dir;
  458.                             ii = (jjj == 2) ? (i + 1) % y : (jjj == 0) ? (i + y - 1) % y : i;
  459.                             jj = (jjj == 1) ? (j + 1) % x : (jjj == 3) ? (j + x - 1) % x : j;
  460.                             switch (field[ii][jj].content) {
  461.                                 case LMONSTER:
  462.                                 case BLOB:
  463.                                 case SPACE:
  464.                                 case GRASS:
  465.                                 case DIAMOND:
  466.                                 case RMONSTER:
  467.                                 case PLAYER:
  468.                                 case NUCBAL:
  469.                                     if (field[ii][jj].content == PLAYER) {
  470.                                         lives--;
  471.                                         scoreobs = TRUE;
  472.                                     }
  473.                                     move_cell(i, j, ii, jj);
  474.                                     break;
  475.                                 case BOULDER:
  476.                                     jjj = (2 * jj - j + x) % x;
  477.                                     if (field[i][jjj].content == SPACE && 
  478.                                          ((rand() % 2) == 0) && 
  479.                                          !(field[ii][jj].dir == E)) {
  480.                                          move_cell(i, jj, i, jjj);
  481.                                          move_cell(i, j, i, jj);
  482.                                      }
  483.                                      else
  484.                                          field[i][j].speed = 0;
  485.                                      break;
  486.                                 default:
  487.                                     field[i][j].speed = 0;
  488.                                     break;
  489.                             }
  490.                         }
  491.                         blink(i, j);
  492.                         break;
  493.                     case RMONSTER:
  494.                         blink(i, j);
  495.                         if (search_destroy(RMONSTER))
  496.                             break;
  497.                         jjj =    3;
  498.                         while (jjj >= 0 && !move_monster(RMONSTER, (field[i][j].dir + jjj + 2) % 4))
  499.                             jjj--;
  500.                         break;
  501.                     case LMONSTER:
  502.                         blink(i, j);
  503.                         if (search_destroy(LMONSTER))
  504.                             break;
  505.                         jjj = 0;
  506.                         while (jjj <= 4 && !move_monster(LMONSTER, (field[i][j].dir + jjj + 3) % 4))
  507.                             jjj++;
  508.                         break;
  509.                     case EXPLOSION:
  510.                         playSound(sndExplode);
  511.                         jjj = field[i][j].stage;
  512.                         if (!(jjj % 5)) {
  513.                             jjj++;        /* use jjj for setting new stage */
  514.                             ii = (i + 1) % y;
  515.                             jj = (j + 1) % x;
  516.                             explode(i, j, jjj);
  517.                             explode(i, jj, jjj);
  518.                             explode(ii, j, jjj);
  519.                             explode(ii, jj, jjj);
  520.                             ii = (i + y - 1) % y;
  521.                             explode(ii, j, jjj);
  522.                             explode(ii, jj, jjj);
  523.                             jj = (j + x - 1) % x;
  524.                             explode(ii, jj, jjj);
  525.                             explode(i, jj, jjj);
  526.                             ii = (i + 1) % y;
  527.                             explode(ii, jj, jjj);
  528.                         }
  529.                         else {
  530.                             if (jjj % 10 < 3)
  531.                                 field[i][j].stage++;
  532.                             else 
  533.                                 if (jjj > DIAEXPLO) {
  534.                                     set_cell(i, j, DIAMOND);
  535.                                 } 
  536.                                 else 
  537.                                     if (jjj > BOULDEXPLO) {
  538.                                         set_cell(i, j, BOULDER);
  539.                                     }
  540.                                     else
  541.                                         if (jjj > SPACEEXPLO) {
  542.                                             set_cell(i, j, SPACE);
  543.                                         }
  544.                                         else
  545.                                             field[i][j].stage++;
  546.                         }
  547.                         break;
  548.                     case EXIT:
  549.                         blink(i, j);
  550.                         break;
  551.                     case BLOB:
  552.                         blobcells++;
  553.                         if (blobcollapse)
  554.                             set_cell(i, j, BOULDER);
  555.                         else {
  556.                             if (blobcells > critical)
  557.                                 blobcollapse = TRUE;
  558.                             else {
  559.                                 if (!field[i][j].checked) {
  560.                                     if (caught(i, j))
  561.                                         propagate(i, j, DIAMOND);
  562.                                     else
  563.                                         propagate(i, j, FALSE);
  564.                                 }
  565.                                 field[i][j].checked = FALSE;
  566.                                 field[i][j].caught = TRUE;
  567.                             }
  568.                         }
  569.                         blink(i, j);
  570.                         break;
  571.                     case NUCBAL:
  572.                         for (jjj = 0; ((jjj < 3) && !move_nucbal(i, j, jjj)); ++jjj);
  573.                         blink(i, j);
  574.                         break;
  575.                     case MAGICWALL:
  576.                         jj = (j + x - 1) % x;
  577.                         if (field[i][jj].content == SPACE)
  578.                             set_cell(i, jj, MAGICWALL);
  579.                         jj = (j + 1) % x;
  580.                         if (field[i][jj].content == SPACE)
  581.                             set_cell(i, jj, MAGICWALL);
  582.                         break;
  583.                     case TINKLE:
  584.                         if (tinkact) {
  585.                             blink(i, j);
  586.                             if (tinkdur > 0) {
  587.                                 switch (field[i][j].stage) {
  588.                                     case BOULDER:
  589.                                         {
  590.                                             field[i][j].content = DIAMOND;
  591.                                             diaboulderproc(i, j);
  592.                                             break;
  593.                                         }
  594.                                     case DIAMOND:
  595.                                         {
  596.                                             field[i][j].content = BOULDER;
  597.                                             diaboulderproc(i, j);
  598.                                             break;
  599.                                         }
  600.                                     default:
  601.                                         break;
  602.                                 }
  603.                             }
  604.                         }
  605.                         set_cell(i, j, TINKLE);    /* reset to empty tinkle wall */
  606.                         break;
  607.                     default:
  608.                         break;
  609.                 }
  610.             }
  611.         }
  612.     }
  613.     curorder = STAND;        /* reset orders */
  614.     blobcells = 0;
  615.     pgc = (pgc == pgc1) ? ((rand() % 22) == 0) ? pgc2 : pgc1 : pgc1;
  616.     dgc = (dgc == dgc1) ? dgc2 : dgc1;
  617.     lgc = (lgc == lgc1) ? lgc2 : lgc1;
  618.     rgc = (rgc == rgc1) ? rgc2 : rgc1;
  619.     egc = (egc == egc1) ? egc2 : egc1;
  620.     Bgc = (Bgc == Bgc1) ? Bgc2 : Bgc1;
  621.     if (tinkact)
  622.         tgc = (tgc == tgc1) ? tgc2 : tgc1;
  623.     if (!diareq) {
  624.         Egc = (Egc == Egc1) ? Egc2 : Egc1;
  625.         if (diareq == 0) {
  626.             diapoints = extradiapoints;
  627.             scoreobs = TRUE;
  628.         }
  629.     }
  630. }
  631.