home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / thx / demos / mfighter / build / fighter.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-14  |  11.3 KB  |  628 lines

  1. #include <fastgraf.h>
  2. #include <stdlib.h>   // abs
  3. #include <string.h>
  4. #include "game.h"
  5. #include "fighter.h"
  6.  
  7. const int MAXFRAMES=6;
  8. const int CLOSE_LIMIT=25;
  9. const int DAMAGE_LIMIT=100;
  10.  
  11. //----------------------------------------------------- data definitions -----
  12.  
  13. struct nextstateinfo
  14.   {
  15.   int mode;
  16.   int frame;
  17.   };
  18.  
  19. struct area
  20.   {
  21.   int x,y;
  22.   int r;
  23.   };
  24.  
  25. struct frameinfo
  26.   {
  27.   int xoffset;
  28.   int yoffset;
  29.   int is_defensive;
  30.  
  31.   int hasattack;
  32.   area attack;
  33.  
  34.   int hastarget;
  35.   area hightarget;
  36.   area lowtarget;
  37.   };
  38.  
  39. //---------------------------------------------- static data tables -----
  40.  
  41. static nextstateinfo next[NUMMODES][MAXFRAMES+1]=
  42.   {
  43. { {0,0},{WAIT,2},{WAIT,3},{WAIT,4},{WAIT,5},{WAIT,6},{WAIT,1} },
  44. { {0,0}, {PUNCH,2},   {WAIT,1},  {0,0},    }, // PUNCH (goes to WAIT)
  45. { {0,0}, {KICK,2},    {WAIT,1},  {0,0}     }, // KICK (also goes to WAIT)
  46. { {0,0}, {BLOCK,2},   {BLOCK,3}, {WAIT,1}  }, // BLOCK (goes to WAIT)
  47. { {0,0}, {VICTORY,1}, {0,0},     {0,1}     }, // VICTORY (dead end)
  48. { {0,0}, {DEFEAT,1},  {0,0},     {0,1}     }, // DEFEAT  (dead end)
  49. { {0,0}, {HIGH,2},    {WAIT,1},  {0,1}     }, // HIGH
  50. { {0,0}, {LOW,2},     {WAIT,1},  {0,1}     }, // LOW
  51. { {0,0}, {OUT,2},     {OUT,3},   {OUT,4},  {OUT,5}, {OUT,5}    }, // OUT
  52. { {0,0}, {WIN,2},     {WIN,1},   {0,1}     }  // WIN
  53.   };
  54.  
  55. static int image_no[NUMMODES][MAXFRAMES+1]=
  56.   {
  57. { 0,1,1,2,2,3,3 },     // wait
  58. { 0, 5, 4, 0 },        // punch
  59. { 0, 6, 7, 0 },        // kick
  60. { 0, 8, 8, 8 },        // block
  61. { 0, 12, 0, 0 },       // victory
  62. { 0, 0, 0, 0,},        // defeat
  63. { 0, 9, 9, 0,},        // high
  64. { 0, 10, 10, 0,},      // low
  65. { 0, 12, 13, 14, 15, 16, 17},      // down
  66. { 0, 11, 11, 0,}       // win
  67.   };
  68.  
  69. //-------------------------------------- left player data
  70. static frameinfo frame_wait_1=
  71.   {
  72.   0,0,FALSE,
  73.   FALSE, { 0,0,0 },
  74.   TRUE, { 29,13,5 }, {21,37,3}
  75.   };
  76.  
  77. static frameinfo frame_wait_2=
  78.   {
  79.   0,0,FALSE,
  80.   FALSE, { 0,0,0 },
  81.   TRUE, {30,14,5}, {21,37,3}
  82.   };
  83.  
  84. static frameinfo frame_wait_3=
  85.   {
  86.   0,0,FALSE,
  87.   FALSE, { 0,0,0 },
  88.   TRUE, { 30,13,5 }, {21,37,3}
  89.   };
  90.  
  91. static frameinfo frame_punch_1=
  92.   {
  93.   0,0,FALSE,
  94.   FALSE, { 33,25,2 },
  95.   TRUE, { 31,12,5}, {21,36,3}
  96.   };
  97.  
  98. static frameinfo frame_punch_2=
  99.   {
  100.   0,0,FALSE,
  101.   TRUE, {47,20,2},
  102.   TRUE, {31,12,5 }, {21,36,3}
  103.   };
  104.  
  105. static frameinfo frame_kick_1=
  106.   {
  107.   0,0,FALSE,
  108.   TRUE, {49,37,2},
  109.   TRUE, {29,12,5}, {20,36,3}
  110.   };
  111.  
  112. static frameinfo frame_kick_2=
  113.   {
  114.   0,0,FALSE,
  115.   FALSE, {36,56,2},
  116.   TRUE, {29,12,5}, {21,36,3}
  117.   };
  118.  
  119. static frameinfo frame_block_1=
  120.   {
  121.   0,0,TRUE,
  122.   FALSE, {0,0,0},
  123.   TRUE, { 29,13,5 }, {21,37,3}
  124.   };
  125.  
  126. static frameinfo frame_high_1=
  127.   {
  128.   0,0,FALSE,
  129.   FALSE, {0,0,0},
  130.   FALSE, {0,0,0}, {0,0,0}
  131.   };
  132.  
  133. static frameinfo frame_low_1=
  134.   {
  135.   0,0,FALSE,
  136.   FALSE, {0,0,0},
  137.   FALSE, {0,0,0}, {0,0,0}
  138.   };
  139.  
  140. static frameinfo frame_win_1=
  141.   {
  142.   0,0,FALSE,
  143.   FALSE, {0,0,0},
  144.   FALSE, {0,0,0}, {0,0,0}
  145.   };
  146.  
  147. static frameinfo frame_down_1=
  148.   {
  149.   0,0,FALSE,
  150.   FALSE, {0,0,0},
  151.   FALSE, {0,0,0}, {0,0,0}
  152.   };
  153.  
  154. static frameinfo frame_down_2=
  155.   {
  156.   0,0,FALSE,
  157.   FALSE, {0,0,0},
  158.   FALSE, {0,0,0}, {0,0,0}
  159.   };
  160.  
  161. static frameinfo frame_down_3=
  162.   {
  163.   0,0,FALSE,
  164.   FALSE, {0,0,0},
  165.   FALSE, {0,0,0}, {0,0,0}
  166.   };
  167.  
  168. static frameinfo frame_down_4=
  169.   {
  170.   0,0,FALSE,
  171.   FALSE, {0,0,0},
  172.   FALSE, {0,0,0}, {0,0,0}
  173.   };
  174.  
  175. static frameinfo frame_down_5=
  176.   {
  177.   0,0,FALSE,
  178.   FALSE, {0,0,0},
  179.   FALSE, {0,0,0}, {0,0,0}
  180.   };
  181.  
  182. //-------------------------------------- right player data
  183. static frameinfo rframe_wait_1=
  184.   {
  185.   0,0,FALSE,
  186.   FALSE, { 0,0,0 },
  187.   TRUE, { 21,14,5 }, {29,36,3}
  188.   };
  189.  
  190. static frameinfo rframe_wait_2=
  191.   {
  192.   0,0,FALSE,
  193.   FALSE, { 0,0,0 },
  194.   TRUE, { 20,15,5 }, {29,36,3}
  195.   };
  196.  
  197. static frameinfo rframe_wait_3=
  198.   {
  199.   0,0,FALSE,
  200.   FALSE, { 0,0,0 },
  201.   TRUE, { 20,14,5 }, {29,36,3}
  202.   };
  203.  
  204. static frameinfo rframe_punch_1=
  205.   {
  206.   0,0,FALSE,
  207.   FALSE, { 17,30,2 },
  208.   TRUE, { 19,14,5 }, {29,35,3}
  209.   };
  210.  
  211. static frameinfo rframe_punch_2=
  212.   {
  213.   0,0,FALSE,
  214.   TRUE, { 6,20,2 },
  215.   TRUE, { 19,14,5 }, {29,34,3}
  216.   };
  217.  
  218. static frameinfo rframe_kick_1=
  219.   {
  220.   0,0,FALSE,
  221.   TRUE, { 0,40,2 },
  222.   TRUE, { 21,14,5 }, {29,35,3}
  223.   };
  224.  
  225. static frameinfo rframe_kick_2=
  226.   {
  227.   0,0,FALSE,
  228.   FALSE, { 16,51,2 },
  229.   TRUE, { 21,14,5 }, {29,35,3}
  230.   };
  231.  
  232. static frameinfo rframe_block_1=
  233.   {
  234.   0,0,TRUE,
  235.   FALSE, {0,0,0},
  236.   TRUE, { 21,14,5 }, {29,36,3}
  237.   };
  238.  
  239. static frameinfo rframe_high_1=
  240.   {
  241.   0,0,FALSE,
  242.   FALSE, {0,0,0},
  243.   FALSE, {0,0,0}, {0,0,0}
  244.   };
  245.  
  246. static frameinfo rframe_low_1=
  247.   {
  248.   0,0,FALSE,
  249.   FALSE, {0,0,0},
  250.   FALSE, {0,0,0}, {0,0,0}
  251.   };
  252.  
  253. static frameinfo rframe_win_1=
  254.   {
  255.   0,0,FALSE,
  256.   FALSE, {0,0,0},
  257.   FALSE, {0,0,0}, {0,0,0}
  258.   };
  259.  
  260. static frameinfo rframe_down_1=
  261.   {
  262.   0,0,FALSE,
  263.   FALSE, {0,0,0},
  264.   FALSE, {0,0,0}, {0,0,0}
  265.   };
  266.  
  267. static frameinfo rframe_down_2=
  268.   {
  269.   0,0,FALSE,
  270.   FALSE, {0,0,0},
  271.   FALSE, {0,0,0}, {0,0,0}
  272.   };
  273.  
  274. static frameinfo rframe_down_3=
  275.   {
  276.   0,0,FALSE,
  277.   FALSE, {0,0,0},
  278.   FALSE, {0,0,0}, {0,0,0}
  279.   };
  280.  
  281. static frameinfo rframe_down_4=
  282.   {
  283.   0,0,FALSE,
  284.   FALSE, {0,0,0},
  285.   FALSE, {0,0,0}, {0,0,0}
  286.   };
  287.  
  288. static frameinfo rframe_down_5=
  289.   {
  290.   0,0,FALSE,
  291.   FALSE, {0,0,0},
  292.   FALSE, {0,0,0}, {0,0,0}
  293.   };
  294.  
  295. //-------------------------------------- frameinfo list
  296. static frameinfo* framelist[2][18]=
  297.   {
  298. {
  299.   NULL,
  300.   &frame_wait_1,
  301.   &frame_wait_2,
  302.   &frame_wait_3,
  303.   &frame_punch_1,
  304.   &frame_punch_2,
  305.   &frame_kick_1,
  306.   &frame_kick_2,
  307.   &frame_block_1,
  308.   &frame_high_1,
  309.   &frame_low_1,
  310.   &frame_win_1,
  311.   &frame_down_1,
  312.   &frame_down_2,
  313.   &frame_down_3,
  314.   &frame_down_4,
  315.   &frame_down_5
  316. },
  317. {
  318.   NULL,
  319.   &rframe_wait_1,
  320.   &rframe_wait_2,
  321.   &rframe_wait_3,
  322.   &rframe_punch_1,
  323.   &rframe_punch_2,
  324.   &rframe_kick_1,
  325.   &rframe_kick_2,
  326.   &rframe_block_1,
  327.   &rframe_high_1,
  328.   &rframe_low_1,
  329.   &rframe_win_1,
  330.   &rframe_down_1,
  331.   &rframe_down_2,
  332.   &rframe_down_3,
  333.   &rframe_down_4,
  334.   &rframe_down_5
  335.  }
  336.   };
  337.  
  338. //----------------------------------------------------------------------
  339.  
  340. void Fighter::initialize()
  341.   {
  342.   load_gfxlib("lfight.gfx");
  343.   load_gfxlib("rfight.gfx");
  344.   if (side==LEFTGUY)
  345.     set_gfxlib("lfight.gfx");
  346.   else
  347.     set_gfxlib("rfight.gfx");
  348.  
  349.   load_sfxlib("sounds.sfx");
  350.   numsounds=get_num_clips();
  351.   }
  352.  
  353. void Fighter::update_status()
  354.   {
  355.   if (newmode)
  356.     {
  357.     newmode=FALSE;
  358.     return;
  359.     }
  360.   if (mode!=OUT)
  361.     {
  362.     if (damage>=DAMAGE_LIMIT)
  363.       {
  364.       mode=OUT;
  365.       frame=1;
  366.       play_sound_clip(5);
  367.       opponent->you_win();
  368.       return;
  369.       }
  370.     }
  371.   int m=mode;
  372.   int f=frame;
  373.   mode=next[m][f].mode;
  374.   frame=next[m][f].frame;
  375.   }
  376.  
  377. void Fighter::display()
  378.   {
  379.   if (side==LEFTGUY)
  380.     x=LEFT_START;
  381.   else
  382.     x=RIGHT_START;
  383.   damage=0;
  384.   y=FIGHTER_Y;
  385.   mode=WAIT;
  386.   frame=1;
  387.  
  388.   int imgno=image_no[mode][frame];
  389.   int xoff=framelist[side][imgno]->xoffset;
  390.   int yoff=framelist[side][imgno]->yoffset;
  391.   show_image(x+xoff,y+yoff,imgno);
  392.   }
  393.  
  394. void Fighter::update()
  395.   {
  396.   int imgno=image_no[mode][frame];
  397.   int xoff=framelist[side][imgno]->xoffset;
  398.   int yoff=framelist[side][imgno]->yoffset;
  399.   show_image(x+xoff,y+yoff,imgno);
  400.  
  401. //#define SHOWZONE
  402. #ifdef SHOWZONE
  403.   frameinfo* ptr=framelist[side][imgno];
  404.   fg_setcolor(2);
  405.   if (ptr->hasattack)
  406.     {
  407.     fg_move(x+ptr->attack.x,y+ptr->attack.y);
  408.     fg_circle(ptr->attack.r);
  409.     }
  410.  
  411.   fg_move(x+ptr->hightarget.x,y+ptr->hightarget.y);
  412.   fg_circle(ptr->hightarget.r);
  413.  
  414.   fg_move(x+ptr->lowtarget.x,y+ptr->lowtarget.y);
  415.   fg_circle(ptr->lowtarget.r);
  416. #endif
  417.   }
  418.  
  419. void Fighter::communicate()
  420.   {
  421.   int imgno=image_no[mode][frame];
  422.   frameinfo* mine=framelist[side][imgno];
  423.   if (mine->hasattack)
  424.     {
  425.     area absolute_area=mine->attack;
  426.     absolute_area.x+=x;
  427.     absolute_area.y+=y;
  428.     opponent->evaluate_attack(absolute_area);
  429.     }
  430.   }
  431.  
  432. #define max(a,b)  ((a<b) ? b : a)
  433. #define min(a,b)  ((a<b) ? a : b)
  434.  
  435. void Fighter::evaluate_attack(area attack)
  436.   {
  437.   if (checkhits==FALSE)  return;
  438.  
  439.   int testx,testy,dist;
  440.   int imgno=image_no[mode][frame];
  441.   frameinfo* mine=framelist[side][imgno];
  442.   if (mine->hastarget)
  443.     {
  444. //  check the high target (head)
  445.     testx=abs(attack.x-(x+mine->hightarget.x));
  446.     testy=abs(attack.y-(y+mine->hightarget.y));
  447.     dist=max(testx,testy) + (min(testx,testy)/2);
  448.     if (dist <= attack.r+mine->hightarget.r)
  449.       {
  450.       if (mine->is_defensive)
  451.         {
  452.         post_message(ATTACK_BLOCKED,side);
  453.         if (usenetpacks)
  454.           post_netpack(ATTACK_BLOCKED);
  455.         play_sound_clip(4);
  456.         }
  457.       else
  458.         {
  459.         mode=HIGH;
  460.         frame=1;
  461.         newmode=TRUE;
  462.         damage+=7;
  463.         post_message(GOT_PUNCHED,side);
  464.         if (usenetpacks)
  465.           post_netpack(GOT_PUNCHED);
  466.         play_sound_clip(2);
  467.         calc_impact();
  468.         }
  469.       }
  470.  
  471. //  check the low target
  472.     testx=abs(attack.x-(x+mine->lowtarget.x));
  473.     testy=abs(attack.y-(y+mine->lowtarget.y));
  474.     dist=max(testx,testy) + (min(testx,testy)/2);
  475.     if (dist <= attack.r+mine->lowtarget.r)
  476.       {
  477.       if (mine->is_defensive)
  478.         {
  479.         post_message(ATTACK_BLOCKED,side);
  480.         if (usenetpacks)
  481.           post_netpack(ATTACK_BLOCKED);
  482.         play_sound_clip(4);
  483.         }
  484.       else
  485.         {
  486.         mode=LOW;
  487.         frame=1;
  488.         newmode=TRUE;
  489.         damage+=10;
  490.         post_message(GOT_KICKED,side);
  491.         if (usenetpacks)
  492.           post_netpack(GOT_KICKED);
  493.         play_sound_clip(3);
  494.         calc_impact();
  495.         }
  496.       }
  497.     }
  498.   }
  499.  
  500. void Fighter::calc_impact()
  501.   {
  502.   if (side==LEFTGUY)
  503.     {
  504.     if (x>MIN_X)
  505.       {
  506.       if (x-IMPACT>MIN_X)
  507.         x-=IMPACT;
  508.       else
  509.         x=MIN_X;
  510.       }
  511.     }
  512.   else   // (side==RIGHT)
  513.     {
  514.     if (x+BITMAP_WIDTH < MAX_X)
  515.       {
  516.       if (x+IMPACT+BITMAP_WIDTH < MAX_X)
  517.         x+=IMPACT;
  518.       else
  519.         x=MAX_X-BITMAP_WIDTH;
  520.       }
  521.     }
  522.   }
  523.  
  524. void Fighter::you_win()
  525.   {
  526.   mode=WIN;
  527.   frame=1;
  528.   post_message(GAME_OVER,side);
  529.   }
  530.  
  531. int Fighter::kick()      // tag
  532.   {
  533.   if (mode==WAIT)
  534.     {
  535.     mode=KICK;
  536.     frame=1;
  537.     newmode=TRUE;
  538.     return 1;
  539.     }
  540.   return 0;
  541.   }
  542.  
  543. int Fighter::punch()
  544.   {
  545.   if (mode==WAIT)
  546.     {
  547.     mode=PUNCH;
  548.     frame=1;
  549.     newmode=TRUE;
  550.     return 1;
  551.     }
  552.   return 0;
  553.   }
  554.  
  555. int Fighter::left()
  556.   {
  557.   if (mode!=WAIT)  return 0;
  558.  
  559.   if (side==LEFTGUY)
  560.     {
  561.     if (x>MIN_X)
  562.       x-=LOC_INC;
  563.     }
  564.   else
  565.     {
  566.     if (x>opponent->x+CLOSE_LIMIT)
  567.       x-=LOC_INC;
  568.     }
  569.   return 1;
  570.   }
  571.  
  572. int Fighter::right()
  573.   {
  574.   if (mode!=WAIT)  return 0;
  575.  
  576.   if (side==LEFTGUY)
  577.     {
  578.     if (x+CLOSE_LIMIT<opponent->x)
  579.       x+=LOC_INC;
  580.     }
  581.   else
  582.     {
  583.     if (x+BITMAP_WIDTH<MAX_X)
  584.       x+=LOC_INC;
  585.     }
  586.   return 1;
  587.   }
  588.  
  589. int Fighter::block()
  590.   {
  591.   if (mode==WAIT)
  592.     {
  593.     mode=BLOCK;
  594.     frame=1;
  595.     newmode=TRUE;
  596.     return 1;
  597.     }
  598.   return 0;
  599.   }
  600.  
  601. void Fighter::got_punched()
  602.   {
  603.   mode=HIGH;
  604.   frame=1;
  605.   newmode=TRUE;
  606.   damage+=7;
  607.   post_message(GOT_PUNCHED,side);
  608.   play_sound_clip(2);
  609.   calc_impact();
  610.   }
  611.  
  612. void Fighter::got_kicked()
  613.   {
  614.   mode=LOW;
  615.   frame=1;
  616.   newmode=TRUE;
  617.   damage+=10;
  618.   post_message(GOT_KICKED,side);
  619.   play_sound_clip(3);
  620.   calc_impact();
  621.   }
  622.  
  623. void Fighter::got_blocked()
  624.   {
  625.   post_message(ATTACK_BLOCKED,side);
  626.   play_sound_clip(4);
  627.   }
  628.