home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / player.c < prev    next >
C/C++ Source or Header  |  1999-09-16  |  10KB  |  429 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. InitPlayer()
  25. /*
  26.  *  Set up initial player position, etc.
  27.  */
  28. {
  29.     /* Initial position */
  30.     player.pos[0] = planet[3].pos[0] - 2.0*planet[3].radius;
  31.     player.pos[1] = planet[3].pos[1];
  32.     player.pos[2] = planet[3].pos[2];
  33.  
  34.     /* Up vector */
  35.     player.up[0] = 0.0;
  36.     player.up[1]= 0.0;
  37.     player.up[2] = 1.0;
  38.  
  39.     /* Viewing vector */
  40.     player.view[0] = 1.0;
  41.     player.view[1] = 0.0;
  42.     player.view[2] = 0.0;
  43.  
  44.     /* Right-hand vector */
  45.     Crossp (player.right, player.up, player.view);
  46.     Normalize (player.right);
  47.  
  48.     /* Velocity components */
  49.     player.vel[0] = player.vel[1] = player.vel[2] = 0.0;
  50.     player.throttle = 0.0;
  51.  
  52.     /* Shields */
  53.     player.shields = player.maxshields = 100.0;
  54.  
  55.     /* Weapon */
  56.     player.weapon = 0;
  57.     player.msl_idle = 0.0;
  58. }
  59.  
  60. void MovePlayer()
  61. {
  62.     double v[3], theta, deltav[3];
  63.     int p, t, was_still;
  64.     char buf[128];
  65.  
  66.     /* Aim player if view is locked */
  67.     if (player.viewlock) ViewLock();
  68.  
  69.     /* Compute angle to move, given time change */
  70.     theta = THETA * deltaT;
  71.  
  72.     /* Deltav will be change in velocity components due to thrust */
  73.     deltav[0] = deltav[1] = deltav[2] = 0.0;
  74.  
  75.     /* Keep track if we've gone from still to not still or vice versa */
  76.     was_still = player.still;
  77.     player.still = 1;
  78.  
  79.     if (player.move_left > 0.0)
  80.     {        
  81.         RotateAbout (v, player.view, player.up, -theta*player.move_left);
  82.         Vset (player.view, v);
  83.         Normalize (player.view);
  84.         Crossp (player.right, player.up, player.view);
  85.         Normalize (player.right);
  86.         player.still = 0;
  87.     }
  88.  
  89.     if (player.move_right > 0.0)
  90.     {
  91.         RotateAbout (v, player.view, player.up, theta*player.move_right);
  92.         Vset (player.view, v);
  93.         Normalize (player.view);
  94.         Crossp (player.right, player.up, player.view);
  95.         Normalize (player.right);
  96.         player.still = 0;
  97.     }
  98.  
  99.     if (player.move_up > 0.0)
  100.     {
  101.         RotateAbout (v, player.view, player.right, theta*player.move_up);
  102.         Vset (player.view, v);
  103.         Normalize (player.view);
  104.         Crossp (player.up, player.view, player.right);
  105.         Normalize (player.up);
  106.         player.still = 0;
  107.     }
  108.  
  109.     if (player.move_down > 0.0)
  110.     {
  111.         RotateAbout (v, player.view, player.right, -theta*player.move_down);
  112.         Vset (player.view, v);
  113.         Normalize (player.view);
  114.         Crossp (player.up, player.view, player.right);
  115.         Normalize (player.up);
  116.         player.still = 0;
  117.     }
  118.  
  119.     if (player.move_pitchright > 0.0)
  120.     {
  121.         RotateAbout (v, player.up, player.view, -theta*player.move_pitchright);
  122.         Vset (player.up, v);
  123.         Normalize (player.up);
  124.         Crossp (player.right, player.up, player.view);
  125.         Normalize (player.right);
  126.         player.still = 0;
  127.     }
  128.  
  129.     if (player.move_pitchleft > 0.0)
  130.     {
  131.         RotateAbout (v, player.up, player.view, theta*player.move_pitchleft);
  132.         Vset (player.up, v);
  133.         Normalize (player.up);
  134.         Crossp (player.right, player.up, player.view);
  135.         Normalize (player.right);
  136.         player.still = 0;
  137.     }
  138.  
  139.     if (player.move_forward > 0.0)
  140.     {
  141.         if (player.flightmodel == FLIGHT_NEWTONIAN)
  142.         {
  143.             if (warpspeed)
  144.             {
  145.                 if (superwarp && !am_client && !am_server)
  146.                     Vmul (v, player.view, 100.0*player.move_forward*DELTAV*deltaT);
  147.                 else
  148.                     Vmul (v, player.view, deltaT * (player.move_forward*DELTAV + WARP_COEFF*Mag(player.vel)));
  149.             }
  150.             else
  151.                 Vmul (v, player.view, player.move_forward*DELTAV*deltaT);
  152.             Vadd (deltav, deltav, v);
  153.         }
  154.         else
  155.         {
  156.             if (player.throttle < MAX_THROTTLE)
  157.             {
  158.                 if (warpspeed)
  159.                     player.throttle += 10.0*player.move_forward*DELTAV*deltaT;
  160.                 else
  161.                     player.throttle += player.move_forward*DELTAV*deltaT;
  162.             }
  163.             else
  164.             {
  165.                 if (warpspeed)
  166.                     player.throttle += 10.0*100.0*player.move_forward*DELTAV*deltaT;
  167.                 else
  168.                     player.throttle += 100.0*player.move_forward*DELTAV*deltaT;
  169.             }
  170.             if (player.throttle > MAX_WARP_THROTTLE)
  171.                 player.throttle = MAX_WARP_THROTTLE;
  172.         }
  173.         player.still = 0;
  174.     }
  175.  
  176.     if (player.move_backward > 0.0)
  177.     {
  178.         if (player.flightmodel == FLIGHT_NEWTONIAN)
  179.         {
  180.             if (warpspeed)
  181.             {
  182.                 if (superwarp && !am_client && !am_server)
  183.                     Vmul (v, player.view, -100.0*player.move_backward*DELTAV*deltaT);
  184.                 else
  185.                     Vmul (v, player.view, -deltaT * (player.move_backward*DELTAV + WARP_COEFF*Mag(player.vel)));
  186.             }
  187.             else
  188.                 Vmul (v, player.view, -player.move_backward*DELTAV*deltaT);
  189.             Vadd (deltav, deltav, v);
  190.         }
  191.         else
  192.         {
  193.             if (player.throttle < MAX_THROTTLE)
  194.             {
  195.                 if (warpspeed)
  196.                     player.throttle -= 10.0*player.move_backward*DELTAV*deltaT;
  197.                 else
  198.                     player.throttle -= player.move_backward*DELTAV*deltaT;
  199.             }
  200.             else
  201.             {
  202.                 if (warpspeed)
  203.                     player.throttle -= 100.0*10.0*player.move_backward*DELTAV*deltaT;
  204.                 else
  205.                     player.throttle -= 100.0*player.move_backward*DELTAV*deltaT;
  206.             }
  207.             if (player.throttle < 0.0) player.throttle = 0.0;
  208.         }
  209.         player.still = 0;
  210.     }
  211.  
  212.     /* Compute change to velocity */
  213.     if (player.flightmodel == FLIGHT_NEWTONIAN)
  214.     {
  215.         Vadd (player.vel, player.vel, deltav);
  216.     }
  217.     else
  218.     {
  219.         Vmul (player.vel, player.view, player.throttle);
  220.     }
  221.  
  222.     /* Compute gravity's contribution */
  223.     if (gravity && (player.flightmodel == FLIGHT_NEWTONIAN) )
  224.     {
  225.         Gravity (deltav, player.pos);
  226.         Vadd (player.vel, player.vel, deltav);
  227.     }
  228.  
  229.     /* Finaly, move player */
  230.     Vmul (v, player.vel, deltaT);
  231.     Vadd (player.pos, player.pos, v);
  232.  
  233.     /* See if player cratered on the planet */
  234.     if (vulnerable)
  235.     {
  236.         if (-1 != (p = InsidePlanet (player.pos)))
  237.         {
  238.             if (!am_client && !am_server)
  239.             {
  240.                 /* Make an explosion */
  241.                 Vsub (v, player.pos, planet[p].pos);
  242.                 Vmul (v, v, planet[p].radius*1.05);
  243.                 Vadd (v, v, planet[p].pos);
  244.                 Boom (v, 1.0);
  245.  
  246.                 /* Send player back home */
  247.                 InitPlayer();
  248.                 gravity = 0;
  249.                 ReadMission (mission.fn);
  250.  
  251.                 /* Give the bad news */
  252.                 sprintf (buf, "You hit %s and died!\\\\Restarting mission.",
  253.                     planet[p].name);
  254.                 Mprint (buf);
  255.             }
  256.             else if (am_server)
  257.             {
  258.                 NetTargetCratered (client[server.client].target, p);
  259.                 NetPlayerDies();
  260.  
  261.                 sprintf (buf, "You hit %s and died!", planet[p].name);
  262.                 Mprint (buf);
  263.             }
  264.         }
  265.     }
  266.  
  267.     /* In network games, update position of target for the player */
  268.     if (am_client || am_server)
  269.     {
  270.         if (am_client) t = client[clientme.client].target;
  271.         if (am_server) t = client[server.client].target;
  272.  
  273.         Vset (target[t].pos, player.pos);
  274.         Vset (target[t].vel, player.vel);
  275.         Vset (target[t].up, player.up);
  276.         Vset (target[t].view, player.view);
  277.  
  278.         target[t].move_up = player.move_up;
  279.         target[t].move_down = player.move_down;
  280.         target[t].move_right = player.move_right;
  281.         target[t].move_left = player.move_left;
  282.         target[t].move_pitchright = player.move_pitchright;
  283.         target[t].move_pitchleft = player.move_pitchleft;
  284.     }
  285.  
  286.     /* If we've gone from still to not still, or other way around,
  287.        send position report */
  288.     if (was_still != player.still)
  289.     {
  290.         if (am_client) clientme.urgent = 1;
  291.         QueuePositionReport();
  292.     }
  293. }
  294.  
  295. UpdatePlayer()
  296. /*
  297.  *  Update all sorts of stuff for the player
  298.  */
  299. {
  300.     MovePlayer();
  301.  
  302.     /* Maintain shields */
  303.     player.shields += deltaT * SHIELD_REGEN;
  304.     if (player.shields > player.maxshields)
  305.         player.shields = player.maxshields;
  306.  
  307.     /* Weapon idle time */
  308.     player.msl_idle += deltaT;
  309.  
  310.     /* Dead time */
  311.     if (state == STATE_DEAD1)
  312.     {
  313.         player.dead_timer -= deltaT;
  314.         if (player.dead_timer <= 0.0)
  315.         {
  316.             state = STATE_DEAD2;
  317.             player.dead_timer = 0.0;
  318.         }
  319.     }
  320. }
  321.  
  322. PlayerFires()
  323. /*
  324.  *  Player maybe fires a missile
  325.  */
  326. {
  327.     double v[3];
  328.  
  329.     paused = 0;
  330.  
  331.     /* Not if dead */
  332.     if (state == STATE_DEAD1) return;
  333.  
  334.     /* Fire button respawns us */
  335.     if (state == STATE_DEAD2)
  336.     {
  337.         state = STATE_NORMAL;
  338.         return;
  339.     }
  340.  
  341.     /* Can't fire too rapidly */
  342.     if (player.msl_idle < weapon[player.weapon].idle)
  343.     {
  344.         return;
  345.     }
  346.     player.msl_idle = 0.0;
  347.  
  348.     /* Okay, fire the missile */
  349.     Vmul (v, player.up, -0.01);
  350.     Vadd (v, v, player.pos);
  351.     FireMissile (v, player.vel, player.view, 1, player.weapon, -1);
  352.  
  353.     /* Send network notification */
  354.     if (am_client)
  355.     {
  356.         SendASCIIPacket (clientme.socket, "FIRE %d", player.weapon);
  357.     }
  358.  
  359.     if (am_server)
  360.     {
  361.         NetClientFires (server.client, player.weapon);
  362.     }
  363. }
  364.  
  365. void DoName (void)
  366. /*
  367.  *  Sparky has typed a new name
  368.  */
  369. {
  370.     int i, len;
  371.  
  372.     len = strlen (text.buf);
  373.  
  374.     /* Remove spaces */
  375.     for (i=0; i<len; i++)
  376.     {
  377.         if (text.buf[i] == ' ') text.buf[i] = '_';
  378.     }
  379.     strcpy (player.name, text.buf);
  380. }
  381.  
  382. ViewLock()
  383. /*
  384.  *  Aim player toward locked object
  385.  */
  386. {
  387.     double pos[3], v[3];
  388.  
  389.     v[0] = 1.0; v[1] = 0.0; v[2] = 0.0;
  390.  
  391.     /* Not if we're not locked */
  392.     if (lock.target == (-1)) return;
  393.  
  394.     /* Figure out what we're locked on */
  395.     if (lock.type == LOCK_ENEMY)
  396.     {
  397.         Vset (pos, target[lock.target].pos);
  398.     }
  399.     else if (lock.type == LOCK_FRIENDLY)
  400.     {
  401.         Vset (pos, target[lock.target].pos);
  402.     }
  403.     else if (lock.type == LOCK_PLANET)
  404.     {
  405.         Vset (pos, planet[lock.target].pos);
  406.     }
  407.     else
  408.     {
  409.         /* Can't happen */
  410.         Log ("ViewLock: Invalid lock.type");
  411.         return;
  412.     }
  413.  
  414.     /* Set view vector */
  415.     Vsub (player.view, pos, player.pos);
  416.     Normalize (player.view);
  417.  
  418.     /* Set up vector */
  419. /*    Perp (player.up, player.view);    */
  420.     Crossp (player.up, player.view, v);
  421.     Normalize (player.up);
  422.  
  423.     /* Try to keep the up vector pointing up */
  424. /*    if (player.up[2] < player.pos[2]) Vmul (player.up, player.up, -1.0);    */
  425.  
  426.     /* Set right-hand vector */
  427.     Crossp (player.right, player.up, player.view);
  428. }
  429.