2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/Network/multi_pinfo.cpp $
16 * Revision 1.3 2002/06/09 04:41:23 relnev
17 * added copyright header
19 * Revision 1.2 2002/05/07 03:16:47 theoddone33
20 * The Great Newline Fix
22 * Revision 1.1.1.1 2002/05/03 03:28:10 root
26 * 15 9/10/99 9:44p Dave
27 * Bumped version # up. Make server reliable connects not have such a huge
30 * 14 8/30/99 5:01p Dave
31 * Made d3d do less state changing in the nebula. Use new chat server for
34 * 13 8/22/99 5:53p Dave
35 * Scoring fixes. Added self destruct key. Put callsigns in the logfile
36 * instead of ship designations for multiplayer players.
38 * 12 8/03/99 11:43a Dave
39 * Don't allow medals button in demo.
41 * 11 7/26/99 11:14a Andsager
42 * Disable medals in demo multiplayer
44 * 10 6/16/99 4:06p Dave
45 * New pilot info popup. Added new draw-bitmap-as-poly function.
47 * 9 1/30/99 1:29a Dave
48 * Fixed nebula thumbnail problem. Full support for 1024x768 choose pilot
49 * screen. Fixed beam weapon death messages.
51 * 8 1/14/99 6:06p Dave
52 * 100% full squad logo support for single player and multiplayer.
54 * 7 1/12/99 4:07a Dave
55 * Put in barracks code support for selecting squad logos. Properly
56 * distribute squad logos in a multiplayer game.
58 * 6 12/14/98 12:13p Dave
59 * Spiffed up xfer system a bit. Put in support for squad logo file xfer.
62 * 5 11/30/98 1:07p Dave
63 * 16 bit conversion, first run.
65 * 4 11/05/98 4:18p Dave
66 * First run nebula support. Beefed up localization a bit. Removed all
67 * conditional compiles for foreign versions. Modified mission file
70 * 3 10/13/98 9:29a Dave
71 * Started neatening up freespace.h. Many variables renamed and
72 * reorganized. Added AlphaColors.[h,cpp]
74 * 2 10/07/98 10:53a Dave
77 * 1 10/07/98 10:50a Dave
86 #include "freespace.h"
87 #include "gamesequence.h"
93 #include "multi_xfer.h"
94 #include "multi_pinfo.h"
95 #include "alphacolors.h"
99 // ---------------------------------------------------------------------------------------
100 // MULTI PLAYER INFO DEFINES/VARS
105 #define MULTI_PINFO_NUM_BUTTONS 4
108 char *Multi_pinfo_bitmap_name[GR_NUM_RESOLUTIONS] = {
112 char *Multi_pinfo_bitmap_mask[GR_NUM_RESOLUTIONS] = {
118 #define MPI_SCROLL_STATS_UP 0
119 #define MPI_SCROLL_STATS_DOWN 1
123 // pilot image area defs
124 int Multi_pinfo_pilot_coords[GR_NUM_RESOLUTIONS][4] = {
132 int Multi_pinfo_squad_coords[GR_NUM_RESOLUTIONS][4] = {
142 typedef struct np_bitmap {
143 int bitmap; // bitmap id
144 char filename[MAX_FILENAME_LEN]; // filename
146 np_bitmap Mp_pilot; // pilot pic
147 np_bitmap Mp_squad; // squad logo
149 UI_WINDOW Multi_pinfo_window; // the window object for the join screen
150 UI_BUTTON Multi_pinfo_select_button; // for selecting list items
151 int Multi_pinfo_bitmap; // the background bitmap
152 ui_button_info Multi_pinfo_buttons[GR_NUM_RESOLUTIONS][MULTI_PINFO_NUM_BUTTONS] = {
154 ui_button_info("PIB_00", 617, 256, -1, -1, 0),
155 ui_button_info("PIB_01", 617, 298, -1, -1, 1),
156 ui_button_info("PIB_02", 172, 322, -1, -1, 2),
157 ui_button_info("PIB_03", 219, 332, 217, 318, 3)
160 ui_button_info("2_PIB_00", 988, 410, -1, -1, 0),
161 ui_button_info("2_PIB_01", 988, 477, -1, -1, 1),
162 ui_button_info("2_PIB_02", 276, 516, -1, -1, 2),
163 ui_button_info("2_PIB_03", 350, 532, 348, 510, 3)
167 #define MULTI_PINFO_NUM_TEXT 1
168 UI_XSTR Multi_pinfo_text[GR_NUM_RESOLUTIONS][MULTI_PINFO_NUM_TEXT] = {
170 { "Close", 428, 217, 318, UI_XSTR_COLOR_PINK, -1, &Multi_pinfo_buttons[0][MPI_EXIT].button },
173 { "Close", 428, 348, 510, UI_XSTR_COLOR_PINK, -1, &Multi_pinfo_buttons[1][MPI_EXIT].button },
180 #define MULTI_PINFO_NUM_STATS_LABELS 9
182 #define MPI_MISSIONS_FLOWN 1
183 #define MPI_FLIGHT_TIME 2
184 #define MPI_LAST_FLOWN 3
185 #define MPI_FIGHTER_KILLS 4
186 // #define MPI_OTHER_KILLS 5
187 #define MPI_PSHOTS_FIRED 5
188 //#define MPI_PSHOTS_HIT 6
189 #define MPI_PSHOTS_PCT 6
190 #define MPI_SSHOTS_FIRED 7
191 // #define MPI_SSHOTS_HIT 10
192 #define MPI_SSHOTS_PCT 8
194 char *Multi_pinfo_stats_labels[MULTI_PINFO_NUM_STATS_LABELS];
196 #define MAX_LABEL_TEXT 50
197 char Multi_pinfo_stats_vals[MULTI_PINFO_NUM_STATS_LABELS][MAX_LABEL_TEXT];
198 int Multi_pinfo_stats_label_offsets[MULTI_PINFO_NUM_STATS_LABELS] = {
199 20,10,10,20,20,10,20,10,10,
203 int Multi_pinfo_stats_area_coords[GR_NUM_RESOLUTIONS][4] = {
211 int Multi_pinfo_stats_x[GR_NUM_RESOLUTIONS] = {
216 // is the popup already running
217 int Multi_pinfo_popup_running = 0;
219 // background bitmap to be blitted
220 int Multi_pinfo_screen_save = -1;
222 // flag indicating if the popup has gotten messed up somewhere and should bail
223 int Multi_pinfo_popup_error = 0;
225 // flag indicating if the popup should be done
226 int Multi_pinfo_popup_done = 0;
228 // player this popup is being used for
229 net_player *Multi_pinfo_popup_player = NULL;
232 extern shader Grey_shader;
234 // hardware textures backup
235 int Multi_pinfo_hardware_texture_backup;
238 // ---------------------------------------------------------------------------------------
239 // MULTI PLAYER INFO FORWARD DECLARATIONS
242 // initialize all popup details (graphics, etc)
243 void multi_pinfo_popup_init(net_player *pl);
245 // run the popup in a tight loop (no states)
246 void multi_pinfo_popup_do();
249 void multi_pinfo_popup_close();
251 // blit the pilot image
252 void multi_pinfo_blit_pilot_image();
254 // blit the pilot squadron logo
255 void multi_pinfo_blit_squadron_logo();
257 // blit the player statistics
258 void multi_pinfo_blit_player_stats();
260 // check for button presses
261 void multi_pinfo_popup_check_buttons();
263 // act on a button press
264 void multi_pinfo_popup_button_pressed(int n);
266 // display the medals screen for this player
267 void multi_pinfo_do_medals();
269 // load up and use the proper palette
270 void multi_pinfo_set_palette();
272 // build the stats value strings for this player
273 void multi_pinfo_build_stats();
275 // if the pilot's image was currently loading when we started the popup, load it up now if its finished
276 void multi_pinfo_maybe_reload_pic(np_bitmap *b);
278 // reset the player infomation for this popup
279 void multi_pinfo_reset_player(net_player *np);
281 // lookup the "previous" player in the netplayer list, return null if not found
282 net_player *multi_pinfo_get_prev_player(net_player *np);
284 // lookup the "next" player in the netplayer list, return null if not found
285 net_player *multi_pinfo_get_next_player(net_player *np);
288 // ---------------------------------------------------------------------------------------
289 // MULTI PLAYER INFO FUNCTIONS
292 // fire up the player info popup, select first available pilot if np == NULL
293 void multi_pinfo_popup(net_player *np)
295 // if the popup is already running, don't do anything
296 if(Multi_pinfo_popup_running){
300 // set the player for informational purposes
303 // play the popup appear sound
304 gamesnd_play_iface(SND_POPUP_APPEAR);
306 // initialize the popup
307 multi_pinfo_popup_init(np);
309 // mark the popup as running
310 Multi_pinfo_popup_running = 1;
313 multi_pinfo_popup_do();
316 multi_pinfo_popup_close();
318 // play the popup disappear sound
319 gamesnd_play_iface(SND_POPUP_DISAPPEAR);
322 // notify the popup that a player has left
323 void multi_pinfo_notify_drop(net_player *np)
327 // if we're no active, bail
328 if(!Multi_pinfo_popup_running){
332 // if this is not the player we're currently displaying, bail
333 if(np != Multi_pinfo_popup_player){
337 // otherwise we need to switch to someone else
338 reset = multi_pinfo_get_prev_player(np);
340 multi_pinfo_reset_player(reset);
343 reset = multi_pinfo_get_next_player(np);
345 multi_pinfo_reset_player(reset);
349 // bail, since there's no one else
351 Multi_pinfo_popup_done = 1;
355 // ---------------------------------------------------------------------------------------
356 // MULTI PLAYER INFO FORWARD DEFINITIONS
359 // initialize all popup details (graphics, etc)
360 void multi_pinfo_popup_init(net_player *np)
364 // no errors to start with
365 Multi_pinfo_popup_error = 0;
368 Multi_pinfo_popup_done = 0;
370 // store the background as it currently is
371 Multi_pinfo_screen_save = gr_save_screen();
372 if(Multi_pinfo_screen_save == -1){
373 Multi_pinfo_popup_error = 1;
377 // create the interface window
378 Multi_pinfo_window.create(0,0,gr_screen.max_w,gr_screen.max_h,0);
379 Multi_pinfo_window.set_mask_bmap(Multi_pinfo_bitmap_mask[gr_screen.res]);
381 // load the background bitmap
382 Multi_pinfo_bitmap = bm_load(Multi_pinfo_bitmap_name[gr_screen.res]);
383 if(Multi_pinfo_bitmap < 0){
384 Multi_pinfo_popup_error = 1;
388 // backup hardware textures setting and bash to max
389 Multi_pinfo_hardware_texture_backup = Detail.hardware_textures;
390 Detail.hardware_textures = MAX_DETAIL_LEVEL;
393 Mp_pilot.bitmap = -1;
394 strcpy(Mp_pilot.filename, "");
395 Mp_squad.bitmap = -1;
396 strcpy(Mp_squad.filename, "");
398 // set the player status
399 multi_pinfo_reset_player(np);
401 // create the interface buttons
402 for(idx=0;idx<MULTI_PINFO_NUM_BUTTONS;idx++){
404 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);
406 // set the sound to play when highlighted
407 Multi_pinfo_buttons[gr_screen.res][idx].button.set_highlight_action(common_play_highlight_sound);
409 // set the ani for the button
410 Multi_pinfo_buttons[gr_screen.res][idx].button.set_bmaps(Multi_pinfo_buttons[gr_screen.res][idx].filename);
413 Multi_pinfo_buttons[gr_screen.res][idx].button.link_hotspot(Multi_pinfo_buttons[gr_screen.res][idx].hotspot);
417 for(idx=0; idx<MULTI_PINFO_NUM_TEXT; idx++){
418 Multi_pinfo_window.add_XSTR(&Multi_pinfo_text[gr_screen.res][idx]);
421 // disable medals button for the demo
423 Multi_pinfo_buttons[gr_screen.res][MPI_MEDALS].button.hide();
424 Multi_pinfo_buttons[gr_screen.res][MPI_MEDALS].button.disable();
427 // initialize strings
428 Multi_pinfo_stats_labels[0] = strdup(XSTR("Rank", 1007));
429 Multi_pinfo_stats_labels[1] = strdup(XSTR("Missions Flown", 1008));
430 Multi_pinfo_stats_labels[2] = strdup(XSTR("Flight Time", 1009));
431 Multi_pinfo_stats_labels[3] = strdup(XSTR("Last Flown",1010));
432 Multi_pinfo_stats_labels[4] = strdup(XSTR("Total Kills", 115));
433 Multi_pinfo_stats_labels[5] = strdup(XSTR("Primary Shots Fired", 1012));
434 Multi_pinfo_stats_labels[6] = strdup(XSTR("Primary Hit %", 1013));
435 Multi_pinfo_stats_labels[7] = strdup(XSTR("Secondary Shots Fired", 1014));
436 Multi_pinfo_stats_labels[8] = strdup(XSTR("Secondary Hit %", 1015));
439 // run the popup in a tight loop (no states)
440 void multi_pinfo_popup_do()
444 // if there was an error in initialization, return immediately
445 if(Multi_pinfo_popup_error){
450 while(!Multi_pinfo_popup_done){
451 multi_pinfo_maybe_reload_pic(&Mp_pilot);
452 multi_pinfo_maybe_reload_pic(&Mp_squad);
454 // process the window
455 k = Multi_pinfo_window.process();
458 Multi_pinfo_popup_done = 1;
462 // check button presses
463 multi_pinfo_popup_check_buttons();
465 // set frametime and run background stuff
466 game_set_frametime(-1);
467 game_do_state_common(gameseq_get_state());
469 // draw the background bitmap and the ui window over it
470 Assert(Multi_pinfo_screen_save != -1);
472 gr_restore_screen(Multi_pinfo_screen_save);
475 gr_set_shader(&Grey_shader);
476 gr_shade(0,0,gr_screen.clip_width, gr_screen.clip_height);
478 // draw the background bitmap
479 gr_set_bitmap(Multi_pinfo_bitmap);
482 // blit the selected pilot image
483 multi_pinfo_blit_pilot_image();
485 // blit the squadron logo
486 multi_pinfo_blit_squadron_logo();
488 // blit the player statistics
489 multi_pinfo_blit_player_stats();
491 // draw the ui window and flip
492 Multi_pinfo_window.draw();
498 void multi_pinfo_popup_close()
502 // unload any bitmaps
503 if(Multi_pinfo_bitmap != -1){
504 bm_release(Multi_pinfo_bitmap);
507 // free the background screen if possible
508 if(Multi_pinfo_screen_save >= 0){
509 gr_free_screen(Multi_pinfo_screen_save);
512 // release the pilot/squad images
513 if(Mp_pilot.bitmap != -1){
514 bm_release(Mp_pilot.bitmap);
516 if(Mp_squad.bitmap != -1){
517 bm_release(Mp_squad.bitmap);
521 for(idx=0; idx<MULTI_PINFO_NUM_STATS_LABELS; idx++){
522 if(Multi_pinfo_stats_labels[idx] != NULL){
523 free(Multi_pinfo_stats_labels[idx]);
524 Multi_pinfo_stats_labels[idx] = NULL;
528 // unset the player handle
529 Multi_pinfo_popup_player = NULL;
531 // mark the popup as not running
532 Multi_pinfo_popup_running = 0;
534 // destroy the UI_WINDOW
535 Multi_pinfo_window.destroy();
537 // restore hardware textures detail level
538 Detail.hardware_textures = Multi_pinfo_hardware_texture_backup;
541 // blit the pilot image
542 void multi_pinfo_blit_pilot_image()
544 char place_text[100];
547 // if we don't have a bitmap handle, blit a placeholder
548 if(Mp_pilot.bitmap == -1){
549 gr_set_color_fast(&Color_normal);
551 // if there is no image
552 if(strlen(Mp_pilot.filename) <= 0){
553 strcpy(place_text,XSTR("No/Invalid Image", 1053));
555 // if the image is xferring
556 else if(multi_xfer_lookup(Mp_pilot.filename)){
557 strcpy(place_text,XSTR("Image Transferring", 691));
559 // if we're not accepting images
560 else if(!(Net_player->p_info.options.flags & MLO_FLAG_ACCEPT_PIX) || !(Netgame.options.flags & MSO_FLAG_ACCEPT_PIX)){
561 strcpy(place_text,XSTR("No Image", 692));
565 strcpy(place_text,XSTR("Waiting", 690));
569 gr_get_string_size(&w,NULL,place_text);
570 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);
572 // otherwise blit the bitmap
574 gr_set_bitmap(Mp_pilot.bitmap);
576 // get width and heigh
578 bm_get_info(Mp_pilot.bitmap, &w, &h, NULL, NULL, NULL, NULL);
580 gr_bitmap(Multi_pinfo_pilot_coords[gr_screen.res][0] + ((Multi_pinfo_pilot_coords[gr_screen.res][2] - w)/2),
581 Multi_pinfo_pilot_coords[gr_screen.res][1] + ((Multi_pinfo_pilot_coords[gr_screen.res][3] - h)/2));
582 // 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]);
586 // blit the pilot squadron logo
587 void multi_pinfo_blit_squadron_logo()
589 char place_text[100];
591 player *p = Multi_pinfo_popup_player->player;
593 // if we don't have a bitmap handle, blit a placeholder
594 if(Mp_squad.bitmap == -1){
595 gr_set_color_fast(&Color_normal);
597 // if there is no image
598 if(strlen(p->squad_filename) <= 0){
599 strcpy(place_text,XSTR("No/Invalid Image", 1053));
601 // if the image is xferring
602 else if(multi_xfer_lookup(p->squad_filename)){
603 strcpy(place_text,XSTR("Image Transferring", 691));
605 // if we're not accepting images
606 else if(!(Net_player->p_info.options.flags & MLO_FLAG_ACCEPT_PIX) || !(Netgame.options.flags & MSO_FLAG_ACCEPT_PIX)){
607 strcpy(place_text,XSTR("No Image", 692));
611 strcpy(place_text,XSTR("Waiting", 690));
615 gr_get_string_size(&w, NULL, place_text);
616 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);
618 // otherwise blit the bitmap
620 gr_set_bitmap(Mp_squad.bitmap);
621 // gr_bitmap(MPI_SQUAD_X, MPI_SQUAD_Y);
623 // get width and heigh
625 bm_get_info(Mp_squad.bitmap, &w, &h, NULL, NULL, NULL, NULL);
627 gr_bitmap(Multi_pinfo_squad_coords[gr_screen.res][0] + ((Multi_pinfo_squad_coords[gr_screen.res][2] - w)/2),
628 Multi_pinfo_squad_coords[gr_screen.res][1] + ((Multi_pinfo_squad_coords[gr_screen.res][3] - h)/2));
629 // 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]);
633 // blit the player statistics
634 void multi_pinfo_blit_player_stats()
638 // blit the player's callsign and "all time stats"
639 gr_set_color_fast(&Color_bright);
640 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);
641 gr_string(Multi_pinfo_stats_x[gr_screen.res], Multi_pinfo_stats_area_coords[gr_screen.res][1], XSTR("All Time Stats", 128));
643 gr_set_color_fast(&Color_normal);
645 // blit all the labels
646 y_start = Multi_pinfo_stats_area_coords[gr_screen.res][1] + 15;
647 for(idx=0;idx<MULTI_PINFO_NUM_STATS_LABELS;idx++){
648 gr_string(Multi_pinfo_stats_area_coords[gr_screen.res][0], y_start, Multi_pinfo_stats_labels[idx]);
649 y_start += Multi_pinfo_stats_label_offsets[idx];
652 // blit all the stats values themselves
653 y_start = Multi_pinfo_stats_area_coords[gr_screen.res][1] + 15;
654 for(idx=0;idx<MULTI_PINFO_NUM_STATS_LABELS;idx++){
655 gr_string(Multi_pinfo_stats_x[gr_screen.res], y_start, Multi_pinfo_stats_vals[idx]);
656 y_start += Multi_pinfo_stats_label_offsets[idx];
660 // check for button presses
661 void multi_pinfo_popup_check_buttons()
665 // check for all buttons
666 for(idx=0;idx<MULTI_PINFO_NUM_BUTTONS;idx++){
667 if(Multi_pinfo_buttons[gr_screen.res][idx].button.pressed()){
668 multi_pinfo_popup_button_pressed(idx);
674 // act on a button press
675 void multi_pinfo_popup_button_pressed(int n)
681 Multi_pinfo_popup_done = 1;
685 gamesnd_play_iface(SND_USER_SELECT);
686 multi_pinfo_do_medals();
689 case MPI_SCROLL_STATS_UP:
690 swap = multi_pinfo_get_prev_player(Multi_pinfo_popup_player);
692 gamesnd_play_iface(SND_USER_SELECT);
693 multi_pinfo_reset_player(swap);
695 gamesnd_play_iface(SND_GENERAL_FAIL);
699 case MPI_SCROLL_STATS_DOWN:
700 swap = multi_pinfo_get_next_player(Multi_pinfo_popup_player);
702 gamesnd_play_iface(SND_USER_SELECT);
703 multi_pinfo_reset_player(swap);
705 gamesnd_play_iface(SND_GENERAL_FAIL);
710 gamesnd_play_iface(SND_GENERAL_FAIL);
715 // display the medals screen for this player
716 void multi_pinfo_do_medals()
719 game_feature_not_in_demo_popup();
723 // initialize the medals screen
724 medal_main_init(Multi_pinfo_popup_player->player,MM_POPUP);
726 // run the medals screen until it says that it should be closed
728 // set frametime and run common functions
729 game_set_frametime(-1);
730 game_do_state_common(gameseq_get_state());
732 // run the medals screen
733 ret_code = medal_main_do();
734 } while(ret_code && !Multi_pinfo_popup_done);
736 // close the medals screen down
739 // restore the proper palette
740 multi_pinfo_set_palette();
744 // load up and use the proper palette
745 void multi_pinfo_set_palette()
747 #ifndef HARDWARE_ONLY
748 palette_use_bm_palette(Multi_pinfo_bitmap);
752 // build the stats value strings for this player
753 void multi_pinfo_build_stats()
756 // int fighter_kills,other_kills;
757 scoring_struct *sc = &Multi_pinfo_popup_player->player->stats;
759 // build alltime fighter and non-fighter kills
763 for(idx=0;idx<MAX_SHIP_TYPES;idx++){
764 if(sc->kills[idx] > 0){
765 if(Ship_info[idx].flags & SIF_FIGHTER){
766 fighter_kills += sc->kills[idx];
768 other_kills += sc->kills[idx];
773 sprintf(Multi_pinfo_stats_vals[MPI_FIGHTER_KILLS], "%d", sc->kill_count);
775 // sprintf(Multi_pinfo_stats_vals[MPI_OTHER_KILLS],"%d",other_kills);
778 sprintf(Multi_pinfo_stats_vals[MPI_MISSIONS_FLOWN],"%d",(int)sc->missions_flown);
781 game_format_time(fl2f((float)sc->flight_time),Multi_pinfo_stats_vals[MPI_FLIGHT_TIME]);
784 if(sc->last_flown == 0){
785 strcpy(Multi_pinfo_stats_vals[MPI_LAST_FLOWN],XSTR("No missions flown",693));
787 tm *tmr = gmtime(&sc->last_flown);
789 strftime(Multi_pinfo_stats_vals[MPI_LAST_FLOWN],MAX_LABEL_TEXT,"%m/%d/%y %H:%M",tmr);
791 strcpy(Multi_pinfo_stats_vals[MPI_LAST_FLOWN], "");
796 strcpy(Multi_pinfo_stats_vals[MPI_RANK],Ranks[sc->rank].name);
798 // primary shots fired
799 sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_FIRED],"%d",sc->p_shots_fired);
802 // sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_HIT],"%d",sc->p_shots_hit);
805 sprintf(Multi_pinfo_stats_vals[MPI_PSHOTS_PCT],"%d%%",(int)(100.0f * ((float)sc->p_shots_hit / (float)sc->p_shots_fired)));
806 // primary shots fired
807 sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_FIRED],"%d",sc->s_shots_fired);
810 // sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_HIT],"%d",sc->s_shots_hit);
813 sprintf(Multi_pinfo_stats_vals[MPI_SSHOTS_PCT],"%d%%",(int)(100.0f * ((float)sc->s_shots_hit / (float)sc->s_shots_fired)));
816 // if the pilot's image was currently loading when we started the popup, load it up now if its finished
817 void multi_pinfo_maybe_reload_pic(np_bitmap *b)
819 // if the bitmap is valid, do nothing
824 // if the local player is not accepting pix or the netgame is not accepting pix, bail here
825 if(!(Net_player->p_info.options.flags & MLO_FLAG_ACCEPT_PIX) || !(Netgame.options.flags & MSO_FLAG_ACCEPT_PIX)){
829 // if the bitmap filename is bogus
830 if(strlen(b->filename) <= 0){
835 b->bitmap = bm_load_duplicate(b->filename);
838 // attempt to validate a bitmap (ie, return whether its displayable or not)
840 int multi_pinfo_validate_bitmap(int bitmap)
844 // if the bitmap handle is invalid false
849 // get the bitmap info
852 bm_get_info(bitmap,&w,&h);
855 if((w != MPI_IMAGE_W) || (h != MPI_IMAGE_H)){
864 // is the pilot info popup currently active?
865 int multi_pinfo_popup_active()
867 return Multi_pinfo_popup_running;
870 // kill the currently active popup (if any)
871 void multi_pinfo_popup_kill()
873 // we're done, byatch
874 Multi_pinfo_popup_done = 1;
877 // reset the player infomation for this popup
878 void multi_pinfo_reset_player(net_player *np)
881 Multi_pinfo_popup_player = np;
883 // unload any old image data if necessary
884 strcpy(Mp_pilot.filename, "");
885 if(Mp_pilot.bitmap != -1){
886 bm_release(Mp_pilot.bitmap);
887 Mp_pilot.bitmap = -1;
889 strcpy(Mp_squad.filename, "");
890 if(Mp_squad.bitmap != -1){
891 bm_release(Mp_squad.bitmap);
892 Mp_squad.bitmap = -1;
895 // try and load pilot pic/squad logo
896 if(strlen(np->player->image_filename) >= 0){
897 strcpy(Mp_pilot.filename, np->player->image_filename);
898 Mp_pilot.bitmap = bm_load_duplicate(Mp_pilot.filename);
900 if(strlen(np->player->squad_filename) >= 0){
901 strcpy(Mp_squad.filename, np->player->squad_filename);
902 Mp_squad.bitmap = bm_load_duplicate(Mp_squad.filename);
905 // build the stats value strings for this player
906 multi_pinfo_build_stats();
909 // lookup the "previous" player in the netplayer list, return null if not found
910 net_player *multi_pinfo_get_prev_player(net_player *np)
915 // get the starting index to look from
916 start_index = NET_PLAYER_INDEX(np);
919 for(idx=start_index-1; idx>=0; idx--){
920 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx])){
921 return &Net_players[idx];
929 // lookup the "next" player in the netplayer list, return null if not found
930 net_player *multi_pinfo_get_next_player(net_player *np)
935 // get the starting index to look from
936 start_index = NET_PLAYER_INDEX(np);
937 if(start_index < (MAX_PLAYERS - 1)){
939 for(idx=start_index+1; idx<MAX_PLAYERS; idx++){
940 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx])){
941 return &Net_players[idx];