home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 1 / CD_Magazyn_EXEC_nr_1.iso / Gry / battalion.lha / Battalion / source / update.c < prev   
C/C++ Source or Header  |  1999-12-23  |  23KB  |  686 lines

  1. /****************************************************************/
  2. /* code copyright 1995-1996 Andrew Johnson - ALL RIGHTS RESERVED*/
  3. /*                          ajohnson@eecs.uic.edu               */
  4. /*                                                              */
  5. /*                      Electronic Visualization Lab (M/C 154)  */
  6. /*                      University of Illinois at Chicago       */
  7. /*                      851 South Morgan St. Room 1120 SEO      */
  8. /*                      Chicago, IL 60607-7053                  */
  9. /*                                                              */
  10. /*                      (312) 996-3002     (312) 413-7585 FAX   */
  11. /***********************************************************************/
  12. /* update.c  v 1.2                                                     */
  13. /* update routines for battalion                                       */
  14. /***********************************************************************/
  15.  
  16. #include "battalion.h"
  17.  
  18. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  19. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  20. /* output an error message                                       */
  21. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  22.  
  23. void showError(char * theString)
  24.     {
  25.     fprintf(stderr, "BATTALION ERROR: %s\n", theString);
  26.     fflush(stderr);
  27.     }
  28.  
  29. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  30. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  31. /* compute height of a building                                  */
  32. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  33.  
  34. float buildingHeight(int type,  int shape)
  35.     {
  36.     float height;
  37.     
  38.     switch(type){
  39.         case 0:     height = 0.5;
  40.                     break;
  41.                     
  42.         case 1:     switch(shape){
  43.                         case 1: 
  44.                         case 11:
  45.                         case 14:
  46.                         case 22:
  47.                         case 23:
  48.                         case 24:
  49.                         case 37:    height = 0.8;
  50.                                     break;
  51.                                     
  52.                         case 9:     height = 0.2;
  53.                                     break; 
  54.                                      
  55.                         case 5:
  56.                         case 6:
  57.                         case 13:
  58.                         case 28:    height = -0.2;
  59.                                     break;
  60.                                     
  61.                         case 31:
  62.                         case 32:    height = -0.4;
  63.                                     break;
  64.                                     
  65.                         default:    height = 0.0;
  66.                                     break;
  67.                     }
  68.                     break;
  69.                     
  70.         case 2:     height = -0.8;
  71.                     break;
  72.                     
  73.         case 3:     if (shape == 0)
  74.                         height = -0.4;   
  75.                     else
  76.                         height = -0.6;
  77.                     break;
  78.                     
  79.         default:    showError("invalid building type (buildingHeight)");
  80.                     break;
  81.         }
  82.         
  83.     return(height);
  84.     }
  85.  
  86. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  87.  
  88. int same(char * first,  char * second)
  89.     {
  90.     if (strcmp(first, second) == 0)
  91.         return(1);
  92.     else
  93.         return(0);
  94.     }
  95.  
  96. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  97.  
  98. int different(char * first,  char * second)
  99.     {
  100.     if (strcmp(first, second) != 0)
  101.         return(1);
  102.     else
  103.         return(0);
  104.     }
  105.     
  106.  
  107. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  108.  
  109. struct monsterInfo resetMonsterParameters(struct monsterInfo Googelon)
  110.     {
  111.     register int i;
  112.  
  113.     /************************************/
  114.     /* reset general monster parmeters  */
  115.     /************************************/
  116.  
  117.     Googelon.monsterScore       = 0;
  118.     Googelon.monsterIsDead      = 0;
  119.     Googelon.deadCount          = 0;
  120.     Googelon.timeDead           = 0;
  121.  
  122.     Googelon.energyRemaining    = MAXLIFE;
  123.  
  124.     Googelon.moveCount          = 0;
  125.  
  126.     Googelon.headHorzRotate     = 0;
  127.     Googelon.headVertRotate     = 150;
  128.     Googelon.beamOn             = 0;
  129.  
  130.     Googelon.monsterID          = rand();
  131.  
  132.     for(i=0; i<MAXTRIBUTES; i++)
  133.         {       
  134.         Googelon.a[i][0] = randy(0.2);
  135.         Googelon.a[i][1] = PLANEY + 0.55 + randy(0.5);
  136.         Googelon.a[i][2] = randy(0.2);
  137.  
  138.         Googelon.a[i][3] = 0;
  139.  
  140.         Googelon.a[i][4] = (rand() % 32) * 0.1;
  141.         }
  142.  
  143.     /*************************************/
  144.     /* reset specific monster parameters */
  145.     /*************************************/
  146.     
  147.     switch(Googelon.monster){
  148.         case GOOGELON:  Googelon.speed      = 0.08;
  149.                         Googelon.xspeed     = 30;
  150.                         Googelon.moveCost   = 0.1;
  151.                         Googelon.height     = PLANEY + 1.3;
  152.                         Googelon.width      = 0.3;
  153.                         Googelon.bottom     = PLANEY;
  154.                         Googelon.regenRate  = 0.1;
  155.                         break;
  156.                         
  157.         case VAPOUR:    Googelon.speed      = 0.12;
  158.                         Googelon.xspeed     = 40;
  159.                         Googelon.moveCost   = 0.05;
  160.                         Googelon.height     = PLANEY + 1.3;
  161.                         Googelon.width      = 0.3;
  162.                         Googelon.bottom     = PLANEY;
  163.                         Googelon.regenRate  = 0.14;
  164.                         break;
  165.                         
  166.         case TECHS:     Googelon.speed      = 0.06;
  167.                         Googelon.xspeed     = 35;
  168.                         Googelon.moveCost   = 0.1;
  169.                         Googelon.height     = PLANEY + 1.3;
  170.                         Googelon.width      = 0.3;
  171.                         Googelon.bottom     = PLANEY;
  172.                         Googelon.regenRate  = 0.1;
  173.                         break;
  174.                         
  175.         case FLUTTER:   Googelon.speed      = 0.12;
  176.                         Googelon.xspeed     = 40;
  177.                         Googelon.moveCost   = 0.06;
  178.                         Googelon.height     = PLANEY + 1.4;
  179.                         Googelon.width      = 0.5;
  180.                         Googelon.bottom     = PLANEY + 0.9;
  181.                         Googelon.regenRate  = 0.1;
  182.                         break;
  183.                         
  184.         default:        showError("Bogus Monster! (setPlayConditions)");
  185.                         break;
  186.     }
  187.     
  188.     return(Googelon);
  189.     }
  190.  
  191. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  192. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  193. /* techs is firing a projectile                                  */
  194. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  195.  
  196. void updateGun(float xhead, float zhead, int horz, int vert, int counter, struct monsterInfo *m)
  197.     {
  198.     float x, y, z;
  199.     
  200.     if (counter % 2)
  201.         {
  202.         x = 0.2* -cos((900+horz) * BIG_DEG_TO_RAD);
  203.         y = 0.2*  cos((900+vert) * BIG_DEG_TO_RAD);
  204.         z = 0.2*  sin((900+horz) * BIG_DEG_TO_RAD);
  205.  
  206.         addProjectile(xhead, PLANEY+1.2, zhead, PROJTECHS, x, y, z, 1000, m);
  207.         }
  208.     }
  209.  
  210. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  211. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  212. /* the vapour is leaving a fire trail                            */
  213. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  214.  
  215. void updateVap(float x,  float z, int counter, struct monsterInfo *m)
  216.     {
  217.     if (counter % 2)
  218.         addProjectile( x, PLANEY+0.12, z, PROJFIRE, 0, -0.0005, 0, 10000, m);
  219.     }
  220.  
  221.  
  222. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  223. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  224. /* googelon/flutter is firing their energy beam                  */
  225. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  226.  
  227. void updateBeam(struct monsterInfo * g,  struct targetInfo * t, float x, float z, struct tank * allTanks,  
  228.                 struct tree ** allTreePtrs, int numTrees, struct monsterInfo * m)
  229.     {
  230.     struct targetInfo * temptarget;
  231.     struct tank * ttank, * temptank;
  232.     struct tree * ttree;
  233.     float loc1[3],  loc3[3];
  234.     float rtankhorz,  rtankvert;
  235.     float atankhorz,  atankvert;
  236.     float abeamhorz,  abeamvert;
  237.     float rbeamhorz,  rbeamvert;
  238.     float hdiff,  vdiff;
  239.     float tankx,  tanky,  tankz;
  240.     float beamx,  beamy,  beamz;
  241.     float height;
  242.     float R;
  243.     int itsDead;
  244.     int i;
  245.     int horz, vert;
  246.     
  247.     
  248.     horz = m->headHorzRotate;
  249.     vert = m->headVertRotate;
  250.  
  251.  
  252.     doSound(MONSTERBEAM);
  253.         
  254.     if (vert < 175)
  255.         R = 4;
  256.     else
  257.         R = 1.2 / (cos((900 - vert) * BIG_DEG_TO_RAD));
  258.         
  259.     loc3[0] = x + R * -cos((900 + horz) * BIG_DEG_TO_RAD);
  260.     loc3[2] = z + R * sin((900 + horz) * BIG_DEG_TO_RAD);
  261.  
  262.     if (vert < 0)
  263.         loc3[1] = PLANEY+1.2 + R * sin(fabs(vert* BIG_DEG_TO_RAD));
  264.     else
  265.         loc3[1] = PLANEY+1.2 - R * sin(fabs(vert* BIG_DEG_TO_RAD));
  266.  
  267.  
  268.     loc1[0] = x;
  269.     loc1[1] = PLANEY + 1.2;
  270.     loc1[2] = z;
  271.  
  272.  
  273.     /**********************************/
  274.     /* does beam touch ground         */
  275.     /**********************************/
  276.  
  277.     if (loc3[1] <= PLANEY + 0.1)
  278.         {
  279.         addProjectile(loc3[0], PLANEY + 0.175, loc3[2], PROJSCAR, 0, -0.0075, 0, 0, NULL);
  280.         }
  281.         
  282.     /******************************/
  283.     /* what does beam hit         */
  284.     /******************************/
  285.     
  286.     if ((loc3[2] - loc1[2]) == 0)
  287.         loc1[2] += NEARZERO;
  288.             
  289.     rbeamhorz = fabs(sqrt(pow(loc3[0] - loc1[0], 2) + pow(loc3[2] - loc1[2], 2)));
  290.     abeamhorz = atan((loc3[0] - loc1[0]) / (loc3[2] - loc1[2]));
  291.  
  292.     if ((loc3[2] - loc1[2]) < 0)
  293.         abeamhorz += PI;
  294.  
  295.     hdiff = - abeamhorz;
  296.  
  297.     beamx = 0;          /* rbeamhorz * sin(abeamhorz + hdiff); */
  298.     beamz = rbeamhorz;  /* rbeamhorz * cos(abeamhorz + hdiff); */
  299.     
  300.     if (beamz == 0)
  301.         beamz = NEARZERO;
  302.  
  303.     rbeamvert = fabs(sqrt(pow(loc3[1] - loc1[1], 2) + beamz*beamz));
  304.     abeamvert = atan( (loc3[1] - loc1[1]) / beamz);
  305.  
  306.     vdiff = -abeamvert;
  307.     beamy = 0;          /* rbeamvert * sin(abeamvert + vdiff); */
  308.     beamz = rbeamvert;  /* rbeamvert * cos(abeamvert + vdiff); */
  309.     
  310.     if (beamz < 0)
  311.         abeamvert += PI;
  312.  
  313.     /**********************************/
  314.     /* does beam touch a tank         */
  315.     /**********************************/
  316.             
  317.     temptank    = allTanks;
  318.  
  319.     while(temptank->next != NULL)
  320.         {
  321.         ttank = temptank->next;
  322.  
  323.         if ((ttank->z - loc1[2]) == 0)
  324.             loc1[2] += NEARZERO; 
  325.  
  326.         rtankhorz = fabs(sqrt((pow(ttank->x - loc1[0], 2) + pow(ttank->z - loc1[2], 2))));
  327.         atankhorz = atan( (ttank->x - loc1[0]) / (ttank->z - loc1[2]));
  328.  
  329.         if ((ttank->z - loc1[2]) < 0)
  330.             atankhorz += PI;
  331.     
  332.         tankx = rtankhorz * sin(atankhorz + hdiff);
  333.         tankz = rtankhorz * cos(atankhorz + hdiff);
  334.  
  335.         if (tankz == 0)
  336.             tankz = NEARZERO;
  337.  
  338.         if ((ttank->type == HELO) || (ttank->type == CHH))
  339.             {
  340.             rtankvert = fabs(sqrt(pow(ttank->y - loc1[1], 2) + tankz*tankz));
  341.             atankvert = atan( (ttank->y - loc1[1]) / tankz);
  342.             }
  343.         else /* tanks are positioned IN the ground so raise them up a bit */
  344.             {
  345.             rtankvert = fabs(sqrt(pow(ttank->y+0.2 - loc1[1], 2) + tankz*tankz));
  346.             atankvert = atan( (ttank->y+0.2 - loc1[1]) / tankz);
  347.             }
  348.  
  349.         if (tankz < 0)
  350.             atankvert += PI;
  351.  
  352.         tanky = rtankvert * sin(atankvert + vdiff);
  353.         tankz = rtankvert * cos(atankvert + vdiff);
  354.  
  355.         itsDead = 0;
  356.  
  357.         switch(ttank->type){
  358.             case TANK:
  359.             case LAUNCHER:
  360.             case MASERTANK: if ((fabs(ttank->z - loc3[2]) <= BEAMKILL) &&
  361.                                 (fabs(ttank->y - loc3[1]) <= 0.3) &&
  362.                                 (fabs(ttank->x - loc3[0]) <= BEAMKILL))
  363.                                 itsDead = 1;
  364.                             break;
  365.                             
  366.             case HELO:
  367.             case CHH:       if ((tankz >= 0) && (tankz <= (beamz + 0.2)) &&
  368.                                 (fabs(tankx) < 0.15) && (fabs(tanky) < 0.15))  
  369.                                 itsDead = 1;
  370.                             break;
  371.  
  372.             case AIRPLANE: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) &&
  373.                                 (fabs(tankx) < 0.50) && (fabs(tanky) < 0.40))
  374.                                 itsDead = 1;
  375.                             break;
  376.  
  377.             case FIGHTER: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) &&
  378.                                 (fabs(tankx) < 0.40) && (fabs(tanky) < 0.30))
  379.                                 itsDead = 1;
  380.                             break;
  381.                     
  382.             case MECHAG:    if ((tankz >= 0) && (tankz <= (beamz+0.2)) &&
  383.                                 (fabs(tankx) < 0.25) && (fabs(tanky) < 0.55))
  384.                                 itsDead = 1;
  385.                             break;
  386.  
  387.             case HERO:      if ((tankz >= 0) && (tankz <= (beamz+0.2)) &&
  388.                                 (fabs(tankx) < 0.2) && (fabs(tanky) < 0.55))
  389.                                 itsDead = 1;
  390.                             break;
  391.                                 
  392.             default:        showError("Bogus Vehicle in Tank List! (updateBeam)");
  393.                             break;
  394.             }
  395.  
  396.         if (itsDead)
  397.             {
  398.             ttank->damage -= 1;
  399.  
  400.             switch (ttank->type)
  401.                 {
  402.                 case TANK:
  403.                 case LAUNCHER:
  404.                 case MASERTANK:
  405.                 case AIRPLANE:
  406.                 case FIGHTER:
  407.                 case HELO:          addScore(ttank->type, m);
  408.                                     break;
  409.                                     
  410.                 case MECHAG:        addScore(PARTIALM, m);
  411.                                     break;
  412.                                     
  413.                 case CHH:           addScore(PARTIALC, m);
  414.                                     break;
  415.                                     
  416.                 case HERO:          addScore(PARTIALH, m);
  417.                                     break;
  418.                 }
  419.             
  420.             if (ttank->damage <= 0)
  421.                 {
  422.                 /**********************************/
  423.                 /* if so, slag it!                */
  424.                 /**********************************/
  425.  
  426.                 doSound(SLAG);
  427.             
  428.                 ttank->damage = -99;
  429.                 }               
  430.             }
  431.             
  432.         temptank = temptank->next;
  433.         }
  434.  
  435. /***********************/
  436. /* check other targets */
  437. /***********************/
  438.  
  439.     temptarget = t->next;
  440.  
  441.     while(temptarget != NULL)
  442.         {
  443.         if (temptarget->monster.monsterID != m->monsterID)
  444.             {
  445.             if ((temptarget->z - loc1[2]) == 0)
  446.                 loc1[2] += NEARZERO; 
  447.     
  448.             rtankhorz = fabs(sqrt((pow(temptarget->x - loc1[0], 2) + pow(temptarget->z - loc1[2], 2))));
  449.             atankhorz = atan( (temptarget->x - loc1[0]) / (temptarget->z - loc1[2]));
  450.     
  451.             if ((temptarget->z - loc1[2]) < 0)
  452.                 atankhorz += PI;
  453.         
  454.             tankx = rtankhorz * sin(atankhorz + hdiff);
  455.             tankz = rtankhorz * cos(atankhorz + hdiff);
  456.     
  457.             if (tankz == 0)
  458.                 tankz = NEARZERO;
  459.     
  460.             rtankvert = fabs(sqrt(pow(((temptarget->monster.height * 0.5 + temptarget->monster.bottom * 0.5) - loc1[1]), 2) + tankz*tankz));
  461.             atankvert = atan( ((temptarget->monster.height * 0.5 + temptarget->monster.bottom * 0.5) - loc1[1]) / tankz);
  462.  
  463.  
  464.     
  465.             if (tankz < 0)
  466.                 atankvert += PI;
  467.     
  468.             tanky = rtankvert * sin(atankvert + vdiff);
  469.             tankz = rtankvert * cos(atankvert + vdiff);
  470.     
  471.             itsDead = 0;
  472.     
  473.             switch(temptarget->monster.monster){
  474.     
  475.                 case FLUTTER: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) &&
  476.                                     (fabs(tankx) < 0.40) && (fabs(tanky) < 0.30))
  477.                                     itsDead = 1;
  478.                                 break;
  479.                         
  480.                 case GOOGELON:
  481.                 case VAPOUR:
  482.                 case TECHS:    if ((tankz >= 0) && (tankz <= (beamz+0.2)) &&
  483.                                     (fabs(tankx) < 0.25) && (fabs(tanky) < 0.55))
  484.                                     itsDead = 1;
  485.                                 break;
  486.                                     
  487.                 default:            showError("Bogus Monster in Target List! (updateBeam)");
  488.                                 break;
  489.                 }
  490.     
  491.             if (itsDead)
  492.                 {
  493. /*              addScore(MONSTER, m); */
  494.                 temptarget->monster.energyRemaining -= 1;
  495.                 }
  496.                 
  497.             }
  498.             temptarget = temptarget->next;
  499.         }
  500.  
  501.  
  502. /**************************/
  503. /* check player's monster */
  504. /**************************/
  505.  
  506.         if (g != m)
  507.             {
  508.             if ((0 - loc1[2]) == 0)
  509.                 loc1[2] += NEARZERO; 
  510.     
  511.             rtankhorz = fabs(sqrt(loc1[0]*loc1[0] + loc1[2]*loc1[2]));
  512.             atankhorz = atan( loc1[0] / loc1[2]);
  513.     
  514.             if (-loc1[2] < 0)
  515.                 atankhorz += PI;
  516.         
  517.             tankx = rtankhorz * sin(atankhorz + hdiff);
  518.             tankz = rtankhorz * cos(atankhorz + hdiff);
  519.     
  520.             if (tankz == 0)
  521.                 tankz = NEARZERO;
  522.     
  523.             rtankvert = fabs(sqrt(pow(((g->height * 0.5 + g->bottom * 0.5) - loc1[1]), 2) + tankz*tankz));
  524.             atankvert = atan( ((g->height * 0.5 + g->bottom * 0.5) - loc1[1]) / tankz);
  525.  
  526.  
  527.     
  528.             if (tankz < 0)
  529.                 atankvert += PI;
  530.     
  531.             tanky = rtankvert * sin(atankvert + vdiff);
  532.             tankz = rtankvert * cos(atankvert + vdiff);
  533.     
  534.             itsDead = 0;
  535.     
  536.             switch(g->monster){
  537.     
  538.                 case FLUTTER: if ((tankz >= 0) && (tankz <= (beamz + 0.2)) &&
  539.                                     (fabs(tankx) < 0.40) && (fabs(tanky) < 0.30))
  540.                                     itsDead = 1;
  541.                                 break;
  542.                         
  543.                 case GOOGELON:
  544.                 case VAPOUR:
  545.                 case TECHS:    if ((tankz >= 0) && (tankz <= (beamz+0.2)) &&
  546.                                     (fabs(tankx) < 0.25) && (fabs(tanky) < 0.55))
  547.                                     itsDead = 1;
  548.                                 break;
  549.                                     
  550.                 default:            showError("Bogus Monster in Target List! (updateBeam)");
  551.                                 break;
  552.                 }
  553.     
  554.             if (itsDead)
  555.                 {
  556.                 addScore(MONSTER, m);
  557.                 g->energyRemaining -= 1;
  558.                 }
  559.                 
  560.             }
  561.  
  562.  
  563.  
  564.  
  565.  
  566.         
  567.         /**********************************/
  568.         /* does beam touch a tree         */
  569.         /**********************************/
  570.  
  571.     for (i=0;i<numTrees;i++)
  572.         {
  573.         ttree = allTreePtrs[i];
  574.         
  575.         if ((ttree->z - loc1[2]) == 0)
  576.             loc1[2] += NEARZERO; 
  577.  
  578.         rtankhorz = fabs(sqrt(pow(ttree->x - loc1[0], 2) + pow(ttree->z - loc1[2], 2)));
  579.         atankhorz = atan( (ttree->x - loc1[0]) / (ttree->z - loc1[2]));
  580.  
  581.         if ((ttree->z - loc1[2]) < 0)
  582.             atankhorz += PI;
  583.     
  584.         tankx = rtankhorz * sin(atankhorz + hdiff);
  585.         tankz = rtankhorz * cos(atankhorz + hdiff);
  586.         
  587.         /* y of building is located on the plane*/
  588.  
  589.         if (ttree->type == 1)
  590.             switch(ttree->treeshape){
  591.                 case 1: 
  592.                 case 11:
  593.                 case 14:
  594.                 case 22:
  595.                 case 23:
  596.                 case 24:    height = 0.8;
  597.                             break;
  598.                 case 5:
  599.                 case 6:
  600.                 case 13:
  601.                 case 28:
  602.                 case 31:
  603.                 case 32:    height = 0.3;
  604.                             break;
  605.                 default:    height = 0.5;
  606.                             break;
  607.                 }
  608.         else
  609.             height = 0.5;
  610.         
  611.         if (tankz == 0)
  612.             tankz = NEARZERO;
  613.  
  614.         rtankvert = fabs(sqrt(pow(ttree->y + height - loc1[1], 2) + tankz * tankz));
  615.         atankvert = atan( (ttree->y + height - loc1[1]) / tankz);
  616.  
  617.         if (tankz < 0)
  618.             atankvert += PI;
  619.  
  620.         tanky = rtankvert * sin(atankvert + vdiff);
  621.         tankz = rtankvert * cos(atankvert + vdiff);
  622.  
  623.         if ((tankz >= 0) && (tankz <= (beamz + 0.2)) &&
  624.             (fabs(tankx) < 0.4) && (fabs(tanky) < height))
  625.                 {
  626.                 if ((ttree->intact) && (ttree->type == 1))
  627.                     addScore(BUILDING, m);
  628.                 ttree->intact = 0;
  629.                 }
  630.         }
  631.     }
  632.  
  633.  
  634. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  635. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  636. /* decide whether a vehicle has been hit                         */
  637. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  638.  
  639. int tankHit(struct tank * ttank, float xloc, float yloc, float zloc)
  640.     {
  641.     float blastx, blasty, blastz;
  642.     
  643.      switch(ttank->type){
  644.         case TANK:
  645.         case LAUNCHER:
  646.         case MASERTANK:     blastx = blasty = blastz = BLASTRX05;
  647.                             break;
  648.  
  649.         case HELO:          blastx = blastz = BLASTRX075;
  650.                             blasty = BLASTRX07;
  651.                             break;
  652.  
  653.         case AIRPLANE:      blastx = blastz = BLASTR;
  654.                             blasty = BLASTRX07;
  655.                             break;
  656.  
  657.         case FIGHTER:       blastx = blastz = BLASTR;
  658.                             blasty = BLASTRX05;
  659.                             break;
  660.  
  661.         case CHH:           blastx = blastz = BLASTRX06;
  662.                             blasty = BLASTRX04;
  663.                             break;
  664.  
  665.         case MECHAG:        blastx = blastz = BLASTR;
  666.                             blasty = BLASTRX2;
  667.                             break;
  668.  
  669.         case HERO:          blastx = blastz = BLASTRX04;
  670.                             blasty = BLASTRX2;
  671.                             break;
  672.  
  673.         default:            showError("Bogus Vehicle in Tank List! (tankHit)");
  674.                             break;
  675.         }
  676.                 
  677.     if ((fabs(ttank->x - xloc) < blastx) &&
  678.         (fabs(ttank->z - zloc) < blastz) &&
  679.         (fabs(ttank->y - yloc) < blasty))
  680.             return(1);
  681.     else
  682.             return(0);
  683.     }
  684.  
  685.  
  686.