home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2611 / missile_control.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-23  |  6.3 KB  |  305 lines

  1. #ifndef lint
  2. static    char    sccsid[] = "@(#)missile_control.c 1.1 92/05/28 SMI" ;
  3.     /* from missile_control.c 1.3 90/05/02 SMI */
  4. #endif
  5.  
  6. /*
  7.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <math.h>
  12. #include "dstar.h"
  13. #include "object_types.h"
  14.  
  15.  
  16.  
  17. #ifdef    DEBUG
  18. extern    float    missile_feedback, missile_turn, missile_speed, missile_slew ;
  19. #endif    DEBUG
  20.  
  21.  
  22.  
  23. /*
  24.  * clear out missile list
  25.  */
  26.  
  27. missile_init()
  28. {
  29.     int    i ;
  30.  
  31.     for(i=0; i<MAX_MISSILES; ++i)
  32.       missiles[i] = NULL ;
  33.  
  34.     num_missiles = 0 ;
  35.     armed_missiles = 0 ;
  36.     missiles_remaining = MISSILES_PER_LIFE ;
  37.  
  38. #ifdef    DEBUG
  39.     missile_feedback = MISSILE_GAIN ;
  40.     missile_turn = MISSILE_TURN ;
  41.     missile_speed = MISSILE_SPEED ;
  42.     missile_slew = MISSILE_SLEW ;
  43. #endif    DEBUG
  44. }
  45.  
  46.  
  47. #ifdef    DEBUG
  48. #undef    MISSILE_GAIN
  49. #undef    MISSILE_TURN
  50. #undef    MISSILE_SPEED
  51. #undef    MISSILE_SLEW
  52. #define    MISSILE_GAIN    missile_feedback
  53. #define    MISSILE_TURN    missile_turn
  54. #define    MISSILE_SPEED    missile_speed
  55. #define    MISSILE_SLEW    missile_slew
  56. #endif    DEBUG
  57.  
  58. /*
  59.  * prepare to fire a missile, ask master for an id
  60.  */
  61.  
  62. missile_arm()
  63. {
  64.     if(armed_missiles > 0)
  65.       puts("missile already armed") ;
  66.     else if(num_missiles >= MAX_MISSILES)
  67.       puts("too many missiles flying at once") ;
  68.     else if( missiles_remaining <= 0 )
  69.       puts("out of missiles") ;
  70.     else
  71.       net_request_missile() ;
  72. }
  73.  
  74.  
  75.  
  76. /*
  77.  * called when master assigns missile id
  78.  */
  79.  
  80. missile_armed(id)
  81.     int    id ;
  82. {
  83.     int    i ;
  84. register Object    *object ;
  85. extern    fptr    missile_vector[VECTOR_LENGTH] ;
  86.  
  87.     if(id < 0)
  88.       puts("can't arm missile, too many objects in game") ;
  89.     else
  90.     {
  91.       for(i=0; i<MAX_MISSILES; ++i)
  92.       {
  93.         if(missiles[i] == NULL)
  94.         {
  95.           missiles[i] = object = &objects[id] ;
  96.           object->id = id ;
  97.           sprintf(object->name, "missile%d@%s", i, Hostname) ;
  98.           object->team = Me->id ;
  99.           object->score = 0 ;
  100.           object->class = OBJ_MISSILE ;
  101.           object->status = OBJ_SLEEPING ;
  102.           object->description = MISSILE_DESC ;
  103.           object->target = Me->target ;
  104.           object->address = Me->address ;
  105.           object->net_addr = Me->net_addr ;
  106.           object->net_status = SLAVE ;
  107.           bcopy(missile_vector, object->f_vector, sizeof(missile_vector)) ;
  108.           ++armed_missiles ;
  109.           ++num_missiles ;
  110.           --missiles_remaining ;
  111.           special_add_player(object) ;
  112.           i = MAX_MISSILES ;
  113.         }
  114.       }
  115.     }
  116. }
  117.  
  118.  
  119.  
  120. /*
  121.  * launch command from player
  122.  */
  123.  
  124. missile_launch()
  125. {
  126. register Object    *victim ;
  127. register Object *missile ;
  128. register int    i ;
  129.  
  130.     victim = Me->target ;
  131.  
  132.     if(armed_missiles <= 0)
  133.       puts("no missile armed") ;
  134.     else
  135.       for(i=0; i<MAX_MISSILES; ++i)
  136.         if( (missile = missiles[i]) != NULL )
  137.           if( missile->class != OBJ_MISSILE )
  138.           {
  139.         printf("missile %d fizzled\n",i) ;
  140.         missiles[i] = NULL ;
  141.         --armed_missiles ;
  142.         --num_missiles ;
  143.           }
  144.           else if( missiles[i]->status == OBJ_SLEEPING )
  145.           {
  146.         missile = missiles[i] ;
  147.         missile->status = OBJ_ACTIVE ;
  148.         missile->flags = (victim != NULL) ? RADAR_FLAG : 0 ;
  149.         missile->Posn = Me->Posn ;
  150.         missile->Forward = Me->Forward ;
  151.         missile->Up = Me->Up ;
  152.         missile->Right = Me->Right ;
  153.         missile->Delta.x = 0.0 ;
  154.         missile->Delta.y = 0.0 ;
  155.         missile->Delta.z = 0.0 ;
  156.         missile->Pointing = Me->Pointing ;
  157.         missile->Speed = MISSILE_SPEED ;
  158.         missile->target = victim ;
  159.         missile->time = MISSILE_LIFE ;
  160.         --armed_missiles ;
  161.         i = MAX_MISSILES ;
  162.           }
  163. }
  164.  
  165.  
  166.  
  167. /*
  168.  * remove a missile from the game
  169.  */
  170.  
  171. static
  172. free_missile(id)
  173.     int    id ;
  174. {
  175.     if(missiles[id] != NULL)
  176.     {
  177.       net_remove_player(missiles[id]->id) ;
  178.       missiles[id] = NULL ;
  179.       --num_missiles ;
  180.     }
  181. }
  182.  
  183.  
  184.  
  185. /*
  186.  * missile has been shot down, was it one of ours?
  187.  */
  188.  
  189. missile_shot(missile)
  190. register Object    *missile ;
  191. {
  192. register int    i ;
  193.  
  194.     for(i=0; i<MAX_MISSILES; ++i)
  195.       if(missile == missiles[i])
  196.       {
  197.         missile->status = OBJ_DEAD ;
  198.         missile->flags = 0 ;
  199.         missile->Delta.x = 0.0 ;
  200.         missile->Delta.y = 0.0 ;
  201.         missile->Delta.z = 0.5 ;
  202.         missile->Speed *= 0.7 ;
  203.         missile->description = BLAST_DESC ;
  204.         missile->time = DEATH_INTERVAL ;
  205.       }
  206. }
  207.  
  208.  
  209.  
  210. /*
  211.  * handle all missiles for one frame
  212.  */
  213.  
  214. fly_missiles()
  215. {
  216. register int        i ;
  217. register Object        *missile ;
  218. register float        dist, d ;
  219.     Pt3d        v1, v2 ;
  220.  
  221.     for(i=0; i<MAX_MISSILES; ++i)
  222.       if( (missile = missiles[i]) != NULL  &&
  223.          missile->status != OBJ_SLEEPING )
  224.       {
  225.         if( (missile->time -= Dtime) < 0.0)
  226.           free_missile(i) ;
  227.         else
  228.         {
  229.           if(missile->target != NULL)
  230.           {
  231.         if( missile->target->class == OBJ_EMPTY  ||
  232.             missile->target->status != OBJ_ACTIVE )
  233.         {
  234.           missile->target = NULL ;
  235.           missile->flags = 0 ;
  236.         }
  237.         else
  238.         {
  239.           /* renew missile's life */
  240.           missile->time += MISSILE_REGEN*Dtime ;
  241.           v1.x = missile->target->Posn.x - missile->Posn.x ;
  242.           v1.y = missile->target->Posn.y - missile->Posn.y ;
  243.           v1.z = missile->target->Posn.z - missile->Posn.z ;
  244.           dist = v1.x*v1.x + v1.y*v1.y + v1.z*v1.z ;
  245.           if(dist > (MISSILE_RANGE*MISSILE_RANGE))
  246.           {
  247.             missile->target = NULL ;        /* lost it */
  248.             missile->flags = 0 ;
  249.           }
  250.           else if (dist > (MISSILE_THRESH*MISSILE_THRESH))
  251.           {
  252.             d = v1.x * missile->Pointing.x +
  253.             v1.y * missile->Pointing.y +
  254.             v1.z * missile->Pointing.z ;
  255.             if(d < 0.0 || d*d < dist * 0.5)    /* cos(45)**2 */
  256.             {
  257.               missile->target = NULL ;        /* lost it */
  258.               missile->flags = 0 ;
  259.             }
  260.             else
  261.             {
  262.   /* we've got a victim, find delta to take us there:
  263.    *
  264.    * transform vector to victim from world to ship coords, ignore z.
  265.    * normalize (we already have distance), multiply by feedback gain.
  266.    * limit to max turn rate.
  267.    */
  268.               v2.x = v1.x*missile->Right.x +
  269.                  v1.y*missile->Right.y +
  270.                  v1.z*missile->Right.z ;
  271.               v2.y = v1.x*missile->Up.x +
  272.                  v1.y*missile->Up.y +
  273.                  v1.z*missile->Up.z ;
  274.  
  275.               dist = MISSILE_GAIN / sqrt(dist) ;
  276.  
  277.               v2.x *= dist ;
  278.               v2.y *= dist ;
  279.  
  280.               if(v2.x >  MISSILE_TURN) v2.x =  MISSILE_TURN ;
  281.               if(v2.x < -MISSILE_TURN) v2.x = -MISSILE_TURN ;
  282.               if(v2.y >  MISSILE_TURN) v2.y =  MISSILE_TURN ;
  283.               if(v2.y < -MISSILE_TURN) v2.y = -MISSILE_TURN ;
  284.  
  285.               set_delta(missile, &v2, MISSILE_SLEW) ;
  286.               adjust_vector(missile,&missile->Delta) ;
  287.             }
  288.           }
  289.           else                    /* got it! */
  290.           {
  291.             net_blow_away(missile, missile->target) ;
  292.             free_missile(i) ;
  293.             missile = NULL ;
  294.           }
  295.         }
  296.           }
  297.         if(missile != NULL)
  298.         {
  299.           adjust_vectors(missile) ;
  300.           send_status(missile) ;
  301.         }
  302.       }
  303.     }
  304. }
  305.