FS2_Open
Open source remastering of the Freespace 2 engine
swarm.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #include "globalincs/linklist.h"
13 #include "io/timer.h"
14 #include "object/object.h"
15 #include "ship/ship.h"
16 #include "weapon/swarm.h"
17 #include "weapon/weapon.h"
18 
19 
20 
21 #define SWARM_DIST_OFFSET 2.0f // distance swarm missile should vary from original path
22 #define SWARM_CONE_LENGTH 10000.0f // used to pick a target point far in the distance
23 #define SWARM_CHANGE_DIR_TIME 400 // time to force change in direction of swarm missile
24 #define SWARM_ANGLE_CHANGE (4*PI/180) // in rad
25 
26 
27 // *No longer need this -Et1
28 //#define SWARM_MISSILE_DELAY 150 // time delay between each swarm missile that is fired
29 
30 
31 #define SWARM_TIME_VARIANCE 100 // max time variance when deciding when to change swarm missile course
32 
33 #define SWARM_DIST_STOP_SWARMING 300
34 
35 #define TURRET_SWARM_VALIDITY_CHECKTIME 5000 // number of ms between checks on turret_swam_info checks
36 
37 #define SWARM_USED (1<<0)
38 #define SWARM_POSITIVE_PATH (1<<1)
39 
40 
42 
44 
46 
47 // ------------------------------------------------------------------
48 // swarm_level_init()
49 //
50 // Called at the start of each new mission
51 //
53 {
54  int i;
55  swarm_info *swarmp;
56  turret_swarm_info *tswarmp;
57 
58  for ( i = 0; i < MAX_SWARM_MISSILES; i++ ) {
59  swarmp = &Swarm_missiles[i];
60  swarmp->flags = 0;
61  swarmp->change_timestamp = 1;
62  swarmp->path_num = -1;
63  }
64 
65  for (i=0; i<MAX_TURRET_SWARM_INFO; i++) {
66  tswarmp = &Turret_swarm_info[i];
67  tswarmp->flags = 0;
68  tswarmp->weapon_class = -1;
69  tswarmp->num_to_launch = 0;
70  tswarmp->parent_objnum = -1;
71  tswarmp->parent_sig = -1;
72  tswarmp->target_objnum = -1;
73  tswarmp->target_sig = -1;
74  tswarmp->turret = NULL;
75  tswarmp->target_subsys = NULL;
76  tswarmp->time_to_fire = 0;
77  }
78 
80 }
81 
82 // ------------------------------------------------------------------
83 // swarm_maybe_fire_missile()
84 //
85 // Check if there are any swarm missiles to fire, and if enough time
86 // has elapsed since last one fired, go ahead and fire it.
87 //
88 // This is called once per ship frame in ship_move()
89 //
90 void swarm_maybe_fire_missile(int shipnum)
91 {
92  ship *sp;
93  ship_weapon *swp;
94  int weapon_info_index;
95 
96  Assert(shipnum >= 0 && shipnum < MAX_SHIPS );
97  sp = &Ships[shipnum];
98 
99  if ( sp->num_swarm_missiles_to_fire <= 0 ) {
100  sp->swarm_missile_bank = -1;
101  return;
102  }
103 
104  swp = &sp->weapons;
105  if ( sp->swarm_missile_bank == -1 ) {
107  return;
108  }
109 
110  weapon_info_index = swp->secondary_bank_weapons[sp->swarm_missile_bank];
111  Assert( weapon_info_index >= 0 && weapon_info_index < MAX_WEAPON_TYPES );
112 
113  // if swarm secondary bank is not a swarm missile, return
114  if ( !(Weapon_info[weapon_info_index].wi_flags & WIF_SWARM) ) {
116  sp->swarm_missile_bank = -1;
117  return;
118  }
119 
121  {
122 
123  // *Get timestamp from weapon info's -Et1
124  sp->next_swarm_fire = timestamp(Weapon_info[weapon_info_index].SwarmWait );
125 
126  ship_fire_secondary( &Objects[sp->objnum], 1 );
128  }
129 }
130 
131 // ------------------------------------------------------------------
132 // swarm_create()
133 //
134 // Get a free swarm missile entry, and initialize the struct members
135 //
137 {
138  int i;
139  swarm_info *swarmp = NULL;
140 
141  for ( i = 0; i < MAX_SWARM_MISSILES; i++ ) {
142  swarmp = &Swarm_missiles[i];
143  if ( !(swarmp->flags & SWARM_USED) )
144  break;
145  }
146 
147  if ( i >= MAX_SWARM_MISSILES ) {
148  nprintf(("Warning","No more swarm missiles are available\n"));
149  return -1;
150  }
151 
152  swarmp->flags = 0;
153  swarmp->change_timestamp = 1;
154  swarmp->path_num = -1;
155  swarmp->homing_objnum = -1;
156 
157  swarmp->flags |= SWARM_USED;
158  return i;
159 }
160 
161 // ------------------------------------------------------------------
162 // swarm_delete()
163 //
164 //
165 void swarm_delete(int i)
166 {
167  swarm_info *swarmp;
168 
169  Assert(i >= 0 && i < MAX_SWARM_MISSILES);
170  swarmp = &Swarm_missiles[i];
171 
172  if ( !(swarmp->flags & SWARM_USED) ) {
173  Int3(); // tried to delete a swarm missile that didn't exist, get Alan
174  }
175 
176  swarmp->flags = 0;
177 }
178 
179 // ------------------------------------------------------------------
180 // swarm_update_direction()
181 //
182 // Check if we want to update the direction of a swarm missile.
183 //
184 void swarm_update_direction(object *objp, float frametime)
185 {
186  weapon_info *wip;
187  weapon *wp;
188  object *hobjp;
189  swarm_info *swarmp;
190  vec3d obj_to_target;
191  float vel, target_dist, radius, missile_speed, missile_dist;
192  physics_info *pi;
193 
194  Assert(objp->instance >= 0 && objp->instance < MAX_WEAPONS);
195 
196  wp = &Weapons[objp->instance];
197 
198  if (wp->swarm_index == -1) {
199  return;
200  }
201 
202  wip = &Weapon_info[wp->weapon_info_index];
203  hobjp = wp->homing_object;
204  pi = &Objects[wp->objnum].phys_info;
205  swarmp = &Swarm_missiles[wp->swarm_index];
206 
207  // check if homing is lost.. if it is then get a new path to move swarm missile along
208  if ( swarmp->homing_objnum != -1 && hobjp == &obj_used_list ) {
209  swarmp->change_timestamp = 1;
210  swarmp->path_num = -1;
211  swarmp->homing_objnum = -1;
212  }
213 
214  if ( hobjp != &obj_used_list ) {
215  swarmp->homing_objnum = OBJ_INDEX(hobjp);
216  }
217 
218  if ( timestamp_elapsed(swarmp->change_timestamp) ) {
219 
220  if ( swarmp->path_num == -1 ) {
221  if ( Objects[objp->parent].type != OBJ_SHIP ) {
222  //AL: parent ship died... so just pick some random paths
223  swarmp->path_num = myrand()%4;
224  } else {
225  ship *parent_shipp;
226  parent_shipp = &Ships[Objects[objp->parent].instance];
227  swarmp->path_num = (parent_shipp->next_swarm_path++)%4;
228 
229  if ( parent_shipp->next_swarm_path%4 == 0 ) {
230  swarmp->flags ^= SWARM_POSITIVE_PATH;
231  }
232  }
233 
234  vm_vec_scale_add(&swarmp->original_target, &objp->pos, &objp->orient.vec.fvec, SWARM_CONE_LENGTH);
235  swarmp->circle_rvec = objp->orient.vec.rvec;
236  swarmp->circle_uvec = objp->orient.vec.uvec;
237 
238  swarmp->change_count = 1;
240 
241  vm_vec_zero(&swarmp->last_offset);
242 
243  missile_speed = pi->speed;
244  missile_dist = missile_speed * swarmp->change_time/1000.0f;
245  if ( missile_dist < SWARM_DIST_OFFSET ) {
246  missile_dist = SWARM_DIST_OFFSET;
247  }
248  swarmp->angle_offset = asinf(SWARM_DIST_OFFSET / missile_dist);
249  Assert(!_isnan(swarmp->angle_offset) );
250  }
251 
252  swarmp->change_timestamp = timestamp(swarmp->change_time);
253 
254  // check if swarm missile is homing, if so need to calculate a new target pos to turn towards
255  if ( hobjp != &obj_used_list && f2fl(Missiontime - wp->creation_time) > 0.5f && ( f2fl(Missiontime - wp->creation_time) > wip->free_flight_time ) ) {
256  swarmp->original_target = wp->homing_pos;
257 
258  // Calculate a rvec and uvec that will determine the displacement from the
259  // intended target. Use crossprod to generate a right vector, from the missile
260  // up vector and the vector connecting missile to the homing object.
261  swarmp->circle_uvec = objp->orient.vec.uvec;
262  swarmp->circle_rvec = objp->orient.vec.rvec;
263 
264  missile_speed = pi->speed;
265  missile_dist = missile_speed * swarmp->change_time/1000.0f;
266  if ( missile_dist < SWARM_DIST_OFFSET ) {
267  missile_dist = SWARM_DIST_OFFSET;
268  }
269  swarmp->angle_offset = asinf(SWARM_DIST_OFFSET / missile_dist);
270  Assert(!_isnan(swarmp->angle_offset) );
271  }
272 
273  vm_vec_sub(&obj_to_target, &swarmp->original_target, &objp->pos);
274  target_dist = vm_vec_mag_quick(&obj_to_target);
275  swarmp->last_dist = target_dist;
276 
277  // If homing swarm missile is close to target, let missile home in on original target
278  if ( target_dist < SWARM_DIST_STOP_SWARMING ) {
279  swarmp->new_target = swarmp->original_target;
280  goto swarm_new_target_calced;
281  }
282 
283  radius = tanf(swarmp->angle_offset) * target_dist;
284  vec3d rvec_component, uvec_component;
285 
286  swarmp->change_count++;
287  if ( swarmp->change_count > 2 ) {
288  swarmp->flags ^= SWARM_POSITIVE_PATH;
289  swarmp->change_count = 0;
290  }
291 
292  // pick a new path number to follow once at center
293  if ( swarmp->change_count == 1 ) {
294  swarmp->path_num = swarmp->path_num + myrand()%3;
295  if ( swarmp->path_num > 3 ) {
296  swarmp->path_num = 0;
297  }
298  }
299 
300  vm_vec_zero(&rvec_component);
301  vm_vec_zero(&uvec_component);
302 
303  switch ( swarmp->path_num ) {
304  case 0: // straight up and down
305  if ( swarmp->flags & SWARM_POSITIVE_PATH )
306  vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, radius);
307  else
308  vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, -radius);
309  break;
310 
311  case 1: // left/right
312  if ( swarmp->flags & SWARM_POSITIVE_PATH )
313  vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, radius);
314  else
315  vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, -radius);
316  break;
317 
318  case 2: // top/right - bottom/left
319  if ( swarmp->flags & SWARM_POSITIVE_PATH ) {
320  vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, radius);
321  vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, radius);
322  }
323  else {
324  vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, -radius);
325  vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, -radius);
326  }
327  break;
328 
329  case 3: // top-left - bottom/right
330  if ( swarmp->flags & SWARM_POSITIVE_PATH ) {
331  vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, -radius);
332  vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, radius);
333  }
334  else {
335  vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, radius);
336  vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, -radius);
337  }
338  break;
339  default:
340  Int3();
341  break;
342  }
343 
344  swarmp->new_target = swarmp->original_target;
345  vm_vec_zero(&swarmp->last_offset);
346  vm_vec_add(&swarmp->last_offset, &uvec_component, &rvec_component);
347  vm_vec_add2(&swarmp->new_target, &swarmp->last_offset);
348  }
349  else {
350  if ( hobjp != &obj_used_list && f2fl(Missiontime - wp->creation_time) > 0.5f ) {
351 
352  swarmp->new_target = swarmp->original_target;
353  if ( swarmp->last_dist < SWARM_DIST_STOP_SWARMING ) {
354  swarmp->new_target = wp->homing_pos;
355  goto swarm_new_target_calced;
356  }
357 
358  vm_vec_add2(&swarmp->new_target, &swarmp->last_offset);
359  }
360  }
361 
362  swarm_new_target_calced:
363 
364  ai_turn_towards_vector(&swarmp->new_target, objp, frametime, wip->turn_time, NULL, NULL, 0.0f, 0);
365  vel = vm_vec_mag(&objp->phys_info.desired_vel);
366  vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, vel);
367 }
368 
369 // ------------------------------------------------------------------
370 // turret_swarm_create()
371 //
372 // Get a free swarm missile entry, and initialize the struct members
373 //
375 {
376  int i;
377  turret_swarm_info *tswarmp = NULL;
378 
379  for (i=0; i<MAX_TURRET_SWARM_INFO; i++) {
380  tswarmp = &Turret_swarm_info[i];
381  if ( !(tswarmp->flags & SWARM_USED) )
382  break;
383  }
384 
385  if ( i >= MAX_TURRET_SWARM_INFO ) {
386  nprintf(("Warning","No more turret swarm info slots are available\n"));
387  return -1;
388  }
389 
390  tswarmp->flags = 0;
391  tswarmp->weapon_class = -1;
392  tswarmp->num_to_launch = 0;
393  tswarmp->parent_objnum = -1;
394  tswarmp->parent_sig = -1;
395  tswarmp->target_objnum = -1;
396  tswarmp->target_sig = -1;
397  tswarmp->turret = NULL;
398  tswarmp->target_subsys = NULL;
399  tswarmp->time_to_fire = 0;
400 
401  tswarmp->flags |= SWARM_USED;
402  return i;
403 }
404 
405 // ------------------------------------------------------------------
406 // turret_swarm_delete()
407 //
409 {
410  turret_swarm_info *tswarmp;
411 
412  Assert(i >= 0 && i < MAX_TURRET_SWARM_INFO);
413  tswarmp = &Turret_swarm_info[i];
414 
415  if ( !(tswarmp->flags & SWARM_USED) ) {
416  Int3(); // tried to delete a swarm missile that didn't exist, get DaveA
417  }
418 
419  tswarmp->flags = 0;
420 }
421 
422 // Set up turret swarm info struct
423 void turret_swarm_set_up_info(int parent_objnum, ship_subsys *turret, weapon_info *wip, int weapon_num)
424 {
425  turret_swarm_info *tsi;
426  object *parent_obj, *target_obj;
427  ship *shipp;
428  int tsi_index;
429 
430  // weapon info pointer
431  //Removed check in the interests of speed -WMC
432  /*
433  Assert((turret_weapon_class >= 0) && (turret_weapon_class < Num_weapon_types));
434  if((turret_weapon_class < 0) || (turret_weapon_class >= Num_weapon_types)){
435  return;
436  }
437  */
438 
439  // get ship pointer
440  Assert((parent_objnum >= 0) && (parent_objnum < MAX_OBJECTS));
441  if((parent_objnum < 0) || (parent_objnum >= MAX_OBJECTS)){
442  return;
443  }
444  parent_obj = &Objects[parent_objnum];
445  Assert(parent_obj->type == OBJ_SHIP);
446  shipp = &Ships[parent_obj->instance];
447  Assert((turret->turret_enemy_objnum >= 0) && (turret->turret_enemy_objnum < MAX_OBJECTS));
448  if((turret->turret_enemy_objnum < 0) || (turret->turret_enemy_objnum >= MAX_OBJECTS)){
449  return;
450  }
451  target_obj = &Objects[turret->turret_enemy_objnum];
452 
453  // valid swarm weapon
454  Assert(((wip->wi_flags & WIF_SWARM) && (wip->swarm_count > 0)) || ((wip->wi_flags & WIF_CORKSCREW) && (wip->cs_num_fired > 0)));
455 
456  if(!((wip->wi_flags & WIF_SWARM) || (wip->wi_flags & WIF_CORKSCREW)) || ((wip->wi_flags & WIF_SWARM) && (wip->swarm_count <= 0)) || ((wip->wi_flags & WIF_CORKSCREW) && (wip->cs_num_fired <= 0)))
457  return;
458 
459  // get turret_swarm_info
460  tsi_index = turret_swarm_create();
461  if (tsi_index == -1) {
462  return;
463  }
464 
465  // set turret to point to tsi
466  tsi = &Turret_swarm_info[tsi_index];
467 
468  if (turret->turret_swarm_num == MAX_TFP)
469  {
470  mprintf(("Overlapping turret swarm firing intervals\n"));
472  int old_s;
473  for (old_s = 0; old_s < (MAX_TFP - 1); old_s++)
474  {
475  turret->turret_swarm_info_index[old_s] = turret->turret_swarm_info_index[old_s + 1];
476  }
477  turret->turret_swarm_info_index[MAX_TFP - 1] = -1;
478  turret->turret_swarm_num--;
479  shipp->num_turret_swarm_info--;
480  }
481  turret->turret_swarm_info_index[turret->turret_swarm_num] = tsi_index;
482  turret->turret_swarm_num++;
483 
484  // increment ship tsi counter
485  shipp->num_turret_swarm_info++;
486 
487  // *Unnecessary check, now done on startup -Et1
488  /*
489 
490  // make sure time is sufficient to launch all the missiles before next volley
491 #ifndef NDEBUG
492  Assert(wip->swarm_count * SWARM_MISSILE_DELAY < wip->fire_wait * 1000.0f);
493 #endif
494 
495  */
496 
497  ship_weapon *swp = &turret->weapons;
498  int bank_fired = swp->current_secondary_bank;
499 
500  // initialize tsi
501  tsi->weapon_class = WEAPON_INFO_INDEX(wip);
502  if (wip->wi_flags & WIF_SWARM) {
503  tsi->num_to_launch = wip->swarm_count;
504  } else {
505  tsi->num_to_launch = wip->cs_num_fired;
506  }
508  swp->secondary_bank_ammo[bank_fired] -= tsi->num_to_launch;
509  }
510  tsi->parent_objnum = parent_objnum;
511  tsi->parent_sig = parent_obj->signature;
512  tsi->target_objnum = turret->turret_enemy_objnum;
513  tsi->target_sig = target_obj->signature;
514  tsi->turret = turret;
515  tsi->target_subsys = turret->targeted_subsys;
516  tsi->time_to_fire = 1; // first missile next frame
517  tsi->weapon_num = weapon_num;
518 }
519 
521 // check if ship has turret ready to fire swarm type missiles
523 {
524  ship *shipp = &Ships[shipnum];
525  ship_subsys *subsys;
526  turret_swarm_info *tsi;
527  object *parent_obj, *target_obj;
528  int num_turret_swarm_turrets_left;
529  int k, j;
530  weapon_info *wip;
531 
532  // check if ship has any turrets ready to fire
533  if (shipp->num_turret_swarm_info <= 0) {
534  Assert(shipp->num_turret_swarm_info == 0);
535  return;
536  }
537 
538  // ship obj which has fired turret swarm missiles
539  parent_obj = &Objects[shipp->objnum];
540  num_turret_swarm_turrets_left = shipp->num_turret_swarm_info;
541 
542  // search ship subsystems for turrets with valid turret_swarm_info_index
543  for (subsys = GET_FIRST(&shipp->subsys_list); subsys != END_OF_LIST(&shipp->subsys_list); subsys = GET_NEXT(subsys)) {
544  if (subsys->turret_swarm_num > 0) {
545 
546  int swarms_per_turret = subsys->turret_swarm_num;
547 
548  for (k = 0; k < swarms_per_turret; k++)
549  {
550  int turret_tsi = subsys->turret_swarm_info_index[k];
551  num_turret_swarm_turrets_left--;
552  Assert(num_turret_swarm_turrets_left >= 0);
553 
554  // get turret_swarm_info
555  Assert( (turret_tsi >= 0) && (turret_tsi < MAX_TURRET_SWARM_INFO) );
556  tsi = &Turret_swarm_info[turret_tsi];
557  wip = &Weapon_info[tsi->weapon_class];
558 
559  // check if parent ship is valid (via signature)
560  if ( tsi->parent_sig == parent_obj->signature ) {
561 
562  // make sure we have the right turret.
563  Assert(tsi->turret == subsys);
564 
565  // check if time to fire
566  if (timestamp_elapsed(tsi->time_to_fire)) {
567  Assert(tsi->num_to_launch > 0);
568 
569  // check target still alive
570  if (tsi->target_objnum > -1) {
571  target_obj= &Objects[tsi->target_objnum];
572 
573  if (target_obj->signature != tsi->target_sig) {
574  // poor target, it died
575  tsi->target_objnum = -1;
576  }
577  }
578 
579  // make sure turret is still alive and fire swarmer
580  if (subsys->current_hits > 0) {
582  }
583 
584  // *Get timestamp from weapon info's -Et1
585  if (wip->wi_flags & WIF_SWARM) {
586  tsi->time_to_fire = timestamp( wip->SwarmWait );
587  } else {
588  tsi->time_to_fire = timestamp( wip->cs_delay );
589  }
590 
591  // do book keeping
592  tsi->num_to_launch--;
593 
594  if (tsi->num_to_launch == 0) {
595  // we are done firing, so see about resetting any animation timestamps for reversal (closing)...
596  // (I figure that a good estimate is to trigger a close after three additional swarms had fired - taylor)
599 
600  shipp->num_turret_swarm_info--;
601  subsys->turret_swarm_num--;
603  subsys->turret_swarm_info_index[k] = -1;
604  }
605  }
606  } else {
607  Warning(LOCATION, "Found turret swarm info on ship: %s with turret: %s, but signature does not match.", shipp->ship_name, subsys->system_info->subobj_name);
608  shipp->num_turret_swarm_info--;
609  subsys->turret_swarm_num--;
611  subsys->turret_swarm_info_index[k] = -1;
612  }
613  }
614  //swarm reset stuff
615  for (k = 0; k < (MAX_TFP - 1); k++)
616  {
617  for (j = (k + 1); j < MAX_TFP; j++)
618  {
619  if ((subsys->turret_swarm_info_index[k] == -1) && (subsys->turret_swarm_info_index[j] != -1))
620  {
621  subsys->turret_swarm_info_index[k] = subsys->turret_swarm_info_index[j];
622  subsys->turret_swarm_info_index[j] = -1;
623  }
624  }
625  }
626  }
627  }
628  Assert(num_turret_swarm_turrets_left == 0);
629 }
630 
631 // check Turret_swarm_info for info that are invalid - ie, ships died while firing.
633 {
634  int i;
635  turret_swarm_info *tswarmp;
636  object *ship_objp;
637 
639 
640  // reset timestamp
642 
643  // go through all Turret_swarm_info, check obj and obj->signature
644  for (i=0; i<MAX_TURRET_SWARM_INFO; i++) {
645  tswarmp = &Turret_swarm_info[i];
646 
647  if (tswarmp->flags & SWARM_USED) {
648  ship_objp = &Objects[tswarmp->parent_objnum];
649  if (ship_objp->type == OBJ_SHIP) {
650  if (ship_objp->signature == tswarmp->parent_sig) {
651  continue;
652  }
653  }
654 
656  }
657  }
658  }
659 }
ship_subsys * target_subsys
Definition: swarm.h:29
void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
Definition: aiturret.cpp:2137
int num_swarm_missiles_to_fire
Definition: ship.h:668
float last_dist
Definition: swarm.h:46
int timestamp(int delta_ms)
Definition: timer.cpp:226
fix creation_time
Definition: weapon.h:175
#define MAX_TFP
Definition: model.h:69
int i
Definition: multi_pxo.cpp:466
fix Missiontime
Definition: systemvars.cpp:19
model_subsystem * system_info
Definition: ship.h:314
weapon Weapons[MAX_WEAPONS]
Definition: weapons.cpp:78
int target_sig
Definition: swarm.h:27
#define _isnan(f)
Definition: config.h:280
#define SWARM_CONE_LENGTH
Definition: swarm.cpp:22
EModelAnimationPosition turret_animation_position
Definition: ship.h:351
float vm_vec_mag_quick(const vec3d *v)
Definition: vecmat.cpp:371
object * homing_object
Definition: weapon.h:177
int objnum
Definition: ship.h:537
int SwarmWait
Definition: weapon.h:511
#define SWARM_DIST_STOP_SWARMING
Definition: swarm.cpp:33
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
Definition: vecmat.cpp:266
#define MSS_FLAG2_TURRET_USE_AMMO
Definition: model.h:143
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
ship_weapon weapons
Definition: ship.h:658
float vm_vec_mag(const vec3d *v)
Definition: vecmat.cpp:325
vec3d desired_vel
Definition: physics.h:70
Definition: weapon.h:163
physics_info phys_info
Definition: object.h:157
int path_num
Definition: swarm.h:42
int num_to_launch
Definition: swarm.h:23
#define MAX_SHIPS
Definition: globals.h:37
int weapon_num
Definition: swarm.h:31
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
uint flags2
Definition: model.h:170
Definition: pstypes.h:88
int flags
Definition: swarm.h:35
#define mprintf(args)
Definition: pstypes.h:238
#define WIF_CORKSCREW
Definition: weapon.h:71
ship_weapon weapons
Definition: ship.h:362
short swarm_count
Definition: weapon.h:398
GLclampf f
Definition: Glext.h:7097
#define MAX_OBJECTS
Definition: globals.h:83
int parent_objnum
Definition: swarm.h:24
#define WEAPON_INFO_INDEX(wip)
Definition: weapon.h:613
object obj_used_list
Definition: object.cpp:53
#define f2fl(fx)
Definition: floating.h:37
void turret_swarm_set_up_info(int parent_objnum, ship_subsys *turret, weapon_info *wip, int weapon_num)
Definition: swarm.cpp:423
#define SWARM_POSITIVE_PATH
Definition: swarm.cpp:38
int ship_fire_secondary(object *obj, int allow_swarm)
Definition: ship.cpp:11799
object * objp
Definition: lua.cpp:3105
int cs_delay
Definition: weapon.h:476
int current_secondary_bank
Definition: ship.h:107
#define Int3()
Definition: pstypes.h:292
ship * shipp
Definition: lua.cpp:9162
vec3d pos
Definition: object.h:152
int next_swarm_fire
Definition: ship.h:669
vec3d last_offset
Definition: swarm.h:40
int signature
Definition: object.h:145
vec3d circle_uvec
Definition: swarm.h:39
int weapon_info_index
Definition: weapon.h:164
int cs_num_fired
Definition: weapon.h:472
ship_subsys subsys_list
Definition: ship.h:630
int Turret_swarm_validity_next_check_time
Definition: swarm.cpp:45
vec3d homing_pos
Definition: weapon.h:179
int instance
Definition: object.h:150
void turret_swarm_maybe_fire_missile(int shipnum)
Definition: swarm.cpp:522
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
#define SWARM_CHANGE_DIR_TIME
Definition: swarm.cpp:23
struct matrix::@228::@230 vec
void swarm_maybe_fire_missile(int shipnum)
Definition: swarm.cpp:90
turret_swarm_info Turret_swarm_info[MAX_TURRET_SWARM_INFO]
Definition: swarm.cpp:43
#define nprintf(args)
Definition: pstypes.h:239
void swarm_level_init()
Definition: swarm.cpp:52
#define WIF_SWARM
Definition: weapon.h:59
vec3d circle_rvec
Definition: swarm.h:39
int objnum
Definition: weapon.h:165
float speed
Definition: physics.h:79
float free_flight_time
Definition: weapon.h:357
#define MAX_WEAPON_TYPES
Definition: globals.h:73
int parent
Definition: object.h:147
int num_turret_swarm_info
Definition: ship.h:671
int homing_objnum
Definition: swarm.h:43
int turret_swarm_create()
Definition: swarm.cpp:374
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
int parent_sig
Definition: swarm.h:25
int time_to_fire
Definition: swarm.h:30
float current_hits
Definition: ship.h:319
Definition: ship.h:534
int weapon_class
Definition: swarm.h:22
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:134
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
int wi_flags
Definition: weapon.h:384
#define vm_vec_zero(v)
Definition: vecmat.h:37
int turret_swarm_num
Definition: ship.h:356
#define OBJ_INDEX(objp)
Definition: object.h:235
matrix orient
Definition: object.h:153
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
Definition: vecmat.cpp:257
#define OBJ_SHIP
Definition: object.h:32
void swarm_update_direction(object *objp, float frametime)
Definition: swarm.cpp:184
int turret_animation_done_time
Definition: ship.h:352
#define SWARM_TIME_VARIANCE
Definition: swarm.cpp:31
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
#define MAX_SWARM_MISSILES
Definition: swarm.h:51
vec3d original_target
Definition: swarm.h:37
float frand()
Return random value in range 0.0..1.0- (1.0- means the closest number less than 1.0)
Definition: floating.cpp:35
swarm_info Swarm_missiles[MAX_SWARM_MISSILES]
Definition: swarm.cpp:41
ship_subsys * turret
Definition: swarm.h:28
#define fl2i(fl)
Definition: floating.h:33
#define TURRET_SWARM_VALIDITY_CHECKTIME
Definition: swarm.cpp:35
ship_subsys * targeted_subsys
Definition: ship.h:344
char subobj_name[MAX_NAME_LEN]
Definition: model.h:172
void ai_turn_towards_vector(vec3d *dest, object *objp, float frametime, float turn_time, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec=NULL, int sexp_flags=0)
Definition: aicode.cpp:1131
#define LOCATION
Definition: pstypes.h:245
int target_objnum
Definition: swarm.h:26
#define SWARM_DIST_OFFSET
Definition: swarm.cpp:21
#define timestamp_elapsed(stamp)
Definition: timer.h:102
#define MAX_WEAPONS
Definition: globals.h:71
int change_timestamp
Definition: swarm.h:36
void swarm_delete(int i)
Definition: swarm.cpp:165
void turret_swarm_check_validity()
Definition: swarm.cpp:632
int swarm_create()
Definition: swarm.cpp:136
int turret_swarm_info_index[MAX_TFP]
Definition: ship.h:355
void turret_swarm_delete(int i)
Definition: swarm.cpp:408
int swarm_missile_bank
Definition: ship.h:672
vec3d new_target
Definition: swarm.h:38
#define SWARM_USED
Definition: swarm.cpp:37
int turret_enemy_objnum
Definition: ship.h:337
float angle_offset
Definition: swarm.h:45
char type
Definition: object.h:146
short swarm_index
Definition: weapon.h:180
#define wp(p)
Definition: modelsinc.h:69
int change_time
Definition: swarm.h:44
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:159
float turn_time
Definition: weapon.h:387
char ship_name[NAME_LENGTH]
Definition: ship.h:604
int myrand()
Definition: systemvars.cpp:102
uint change_count
Definition: swarm.h:41
int next_swarm_path
Definition: ship.h:670
#define MAX_TURRET_SWARM_INFO
Definition: swarm.h:54