2 * $Logfile: /Freespace2/code/Network/multi_pinfo.cpp $
8 * Revision 1.1 2002/05/03 03:28:10 root
12 * 15 9/10/99 9:44p Dave
13 * Bumped version # up. Make server reliable connects not have such a huge
16 * 14 8/30/99 5:01p Dave
17 * Made d3d do less state changing in the nebula. Use new chat server for
20 * 13 8/22/99 5:53p Dave
21 * Scoring fixes. Added self destruct key. Put callsigns in the logfile
22 * instead of ship designations for multiplayer players.
24 * 12 8/03/99 11:43a Dave
25 * Don't allow medals button in demo.
27 * 11 7/26/99 11:14a Andsager
28 * Disable medals in demo multiplayer
30 * 10 6/16/99 4:06p Dave
31 * New pilot info popup. Added new draw-bitmap-as-poly function.
33 * 9 1/30/99 1:29a Dave
34 * Fixed nebula thumbnail problem. Full support for 1024x768 choose pilot
35 * screen. Fixed beam weapon death messages.
37 * 8 1/14/99 6:06p Dave
38 * 100% full squad logo support for single player and multiplayer.
40 * 7 1/12/99 4:07a Dave
41 * Put in barracks code support for selecting squad logos. Properly
42 * distribute squad logos in a multiplayer game.
44 * 6 12/14/98 12:13p Dave
45 * Spiffed up xfer system a bit. Put in support for squad logo file xfer.
48 * 5 11/30/98 1:07p Dave
49 * 16 bit conversion, first run.
51 * 4 11/05/98 4:18p Dave
52 * First run nebula support. Beefed up localization a bit. Removed all
53 * conditional compiles for foreign versions. Modified mission file
56 * 3 10/13/98 9:29a Dave
57 * Started neatening up freespace.h. Many variables renamed and
58 * reorganized. Added AlphaColors.[h,cpp]
60 * 2 10/07/98 10:53a Dave
63 * 1 10/07/98 10:50a Dave
72 #include "freespace.h"
73 #include "gamesequence.h"
79 #include "multi_xfer.h"
80 #include "multi_pinfo.h"
81 #include "alphacolors.h"
85 // ---------------------------------------------------------------------------------------
86 // MULTI PLAYER INFO DEFINES/VARS
91 #define MULTI_PINFO_NUM_BUTTONS 4
94 char *Multi_pinfo_bitmap_name[GR_NUM_RESOLUTIONS] = {
98 char *Multi_pinfo_bitmap_mask[GR_NUM_RESOLUTIONS] = {
104 #define MPI_SCROLL_STATS_UP 0
105 #define MPI_SCROLL_STATS_DOWN 1
109 // pilot image area defs
110 int Multi_pinfo_pilot_coords[GR_NUM_RESOLUTIONS][4] = {
118 int Multi_pinfo_squad_coords[GR_NUM_RESOLUTIONS][4] = {
128 typedef struct np_bitmap {
129 int bitmap; // bitmap id
130 char filename[MAX_FILENAME_LEN]; // filename
132 np_bitmap Mp_pilot; // pilot pic
133 np_bitmap Mp_squad; // squad logo
135 UI_WINDOW Multi_pinfo_window; // the window object for the join screen
136 UI_BUTTON Multi_pinfo_select_button; // for selecting list items
137 int Multi_pinfo_bitmap; // the background bitmap
138 ui_button_info Multi_pinfo_buttons[GR_NUM_RESOLUTIONS][MULTI_PINFO_NUM_BUTTONS] = {
140 ui_button_info("PIB_00", 617, 256, -1, -1, 0),
141 ui_button_info("PIB_01", 617, 298, -1, -1, 1),
142 ui_button_info("PIB_02", 172, 322, -1, -1, 2),
143 ui_button_info("PIB_03", 219, 332, 217, 318, 3)
146 ui_button_info("2_PIB_00", 988, 410, -1, -1, 0),
147 ui_button_info("2_PIB_01", 988, 477, -1, -1, 1),
148 ui_button_info("2_PIB_02", 276, 516, -1, -1, 2),
149 ui_button_info("2_PIB_03", 350, 532, 348, 510, 3)
153 #define MULTI_PINFO_NUM_TEXT 1
154 UI_XSTR Multi_pinfo_text[GR_NUM_RESOLUTIONS][MULTI_PINFO_NUM_TEXT] = {
156 { "Close", 428, 217, 318, UI_XSTR_COLOR_PINK, -1, &Multi_pinfo_buttons[0][MPI_EXIT].button },
159 { "Close", 428, 348, 510, UI_XSTR_COLOR_PINK, -1, &Multi_pinfo_buttons[1][MPI_EXIT].button },
166 #define MULTI_PINFO_NUM_STATS_LABELS 9
168 #define MPI_MISSIONS_FLOWN 1
169 #define MPI_FLIGHT_TIME 2
170 #define MPI_LAST_FLOWN 3
171 #define MPI_FIGHTER_KILLS 4
172 // #define MPI_OTHER_KILLS 5
173 #define MPI_PSHOTS_FIRED 5
174 //#define MPI_PSHOTS_HIT 6
175 #define MPI_PSHOTS_PCT 6
176 #define MPI_SSHOTS_FIRED 7
177 // #define MPI_SSHOTS_HIT 10
178 #define MPI_SSHOTS_PCT 8
180 char *Multi_pinfo_stats_labels[MULTI_PINFO_NUM_STATS_LABELS];
182 #define MAX_LABEL_TEXT 50
183 char Multi_pinfo_stats_vals[MULTI_PINFO_NUM_STATS_LABELS][MAX_LABEL_TEXT];
184 int Multi_pinfo_stats_label_offsets[MULTI_PINFO_NUM_STATS_LABELS] = {
185 20,10,10,20,20,10,20,10,10,
189 int Multi_pinfo_stats_area_coords[GR_NUM_RESOLUTIONS][4] = {
197 int Multi_pinfo_stats_x[GR_NUM_RESOLUTIONS] = {
202 // is the popup already running
203 int Multi_pinfo_popup_running = 0;
205 // background bitmap to be blitted
206 int Multi_pinfo_screen_save = -1;
208 // flag indicating if the popup has gotten messed up somewhere and should bail
209 int Multi_pinfo_popup_error = 0;
211 // flag indicating if the popup should be done
212 int Multi_pinfo_popup_done = 0;
214 // player this popup is being used for
215 net_player *Multi_pinfo_popup_player = NULL;
218 extern shader Grey_shader;
220 // hardware textures backup
221 int Multi_pinfo_hardware_texture_backup;
224 // ---------------------------------------------------------------------------------------
225 // MULTI PLAYER INFO FORWARD DECLARATIONS
228 // initialize all popup details (graphics, etc)
229 void multi_pinfo_popup_init(net_player *pl);
231 // run the popup in a tight loop (no states)
232 void multi_pinfo_popup_do();
235 void multi_pinfo_popup_close();
237 // blit the pilot image
238 void multi_pinfo_blit_pilot_image();
240 // blit the pilot squadron logo
241 void multi_pinfo_blit_squadron_logo();
243 // blit the player statistics
244 void multi_pinfo_blit_player_stats();
246 // check for button presses
247 void multi_pinfo_popup_check_buttons();
249 // act on a button press
250 void multi_pinfo_popup_button_pressed(int n);
252 // display the medals screen for this player
253 void multi_pinfo_do_medals();
255 // load up and use the proper palette
256 void multi_pinfo_set_palette();
258 // build the stats value strings for this player
259 void multi_pinfo_build_stats();
261 // if the pilot's image was currently loading when we started the popup, load it up now if its finished
262 void multi_pinfo_maybe_reload_pic(np_bitmap *b);
264 // reset the player infomation for this popup
265 void multi_pinfo_reset_player(net_player *np);
267 // lookup the "previous" player in the netplayer list, return null if not found
268 net_player *multi_pinfo_get_prev_player(net_player *np);
270 // lookup the "next" player in the netplayer list, return null if not found
271 net_player *multi_pinfo_get_next_player(net_player *np);
274 // ---------------------------------------------------------------------------------------
275 // MULTI PLAYER INFO FUNCTIONS
278 // fire up the player info popup, select first available pilot if np == NULL
279 void multi_pinfo_popup(net_player *np)
281 // if the popup is already running, don't do anything
282 if(Multi_pinfo_popup_running){
286 // set the player for informational purposes
289 // play the popup appear sound
290 gamesnd_play_iface(SND_POPUP_APPEAR);
292 // initialize the popup
293 multi_pinfo_popup_init(np);
295 // mark the popup as running
296 Multi_pinfo_popup_running = 1;
299 multi_pinfo_popup_do();
302 multi_pinfo_popup_close();
304 // play the popup disappear sound
305 gamesnd_play_iface(SND_POPUP_DISAPPEAR);
308 // notify the popup that a player has left
309 void multi_pinfo_notify_drop(net_player *np)
313 // if we're no active, bail
314 if(!Multi_pinfo_popup_running){
318 // if this is not the player we're currently displaying, bail
319 if(np != Multi_pinfo_popup_player){
323 // otherwise we need to switch to someone else
324 reset = multi_pinfo_get_prev_player(np);
326 multi_pinfo_reset_player(reset);
329 reset = multi_pinfo_get_next_player(np);
331 multi_pinfo_reset_player(reset);
335 // bail, since there's no one else
337 Multi_pinfo_popup_done = 1;
341 // ---------------------------------------------------------------------------------------
342 // MULTI PLAYER INFO FORWARD DEFINITIONS
345 // initialize all popup details (graphics, etc)
346 void multi_pinfo_popup_init(net_player *np)
350 // no errors to start with
351 Multi_pinfo_popup_error = 0;
354 Multi_pinfo_popup_done = 0;
356 // store the background as it currently is
357 Multi_pinfo_screen_save = gr_save_screen();
358 if(Multi_pinfo_screen_save == -1){
359 Multi_pinfo_popup_error = 1;
363 // create the interface window
364 Multi_pinfo_window.create(0,0,gr_screen.max_w,gr_screen.max_h,0);
365 Multi_pinfo_window.set_mask_bmap(Multi_pinfo_bitmap_mask[gr_screen.res]);
367 // load the background bitmap
368 Multi_pinfo_bitmap = bm_load(Multi_pinfo_bitmap_name[gr_screen.res]);
369 if(Multi_pinfo_bitmap < 0){
370 Multi_pinfo_popup_error = 1;
374 // backup hardware textures setting and bash to max
375 Multi_pinfo_hardware_texture_backup = Detail.hardware_textures;
376 Detail.hardware_textures = MAX_DETAIL_LEVEL;
379 Mp_pilot.bitmap = -1;
380 strcpy(Mp_pilot.filename, "");
381 Mp_squad.bitmap = -1;
382 strcpy(Mp_squad.filename, "");
384 // set the player status
385 multi_pinfo_reset_player(np);
387 // create the interface buttons
388 for(idx=0;idx<MULTI_PINFO_NUM_BUTTONS;idx++){
390 Multi_pinfo_buttons[gr_screen.res][idx].button.create(&Multi_pinfo_window, "", Multi_pinfo_buttons[gr_screen.res][idx].x, Multi_pinfo_buttons[gr_screen.res][idx].y, 1, 1, 0, 1);
392 // set the sound to play when highlighted
393 Multi_pinfo_buttons[gr_screen.res][idx].button.set_highlight_action(common_play_highlight_sound);
395 // set the ani for the button
396 Multi_pinfo_buttons[gr_screen.res][idx].button.set_bmaps(Multi_pinfo_buttons[gr_screen.res][idx].filename);
399 Multi_pinfo_buttons[gr_screen.res][idx].button.link_hotspot(Multi_pinfo_buttons[gr_screen.res][idx].hotspot);
403 for(idx=0; idx<MULTI_PINFO_NUM_TEXT; idx++){
404 Multi_pinfo_window.add_XSTR(&Multi_pinfo_text[gr_screen.res][idx]);
407 // disable medals button for the demo
409 Multi_pinfo_buttons[gr_screen.res][MPI_MEDALS].button.hide();
410 Multi_pinfo_buttons[gr_screen.res][MPI_MEDALS].button.disable();
413 // initialize strings
414 Multi_pinfo_stats_labels[0] = strdup(XSTR("Rank", 1007));
415 Multi_pinfo_stats_labels[1] = strdup(XSTR("Missions Flown", 1008));
416 Multi_pinfo_stats_labels[2] = strdup(XSTR("Flight Time", 1009));
417 Multi_pinfo_stats_labels[3] = strdup(XSTR("Last Flown",1010));
418 Multi_pinfo_stats_labels[4] = strdup(XSTR("Total Kills", 115));
419 Multi_pinfo_stats_labels[5] = strdup(XSTR("Primary Shots Fired", 1012));
420 Multi_pinfo_stats_labels[6] = strdup(XSTR("Primary Hit %", 1013));
421 Multi_pinfo_stats_labels[7] = strdup(XSTR("Secondary Shots Fired", 1014));
422 Multi_pinfo_stats_labels[8] = strdup(XSTR("Secondary Hit %", 1015));
425 // run the popup in a tight loop (no states)
426 void multi_pinfo_popup_do()
430 // if there was an error in initialization, return immediately
431 if(Multi_pinfo_popup_error){
436 while(!Multi_pinfo_popup_done){
437 multi_pinfo_maybe_reload_pic(&Mp_pilot);
438 multi_pinfo_maybe_reload_pic(&Mp_squad);
440 // process the window
441 k = Multi_pinfo_window.process();
444 Multi_pinfo_popup_done = 1;
448 // check button presses
449 multi_pinfo_popup_check_buttons();
451 // set frametime and run background stuff
452 game_set_frametime(-1);
453 game_do_state_common(gameseq_get_state());
455 // draw the background bitmap and the ui window over it
456 Assert(Multi_pinfo_screen_save != -1);
458 gr_restore_screen(Multi_pinfo_screen_save);
461 gr_set_shader(&Grey_shader);
462 gr_shade(0,0,gr_screen.clip_width, gr_screen.clip_height);
464 // draw the background bitmap
465 gr_set_bitmap(Multi_pinfo_bitmap);
468 // blit the selected pilot image
469 multi_pinfo_blit_pilot_image();
471 // blit the squadron logo
472 multi_pinfo_blit_squadron_logo();
474 // blit the player statistics
475 multi_pinfo_blit_player_stats();
477 // draw the ui window and flip
478 Multi_pinfo_window.draw();
484 void multi_pinfo_popup_close()
488 // unload any bitmaps
489 if(Multi_pinfo_bitmap != -1){
490 bm_release(Multi_pinfo_bitmap);
493 // free the background screen if possible
494 if(Multi_pinfo_screen_save >= 0){
495 gr_free_screen(Multi_pinfo_screen_save);
498 // release the pilot/squad images
499 if(Mp_pilot.bitmap != -1){
500 bm_release(Mp_pilot.bitmap);
502 if(Mp_squad.bitmap != -1){
503 bm_release(Mp_squad.bitmap);
507 for(idx=0; idx<MULTI_PINFO_NUM_STATS_LABELS; idx++){
508 if(Multi_pinfo_stats_labels[idx] != NULL){
509 free(Multi_pinfo_stats_labels[idx]);
510 Multi_pinfo_stats_labels[idx] = NULL;
514 // unset the player handle
515 Multi_pinfo_popup_player = NULL;
517 // mark the popup as not running
518 Multi_pinfo_popup_running = 0;
520 // destroy the UI_WINDOW
521 Multi_pinfo_window.destroy();
523 // restore hardware textures detail level
524 Detail.hardware_textures = Multi_pinfo_hardware_texture_backup;
527 // blit the pilot image
528 void multi_pinfo_blit_pilot_image()
530 char place_text[100];
533 // if we don't have a bitmap handle, blit a placeholder
534 if(Mp_pilot.bitmap == -1){
535 gr_set_color_fast(&Color_normal);
537 // if there is no image
538 if(strlen(Mp_pilot.filename) <= 0){
539 strcpy(place_text,XSTR("No/Invalid Image", 1053));
541 // if the image is xferring
542 else if(multi_xfer_lookup(Mp_pilot.filename)){
543 strcpy(place_text,XSTR("Image Transferring", 691));
545 // if we're not accepting images
546 else if(!(Net_player->p_info.options.flags & MLO_FLAG_ACCEPT_PIX) || !(Netgame.options.flags & MSO_FLAG_ACCEPT_PIX)){
547 strcpy(place_text,XSTR("No Image", 692));
551 strcpy(place_text,XSTR("Waiting", 690));
555 gr_get_string_size(&w,NULL,place_text);
556 gr_string(Multi_pinfo_pilot_coords[gr_screen.res][0] + ((Multi_pinfo_pilot_coords[gr_screen.res][2] - w)/2), Multi_pinfo_pilot_coords[gr_screen.res][1], place_text);
558 // otherwise blit the bitmap
560 gr_set_bitmap(Mp_pilot.bitmap);
562 // get width and heigh
564 bm_get_info(Mp_pilot.bitmap, &w, &h, NULL, NULL, NULL, NULL);
566 gr_bitmap(Multi_pinfo_pilot_coords[gr_screen.res][0] + ((Multi_pinfo_pilot_coords[gr_screen.res][2] - w)/2),
567 Multi_pinfo_pilot_coords[gr_screen.res][1] + ((Multi_pinfo_pilot_coords[gr_screen.res][3] - h)/2));
568 // g3_draw_2d_poly_bitmap(Multi_pinfo_pilot_coords[gr_screen.res][0], Multi_pinfo_pilot_coords[gr_screen.res][1], Multi_pinfo_pilot_coords[gr_screen.res][2], Multi_pinfo_pilot_coords[gr_screen.res][3]);
572 // blit the pilot squadron logo
573 void multi_pinfo_blit_squadron_logo()
575 char place_text[100];
577 player *p = Multi_pinfo_popup_player->player;
579 // if we don't have a bitmap handle, blit a placeholder
580 if(Mp_squad.bitmap == -1){
581 gr_set_color_fast(&Color_normal);
583 // if there is no image
584 if(strlen(p->squad_filename) <= 0){
585 strcpy(place_text,XSTR("No/Invalid Image", 1053));
587 // if the image is xferring
588 else if(multi_xfer_lookup(p->squad_filename)){
589 strcpy(place_text,XSTR("Image Transferring", 691));
591 // if we're not accepting images
592 else if(!(Net_player->p_info.options.flags & MLO_FLAG_ACCEPT_PIX) || !(Netgame.options.flags & MSO_FLAG_ACCEPT_PIX)){
593 strcpy(place_text,XSTR("No Image", 692));
597 strcpy(place_text,XSTR("Waiting", 690));
601 gr_get_string_size(&w, NULL, place_text);
602 gr_string(Multi_pinfo_squad_coords[gr_screen.res][0] + ((Multi_pinfo_squad_coords[gr_screen.res][2] - w)/2), Multi_pinfo_squad_coords[gr_screen.res][1], place_text);
604 // otherwise blit the bitmap
606 gr_set_bitmap(Mp_squad.bitmap);
607 // gr_bitmap(MPI_SQUAD_X, MPI_SQUAD_Y);
609 // get width and heigh
611 bm_get_info(Mp_squad.bitmap, &w, &h, NULL, NULL, NULL, NULL);
613 gr_bitmap(Multi_pinfo_squad_coords[gr_screen.res][0] + ((Multi_pinfo_squad_coords[gr_screen.res][2] - w)/2),
614 Multi_pinfo_squad_coords[gr_screen.res][1] + ((Multi_pinfo_squad_coords[gr_screen.res][3] - h)/2));
615 // g3_draw_2d_poly_bitmap(Multi_pinfo_squad_coords[gr_screen.res][0], Multi_pinfo_squad_coords[gr_screen.res][1], Multi_pinfo_squad_coords[gr_screen.res][2], Multi_pinfo_squad_coords[gr_screen.res][3]);
619 // blit the player statistics
620 void multi_pinfo_blit_player_stats()
624 // blit the player's callsign and "all time stats"
625 gr_set_color_fast(&Color_bright);
626 gr_string(Multi_pinfo_stats_area_coords[gr_screen.res][0], Multi_pinfo_stats_area_coords[gr_screen.res][1], Multi_pinfo_popup_player->player->callsign);
627 gr_string(Multi_pinfo_stats_x[gr_screen.res], Multi_pinfo_stats_area_coords[gr_screen.res][1], XSTR("All Time Stats", 128));
629 gr_set_color_fast(&Color_normal);
631 // blit all the labels
632 y_start = Multi_pinfo_stats_area_coords[gr_screen.res][1] + 15;
633 for(idx=0;idx<MULTI_PINFO_NUM_STATS_LABELS;idx++){
634 gr_string(Multi_pinfo_stats_area_coords[gr_screen.res][0], y_start, Multi_pinfo_stats_labels[idx]);
635 y_start += Multi_pinfo_stats_label_offsets[idx];
638 // blit all the stats values themselves
639 y_start = Multi_pinfo_stats_area_coords[gr_screen.res][1] + 15;
640 for(idx=0;idx<MULTI_PINFO_NUM_STATS_LABELS;idx++){
641 gr_string(Multi_pinfo_stats_x[gr_screen.res], y_start, Multi_pinfo_stats_vals[idx]);
642 y_start += Multi_pinfo_stats_label_offsets[idx];
646 // check for button presses
647 void multi_pinfo_popup_check_buttons()
651 // check for all buttons
652 for(idx=0;idx<MULTI_PINFO_NUM_BUTTONS;idx++){
653 if(Multi_pinfo_buttons[gr_screen.res][idx].button.pressed()){
654 multi_pinfo_popup_button_pressed(idx);
660 // act on a button press
661 void multi_pinfo_popup_button_pressed(int n)
667 Multi_pinfo_popup_done = 1;
671 gamesnd_play_iface(SND_USER_SELECT);
672 multi_pinfo_do_medals();
675 case MPI_SCROLL_STATS_UP:
676 swap = multi_pinfo_get_prev_player(Multi_pinfo_popup_player);
678 gamesnd_play_iface(SND_USER_SELECT);
679 multi_pinfo_reset_player(swap);
681 gamesnd_play_iface(SND_GENERAL_FAIL);
685 case MPI_SCROLL_STATS_DOWN:
686 swap = multi_pinfo_get_next_player(Multi_pinfo_popup_player);
688 gamesnd_play_iface(SND_USER_SELECT);
689 multi_pinfo_reset_player(swap);
691 gamesnd_play_iface(SND_GENERAL_FAIL);
696 gamesnd_play_iface(SND_GENERAL_FAIL);
701 // display the medals screen for this player
702 void multi_pinfo_do_medals()
705 game_feature_not_in_demo_popup();
709 // initialize the medals screen
710 medal_main_init(Multi_pinfo_popup_player->player,MM_POPUP);
712 // run the medals screen until it says that it should be closed
714 // set frametime and run common functions
715 game_set_frametime(-1);
716 game_do_state_common(gameseq_get_state());
718 // run the medals screen
719 ret_code = medal_main_do();
720 } while(ret_code && !Multi_pinfo_popup_done);
722 // close the medals screen down
725 // restore the proper palette
726 multi_pinfo_set_palette();
730 // load up and use the proper palette
731 void multi_pinfo_set_palette()
733 #ifndef HARDWARE_ONLY
734 palette_use_bm_palette(Multi_pinfo_bitmap);
738 // build the stats value strings for this player
739 void multi_pinfo_build_stats()
742 // int fighter_kills,other_kills;
743 scoring_struct *sc = &Multi_pinfo_popup_player->player->stats;
745 // build alltime fighter and non-fighter kills
749 for(idx=0;idx<MAX_SHIP_TYPES;idx++){
750 if(sc->kills[idx] > 0){
751 if(Ship_info[idx].flags & SIF_FIGHTER){
752 fighter_kills += sc->kills[idx];
754 other_kills += sc->kills[idx];
759 sprintf(Multi_pinfo_stats_vals[MPI_FIGHTER_KILLS], "%d", sc->kill_count);
761 // sprintf(Multi_pinfo_stats_vals[MPI_OTHER_KILLS],"%d",other_kills);
764 sprintf(Multi_pinfo_stats_vals[MPI_MISSIONS_FLOWN],"%d",(int)sc->missions_flown);
767 game_format_time(fl2f((float)sc->flight_time),Multi_pinfo_stats_vals[MPI_FLIGHT_TIME]);
770 if(sc->last_flown == 0){
771 strcpy(Multi_pinfo_stats_vals[MPI_LAST_FLOWN],XSTR("No missions flown",693));
773 tm *tmr = gmtime(&sc->last_flown);
775 strftime(Multi_pinfo_stats_vals[MPI_LAST_FLOWN],MAX_LABEL_TEXT,"%m/%d/%y %H:%M",tmr);
777 strcpy(Multi_pinfo_stats_vals[MPI_LAST_FLOWN], "");
782 strcpy(Multi_pinfo_stats_vals[MPI_RANK],Ranks[sc->rank].name);
784 // primary shots fired
785 sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_FIRED],"%d",sc->p_shots_fired);
788 // sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_HIT],"%d",sc->p_shots_hit);
791 sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_PCT],"%d%%",(int)(100.0f * ((float)sc->p_shots_hit / (float)sc->p_shots_fired)));
792 // primary shots fired
793 sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_FIRED],"%d",sc->s_shots_fired);
796 // sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_HIT],"%d",sc->s_shots_hit);
799 sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_PCT],"%d%%",(int)(100.0f * ((float)sc->s_shots_hit / (float)sc->s_shots_fired)));
802 // if the pilot's image was currently loading when we started the popup, load it up now if its finished
803 void multi_pinfo_maybe_reload_pic(np_bitmap *b)
805 // if the bitmap is valid, do nothing
810 // if the local player is not accepting pix or the netgame is not accepting pix, bail here
811 if(!(Net_player->p_info.options.flags & MLO_FLAG_ACCEPT_PIX) || !(Netgame.options.flags & MSO_FLAG_ACCEPT_PIX)){
815 // if the bitmap filename is bogus
816 if(strlen(b->filename) <= 0){
821 b->bitmap = bm_load_duplicate(b->filename);
824 // attempt to validate a bitmap (ie, return whether its displayable or not)
826 int multi_pinfo_validate_bitmap(int bitmap)
830 // if the bitmap handle is invalid false
835 // get the bitmap info
838 bm_get_info(bitmap,&w,&h);
841 if((w != MPI_IMAGE_W) || (h != MPI_IMAGE_H)){
850 // is the pilot info popup currently active?
851 int multi_pinfo_popup_active()
853 return Multi_pinfo_popup_running;
856 // kill the currently active popup (if any)
857 void multi_pinfo_popup_kill()
859 // we're done, byatch
860 Multi_pinfo_popup_done = 1;
863 // reset the player infomation for this popup
864 void multi_pinfo_reset_player(net_player *np)
867 Multi_pinfo_popup_player = np;
869 // unload any old image data if necessary
870 strcpy(Mp_pilot.filename, "");
871 if(Mp_pilot.bitmap != -1){
872 bm_release(Mp_pilot.bitmap);
873 Mp_pilot.bitmap = -1;
875 strcpy(Mp_squad.filename, "");
876 if(Mp_squad.bitmap != -1){
877 bm_release(Mp_squad.bitmap);
878 Mp_squad.bitmap = -1;
881 // try and load pilot pic/squad logo
882 if(strlen(np->player->image_filename) >= 0){
883 strcpy(Mp_pilot.filename, np->player->image_filename);
884 Mp_pilot.bitmap = bm_load_duplicate(Mp_pilot.filename);
886 if(strlen(np->player->squad_filename) >= 0){
887 strcpy(Mp_squad.filename, np->player->squad_filename);
888 Mp_squad.bitmap = bm_load_duplicate(Mp_squad.filename);
891 // build the stats value strings for this player
892 multi_pinfo_build_stats();
895 // lookup the "previous" player in the netplayer list, return null if not found
896 net_player *multi_pinfo_get_prev_player(net_player *np)
901 // get the starting index to look from
902 start_index = NET_PLAYER_INDEX(np);
905 for(idx=start_index-1; idx>=0; idx--){
906 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx])){
907 return &Net_players[idx];
915 // lookup the "next" player in the netplayer list, return null if not found
916 net_player *multi_pinfo_get_next_player(net_player *np)
921 // get the starting index to look from
922 start_index = NET_PLAYER_INDEX(np);
923 if(start_index < (MAX_PLAYERS - 1)){
925 for(idx=start_index+1; idx<MAX_PLAYERS; idx++){
926 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx])){
927 return &Net_players[idx];