FS2_Open
Open source remastering of the Freespace 2 engine
debris.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 "cmdline/cmdline.h"
13 #include "debris/debris.h"
14 #include "fireball/fireballs.h"
15 #include "freespace2/freespace.h"
16 #include "gamesnd/gamesnd.h"
17 #include "globalincs/linklist.h"
18 #include "io/timer.h"
19 #include "network/multi.h"
20 #include "network/multimsgs.h"
21 #include "network/multiutil.h"
22 #include "object/objcollide.h"
23 #include "object/objectsnd.h"
24 #include "particle/particle.h"
25 #include "radar/radar.h"
26 #include "radar/radarsetup.h"
27 #include "render/3d.h"
28 #include "ship/ship.h"
29 #include "ship/shipfx.h"
31 #include "weapon/weapon.h"
32 
33 #define MAX_LIFE 10.0f
34 #define MIN_RADIUS_FOR_PERSISTANT_DEBRIS 50 // ship radius at which debris from it becomes persistant
35 #define DEBRIS_SOUND_DELAY 2000 // time to start debris sound after created
36 #define MAX_HULL_PIECES MAX_DEBRIS_PIECES // limit the number of hull debris chunks that can exist.
37 
38 int Num_hull_pieces; // number of hull pieces in existance
39 debris Hull_debris_list; // head of linked list for hull debris chunks, for quick search
40 
42 
44 int Debris_inited = 0;
45 
46 int Debris_model = -1;
49 
50 #define MAX_DEBRIS_DIST 10000.0f // Debris goes away if it's this far away.
51 #define DEBRIS_DISTANCE_CHECK_TIME (10*1000) // Check every 10 seconds.
52 #define DEBRIS_INDEX(dp) (dp-Debris)
53 
54 #define MAX_SPEED_SMALL_DEBRIS 200 // maximum velocity of small debris piece
55 #define MAX_SPEED_BIG_DEBRIS 150 // maximum velocity of big debris piece
56 #define MAX_SPEED_CAPITAL_DEBRIS 100 // maximum velocity of capital debris piece
57 
61 static void debris_start_death_roll(object *debris_obj, debris *debris_p)
62 {
63  if (debris_p->is_hull) {
64  // tell everyone else to blow up the piece of debris
65  if( MULTIPLAYER_MASTER )
67 
68  int fireball_type = fireball_ship_explosion_type(&Ship_info[debris_p->ship_info_index]);
69  if(fireball_type < 0) {
71  }
72  fireball_create( &debris_obj->pos, fireball_type, FIREBALL_LARGE_EXPLOSION, OBJ_INDEX(debris_obj), debris_obj->radius*1.75f);
73 
74  // only play debris destroy sound if hull piece and it has been around for at least 2 seconds
75  if ( Missiontime > debris_p->time_started + 2*F1_0 ) {
76  snd_play_3d( &Snds[SND_MISSILE_IMPACT1], &debris_obj->pos, &View_position, debris_obj->radius );
77 
78  }
79  }
80 
81  debris_obj->flags |= OF_SHOULD_BE_DEAD;
82 }
83 
88 {
89  int i;
90 
91  if ( !Debris_inited ) {
92  Debris_inited = 1;
93  }
94 
95  Debris_model = -1;
98 
99  // Reset everything between levels
100  Num_debris_pieces = 0;
101  for (i=0; i<MAX_DEBRIS_PIECES; i++ ) {
102  Debris[i].flags = 0;
103  Debris[i].sound_delay = 0;
104  Debris[i].objnum = -1;
105  }
106 
107  Num_hull_pieces = 0;
108  list_init(&Hull_debris_list);
109 }
110 
115 {
116  uint i;
117 
118  Debris_model = model_load( NOX("debris01.pof"), 0, NULL );
119  if (Debris_model >= 0) {
120  polymodel * pm;
121  pm = model_get(Debris_model);
123  }
124 
125  Debris_vaporize_model = model_load( NOX("debris02.pof"), 0, NULL );
126 
127  for (i=0; i<Species_info.size(); i++ )
128  {
129  species_info *species = &Species_info[i];
130 
131  nprintf(( "Paging", "Paging in debris texture '%s'\n", species->debris_texture.filename));
132 
134  if (species->debris_texture.bitmap_id < 0)
135  {
136  Warning( LOCATION, "Couldn't load species %s debris\ntexture, '%s'\n", species->species_name, species->debris_texture.filename);
137  }
138 
140  }
141 
142 }
143 
144 MONITOR(NumSmallDebrisRend)
145 MONITOR(NumHullDebrisRend)
146 
151 {
152  int i, num, swapped;
153  polymodel *pm;
154  debris *db;
155 
156 
157  swapped = -1;
158  pm = NULL;
159  num = obj->instance;
160 
161  Assert(num >= 0 && num < MAX_DEBRIS_PIECES);
162  db = &Debris[num];
163 
164  Assert(db->flags & DEBRIS_USED);
165 
166  texture_info *tbase = NULL;
167 
169 
170  // Swap in a different texture depending on the species
171  if (db->species >= 0)
172  {
173  pm = model_get( db->model_num );
174 
175  //WMC - Someday, we should have glowing debris.
176  if ( pm != NULL && (pm->n_textures == 1) ) {
177  tbase = &pm->maps[0].textures[TM_BASE_TYPE];
178  swapped = tbase->GetTexture();
179  tbase->SetTexture(Species_info[db->species].debris_texture.bitmap_id);
180  }
181  }
182 
183  // Only render electrical arcs if within 500m of the eye (for a 10m piece)
184  if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
185  for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
186  if ( timestamp_valid( db->arc_timestamp[i] ) ) {
187  model_add_arc( db->model_num, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_NORMAL );
188  }
189  }
190  }
191 
192  if ( db->is_hull ) {
193  MONITOR_INC(NumHullDebrisRend,1);
194  submodel_render_DEPRECATED( db->model_num, db->submodel_num, &obj->orient, &obj->pos );
195  } else {
196  MONITOR_INC(NumSmallDebrisRend,1);
197  submodel_render_DEPRECATED( db->model_num, db->submodel_num, &obj->orient, &obj->pos, MR_NO_LIGHTING );
198  }
199 
200  if (tbase != NULL && (swapped!=-1) && pm) {
201  tbase->SetTexture(swapped);
202  }
203 }
204 
209 {
210  if ( db->flags & DEBRIS_EXPIRE ) {
211  db->flags &= ~DEBRIS_EXPIRE;
212  if ( db->is_hull ) {
213  Num_hull_pieces--;
214  list_remove(Hull_debris_list, db);
215  Assert( Num_hull_pieces >= 0 );
216  }
217  }
218 }
219 
225 void debris_delete( object * obj )
226 {
227  int num;
228  debris *db;
229 
230  num = obj->instance;
231  Assert( Debris[num].objnum == OBJ_INDEX(obj));
232 
233  db = &Debris[num];
234 
235  Assert( Num_debris_pieces >= 0 );
236  if ( db->is_hull && (db->flags & DEBRIS_EXPIRE) ) {
238  }
239 
240  db->flags = 0;
241  db->objnum = -1;
243 }
244 
251 {
252  object *objp;
253 
255  if (!(Game_mode & GM_MULTIPLAYER)) { // In single player game, just check against player.
257  db->lifeleft = 0.1f;
258  else
260  } else {
261  for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
262  if (objp->flags & OF_PLAYER_SHIP) {
263  if (vm_vec_dist_quick(&objp->pos, &Objects[db->objnum].pos) < MAX_DEBRIS_DIST) {
265  return;
266  }
267  }
268  }
269  db->lifeleft = 0.1f;
270  }
271  }
272 }
273 
274 MONITOR(NumSmallDebris)
275 MONITOR(NumHullDebris)
276 
284 void debris_process_post(object * obj, float frame_time)
285 {
286  int i, num;
287  num = obj->instance;
288 
289  int objnum = OBJ_INDEX(obj);
290  Assert( Debris[num].objnum == objnum );
291  debris *db = &Debris[num];
292 
293  if ( db->is_hull ) {
294  MONITOR_INC(NumHullDebris,1);
295  radar_plot_object( obj );
296 
297  if ( timestamp_elapsed(db->sound_delay) ) {
299  db->sound_delay = 0;
300  }
301  } else {
302  MONITOR_INC(NumSmallDebris,1);
303  }
304 
305  if ( db->lifeleft >= 0.0f) {
306  db->lifeleft -= frame_time;
307  if ( db->lifeleft < 0.0f ) {
308  debris_start_death_roll(obj, db);
309  }
310  }
311 
312  maybe_delete_debris(db); // Make this debris go away if it's very far away.
313 
314  // ================== DO THE ELECTRIC ARCING STUFF =====================
315  if ( db->arc_frequency <= 0 ) {
316  return; // If arc_frequency <= 0, this piece has no arcs on it
317  }
318 
320 
322  db->arc_frequency += 100;
323 
324  if (db->is_hull) {
325 
326  int n, n_arcs = ((rand()>>5) % 3)+1; // Create 1-3 sparks
327 
328  vec3d v1, v2, v3, v4;
329 
333  } else {
336  }
337 
338  n = 0;
339 
340  int a = 100, b = 1000;
341  int lifetime = (myrand()%((b)-(a)+1))+(a);
342 
343  // Create the spark effects
344  for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
345  if ( !timestamp_valid( db->arc_timestamp[i] ) ) {
346 
347  db->arc_timestamp[i] = timestamp(lifetime); // live up to a second
348 
349  switch( n ) {
350  case 0:
351  db->arc_pts[i][0] = v1;
352  db->arc_pts[i][1] = v2;
353  break;
354  case 1:
355  db->arc_pts[i][0] = v2;
356  db->arc_pts[i][1] = v3;
357  break;
358 
359  case 2:
360  db->arc_pts[i][0] = v2;
361  db->arc_pts[i][1] = v4;
362  break;
363 
364  default:
365  Int3();
366  }
367 
368  n++;
369  if ( n == n_arcs )
370  break; // Don't need to create anymore
371  }
372  }
373 
374 
375  // rotate v2 out of local coordinates into world.
376  // Use v2 since it is used in every bolt. See above switch().
377  vec3d snd_pos;
378  vm_vec_unrotate(&snd_pos, &v2, &obj->orient);
379  vm_vec_add2(&snd_pos, &obj->pos );
380 
381  //Play a sound effect
382  if ( lifetime > 750 ) {
383  // 1.00 second effect
384  snd_play_3d( &Snds[SND_DEBRIS_ARC_05], &snd_pos, &View_position, obj->radius );
385  } else if ( lifetime > 500 ) {
386  // 0.75 second effect
387  snd_play_3d( &Snds[SND_DEBRIS_ARC_04], &snd_pos, &View_position, obj->radius );
388  } else if ( lifetime > 250 ) {
389  // 0.50 second effect
390  snd_play_3d( &Snds[SND_DEBRIS_ARC_03], &snd_pos, &View_position, obj->radius );
391  } else if ( lifetime > 100 ) {
392  // 0.25 second effect
393  snd_play_3d( &Snds[SND_DEBRIS_ARC_02], &snd_pos, &View_position, obj->radius );
394  } else {
395  // 0.10 second effect
396  snd_play_3d( &Snds[SND_DEBRIS_ARC_01], &snd_pos, &View_position, obj->radius );
397  }
398  }
399  }
400 
401  for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
402  if ( timestamp_valid( db->arc_timestamp[i] ) ) {
403  if ( timestamp_elapsed( db->arc_timestamp[i] ) ) {
404  // Kill off the spark
405  db->arc_timestamp[i] = timestamp(-1);
406  } else {
407  // Maybe move a vertex.... 20% of the time maybe?
408  int mr = myrand();
409  if ( mr < RAND_MAX/5 ) {
410  vec3d v1, v2;
411 
414  } else {
416  }
417 
418  db->arc_pts[i][mr % 2] = v1;
419  }
420  }
421  }
422  }
423 }
424 
430 {
431  int oldest_index;
432  fix oldest_time;
433  debris *db;
434 
435  oldest_index = -1;
436  oldest_time = 0x7fffffff;
437 
438  for ( db = GET_FIRST(&Hull_debris_list); db != END_OF_LIST(&Hull_debris_list); db = GET_NEXT(db) ) {
439  if ( (db->time_started < oldest_time) && !(Objects[db->objnum].flags & OF_SHOULD_BE_DEAD) ) {
440  oldest_index = DEBRIS_INDEX(db);
441  oldest_time = db->time_started;
442  }
443  }
444 
445  return oldest_index;
446 }
447 
448 #define DEBRIS_ROTVEL_SCALE 5.0f
450 
462 object *debris_create(object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force)
463 {
464  int i, n, objnum, parent_objnum;
465  object *obj;
466  ship *shipp;
467  debris *db;
468  polymodel *pm;
469  int vaporize;
470  physics_info *pi = NULL;
471  ship_info *sip = NULL;
472 
473  parent_objnum = OBJ_INDEX(source_obj);
474 
475  Assert( (source_obj->type == OBJ_SHIP ) || (source_obj->type == OBJ_GHOST));
476  Assert( source_obj->instance >= 0 && source_obj->instance < MAX_SHIPS );
477  shipp = &Ships[source_obj->instance];
478  sip = &Ship_info[shipp->ship_info_index];
479  vaporize = (shipp->flags &SF_VAPORIZE);
480 
481  if ( !hull_flag ) {
482  // Make vaporize debris seen from farther away
483  float dist = vm_vec_dist_quick( pos, &Eye_position );
484  if (vaporize) {
485  dist /= 2.0f;
486  }
487  if ( dist > 200.0f ) {
488  return NULL;
489  }
490  }
491 
492  if ( hull_flag && (Num_hull_pieces >= MAX_HULL_PIECES ) ) {
493  // cause oldest hull debris chunk to blow up
494  n = debris_find_oldest();
495  if ( n >= 0 ) {
496  debris_start_death_roll(&Objects[Debris[n].objnum], &Debris[n] );
497  }
498  }
499 
500  for (n=0; n<MAX_DEBRIS_PIECES; n++ ) {
501  if ( !(Debris[n].flags & DEBRIS_USED) )
502  break;
503  }
504 
505  if (n == MAX_DEBRIS_PIECES) {
506  n = debris_find_oldest();
507 
508  if (n >= 0)
509  debris_start_death_roll(&Objects[Debris[n].objnum], &Debris[n]);
510 
511  nprintf(("Warning","Frame %i: Could not create debris, no more slots left\n", Framecount));
512  return NULL;
513  }
514 
515  db = &Debris[n];
516 
517  //WMC - We must survive until now, at least.
519 
520  if(hull_flag && sip->debris_min_lifetime >= 0.0f && sip->debris_max_lifetime >= 0.0f)
521  {
522  db->lifeleft = (( sip->debris_max_lifetime - sip->debris_min_lifetime ) * frand()) + sip->debris_min_lifetime;
523  }
524  else
525  {
526  // Create Debris piece n!
527  if ( hull_flag ) {
528  if (rand() < RAND_MAX/6) // Make some pieces blow up shortly after explosion.
529  db->lifeleft = 2.0f * (myrand() * RAND_MAX_1f) + 0.5f;
530  else
531  db->lifeleft = -1.0f; // large hull pieces stay around forever
532  } else {
533  db->lifeleft = (myrand() * RAND_MAX_1f) * 2.0f + 0.1f;
534  }
535  }
536 
537  //WMC - Oh noes, we may need to change lifeleft
538  if(hull_flag)
539  {
540  if(sip->debris_min_lifetime >= 0.0f && sip->debris_max_lifetime >= 0.0f)
541  {
542  db->must_survive_until = timestamp(fl2i(sip->debris_min_lifetime * 1000.0f));
543  db->lifeleft = (( sip->debris_max_lifetime - sip->debris_min_lifetime ) * frand()) + sip->debris_min_lifetime;
544  }
545  else if(sip->debris_min_lifetime >= 0.0f)
546  {
547  db->must_survive_until = timestamp(fl2i(sip->debris_min_lifetime * 1000.0f));
548  if(db->lifeleft < sip->debris_min_lifetime)
549  db->lifeleft = sip->debris_min_lifetime;
550  }
551  else if(sip->debris_max_lifetime >= 0.0f)
552  {
553  if(db->lifeleft > sip->debris_max_lifetime)
554  db->lifeleft = sip->debris_max_lifetime;
555  }
556  }
557 
558  // increase lifetime for vaporized debris
559  if (vaporize) {
560  db->lifeleft *= 3.0f;
561  }
562  db->flags |= DEBRIS_USED;
563  db->is_hull = hull_flag;
564  db->source_objnum = parent_objnum;
565  db->source_sig = source_obj->signature;
567  db->ship_info_index = shipp->ship_info_index;
568  db->team = shipp->team;
569  db->fire_timeout = 0; // if not changed, timestamp_elapsed() will return false
571  db->species = Ship_info[shipp->ship_info_index].species;
573  db->parent_alt_name = shipp->alt_type_index;
574  db->damage_mult = 1.0f;
575 
576  for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
577  db->arc_timestamp[i] = timestamp(-1);
578  }
579 
580  if ( db->is_hull ) {
581  // Percent of debris pieces with arcs controlled via table (default 50%)
582  if (frand() < sip->debris_arc_percent) {
583  db->arc_frequency = 1000;
584  } else {
585  db->arc_frequency = 0;
586  }
587  } else {
588  db->arc_frequency = 0;
589  }
590 
591  if ( model_num < 0 ) {
592  if (vaporize) {
594  } else {
595  db->model_num = Debris_model;
596  }
598  } else {
599  db->model_num = model_num;
601  }
602  float radius = submodel_get_radius( db->model_num, db->submodel_num );
603 
604  db->next_fireball = timestamp_rand(500,2000); //start one 1/2 - 2 secs later
605 
606  if ( pos == NULL )
607  pos = &source_obj->pos;
608 
610  if ( hull_flag )
611  flags |= OF_COLLIDES;
612  objnum = obj_create( OBJ_DEBRIS, parent_objnum, n, &source_obj->orient, pos, radius, flags );
613  if ( objnum == -1 ) {
614  mprintf(("Couldn't create debris object -- out of object slots\n"));
615  return NULL;
616  }
617 
618  db->objnum = objnum;
619 
620  obj = &Objects[objnum];
621  pi = &obj->phys_info;
622 
623  // assign the network signature. The signature will be 0 for non-hull pieces, but since that
624  // is our invalid signature, it should be okay.
625  obj->net_signature = 0;
626 
627  if ( (Game_mode & GM_MULTIPLAYER) && hull_flag ) {
629  }
630 
631  if (source_obj->type == OBJ_SHIP) {
632  obj->hull_strength = Ships[source_obj->instance].ship_max_hull_strength/8.0f;
633  } else
634  obj->hull_strength = 10.0f;
635 
636  if (hull_flag) {
637  if(sip->debris_min_hitpoints >= 0.0f && sip->debris_max_hitpoints >= 0.0f)
638  {
640  }
641  else if(sip->debris_min_hitpoints >= 0.0f)
642  {
643  if(obj->hull_strength < sip->debris_min_hitpoints)
645  }
646  else if(sip->debris_max_hitpoints >= 0.0f)
647  {
648  if(obj->hull_strength > sip->debris_max_hitpoints)
650  }
651  db->damage_mult = sip->debris_damage_mult;
652  }
653 
655 
656  vec3d rotvel, radial_vel, to_center;
657 
658  if ( exp_center )
659  vm_vec_sub( &to_center,pos, exp_center );
660  else
661  vm_vec_zero(&to_center);
662 
663  float scale;
664 
665  if ( hull_flag ) {
666  float t;
667  scale = exp_force * i2fl((myrand()%20) + 10); // for radial_vel away from location of blast center
669 
670  // set up physics mass and I_inv for hull debris pieces
671  pm = model_get(model_num);
672  vec3d *min, *max;
673  min = &pm->submodel[submodel_num].min;
674  max = &pm->submodel[submodel_num].max;
675  calc_debris_physics_properties( &obj->phys_info, min, max );
676 
677  // limit the amount of time that fireballs appear
678  // let fireball length be linked to radius of ship. Range is .33 radius => 3.33 radius seconds.
679  t = 1000*Objects[db->source_objnum].radius/3 + myrand()%(fl2i(1000*3*Objects[db->source_objnum].radius));
680  db->fire_timeout = timestamp(fl2i(t)); // fireballs last from 5 - 30 seconds
681 
683  db->flags |= DEBRIS_EXPIRE; // debris can expire
684  Num_hull_pieces++;
685  list_append(&Hull_debris_list, db);
686  } else {
687  nprintf(("Alan","A forever chunk of debris was created from ship with radius %f\n",Objects[db->source_objnum].radius));
688  }
689  }
690  else {
691  scale = exp_force * i2fl((myrand()%20) + 10); // for radial_vel away from blast center (non-hull)
692  }
693 
694  if ( vm_vec_mag_squared( &to_center ) < 0.1f ) {
695  vm_vec_rand_vec_quick(&radial_vel);
696  vm_vec_scale(&radial_vel, scale );
697  }
698  else {
699  vm_vec_normalize(&to_center);
700  vm_vec_copy_scale(&radial_vel, &to_center, scale );
701  }
702 
703  // DA: here we need to vel_from_rot = w x to_center, where w is world is unrotated to world coords and offset is the
704  // displacement fromt the center of the parent object to the center of the debris piece
705  vec3d world_rotvel, vel_from_rotvel;
706  vm_vec_unrotate ( &world_rotvel, &source_obj->phys_info.rotvel, &source_obj->orient );
707  vm_vec_cross ( &vel_from_rotvel, &world_rotvel, &to_center );
708  vm_vec_scale ( &vel_from_rotvel, DEBRIS_ROTVEL_SCALE);
709 
710  vm_vec_add (&obj->phys_info.vel, &radial_vel, &source_obj->phys_info.vel);
711  vm_vec_add2(&obj->phys_info.vel, &vel_from_rotvel);
712 
713  // make sure rotational velocity does not get too high
714  if (radius < 1.0) {
715  radius = 1.0f;
716  }
717 
718  scale = ( 6.0f + i2fl(myrand()%4) ) / radius;
719 
720  vm_vec_rand_vec_quick(&rotvel);
721  vm_vec_scale(&rotvel, scale);
722 
723  pi->flags |= PF_DEAD_DAMP;
724  pi->rotvel = rotvel;
725  check_rotvel_limit( &obj->phys_info );
726 
727  // check that debris is not created with too high a velocity
728  if (hull_flag)
729  {
730  shipfx_debris_limit_speed(db, shipp);
731  }
732 
733  // blow out his reverse thrusters. Or drag, same thing.
734  pi->rotdamp = 10000.0f;
735  pi->side_slip_time_const = 10000.0f;
736  pi->flags |= (PF_REDUCED_DAMP | PF_DEAD_DAMP); // set damping equal for all axis and not changable
737 
738  vm_vec_zero(&pi->max_vel); // make so he can't turn on his own VOLITION anymore.
739  vm_vec_zero(&pi->max_rotvel); // make so he can't change speed on his own VOLITION anymore.
740 
741  // ensure vel is valid
742  Assert( !vm_is_vec_nan(&obj->phys_info.vel) );
743 
744  return obj;
745 }
746 
751 void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float damage)
752 {
753  debris *debris_p = &Debris[debris_obj->instance];
754 
755  // Do a little particle spark shower to show we hit
756  {
757  particle_emitter pe;
758 
759  pe.pos = *hitpos; // Where the particles emit from
760  pe.vel = debris_obj->phys_info.vel; // Initial velocity of all the particles
761 
762  vec3d tmp_norm;
763  vm_vec_sub( &tmp_norm, hitpos, &debris_obj->pos );
764  vm_vec_normalize_safe(&tmp_norm);
765 
766  pe.normal = tmp_norm; // What normal the particle emit around
767  pe.normal_variance = 0.3f; // How close they stick to that normal 0=good, 1=360 degree
768  pe.min_rad = 0.20f; // Min radius
769  pe.max_rad = 0.40f; // Max radius
770 
771  // Sparks for first time at this spot
772  pe.num_low = 10; // Lowest number of particles to create
773  pe.num_high = 10; // Highest number of particles to create
774  pe.normal_variance = 0.3f; // How close they stick to that normal 0=good, 1=360 degree
775  pe.min_vel = 0.0f; // How fast the slowest particle can move
776  pe.max_vel = 10.0f; // How fast the fastest particle can move
777  pe.min_life = 0.25f; // How long the particles live
778  pe.max_life = 0.75f; // How long the particles live
779  particle_emit( &pe, PARTICLE_FIRE, 0 );
780  }
781 
782  // multiplayer clients bail here
783  if(MULTIPLAYER_CLIENT){
784  return;
785  }
786 
787  if ( damage < 0.0f ) {
788  damage = 0.0f;
789  }
790 
791  debris_obj->hull_strength -= damage;
792 
793  if (debris_obj->hull_strength < 0.0f) {
794  debris_start_death_roll(debris_obj, debris_p );
795  } else {
796  // otherwise, give all the other players an update on the debris
797  if(MULTIPLAYER_MASTER){
799  }
800  }
801 }
802 
808 int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, collision_info_struct *debris_hit_info)
809 {
810  mc_info mc;
811  mc_info_init(&mc);
812  int num;
813 
814  Assert( pdebris->type == OBJ_DEBRIS );
815 
816  num = pdebris->instance;
817  Assert( num >= 0 );
818 
819  Assert( Debris[num].objnum == OBJ_INDEX(pdebris));
820 
821  // debris_hit_info NULL - so debris-weapon collision
822  if ( debris_hit_info == NULL ) {
823  // debris weapon collision
824  Assert( other_obj->type == OBJ_WEAPON );
825  mc.model_instance_num = -1;
826  mc.model_num = Debris[num].model_num; // Fill in the model to check
827  mc.submodel_num = Debris[num].submodel_num;
829  mc.orient = &pdebris->orient; // The object's orient
830  mc.pos = &pdebris->pos; // The object's position
831  mc.p0 = &other_obj->last_pos; // Point 1 of ray to check
832  mc.p1 = &other_obj->pos; // Point 2 of ray to check
834 
835  if (model_collide(&mc)) {
836  *hitpos = mc.hit_point_world;
837  }
838 
839  weapon *wp = &Weapons[other_obj->instance];
840  wp->collisionOccured = true;
841  memcpy(&wp->collisionInfo, &mc, sizeof(mc_info));
842 
843  return mc.num_hits;
844  }
845 
846  // debris ship collision -- use debris_hit_info to calculate physics
847  object *pship_obj = other_obj;
848  Assert( pship_obj->type == OBJ_SHIP );
849 
850  object *heavy = debris_hit_info->heavy;
851  object *lighter = debris_hit_info->light;
852  object *heavy_obj = heavy;
853  object *light_obj = lighter;
854 
855  vec3d zero, p0, p1;
856  vm_vec_zero(&zero);
857  vm_vec_sub(&p0, &lighter->last_pos, &heavy->last_pos);
858  vm_vec_sub(&p1, &lighter->pos, &heavy->pos);
859 
860  mc.pos = &zero; // The object's position
861  mc.p0 = &p0; // Point 1 of ray to check
862  mc.p1 = &p1; // Point 2 of ray to check
863 
864  // find the light object's position in the heavy object's reference frame at last frame and also in this frame.
865  vec3d p0_temp, p0_rotated;
866 
867  // Collision detection from rotation enabled if at rotaion is less than 30 degree in frame
868  // This should account for all ships
869  if ( (vm_vec_mag_squared(&heavy->phys_info.rotvel) * flFrametime*flFrametime) < (PI*PI/36) ) {
870  // collide_rotate calculate (1) start position and (2) relative velocity
871  debris_hit_info->collide_rotate = 1;
872  vm_vec_rotate(&p0_temp, &p0, &heavy->last_orient);
873  vm_vec_unrotate(&p0_rotated, &p0_temp, &heavy->orient);
874  mc.p0 = &p0_rotated; // Point 1 of ray to check
875  vm_vec_sub(&debris_hit_info->light_rel_vel, &p1, &p0_rotated);
876  vm_vec_scale(&debris_hit_info->light_rel_vel, 1/flFrametime);
877  } else {
878  debris_hit_info->collide_rotate = 0;
879  vm_vec_sub(&debris_hit_info->light_rel_vel, &lighter->phys_info.vel, &heavy->phys_info.vel);
880  }
881 
882  int mc_ret_val = 0;
883 
884  if ( debris_hit_info->heavy == pship_obj ) { // ship is heavier, so debris is sphere. Check sphere collision against ship poly model
886  mc.model_num = Ship_info[Ships[pship_obj->instance].ship_info_index].model_num; // Fill in the model to check
887  mc.orient = &pship_obj->orient; // The object's orient
888  mc.radius = pdebris->radius;
890 
891  // copy important data
892  int copy_flags = mc.flags; // make a copy of start end positions of sphere in big ship RF
893  vec3d copy_p0, copy_p1;
894  copy_p0 = *mc.p0;
895  copy_p1 = *mc.p1;
896 
897  // first test against the sphere - if this fails then don't do any submodel tests
899 
900  SCP_vector<int> submodel_vector;
901  polymodel_instance *pmi;
902 
903  if (model_collide(&mc)) {
904 
905  // Set earliest hit time
906  debris_hit_info->hit_time = FLT_MAX;
907 
908  // Do collision the cool new way
909  if ( debris_hit_info->collide_rotate ) {
911 
912  // We collide with the sphere, find the list of rotating submodels and test one at a time
913  model_get_rotating_submodel_list(&submodel_vector, heavy_obj);
914 
915  // Get polymodel and turn off all rotating submodels, collide against only 1 at a time.
917 
918  // turn off all rotating submodels and test for collision
919  for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
920  pmi->submodel[*smv].collision_checked = true;
921  }
922 
923  // reset flags to check MC_CHECK_MODEL | MC_CHECK_SPHERELINE and maybe MC_CHECK_INVISIBLE_FACES and MC_SUBMODEL_INSTANCE
924  mc.flags = copy_flags | MC_SUBMODEL_INSTANCE;
925 
926  if (Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod > -1) {
927  mc.lod = Ship_info[Ships[pship_obj->instance].ship_info_index].collision_lod;
928  }
929 
930  // check each submodel in turn
931  for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
932  // turn on submodel for collision test
933  pmi->submodel[*smv].collision_checked = false;
934 
935  // set angles for last frame (need to set to prev to get p0)
936  angles copy_angles = pmi->submodel[*smv].angs;
937 
938  // find the start and end positions of the sphere in submodel RF
939  pmi->submodel[*smv].angs = pmi->submodel[*smv].prev_angs;
940  world_find_model_instance_point(&p0, &light_obj->last_pos, pmi, *smv, &heavy_obj->last_orient, &heavy_obj->last_pos);
941 
942  pmi->submodel[*smv].angs = copy_angles;
943  world_find_model_instance_point(&p1, &light_obj->pos, pmi, *smv, &heavy_obj->orient, &heavy_obj->pos);
944 
945  mc.p0 = &p0;
946  mc.p1 = &p1;
947 
949  mc.submodel_num = *smv;
950 
951  if ( model_collide(&mc) ) {
952  if ( mc.hit_dist < debris_hit_info->hit_time ) {
953  mc_ret_val = 1;
954 
955  // set up debris_hit_info common
956  set_hit_struct_info(debris_hit_info, &mc, SUBMODEL_ROT_HIT);
957  model_instance_find_world_point(&debris_hit_info->hit_pos, &mc.hit_point, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
958 
959  // set up debris_hit_info for rotating submodel
960  if (debris_hit_info->edge_hit == 0) {
962  }
963 
964  // find position in submodel RF of light object at collison
965  vec3d int_light_pos, diff;
966  vm_vec_sub(&diff, mc.p1, mc.p0);
967  vm_vec_scale_add(&int_light_pos, mc.p0, &diff, mc.hit_dist);
968  model_instance_find_world_point(&debris_hit_info->light_collision_cm_pos, &int_light_pos, mc.model_instance_num, mc.hit_submodel, &heavy_obj->orient, &zero);
969  }
970  }
971  // Don't look at this submodel again
972  pmi->submodel[*smv].collision_checked = true;
973  }
974  }
975 
976  // Recover and do usual ship_ship collision, but without rotating submodels
977  mc.flags = copy_flags;
978  *mc.p0 = copy_p0;
979  *mc.p1 = copy_p1;
980  mc.orient = &heavy_obj->orient;
981 
982  // usual ship_ship collision test
983  if ( model_collide(&mc) ) {
984  // check if this is the earliest hit
985  if (mc.hit_dist < debris_hit_info->hit_time) {
986  mc_ret_val = 1;
987 
988  set_hit_struct_info(debris_hit_info, &mc, SUBMODEL_NO_ROT_HIT);
989 
990  // get collision normal if not edge hit
991  if (debris_hit_info->edge_hit == 0) {
992  model_instance_find_obj_dir(&debris_hit_info->collision_normal, &mc.hit_normal, Ships[heavy_obj->instance].model_instance_num, mc.hit_submodel, &heavy_obj->orient);
993  }
994 
995  // find position in submodel RF of light object at collison
996  vec3d diff;
997  vm_vec_sub(&diff, mc.p1, mc.p0);
998  vm_vec_scale_add(&debris_hit_info->light_collision_cm_pos, mc.p0, &diff, mc.hit_dist);
999 
1000  }
1001  }
1002  }
1003 
1004  } else {
1005  // Debris is heavier obj
1006  mc.model_instance_num = -1;
1007  mc.model_num = Debris[num].model_num; // Fill in the model to check
1008  mc.submodel_num = Debris[num].submodel_num;
1010  mc.orient = &pdebris->orient; // The object's orient
1011  mc.radius = model_get_core_radius(Ship_info[Ships[pship_obj->instance].ship_info_index].model_num);
1012 
1013  // check for collision between debris model and ship sphere
1015 
1016  mc_ret_val = model_collide(&mc);
1017 
1018  if (mc_ret_val) {
1019  set_hit_struct_info(debris_hit_info, &mc, SUBMODEL_NO_ROT_HIT);
1020 
1021  // set normal if not edge hit
1022  if ( !debris_hit_info->edge_hit ) {
1023  vm_vec_unrotate(&debris_hit_info->collision_normal, &mc.hit_normal, &heavy->orient);
1024  }
1025 
1026  // find position in submodel RF of light object at collison
1027  vec3d diff;
1028  vm_vec_sub(&diff, mc.p1, mc.p0);
1029  vm_vec_scale_add(&debris_hit_info->light_collision_cm_pos, mc.p0, &diff, mc.hit_dist);
1030 
1031  }
1032  }
1033 
1034 
1035  if ( mc_ret_val ) {
1036 
1037  // SET PHYSICS PARAMETERS
1038  // already have (hitpos - heavy) and light_cm_pos
1039  // get heavy cm pos - already have light_cm_pos
1040  debris_hit_info->heavy_collision_cm_pos = zero;
1041 
1042  // get r_heavy and r_light
1043  debris_hit_info->r_heavy = debris_hit_info->hit_pos;
1044  vm_vec_sub(&debris_hit_info->r_light, &debris_hit_info->hit_pos, &debris_hit_info->light_collision_cm_pos);
1045 
1046  // set normal for edge hit
1047  if ( debris_hit_info->edge_hit ) {
1048  vm_vec_copy_normalize(&debris_hit_info->collision_normal, &debris_hit_info->r_light);
1049  vm_vec_negate(&debris_hit_info->collision_normal);
1050  }
1051 
1052  // get world hitpos
1053  vm_vec_add(hitpos, &debris_hit_info->heavy->pos, &debris_hit_info->r_heavy);
1054 
1055  return 1;
1056  } else {
1057  // no hit
1058  return 0;
1059  }
1060 }
1061 
1065 int debris_get_team(object *objp)
1066 {
1067  Assert( objp->type == OBJ_DEBRIS );
1068  Assert( objp->instance >= 0 && objp->instance < MAX_DEBRIS_PIECES );
1069  return Debris[objp->instance].team;
1070 }
1071 
1076 {
1077  float dx, dy, dz, mass;
1078  dx = maxs->xyz.x - mins->xyz.x;
1079  dy = maxs->xyz.y - mins->xyz.y;
1080  dz = maxs->xyz.z - mins->xyz.z;
1081 
1082  // John, with new bspgen, just set pi->mass = mass
1083  mass = 0.12f * dx * dy * dz;
1084  pi->mass = (float) pow(mass, 0.6666667f) * 4.65f;
1085 
1086  pi->I_body_inv.vec.rvec.xyz.x = 12.0f / (pi->mass * (dy*dy + dz*dz));
1087  pi->I_body_inv.vec.rvec.xyz.y = 0.0f;
1088  pi->I_body_inv.vec.rvec.xyz.z = 0.0f;
1089 
1090  pi->I_body_inv.vec.uvec.xyz.x = 0.0f;
1091  pi->I_body_inv.vec.uvec.xyz.y = 12.0f / (pi->mass * (dx*dx + dz*dz));
1092  pi->I_body_inv.vec.uvec.xyz.z = 0.0f;
1093 
1094  pi->I_body_inv.vec.fvec.xyz.x = 0.0f;
1095  pi->I_body_inv.vec.fvec.xyz.y = 0.0f;
1096  pi->I_body_inv.vec.fvec.xyz.z = 12.0f / (pi->mass * (dx*dx + dy*dy));
1097 }
1098 
1099 void debris_render(object * obj, draw_list *scene)
1100 {
1101  int i, num, swapped;
1102  polymodel *pm;
1103  debris *db;
1104 
1105 
1106  swapped = -1;
1107  pm = NULL;
1108  num = obj->instance;
1109 
1110  Assert(num >= 0 && num < MAX_DEBRIS_PIECES);
1111  db = &Debris[num];
1112 
1113  Assert(db->flags & DEBRIS_USED);
1114 
1115  texture_info *tbase = NULL;
1116 
1118 
1119  // Swap in a different texture depending on the species
1120  if (db->species >= 0)
1121  {
1122  pm = model_get( db->model_num );
1123 
1124  //WMC - Someday, we should have glowing debris.
1125  if ( pm != NULL && (pm->n_textures == 1) ) {
1126  tbase = &pm->maps[0].textures[TM_BASE_TYPE];
1127  swapped = tbase->GetTexture();
1128  tbase->SetTexture(Species_info[db->species].debris_texture.bitmap_id);
1129  }
1130  }
1131 
1132  // Only render electrical arcs if within 500m of the eye (for a 10m piece)
1133  if ( vm_vec_dist_quick( &obj->pos, &Eye_position ) < obj->radius*50.0f ) {
1134  for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
1135  if ( timestamp_valid( db->arc_timestamp[i] ) ) {
1136  model_add_arc( db->model_num, db->submodel_num, &db->arc_pts[i][0], &db->arc_pts[i][1], MARC_TYPE_NORMAL );
1137  }
1138  }
1139  }
1140 
1141  model_render_params render_info;
1142 
1143  if ( !db->is_hull ) {
1144  render_info.set_flags(MR_NO_LIGHTING);
1145  }
1146 
1147  MONITOR_INC(NumHullDebrisRend,1);
1148  submodel_render_queue( &render_info, scene, db->model_num, db->submodel_num, &obj->orient, &obj->pos );
1149 
1150  if (tbase != NULL && (swapped!=-1) && pm) {
1151  tbase->SetTexture(swapped);
1152  }
1153 }
void calc_debris_physics_properties(physics_info *pi, vec3d *min, vec3d *max)
Definition: debris.cpp:1075
void mc_info_init(mc_info *mc)
Definition: model.h:1138
vec3d max
Definition: model.h:343
float submodel_get_radius(int modelnum, int submodelnum)
Definition: modelread.cpp:3123
int model_collide(mc_info *mc_info_obj)
void radar_plot_object(object *objp)
Definition: radarsetup.cpp:146
int arc_frequency
Definition: debris.h:46
bsp_info * submodel
Definition: model.h:764
int timestamp(int delta_ms)
Definition: timer.cpp:226
#define MULTIPLAYER_CLIENT
Definition: multi.h:132
int Framecount
Definition: systemvars.cpp:22
int i
Definition: multi_pxo.cpp:466
fix Missiontime
Definition: systemvars.cpp:19
int n_textures
Definition: model.h:761
weapon Weapons[MAX_WEAPONS]
Definition: weapons.cpp:78
0.75 second spark sound effect
Definition: gamesnd.h:213
vec3d hit_point
Definition: model.h:1123
#define TM_BASE_TYPE
Definition: model.h:657
vec3d * pos
Definition: model.h:1113
int team
Definition: ship.h:606
int Cmdline_old_collision_sys
Definition: cmdline.cpp:489
vec3d min
Definition: model.h:342
#define SUBMODEL_ROT_HIT
Definition: objcollide.h:72
int next_distance_check
Definition: debris.h:42
vec3d View_position
Definition: 3dsetup.cpp:20
int Game_mode
Definition: systemvars.cpp:24
#define F1_0
Definition: fix.h:15
float debris_arc_percent
Definition: ship.h:1267
vec3d rotvel
Definition: physics.h:78
int debris_get_team(object *objp)
Definition: debris.cpp:1065
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
Definition: vecmat.cpp:266
int alt_type_index
Definition: ship.h:556
float debris_min_lifetime
Definition: ship.h:1257
polymodel * model_get(int model_num)
Definition: modelread.cpp:3134
int Debris_model
Definition: debris.cpp:46
0.50 second spark sound effect
Definition: gamesnd.h:212
fix time_started
Definition: debris.h:41
SCP_vector< game_snd > Snds
Definition: gamesnd.cpp:19
#define FIREBALL_LARGE_EXPLOSION
Definition: fireballs.h:24
float flFrametime
Definition: fredstubs.cpp:22
#define MULTI_SIG_DEBRIS
Definition: multiutil.h:35
#define DEBRIS_ROTVEL_SCALE
Definition: debris.cpp:448
Definition: weapon.h:163
ushort multi_get_next_network_signature(int what_kind)
Definition: multiutil.cpp:168
physics_info phys_info
Definition: object.h:157
void debris_render_DEPRECATED(object *obj)
Definition: debris.cpp:150
#define MAX_SHIPS
Definition: globals.h:37
void model_get_rotating_submodel_list(SCP_vector< int > *submodel_vector, object *objp)
Definition: modelread.cpp:4468
int source_sig
Definition: debris.h:27
int model_instance_num
Definition: ship.h:802
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)
#define SUBMODEL_NO_ROT_HIT
Definition: objcollide.h:71
Definition: pstypes.h:88
#define mprintf(args)
Definition: pstypes.h:238
ushort net_signature
Definition: object.h:163
float side_slip_time_const
Definition: physics.h:44
hull_check p0
Definition: lua.cpp:5051
#define OF_RENDERS
Definition: object.h:103
vec3d arc_pts[MAX_DEBRIS_ARCS][2]
Definition: debris.h:44
void set_flags(uint flags)
#define MARC_TYPE_NORMAL
Definition: model.h:252
#define MR_NO_LIGHTING
Definition: model.h:867
struct vec3d::@225::@227 xyz
vec3d max_vel
Definition: physics.h:49
GLclampf f
Definition: Glext.h:7097
int model_num
Definition: debris.h:34
float model_get_core_radius(int modelnum)
Definition: modelread.cpp:3114
int damage_type_idx
Definition: debris.h:28
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:933
int lod
Definition: model.h:1118
void model_add_arc(int model_num, int sub_model_num, vec3d *v1, vec3d *v2, int arc_type)
Definition: modelread.cpp:5003
object obj_used_list
Definition: object.cpp:53
int bitmap_id
Definition: generic.h:53
#define OF_COLLIDES
Definition: object.h:104
#define FIREBALL_EXPLOSION_LARGE1
Definition: fireballs.h:32
uint flags
Definition: ship.h:644
#define OF_PLAYER_SHIP
Definition: object.h:109
float debris_max_hitpoints
Definition: ship.h:1265
int Num_debris_pieces
Definition: debris.cpp:43
object * objp
Definition: lua.cpp:3105
float hit_dist
Definition: model.h:1122
GLenum GLenum GLenum GLenum GLenum scale
Definition: Glext.h:8503
GLfloat GLfloat GLfloat v2
Definition: Glext.h:5640
matrix I_body_inv
Definition: physics.h:41
#define Int3()
Definition: pstypes.h:292
vec3d max_rotvel
Definition: physics.h:52
#define MAX_DEBRIS_PIECES
Definition: debris.h:57
ship * shipp
Definition: lua.cpp:9162
vec3d pos
Definition: object.h:152
vec3d * p0
Definition: model.h:1114
hull_check submodel_num
Definition: lua.cpp:5048
float vm_vec_mag_squared(const vec3d *v)
Definition: vecmat.cpp:339
void particle_emit(particle_emitter *pe, int type, int optional_data, float range)
Definition: particle.cpp:495
int signature
Definition: object.h:145
void debris_process_post(object *obj, float frame_time)
Definition: debris.cpp:284
int model_num
Definition: model.h:1110
int obj_snd_assign(int objnum, int sndnum, vec3d *pos, int main, int flags, ship_subsys *associated_sub)
Definition: objectsnd.cpp:705
void submodel_render_DEPRECATED(int model_num, int submodel_num, matrix *orient, vec3d *pos, uint flags=MR_DEPRECATED_NORMAL, int objnum=-1, int *replacement_textures=NULL, int render=MODEL_RENDER_ALL)
0.10 second spark sound effect
Definition: gamesnd.h:210
void debris_hit(object *debris_obj, object *other_obj, vec3d *hitpos, float damage)
Definition: debris.cpp:751
void shipfx_debris_limit_speed(debris *db, ship *shipp)
Definition: shipfx.cpp:2031
int submodel_num
Definition: debris.h:35
int fire_timeout
Definition: debris.h:39
vec3d heavy_collision_cm_pos
Definition: objcollide.h:25
int is_hull
Definition: debris.h:37
void model_instance_find_world_point(vec3d *outpnt, vec3d *mpnt, int model_instance_num, int submodel_num, const matrix *objorient, const vec3d *objpos)
Definition: modelread.cpp:4135
int instance
Definition: object.h:150
Definition: debris.h:23
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
vec3d last_pos
Definition: object.h:155
mc_info collisionInfo
Definition: weapon.h:231
#define PARTICLE_FIRE
Definition: particle.h:51
int team
Definition: debris.h:30
int flags
Definition: model.h:1116
struct matrix::@228::@230 vec
unsigned int uint
Definition: pstypes.h:64
#define PF_REDUCED_DAMP
Definition: physics.h:22
float ship_max_hull_strength
Definition: ship.h:597
void vm_vec_scale(vec3d *dest, float s)
Definition: vecmat.cpp:248
#define nprintf(args)
Definition: pstypes.h:239
#define GM_MULTIPLAYER
Definition: systemvars.h:18
float rotdamp
Definition: physics.h:43
#define DEBRIS_DISTANCE_CHECK_TIME
Definition: debris.cpp:51
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
int fireball_ship_explosion_type(ship_info *sip)
Definition: fireballs.cpp:993
int obj_create(ubyte type, int parent_obj, int instance, matrix *orient, vec3d *pos, float radius, uint flags)
Definition: object.cpp:467
vec3d * p1
Definition: model.h:1115
float damage_mult
Definition: debris.h:48
void model_clear_instance(int model_num)
Definition: modelread.cpp:4624
#define OBJ_WEAPON
Definition: object.h:33
int snd_play_3d(game_snd *gs, vec3d *source_pos, vec3d *listen_pos, float radius, vec3d *source_vel, int looping, float vol_scale, int priority, vec3d *sound_fvec, float range_factor, int force, bool is_ambient)
Definition: sound.cpp:594
texture_map maps[MAX_MODEL_TEXTURES]
Definition: model.h:762
#define MAX_DEBRIS_DIST
Definition: debris.cpp:50
float hull_strength
Definition: object.h:160
#define OBJ_DEBRIS
Definition: object.h:37
void world_find_model_instance_point(vec3d *out, vec3d *world_pt, const polymodel_instance *pmi, int submodel_num, const matrix *orient, const vec3d *pos)
Definition: modelread.cpp:4215
#define MC_SUBMODEL
Definition: model.h:1178
void submodel_render_queue(model_render_params *render_info, draw_list *scene, int model_num, int submodel_num, matrix *orient, vec3d *pos)
void debris_clear_expired_flag(debris *db)
Definition: debris.cpp:208
submodel_instance * submodel
Definition: model.h:100
const float RAND_MAX_1f
Definition: pstypes.h:309
int flags
Definition: debris.h:25
float lifeleft
Definition: debris.h:32
#define vm_vec_negate(v)
Definition: vecmat.h:70
#define MIN_RADIUS_FOR_PERSISTANT_DEBRIS
Definition: debris.cpp:34
float debris_max_lifetime
Definition: ship.h:1258
hull_check p1
Definition: lua.cpp:5052
int hit_submodel
Definition: model.h:1125
int ship_info_index
Definition: debris.h:29
bool collisionOccured
Definition: weapon.h:230
generic_bitmap debris_texture
Definition: species_defs.h:58
#define MONITOR(function_name)
Definition: pstypes.h:454
debris Hull_debris_list
Definition: debris.cpp:39
int source_objnum
Definition: debris.h:26
Definition: ship.h:534
int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, int ferror=1, int duplicate=0)
Definition: modelread.cpp:2573
float radius
Definition: model.h:1117
float vm_vec_normalize_safe(vec3d *v)
Definition: vecmat.cpp:471
GLdouble GLdouble t
Definition: Glext.h:5329
debris Debris[MAX_DEBRIS_PIECES]
Definition: debris.cpp:41
#define MC_CHECK_SPHERELINE
Definition: model.h:1177
void model_instance_find_obj_dir(vec3d *w_vec, vec3d *m_vec, int model_instance_num, int submodel_num, matrix *objorient)
Definition: modelread.cpp:3416
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
#define DEBRIS_SOUND_DELAY
Definition: debris.cpp:35
void maybe_delete_debris(debris *db)
Definition: debris.cpp:250
#define MC_SUBMODEL_INSTANCE
Definition: model.h:1179
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
long fix
Definition: pstypes.h:54
void submodel_get_two_random_points(int model_num, int submodel_num, vec3d *v1, vec3d *v2, vec3d *n1=NULL, vec3d *n2=NULL)
GLclampd n
Definition: Glext.h:7286
#define MONITOR_INC(function_name, inc)
Definition: pstypes.h:457
#define vm_vec_zero(v)
Definition: vecmat.h:37
uint flags
Definition: physics.h:37
int sound_delay
Definition: debris.h:40
int debris_find_oldest()
Definition: debris.cpp:429
#define DEBRIS_UPDATE_NUKE
Definition: multi.h:317
#define OBJ_INDEX(objp)
Definition: object.h:235
vec3d hit_point_world
Definition: model.h:1124
int parent_alt_name
Definition: debris.h:47
void send_debris_update_packet(object *objp, int code)
Definition: multimsgs.cpp:5294
matrix orient
Definition: object.h:153
#define NOX(s)
Definition: pstypes.h:473
#define FIREBALL_NUM_LARGE_EXPLOSIONS
Definition: fireballs.h:38
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
Definition: vecmat.cpp:257
#define OBJ_SHIP
Definition: object.h:32
GLfloat GLfloat v1
Definition: Glext.h:5639
void set_hit_struct_info(collision_info_struct *hit, mc_info *mc, int submodel_rot_hit)
GLbitfield flags
Definition: Glext.h:6722
void vm_vec_rand_vec_quick(vec3d *rvec)
Definition: vecmat.cpp:1379
int Debris_num_submodels
Definition: debris.cpp:48
int objnum
Definition: debris.h:31
int SetTexture(int n_tex)
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
vec3d vel
Definition: physics.h:77
vec3d Eye_position
Definition: 3dsetup.cpp:27
#define SF_VAPORIZE
Definition: ship.h:470
int check_rotvel_limit(physics_info *pi)
Definition: physics.cpp:1064
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
int num_hits
Definition: model.h:1121
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
GLuint GLuint num
Definition: Glext.h:9089
int species
Definition: debris.h:38
int must_survive_until
Definition: debris.h:33
polymodel_instance * model_get_instance(int model_instance_num)
Definition: modelread.cpp:3154
float frame_time
Definition: multi.cpp:1426
float debris_damage_mult
Definition: ship.h:1266
float vm_vec_dist_quick(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:417
#define MAX_DEBRIS_ARCS
Definition: debris.h:21
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
bool collision_checked
Definition: model.h:92
int n_models
Definition: model.h:744
void submodel_get_two_random_points_better(int model_num, int submodel_num, vec3d *v1, vec3d *v2)
#define fl2i(fl)
Definition: floating.h:33
0.25 second spark sound effect
Definition: gamesnd.h:211
#define MAX_HULL_PIECES
Definition: debris.cpp:36
void bm_page_in_texture(int bitmapnum, int nframes)
Marks a texture as being used for this level.
Definition: bmpman.cpp:2462
int Num_hull_pieces
Definition: debris.cpp:38
#define MC_CHECK_MODEL
Definition: model.h:1169
void debris_render(object *obj, draw_list *scene)
Definition: debris.cpp:1099
int debris_check_collision(object *pdebris, object *other_obj, vec3d *hitpos, collision_info_struct *debris_hit_info)
Definition: debris.cpp:808
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:427
void debris_init()
Definition: debris.cpp:87
#define vm_is_vec_nan(v)
Definition: vecmat.h:19
#define OF_PHYSICS
Definition: object.h:105
int ship_info_index
Definition: ship.h:539
#define MULTIPLAYER_MASTER
Definition: multi.h:130
int arc_timestamp[MAX_DEBRIS_ARCS]
Definition: debris.h:45
texture_info textures[TM_NUM_TYPES]
Definition: model.h:671
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define LOCATION
Definition: pstypes.h:245
#define DEBRIS_EXPIRE
Definition: debris.h:55
char species_name[NAME_LENGTH]
Definition: species_defs.h:47
#define PF_DEAD_DAMP
Definition: physics.h:24
#define timestamp_elapsed(stamp)
Definition: timer.h:102
float debris_min_hitpoints
Definition: ship.h:1264
SCP_vector< species_info > Species_info
1.00 second spark sound effect
Definition: gamesnd.h:214
float normal_variance
Definition: particle.h:114
#define OF_SHOULD_BE_DEAD
Definition: object.h:106
int next_fireball
Definition: debris.h:36
#define PI
Definition: pstypes.h:303
hull_check pos
Definition: lua.cpp:5050
#define DEBRIS_UPDATE_UPDATE
Definition: multi.h:315
#define DEBRIS_INDEX(dp)
Definition: debris.cpp:52
debris sound (persistant, looping)
Definition: gamesnd.h:99
GLsizei GLsizei GLuint * obj
Definition: Glext.h:5619
int model_instance_num
Definition: model.h:1109
void debris_delete(object *obj)
Definition: debris.cpp:225
#define i2fl(i)
Definition: floating.h:32
#define timestamp_rand(a, b)
Definition: timer.h:92
object * Player_obj
Definition: object.cpp:56
object * debris_create(object *source_obj, int model_num, int submodel_num, vec3d *pos, vec3d *exp_center, int hull_flag, float exp_force)
Definition: debris.cpp:462
polymodel * pm
Definition: lua.cpp:1598
vec3d hit_normal
Definition: model.h:1129
#define DEBRIS_USED
Definition: debris.h:54
char filename[MAX_FILENAME_LEN]
Definition: generic.h:52
float mass
Definition: physics.h:39
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:645
uint flags
Definition: object.h:151
float radius
Definition: object.h:154
missile impact 1
Definition: gamesnd.h:157
void debris_page_in()
Definition: debris.cpp:114
matrix last_orient
Definition: object.h:156
int model_num
Definition: lua.cpp:4996
int submodel_num
Definition: model.h:1111
char type
Definition: object.h:146
angles angs
Definition: model.h:88
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
#define wp(p)
Definition: modelsinc.h:69
#define MC_ONLY_SPHERE
Definition: model.h:1171
matrix * orient
Definition: model.h:1112
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:159
#define OBJ_GHOST
Definition: object.h:39
matrix vmd_identity_matrix
Definition: vecmat.cpp:28
#define timestamp_valid(stamp)
Definition: timer.h:104
int Debris_vaporize_model
Definition: debris.cpp:47
int Debris_inited
Definition: debris.cpp:44
angles prev_angs
Definition: model.h:89
int myrand()
Definition: systemvars.cpp:102
vec3d light_collision_cm_pos
Definition: objcollide.h:26
int debris_damage_type_idx
Definition: ship.h:799
GLfloat GLfloat GLfloat GLfloat v3
Definition: Glext.h:5641
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460
int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_obj, float size, int reverse, vec3d *velocity, float warp_lifetime, int ship_class, matrix *orient_override, int low_res, int extra_flags, int warp_open_sound, int warp_close_sound)
Definition: fireballs.cpp:788