2 * $Logfile: /Freespace2/code/Hud/HUDescort.cpp $
7 * C module for managing and displaying ships that are in an escort
10 * Revision 1.2 2002/05/07 03:16:45 theoddone33
11 * The Great Newline Fix
13 * Revision 1.1.1.1 2002/05/03 03:28:09 root
17 * 22 8/04/99 2:24a Dave
18 * Fixed escort gauge ordering for dogfight.
20 * 21 7/30/99 7:01p Dave
21 * Dogfight escort gauge. Fixed up laser rendering in Glide.
23 * 20 7/29/99 1:57p Jefff
24 * Fixed location of "D" for disabled ships in hi-res
26 * 19 7/22/99 7:49p Dave
27 * Show enemy ships on the escort list in red.
29 * 18 6/23/99 10:13p Andsager
30 * Fix Baranec hud escort default color bug!
32 * 17 6/10/99 3:43p Dave
33 * Do a better job of syncing text colors to HUD gauges.
35 * 16 5/24/99 11:28a Dave
36 * Sexpression for adding/removing ships from the hud escort list.
38 * 15 3/30/99 5:40p Dave
39 * Fixed reinforcements for TvT in multiplayer.
41 * 14 3/19/99 9:51a Dave
42 * Checkin to repair massive source safe crash. Also added support for
43 * pof-style nebulae, and some new weapons code.
45 * 14 3/12/99 4:24p Andsager
46 * Fix bug where two or more ships are culled from escort list same frame
48 * 13 3/04/99 9:22a Andsager
49 * Make escort list work with ship-is-visible. When not visible, dump,
50 * when becoming visible, maybe add.
52 * 12 3/02/99 12:27p Andsager
53 * Fixed bug in hud_add_ship_to_escort -- multiple entries and
54 * uninitialized entries.
56 * 11 3/02/99 11:45a Anoop
57 * put in assert for escort list
59 * 10 3/01/99 12:00p Andsager
60 * Fix escort priority to look at newly added ships.
62 * 9 2/03/99 6:13p Andsager
63 * Added priorities to escort list. Folded escort hit info into
66 * 8 2/01/99 9:47a Jasen
67 * Tweaked coords for the monitoring window in hi res.
69 * 7 1/30/99 7:48p Jasen
71 * 6 1/07/99 9:07a Jasen
74 * 5 12/28/98 3:17p Dave
75 * Support for multiple hud bitmap filenames for hi-res mode.
87 #include "hudtarget.h"
88 #include "hudtargetbox.h"
90 #include "freespace.h"
93 #include "hudshield.h"
95 #include "hudescort.h"
97 #include "alphacolors.h"
99 #include "multiutil.h"
101 int Show_escort_view;
103 typedef struct escort_info
106 int obj_signature; // so we are sure we have a valid objnum
107 int priority; // higher priority is higher in the list
108 short np_id; // netplayer id (for multiplayer dogfight mode)
109 shield_hit_info hit_info;
112 escort_info Escort_ships[MAX_ESCORT_SHIPS];
113 int Num_escort_ships;
116 // size of complete escort list, including all those wanting to get onto list but without space
117 #define MAX_COMPLETE_ESCORT_LIST 20
120 #define NUM_ESCORT_FRAMES 3
121 hud_frames Escort_gauges[NUM_ESCORT_FRAMES];
122 int Escort_gauges_loaded = 0;
124 int Escort_gauge_y[MAX_ESCORT_SHIPS] = { 219, 230, 241 };
127 int Escort_gauge_text_coords[GR_NUM_RESOLUTIONS][MAX_ESCORT_SHIPS][4][2] =
171 // escort gauge coords
172 int Escort_coords[GR_NUM_RESOLUTIONS][4][2] = {
187 // monitoring text coords
188 int Monitoring_coords[GR_NUM_RESOLUTIONS][2] = {
197 char *Escort_gauge_filenames[GR_NUM_RESOLUTIONS][MAX_ESCORT_SHIPS] =
213 static int Last_target_index; // index into Escort_gauges for last targeted via 'Next Escort Target' key
215 // data needed from HUDshield.cpp
216 extern hud_frames Shield_mini_gauge;
218 // called from HUD init, loads the bitmap data in once, and resets any data for each level
219 void hud_escort_init()
223 if ( !Escort_gauges_loaded ) {
224 for ( i = 0; i < MAX_ESCORT_SHIPS; i++ ) {
225 Escort_gauges[i].first_frame = bm_load_animation(Escort_gauge_filenames[gr_screen.res][i], &Escort_gauges[i].num_frames);
226 if ( Escort_gauges[i].first_frame == -1 ) {
227 Warning(LOCATION, "Could not load in ani: %s\n", Escort_gauge_filenames[gr_screen.res][i]);
231 Escort_gauges_loaded = 1;
234 Last_target_index = -1;
237 // ----------------------------------------------------------------------
238 // hud_escort_clear_all()
240 void hud_escort_clear_all()
244 Num_escort_ships = 0;
245 for ( i = 0; i < MAX_ESCORT_SHIPS; i++ ) {
246 Escort_ships[i].obj_signature = -99;
247 Escort_ships[i].np_id = -1;
248 shield_info_reset(&Escort_ships[i].hit_info);
252 // internal helper function for sort.
253 // sorts first by priority number and then alphabetically
254 int escort_compare_func(const void *e1, const void *e2)
256 escort_info *escort1, *escort2;
260 escort1 = (escort_info*) e1;
261 escort2 = (escort_info*) e2;
263 // multiplayer dogfight
264 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
267 n1 = find_player_id(escort1->np_id);
268 n2 = find_player_id(escort2->np_id);
269 if((n1 < 0) || (n2 < 0) || (Net_players[n1].player == NULL) || (Net_players[n2].player == NULL)){
272 // player 1 is higher than player 2
273 if(Net_players[n1].player->stats.m_kill_count_ok >= Net_players[n2].player->stats.m_kill_count_ok){
280 diff = escort2->priority - escort1->priority;
286 name1 = Ships[Objects[escort1->objnum].instance].ship_name;
287 name2 = Ships[Objects[escort2->objnum].instance].ship_name;
289 ret = stricmp(name1, name2);
296 // create complete priority sorted escort list for all active ships
297 // escorts - array of escort info
298 // num_escorts - number of escorts requests in field of active ships
299 // This will be culled to MAX_ESCORTS, selecting the top set from escorts
300 void hud_create_complete_escort_list(escort_info *escorts, int *num_escorts)
306 // start with none on list
309 // multiplayer dogfight
310 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
311 for(idx=0; idx<MAX_PLAYERS; idx++){
312 // break out of the loop when we have reached our max
313 if ( *num_escorts == MAX_COMPLETE_ESCORT_LIST ) {
314 mprintf(("exceeded max ships in big escort list"));
318 // is this a valid player
319 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_OBSERVER(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx])){
321 escorts[*num_escorts].objnum = -1;
322 escorts[*num_escorts].obj_signature = -1;
323 escorts[*num_escorts].priority = -1;
324 escorts[*num_escorts].np_id = Net_players[idx].player_id;
331 for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) {
332 Assert( so->objnum >= 0 && so->objnum < MAX_OBJECTS);
333 if((so->objnum < 0) || (so->objnum >= MAX_OBJECTS)){
336 objp = &Objects[so->objnum];
337 Assert( objp->type == OBJ_SHIP );
338 if(objp->type != OBJ_SHIP){
342 // break out of the loop when we have reached our max
343 if ( *num_escorts == MAX_COMPLETE_ESCORT_LIST ) {
344 mprintf(("exceeded max ships in big escort list"));
348 // only process ships that might be on the list
349 if ( !(Ships[objp->instance].flags & SF_ESCORT) ){
353 // only process ships that can be seen by sensors
354 if ( (Ships[objp->instance].flags & SF_HIDDEN_FROM_SENSORS) ){
358 // don't process ships that are dying, or objects that should be dead
359 if ( (Ships[objp->instance].flags & (SF_DYING|SF_DEPARTING)) || (objp->flags & OF_SHOULD_BE_DEAD) ){
364 escorts[*num_escorts].objnum = so->objnum;
365 escorts[*num_escorts].obj_signature = objp->signature;
366 escorts[*num_escorts].priority = Ships[objp->instance].escort_priority;
367 escorts[*num_escorts].np_id = -1;
374 // ----------------------------------------------------------------------
375 // hud_init_escort_info()
377 // Set up the escort list
379 void hud_setup_escort_list(int level)
381 int num_escorts, num_complete_escorts;
382 escort_info complete_escorts[MAX_COMPLETE_ESCORT_LIST];
384 hud_escort_clear_all();
386 // get complete escort list
387 hud_create_complete_escort_list(complete_escorts, &num_complete_escorts);
389 // sort escort list by priority
390 qsort(complete_escorts, num_complete_escorts, sizeof(escort_info), escort_compare_func);
392 // set number in escort list
393 num_escorts = num_complete_escorts;
394 if (num_escorts > MAX_ESCORT_SHIPS) {
395 num_escorts = MAX_ESCORT_SHIPS;
398 // add ships to escort list
399 for (Num_escort_ships=0; Num_escort_ships<num_escorts; Num_escort_ships++) {
400 Escort_ships[Num_escort_ships].obj_signature = complete_escorts[Num_escort_ships].obj_signature;
401 Escort_ships[Num_escort_ships].priority = complete_escorts[Num_escort_ships].priority;
402 Escort_ships[Num_escort_ships].objnum = complete_escorts[Num_escort_ships].objnum;
403 Escort_ships[Num_escort_ships].np_id = complete_escorts[Num_escort_ships].np_id;
407 Show_escort_view = 1;
412 // combine complete escort list with Escort_ships, keeping valid hit info
413 void merge_escort_lists(escort_info *complete_escorts, int num_complete_escorts)
415 int i, j, top_complete_escorts;
416 int valid_hit_info[MAX_ESCORT_SHIPS];
418 // may be > 1 ship change to list (ie, 2 or 3 culled during same frame)
419 // set Num_escort_ships and cap
420 Num_escort_ships = num_complete_escorts;
421 if (Num_escort_ships > MAX_ESCORT_SHIPS) {
422 Num_escort_ships = MAX_ESCORT_SHIPS;
426 if (Num_escort_ships == 0) {
430 // check used as a flag whether top slots in complete_escorts were copied
431 // this is important re. hit info
432 for (i=0; i<MAX_ESCORT_SHIPS; i++) {
433 valid_hit_info[i] = 0;
436 // get the top slots in complete escort list that will be copied onto Escort_ships
437 top_complete_escorts = num_complete_escorts;
438 if (top_complete_escorts > MAX_ESCORT_SHIPS) {
439 top_complete_escorts = MAX_ESCORT_SHIPS;
442 // copy for Escort_ships to complete_escorts to retain hit_info
443 if(!((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT))){
444 for (i=0; i<top_complete_escorts; i++) {
445 for (j=0; j<Num_escort_ships; j++) {
446 if (Escort_ships[j].obj_signature == complete_escorts[i].obj_signature) {
447 complete_escorts[i] = Escort_ships[j];
448 valid_hit_info[i] = 1;
454 // copy top slots to Escort_ships
455 for (i=0; i<top_complete_escorts; i++) {
456 Escort_ships[i] = complete_escorts[i];
457 // check all ships are valid
458 int objnum = Escort_ships[i].objnum;
459 Assert( objnum >=0 && objnum < MAX_OBJECTS );
460 if((objnum < 0) || (objnum >= MAX_OBJECTS)){
463 if ( !valid_hit_info[i] ) {
464 shield_info_reset(&Escort_ships[i].hit_info);
469 // reset Num_escort_ships
470 Num_escort_ships = top_complete_escorts;
474 // ----------------------------------------------------------------------
475 // hud_remove_ship_from_escort_index()
477 // Take a ship out of the escort list
478 void hud_remove_ship_from_escort_index(int dead_index, int objnum)
480 int i, count, num_complete_escorts;
481 escort_info bakup_arr[MAX_ESCORT_SHIPS], complete_escorts[MAX_COMPLETE_ESCORT_LIST];
483 // remove him from escort list
484 if((objnum >= 0) && (Objects[objnum].type == OBJ_SHIP) && (Objects[objnum].instance >= 0)){
485 Ships[Objects[objnum].instance].flags &= ~SF_ESCORT;
489 for ( i = 0; i < Num_escort_ships; i++ ) {
490 if ( i != dead_index ) {
491 bakup_arr[count++] = Escort_ships[i];
495 for ( i = 0; i < count; i++ ) {
496 Escort_ships[i] = bakup_arr[i];
500 Assert(Num_escort_ships >= 0);
502 // get complete escort list
503 hud_create_complete_escort_list(complete_escorts, &num_complete_escorts);
505 // sort escort list by priority
506 qsort(complete_escorts, num_complete_escorts, sizeof(escort_info), escort_compare_func);
509 merge_escort_lists(complete_escorts, num_complete_escorts);
511 hud_gauge_popup_start(HUD_ESCORT_VIEW);
515 // called once per frame to remove dead or departed ships from the escort list
516 void hud_escort_cull_list()
518 int i, objnum, np_index;
520 // multiplayer dogfight
521 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
522 for ( i = 0; i < Num_escort_ships; i++ ) {
523 np_index = find_player_id(Escort_ships[i].np_id);
525 // maybe remove him if he left
526 if ( np_index < 0 ) {
527 hud_remove_ship_from_escort_index(i, -1);
534 for ( i = 0; i < Num_escort_ships; i++ ) {
535 objnum = Escort_ships[i].objnum;
536 Assert( objnum >=0 && objnum < MAX_OBJECTS );
537 if ( Objects[objnum].flags & OF_SHOULD_BE_DEAD || Ships[Objects[objnum].instance].flags & SF_HIDDEN_FROM_SENSORS ) {
538 hud_remove_ship_from_escort_index(i, objnum);
545 // Set the color for the text to be displayed
546 int hud_escort_set_gauge_color(int index, int friendly)
549 shield_hit_info *shi;
551 shi = &Escort_ships[index].hit_info;
553 // multiplayer dogfight
554 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
555 hud_set_gauge_color(HUD_ESCORT_VIEW);
560 hud_set_gauge_color(HUD_ESCORT_VIEW, HUD_C_DIM);
562 gr_set_color_fast(&Color_red);
565 // set flashing color
566 if ( !timestamp_elapsed(shi->shield_hit_timers[HULL_HIT_OFFSET]) ) {
567 if ( timestamp_elapsed(shi->shield_hit_next_flash[HULL_HIT_OFFSET]) ) {
568 shi->shield_hit_next_flash[HULL_HIT_OFFSET] = timestamp(SHIELD_FLASH_INTERVAL);
569 shi->shield_show_bright ^= (1<<HULL_HIT_OFFSET); // toggle between default and bright frames
573 if ( shi->shield_show_bright & (1<<HULL_HIT_OFFSET) ) {
575 hud_set_gauge_color(HUD_ESCORT_VIEW, HUD_C_BRIGHT);
577 gr_set_color_fast(&Color_bright_red);
581 hud_set_gauge_color(HUD_ESCORT_VIEW, HUD_C_DIM);
583 gr_set_color_fast(&Color_dim_red);
591 // draw the shield icon and integrity for the escort ship
592 void hud_escort_show_icon(int index, object *objp)
594 float shields, integrity;
595 int screen_integrity, offset;
599 shield_hit_info *shi;
601 // multiplayer dogfight code should never get into here
602 Assert(!((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)));
603 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
607 sp = &Ships[objp->instance];
608 sip = &Ship_info[sp->ship_info_index];
609 shi = &Escort_ships[index].hit_info;
611 // determine if its "friendly" or not
612 if(Player_ship != NULL){
613 hud_escort_set_gauge_color(index, (sp->team == Player_ship->team) ? 1 : 0);
615 hud_escort_set_gauge_color(index, 1);
618 // draw a 'D' if a ship is disabled
619 if ( (sp->flags & SF_DISABLED) || (ship_subsys_disrupted(sp, SUBSYSTEM_ENGINE)) ) {
620 emp_hud_string( Escort_gauge_text_coords[gr_screen.res][index][3][0], Escort_gauge_text_coords[gr_screen.res][index][3][1], EG_NULL, XSTR( "D", 284));
623 // print out ship name
624 strcpy(buf, sp->ship_name);
625 gr_force_fit_string(buf, 255, 100);
627 emp_hud_string( Escort_gauge_text_coords[gr_screen.res][index][0][0], Escort_gauge_text_coords[gr_screen.res][index][0][1], EG_ESCORT1 + index, buf);
629 // show ship integrity
630 hud_get_target_strength(objp, &shields, &integrity);
631 screen_integrity = fl2i(integrity*100 + 0.5f);
633 if ( screen_integrity < 100 ) {
635 if ( screen_integrity == 0 ) {
636 if ( integrity > 0 ) {
637 screen_integrity = 1;
641 emp_hud_printf( Escort_gauge_text_coords[gr_screen.res][index][2][0]+offset, Escort_gauge_text_coords[gr_screen.res][index][2][1], EG_NULL, "%d", screen_integrity);
644 // multiplayer dogfight
645 void hud_escort_show_icon_dogfight(int index)
647 int hull_integrity = 100;
655 // always use the standard color to avoid confusion
656 hud_set_gauge_color(HUD_ESCORT_VIEW);
659 np_index = find_player_id(Escort_ships[index].np_id);
660 if((np_index < 0) || (np_index >= MAX_PLAYERS) || (Net_players[np_index].player == NULL)){
664 // print out player name
665 strcpy(buf, Net_players[np_index].player->callsign);
666 gr_force_fit_string(buf, 255, 100 - stat_shift);
667 emp_hud_string( Escort_gauge_text_coords[gr_screen.res][index][0][0], Escort_gauge_text_coords[gr_screen.res][index][0][1], EG_ESCORT1 + index, buf);
669 // can we get the player object?
671 if((Net_players[np_index].player->objnum >= 0) && (Net_players[np_index].player->objnum < MAX_OBJECTS) && (Objects[Net_players[np_index].player->objnum].type == OBJ_SHIP)){
672 objp = &Objects[Net_players[np_index].player->objnum];
673 if((objp->instance >= 0) && (objp->instance < MAX_SHIPS) && (Ships[objp->instance].ship_info_index >= 0) && (Ships[objp->instance].ship_info_index < MAX_SHIPS)){
674 sip = &Ship_info[Ships[objp->instance].ship_info_index];
679 hull_integrity = (int)(((float)objp->hull_strength / (float)sip->initial_hull_strength) * 100.0f);
680 if(hull_integrity < 0){
685 // show ship integrity
687 emp_hud_printf( Escort_gauge_text_coords[gr_screen.res][index][2][0] - stat_shift, Escort_gauge_text_coords[gr_screen.res][index][2][1], EG_NULL, "%d", Net_players[np_index].player->stats.m_kill_count_ok);
689 emp_hud_printf( Escort_gauge_text_coords[gr_screen.res][index][2][0] - stat_shift, Escort_gauge_text_coords[gr_screen.res][index][2][1], EG_NULL, "(%d%%) %d", hull_integrity, Net_players[np_index].player->stats.m_kill_count_ok);
694 // ----------------------------------------------------------------------
695 // hud_display_escort()
697 // Display the data on ships in the escort list
698 void hud_display_escort()
703 if ( !Show_escort_view ) {
707 if ( !Num_escort_ships ) {
711 // hud_set_default_color();
712 hud_set_gauge_color(HUD_ESCORT_VIEW);
714 // draw the top of the escort view
715 GR_AABITMAP(Escort_gauges[0].first_frame, Escort_coords[gr_screen.res][0][0], Escort_coords[gr_screen.res][0][1]);
716 gr_string(Monitoring_coords[gr_screen.res][0], Monitoring_coords[gr_screen.res][1], XSTR( "monitoring", 285));
718 if ( Num_escort_ships >= 2 ) {
719 GR_AABITMAP(Escort_gauges[1].first_frame, Escort_coords[gr_screen.res][1][0], Escort_coords[gr_screen.res][1][1]);
722 if ( Num_escort_ships >= 3 ) {
723 GR_AABITMAP(Escort_gauges[1].first_frame, Escort_coords[gr_screen.res][2][0], Escort_coords[gr_screen.res][2][1]);
726 // draw bottom of box
727 GR_AABITMAP(Escort_gauges[2].first_frame, Escort_coords[gr_screen.res][3][0], Escort_coords[gr_screen.res][Num_escort_ships][1]);
729 // multiplayer dogfight
730 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
731 // draw the escort ship data
732 for ( i = 0; i < Num_escort_ships; i++ ) {
733 // oops. only show top 3
739 hud_escort_show_icon_dogfight(i);
744 // draw the escort ship data
745 for ( i = 0; i < Num_escort_ships; i++ ) {
746 objp = &Objects[Escort_ships[i].objnum];
747 hud_escort_show_icon(i, objp);
752 // ----------------------------------------------------------------------
753 // hud_escort_view_toggle()
755 void hud_escort_view_toggle()
757 Show_escort_view ^= 1;
758 if ( Show_escort_view ) {
759 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Escort view enabled", 286));
761 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Escort view disabled", 287));
765 // try to add a ship to the escort list, if slot available
766 void hud_add_ship_to_escort(int objnum, int supress_feedback)
768 escort_info complete_escorts[MAX_COMPLETE_ESCORT_LIST];
769 int num_complete_escorts, idx, found;
771 // get complete escort list
772 hud_create_complete_escort_list(complete_escorts, &num_complete_escorts);
774 // check if ship is already on complete escort list
776 for (idx=0; idx<num_complete_escorts; idx++) {
777 if (complete_escorts[idx].obj_signature == Objects[objnum].signature) {
783 // add new ship into complete list
785 complete_escorts[num_complete_escorts].objnum = objnum;
786 complete_escorts[num_complete_escorts].obj_signature = Objects[objnum].signature;
787 complete_escorts[num_complete_escorts].priority = Ships[Objects[objnum].instance].escort_priority;
789 // remove him from escort list
790 Ships[Objects[objnum].instance].flags |= SF_ESCORT;
792 num_complete_escorts++;
795 // sort escort list by priority
796 qsort(complete_escorts, num_complete_escorts, sizeof(escort_info), escort_compare_func);
799 merge_escort_lists(complete_escorts, num_complete_escorts);
802 if ( (Num_escort_ships == MAX_ESCORT_SHIPS) && !supress_feedback) {
804 // search thru list for objnum
805 for (idx=0; idx<Num_escort_ships; idx++) {
806 if (Escort_ships[idx].objnum == objnum) {
813 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Escort list is full with %d ships", 288), Num_escort_ships);
814 snd_play( &Snds[SND_TARGET_FAIL]);
818 hud_gauge_popup_start(HUD_ESCORT_VIEW);
822 // ----------------------------------------------------------------------
823 // hud_add_remove_ship_escort()
825 void hud_add_remove_ship_escort(int objnum, int supress_feedback)
829 // no ships on the escort list in multiplayer dogfight
830 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
839 if ( Objects[objnum].type != OBJ_SHIP ) {
840 if ( !supress_feedback ) {
841 snd_play( &Snds[SND_TARGET_FAIL]);
847 for ( i = 0; i < Num_escort_ships; i++ ) {
848 if ( Escort_ships[i].obj_signature == Objects[objnum].signature ) {
855 hud_remove_ship_from_escort_index(i, objnum);
859 hud_add_ship_to_escort(objnum, supress_feedback);
862 void hud_remove_ship_from_escort(int objnum)
866 // no ships on the escort list in multiplayer dogfight
867 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
877 for ( i = 0; i < Num_escort_ships; i++ ) {
878 if ( Escort_ships[i].obj_signature == Objects[objnum].signature ) {
885 hud_remove_ship_from_escort_index(i, objnum);
890 // Called whenever a ship is hit to determine if that ship is in the escort list. If it
891 // is, then start timers to flash the name hull/shield icon for that ship.
892 void hud_escort_ship_hit(object *objp, int quadrant)
895 shield_hit_info *shi;
897 // no ships on the escort list in multiplayer dogfight
898 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)){
902 for ( i = 0; i < Num_escort_ships; i++ ) {
903 if ( Escort_ships[i].objnum == OBJ_INDEX(objp) ) {
904 shi = &Escort_ships[i].hit_info;
905 num = Quadrant_xlate[quadrant];
906 hud_gauge_popup_start(HUD_ESCORT_VIEW);
907 if ( quadrant >= 0 ) {
908 shi->shield_hit_timers[num] = timestamp(SHIELD_HIT_DURATION);
910 shi->shield_hit_timers[HULL_HIT_OFFSET] = timestamp(SHIELD_HIT_DURATION);
916 // target the next ship in the escort list
917 void hud_escort_target_next()
921 if ( Num_escort_ships == 0 ) {
922 snd_play( &Snds[SND_TARGET_FAIL], 0.0f );
927 if ( Last_target_index >= Num_escort_ships ) {
928 Last_target_index = 0;
931 objnum = Escort_ships[Last_target_index].objnum;
932 set_target_objnum( Player_ai, objnum);
933 hud_restore_subsystem_target(&Ships[Objects[objnum].instance]);
936 // return the number of ships currently on the escort list
937 int hud_escort_num_ships_on_list()
939 return Num_escort_ships;
942 // Return the object number for the ship at index position in the escort list
943 int hud_escort_return_objnum(int index)
945 int escort_objnum, escort_sig;
946 if ( index >= Num_escort_ships ) {
950 escort_objnum = Escort_ships[index].objnum;
951 escort_sig = Escort_ships[index].obj_signature;
953 if ( escort_objnum < 0 ) {
957 // ensure this is still a valid index
958 if ( Objects[escort_objnum].signature != escort_sig ) {
962 return Escort_ships[index].objnum;
966 void hudescort_page_in()
970 for ( i = 0; i < MAX_ESCORT_SHIPS; i++ ) {
971 bm_page_in_aabitmap( Escort_gauges[i].first_frame, Escort_gauges[i].num_frames);
975 void hud_escort_add_player(short id)
977 Assert(Game_mode & GM_MULTIPLAYER);
978 if(!(Game_mode & GM_MULTIPLAYER)){
984 // just go through and add as long as its not a duplicate
985 for(idx=0; idx<Num_escort_ships; idx++){
986 if(Escort_ships[idx].np_id == id){
991 // re-setup the escort list
992 hud_setup_escort_list(0);
995 void hud_escort_remove_player(short id)
997 Assert(Game_mode & GM_MULTIPLAYER);
998 if(!(Game_mode & GM_MULTIPLAYER)){
1004 // find the instance and remove it if possible
1005 for(idx=0; idx<Num_escort_ships; idx++){
1006 if(Escort_ships[idx].np_id == id){
1007 hud_remove_ship_from_escort_index(idx, -1);