home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / target.c < prev    next >
C/C++ Source or Header  |  1999-09-27  |  11KB  |  538 lines

  1. /*
  2.  
  3. ORBIT, a freeware space combat simulator
  4. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20. */
  21.  
  22. #include "orbit.h"
  23.  
  24. InitTargets()
  25. /*
  26.  *  Set up targets
  27.  */
  28. {
  29.     int t;
  30.  
  31.     for (t=0; t<NTARGETS; t++)
  32.     {
  33.         target[t].age = target[t].msl_idle = 0.0;
  34.         target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  35.  
  36.         target[t].hidden = 0;
  37.         target[t].friendly = 0;
  38.         target[t].invisible = 0;
  39.  
  40.         target[t].move_forward = target[t].move_backward =
  41.             target[t].move_up = target[t].move_down =
  42.             target[t].move_pitchleft = target[t].move_pitchright =
  43.             target[t].move_left = target[t].move_right = 0.0;
  44.  
  45.         target[t].weapon = NPLAYER_WEAPONS;
  46.         target[t].shields = 100.0;
  47.         target[t].maxshields = 100.0;
  48.  
  49.         strcpy (target[t].name, "Sparky");
  50.     }
  51. }
  52.  
  53. int FindTarget()
  54. /*
  55.  *  Find an unsed target
  56.  */
  57. {
  58.     int i, oldest;
  59.     double maxage;
  60.  
  61.     for (i=0; i<NTARGETS; i++)
  62.     {
  63.         if (target[i].age == 0.0) return (i);
  64.  
  65.         if (i == 0)
  66.         {
  67.             oldest = i;
  68.             maxage = target[i].age;
  69.         }
  70.         else
  71.         {
  72.             if (target[i].age > maxage)
  73.             {
  74.                 maxage = target[i].age;
  75.                 oldest = i;
  76.             }
  77.         }
  78.     }
  79.  
  80.     return (oldest);
  81. }
  82.  
  83. int FindTargetByName (name)
  84. char *name;
  85. {
  86.     int t;
  87.  
  88.     for (t=0; t<NTARGETS; t++)
  89.     {
  90.         if ( (target[t].age > 0.0) &&
  91.              (!strcasecmp (name, target[t].name)) )
  92.         {
  93.             return (t);
  94.         }
  95.     }
  96.  
  97.     return (-1);
  98. }
  99.  
  100. PlaceTarget (x, y, z)
  101. double x, y, z;
  102. /*
  103.  *  Put a brand new target somewhere
  104.  */
  105. {
  106.     int t;
  107.  
  108.     t = FindTarget();
  109.  
  110.     target[t].pos[0] = x;
  111.     target[t].pos[1] = y;
  112.     target[t].pos[2] = z;
  113.  
  114.     target[t].view[0] = 1.0;
  115.     target[t].view[1] = target[t].view[2] = 0.0;
  116.  
  117.     target[t].up[0] = 0.0;
  118.     target[t].up[1] = 0.0;
  119.     target[t].up[2] = 1.0;
  120.  
  121.     Crossp (target[t].right, target[t].up, target[t].view);
  122.  
  123.     if (deltaT == 0.0)
  124.     {
  125.         target[t].age = 0.1;
  126.     }
  127.     else
  128.     {
  129.         target[t].age = deltaT;
  130.     }
  131.  
  132.     target[t].msl_idle = 0.0;
  133.  
  134.     target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  135.  
  136.     target[t].move_forward = target[t].move_backward =
  137.         target[t].move_up = target[t].move_down =
  138.         target[t].move_pitchleft = target[t].move_pitchright =
  139.         target[t].move_left = target[t].move_right = 0.0;
  140.  
  141.     strcpy (target[t].name, "Target");
  142.     target[t].list = model[0].list;
  143. }
  144.  
  145. PlaceRandomTarget()
  146. /*
  147.  *  Put a target somewhere reasonable, randomly
  148.  */
  149. {
  150.     double x, y, z, th;
  151.  
  152.     th = 2.0 * rnd (6.28);
  153.  
  154.     x = planet[3].pos[0] + 2.0 * planet[3].radius * sin (th);
  155.     y = planet[3].pos[1] + 2.0 * planet[3].radius * cos (th);
  156.     z = planet[3].pos[2];
  157.  
  158.     PlaceTarget (x, y, z);
  159. }
  160.  
  161. DestroyTarget (t)
  162. int t;
  163. /*
  164.  *  Destroy specified target
  165.  */
  166. {
  167.     int e;
  168.  
  169.     target[t].age = 0.0;
  170.  
  171.     player.score += target[t].score;
  172.  
  173.     /* If this was the locked target, unset lock */
  174.     CheckLock();
  175.  
  176.     /* Check to see if destroying this target triggers an event */
  177.     for (e=0; e<NEVENTS; e++)
  178.     {
  179.         if (event[e].pending &&
  180.             event[e].enabled &&
  181.             (event[e].trigger == EVENT_DESTROY) &&
  182.             (!strcasecmp (event[e].cvalue, target[t].name)) )
  183.         {
  184.             EventAction (e);
  185.         }
  186.     }
  187. }
  188.  
  189. static float lmodel_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
  190.  
  191. DrawTargets ()
  192. /*
  193.  *  Draw all the targets
  194.  */
  195. {
  196.     int i;
  197.  
  198.     glShadeModel (GL_FLAT);
  199.  
  200.     /* Need some ambient light for targets */
  201.     glLightfv (GL_LIGHT0, GL_AMBIENT, lmodel_ambient);
  202.  
  203.     for (i=0; i<NTARGETS; i++)
  204.     {
  205.         if (target[i].age > 0.0) DrawTarget (i);
  206.     }
  207.  
  208.     glShadeModel (GL_SMOOTH);
  209. }
  210.  
  211. DrawTarget (i)
  212. int i;
  213. /*
  214.  *  Draw this target
  215.  */
  216. {
  217.     double v[3];
  218.  
  219.     /* Bump this target's age */
  220.     target[i].age += deltaT;
  221.  
  222.     /* Forget it if target is hidden or invisible */
  223.     if (target[i].hidden || target[i].invisible) return;
  224.  
  225.     /* Don't bother if target is too far away */
  226.     if (target[i].range2 > TARG_MAXRANGE2) return;
  227.  
  228.     /* Bail if couldn't load model */
  229.     if (target[i].model == (-1)) return;
  230.  
  231.     glPushMatrix();
  232.  
  233.     Vsub (v, target[i].pos, player.pos);
  234.     glTranslated (v[0], v[1], v[2]);
  235.  
  236.     /* Show up vector */
  237. /*    glDisable (GL_LIGHTING);
  238.     glColor3f (0.0, 1.0, 0.0);
  239.     glBegin (GL_LINES);
  240.     glVertex3f (0.0, 0.0, 0.0);
  241.     glVertex3dv (target[i].up);
  242.     glEnd();
  243.     glEnable (GL_LIGHTING);    */
  244.  
  245.     /* Have target look in proper direction */
  246.     LookAt (target[i].view, target[i].up);
  247.  
  248.     /* Draw it */
  249.     glCallList (target[i].list);
  250.  
  251.     /* Draw bounding box */
  252. /*    if (i == lock.target)
  253.     {
  254.         m = target[i].model;
  255.  
  256.         glDisable (GL_LIGHTING);
  257.         glColor3f (1.0, 1.0, 0.0);
  258.         glScaled (model[m].hibound[0] - model[m].lobound[0],
  259.                   model[m].hibound[1] - model[m].lobound[1],
  260.                   model[m].hibound[2] - model[m].lobound[2]);
  261.         glutWireCube (1.0);
  262.         glEnable (GL_LIGHTING);
  263.     }
  264. */
  265.     glPopMatrix();
  266. }
  267.  
  268. MoveTargets()
  269. /*
  270.  *  Move all the targets
  271.  */
  272. {
  273.     int t;
  274.     double v[3];
  275.  
  276.     for (t=0; t<NTARGETS; t++)
  277.     {
  278.         if (target[t].age > 0.0)
  279.         {
  280.             /* Determine distance from player */
  281.             Vsub (v, target[t].pos, player.pos);
  282.             target[t].range2 = Mag2 (v);
  283.  
  284.             if (!target[t].hidden)
  285.             {
  286.                 target[t].age += deltaT;
  287.                 target[t].msl_idle += deltaT;
  288.  
  289.                 /* Give this target a chance to think */
  290.                 if (target[t].range2 < TARG_MAXRANGE2) ThinkTarget (t);
  291.  
  292.                 /* Now move it */
  293.                 MoveTarget (t);
  294.             }
  295.         }
  296.     }
  297. }
  298.  
  299. MoveTarget (t)
  300. int t;
  301. /*
  302.  *  Move this target
  303.  */
  304. {
  305.     double deltav[3], v[3], theta;
  306.     int p;
  307.  
  308.     /* Is this a network game and this target is us? */
  309. /*
  310.     if (am_client && (t == client[clientme.client].target)) return;
  311.     if (am_server && (t == client[server.client].target)) return;
  312. */
  313.     /* Compute angle to move, given time change */
  314.     theta = THETA * deltaT;
  315.  
  316.     /* Deltav will be change in velocity components due to thrust */
  317.     deltav[0] = deltav[1] = deltav[2] = 0.0;
  318.  
  319.     if (target[t].move_left > 0.0)
  320.     {        
  321.         RotateAbout (v, target[t].view, target[t].up, -theta*target[t].move_left);
  322.         Vset (target[t].view, v);
  323.         Normalize (target[t].view);
  324.         Crossp (target[t].right, target[t].up, target[t].view);
  325.         Normalize (target[t].right);
  326.     }
  327.  
  328.     if (target[t].move_right > 0.0)
  329.     {
  330.         RotateAbout (v, target[t].view, target[t].up, theta*target[t].move_right);
  331.         Vset (target[t].view, v);
  332.         Normalize (target[t].view);
  333.         Crossp (target[t].right, target[t].up, target[t].view);
  334.         Normalize (target[t].right);
  335.     }
  336.  
  337.     if (target[t].move_up > 0.0)
  338.     {
  339.         RotateAbout (v, target[t].view, target[t].right, theta*target[t].move_up);
  340.         Vset (target[t].view, v);
  341.         Normalize (target[t].view);
  342.         Crossp (target[t].up, target[t].view, target[t].right);
  343.         Normalize (target[t].up);
  344.     }
  345.  
  346.     if (target[t].move_down > 0.0)
  347.     {
  348.         RotateAbout (v, target[t].view, target[t].right, -theta*target[t].move_down);
  349.         Vset (target[t].view, v);
  350.         Normalize (target[t].view);
  351.         Crossp (target[t].up, target[t].view, target[t].right);
  352.         Normalize (target[t].up);
  353.     }
  354.  
  355.     if (target[t].move_pitchright > 0.0)
  356.     {
  357.         RotateAbout (v, target[t].up, target[t].view, -theta*target[t].move_pitchright);
  358.         Vset (target[t].up, v);
  359.         Normalize (target[t].up);
  360.         Crossp (target[t].right, target[t].up, target[t].view);
  361.         Normalize (target[t].right);
  362.     }
  363.  
  364.     if (target[t].move_pitchleft > 0.0)
  365.     {
  366.         RotateAbout (v, target[t].up, target[t].view, theta*target[t].move_pitchleft);
  367.         Vset (target[t].up, v);
  368.         Normalize (target[t].up);
  369.         Crossp (target[t].right, target[t].up, target[t].view);
  370.         Normalize (target[t].right);
  371.     }
  372.  
  373.     if (target[t].move_forward > 0.0)
  374.     {
  375.         Vmul (v, target[t].view, target[t].move_forward*DELTAV*deltaT);
  376.         Vadd (deltav, deltav, v);
  377.     }
  378.  
  379.     if (target[t].move_backward > 0.0)
  380.     {
  381.         Vmul (v, target[t].view, -target[t].move_backward*DELTAV*deltaT);
  382.         Vadd (deltav, deltav, v);
  383.     }
  384.  
  385.     /* Compute change to velocity */
  386.     Vadd (target[t].vel, target[t].vel, deltav);
  387.  
  388.     /* Compute gravity's contribution */
  389.     if (gravity && (am_client || am_server))
  390.     {
  391.         Gravity (deltav, target[t].pos);
  392.         Vadd (target[t].vel, target[t].vel, deltav);
  393.     }
  394.  
  395.     /* Finaly, move target */
  396.     Vmul (v, target[t].vel, deltaT);
  397.     Vadd (target[t].pos, target[t].pos, v);
  398.  
  399.     target[t].move_forward = target[t].move_backward = 0.0;
  400.  
  401.     if ( (!am_client) && (!am_server) )
  402.     {
  403.         target[t].move_up = target[t].move_down =
  404.         target[t].move_pitchleft = target[t].move_pitchright =
  405.         target[t].move_left = target[t].move_right = 0.0;
  406.     }
  407.  
  408.     /* See if target[t] cratered on a planet */
  409.     if ((!am_client) && ((-1) != (p = InsidePlanet (target[t].pos))))
  410.     {
  411.         /* Make an explosion */
  412.         Vmul (v, target[t].pos, 1.05);
  413.         Boom (v, 1.0);
  414.         if (am_server)
  415.         {
  416.             NetTargetCratered (t, p);
  417.         }
  418.         else
  419.         {
  420.             DestroyTarget (t);
  421.         }
  422.     }
  423.  
  424.     /* Regenerate target shields */
  425.     target[t].shields += target[t].shieldregen * deltaT;
  426.     if (target[t].shields > target[t].maxshields)
  427.         target[t].shields = target[t].maxshields;
  428. }
  429.  
  430. TargetFiresMissile (t)
  431. int t;
  432. /*
  433.  *  Target t tries to fire missile at player
  434.  */
  435. {
  436.     if (target[t].msl_idle > weapon[target[t].weapon].idle)
  437.     {
  438.         /* Fire away! */
  439.         target[t].msl_idle = 0.0;
  440.         FireMissile (target[t].pos, target[t].vel, target[t].view,
  441.             target[t].friendly, target[t].weapon, t);
  442.     }
  443. }
  444.  
  445. ShowTargetNames()
  446. {
  447.     int t;
  448.     char v, buf[128];
  449.     double v1[3];
  450.  
  451.     for (t=0; t<NTARGETS; t++)
  452.     {
  453.         if ( (target[t].age > 0.0) &&
  454.              (target[t].range2 < TARG_MAXRANGE2) &&
  455.              (!target[t].hidden) &&
  456.              (!target[t].invisible) )
  457.         {
  458.             if (target[t].friendly)
  459.                 glColor3d (0.0, 0.8, 0.0);
  460.             else
  461.                 glColor3d (0.8, 0.0, 0.0);
  462.  
  463.             Vsub (v1, target[t].pos, player.pos);
  464.             glRasterPos3dv (v1);
  465.             glGetBooleanv (GL_CURRENT_RASTER_POSITION_VALID, &v);
  466.             if (v)
  467.             {
  468.                 if (target[t].range2 <= weapon[player.weapon].range2)
  469.                 {
  470.                     sprintf (buf, "%s:%.0lf", target[t].name, 
  471.                         KM_TO_UNITS1*sqrt(target[t].range2));
  472.                 }
  473.                 else
  474.                 {
  475.                     strcpy (buf, target[t].name);
  476.                 }
  477.                 Print (GLUT_BITMAP_HELVETICA_10, buf);
  478.             }
  479.         }
  480.     }
  481. }
  482.  
  483. int HitTarget (m)
  484. int m;
  485. /*
  486.  *  See if missile m hit any target.  -1 if not.
  487.  */
  488. {
  489.     int t, mdl, valid;
  490.     double v1[3], d;
  491.  
  492.     /* Loop through targets */
  493.     for (t=0; t<NTARGETS; t++)
  494.     {
  495.         /* See if we should even check this target */
  496.         if (!am_client && !am_server)
  497.         {
  498.             valid = (target[t].age > 0.0) &&
  499.                     (!target[t].hidden) &&
  500.                     (msl[m].friendly != target[t].friendly);
  501.         }
  502.         else
  503.         {
  504.             valid = (target[t].age > 0.0) &&
  505.                     (!target[t].hidden) &&
  506.                     (t != msl[m].owner);
  507.         }
  508.  
  509.         if (valid)
  510.         {
  511.             /* Get coords relative to target */
  512.             Vsub (v1, msl[m].pos, target[t].pos);
  513.  
  514.             /* Get target's model */
  515.             mdl = target[t].model;
  516.  
  517.             /* Check each axis by projecting v1 and checking bounding box */
  518.             d = Dotp (v1, target[t].view);
  519.             if ( (d < model[mdl].lobound[0]) ||
  520.                  (d > model[mdl].hibound[0]) ) continue;
  521.  
  522.             d = Dotp (v1, target[t].right);
  523.             if ( (d < model[mdl].lobound[1]) ||
  524.                  (d > model[mdl].hibound[1]) ) continue;
  525.  
  526.             d = Dotp (v1, target[t].up);
  527.             if ( (d < model[mdl].lobound[2]) ||
  528.                  (d > model[mdl].hibound[2]) ) continue;
  529.  
  530.             /* If we get here, it's a hit! */
  531.             return (t);
  532.         }
  533.     }
  534.  
  535.     /* Nope */
  536.     return (-1);
  537. }
  538.