FS2_Open
Open source remastering of the Freespace 2 engine
object.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 
13 #include "asteroid/asteroid.h"
14 #include "cmeasure/cmeasure.h"
15 #include "debris/debris.h"
16 #include "debugconsole/console.h"
17 #include "fireball/fireballs.h"
18 #include "freespace2/freespace.h"
19 #include "globalincs/linklist.h"
20 #include "iff_defs/iff_defs.h"
21 #include "io/timer.h"
22 #include "jumpnode/jumpnode.h"
23 #include "lighting/lighting.h"
24 #include "mission/missionparse.h" //For 2D Mode
25 #include "network/multi.h"
26 #include "network/multiutil.h"
27 #include "object/deadobjectdock.h"
28 #include "object/objcollide.h"
29 #include "object/object.h"
30 #include "object/objectdock.h"
31 #include "object/objectshield.h"
32 #include "object/objectsnd.h"
33 #include "observer/observer.h"
34 #include "parse/scripting.h"
35 #include "playerman/player.h"
36 #include "radar/radar.h"
37 #include "radar/radarsetup.h"
38 #include "render/3d.h"
39 #include "ship/afterburner.h"
40 #include "ship/ship.h"
41 #include "weapon/beam.h"
42 #include "weapon/shockwave.h"
43 #include "weapon/swarm.h"
44 #include "weapon/weapon.h"
45 
46 
47 
48 /*
49  * Global variables
50  */
51 
55 
56 object *Player_obj = NULL;
57 object *Viewer_obj = NULL;
58 
59 extern int Cmdline_old_collision_sys;
60 
61 //Data for objects
63 
64 #ifdef OBJECT_CHECK
66 #endif
67 
68 int Num_objects=-1;
71 int Object_next_signature = 1; //0 is bogus, start at 1
72 int Object_inited = 0;
74 
75 //WMC - Made these prettier
77 //XSTR:OFF
78  "None",
79  "Ship",
80  "Weapon",
81  "Fireball",
82  "Start",
83  "Waypoint",
84  "Debris",
85  "Countermeasure",
86  "Ghost",
87  "Point",
88  "Shockwave",
89  "Wing",
90  "Observer",
91  "Asteroid",
92  "Jump Node",
93  "Beam",
94 //XSTR:ON
95 };
96 
98  {OF_INVULNERABLE, "invulnerable", 1, },
99  {OF_PROTECTED, "protect-ship", 1, },
100  {OF_BEAM_PROTECTED, "beam-protect-ship", 1, },
101  {OF_NO_SHIELDS, "no-shields", 1, },
102  {OF_TARGETABLE_AS_BOMB, "targetable-as-bomb", 1, },
103  {OF_FLAK_PROTECTED, "flak-protect-ship", 1, },
104  {OF_LASER_PROTECTED, "laser-protect-ship", 1, },
105  {OF_MISSILE_PROTECTED, "missile-protect-ship", 1, },
106  {OF_IMMOBILE, "immobile", 1, },
107  {OF_COLLIDES, "collides", 1, },
108 };
109 
110 // all we need to set are the pointers, but type, parent, and instance are useful to set as well
112  : next(NULL), prev(NULL), type(OBJ_NONE), parent(-1), instance(-1), n_quadrants(0), hull_strength(0.0),
113  sim_hull_strength(0.0), net_signature(0), num_pairs(0), dock_list(NULL), dead_dock_list(NULL), collision_group_id(0)
114 {
115  memset(&(this->phys_info), 0, sizeof(physics_info));
116 }
117 
119 {
120  objsnd_num.clear();
121 
122  dock_free_dock_list(this);
124 }
125 
126 // DO NOT set next and prev to NULL because they keep the object on the free and used lists
128 {
130  parent = parent_sig = instance = -1;
132  flags = 0;
137  shield_quadrant.clear();
138  objsnd_num.clear();
139  net_signature = 0;
140 
141  // just in case nobody called obj_delete last mission
142  dock_free_dock_list(this);
144 }
145 
152 int free_object_slots(int num_used)
153 {
154  int i, olind, deleted_weapons;
155  int obj_list[MAX_OBJECTS];
156  int num_already_free, num_to_free, original_num_to_free;
157  object *objp;
158 
159  olind = 0;
160 
161  // calc num_already_free by walking the obj_free_list
162  num_already_free = 0;
163  for ( objp = GET_FIRST(&obj_free_list); objp != END_OF_LIST(&obj_free_list); objp = GET_NEXT(objp) )
164  num_already_free++;
165 
166  if (MAX_OBJECTS - num_already_free < num_used)
167  return 0;
168 
169  for ( objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
170  if (objp->flags & OF_SHOULD_BE_DEAD) {
171  num_already_free++;
172  if (MAX_OBJECTS - num_already_free < num_used)
173  return num_already_free;
174  } else
175  switch (objp->type) {
176  case OBJ_NONE:
177  num_already_free++;
178  if (MAX_OBJECTS - num_already_free < num_used)
179  return 0;
180  break;
181  case OBJ_FIREBALL:
182  case OBJ_WEAPON:
183  case OBJ_DEBRIS:
184 // case OBJ_CMEASURE:
185  obj_list[olind++] = OBJ_INDEX(objp);
186  break;
187 
188  case OBJ_GHOST:
189  case OBJ_SHIP:
190  case OBJ_START:
191  case OBJ_WAYPOINT:
192  case OBJ_POINT:
193  case OBJ_SHOCKWAVE:
194  case OBJ_WING:
195  case OBJ_OBSERVER:
196  case OBJ_ASTEROID:
197  case OBJ_JUMP_NODE:
198  case OBJ_BEAM:
199  break;
200  default:
201  Int3(); // Hey, what kind of object is this? Unknown!
202  break;
203  }
204 
205  }
206 
207  num_to_free = MAX_OBJECTS - num_used - num_already_free;
208  original_num_to_free = num_to_free;
209 
210  if (num_to_free > olind) {
211  nprintf(("allender", "Warning: Asked to free %i objects, but can only free %i.\n", num_to_free, olind));
212  num_to_free = olind;
213  }
214 
215  for (i=0; i<num_to_free; i++)
216  if ( (Objects[obj_list[i]].type == OBJ_DEBRIS) && (Debris[Objects[obj_list[i]].instance].flags & DEBRIS_EXPIRE) ) {
217  num_to_free--;
218  nprintf(("allender", "Freeing DEBRIS object %3i\n", obj_list[i]));
219  Objects[obj_list[i]].flags |= OF_SHOULD_BE_DEAD;
220  }
221 
222  if (!num_to_free)
223  return original_num_to_free;
224 
225  for (i=0; i<num_to_free; i++) {
226  object *tmp_obj = &Objects[obj_list[i]];
227  if ( (tmp_obj->type == OBJ_FIREBALL) && (fireball_is_perishable(tmp_obj)) ) {
228  num_to_free--;
229  nprintf(("allender", "Freeing FIREBALL object %3i\n", obj_list[i]));
230  tmp_obj->flags |= OF_SHOULD_BE_DEAD;
231  }
232  }
233 
234  if (!num_to_free){
235  return original_num_to_free;
236  }
237 
238  deleted_weapons = collide_remove_weapons();
239 
240  num_to_free -= deleted_weapons;
241  if ( !num_to_free ){
242  return original_num_to_free;
243  }
244 
245  for (i=0; i<num_to_free; i++){
246  if ( Objects[obj_list[i]].type == OBJ_WEAPON ) {
247  num_to_free--;
248  Objects[obj_list[i]].flags |= OF_SHOULD_BE_DEAD;
249  }
250  }
251 
252  if (!num_to_free){
253  return original_num_to_free;
254  }
255 
256  return original_num_to_free - num_to_free;
257 }
258 
259 // Goober5000
260 float get_max_shield_quad(object *objp)
261 {
262  Assert(objp);
263  if(objp->type != OBJ_SHIP) {
264  return 0.0f;
265  }
266 
267  return Ships[objp->instance].ship_max_shield_strength / objp->n_quadrants;
268 }
269 
270 // Goober5000
271 float get_hull_pct(object *objp)
272 {
273  Assert(objp);
274  Assert(objp->type == OBJ_SHIP);
275 
276  float total_strength = Ships[objp->instance].ship_max_hull_strength;
277 
278  Assert(total_strength > 0.0f); // unlike shield, no ship can have 0 hull
279 
280  if (total_strength == 0.0f)
281  return 0.0f;
282 
283  if (objp->hull_strength < 0.0f) // this sometimes happens when a ship is being destroyed
284  return 0.0f;
285 
286  return objp->hull_strength / total_strength;
287 }
288 
289 float get_sim_hull_pct(object *objp)
290 {
291  Assert(objp);
292  Assert(objp->type == OBJ_SHIP);
293 
294  float total_strength = Ships[objp->instance].ship_max_hull_strength;
295 
296  Assert(total_strength > 0.0f); // unlike shield, no ship can have 0 hull
297 
298  if (total_strength == 0.0f)
299  return 0.0f;
300 
301  if (objp->sim_hull_strength < 0.0f) // this sometimes happens when a ship is being destroyed
302  return 0.0f;
303 
304  return objp->sim_hull_strength / total_strength;
305 }
306 
307 // Goober5000
308 float get_shield_pct(object *objp)
309 {
310  Assert(objp);
311 
312  // bah - we might have asteroids
313  if (objp->type != OBJ_SHIP)
314  return 0.0f;
315 
316  float total_strength = Ships[objp->instance].ship_max_shield_strength;
317 
318  if (total_strength == 0.0f)
319  return 0.0f;
320 
321  return shield_get_strength(objp) / total_strength;
322 }
323 
327 void obj_init()
328 {
329  int i;
330  object *objp;
331 
332  Object_inited = 1;
333  for (i = 0; i < MAX_OBJECTS; ++i)
334  Objects[i].clear();
335  Viewer_obj = NULL;
336 
337  list_init( &obj_free_list );
338  list_init( &obj_used_list );
339  list_init( &obj_create_list );
340 
341  // Link all object slots into the free list
342  objp = Objects;
343  for (i=0; i<MAX_OBJECTS; i++) {
344  list_append(&obj_free_list, objp);
345  objp++;
346  }
347 
348  Object_next_signature = 1; //0 is invalid, others start at 1
349  Num_objects = 0;
351 
353  obj_reset_pairs();
354  } else {
356  }
357 }
358 
359 static int num_objects_hwm = 0;
360 
370 int obj_allocate(void)
371 {
372  int objnum;
373  object *objp;
374 
375  if (!Object_inited) {
376  mprintf(("Why hasn't obj_init() been called yet?\n"));
377  obj_init();
378  }
379 
380  if ( Num_objects >= MAX_OBJECTS-10 ) {
381  int num_freed;
382 
383  num_freed = free_object_slots(MAX_OBJECTS-10);
384  nprintf(("warning", " *** Freed %i objects\n", num_freed));
385  }
386 
387  if (Num_objects >= MAX_OBJECTS) {
388  #ifndef NDEBUG
389  mprintf(("Object creation failed - too many objects!\n" ));
390  #endif
391  return -1;
392  }
393 
394  // Find next available object
395  objp = GET_FIRST(&obj_free_list);
396  Assert ( objp != &obj_free_list ); // shouldn't have the dummy element
397 
398  // remove objp from the free list
399  list_remove( &obj_free_list, objp );
400 
401  // insert objp onto the end of create list
402  list_append( &obj_create_list, objp );
403 
404  // increment counter
405  Num_objects++;
406 
407  if (Num_objects > num_objects_hwm) {
408  num_objects_hwm = Num_objects;
409  }
410 
411  // get objnum
412  objnum = OBJ_INDEX(objp);
413 
414  if (objnum > Highest_object_index) {
415  Highest_object_index = objnum;
418  }
419 
420  return objnum;
421 }
422 
429 void obj_free(int objnum)
430 {
431  object *objp;
432 
433  if (!Object_inited) {
434  mprintf(("Why hasn't obj_init() been called yet?\n"));
435  obj_init();
436  }
437 
438  Assert( objnum >= 0 ); // Trying to free bogus object!!!
439 
440  // get object pointer
441  objp = &Objects[objnum];
442 
443  // remove objp from the used list
444  list_remove( &obj_used_list, objp );
445 
446  // add objp to the end of the free
447  list_append( &obj_free_list, objp );
448 
449  // decrement counter
450  Num_objects--;
451 
452  Objects[objnum].type = OBJ_NONE;
453 
454  Assert(Num_objects >= 0);
455 
456  if (objnum == Highest_object_index)
457  while (Objects[--Highest_object_index].type == OBJ_NONE);
458 
459 }
460 
467 int obj_create(ubyte type,int parent_obj,int instance, matrix * orient,
468  vec3d * pos, float radius, uint flags )
469 {
470  int objnum;
471  object *obj;
472 
473  // Find next free object
474  objnum = obj_allocate();
475 
476  if (objnum == -1) //no free objects
477  return -1;
478 
479  obj = &Objects[objnum];
480  Assert(obj->type == OBJ_NONE); //make sure unused
481 
482  // clear object in preparation for setting of custom values
483  obj->clear();
484 
485  Assert(Object_next_signature > 0); // 0 is bogus!
487 
488  obj->type = type;
489  obj->instance = instance;
490  obj->parent = parent_obj;
491  if (obj->parent != -1) {
492  obj->parent_sig = Objects[parent_obj].signature;
493  obj->parent_type = Objects[parent_obj].type;
494  } else {
495  obj->parent_sig = obj->signature;
496  obj->parent_type = obj->type;
497  }
498 
499  obj->flags = flags | OF_NOT_IN_COLL;
500  if (pos) {
501  obj->pos = *pos;
502  obj->last_pos = *pos;
503  }
504 
505  if (orient) {
506  obj->orient = *orient;
507  obj->last_orient = *orient;
508  }
509  obj->radius = radius;
510 
511  obj->n_quadrants = DEFAULT_SHIELD_SECTIONS; // Might be changed by the ship creation code
512  obj->shield_quadrant.resize(obj->n_quadrants);
513  return objnum;
514 }
515 
522 void obj_delete(int objnum)
523 {
524  object *objp;
525 
526  Assert(objnum >= 0 && objnum < MAX_OBJECTS);
527  objp = &Objects[objnum];
528  if (objp->type == OBJ_NONE) {
529  mprintf(("obj_delete() called for already deleted object %d.\n", objnum));
530  return;
531  };
532 
533  // Remove all object pairs
535  obj_remove_pairs( objp );
536  } else {
537  obj_remove_collider(objnum);
538  }
539 
540  switch( objp->type ) {
541  case OBJ_WEAPON:
542  weapon_delete( objp );
543  break;
544  case OBJ_SHIP:
545  if ((objp == Player_obj) && !Fred_running) {
546  objp->type = OBJ_GHOST;
547  objp->flags &= ~(OF_SHOULD_BE_DEAD);
548 
549  // we have to traverse the ship_obj list and remove this guy from it as well
550  ship_obj *moveup = GET_FIRST(&Ship_obj_list);
551  while(moveup != END_OF_LIST(&Ship_obj_list)){
552  if(OBJ_INDEX(objp) == moveup->objnum){
553  list_remove(&Ship_obj_list,moveup);
554  break;
555  }
556  moveup = GET_NEXT(moveup);
557  }
558 
559  physics_init(&objp->phys_info);
561  return;
562  } else
563  ship_delete( objp );
564  break;
565  case OBJ_FIREBALL:
566  fireball_delete( objp );
567  break;
568  case OBJ_SHOCKWAVE:
569  shockwave_delete( objp );
570  break;
571  case OBJ_START:
572  case OBJ_WAYPOINT:
573  case OBJ_POINT:
575  break; // requires no action, handled by the Fred code.
576  case OBJ_JUMP_NODE:
577  break; // requires no further action, handled by jumpnode deconstructor.
578  case OBJ_DEBRIS:
579  debris_delete( objp );
580  break;
581  case OBJ_ASTEROID:
582  asteroid_delete(objp);
583  break;
584 /* case OBJ_CMEASURE:
585  cmeasure_delete( objp );
586  break;*/
587  case OBJ_GHOST:
588  if(!(Game_mode & GM_MULTIPLAYER)){
589  mprintf(("Warning: Tried to delete a ghost!\n"));
590  objp->flags &= ~OF_SHOULD_BE_DEAD;
591  return;
592  } else {
593  // we need to be able to delete GHOST objects in multiplayer to allow for player respawns.
594  nprintf(("Network","Deleting GHOST object\n"));
595  }
596  break;
597  case OBJ_OBSERVER:
598  observer_delete(objp);
599  break;
600  case OBJ_BEAM:
601  break;
602  case OBJ_NONE:
603  Int3();
604  break;
605  default:
606  Error( LOCATION, "Unhandled object type %d in obj_delete_all_that_should_be_dead", objp->type );
607  }
608 
609  // delete any dock information we still have
610  dock_free_dock_list(objp);
612 
613  // if a persistant sound has been created, delete it
615 
616  objp->type = OBJ_NONE; //unused!
617  objp->signature = 0;
618 
619  obj_free(objnum);
620 }
621 
622 
623 // ------------------------------------------------------------------------------------------------------------------
625 {
626  object *objp, *temp;
627 
628  if (!Object_inited) {
629  mprintf(("Why hasn't obj_init() been called yet?\n"));
630  obj_init();
631  }
632 
633  // Move all objects
634  objp = GET_FIRST(&obj_used_list);
635  while( objp !=END_OF_LIST(&obj_used_list) ) {
636  // Goober5000 - HACK HACK HACK - see obj_move_all
638 
639  temp = GET_NEXT(objp);
640  if ( objp->flags&OF_SHOULD_BE_DEAD )
641  obj_delete( OBJ_INDEX(objp) ); // MWA says that john says that let obj_delete handle everything because of the editor
642  objp = temp;
643  }
644 
645 }
646 
652 {
653  // The old way just merged the two. This code takes one out of the create list,
654  // creates object pairs for it, and then adds it to the used list.
655  // OLD WAY: list_merge( &obj_used_list, &obj_create_list );
656  object *objp = GET_FIRST(&obj_create_list);
657  while( objp !=END_OF_LIST(&obj_create_list) ) {
658  list_remove( obj_create_list, objp );
659 
660  // Add it to the object pairs array
662  obj_add_pairs(OBJ_INDEX(objp));
663  } else {
665  }
666 
667  // Then add it to the object used list
668  list_append( &obj_used_list, objp );
669 
670  objp = GET_FIRST(&obj_create_list);
671  }
672 
673  // Make sure the create list is empty.
674  list_init(&obj_create_list);
675 }
676 
678 
679 
680 // Goober5000
681 extern void call_doa(object *child, object *parent);
682 void obj_move_one_docked_object(object *objp, object *parent_objp)
683 {
684  // in FRED, just move and return
685  if (Fred_running)
686  {
687  call_doa(objp, parent_objp);
688  return;
689  }
690 
691  // support ships (and anyone else, for that matter) don't keep up if they're undocking
692  ai_info *aip = &Ai_info[Ships[objp->instance].ai_index];
693  if ( (aip->mode == AIM_DOCK) && (aip->submode >= AIS_UNDOCK_1) )
694  {
695  if (aip->goal_objnum == OBJ_INDEX(parent_objp))
696  {
697  return;
698  }
699  }
700 
701  // check the guy that I'm docked with and don't move if he's undocking from me
702  ai_info *other_aip = &Ai_info[Ships[parent_objp->instance].ai_index];
703  if ( (other_aip->mode == AIM_DOCK) && (other_aip->submode >= AIS_UNDOCK_1) )
704  {
705  if (other_aip->goal_objnum == OBJ_INDEX(objp))
706  {
707  return;
708  }
709  }
710 
711  // we're here, so we move with our parent object
712  call_doa(objp, parent_objp);
713 }
714 
721 {
722  ship *shipp;
723 
724  Assert( objp->flags & OF_PLAYER_SHIP);
725 
726  // try and get the ship pointer
727  shipp = NULL;
728  if((objp->type == OBJ_SHIP) && (objp->instance >= 0) && (objp->instance < MAX_SHIPS)){
729  shipp = &Ships[objp->instance];
730  } else {
731  return;
732  }
733 
734  // single player pilots, and all players in multiplayer take care of firing their own primaries
735  if(!(Game_mode & GM_MULTIPLAYER) || (objp == Player_obj))
736  {
737  if ( ci.fire_primary_count ) {
738  // flag the ship as having the trigger down
739  if(shipp != NULL){
740  shipp->flags |= SF_TRIGGER_DOWN;
741  }
742 
743  // fire non-streaming primaries here
744  ship_fire_primary( objp, 0 );
745  } else {
746  // unflag the ship as having the trigger down
747  if(shipp != NULL){
748  shipp->flags &= ~(SF_TRIGGER_DOWN);
749  ship_stop_fire_primary(objp); //if it hasn't fired do the "has just stoped fireing" stuff
750  }
751  }
752 
753  if ( ci.fire_countermeasure_count ) {
755  }
756  }
757 
758  // single player and multiplayer masters do all of the following
759  if ( !MULTIPLAYER_CLIENT ) {
760  if ( ci.fire_secondary_count ) {
761  ship_fire_secondary( objp );
762 
763  // kill the secondary count
764  ci.fire_secondary_count = 0;
765  }
766  }
767 
768  // everyone does the following for their own ships.
769  if ( ci.afterburner_start ){
771  afterburners_start( objp );
772  }
773  }
774 
775  if ( ci.afterburner_stop ){
776  afterburners_stop( objp, 1 );
777  }
778 
779 }
780 
781 void obj_move_call_physics(object *objp, float frametime)
782 {
783  int has_fired = -1; //stop fireing stuff-Bobboau
784 
785  // Do physics for objects with OF_PHYSICS flag set and with some engine strength remaining.
786  if ( objp->flags & OF_PHYSICS ) {
787  // only set phys info if ship is not dead
788  if ((objp->type == OBJ_SHIP) && !(Ships[objp->instance].flags & SF_DYING)) {
789  ship *shipp = &Ships[objp->instance];
790  float engine_strength;
791 
792  engine_strength = ship_get_subsystem_strength(shipp, SUBSYSTEM_ENGINE);
793  if ( ship_subsys_disrupted(shipp, SUBSYSTEM_ENGINE) ) {
794  engine_strength=0.0f;
795  }
796 
797  if (engine_strength == 0.0f) { // All this is necessary to make ship gradually come to a stop after engines are blown.
801  objp->phys_info.side_slip_time_const = Ship_info[shipp->ship_info_index].damp * 4.0f;
802  }
803 
804  if (shipp->weapons.num_secondary_banks > 0) {
805  polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num);
806  Assertion( pm != NULL, "No polymodel found for ship %s", Ship_info[shipp->ship_info_index].name );
807  Assertion( pm->missile_banks != NULL, "Ship %s has %d secondary banks, but no missile banks could be found.\n", Ship_info[shipp->ship_info_index].name, shipp->weapons.num_secondary_banks );
808 
809  for (int i = 0; i < shipp->weapons.num_secondary_banks; i++) {
810  //if there are no missles left don't bother
811  if (shipp->weapons.secondary_bank_ammo[i] == 0)
812  continue;
813 
814  int points = pm->missile_banks[i].num_slots;
815  int missles_left = shipp->weapons.secondary_bank_ammo[i];
816  int next_point = shipp->weapons.secondary_next_slot[i];
817  float fire_wait = Weapon_info[shipp->weapons.secondary_bank_weapons[i]].fire_wait;
818  float reload_time = (fire_wait == 0.0f) ? 1.0f : 1.0f / fire_wait;
819 
820  //ok so...we want to move up missles but only if there is a missle there to be moved up
821  //there is a missle behind next_point, and how ever many missles there are left after that
822 
823  if (points > missles_left) {
824  //there are more slots than missles left, so not all of the slots will have missles drawn on them
825  for (int k = next_point; k < next_point+missles_left; k ++) {
826  float &s_pct = shipp->secondary_point_reload_pct[i][k % points];
827  if (s_pct < 1.0)
828  s_pct += reload_time * frametime;
829  if (s_pct > 1.0)
830  s_pct = 1.0f;
831  }
832  } else {
833  //we don't have to worry about such things
834  for (int k = 0; k < points; k++) {
835  float &s_pct = shipp->secondary_point_reload_pct[i][k];
836  if (s_pct < 1.0)
837  s_pct += reload_time * frametime;
838  if (s_pct > 1.0)
839  s_pct = 1.0f;
840  }
841  }
842  }
843  }
844  }
845 
846  // if a weapon is flagged as dead, kill its engines just like a ship
847  if((objp->type == OBJ_WEAPON) && (Weapons[objp->instance].weapon_flags & WF_DEAD_IN_WATER)){
851  objp->phys_info.side_slip_time_const = 1.0f; // FIXME? originally indexed into Ship_info[], which was a bug...
852  }
853 
854  if (physics_paused) {
855  if (objp==Player_obj){
856  physics_sim(&objp->pos, &objp->orient, &objp->phys_info, frametime ); // simulate the physics
857  }
858  } else {
859  // Hack for dock mode.
860  // If docking with a ship, we don't obey the normal ship physics, we can slew about.
861  if (objp->type == OBJ_SHIP) {
862  ai_info *aip = &Ai_info[Ships[objp->instance].ai_index];
863 
864  // Note: This conditional for using PF_USE_VEL (instantaneous acceleration) is probably too loose.
865  // A ships awaiting support will fly towards the support ship with instantaneous acceleration.
866  // But we want to have ships in the process of docking have quick acceleration, or they overshoot their goals.
867  // Probably can not key off objnum_I_am_docked_or_docking_with, but then need to add some other condition. Live with it for now. -- MK, 2/19/98
868 
869  // Goober5000 - no need to key off objnum; other conditions get it just fine
870 
871  if (/* (objnum_I_am_docked_or_docking_with != -1) || */
872  ((aip->mode == AIM_DOCK) && ((aip->submode == AIS_DOCK_2) || (aip->submode == AIS_DOCK_3) || (aip->submode == AIS_UNDOCK_0))) ||
873  ((aip->mode == AIM_WARP_OUT) && (aip->submode >= AIS_WARP_3))) {
874  if (ship_get_subsystem_strength(&Ships[objp->instance], SUBSYSTEM_ENGINE) > 0.0f){
875  objp->phys_info.flags |= PF_USE_VEL;
876  } else {
877  objp->phys_info.flags &= ~PF_USE_VEL; // If engine blown, don't PF_USE_VEL, or ships stop immediately
878  }
879  } else {
880  objp->phys_info.flags &= ~PF_USE_VEL;
881  }
882  }
883 
884  // in multiplayer, if this object was just updatd (i.e. clients send their own positions),
885  // then reset the flag and don't move the object.
886  if ( MULTIPLAYER_MASTER && (objp->flags & OF_JUST_UPDATED) ) {
887  objp->flags &= ~OF_JUST_UPDATED;
888  goto obj_maybe_fire;
889  }
890 
891  physics_sim(&objp->pos, &objp->orient, &objp->phys_info, frametime ); // simulate the physics
892 
893  // if the object is the player object, do things that need to be done after the ship
894  // is moved (like firing weapons, etc). This routine will get called either single
895  // or multiplayer. We must find the player object to get to the control info field
896 obj_maybe_fire:
897  if ( (objp->flags & OF_PLAYER_SHIP) && (objp->type != OBJ_OBSERVER) && (objp == Player_obj)) {
898  player *pp;
899  if(Player != NULL){
900  pp = Player;
901  obj_player_fire_stuff( objp, pp->ci );
902  }
903  }
904 
905  // fire streaming weapons for ships in here - ALL PLAYERS, regardless of client, single player, server, whatever.
906  // do stream weapon firing for all ships themselves.
907  if(objp->type == OBJ_SHIP){
908  ship_fire_primary(objp, 1, 0);
909  has_fired = 1;
910  }
911  }
912  }
913 
914  if(has_fired == -1){
915  ship_stop_fire_primary(objp); //if it hasn't fired do the "has just stoped fireing" stuff
916  }
917 
918  //2D MODE
919  //THIS IS A FREAKIN' HACK
920  //Do not let ship change position on Y axis
922  {
923  angles old_angles, new_angles;
924  objp->pos.xyz.y = objp->last_pos.xyz.y;
925  vm_extract_angles_matrix(&old_angles, &objp->last_orient);
926  vm_extract_angles_matrix(&new_angles, &objp->orient);
927  new_angles.p = old_angles.p;
928  new_angles.b = old_angles.b;
929  vm_angles_2_matrix(&objp->orient, &new_angles);
930 
931  //Phys stuff hack
932  new_angles.h = old_angles.h;
933  vm_angles_2_matrix(&objp->phys_info.last_rotmat, &new_angles);
934  objp->phys_info.vel.xyz.y = 0.0f;
935  objp->phys_info.desired_rotvel.xyz.x = 0;
936  objp->phys_info.desired_rotvel.xyz.z = 0;
937  objp->phys_info.desired_vel.xyz.y = 0.0f;
938  }
939 }
940 
941 
942 #define IMPORTANT_FLAGS (OF_COLLIDES)
943 
944 #ifdef OBJECT_CHECK
945 
946 void obj_check_object( object *obj )
947 {
948  int objnum = OBJ_INDEX(obj);
949 
950  // PROGRAMMERS: If one of these Int3() gets hit, then someone
951  // is changing a value in the object structure that might cause
952  // collision detection to not work. See John for more info if
953  // you are hitting one of these.
954 
955  if ( CheckObjects[objnum].type != obj->type ) {
956  if ( (obj->type==OBJ_WAYPOINT) && (CheckObjects[objnum].type==OBJ_SHIP) ) {
957  // We know about ships changing into waypoints and that is
958  // ok.
959  CheckObjects[objnum].type = OBJ_WAYPOINT;
960  } else if ( (obj->type==OBJ_SHIP) && (CheckObjects[objnum].type==OBJ_GHOST) ) {
961  // We know about player changing into a ghost after dying and that is
962  // ok.
963  CheckObjects[objnum].type = OBJ_GHOST;
964  } else if ( (obj->type==OBJ_GHOST) && (CheckObjects[objnum].type==OBJ_SHIP) ) {
965  // We know about player changing into a ghost after dying and that is
966  // ok.
967  CheckObjects[objnum].type = OBJ_SHIP;
968  } else {
969  mprintf(( "Object type changed! Old: %i, Current: %i\n", CheckObjects[objnum].type, obj->type ));
970  Int3();
971  }
972  }
973  if ( CheckObjects[objnum].signature != obj->signature ) {
974  mprintf(( "Object signature changed!\n" ));
975  Int3();
976  }
977  if ( (CheckObjects[objnum].flags&IMPORTANT_FLAGS) != (obj->flags&IMPORTANT_FLAGS) ) {
978  mprintf(( "Object flags changed!\n" ));
979  Int3();
980  }
981  if ( CheckObjects[objnum].parent_sig != obj->parent_sig ) {
982  mprintf(( "Object parent sig changed!\n" ));
983  Int3();
984  }
985  if ( CheckObjects[objnum].parent_type != obj->parent_type ) {
986  mprintf(( "Object's parent type changed!\n" ));
987  Int3();
988  }
989 }
990 #endif
991 
1000 void obj_set_flags( object *obj, uint new_flags )
1001 {
1002  int objnum = OBJ_INDEX(obj);
1003 
1004  // turning collision detection off
1005  if ( (obj->flags & OF_COLLIDES) && (!(new_flags&OF_COLLIDES))) {
1006  // Remove all object pairs
1007  if ( Cmdline_old_collision_sys ) {
1008  obj_remove_pairs( obj );
1009  } else {
1010  obj_remove_collider(objnum);
1011  }
1012 
1013  // update object flags properly
1014  obj->flags = new_flags;
1015  obj->flags |= OF_NOT_IN_COLL;
1016 #ifdef OBJECT_CHECK
1017  CheckObjects[objnum].flags = new_flags;
1018  CheckObjects[objnum].flags |= OF_NOT_IN_COLL;
1019 #endif
1020  return;
1021  }
1022 
1023 
1024  // turning collision detection on
1025  if ( (!(obj->flags & OF_COLLIDES)) && (new_flags&OF_COLLIDES) ) {
1026 
1027  // observers can't collide or be hit, and they therefore have no hit or collide functions
1028  // So, don't allow this bit to be set
1029  if(obj->type == OBJ_OBSERVER){
1030  mprintf(("Illegal to set collision bit for OBJ_OBSERVER!!\n"));
1031  Int3();
1032  }
1033 
1034  obj->flags |= OF_COLLIDES;
1035 
1036  // Turn on collision detection
1037  if ( Cmdline_old_collision_sys ) {
1038  obj_add_pairs(objnum);
1039  } else {
1040  obj_add_collider(objnum);
1041  }
1042 
1043  obj->flags = new_flags;
1044  obj->flags &= ~(OF_NOT_IN_COLL);
1045 #ifdef OBJECT_CHECK
1046  CheckObjects[objnum].flags = new_flags;
1047  CheckObjects[objnum].flags &= ~(OF_NOT_IN_COLL);
1048 #endif
1049  return;
1050  }
1051 
1052  // for a multiplayer host -- use this debug code to help trap when non-player ships are getting
1053  // marked as OF_COULD_BE_PLAYER
1054  // this code is pretty much debug code and shouldn't be relied on to always do the right thing
1055  // for flags other than
1056  if ( MULTIPLAYER_MASTER && !(obj->flags & OF_COULD_BE_PLAYER) && (new_flags & OF_COULD_BE_PLAYER) ) {
1057  ship *shipp;
1058  int team, slot;
1059 
1060  // this flag sometimes gets set for observers.
1061  if ( obj->type == OBJ_OBSERVER ) {
1062  return;
1063  }
1064 
1065  // sanity checks
1066  if ( (obj->type != OBJ_SHIP) || (obj->instance < 0) ) {
1067  return; // return because we really don't want to set the flag
1068  }
1069 
1070  // see if this ship is really a player ship (or should be)
1071  shipp = &Ships[obj->instance];
1072  extern void multi_ts_get_team_and_slot(char *, int *, int *, bool);
1073  multi_ts_get_team_and_slot(shipp->ship_name,&team,&slot, false);
1074  if ( (shipp->wingnum == -1) || (team == -1) || (slot==-1) ) {
1075  Int3();
1076  return;
1077  }
1078 
1079  // set the flag
1080  obj->flags = new_flags;
1081 #ifdef OBJECT_CHECK
1082  CheckObjects[objnum].flags = new_flags;
1083 #endif
1084 
1085  return;
1086  }
1087 
1088  // Check for unhandled flag changing
1089  if ( (new_flags&IMPORTANT_FLAGS) != (obj->flags&IMPORTANT_FLAGS) ) {
1090  mprintf(( "Unhandled flag changing in obj_set_flags!!\n" ));
1091  mprintf(( "Add code to support it, see John for questions!!\n" ));
1092  Int3();
1093  } else {
1094  // Since it wasn't an important flag, just bash it.
1095  obj->flags = new_flags;
1096  #ifdef OBJECT_CHECK
1097  CheckObjects[objnum].flags = new_flags;
1098  #endif
1099  }
1100 }
1101 
1102 
1103 void obj_move_all_pre(object *objp, float frametime)
1104 {
1105  switch( objp->type ) {
1106  case OBJ_WEAPON:
1107  if (!physics_paused){
1108  weapon_process_pre( objp, frametime );
1109  }
1110  break;
1111  case OBJ_SHIP:
1112  if (!physics_paused || (objp==Player_obj )){
1113  ship_process_pre( objp, frametime );
1114  }
1115  break;
1116  case OBJ_FIREBALL:
1117  // all fireballs are moved via fireball_process_post()
1118  break;
1119  case OBJ_SHOCKWAVE:
1120  // all shockwaves are moved via shockwave_move_all()
1121  break;
1122  case OBJ_DEBRIS:
1123  // all debris are moved via debris_process_post()
1124  break;
1125  case OBJ_ASTEROID:
1126  if (!physics_paused){
1127  asteroid_process_pre(objp);
1128  }
1129  break;
1130 /* case OBJ_CMEASURE:
1131  if (!physics_paused){
1132  cmeasure_process_pre(objp, frametime);
1133  }
1134  break;*/
1135  case OBJ_WAYPOINT:
1136  break; // waypoints don't move..
1137  case OBJ_GHOST:
1138  break;
1139  case OBJ_OBSERVER:
1140  case OBJ_JUMP_NODE:
1141  break;
1142  case OBJ_BEAM:
1143  break;
1144  case OBJ_NONE:
1145  Int3();
1146  break;
1147  default:
1148  Error( LOCATION, "Unhandled object type %d in obj_move_one\n", objp->type );
1149  }
1150 }
1151 
1152 // Used to tell if a particular group of lasers has cast light yet.
1154 
1159 {
1160  memset( Obj_weapon_group_id_used, 0, sizeof(Obj_weapon_group_id_used) );
1161 }
1162 
1163 int Arc_light = 1; // If set, electrical arcs on debris cast light
1164 DCF_BOOL(arc_light, Arc_light)
1165 extern fireball Fireballs[];
1166 
1167 void obj_move_all_post(object *objp, float frametime)
1168 {
1169  switch (objp->type)
1170  {
1171  case OBJ_WEAPON:
1172  {
1173  if ( !physics_paused )
1174  weapon_process_post( objp, frametime );
1175 
1176  // Cast light
1177  if ( Detail.lighting > 2 ) {
1178  // Weapons cast light
1179 
1180  int group_id = Weapons[objp->instance].group_id;
1181  int cast_light = 1;
1182 
1183  if ( (group_id >= 0) && (Obj_weapon_group_id_used[group_id]==0) ) {
1184  // Mark this group as done
1185  Obj_weapon_group_id_used[group_id]++;
1186  } else {
1187  // This group has already done its light casting
1188  cast_light = 0;
1189  }
1190 
1191  if ( cast_light ) {
1192  weapon_info * wi = &Weapon_info[Weapons[objp->instance].weapon_info_index];
1193 
1194  if ( wi->render_type == WRT_LASER ) {
1195  color c;
1196  float r,g,b;
1197 
1198  // get the laser color
1199  weapon_get_laser_color(&c, objp);
1200 
1201  r = i2fl(c.red)/255.0f;
1202  g = i2fl(c.green)/255.0f;
1203  b = i2fl(c.blue)/255.0f;
1204 
1205  //light_add_point( &objp->pos, 10.0f, 20.0f, 1.0f, r, g, b, objp->parent );
1206  light_add_point( &objp->pos, 10.0f, is_minimum_GLSL_version()?100.0f:20.0f, 1.0f, r, g, b, objp->parent );
1207  } else {
1208  light_add_point( &objp->pos, 10.0f, 20.0f, 1.0f, 1.0f, 1.0f, 1.0f, objp->parent );
1209  }
1210  }
1211  }
1212 
1213  break;
1214  }
1215 
1216  case OBJ_SHIP:
1217  {
1218  if ( !physics_paused || (objp==Player_obj) ) {
1219  ship_process_post( objp, frametime );
1221  }
1222 
1223  // Make any electrical arcs on ships cast light
1224  if (Arc_light) {
1225  if ( (Detail.lighting > 2) && (objp != Viewer_obj) ) {
1226  int i;
1227  ship *shipp;
1228  shipp = &Ships[objp->instance];
1229 
1230  for (i=0; i<MAX_SHIP_ARCS; i++ ) {
1231  if ( timestamp_valid( shipp->arc_timestamp[i] ) ) {
1232  // Move arc endpoints into world coordinates
1233  vec3d tmp1, tmp2;
1234  vm_vec_unrotate(&tmp1,&shipp->arc_pts[i][0],&objp->orient);
1235  vm_vec_add2(&tmp1,&objp->pos);
1236 
1237  vm_vec_unrotate(&tmp2,&shipp->arc_pts[i][1],&objp->orient);
1238  vm_vec_add2(&tmp2,&objp->pos);
1239 
1240  light_add_point( &tmp1, 10.0f, 20.0f, frand(), 1.0f, 1.0f, 1.0f, -1 );
1241  light_add_point( &tmp2, 10.0f, 20.0f, frand(), 1.0f, 1.0f, 1.0f, -1 );
1242  }
1243  }
1244  }
1245  }
1246 
1247  //Check for changing team colors
1248  ship* shipp = &Ships[objp->instance];
1249  if (Ship_info[shipp->ship_info_index].uses_team_colors && stricmp(shipp->secondary_team_name.c_str(), "none")) {
1250  if (f2fl(Missiontime) * 1000 > f2fl(shipp->team_change_timestamp) * 1000 + shipp->team_change_time) {
1251  shipp->team_name = shipp->secondary_team_name;
1252  shipp->team_change_timestamp = 0;
1253  shipp->team_change_time = 0;
1254  shipp->secondary_team_name = "none";
1255  }
1256  }
1257 
1258  break;
1259  }
1260 
1261  case OBJ_FIREBALL:
1262  {
1263  if ( !physics_paused )
1264  fireball_process_post(objp,frametime);
1265 
1266  if (Detail.lighting > 3) {
1267  float r = 0.0f, g = 0.0f, b = 0.0f;
1268 
1269  fireball_get_color(Fireballs[objp->instance].fireball_info_index, &r, &g, &b);
1270 
1271  // we don't cast black light, so just bail in that case
1272  if ( (r == 0.0f) && (g == 0.0f) && (b == 0.0f) )
1273  break;
1274 
1275  // Make explosions cast light
1276  float p = fireball_lifeleft_percent(objp);
1277  if (p > 0.0f) {
1278  if (p > 0.5f)
1279  p = 1.0f - p;
1280 
1281  p *= 2.0f;
1282  float rad = p * (1.0f + frand() * 0.05f) * objp->radius;
1283 
1284  float intensity = 1.0f;
1285  if(fireball_is_warp(objp))
1286  {
1287  intensity = fireball_wormhole_intensity(objp); // Valathil: Get wormhole radius for lighting
1288  rad = objp->radius;
1289  }
1290  // P goes from 0 to 1 to 0 over the life of the explosion
1291  // Only do this if rad is > 0.0000001f
1292  if (rad > 0.0001f)
1293  light_add_point( &objp->pos, rad * 2.0f, rad * 5.0f, intensity, r, g, b, -1 );
1294  }
1295  }
1296 
1297  break;
1298  }
1299 
1300  case OBJ_SHOCKWAVE:
1301  // all shockwaves are moved via shockwave_move_all()
1302  break;
1303 
1304  case OBJ_DEBRIS:
1305  {
1306  if ( !physics_paused )
1307  debris_process_post(objp, frametime);
1308 
1309  // Make any electrical arcs on debris cast light
1310  if (Arc_light) {
1311  if ( Detail.lighting > 2 ) {
1312  int i;
1313  debris *db;
1314  db = &Debris[objp->instance];
1315 
1316  if (db->arc_frequency > 0) {
1317  for (i=0; i<MAX_DEBRIS_ARCS; i++ ) {
1318  if ( timestamp_valid( db->arc_timestamp[i] ) ) {
1319  // Move arc endpoints into world coordinates
1320  vec3d tmp1, tmp2;
1321  vm_vec_unrotate(&tmp1,&db->arc_pts[i][0],&objp->orient);
1322  vm_vec_add2(&tmp1,&objp->pos);
1323 
1324  vm_vec_unrotate(&tmp2,&db->arc_pts[i][1],&objp->orient);
1325  vm_vec_add2(&tmp2,&objp->pos);
1326 
1327  light_add_point( &tmp1, 10.0f, 20.0f, frand(), 1.0f, 1.0f, 1.0f, -1 );
1328  light_add_point( &tmp2, 10.0f, 20.0f, frand(), 1.0f, 1.0f, 1.0f, -1 );
1329  }
1330  }
1331  }
1332  }
1333  }
1334 
1335  break;
1336  }
1337 
1338  case OBJ_ASTEROID:
1339  {
1340  if ( !physics_paused )
1341  asteroid_process_post(objp);
1342 
1343  break;
1344  }
1345 
1346  case OBJ_WAYPOINT:
1347  break; // waypoints don't move..
1348 
1349  case OBJ_GHOST:
1350  break;
1351 
1352  case OBJ_OBSERVER:
1353  void observer_process_post(object *objp);
1354  observer_process_post(objp);
1355  break;
1356 
1357  case OBJ_JUMP_NODE:
1358  radar_plot_object(objp);
1359  break;
1360 
1361  case OBJ_BEAM:
1362  break;
1363 
1364  case OBJ_NONE:
1365  Int3();
1366  break;
1367 
1368  default:
1369  Error( LOCATION, "Unhandled object type %d in obj_move_one\n", objp->type );
1370  }
1371 }
1372 
1373 
1375 
1376 DCF_BOOL( collisions, Collisions_enabled )
1377 
1378 MONITOR( NumObjects )
1379 
1383 void obj_move_all(float frametime)
1384 {
1385  object *objp;
1386 
1387  // Goober5000 - HACK HACK HACK
1388  // this function also resets the OF_DOCKED_ALREADY_HANDLED flag, to save trips
1389  // through the used object list
1391 
1393 
1394  // Clear the table that tells which groups of weapons have cast light so far.
1397  }
1398 
1399  MONITOR_INC( NumObjects, Num_objects );
1400 
1401  for (objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp)) {
1402  // skip objects which should be dead
1403  if (objp->flags & OF_SHOULD_BE_DEAD) {
1404  continue;
1405  }
1406 
1407  // if this is an observer object, skip it
1408  if (objp->type == OBJ_OBSERVER) {
1409  continue;
1410  }
1411 
1412  vec3d cur_pos = objp->pos; // Save the current position
1413 
1414 #ifdef OBJECT_CHECK
1415  obj_check_object( objp );
1416 #endif
1417 
1418  // pre-move
1419  PROFILE("Pre Move", obj_move_all_pre(objp, frametime));
1420 
1421  // store last pos and orient
1422  objp->last_pos = cur_pos;
1423  objp->last_orient = objp->orient;
1424 
1425  // Goober5000 - skip objects which don't move, but only until they're destroyed
1426  if (!(objp->flags & OF_IMMOBILE && objp->hull_strength > 0.0f)) {
1427  // if this is an object which should be interpolated in multiplayer, do so
1428  if (multi_oo_is_interp_object(objp)) {
1429  multi_oo_interp(objp);
1430  } else {
1431  // physics
1432  PROFILE("Physics", obj_move_call_physics(objp, frametime));
1433  }
1434  }
1435 
1436  // move post
1437  PROFILE("Post Move", obj_move_all_post(objp, frametime));
1438 
1439  // Equipment script processing
1440  if (objp->type == OBJ_SHIP) {
1441  ship* shipp = &Ships[objp->instance];
1442  object* target;
1443 
1444  if (Ai_info[shipp->ai_index].target_objnum != -1)
1445  target = &Objects[Ai_info[shipp->ai_index].target_objnum];
1446  else
1447  target = NULL;
1448  if (objp == Player_obj && Player_ai->target_objnum != -1)
1449  target = &Objects[Player_ai->target_objnum];
1450 
1451  Script_system.SetHookObjects(2, "User", objp, "Target", target);
1453  }
1454  Script_system.RemHookVars(2, "User", "Target");
1455  }
1456 
1457  // Now that we've moved all the objects, move all the models that use intrinsic rotations. We do that here because we already handled the
1458  // ship models in obj_move_all_post, and this is more or less conceptually close enough to move the rest. (Originally all models
1459  // were intrinsic-rotated here, but for sequencing reasons, intrinsic ship rotations must happen along with regular ship rotations.)
1461 
1462  // After all objects have been moved, move all docked objects.
1463  objp = GET_FIRST(&obj_used_list);
1464  while( objp !=END_OF_LIST(&obj_used_list) ) {
1466 
1467  //Valathil - Move the screen rotation calculation for billboards here to get the updated orientation matrices caused by docking interpolation
1468  vec3d tangles;
1469 
1470  tangles.xyz.x = -objp->phys_info.rotvel.xyz.x*frametime;
1471  tangles.xyz.y = -objp->phys_info.rotvel.xyz.y*frametime;
1472  tangles.xyz.z = objp->phys_info.rotvel.xyz.z*frametime;
1473 
1474  // If this is the viewer_object, keep track of the
1475  // changes in banking so that rotated bitmaps look correct.
1476  // This is used by the g3_draw_rotated_bitmap function.
1478  if ( &objp->phys_info == Viewer_physics_info ) {
1479  vec3d tangles_r;
1480  vm_vec_unrotate(&tangles_r, &tangles, &Eye_matrix);
1481  vm_vec_rotate(&tangles, &tangles_r, &objp->orient);
1482 
1484  Physics_viewer_bank -= tangles.xyz.z*0.65f;
1485  } else {
1486  Physics_viewer_bank -= tangles.xyz.z;
1487  }
1488 
1489  if ( Physics_viewer_bank < 0.0f ){
1490  Physics_viewer_bank += 2.0f * PI;
1491  }
1492 
1493  if ( Physics_viewer_bank > 2.0f * PI ){
1494  Physics_viewer_bank -= 2.0f * PI;
1495  }
1496  }
1497 
1498  // unflag all objects as being updates
1499  objp->flags &= ~OF_JUST_UPDATED;
1500 
1501  objp = GET_NEXT(objp);
1502  }
1503 
1504  find_homing_object_cmeasures(); // If any cmeasures fired, maybe steer away homing missiles
1505 
1506  // do pre-collision stuff for beam weapons
1508 
1509  profile_begin("Collision Detection");
1510  if ( Collisions_enabled ) {
1511  if ( Cmdline_old_collision_sys ) {
1513  } else {
1515  }
1516  }
1517  profile_end("Collision Detection");
1518 
1520 
1521  // do post-collision stuff for beam weapons
1523 
1524  // update artillery locking info now
1526 
1527 // mprintf(("moved all objects\n"));
1528 }
1529 
1530 
1531 MONITOR( NumObjectsRend )
1532 
1533 
1536 extern int Cmdline_dis_weapons;
1538 {
1540 
1541  if ( obj->flags & OF_SHOULD_BE_DEAD ) return;
1542 
1543  MONITOR_INC( NumObjectsRend, 1 );
1544 
1545  //WMC - By definition, override statements are executed before the actual statement
1546  Script_system.SetHookObject("Self", obj);
1548  {
1549  switch( obj->type ) {
1550  case OBJ_NONE:
1551  #ifndef NDEBUG
1552  mprintf(( "ERROR!!!! Bogus obj " PTRDIFF_T_ARG " is rendering!\n", obj-Objects ));
1553  Int3();
1554  #endif
1555  break;
1556  case OBJ_WEAPON:
1557  if(Cmdline_dis_weapons) return;
1559  break;
1560  case OBJ_SHIP:
1562  break;
1563  case OBJ_FIREBALL:
1565  break;
1566  case OBJ_SHOCKWAVE:
1568  break;
1569  case OBJ_DEBRIS:
1571  break;
1572  case OBJ_ASTEROID:
1574  break;
1575  /* case OBJ_CMEASURE:
1576  cmeasure_render(obj);
1577  break;*/
1578  case OBJ_JUMP_NODE:
1579  for (jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp) {
1580  if(jnp->GetSCPObject() != obj)
1581  continue;
1582  jnp->RenderDEPRECATED(&obj->pos, &Eye_position);
1583  }
1584  break;
1585  case OBJ_WAYPOINT:
1586  if (Show_waypoints) {
1587  gr_set_color( 128, 128, 128 );
1588  g3_draw_sphere_ez( &obj->pos, 5.0f );
1589  }
1590  break;
1591  case OBJ_GHOST:
1592  break;
1593  case OBJ_BEAM:
1594  break;
1595  default:
1596  Error( LOCATION, "Unhandled obj type %d in obj_render", obj->type );
1597  }
1598  }
1599 
1600  Script_system.RunCondition(CHA_OBJECTRENDER, '\0', NULL, obj);
1601  Script_system.RemHookVar("Self");
1602 }
1603 
1604 void obj_render(object *obj)
1605 {
1606  draw_list render_list;
1607 
1608  obj_queue_render(obj, &render_list);
1609 
1610  render_list.init_render();
1611  render_list.render_all();
1612 
1613  gr_zbias(0);
1614  gr_set_cull(0);
1617 
1618  gr_clear_states();
1619  gr_set_buffer(-1);
1620 
1622  gr_set_lighting(false, false);
1623 }
1624 
1625 void obj_queue_render(object* obj, draw_list* scene)
1626 {
1627  if ( obj->flags & OF_SHOULD_BE_DEAD ) return;
1628 
1629  // need to figure out what to do with this hook.
1630  // maybe save an array of these and run the script conditions after we finish drawing
1631  Script_system.SetHookObject("Self", obj);
1632 
1634  Script_system.RunCondition(CHA_OBJECTRENDER, '\0', NULL, obj);
1635  Script_system.RemHookVar("Self");
1636  return;
1637  }
1638 
1639  switch ( obj->type ) {
1640  case OBJ_NONE:
1641 #ifndef NDEBUG
1642  mprintf(( "ERROR!!!! Bogus obj " PTRDIFF_T_ARG " is rendering!\n", obj-Objects ));
1643  Int3();
1644 #endif
1645  break;
1646  case OBJ_WEAPON:
1647  if ( Cmdline_dis_weapons ) return;
1648  weapon_render(obj, scene);
1649  break;
1650  case OBJ_SHIP:
1651  ship_render(obj, scene);
1652  break;
1653  case OBJ_FIREBALL:
1654  fireball_render(obj, scene);
1655  break;
1656  case OBJ_SHOCKWAVE:
1657  shockwave_render(obj, scene);
1658  break;
1659  case OBJ_DEBRIS:
1660  debris_render(obj, scene);
1661  break;
1662  case OBJ_ASTEROID:
1663  asteroid_render(obj, scene);
1664  break;
1665  case OBJ_JUMP_NODE:
1666  for ( SCP_list<CJumpNode>::iterator jnp = Jump_nodes.begin(); jnp != Jump_nodes.end(); ++jnp ) {
1667  if ( jnp->GetSCPObject() != obj ) {
1668  continue;
1669  }
1670 
1671  jnp->Render(scene, &obj->pos, &Eye_position);
1672  }
1673  break;
1674  case OBJ_WAYPOINT:
1675  // if (Show_waypoints) {
1676  // gr_set_color( 128, 128, 128 );
1677  // g3_draw_sphere_ez( &obj->pos, 5.0f );
1678  // }
1679  break;
1680  case OBJ_GHOST:
1681  break;
1682  case OBJ_BEAM:
1683  break;
1684  default:
1685  Error( LOCATION, "Unhandled obj type %d in obj_render", obj->type );
1686  }
1687 }
1688 
1690 {
1691  object *objp;
1692 
1693  for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
1694  if (objp->type == OBJ_SHIP)
1695  physics_ship_init(objp);
1696  }
1697 
1698 }
1699 
1704 {
1705  object *objp;
1706 
1707  // duh
1709 
1710  // client side processing of warping in effect stages
1712 
1713  // client side movement of an observer
1714  if((Net_player->flags & NETINFO_FLAG_OBSERVER) || (Player_obj->type == OBJ_OBSERVER)){
1716  }
1717 
1718  // run everything except ships through physics (and ourselves of course)
1719  obj_merge_created_list(); // must merge any objects created by the host!
1720 
1721  objp = GET_FIRST(&obj_used_list);
1722  for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
1723  if((objp != Player_obj) && (objp->type == OBJ_SHIP)){
1724  continue;
1725  }
1726 
1727  // for all non-dead object which are _not_ ships
1728  if ( !(objp->flags&OF_SHOULD_BE_DEAD) ) {
1729  // pre-move step
1731 
1732  // store position and orientation
1733  objp->last_pos = objp->pos;
1734  objp->last_orient = objp->orient;
1735 
1736  // call physics
1738 
1739  // post-move step
1741  }
1742  }
1743 }
1744 
1749 {
1750  object *objp;
1751 
1752  // After all objects have been moved, move all docked objects.
1753  objp = GET_FIRST(&obj_used_list);
1754  while( objp !=END_OF_LIST(&obj_used_list) ) {
1755  if ( objp != Player_obj ) {
1757  }
1758  objp = GET_NEXT(objp);
1759  }
1760 
1761  // check collisions
1762  if ( Cmdline_old_collision_sys ) {
1764  } else {
1766  }
1767 
1768  // do post-collision stuff for beam weapons
1770 }
1771 
1773 {
1774  object *objp;
1775  float ft;
1776 
1777  // if i'm not in multiplayer, or not an observer, bail
1778  if(!(Game_mode & GM_MULTIPLAYER) || (Net_player == NULL) || !(Net_player->flags & NETINFO_FLAG_OBSERVER) || (Player_obj->type != OBJ_OBSERVER)){
1779  return;
1780  }
1781 
1782  objp = Player_obj;
1783 
1784  objp->last_pos = objp->pos;
1785  objp->last_orient = objp->orient; // save the orientation -- useful in multiplayer.
1786 
1787  ft = flFrametime;
1788  obj_move_call_physics( objp, ft );
1789  obj_move_all_post(objp, frame_time);
1790  objp->flags &= ~OF_JUST_UPDATED;
1791 }
1792 
1797 {
1798  int count;
1799  object *objp;
1800 
1801  vm_vec_zero( pos );
1802 
1803  // average up all ship positions
1804  count = 0;
1805  for ( objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
1806  if ( objp->type != OBJ_SHIP )
1807  continue;
1808  vm_vec_add2( pos, &objp->pos );
1809  count++;
1810  }
1811 
1812  if ( count )
1813  vm_vec_scale( pos, 1.0f/(float)count );
1814 }
1815 
1816 
1817 int obj_get_SIF(object *objp)
1818 {
1819  if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START))
1820  return Ship_info[Ships[objp->instance].ship_info_index].flags;
1821 
1822  Int3();
1823  return 0;
1824 }
1825 
1827 {
1828  if ((Objects[obj].type == OBJ_SHIP) || (Objects[obj].type == OBJ_START))
1829  return Ship_info[Ships[Objects[obj].instance].ship_info_index].flags;
1830 
1831  Int3();
1832  return 0;
1833 }
1834 
1843 int obj_team(object *objp)
1844 {
1845  Assert( objp != NULL );
1846  int team = -1;
1847 
1848  switch ( objp->type ) {
1849  case OBJ_SHIP:
1850  Assert( objp->instance >= 0 && objp->instance < MAX_SHIPS );
1851  team = Ships[objp->instance].team;
1852  break;
1853 
1854  case OBJ_DEBRIS:
1855  team = debris_get_team(objp);
1856  Assertion(team != -1, "Obj_team called for a debris object with no team.");
1857  break;
1858 
1859 /* case OBJ_CMEASURE:
1860  Assert( objp->instance >= 0 && objp->instance < MAX_CMEASURES);
1861  team = Cmeasures[objp->instance].team;
1862  break;
1863 */
1864  case OBJ_WEAPON:
1865  Assert( objp->instance >= 0 && objp->instance < MAX_WEAPONS );
1866  team = Weapons[objp->instance].team;
1867  break;
1868 
1869  case OBJ_JUMP_NODE:
1870  team = Player_ship->team;
1871  break;
1872 
1873  case OBJ_FIREBALL:
1874  case OBJ_WAYPOINT:
1875  case OBJ_START:
1876  case OBJ_NONE:
1877  case OBJ_GHOST:
1878  case OBJ_SHOCKWAVE:
1879  case OBJ_BEAM:
1880  team = -1;
1881  break;
1882 
1883  case OBJ_ASTEROID:
1884  team = Iff_traitor;
1885  break;
1886 
1887  default:
1888  Int3(); // can't happen
1889  break;
1890  } // end switch
1891 
1892  Assertion(team != -1, "Obj_team called for a object of type %s with no team.", Object_type_names[objp->type]);
1893  return team;
1894 }
1895 
1901 void obj_add_pairs(int objnum)
1902 {
1903  object *objp;
1904 
1905  Assert(objnum != -1);
1906  objp = &Objects[objnum];
1907 
1908  // don't do anything if its already in the object pair list
1909  if(!(objp->flags & OF_NOT_IN_COLL)){
1910  return;
1911  }
1912 
1913 #ifdef OBJECT_CHECK
1914  CheckObjects[objnum].type = objp->type;
1915  CheckObjects[objnum].signature = objp->signature;
1916  CheckObjects[objnum].flags = objp->flags & ~(OF_NOT_IN_COLL);
1917  CheckObjects[objnum].parent_sig = objp->parent_sig;
1918  CheckObjects[objnum].parent_type = objp->parent_type;
1919 #endif
1920 
1921  // Find all the objects that can collide with this and add
1922  // it to the collision pair list.
1923  object * A;
1924  for ( A = GET_FIRST(&obj_used_list); A !=END_OF_LIST(&obj_used_list); A = GET_NEXT(A) ) {
1925  obj_add_pair( objp, A );
1926  }
1927 
1928  objp->flags &= ~OF_NOT_IN_COLL;
1929 }
1930 
1935 extern int Num_pairs;
1936 extern obj_pair pair_used_list;
1937 extern obj_pair pair_free_list;
1938 void obj_remove_pairs( object * a )
1939 {
1940  obj_pair *parent, *tmp;
1941 
1942  a->flags |= OF_NOT_IN_COLL;
1943 #ifdef OBJECT_CHECK
1944  CheckObjects[OBJ_INDEX(a)].flags |= OF_NOT_IN_COLL;
1945 #endif
1946 
1947  if ( a->num_pairs < 1 ) {
1948  return;
1949  }
1950 
1951  Num_pairs-=a->num_pairs;
1952 
1953  parent = &pair_used_list;
1954  tmp = parent->next;
1955 
1956  while( tmp != NULL ) {
1957  if ( (tmp->a==a) || (tmp->b==a) ) {
1958  // Hmmm... a potenial compiler optimization problem here... either tmp->a or tmp->b
1959  // is equal to 'a' and we modify 'num_pairs' in one of these and then use the value
1960  // stored in 'a' later one... will the optimizer find that? Hmmm...
1961  tmp->a->num_pairs--;
1962  Assert( tmp->a->num_pairs > -1 );
1963  tmp->b->num_pairs--;
1964  Assert( tmp->b->num_pairs > -1 );
1965  parent->next = tmp->next;
1966  tmp->a = tmp->b = NULL;
1967  tmp->next = pair_free_list.next;
1968  pair_free_list.next = tmp;
1969  tmp = parent->next;
1970 
1971  if ( a->num_pairs==0 ) {
1972  break;
1973  }
1974 
1975  } else {
1976  parent = tmp;
1977  tmp = tmp->next;
1978  }
1979  }
1980 }
1981 
1986 {
1987  // clear checkobjects
1988 #ifndef NDEBUG
1989  memset(CheckObjects, 0, sizeof(checkobject) * MAX_OBJECTS);
1990 #endif
1991 
1992  // clear object pairs
1993  if ( Cmdline_old_collision_sys ) {
1994  obj_reset_pairs();
1995  } else {
1997  }
1998 
1999  // now add every object back into the object collision pairs
2000  object *moveup;
2001  moveup = GET_FIRST(&obj_used_list);
2002  while(moveup != END_OF_LIST(&obj_used_list)){
2003  // he's not in the collision list
2004  moveup->flags |= OF_NOT_IN_COLL;
2005 
2006  // recalc pairs for this guy
2007  if ( Cmdline_old_collision_sys ) {
2008  obj_add_pairs(OBJ_INDEX(moveup));
2009  } else {
2010  obj_add_collider(OBJ_INDEX(moveup));
2011  }
2012 
2013  // next
2014  moveup = GET_NEXT(moveup);
2015  }
2016 }
2017 
2018 // Goober5000
2020 {
2021  return (objp->dock_list != NULL);
2022 }
2023 
2024 // Goober5000
2026 {
2027  return (objp->dead_dock_list != NULL);
2028 }
2029 
2036 void object_set_gliding(object *objp, bool enable, bool force)
2037 {
2038  Assert(objp != NULL);
2039 
2040  if(enable) {
2041  if (!force) {
2042  objp->phys_info.flags |= PF_GLIDING;
2043  } else {
2044  objp->phys_info.flags |= PF_FORCE_GLIDE;
2045  }
2046  } else {
2047  if (!force) {
2048  objp->phys_info.flags &= ~PF_GLIDING;
2049  } else {
2050  objp->phys_info.flags &= ~PF_FORCE_GLIDE;
2051  }
2052  vm_vec_rotate(&objp->phys_info.prev_ramp_vel, &objp->phys_info.vel, &objp->orient); //Backslash
2053  }
2054 }
2055 
2060 {
2061  Assert(objp != NULL);
2062 
2063  return ( ((objp->phys_info.flags & PF_GLIDING) != 0) || ((objp->phys_info.flags & PF_FORCE_GLIDE) != 0));
2064 }
2065 
2067 {
2068  return (objp->phys_info.flags & PF_FORCE_GLIDE) != 0;
2069 }
2070 
2075 {
2076  Assert(sig > 0);
2077 
2078  object *objp = GET_FIRST(&obj_used_list);
2079  while( objp !=END_OF_LIST(&obj_used_list) )
2080  {
2081  if(objp->signature == sig)
2082  return OBJ_INDEX(objp);
2083 
2084  objp = GET_NEXT(objp);
2085  }
2086  return -1;
2087 }
2088 
2093 {
2094  switch(objp->type)
2095  {
2096  case OBJ_ASTEROID:
2097  {
2098  asteroid *asp = &Asteroids[objp->instance];
2099  return Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype];
2100  }
2101  case OBJ_DEBRIS:
2102  {
2103  debris *debrisp = &Debris[objp->instance];
2104  return debrisp->model_num;
2105  }
2106  case OBJ_SHIP:
2107  {
2108  ship *shipp = &Ships[objp->instance];
2109  return Ship_info[shipp->ship_info_index].model_num;
2110  }
2111  case OBJ_WEAPON:
2112  {
2113  weapon *wp = &Weapons[objp->instance];
2115  }
2116  default:
2117  break;
2118  }
2119 
2120  return -1;
2121 }
void beam_move_all_post()
Definition: beam.cpp:986
int fire_countermeasure_count
Definition: physics.h:112
#define MAX_OBJECT_TYPES
Definition: object.h:49
#define OF_INVULNERABLE
Definition: object.h:107
void radar_plot_object(object *objp)
Definition: radarsetup.cpp:146
#define gr_zbuffer_set
Definition: 2d.h:817
int arc_frequency
Definition: debris.h:46
void dock_free_dock_list(object *objp)
Definition: objectdock.cpp:725
#define MULTIPLAYER_CLIENT
Definition: multi.h:132
float sim_hull_strength
Definition: object.h:161
void obj_set_flags(object *obj, uint new_flags)
Definition: object.cpp:1000
int i
Definition: multi_pxo.cpp:466
fix Missiontime
Definition: systemvars.cpp:19
float get_max_shield_quad(object *objp)
Definition: object.cpp:260
float p
Definition: pstypes.h:111
fix team_change_timestamp
Definition: ship.h:814
void call_doa(object *child, object *parent)
Definition: aicode.cpp:12072
weapon Weapons[MAX_WEAPONS]
Definition: weapons.cpp:78
#define OF_NOT_IN_COLL
Definition: object.h:114
int group_id
Definition: weapon.h:184
ai_info * Player_ai
Definition: ai.cpp:24
SCP_string secondary_team_name
Definition: ship.h:813
int team
Definition: ship.h:606
int afterburner_start
Definition: physics.h:116
bool object_glide_forced(object *objp)
Definition: object.cpp:2066
control_info ci
Definition: player.h:126
#define AIS_DOCK_4
Definition: ai.h:273
#define OBJ_FIREBALL
Definition: object.h:34
void weapon_process_pre(object *obj, float frame_time)
Definition: weapons.cpp:4667
int Game_mode
Definition: systemvars.cpp:24
vec3d rotvel
Definition: physics.h:78
int debris_get_team(object *objp)
Definition: debris.cpp:1065
#define OF_LASER_PROTECTED
Definition: object.h:120
void obj_client_post_interpolate()
Definition: object.cpp:1748
polymodel * model_get(int model_num)
Definition: modelread.cpp:3134
int obj_team(object *objp)
Definition: object.cpp:1843
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
float shield_get_strength(object *objp)
void obj_render(object *obj)
Definition: object.cpp:1604
ship_weapon weapons
Definition: ship.h:658
void RemHookVar(char *name)
Definition: scripting.cpp:749
net_player * Net_player
Definition: multi.cpp:94
float fire_wait
Definition: weapon.h:359
char parent_type
Definition: object.h:149
void obj_move_all_pre(object *objp, float frametime)
Definition: object.cpp:1103
float flFrametime
Definition: fredstubs.cpp:22
vec3d desired_vel
Definition: physics.h:70
Definition: weapon.h:163
asteroid Asteroids[MAX_ASTEROIDS]
Definition: asteroid.cpp:63
physics_info phys_info
Definition: object.h:157
int Fred_running
Definition: fred.cpp:44
matrix * vm_angles_2_matrix(matrix *m, const angles *a)
Definition: vecmat.cpp:752
void debris_render_DEPRECATED(object *obj)
Definition: debris.cpp:150
void obj_reset_all_collisions()
Definition: object.cpp:1985
#define MAX_SHIPS
Definition: globals.h:37
GLsizei const GLfloat * points
Definition: Glext.h:7583
int fire_secondary_count
Definition: physics.h:111
char * Object_type_names[MAX_OBJECT_TYPES]
Definition: object.cpp:76
void object_set_gliding(object *objp, bool enable, bool force)
Definition: object.cpp:2036
void obj_init_all_ships_physics()
Definition: object.cpp:1689
float ship_max_shield_strength
Definition: ship.h:596
void obj_init()
Definition: object.cpp:327
#define PF_GLIDING
Definition: physics.h:32
Assert(pm!=NULL)
int target_objnum
Definition: ai.h:339
int submode
Definition: ai.h:394
void multi_ts_get_team_and_slot(char *ship_name, int *team_index, int *slot_index, bool mantis2757switch)
int fire_primary_count
Definition: physics.h:110
object obj_free_list
Definition: object.cpp:52
Definition: pstypes.h:88
void light_add_point(const vec3d *pos, float r1, float r2, float intensity, float r, float g, float b, int light_ignore_objnum, float spec_r, float spec_g, float spec_b, bool specular)
Definition: lighting.cpp:253
#define mprintf(args)
Definition: pstypes.h:238
void shockwave_delete(object *objp)
Definition: shockwave.cpp:159
int ai_index
Definition: ship.h:538
#define NETINFO_FLAG_OBSERVER
Definition: multi.h:605
ushort net_signature
Definition: object.h:163
int ship_fire_primary(object *obj, int stream_weapons, int force)
Definition: ship.cpp:10760
void obj_reset_colliders()
float side_slip_time_const
Definition: physics.h:44
#define OBJ_ASTEROID
Definition: object.h:44
int ship_stop_fire_primary(object *obj)
Definition: ship.cpp:10711
Definition: 2d.h:95
matrix Eye_matrix
Definition: 3dsetup.cpp:26
void obj_snd_delete_type(int objnum, int sndnum, ship_subsys *ss)
Definition: objectsnd.cpp:812
vec3d arc_pts[MAX_DEBRIS_ARCS][2]
Definition: debris.h:44
int parent_type
Definition: object.h:203
struct vec3d::@225::@227 xyz
CButton * team
int Cmdline_dis_weapons
Definition: cmdline.cpp:491
GLclampf f
Definition: Glext.h:7097
#define MAX_OBJECTS
Definition: globals.h:83
void weapon_render(object *obj, draw_list *scene)
Definition: weapons.cpp:7268
int model_num
Definition: debris.h:34
object()
Definition: object.cpp:111
int Object_next_signature
Definition: object.cpp:71
#define OF_NO_SHIELDS
Definition: object.h:110
ai_info Ai_info[MAX_AI_INFO]
Definition: ai.cpp:23
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:933
void ship_process_pre(object *objp, float frametime)
Definition: ship.cpp:9128
#define Assertion(expr, msg,...)
Definition: clang.h:41
void obj_free(int objnum)
Definition: object.cpp:429
#define f2fl(fx)
Definition: floating.h:37
int n_quadrants
Definition: object.h:158
void ship_process_post(object *obj, float frametime)
Definition: ship.cpp:9180
#define OF_COLLIDES
Definition: object.h:104
Definition: ai.h:329
#define GR_FILL_MODE_SOLID
Definition: 2d.h:670
uint flags
Definition: ship.h:644
int ship_fire_secondary(object *obj, int allow_swarm)
Definition: ship.cpp:11799
ubyte blue
Definition: 2d.h:102
hull_check orient
Definition: lua.cpp:5049
int flags
Definition: multi.h:463
#define OF_PLAYER_SHIP
Definition: object.h:109
void obj_merge_created_list(void)
Definition: object.cpp:651
void dock_move_docked_objects(object *objp)
Definition: objectdock.cpp:371
object * objp
Definition: lua.cpp:3105
void profile_begin(const char *name)
Definition: profiling.cpp:80
#define OBJ_OBSERVER
Definition: object.h:43
#define Int3()
Definition: pstypes.h:292
int collide_remove_weapons()
void find_homing_object_cmeasures()
Definition: weapons.cpp:4170
void obj_move_one_docked_object(object *objp, object *parent_objp)
Definition: object.cpp:682
ship * shipp
Definition: lua.cpp:9162
uint flags
Definition: object.h:201
vec3d pos
Definition: object.h:152
void obj_move_call_physics(object *objp, float frametime)
Definition: object.cpp:781
int render_type
Definition: weapon.h:327
int object_get_model(object *objp)
Definition: object.cpp:2092
void obj_remove_collider(int obj_index)
void obj_player_fire_stuff(object *objp, control_info ci)
Definition: object.cpp:720
void multi_do_client_warp(float frame_time)
Definition: multiutil.cpp:1140
int asteroid_subtype
Definition: asteroid.h:103
script_state Script_system("FS2_Open Scripting")
#define PROFILE(name, function)
Definition: systemvars.h:251
int signature
Definition: object.h:145
void debris_process_post(object *obj, float frame_time)
Definition: debris.cpp:284
SCP_list< CJumpNode > Jump_nodes
Definition: jumpnode.cpp:16
GLenum type
Definition: Gl.h:1492
void obj_sort_and_collide()
ubyte green
Definition: 2d.h:101
int weapon_info_index
Definition: weapon.h:164
#define gr_set_lighting
Definition: 2d.h:924
void gr_set_color(int r, int g, int b)
Definition: 2d.cpp:1188
int asteroid_type
Definition: asteroid.h:102
object obj_used_list
Definition: object.cpp:53
void obj_observer_move(float frame_time)
Definition: object.cpp:1772
int objnum
Definition: ship.h:1483
#define OF_TARGETABLE_AS_BOMB
Definition: object.h:118
void shockwave_render_DEPRECATED(object *objp)
Definition: shockwave.cpp:388
int object_is_docked(object *objp)
Definition: object.cpp:2019
#define OBJ_WAYPOINT
Definition: object.h:36
int fireball_is_warp(object *obj)
Definition: fireballs.cpp:601
int instance
Definition: object.h:150
void obj_add_pairs(int objnum)
Definition: object.cpp:1901
void weapon_delete(object *obj)
Definition: weapons.cpp:3822
void afterburners_stop(object *objp, int key_released)
object * a
Definition: objcollide.h:55
Definition: player.h:85
float ship_get_subsystem_strength(ship *shipp, int type)
Definition: ship.cpp:13446
Definition: debris.h:23
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
#define OBJ_START
Definition: object.h:35
vec3d last_pos
Definition: object.h:155
int weapon_flags
Definition: weapon.h:176
#define OF_IMMOBILE
Definition: object.h:122
void obj_add_collider(int obj_index)
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
dock_instance * dock_list
Definition: object.h:166
int obj_get_SIF(object *objp)
Definition: object.cpp:1817
vec3d desired_rotvel
Definition: physics.h:71
unsigned int uint
Definition: pstypes.h:64
void observer_process_post(object *objp)
Definition: ship.cpp:8947
#define PF_REDUCED_DAMP
Definition: physics.h:22
float ship_max_hull_strength
Definition: ship.h:597
GLboolean GLboolean g
Definition: Glext.h:5781
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
detail_levels Detail
Definition: systemvars.cpp:478
int team
Definition: weapon.h:167
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
int obj_create(ubyte type, int parent_obj, int instance, matrix *orient, vec3d *pos, float radius, uint flags)
Definition: object.cpp:467
int ship_subsys_disrupted(ship_subsys *ss)
Definition: ship.cpp:9033
void fireball_get_color(int idx, float *red, float *green, float *blue)
Definition: fireballs.cpp:972
float get_hull_pct(object *objp)
Definition: object.cpp:271
#define gr_set_buffer
Definition: 2d.h:891
bool object_get_gliding(object *objp)
Definition: object.cpp:2059
int wingnum
Definition: ship.h:623
void obj_remove_pairs(object *a)
Definition: object.cpp:1938
int num_secondary_banks
Definition: ship.h:100
#define OBJ_WEAPON
Definition: object.h:33
int mode
Definition: ai.h:336
void obj_move_all_post(object *objp, float frametime)
Definition: object.cpp:1167
int ai_paused
Definition: object.cpp:677
ubyte Obj_weapon_group_id_used[WEAPON_MAX_GROUP_IDS]
Definition: object.cpp:1153
int type
Definition: object.h:199
object obj_create_list
Definition: object.cpp:54
int Cmdline_old_collision_sys
Definition: cmdline.cpp:489
float hull_strength
Definition: object.h:160
#define OBJ_DEBRIS
Definition: object.h:37
#define WRT_LASER
Definition: weapon.h:34
int parent
Definition: object.h:147
int multi_oo_is_interp_object(object *objp)
Definition: multi_obj.cpp:1825
int object_is_dead_docked(object *objp)
Definition: object.cpp:2025
void dock_free_dead_dock_list(object *objp)
void asteroid_render_DEPRECATED(object *obj)
Definition: asteroid.cpp:1170
struct obj_pair * next
Definition: objcollide.h:59
ubyte red
Definition: 2d.h:100
#define OF_PROTECTED
Definition: object.h:108
void ship_delete(object *obj)
Definition: ship.cpp:7585
int Highest_ever_object_index
Definition: object.cpp:70
object * Viewer_obj
Definition: object.cpp:57
void physics_init(physics_info *pi)
Definition: physics.cpp:49
void obj_clear_weapon_group_id_list()
Definition: object.cpp:1158
#define AIS_DOCK_3
Definition: ai.h:272
#define PF_FORCE_GLIDE
Definition: physics.h:33
int secondary_bank_weapons[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:104
#define WEAPON_MAX_GROUP_IDS
Definition: weapon.h:637
int arc_timestamp[MAX_SHIP_ARCS]
Definition: ship.h:712
void weapon_process_post(object *obj, float frame_time)
Definition: weapons.cpp:4775
#define PTRDIFF_T_ARG
Definition: clang.h:62
obj_pair pair_used_list
Definition: objcollide.cpp:41
#define OF_COULD_BE_PLAYER
Definition: object.h:112
#define AIM_WARP_OUT
Definition: ai.h:186
#define MONITOR(function_name)
Definition: pstypes.h:454
float fireball_lifeleft_percent(object *obj)
Definition: fireballs.cpp:686
void init_render(bool sort=true)
angles * vm_extract_angles_matrix(angles *a, const matrix *m)
Definition: vecmat.cpp:1027
#define DEFAULT_SHIELD_SECTIONS
Definition: object.h:24
void model_do_intrinsic_rotations(int model_instance_num=-1)
Definition: modelread.cpp:4878
Definition: ship.h:534
void SetHookObject(char *name, object *objp)
Definition: scripting.cpp:551
int num_slots
Definition: model.h:433
int secondary_bank_ammo[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:134
debris Debris[MAX_DEBRIS_PIECES]
Definition: debris.cpp:41
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
void shockwave_render(object *objp, draw_list *scene)
Definition: shockwave.cpp:462
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
#define AIM_DOCK
Definition: ai.h:174
unsigned char ubyte
Definition: pstypes.h:62
#define MONITOR_INC(function_name, inc)
Definition: pstypes.h:457
int fireball_is_perishable(object *obj)
Definition: fireballs.cpp:540
#define vm_vec_zero(v)
Definition: vecmat.h:37
uint flags
Definition: physics.h:37
void asteroid_process_post(object *obj)
Definition: asteroid.cpp:1750
#define PF_USE_VEL
Definition: physics.h:19
#define OBJ_INDEX(objp)
Definition: object.h:235
void obj_client_pre_interpolate()
Definition: object.cpp:1703
ship * Player_ship
Definition: ship.cpp:124
void obj_get_average_ship_pos(vec3d *pos)
Definition: object.cpp:1796
SCP_string team_name
Definition: ship.h:812
#define gr_set_cull
Definition: 2d.h:838
matrix orient
Definition: object.h:153
int parent_sig
Definition: object.h:202
float get_sim_hull_pct(object *objp)
Definition: object.cpp:289
void ship_render_DEPRECATED(object *obj)
Definition: ship.cpp:6733
void clear()
Definition: object.cpp:127
#define WF_DEAD_IN_WATER
Definition: weapon.h:141
#define OBJ_SHIP
Definition: object.h:32
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
void fireball_render(object *obj, draw_list *scene)
Definition: fireballs.cpp:1055
void weapon_get_laser_color(color *c, object *objp)
Definition: weapons.cpp:6707
GLbitfield flags
Definition: Glext.h:6722
int afterburner_stop
Definition: physics.h:117
fireball Fireballs[]
Definition: fireballs.cpp:43
#define OF_MISSILE_PROTECTED
Definition: object.h:121
int RunCondition(int condition, char format='\0', void *data=NULL, class object *objp=NULL, int more_data=0)
Definition: scripting.cpp:924
#define CHA_ONWPEQUIPPED
Definition: scripting.h:65
void SetHookObjects(int num,...)
Definition: scripting.cpp:556
GLboolean enable
Definition: Glext.h:10591
#define SUBSYSTEM_ENGINE
Definition: model.h:53
vec3d vel
Definition: physics.h:77
vec3d Eye_position
Definition: 3dsetup.cpp:27
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
float get_shield_pct(object *objp)
Definition: object.cpp:308
void profile_end(const char *name)
Definition: profiling.cpp:130
void physics_sim(vec3d *position, matrix *orient, physics_info *pi, float sim_time)
Definition: physics.cpp:364
void afterburners_start(object *objp)
Definition: afterburner.cpp:68
checkobject CheckObjects[MAX_OBJECTS]
void asteroid_render(object *obj, draw_list *scene)
Definition: asteroid.cpp:1189
#define AIS_UNDOCK_0
Definition: ai.h:275
void obj_delete(int objnum)
Definition: object.cpp:522
#define DCF_BOOL(function_name, bool_variable)
Definition: console.h:71
#define gr_zbias
Definition: 2d.h:932
int ship_launch_countermeasure(object *objp, int rand_val)
Definition: ship.cpp:10421
void obj_add_pair(object *A, object *B, int check_time, int add_to_end)
Definition: objcollide.cpp:174
float frame_time
Definition: multi.cpp:1426
int secondary_next_slot[MAX_SHIP_SECONDARY_BANKS]
Definition: ship.h:137
int Collisions_enabled
Definition: object.cpp:1374
#define AIS_WARP_3
Definition: ai.h:306
#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
void fireball_delete(object *obj)
Definition: fireballs.cpp:458
int num_pairs
Definition: object.h:164
int signature
Definition: object.h:200
void ship_render(object *obj, draw_list *scene)
Definition: ship.cpp:19003
void multi_oo_interp(object *objp)
Definition: multi_obj.cpp:1866
float Physics_viewer_bank
Definition: physics.cpp:128
player * Player
void debris_render(object *obj, draw_list *scene)
Definition: debris.cpp:1099
GLenum target
Definition: Glext.h:6872
physics_info * Viewer_physics_info
Definition: physics.cpp:130
#define OBJ_SHOCKWAVE
Definition: object.h:41
matrix last_rotmat
Definition: physics.h:83
#define MAX_SHIP_ARCS
Definition: ship.h:517
#define gr_clear_states
Definition: 2d.h:946
#define OF_JUST_UPDATED
Definition: object.h:111
ship_obj Ship_obj_list
Definition: ship.cpp:162
void RemHookVars(unsigned int num,...)
Definition: scripting.cpp:754
void render_all(int depth_mode=-1)
#define OF_PHYSICS
Definition: object.h:105
int ship_info_index
Definition: ship.h:539
int Highest_object_index
Definition: object.cpp:69
GLfloat GLfloat p
Definition: Glext.h:8373
#define MULTIPLAYER_MASTER
Definition: multi.h:130
int arc_timestamp[MAX_DEBRIS_ARCS]
Definition: debris.h:45
#define CHA_OBJECTRENDER
Definition: scripting.h:52
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
void asteroid_process_pre(object *objp)
Definition: asteroid.cpp:908
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define LOCATION
Definition: pstypes.h:245
#define OF_FLAK_PROTECTED
Definition: object.h:119
#define DEBRIS_EXPIRE
Definition: debris.h:55
#define PF_DEAD_DAMP
Definition: physics.h:24
object * docked_objp
Definition: objectdock.h:22
int Num_pairs
Definition: objcollide.cpp:32
object * b
Definition: objcollide.h:56
#define gr_set_fill_mode
Definition: 2d.h:933
SCP_vector< float > shield_quadrant
Definition: object.h:159
int free_object_slots(int num_used)
Definition: object.cpp:152
float fireball_wormhole_intensity(object *obj)
Definition: fireballs.cpp:1031
#define OF_SHOULD_BE_DEAD
Definition: object.h:106
void fireball_render_DEPRECATED(object *obj)
Definition: fireballs.cpp:377
void obj_delete_all_that_should_be_dead()
Definition: object.cpp:624
#define PI
Definition: pstypes.h:303
dock_instance * dead_dock_list
Definition: object.h:167
#define MAX_WEAPONS
Definition: globals.h:71
hull_check pos
Definition: lua.cpp:5050
#define MISSION_FLAG_2D_MISSION
Definition: missionparse.h:82
GLsizei GLsizei GLuint * obj
Definition: Glext.h:5619
void weapon_render_DEPRECATED(object *obj)
Definition: weapons.cpp:3625
int Iff_traitor
Definition: iff_defs.cpp:22
#define gr_reset_lighting
Definition: 2d.h:907
void debris_delete(object *obj)
Definition: debris.cpp:225
int model_num
Definition: weapon.h:329
#define i2fl(i)
Definition: floating.h:32
#define AIS_UNDOCK_1
Definition: ai.h:276
GLint GLsizei count
Definition: Gl.h:1491
int physics_paused
Definition: object.cpp:677
matrix * A
Definition: lua.cpp:444
object * Player_obj
Definition: object.cpp:56
obj_pair pair_free_list
Definition: objcollide.cpp:42
void obj_check_all_collisions()
Definition: objcollide.cpp:530
vec3d prev_ramp_vel
Definition: physics.h:69
vec3d arc_pts[MAX_SHIP_ARCS][2]
Definition: ship.h:711
#define SF_DYING
Definition: ship.h:447
int temp
Definition: lua.cpp:4996
int goal_objnum
Definition: ai.h:355
int Object_inited
Definition: object.cpp:72
int team_change_time
Definition: ship.h:815
bool is_minimum_GLSL_version()
Definition: gropengl.cpp:2064
polymodel * pm
Definition: lua.cpp:1598
void ship_update_artillery_lock()
Definition: ship.cpp:17146
w_bank * missile_banks
Definition: model.h:773
void obj_reset_pairs()
Definition: objcollide.cpp:98
void turret_swarm_check_validity()
Definition: swarm.cpp:632
int g3_draw_sphere_ez(const vec3d *pnt, float rad)
Definition: 3ddraw.cpp:498
#define OBJ_NONE
Definition: object.h:31
#define OBJ_BEAM
Definition: object.h:46
void ship_model_update_instance(object *objp)
Definition: ship.cpp:13072
int collision_group_id
Definition: object.h:169
obj_flag_name Object_flag_names[]
Definition: object.cpp:97
int obj_get_by_signature(int sig)
Definition: object.cpp:2074
uint flags
Definition: object.h:151
float radius
Definition: object.h:154
void beam_move_all_pre()
Definition: beam.cpp:906
mission The_mission
#define OBJ_WING
Definition: object.h:42
matrix last_orient
Definition: object.h:156
#define SF_TRIGGER_DOWN
Definition: ship.h:462
float h
Definition: pstypes.h:111
int Show_waypoints
Definition: object.cpp:73
char type
Definition: object.h:146
#define AIS_DOCK_2
Definition: ai.h:271
void obj_render_DEPRECATED(object *obj)
Definition: object.cpp:1537
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
SCP_vector< int > objsnd_num
Definition: object.h:162
void observer_delete(object *obj)
Definition: observer.cpp:86
void obj_queue_render(object *obj, draw_list *scene)
Definition: object.cpp:1625
#define wp(p)
Definition: modelsinc.h:69
#define OBJ_POINT
Definition: object.h:40
int Num_objects
Definition: object.cpp:68
bool IsConditionOverride(int action, object *objp=NULL)
Definition: scripting.cpp:938
SCP_vector< asteroid_info > Asteroid_info
Definition: asteroid.cpp:62
~object()
Definition: object.cpp:118
#define stricmp(s1, s2)
Definition: config.h:271
#define OBJ_JUMP_NODE
Definition: object.h:45
void obj_move_all(float frametime)
Definition: object.cpp:1383
#define OBJ_GHOST
Definition: object.h:39
matrix vmd_identity_matrix
Definition: vecmat.cpp:28
#define timestamp_valid(stamp)
Definition: timer.h:104
void fireball_process_post(object *obj, float frame_time)
Definition: fireballs.cpp:643
int parent_sig
Definition: object.h:148
char ship_name[NAME_LENGTH]
Definition: ship.h:604
int Arc_light
Definition: object.cpp:1163
const GLubyte * c
Definition: Glext.h:8376
void physics_ship_init(object *objp)
Definition: ship.cpp:5366
#define OF_DOCKED_ALREADY_HANDLED
Definition: object.h:117
void asteroid_delete(object *obj)
Definition: asteroid.cpp:826
int obj_allocate(void)
Definition: object.cpp:370
float b
Definition: pstypes.h:111
float secondary_point_reload_pct[MAX_SHIP_SECONDARY_BANKS][MAX_SLOTS]
Definition: ship.h:784
#define IMPORTANT_FLAGS
Definition: object.cpp:942
#define OF_BEAM_PROTECTED
Definition: object.h:115