home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char sccsid[] = "@(#)missile_control.c 1.1 92/05/28 SMI" ;
- /* from missile_control.c 1.3 90/05/02 SMI */
- #endif
-
- /*
- * Copyright (c) 1986 by Sun Microsystems, Inc.
- */
-
- #include <stdio.h>
- #include <math.h>
- #include "dstar.h"
- #include "object_types.h"
-
-
-
- #ifdef DEBUG
- extern float missile_feedback, missile_turn, missile_speed, missile_slew ;
- #endif DEBUG
-
-
-
- /*
- * clear out missile list
- */
-
- missile_init()
- {
- int i ;
-
- for(i=0; i<MAX_MISSILES; ++i)
- missiles[i] = NULL ;
-
- num_missiles = 0 ;
- armed_missiles = 0 ;
- missiles_remaining = MISSILES_PER_LIFE ;
-
- #ifdef DEBUG
- missile_feedback = MISSILE_GAIN ;
- missile_turn = MISSILE_TURN ;
- missile_speed = MISSILE_SPEED ;
- missile_slew = MISSILE_SLEW ;
- #endif DEBUG
- }
-
-
- #ifdef DEBUG
- #undef MISSILE_GAIN
- #undef MISSILE_TURN
- #undef MISSILE_SPEED
- #undef MISSILE_SLEW
- #define MISSILE_GAIN missile_feedback
- #define MISSILE_TURN missile_turn
- #define MISSILE_SPEED missile_speed
- #define MISSILE_SLEW missile_slew
- #endif DEBUG
-
- /*
- * prepare to fire a missile, ask master for an id
- */
-
- missile_arm()
- {
- if(armed_missiles > 0)
- puts("missile already armed") ;
- else if(num_missiles >= MAX_MISSILES)
- puts("too many missiles flying at once") ;
- else if( missiles_remaining <= 0 )
- puts("out of missiles") ;
- else
- net_request_missile() ;
- }
-
-
-
- /*
- * called when master assigns missile id
- */
-
- missile_armed(id)
- int id ;
- {
- int i ;
- register Object *object ;
- extern fptr missile_vector[VECTOR_LENGTH] ;
-
- if(id < 0)
- puts("can't arm missile, too many objects in game") ;
- else
- {
- for(i=0; i<MAX_MISSILES; ++i)
- {
- if(missiles[i] == NULL)
- {
- missiles[i] = object = &objects[id] ;
- object->id = id ;
- sprintf(object->name, "missile%d@%s", i, Hostname) ;
- object->team = Me->id ;
- object->score = 0 ;
- object->class = OBJ_MISSILE ;
- object->status = OBJ_SLEEPING ;
- object->description = MISSILE_DESC ;
- object->target = Me->target ;
- object->address = Me->address ;
- object->net_addr = Me->net_addr ;
- object->net_status = SLAVE ;
- bcopy(missile_vector, object->f_vector, sizeof(missile_vector)) ;
- ++armed_missiles ;
- ++num_missiles ;
- --missiles_remaining ;
- special_add_player(object) ;
- i = MAX_MISSILES ;
- }
- }
- }
- }
-
-
-
- /*
- * launch command from player
- */
-
- missile_launch()
- {
- register Object *victim ;
- register Object *missile ;
- register int i ;
-
- victim = Me->target ;
-
- if(armed_missiles <= 0)
- puts("no missile armed") ;
- else
- for(i=0; i<MAX_MISSILES; ++i)
- if( (missile = missiles[i]) != NULL )
- if( missile->class != OBJ_MISSILE )
- {
- printf("missile %d fizzled\n",i) ;
- missiles[i] = NULL ;
- --armed_missiles ;
- --num_missiles ;
- }
- else if( missiles[i]->status == OBJ_SLEEPING )
- {
- missile = missiles[i] ;
- missile->status = OBJ_ACTIVE ;
- missile->flags = (victim != NULL) ? RADAR_FLAG : 0 ;
- missile->Posn = Me->Posn ;
- missile->Forward = Me->Forward ;
- missile->Up = Me->Up ;
- missile->Right = Me->Right ;
- missile->Delta.x = 0.0 ;
- missile->Delta.y = 0.0 ;
- missile->Delta.z = 0.0 ;
- missile->Pointing = Me->Pointing ;
- missile->Speed = MISSILE_SPEED ;
- missile->target = victim ;
- missile->time = MISSILE_LIFE ;
- --armed_missiles ;
- i = MAX_MISSILES ;
- }
- }
-
-
-
- /*
- * remove a missile from the game
- */
-
- static
- free_missile(id)
- int id ;
- {
- if(missiles[id] != NULL)
- {
- net_remove_player(missiles[id]->id) ;
- missiles[id] = NULL ;
- --num_missiles ;
- }
- }
-
-
-
- /*
- * missile has been shot down, was it one of ours?
- */
-
- missile_shot(missile)
- register Object *missile ;
- {
- register int i ;
-
- for(i=0; i<MAX_MISSILES; ++i)
- if(missile == missiles[i])
- {
- missile->status = OBJ_DEAD ;
- missile->flags = 0 ;
- missile->Delta.x = 0.0 ;
- missile->Delta.y = 0.0 ;
- missile->Delta.z = 0.5 ;
- missile->Speed *= 0.7 ;
- missile->description = BLAST_DESC ;
- missile->time = DEATH_INTERVAL ;
- }
- }
-
-
-
- /*
- * handle all missiles for one frame
- */
-
- fly_missiles()
- {
- register int i ;
- register Object *missile ;
- register float dist, d ;
- Pt3d v1, v2 ;
-
- for(i=0; i<MAX_MISSILES; ++i)
- if( (missile = missiles[i]) != NULL &&
- missile->status != OBJ_SLEEPING )
- {
- if( (missile->time -= Dtime) < 0.0)
- free_missile(i) ;
- else
- {
- if(missile->target != NULL)
- {
- if( missile->target->class == OBJ_EMPTY ||
- missile->target->status != OBJ_ACTIVE )
- {
- missile->target = NULL ;
- missile->flags = 0 ;
- }
- else
- {
- /* renew missile's life */
- missile->time += MISSILE_REGEN*Dtime ;
- v1.x = missile->target->Posn.x - missile->Posn.x ;
- v1.y = missile->target->Posn.y - missile->Posn.y ;
- v1.z = missile->target->Posn.z - missile->Posn.z ;
- dist = v1.x*v1.x + v1.y*v1.y + v1.z*v1.z ;
- if(dist > (MISSILE_RANGE*MISSILE_RANGE))
- {
- missile->target = NULL ; /* lost it */
- missile->flags = 0 ;
- }
- else if (dist > (MISSILE_THRESH*MISSILE_THRESH))
- {
- d = v1.x * missile->Pointing.x +
- v1.y * missile->Pointing.y +
- v1.z * missile->Pointing.z ;
- if(d < 0.0 || d*d < dist * 0.5) /* cos(45)**2 */
- {
- missile->target = NULL ; /* lost it */
- missile->flags = 0 ;
- }
- else
- {
- /* we've got a victim, find delta to take us there:
- *
- * transform vector to victim from world to ship coords, ignore z.
- * normalize (we already have distance), multiply by feedback gain.
- * limit to max turn rate.
- */
- v2.x = v1.x*missile->Right.x +
- v1.y*missile->Right.y +
- v1.z*missile->Right.z ;
- v2.y = v1.x*missile->Up.x +
- v1.y*missile->Up.y +
- v1.z*missile->Up.z ;
-
- dist = MISSILE_GAIN / sqrt(dist) ;
-
- v2.x *= dist ;
- v2.y *= dist ;
-
- if(v2.x > MISSILE_TURN) v2.x = MISSILE_TURN ;
- if(v2.x < -MISSILE_TURN) v2.x = -MISSILE_TURN ;
- if(v2.y > MISSILE_TURN) v2.y = MISSILE_TURN ;
- if(v2.y < -MISSILE_TURN) v2.y = -MISSILE_TURN ;
-
- set_delta(missile, &v2, MISSILE_SLEW) ;
- adjust_vector(missile,&missile->Delta) ;
- }
- }
- else /* got it! */
- {
- net_blow_away(missile, missile->target) ;
- free_missile(i) ;
- missile = NULL ;
- }
- }
- }
- if(missile != NULL)
- {
- adjust_vectors(missile) ;
- send_status(missile) ;
- }
- }
- }
- }
-