home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / missile.c < prev    next >
C/C++ Source or Header  |  1999-09-27  |  8KB  |  447 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. InitMissiles()
  25. /*
  26.  *  Set up missile structures
  27.  */
  28. {
  29.     int i;
  30.  
  31.     /* Mark all missiles as unused */
  32.     for (i=0; i<NMSLS; i++)
  33.     {
  34.         msl[i].age = 0.0;
  35.     }
  36. }
  37.  
  38. int FindMissile()
  39. /*
  40.  *  Find unused missile
  41.  */
  42. {
  43.     int i, oldest;
  44.     double maxage;
  45.  
  46.     /* Look for free missile, or oldest */
  47.     for (i=0; i<NMSLS; i++)
  48.     {
  49.         if (msl[i].age == 0.0) return (i);
  50.  
  51.         if (i == 0)
  52.         {
  53.             maxage = msl[i].age;
  54.             oldest = i;
  55.         }
  56.         else
  57.         {
  58.             if (msl[i].age > maxage)
  59.             {
  60.                 maxage = msl[i].age;
  61.                 oldest = i;
  62.             }
  63.         }
  64.     }
  65.  
  66.     /* None free, return oldest */
  67.     return (oldest);
  68. }
  69.  
  70. FireMissile (pos, vel, dir, friendly, wep, owner)
  71. double pos[3], vel[3], dir[3];
  72. int friendly, wep, owner;
  73. /*
  74.  *  Fire missile at the given location and velocity, in
  75.  *  the specified direction
  76.  */
  77. {
  78.     int m;
  79.     double v[3];
  80.  
  81.     /* Find a free missile */
  82.     m = FindMissile();
  83.  
  84.     /* Set it up */
  85.     msl[m].age = deltaT;
  86.     Vset (msl[m].pos, pos);
  87.  
  88.     if (friendly && !am_client && !am_server)
  89.     {
  90.         Vmul (v, player.up, -0.005);
  91.         Vadd (msl[m].pos, msl[m].pos, v);
  92.     }
  93.  
  94.     Vmul (msl[m].vel, dir, weapon[wep].speed);
  95.     Vadd (msl[m].vel, msl[m].vel, vel);
  96.  
  97.     msl[m].friendly = friendly;
  98.     msl[m].weapon = wep;
  99.     msl[m].owner = owner;
  100.  
  101.     /* Play the sound */
  102. /*    if (sound) PlaySound ("phaser.wav", NULL, SND_ASYNC | SND_FILENAME);    */
  103.     if (sound) PlayAudio (SOUND_FIRE);
  104. }
  105.  
  106. MoveMissiles()
  107. /*
  108.  *  Move all the missiles
  109.  */
  110. {
  111.     int m, t, p;
  112.     double v[3], deltav[3];
  113.  
  114.     /* Loop through missiles */
  115.     for (m=0; m<NMSLS; m++)
  116.     {
  117.         /* If missile in use */
  118.         if (msl[m].age > 0.0)
  119.         {
  120.             /* Bump age */
  121.             msl[m].age += deltaT;
  122.  
  123.             /* See if expired */
  124.             if (msl[m].age > weapon[msl[m].weapon].expire)
  125.             {
  126.                 DestroyMissile (m);
  127.                 return;
  128.             }
  129.  
  130.             /* See if missile has hit planet */
  131.             if ((-1) != (p = InsidePlanet (msl[m].pos)))
  132.             {
  133.                 /* Missile has hit planet */
  134.  
  135.                 /* Move point of impact just above planet surface */
  136.                 Vsub (v, msl[m].pos, planet[p].pos);
  137.                 Normalize (v);
  138.                 Vmul (v, v, planet[p].radius*1.05);
  139.                 Vadd (v, v, planet[p].pos);
  140.                 Boom (v, weapon[msl[m].weapon].yield/100.0);
  141.                 DestroyMissile (m);
  142.                 return;
  143.             }
  144.  
  145.             /* See if missile hit a target */
  146.             if ((-1) != (t = HitTarget (m)))
  147.             {
  148.                 /* Missle hit target */
  149.                 MissileHitTarget (m, t);
  150.                 return;
  151.             }
  152.  
  153.             /* See if missile hit player */
  154.             if (!msl[m].friendly && !am_client &&
  155.                 (state != STATE_DEAD1) && (state != STATE_DEAD2) )
  156.             {
  157.                 if (TARGDIST2 > Dist2 (msl[m].pos[0], msl[m].pos[1], msl[m].pos[2],
  158.                                        player.pos[0], player.pos[1], player.pos[2]))
  159.                 {
  160.                     /* Missile hit player */
  161.                     MissileHitPlayer (m);
  162.                     return;
  163.                 }
  164.             }
  165.  
  166.             /* Else update its position */
  167.             if (gravity)
  168.             {
  169.                 Gravity (deltav, msl[m].pos);
  170.                 Vadd (msl[m].vel, msl[m].vel, deltav);
  171.             }
  172.             Vmul (v, msl[m].vel, deltaT);
  173.             Vadd (msl[m].pos, msl[m].pos, v);
  174.         }
  175.     }
  176. }
  177.  
  178. DestroyMissile (m)
  179. int m;
  180. /*
  181.  *  Missile has expired 
  182.  */
  183. {
  184.     msl[m].age = 0.0;
  185. }
  186.  
  187. DrawMissiles ()
  188. /*
  189.  *  Draw all the missiles
  190.  */
  191. {
  192.     int m;
  193.  
  194.     for (m=0; m<NMSLS; m++)
  195.     {
  196.         if (msl[m].age > 0.0) DrawMissile (m);
  197.     }
  198. }
  199.  
  200. DrawMissile (m)
  201. int m;
  202. /*
  203.  *  Draw this missile
  204.  */
  205. {
  206.     glPushMatrix();
  207.     glDisable (GL_LIGHTING);
  208.     glDisable (GL_CULL_FACE);
  209.  
  210.     switch (weapon[msl[m].weapon].renderer)
  211.     {
  212.     case 0:    DrawMissile0 (m);
  213.             break;
  214.  
  215.     case 1: DrawMissile1 (m);
  216.             break;
  217.  
  218.     case 2: DrawMissile2 (m);
  219.             break;
  220.  
  221.     case 3: DrawMissile3 (m);
  222.             break;
  223.  
  224.     case 4:    DrawMissile4 (m);
  225.             break;
  226.     }
  227.  
  228.     glEnable (GL_CULL_FACE);
  229.     glEnable (GL_LIGHTING);
  230.     glPopMatrix();
  231. }
  232.  
  233. DrawMissile0 (m)
  234. int m;
  235. {
  236.     double r, s, v[3];
  237.  
  238.     /* Figure how much to spin missile */
  239.     r = absT - ((double)(int)absT);
  240.     s = 360.0 * r;
  241.  
  242.     glColor3fv (weapon[msl[m].weapon].color);
  243.  
  244.     Vsub (v, msl[m].pos, player.pos);
  245.     glTranslated (v[0], v[1], v[2]);
  246.     glRotated (s, 0.3, 1.0, 0.6);
  247.  
  248.     glBegin (GL_LINES);
  249.     glVertex3d (-0.01, 0.0, 0.0);
  250.     glVertex3d ( 0.01, 0.0, 0.0);
  251.     glVertex3d (0.0, -0.01, 0.0);
  252.     glVertex3d (0.0,  0.01, 0.0);
  253.     glVertex3d (0.0, 0.0, -0.01);
  254.     glVertex3d (0.0, 0.0,  0.01);
  255.     glEnd();
  256. }
  257.  
  258. DrawMissile1 (m)
  259. int m;
  260. {
  261.     double r, s, v[3];
  262.  
  263.     /* Figure how much to spin missile */
  264.     r = absT - ((double)(int)absT);
  265.     s = 360.0 * r;
  266.  
  267.     glColor3fv (weapon[msl[m].weapon].color);
  268.  
  269.     Vsub (v, msl[m].pos, player.pos);
  270.     glTranslated (v[0], v[1], v[2]);
  271.     glRotated (s, 0.3, 1.0, 0.6);
  272.  
  273.     glBegin (GL_LINES);
  274.     glVertex3d (-0.01, 0.0, 0.0);
  275.     glVertex3d ( 0.01, 0.0, 0.0);
  276.     glVertex3d (0.0, -0.01, 0.0);
  277.     glVertex3d (0.0,  0.01, 0.0);
  278.     glVertex3d (0.0, 0.0, -0.01);
  279.     glVertex3d (0.0, 0.0,  0.01);
  280.     glEnd();
  281. }
  282.  
  283. DrawMissile2 (m)
  284. int m;
  285. {
  286.     double v1[3], v2[3], v3[3], v4[4], vel[3], v[3];
  287.  
  288.     glColor3fv (weapon[msl[m].weapon].color);
  289.  
  290.     Vsub (v, msl[m].pos, player.pos);
  291.     glTranslated (v[0], v[1], v[2]);
  292.  
  293.     Vmul (vel, msl[m].vel, 0.1);
  294.  
  295.     glBegin (GL_QUADS);
  296.  
  297.     v1[0] =  0.01; v1[1] = 0.0; v1[2] = 0.0;
  298.     v2[0] = -0.01; v2[1] = 0.0; v2[2] = 0.0;
  299.     Vsub (v3, v2, vel);
  300.      Vsub (v4, v1, vel);
  301.     glVertex3dv (v1);
  302.     glVertex3dv (v2);
  303.     glVertex3dv (v3);
  304.     glVertex3dv (v4);
  305.  
  306.     v1[0] = 0.0; v1[1] =  0.01; v1[2] = 0.0;
  307.     v2[0] = 0.0; v2[1] = -0.01; v2[2] = 0.0;
  308.     Vsub (v3, v2, vel);
  309.     Vsub (v4, v1, vel);
  310.     glVertex3dv (v1);
  311.     glVertex3dv (v2);
  312.     glVertex3dv (v3);
  313.     glVertex3dv (v4);
  314.  
  315.     v1[0] = 0.0; v1[1] = 0.0; v1[2] =  0.01;
  316.     v2[0] = 0.0; v2[1] = 0.0; v2[2] = -0.01;
  317.     Vsub (v3, v2, vel);
  318.     Vsub (v4, v1, vel);
  319.     glVertex3dv (v1);
  320.     glVertex3dv (v2);
  321.     glVertex3dv (v3);
  322.     glVertex3dv (v4);
  323.  
  324.     glEnd();
  325. }
  326.  
  327. DrawMissile3 (m)
  328. int m;
  329. {
  330.     double r, s, v[3];
  331.  
  332.     /* Figure how much to spin missile */
  333.     r = absT - ((double)(int)absT);
  334.     s = 360.0 * r;
  335.  
  336.     glColor3fv (weapon[msl[m].weapon].color);
  337.  
  338.     Vsub (v, msl[m].pos, player.pos);
  339.     glTranslated (v[0], v[1], v[2]);
  340.     glRotated (s, 0.3, 1.0, 0.6);
  341.     glScaled (0.01, 0.01, 0.01);
  342.  
  343.     glutSolidTetrahedron ();
  344. }
  345.  
  346. DrawMissile4 (m)
  347. int m;
  348. {
  349.     int i;
  350.     double v[3], u[3];
  351.  
  352.     glColor3fv (weapon[msl[m].weapon].color);
  353.  
  354.     Vsub (u, msl[m].pos, player.pos);
  355.     glTranslated (u[0], u[1], u[2]);
  356.  
  357.     glBegin (GL_LINE_LOOP);
  358.     for (i=0; i<6; i++)
  359.     {
  360.         v[0] = rnd(0.04) - 0.01;
  361.         v[1] = rnd(0.04) - 0.01;
  362.         v[2] = rnd(0.04) - 0.01;
  363.         glVertex3dv (v);
  364.     }    
  365.     glEnd();
  366. }
  367.  
  368. MissileHitPlayer (m)
  369. int m;
  370. /*
  371.  *  Missile m hit player.  Ouch!
  372.  */
  373. {
  374.     /* Flash screen red */
  375.     palette_flash = 2;
  376.  
  377.     /* Damage shields */
  378.     player.shields -= weapon[msl[m].weapon].yield;
  379.  
  380.     /* Get rid of missile */
  381.     DestroyMissile (m);
  382.  
  383.     /* See if player died */
  384.     if (vulnerable && (player.shields < 0.0) && !am_client)
  385.     {
  386.         if (am_server)
  387.         {
  388.             /* Tell other clients */
  389.             NetDestroyClient (server.client, FindClientByTarget (msl[m].owner));
  390.             NetPlayerDies();
  391.         }
  392.         else
  393.         {
  394.             /* Single player games, reset */
  395.             InitPlayer();
  396.             ReadMission (mission.fn);
  397.             Mprint ("You were killed!  Restarting mission.");
  398.         }
  399.     }
  400.  
  401.     if (player.shields < 0.0) player.shields = 100.0;
  402. }
  403.  
  404. MissileHitTarget (m, t)
  405. int m, t;
  406. /*
  407.  *  Missile m hit target t.  Go get 'em!
  408.  */
  409. {
  410.     int e;
  411.  
  412.     Boom (msl[m].pos, weapon[msl[m].weapon].yield/100.0);
  413.  
  414.     target[t].shields -= weapon[msl[m].weapon].yield;
  415.     if (target[t].shields < 0.0) target[t].shields = 0.0;
  416.  
  417.     /* Announce to network */
  418.     if (am_server) NetHitTarget (t, m);
  419.  
  420.     /* See if we set off an event */
  421.     for (e=0; e<NEVENTS; e++)
  422.     {
  423.         if (event[e].pending &&
  424.             event[e].enabled &&
  425.             (event[e].trigger == EVENT_SHIELDS) &&
  426.             (!strcasecmp (event[e].cvalue, target[t].name)) &&
  427.             (target[t].shields <= event[e].fvalue) )
  428.         {
  429.             EventAction (e);
  430.         }
  431.     }
  432.  
  433.     /* See if target is destroyed */
  434.     if (!am_client && target[t].shields <= 0.0)
  435.     {
  436.         /* Announce to network */
  437.         NetDestroyTarget (t, m);
  438.  
  439.         /* Kablooie! */
  440.         Boom (target[t].pos, 1.0);
  441.         if (!am_server) DestroyTarget (t);
  442.         if (am_server) target[t].shields = 100.0;
  443.     }
  444.  
  445.     DestroyMissile (m);
  446. }
  447.