home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 199.lha / DmfSrc_v2.5 / dmf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-12-27  |  20.0 KB  |  635 lines

  1. /* Main combat routines for Dungeon Master's Familiar
  2.    by James Gary
  3.  
  4. Modification history:
  5.  
  6.    6-26-88  Fixed size determination error in damage calculation 
  7.    7-1-88   Added saving throws
  8.    7-1-88   Changed Attacker/Defender from temp records to cursors
  9.             Previously editor changes not effective untill re-selection.
  10.    7-9-88   Changed saving throws from gadgets to Inovatools 1 pop-up
  11.             menus
  12.    7-9-88   Added turning to pop-up menu
  13.    7-12-88  Modified message handler for new roller functions
  14.             (See roller.c for more detail)
  15. */
  16.  
  17. #include <exec/types.h>
  18. #include <exec/io.h>
  19. #include <exec/memory.h>
  20. #include <libraries/dos.h>
  21. #include <intuition/intuition.h>
  22. #include <clib/macros.h>
  23. #include "character.h"
  24. #include "dmf.h"
  25.  
  26. extern struct Character characters[];
  27. int Attacker=0,Defender=0; /* cursors to att. & def. */
  28. struct Window *wG; /* Main combat window */
  29. struct MsgPort *MyPort; /* Use this because handling input from
  30.                            multiple windows */
  31.  
  32. /* Cleric combat table */
  33. int ClericTable[21][8] = {
  34.     {25, 23, 21, 20, 20, 20, 19 },
  35.     {24, 22, 20, 20, 20, 19, 18 },
  36.     {23, 21, 20, 20, 20, 18, 17 },
  37.     {22, 20, 20, 20, 19, 17, 16 },
  38.     {21, 20, 20, 20, 18, 16, 15 },
  39.     {20, 20, 20, 19, 17, 15, 14 },
  40.     {20, 20, 20, 18, 16, 14, 13 },
  41.     {20, 20, 19, 17, 15, 13, 12 },
  42.     {20, 20, 18, 16, 14, 12, 11 },
  43.     {20, 19, 17, 15, 13, 11, 10 },
  44.     {20, 18, 16, 14, 12, 10,  9 },
  45.     {19, 17, 15, 13, 11,  9,  8 },
  46.     {18, 16, 14, 12, 10,  8,  7 },
  47.     {17, 15, 13, 11,  9,  7,  6 },
  48.     {16, 14, 12, 10,  8,  6,  5 },
  49.     {15, 13, 11,  9,  7,  5,  4 },
  50.     {14, 12, 10,  8,  6,  4,  3 },
  51.     {13, 11,  9,  7,  5,  3,  2 },
  52.     {12, 10,  8,  6,  4,  2,  1 },
  53.     {11,  9,  7,  5,  3,  1,  0 },
  54.     {10,  8,  6,  4,  2,  0, -1 } };
  55.  
  56. /* Fighter combat table */
  57. int FighterTable[21][11] = {
  58.     {26, 25, 23, 21, 20, 20, 20, 18, 16, 14 },
  59.     {25, 24, 22, 20, 20, 20, 19, 17, 15, 13 },
  60.     {24, 23, 21, 20, 20, 20, 18, 16, 14, 12 },
  61.     {23, 22, 20, 20, 20, 19, 17, 15, 13, 11 },
  62.     {22, 21, 20, 20, 20, 18, 16, 14, 12, 10 },
  63.     {21, 20, 20, 20, 19, 17, 15, 13, 11,  9 },
  64.     {20, 20, 20, 20, 18, 16, 14, 12, 10,  8 },
  65.     {20, 20, 20, 19, 17, 15, 13, 11,  9,  7 },
  66.     {20, 20, 20, 18, 16, 14, 12, 10,  8,  6 },
  67.     {20, 20, 19, 17, 15, 13, 11,  9,  7,  5 },
  68.     {20, 20, 18, 16, 14, 12, 10,  8,  6,  4 },
  69.     {20, 19, 17, 15, 13, 11,  9,  7,  5,  3 },
  70.     {19, 18, 16, 14, 12, 10,  8,  6,  4,  2 },
  71.     {18, 17, 15, 13, 11,  9,  7,  5,  3,  1 },
  72.     {17, 16, 14, 12, 10,  8,  6,  4,  2,  0 },
  73.     {16, 15, 13, 11,  9,  7,  5,  3,  1, -1 },
  74.     {15, 14, 12, 10,  8,  6,  4,  2,  0, -2 },
  75.     {14, 13, 11,  9,  7,  5,  3,  2, -1, -3 },
  76.     {13, 12, 10,  8,  6,  4,  2,  1, -2, -4 },
  77.     {12, 11,  9,  7,  5,  3,  1,  0, -3, -5 },
  78.     {11, 10,  8,  6,  4,  2,  0, -1, -4, -6 } };
  79.  
  80. /* Magic user combat table */
  81. int MagicTable[21][6] = {
  82.     {26, 24, 21, 20, 20 },
  83.     {25, 23, 20, 20, 20 },
  84.     {24, 22, 20, 20, 19 },
  85.     {23, 21, 20, 20, 18 },
  86.     {22, 20, 20, 19, 17 },
  87.     {21, 20, 20, 18, 16 },
  88.     {20, 20, 20, 17, 15 },
  89.     {20, 20, 19, 16, 14 },
  90.     {20, 20, 18, 15, 13 },
  91.     {20, 20, 17, 14, 12 },
  92.     {20, 19, 16, 13, 11 },
  93.     {20, 18, 15, 12, 10 },
  94.     {19, 17, 14, 11,  9 },
  95.     {18, 16, 13, 10,  8 },
  96.     {17, 15, 12,  9,  7 },
  97.     {16, 14, 11,  8,  6 },
  98.     {15, 13, 10,  7,  5 },
  99.     {14, 12,  9,  6,  4 },
  100.     {13, 11,  8,  5,  3 },
  101.     {12, 10,  7,  4,  2 },
  102.     {11,  9,  6,  3,  1 } };
  103.  
  104. /* Thief combat table */
  105. int ThiefTable[21][7] = {
  106.     {26, 24, 21, 20, 20, 20 },
  107.     {25, 23, 20, 20, 20, 19 },
  108.     {24, 22, 20, 20, 20, 18 },
  109.     {23, 21, 20, 20, 19, 17 },
  110.     {22, 20, 20, 20, 18, 16 },
  111.     {21, 20, 20, 19, 17, 15 },
  112.     {20, 20, 20, 18, 16, 14 },
  113.     {20, 20, 19, 17, 15, 13 },
  114.     {20, 20, 18, 16, 14, 12 },
  115.     {20, 20, 17, 15, 13, 11 },
  116.     {20, 19, 16, 14, 12, 10 },
  117.     {20, 18, 15, 13, 11,  9 },
  118.     {19, 17, 14, 12, 10,  8 },
  119.     {18, 16, 13, 11,  9,  7 },
  120.     {17, 15, 12, 10,  8,  6 },
  121.     {16, 14, 11,  9,  7,  5 },
  122.     {15, 13, 10,  8,  6,  4 },
  123.     {14, 12,  9,  7,  5,  3 },
  124.     {13, 11,  8,  6,  4,  2 },
  125.     {12, 10,  7,  5,  3,  1 },
  126.     {11,  9,  6,  4,  2,  0 } };
  127.  
  128. /* Monster combat table */
  129. int MonsterTable[21][13] = {
  130.     {26, 25, 24, 23, 21, 20, 20, 20, 20, 19, 18, 17 },
  131.     {25, 24, 23, 22, 20, 20, 20, 20, 19, 18, 17, 16 },
  132.     {24, 23, 22, 21, 20, 20, 20, 20, 18, 17, 16, 15 },
  133.     {23, 22, 21, 20, 20, 20, 20, 19, 17, 16, 15, 14 },
  134.     {22, 21, 20, 20, 20, 20, 19, 18, 16, 15, 14, 13 },
  135.     {21, 20, 20, 20, 20, 20, 18, 17, 15, 14, 13, 12 },
  136.     {20, 20, 20, 20, 20, 19, 17, 16, 14, 13, 12, 11 },
  137.     {20, 20, 20, 20, 19, 18, 16, 15, 13, 12, 11, 10 },
  138.     {20, 20, 20, 20, 18, 17, 15, 14, 12, 11, 10,  9 },
  139.     {20, 20, 20, 19, 17, 16, 14, 13, 11, 10,  9,  8 },
  140.     {20, 20, 19, 18, 16, 15, 13, 12, 10,  9,  8,  7 },
  141.     {20, 19, 18, 17, 15, 14, 12, 11,  9,  8,  7,  6 },
  142.     {19, 18, 17, 16, 14, 12, 11, 10,  8,  7,  6,  5 },
  143.     {18, 17, 16, 15, 13, 11, 10,  9,  7,  6,  5,  4 },
  144.     {17, 16, 15, 14, 12, 10,  9,  8,  6,  5,  4,  3 },
  145.     {16, 15, 14, 13, 11,  9,  8,  7,  5,  4,  3,  2 },
  146.     {15, 14, 13, 12, 10,  8,  7,  6,  4,  3,  2,  1 },
  147.     {14, 13, 12, 11,  9,  7,  6,  5,  3,  2,  1,  0 },
  148.     {13, 12, 11, 10,  8,  6,  5,  4,  2,  1,  0, -1 },
  149.     {12, 11, 10,  9,  7,  5,  4,  3,  1,  0, -1, -2 },
  150.     {11, 10,  9,  8,  6,  5,  3,  2,  0, -1, -2, -3 } };
  151.  
  152. /* Undead turning table */
  153. int TurnTable[13][10] = {
  154.     {10, 7, 4, 0, 0,-1,-1,-2,-2,-2},  /* 0 => automatic turn */
  155.     {13,10, 7, 0, 0,-1,-1,-2,-2,-2},  /*-1 => automatic death*/
  156.     {16,13,10, 4, 0, 0,-1,-1,-1,-2},  /*-2 => auto death 7-12*/
  157.     {19,16,13, 7, 4, 0, 0,-1,-1,-2},
  158.     {20,19,16,10, 7, 4, 0, 0,-1,-1},
  159.     {21,20,19,13,10, 7, 4, 0, 0,-1},
  160.     {21,21,20,16,13,10, 7, 4, 0,-1},
  161.     {21,21,21,20,16,13,10, 7, 4, 0},
  162.     {21,21,21,21,20,16,13,10, 7, 0},
  163.     {21,21,21,21,21,20,16,13,10, 4},
  164.     {21,21,21,21,21,21,20,16,13, 7},
  165.     {21,21,21,21,21,21,21,19,16,10},
  166.     {21,21,21,21,21,21,21,20,19,13} };
  167.  
  168. extern long IntuitionBase;
  169. extern long GfxBase;
  170. long MathBase;
  171. long LayersBase;
  172.  
  173. /* Do saving throw */
  174. SaveRoll(num)
  175. int num;
  176. {
  177.      int roll,needed,len;
  178.      char buff[80];
  179.  
  180.      roll = random(20);
  181.      needed = characters[Attacker].Saves[num];
  182.      if (roll >= needed)
  183.           len = sprintf(buff,"%15s needs %2d, rolls %2d, saved!                      ",
  184.                 characters[Attacker].Name,needed,roll);
  185.      else
  186.           len = sprintf(buff,"%15s needs %2d, rolls %2d, failed!                     ",
  187.                 characters[Attacker].Name,needed,roll);
  188.      Move(wG->RPort,9,195);
  189.      SetAPen(wG->RPort,1); /* Contrasting color for visibility*/
  190.      Text(wG->RPort,buff,len);
  191.      SetAPen(wG->RPort,3); /* Reset color */
  192.      return(0);
  193. }
  194.  
  195. /* Do undead turning */
  196. TurnRoll(row)
  197. int row;
  198. {
  199.      int roll,needed,len,level,col=0;
  200.      char buff[80];
  201.  
  202.      level = characters[Attacker].Level;
  203.      if (level < 9)
  204.           col = level - 1;
  205.      else if (level < 14) 
  206.           col = 8;
  207.      else if (level > 13)
  208.           col = 9;
  209.      roll = random(20);
  210.      needed = TurnTable[row][col];
  211.      if (needed == 21) 
  212.          len = sprintf(buff,"%15s needs %2d, rolls %2d, failed!                      ",
  213.                characters[Attacker].Name,needed,roll);
  214.      else if (needed == -1)
  215.          len = sprintf(buff,"%15s kills %2d!                                         ",
  216.                characters[Attacker].Name,random(12));
  217.      else if (needed == -2)
  218.          len = sprintf(buff,"%15s kills %2d!                                         ",
  219.                characters[Attacker].Name,random(6)+6);
  220.      else if (roll < needed)
  221.          len = sprintf(buff,"%15s needs %2d, rolls %2d, failed!                      ",
  222.                characters[Attacker].Name,needed,roll);
  223.      else
  224.           if (row < 12)
  225.                 len = sprintf(buff,"%15s needs %2d, rolls %2d, turned %2d                   ", 
  226.                       characters[Attacker].Name,needed,roll,random(12));
  227.           else
  228.                 len = sprintf(buff,"%15s needs %2d, rolls %2d, turned %2d                   ",
  229.                       characters[Attacker].Name,needed,roll,random(2));
  230.  
  231.      Move(wG->RPort,9,195);
  232.      SetAPen(wG->RPort,1); /* Contrasting color for visibility*/
  233.      Text(wG->RPort,buff,len);
  234.      SetAPen(wG->RPort,3); /* Reset color */
  235.      return(0);
  236. }
  237.  
  238. /* Handle a pop-up menu event */
  239. void HandleMenu(num)
  240. USHORT num;
  241. {
  242.      switch (ITEMNUM(num)) {
  243.          case 0 : TurnRoll(SUBNUM(num));
  244.                   break;
  245.          case 2 : SaveRoll(SUBNUM(num));
  246.                   break;
  247.          }
  248. }
  249.      
  250. /* Determine fighter to-hit number */
  251. fighter(level,ac)
  252. int level; /* Level of fighter */
  253. int ac; /* AC of defender */
  254. {
  255.     int row,col;
  256.  
  257.     if (level <= 0)           /* This mess determines proper row and column */
  258.         col = 0;              /*  |                                         */
  259.     else                      /*  |                                         */
  260.         col = (level + 1)/2;  /*  | (Advances by twos)                      */
  261.     if (col > 9)              /*  | (up to column nine)                     */
  262.         col = 9;              /*  |                                         */
  263.     row = 10 + ac;            /*  | (Ac 10 -> -10)                          */
  264.     if (row < 0)              /*  | Handle AC's off table                   */
  265.         row = 0;              /*  |                                         */
  266.     if (row > 19)             /*  |                                         */
  267.         row = 19;             /*  |_________________________________________*/
  268.     return(FighterTable[row][col]);
  269. }
  270.  
  271. /* Determine cleric to-hit number */
  272. cleric(level,ac)
  273. int level; /* Level of attacker */
  274. int ac;    /* AC of defender */
  275. {
  276.     int row,col;
  277.  
  278.     col = (level + 2)/3 - 1;
  279.     if (col < 0)
  280.         col = 0;
  281.     if (col > 6)
  282.         col = 6;
  283.     row = 10 + ac;
  284.     if (row < 0)
  285.         row = 0;
  286.     if (row > 19)
  287.         row = 19;
  288.     return(ClericTable[row][col]);
  289. }
  290.  
  291. /* Determine thief to-hit number */
  292. thief(level,ac)
  293. int level; /* Level of thief */
  294. int ac;    /* AC of defender */
  295. {
  296.     int row,col;
  297.  
  298.     col = (level + 3)/4 -1;
  299.     if (col < 0)
  300.         col = 0;
  301.     if (col > 5)
  302.         col = 5;
  303.     row = 10 + ac;
  304.     if (row < 0)
  305.         row = 0;
  306.     if (row > 19)
  307.         row = 19;
  308.     return(ThiefTable[row][col]);
  309. }
  310.  
  311. /* Determine magic user to-hit number */
  312. magic(level,ac)
  313. int level; /* Level of attacker */
  314. int ac;    /* AC of defender */
  315. {
  316.     int row,col;
  317.  
  318.     col = (level + 4)/5 - 1;
  319.     if (col < 0)
  320.         col = 0;
  321.     if (col > 4)
  322.         col = 4;
  323.     row = 10 + ac;
  324.     if (row < 0)
  325.         row = 0;
  326.     if (row > 19)
  327.         row = 19;
  328.     return(MagicTable[row][col]);
  329. }
  330.  
  331. /* Determine monster to-hit number */
  332. monster(level,ac)
  333. int level; /* Level of monster */
  334. int ac;    /* AC of defender */
  335. {
  336.     int row,col;
  337.  
  338.     col = level - 1;
  339.     if (col < 0)
  340.         col = 0;
  341.     if (col > 11)
  342.         col = 11;
  343.     row = 10 + ac;
  344.     if (row < 0)
  345.         row = 0;
  346.     if (row > 19)
  347.         row = 19;
  348.     return(MonsterTable[row][col]);
  349. }
  350.  
  351. /* User selected reverse gadget, so switch attacker and defender
  352.    and call repeat */
  353. Reverse(gad)
  354. struct Gadget *gad;
  355. {
  356.         int temp;
  357.         int Repeat();
  358.  
  359.         temp = Attacker;
  360.         Attacker = Defender;
  361.         Defender = temp;
  362.         Repeat(NULL);
  363.     return(0);
  364. }
  365.  
  366. /* User selected repeat gadget or selected defender, so handle combat */
  367. Repeat(gad)
  368. struct Gadget *gad;
  369. {
  370.         int len,ToHit,Roll,NumDice,TypeDie,DamPlus,Damage,i;
  371.         char buf[80]; /* to hold result string */
  372.  
  373.         switch(characters[Attacker].Job) { /* get proper to-hit number */
  374.                 case(FIGHTER) : ToHit = fighter(characters[Attacker].Level,characters[Defender].AC);
  375.                                 break;
  376.                 case(CLERIC) : ToHit = cleric(characters[Attacker].Level,characters[Defender].AC);
  377.                                break;
  378.                 case(MAGICUSER) : ToHit = magic(characters[Attacker].Level,characters[Defender].AC);
  379.                                   break;
  380.                 case(THIEF) : ToHit = thief(characters[Attacker].Level,characters[Defender].AC);
  381.                               break;
  382.                 case(MONSTER) : ToHit = monster(characters[Attacker].Level,characters[Defender].AC);
  383.                                 break;
  384.                 }
  385.  
  386.         if (characters[Defender].Size == SMALL) { /* Adjust vars for small defender */
  387.                 ToHit += characters[Attacker].SmHitPlus;
  388.                 NumDice = characters[Attacker].SmNumDie;
  389.                 TypeDie = characters[Attacker].SmTypeDie;
  390.                 DamPlus = characters[Attacker].SmDamPlus;
  391.         }
  392.         else { /* Adjust vars for large defender */
  393.                 ToHit += characters[Attacker].LgHitPlus;
  394.                 NumDice = characters[Attacker].LgNumDie;
  395.                 TypeDie = characters[Attacker].LgTypeDie;
  396.                 DamPlus = characters[Attacker].LgDamPlus;
  397.         }
  398.  
  399.         Roll = random(20); /* Roll dem bones! */
  400.         Damage = 0;
  401.         if (Roll >= ToHit) { /* Contact! */
  402.                 for (i=0;i<NumDice;i++)
  403.                         Damage += random(TypeDie);
  404.                 Damage += DamPlus;
  405.                 }
  406.  
  407.         len = sprintf(buf,"%15s vs. %15s needs %2d, rolls %2d, for %3d   ",
  408.               characters[Attacker].Name,characters[Defender].Name,ToHit,Roll,Damage);
  409.         Move(wG->RPort,9,195);
  410.         SetAPen(wG->RPort,1); /* Contrasting color for visibility*/
  411.         Text(wG->RPort,buf,len);
  412.         SetAPen(wG->RPort,3); /* Reset color */
  413.     return(0);
  414. }
  415.  
  416. /* Display character names on main window */
  417. PrintChars()
  418. {
  419.      int len,row,col,i;
  420.      char buf[20];
  421.  
  422.      i = 0;
  423.      for (row=0; row < 15; row++) {
  424.           for (col = 0; col < 4; col++) {
  425.                len = sprintf(buf,"%15s",characters[i++].Name);
  426.                Move(wG->RPort,3+160*col,10*row+18);
  427.                Text(wG->RPort,buf,len);
  428.           }
  429.      }
  430.      return(0);
  431. }
  432. void PrintOne(i,fp,bp)
  433. int i;
  434. UBYTE fp,bp;
  435. {
  436.      int row,col,len;
  437.      char buf[20];
  438.  
  439.      row = i/4;
  440.      col = i%4;
  441.      len = sprintf(buf,"%15s",characters[i].Name);
  442.      SetAPen(wG->RPort,fp);
  443.      SetBPen(wG->RPort,bp);
  444.      Move(wG->RPort,3+160*col,10*row+18);
  445.      Text(wG->RPort,buf,len);
  446.      SetAPen(wG->RPort,3);
  447.      SetBPen(wG->RPort,0);
  448. }
  449. USHORT quit_flag = FALSE;
  450.  
  451. /* This is for the event handler */
  452. void quit(object)
  453. APTR object;
  454. {
  455.         quit_flag = TRUE;
  456.     return(0);
  457. }
  458.  
  459.  
  460. struct Window *OpenWindow();
  461. struct Screen *OpenScreen();
  462.  
  463. /* User selected attacker with Left Mouse button, determine which */
  464. SetAttacker(x,y)
  465. int x,y;
  466. {
  467.         int row,col,charnum;
  468.  
  469.         PrintOne(Attacker,3,0);
  470.         row = (y-12)/10;
  471.         col = (x/160);
  472.         charnum = row*4+col;
  473.         charnum = MAX(charnum,0);           /* Make sure that */
  474.         charnum = MIN(charnum,MAXCHARS-1);  /* we are in range*/
  475.         Attacker = charnum;
  476.     PrintOne(Attacker,1,3);
  477.         return(0);
  478. }
  479.  
  480. /* User selected defender with Right Mouse button, determine which */
  481. SetDefender(x,y)
  482. int x,y;
  483. {
  484.         int row,col,charnum;
  485.  
  486.         row = (y-12)/10;
  487.         col = (x/160);
  488.         charnum = row*4+col;
  489.         charnum = MAX(charnum,0);          /* Make sure that  */
  490.         charnum = MIN(charnum,MAXCHARS-1); /* we are in range */
  491.         Defender = charnum;
  492.     return(0);
  493. }
  494.  
  495. /* The main program was adapted from PW's example program and contains
  496.    some unused leftovers from that code. Sorry. */
  497. main()
  498. {
  499.         UWORD code;
  500.         ULONG class;
  501.         APTR object;
  502.         int x,y;    /* for mouse button message */
  503.  
  504.         struct Gadget *gad;
  505.         extern struct Window *MyWindow; /* Roller window */
  506.         struct Window *win;             /* Main combat window */
  507.         struct RastPort *rpG;
  508.         struct IntuiMessage *message;   /* the message the IDCMP sends us */
  509.         USHORT num;
  510.         extern int Total;
  511.         struct StringInfo *sinfo;
  512.         long last;
  513.  
  514.         IntuitionBase = OpenLibrary("intuition.library", 0);
  515.         if (IntuitionBase == NULL)
  516.         {
  517.                 printf("intuition is not here.  where are we?\n");
  518.                 goto cleanup1;
  519.         }
  520.         LayersBase = OpenLibrary("layers.library",0);
  521.         GfxBase = OpenLibrary("graphics.library", 0);
  522.         MathBase = OpenLibrary("mathffp.library",0);
  523.    
  524.            /* Must set up own port to handle input from multiple windows*/
  525.         MyPort = (struct MsgPort *) CreatePort("CombatPort",0); 
  526.         wG = OpenWindow(&NewWindowStructure1);  /* open the window */
  527.         if ( wG == NULL )
  528.         {
  529.                 printf ("open window failed\n");
  530.                 goto cleanup1;
  531.         }
  532.         wG->UserPort = MyPort; /* Attach to port*/
  533.  
  534.           /* To facilitate user port, no IDCMP were specified in NewWindow*/
  535.           /* so add the ones we want now. */
  536.         ModifyIDCMP(wG,MOUSEBUTTONS|GADGETDOWN|GADGETUP|CLOSEWINDOW);
  537.         
  538.         rpG = wG->RPort;        /* get a rastport pointer for the window */
  539.          
  540.         InitChars(); /* Initialize character array*/
  541.  
  542.         PrintChars(); /* Display character names in main window */
  543.  
  544.         PrintOne(Attacker,1,0); /*Highlight Attacker*/
  545. #ifdef IntuiTextList1
  546.         PrintIText(rpG,&IntuiTextList1,0,0);    /* Print the text if there is
  547.                                                 any */
  548. #endif
  549.  
  550. #ifdef BorderList1
  551.         DrawBorder(rpG,&BorderList1,0,0);       /* Draw the borders if there are
  552.                                                 any */
  553. #endif
  554.  
  555. #ifdef ImageList1
  556.         DrawImage(rpG,&ImageList1,0,0); /* Draw the images if there are any */
  557. #endif
  558.  
  559.   do {
  560.      WaitPort(wG->UserPort);
  561.      while( (message = (struct IntuiMessage *) GetMsg(wG->UserPort)) != NULL)
  562.          {
  563.          code = message->Code;  /* MENUNUM */
  564.          object = message->IAddress;  /* Gadget */
  565.          class = message->Class;
  566.          x = message->MouseX;
  567.          y = message->MouseY;
  568.          win = message->IDCMPWindow;
  569.          ReplyMsg(message); /* All good stuff is recorded, make Intuition :) */
  570.          
  571.          /* User did something, no figure out what */
  572.          if (win == wG) {  /* Main window event!*/
  573.             if ( class == CLOSEWINDOW ) (quit_flag = TRUE);
  574.             if (( class == GADGETDOWN ) ||
  575.                   (class == GADGETUP)) {
  576.                         if (object == (APTR) &ExtraGad) {
  577.                              num = PopUpMenu(wG,&Menu1);
  578.                              HandleMenu(num);
  579.                         }
  580.                         else 
  581.                              HandleEvent(object);
  582.                  }   
  583.             if ( class == MOUSEBUTTONS ){
  584.                if (code == SELECTUP)
  585.                   SetAttacker(x,y); /* Left button means attacker */
  586.                if (code == MENUUP) {
  587.                   SetDefender(x,y); /* Right button means defender */
  588.                   Repeat(); /* Resolve combat */
  589.                }
  590.             }
  591.          }
  592.          else {  /* Must be roller window!*/
  593.             switch(class) {
  594.                case CLOSEWINDOW: cleanup();
  595.                                  break;
  596.                case GADGETDOWN:
  597.                case GADGETUP:  gad = (struct Gadget *) object;
  598.                         switch((int)gad->GadgetID) {
  599. /* Gadget ID's : */         case 25:
  600. /* 25: UserNum   */                  sinfo = (struct StringInfo *)gad->SpecialInfo;
  601. /* 50: Again     */                  last = sinfo->LongInt;
  602. /* 75: ClearTotal*/                  display(last);
  603.                                      break;
  604.                             case 50: display(last);
  605.                                      break;
  606.                             case 75: Total = 0;
  607.                                      DisplayTotal();
  608.                                      break;
  609.                             default: display((int)gad->GadgetID); /* Roll 'em */
  610.                                      break;
  611.                         }
  612.                         break;
  613.                default:  cleanup();
  614.                          break;
  615.             }
  616.          }
  617.       }
  618.    } while (quit_flag == FALSE);
  619.  
  620. cleanup3:
  621.  
  622. cleanup2:
  623.         wG->UserPort = NULL;
  624.         CloseWindow(wG);
  625.     cleanup();
  626.         DeletePort(MyPort);
  627. cleanup1:
  628.         if (MathBase != NULL) CloseLibrary(MathBase);
  629.         if (GfxBase != NULL) CloseLibrary(GfxBase);
  630.         if (LayersBase != NULL) CloseLibrary(LayersBase);
  631.         if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
  632.         return(0);
  633.  
  634. }
  635.