home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / think.c < prev    next >
C/C++ Source or Header  |  1999-08-19  |  7KB  |  406 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. /* Ignore beyond this distance */
  25. #define THINK_CUTOFFA (20000.0 / KM_TO_UNITS1)
  26. #define THINK_CUTOFFA2 (THINK_CUTOFFA * THINK_CUTOFFA)
  27.  
  28. /* Pursue beyond this distance */
  29. #define THINK_CUTOFFB (2000.0 / KM_TO_UNITS1)
  30. #define THINK_CUTOFFB2 (THINK_CUTOFFB * THINK_CUTOFFB)
  31.  
  32. /* Maintain distance beyond this distance */
  33. #define THINK_CUTOFFC (500.0 / KM_TO_UNITS1)
  34. #define THINK_CUTOFFC2 (THINK_CUTOFFC * THINK_CUTOFFC)
  35.  
  36. ThinkTarget (t)
  37. int t;
  38. /*
  39.  *  Give this target a chance to think about what it wants to do
  40.  */
  41. {
  42.     /* Targets do their own thinking in network games */
  43.     if (am_client || am_server) return;
  44.  
  45.     switch (target[t].strategy)
  46.     {
  47.     case STRAT_DONOTHING:
  48.         break;
  49.  
  50.     case STRAT_SIT1:
  51.         ThinkSit1 (t);
  52.         break;
  53.  
  54.     case STRAT_SIT2:
  55.         ThinkSit2 (t);
  56.         break;
  57.  
  58.     case STRAT_SIT3:
  59.         ThinkSit3 (t);
  60.         break;
  61.  
  62.     case STRAT_SIT4:
  63.         ThinkSit4 (t);
  64.         break;
  65.  
  66.     case STRAT_HUNT1:
  67.         ThinkHunt1 (t);
  68.         break;
  69.  
  70.     case STRAT_HUNT2:
  71.         ThinkHunt2 (t);
  72.         break;
  73.  
  74.     case STRAT_HUNT3:
  75.         ThinkHunt3 (t);
  76.         break;
  77.  
  78.     case STRAT_HUNT4:
  79.         ThinkHunt4 (t);
  80.         break;
  81.     }
  82. }
  83.  
  84. ThinkSit1 (t)
  85. int t;
  86. /*
  87.  *  Don't move, just turn toward player and shoot
  88.  */
  89. {
  90.     TurnToward (t, player.pos);
  91. }
  92.  
  93. ThinkSit2 (t)
  94. int t;
  95. /*
  96.  *  Don't move, just turn toward player and shoot
  97.  */
  98. {
  99.     double v[3];
  100.  
  101.     /* Aim at player */
  102.     if (!Aim (v, target[t].pos, target[t].vel, player.pos, player.vel,
  103.         weapon[target[t].weapon].speed))
  104.     {
  105.         TurnToward (t, player.pos);
  106.         return;
  107.     }
  108.  
  109.     TurnToward (t, v);
  110. }
  111.  
  112. ThinkSit3 (t)
  113. int t;
  114. /*
  115.  *  Don't move, just turn toward nearest enemy and shoot poorly
  116.  */
  117. {
  118.     double pos[3], vel[3];
  119.  
  120.     if (!FindEnemy (t, pos, vel)) return;
  121.     TurnToward (t, pos);
  122. }
  123.  
  124. ThinkSit4 (t)
  125. int t;
  126. /*
  127.  *  Don't move, just turn toward nearest enemy and shoot well
  128.  */
  129. {
  130.     double v[3], pos[3], vel[3];
  131.  
  132.     if (!FindEnemy (t, pos, vel)) return;
  133.     if (!Aim (v, target[t].pos, target[t].vel, pos, vel,
  134.         weapon[target[t].weapon].speed))
  135.     {
  136.         TurnToward (t, pos);
  137.         return;
  138.     }
  139.  
  140.     TurnToward (t, v);
  141. }
  142.  
  143. ThinkHunt1 (t)
  144. int t;
  145. /*
  146.  *  Move toward player and shoot
  147.  */
  148. {
  149.     MoveToward (t, player.pos);
  150. }
  151.  
  152. ThinkHunt2 (t)
  153. int t;
  154. /*
  155.  *  Move toward aiming point and shoot
  156.  */
  157. {
  158.     double v[3];
  159.  
  160.     /* Aim at player */
  161.     if (!Aim (v, target[t].pos, target[t].vel, player.pos, player.vel,
  162.         weapon[target[t].weapon].speed))
  163.     {
  164.         ThinkHunt1 (t);
  165.         return;
  166.     }
  167.  
  168.     MoveToward (t, v);
  169. }
  170.  
  171. ThinkHunt3 (t)
  172. int t;
  173. /*
  174.  *  Move toward closest enemy and shoot poorly
  175.  */
  176. {
  177.     double pos[3], vel[3];
  178.  
  179.     if (!FindEnemy (t, pos, vel)) return;
  180.     MoveToward (t, pos);
  181. }
  182.  
  183. ThinkHunt4 (t)
  184. int t;
  185. /*
  186.  *  Move toward closest enemy and shoot well
  187.  */
  188. {
  189.     double v[3], pos[3], vel[3];
  190.  
  191.     if (!FindEnemy (t, pos, vel)) return;
  192.     if (!Aim (v, target[t].pos, target[t].vel, pos, vel,
  193.         weapon[target[t].weapon].speed))
  194.     {
  195.         ThinkHunt3 (t);
  196.         return;
  197.     }
  198.  
  199.     MoveToward (t, v);
  200. }
  201.  
  202. TurnToward (t, pos)
  203. int t;
  204. double pos[3];
  205. {
  206. /*
  207.  *  Turn target t toward position v
  208.  */
  209.     double r, v[3], alpha, beta, theta;
  210.  
  211.     Vsub (v, pos, target[t].pos);
  212.     r = Mag2 (v);
  213.  
  214.     /* Don't bother if too far away */
  215.     if (r > THINK_CUTOFFA2)
  216.     {
  217.         target[t].vel[0] =
  218.         target[t].vel[1] =
  219.         target[t].vel[2] = 0.0;
  220.  
  221.         return;
  222.     }
  223.  
  224.     /* v is unit vector toward player */
  225.     Normalize (v);
  226.  
  227.     /* Determine angles from right-hand and up vectors */
  228.     alpha = Dotp (v, target[t].right);
  229.     beta = Dotp (v, target[t].up);
  230.     theta = Dotp (v, target[t].view);
  231.  
  232.     /* Turn towards player */
  233.  
  234.     /* First check left or right */
  235.     /* Is player to our right or left? */
  236.     if (alpha > 0.0)
  237.     {
  238.         /* To our right */
  239.         target[t].move_left = target[t].turnrate;
  240.     }
  241.     else
  242.     {
  243.         /* To our left */
  244.         target[t].move_right = target[t].turnrate;
  245.     }
  246.  
  247.     /* Up or down? */
  248.     if (beta > 0.0)
  249.     {
  250.         /* Above us */
  251.         target[t].move_up = target[t].turnrate;
  252.     }
  253.     else
  254.     {
  255.         target[t].move_down = target[t].turnrate;
  256.     }
  257.  
  258.     /* If we are facing target and are in range, shoot
  259.        a missile! */
  260.     if ( (theta > 0.9) && (r < weapon[target[t].weapon].range2) )
  261.     {
  262.         TargetFiresMissile (t);
  263.     }
  264. }
  265.  
  266. MoveToward (t, pos)
  267. int t;
  268. double pos[3];
  269. {
  270. /*
  271.  *  Turn target t toward position v
  272.  */
  273.     double r, v[3], alpha, beta, theta;
  274.  
  275.     Vsub (v, pos, target[t].pos);
  276.     r = Mag2 (v);
  277.  
  278.     /* Don't bother if too far away */
  279.     if (r > THINK_CUTOFFA2)
  280.     {
  281.         target[t].vel[0] =
  282.         target[t].vel[1] =
  283.         target[t].vel[2] = 0.0;
  284.  
  285.         return;
  286.     }
  287.  
  288.     /* v is unit vector toward player */
  289.     Normalize (v);
  290.  
  291.     /* Determine angles from right-hand and up vectors */
  292.     alpha = Dotp (v, target[t].right);
  293.     beta = Dotp (v, target[t].up);
  294.     theta = Dotp (v, target[t].view);
  295.  
  296.     /* Turn towards player */
  297.  
  298.     /* First check left or right */
  299.     /* Is player to our right or left? */
  300.     if (alpha > 0.0)
  301.     {
  302.         /* To our right */
  303.         target[t].move_left = target[t].turnrate;
  304.     }
  305.     else
  306.     {
  307.         /* To our left */
  308.         target[t].move_right = target[t].turnrate;
  309.     }
  310.  
  311.     /* Up or down? */
  312.     if (beta > 0.0)
  313.     {
  314.         /* Above us */
  315.         target[t].move_up = target[t].turnrate;
  316.     }
  317.     else
  318.     {
  319.         target[t].move_down = target[t].turnrate;
  320.     }
  321.  
  322.     /* Don't bother if too far away */
  323.     if (r > THINK_CUTOFFA2)
  324.     {
  325.         target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  326.     }
  327.  
  328.     /* If far enough away, move toward player */
  329.     if (r > THINK_CUTOFFB2)
  330.     {
  331.         if (theta > 0.0)
  332.             target[t].move_forward = target[t].maxvel;
  333.         else
  334.             target[t].move_backward = target[t].maxvel;
  335.     }
  336.     /* If too close, move away */
  337.     if (r < THINK_CUTOFFC2)
  338.     {
  339.         target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  340.     }
  341.  
  342.     /* If we are facing target and are in range, shoot
  343.        a missile! */
  344.     if ( (theta > 0.9) && (r < weapon[target[t].weapon].range2) )
  345.     {
  346.         TargetFiresMissile (t);
  347.     }
  348. }
  349.  
  350. int FindEnemy (targ, pos, vel)
  351. int targ;
  352. double pos[3], vel[3];
  353. /*
  354.  *  Find closest enemy to target targ, return position and speed
  355.  */
  356. {
  357.     int t, tt;
  358.     double d, v[3], r;
  359.  
  360.     /* d will be distance to closest */
  361.     d = -1.0;
  362.  
  363.     /* Loop through targets */
  364.     for (t=0; t<NTARGETS; t++)
  365.     {
  366.         if ( (target[t].age > 0.0) &&
  367.              (!target[t].hidden) &&
  368.              (t != targ) &&
  369.              (target[t].friendly != target[targ].friendly) )
  370.         {
  371.             /* Closer? */
  372.             Vsub (v, target[t].pos, target[targ].pos);
  373.             r = Mag2 (v);
  374.             if ( (d < 0.0) || (r < d) )
  375.             {
  376.                 tt = t;
  377.                 d = r;
  378.             }
  379.         }
  380.     }
  381.  
  382.     /* Set position and velocity if we found something */
  383.     if (d > 0.0)
  384.     {
  385.         Vset (pos, target[tt].pos);
  386.         Vset (vel, target[tt].vel);
  387.     }
  388.  
  389.     /* Must check player? */
  390.     if (!target[targ].friendly)
  391.     {
  392.         if ( (d < 0.0) || (target[targ].range2 < d) )
  393.         {
  394.             Vset (pos, player.pos);
  395.             Vset (vel, player.vel);
  396.             d = target[targ].range2;
  397.         }
  398.     }
  399.  
  400.     /* Found nothing? */
  401.     if (d == (-1.0)) return 0;
  402.  
  403.     return 1;
  404. }
  405.  
  406.