예제 #1
0
void pilot_set_short_callsign(player *p, int max_width)
{
	strcpy_s(p->short_callsign, p->callsign);
	gr_set_font(FONT1);
	gr_force_fit_string(p->short_callsign, CALLSIGN_LEN - 1, max_width);
	gr_get_string_size( &(p->short_callsign_width), NULL, p->short_callsign );
}
예제 #2
0
// draw the shield icon and integrity for the escort ship
void hud_escort_show_icon(int x, int y, int index)
{
#ifndef NEW_HUD
	if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT) && index <= 2)
	{
		hud_escort_show_icon_dogfight(x, y, index);
		return;
	}

	float	shields, integrity;
	int		screen_integrity, offset;
	char	buf[255];

	object	*objp	= &Objects[Escort_ships[index].objnum];
	ship	*sp		= &Ships[objp->instance];

	// determine if its "friendly" or not	
	// Goober5000 - changed in favor of just passing the team
	hud_escort_set_gauge_color(index, sp->team);
	/*
	if(Player_ship != NULL){
		hud_escort_set_gauge_color(index, (sp->team == Player_ship->team) ? 1 : 0);
	} else {
		hud_escort_set_gauge_color(index, 1);
	}
	*/

	// draw a 'D' if a ship is disabled
	if ( (sp->flags & SF_DISABLED) || (ship_subsys_disrupted(sp, SUBSYSTEM_ENGINE)) ) {		
		emp_hud_string( x + current_hud->Escort_status[0], y + current_hud->Escort_status[1], EG_NULL, XSTR( "D", 284));				
	}

	// print out ship name
	strcpy(buf, sp->ship_name);
	gr_force_fit_string(buf, 255, 100);	
	
	emp_hud_string( x + current_hud->Escort_name[0], y + current_hud->Escort_name[1], EG_ESCORT1 + index, buf);	

	// show ship integrity
	hud_get_target_strength(objp, &shields, &integrity);
	screen_integrity = fl2i(integrity*100 + 0.5f);
	offset = 0;
	if ( screen_integrity < 100 ) {
		offset = 2;
		if ( screen_integrity == 0 ) {
			if ( integrity > 0 ) {
				screen_integrity = 1;
			}
		}
	}
	emp_hud_printf( x+current_hud->Escort_integrity[0] + offset, y+current_hud->Escort_integrity[1], EG_NULL, "%d", screen_integrity);

	//Let's be nice.
	hud_set_gauge_color(HUD_ESCORT_VIEW);
#endif
}
// draw the shield icon and integrity for the escort ship
void HudGaugeEscort::renderIcon(int x, int y, int index)
{
	if(MULTI_DOGFIGHT && index <= 2)
	{
		renderIconDogfight(x, y, index);
		return;
	}

	float	shields, integrity;
	int		screen_integrity, offset;
	char	buf[255];

	object	*objp	= &Objects[Escort_ships[index].objnum];
	ship	*sp		= &Ships[objp->instance];

	// determine if its "friendly" or not	
	// Goober5000 - changed in favor of just passing the team
	setGaugeColorEscort(index, sp->team);
	/*
	if(Player_ship != NULL){
		hud_escort_set_gauge_color(index, (sp->team == Player_ship->team) ? 1 : 0);
	} else {
		hud_escort_set_gauge_color(index, 1);
	}
	*/

	// draw a 'D' if a ship is disabled
	if ( (sp->flags & SF_DISABLED) || (ship_subsys_disrupted(sp, SUBSYSTEM_ENGINE)) ) {		
		renderString( x + ship_status_offsets[0], y + ship_status_offsets[1], EG_NULL, XSTR( "D", 284));				
	}

	// print out ship name
	strcpy_s(buf, sp->ship_name);
	gr_force_fit_string(buf, 255, ship_name_max_width);	
    end_string_at_first_hash_symbol(buf);
	
	renderString( x + ship_name_offsets[0], y + ship_name_offsets[1], EG_ESCORT1 + index, buf);	

	// show ship integrity
	hud_get_target_strength(objp, &shields, &integrity);
	screen_integrity = fl2i(integrity*100 + 0.5f);
	offset = 0;
	if ( screen_integrity < 100 ) {
		offset = 2;
		if ( screen_integrity == 0 ) {
			if ( integrity > 0 ) {
				screen_integrity = 1;
			}
		}
	}
	renderPrintf( x+ship_integrity_offsets[0] + offset, y+ship_integrity_offsets[1], EG_NULL, "%d", screen_integrity);

	//Let's be nice.
	setGaugeColor();
}
예제 #4
0
// renders the stuff common to all 3 tech room tabs
void tech_common_render()
{
	char buf[256];
	int y, z, font_height;

	// render description in its box
	gr_set_color_fast(&Color_text_normal);
	techroom_render_desc(Tech_desc_coords[gr_screen.res][SHIP_X_COORD], Tech_desc_coords[gr_screen.res][SHIP_Y_COORD], Tech_desc_coords[gr_screen.res][SHIP_H_COORD]);

	font_height = gr_get_font_height();

	// draw the list of entries
	y = 0;
	z = List_offset;
	while (y + font_height <= Tech_list_coords[gr_screen.res][SHIP_H_COORD]) {
		if (z >= Current_list_size) {
			break;
		}

		if (z == Cur_entry) {
			gr_set_color_fast(&Color_text_selected);
		} else if (z == Select_tease_line) {
			gr_set_color_fast(&Color_text_subselected);
		} else {
			gr_set_color_fast(&Color_text_normal);
		}

		memset( buf, 0, sizeof(buf) );
		strncpy(buf, Current_list[z].name, sizeof(buf) - 1);

		if (Lcl_gr)
			lcl_translate_ship_name_gr(buf);

		gr_force_fit_string(buf, 255, Tech_list_coords[gr_screen.res][SHIP_W_COORD]);
		gr_string(Tech_list_coords[gr_screen.res][SHIP_X_COORD], Tech_list_coords[gr_screen.res][SHIP_Y_COORD] + y, buf, GR_RESIZE_MENU);

		List_buttons[z - List_offset].update_dimensions(Tech_list_coords[gr_screen.res][SHIP_X_COORD], Tech_list_coords[gr_screen.res][SHIP_Y_COORD] + y, Tech_list_coords[gr_screen.res][SHIP_W_COORD], font_height);
		List_buttons[z - List_offset].enable(1);

		y += font_height;
		z++;
	}

	// disable the rest of the list buttons
	z -= List_offset;
	while (z < LIST_BUTTONS_MAX) {
		List_buttons[z++].disable();
	}
}
예제 #5
0
// multiplayer dogfight
void hud_escort_show_icon_dogfight(int x, int y, int index)
{
#ifndef NEW_HUD
	int			hull_integrity = 100;
	char			buf[255];	
	int			np_index;
	object		*objp;
	ship_info	*sip;

	int stat_shift = 40;

	// always use the standard color to avoid confusion
	hud_set_gauge_color(HUD_ESCORT_VIEW);	

	// netplayer index
	np_index = find_player_id(Escort_ships[index].np_id);
	if((np_index < 0) || (np_index >= MAX_PLAYERS) || (Net_players[np_index].m_player == NULL)){
		return;
	}
	
	// print out player name
	strcpy(buf, Net_players[np_index].m_player->callsign);
	gr_force_fit_string(buf, 255, 100 - stat_shift);
	emp_hud_string( x + current_hud->Escort_name[0], y + current_hud->Escort_name[1], EG_ESCORT1 + index, buf);	

	// can we get the player object?
	objp = NULL;
	if((Net_players[np_index].m_player->objnum >= 0) && (Net_players[np_index].m_player->objnum < MAX_OBJECTS) && (Objects[Net_players[np_index].m_player->objnum].type == OBJ_SHIP)){
		objp = &Objects[Net_players[np_index].m_player->objnum];
		if((objp->instance >= 0) && (objp->instance < MAX_SHIPS) && (Ships[objp->instance].ship_info_index >= 0) && (Ships[objp->instance].ship_info_index < MAX_SHIPS)){
			sip = &Ship_info[Ships[objp->instance].ship_info_index];
		} else {
			return;
		}

		hull_integrity = (int)(((float)objp->hull_strength / (float)Ships[objp->instance].ship_max_hull_strength) * 100.0f);
		if(hull_integrity < 0){
			hull_integrity = 0;
		}
	}

	// show ship integrity
	if(objp == NULL){	
		emp_hud_printf( x+current_hud->Escort_integrity[0] - stat_shift, y+current_hud->Escort_integrity[1], EG_NULL, "%d", Net_players[np_index].m_player->stats.m_kill_count_ok);	
	} else {
		emp_hud_printf( x+current_hud->Escort_integrity[0] - stat_shift, y+current_hud->Escort_integrity[1], EG_NULL, "(%d%%) %d", hull_integrity, Net_players[np_index].m_player->stats.m_kill_count_ok);	
	}
#endif
}
// multiplayer dogfight
void HudGaugeEscort::renderIconDogfight(int x, int y, int index)
{
	int			hull_integrity = 100;
	char			buf[255];	
	int			np_index;
	object		*objp;

	int stat_shift = 40;

	// always use the standard color to avoid confusion
	setGaugeColor();

	// netplayer index
	np_index = find_player_id(Escort_ships[index].np_id);
	if((np_index < 0) || (np_index >= MAX_PLAYERS) || (Net_players[np_index].m_player == NULL)){
		return;
	}
	
	// print out player name
	strcpy_s(buf, Net_players[np_index].m_player->callsign);
	gr_force_fit_string(buf, 255, 100 - stat_shift);
	renderString( x + ship_name_offsets[0], y + ship_name_offsets[1], EG_ESCORT1 + index, buf);	

	// can we get the player object?
	objp = NULL;
	if((Net_players[np_index].m_player->objnum >= 0) && (Net_players[np_index].m_player->objnum < MAX_OBJECTS) && (Objects[Net_players[np_index].m_player->objnum].type == OBJ_SHIP)){
		objp = &Objects[Net_players[np_index].m_player->objnum];
		if((objp->instance >= 0) && (objp->instance < MAX_SHIPS) && (Ships[objp->instance].ship_info_index >= 0) && (Ships[objp->instance].ship_info_index < MAX_SHIPS)){
			//
		} else {
			return;
		}

		hull_integrity = (int)(((float)objp->hull_strength / (float)Ships[objp->instance].ship_max_hull_strength) * 100.0f);
		if(hull_integrity < 0){
			hull_integrity = 0;
		}
	}

	// show ship integrity
	if(objp == NULL){	
		renderPrintf( x+ship_integrity_offsets[0] - stat_shift, y+ship_integrity_offsets[1], EG_NULL, "%d", Net_players[np_index].m_player->stats.m_kill_count_ok);	
	} else {
		renderPrintf( x+ship_integrity_offsets[0] - stat_shift, y+ship_integrity_offsets[1], EG_NULL, "(%d%%) %d", hull_integrity, Net_players[np_index].m_player->stats.m_kill_count_ok);	
	}
}
// ---------------------------------------------------------------------
// mission_hotkey_do_frame()
//
// Called once per frame to process user input for the Hotkey Assignment Screen
//
void mission_hotkey_do_frame(float frametime)
{
	char buf[256];
	int i, k, w, h, y, z, line, hotkeys;
	int font_height = gr_get_font_height();
	int select_tease_line = -1;  // line mouse is down on, but won't be selected until button released
	color circle_color;

	if ( help_overlay_active(Hotkey_overlay_id) ) {
		Buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
		Ui_window.set_ignore_gadgets(1);
	}

	k = Ui_window.process() & ~KEY_DEBUGGED;

	if ( (k > 0) || B1_JUST_RELEASED ) {
		if ( help_overlay_active(Hotkey_overlay_id) ) {
			help_overlay_set_state(Hotkey_overlay_id, gr_screen.res, 0);
			Ui_window.set_ignore_gadgets(0);
			k = 0;
		}
	}

	if ( !help_overlay_active(Hotkey_overlay_id) ) {
		Ui_window.set_ignore_gadgets(0);
	}

	switch (k) {
		case KEY_DOWN:  // scroll list down
			hotkey_scroll_line_down();
			break;

		case KEY_UP:  // scroll list up
			hotkey_scroll_line_up();
			break;

		case KEY_PAGEDOWN:  // scroll list down
			hotkey_scroll_screen_down();
			break;

		case KEY_PAGEUP:  // scroll list up
			hotkey_scroll_screen_up();
			break;

		case KEY_CTRLED | KEY_ENTER:
			save_hotkeys();
			// fall through to next state -- allender changed this behavior since ESC should always cancel, no?

		case KEY_ESC:			
			mission_hotkey_exit();
			break;

		case KEY_TAB:
		case KEY_ENTER:
		case KEY_PADENTER:
			expand_wing();
			break;

		case KEY_EQUAL:
		case KEY_PADPLUS:
			add_hotkey(Cur_hotkey);
			break;

		case KEY_MINUS:
		case KEY_PADMINUS:
			remove_hotkey();
			break;

		case KEY_F2:			
			gameseq_post_event(GS_EVENT_OPTIONS_MENU);			
			break;

		case KEY_CTRLED | KEY_R:
			reset_hotkeys();
			break;

		case KEY_CTRLED | KEY_C:
			clear_hotkeys();
			break;
	}	// end switch

	// ?
	for (i=0; i<MAX_KEYED_TARGETS; i++) {
		if (k == Key_sets[i])
			Cur_hotkey = i;

		if (k == (Key_sets[i] | KEY_SHIFTED))
			add_hotkey(i);
	}

	// handle pressed buttons
	for (i=0; i<NUM_BUTTONS; i++) {
		if (Buttons[gr_screen.res][i].button.pressed()) {
			hotkey_button_pressed(i);
			break;					// only need to handle 1 button @ a time
		}
	}

	for (i=0; i<LIST_BUTTONS_MAX; i++) {
		// check for tease line
		if (List_buttons[i].button_down()) {
			select_tease_line = i + Scroll_offset;
		}
	
		// check for selected list item
		if (List_buttons[i].pressed()) {
			Selected_line = i + Scroll_offset;
			List_buttons[i].get_mouse_pos(&z, NULL);
			z += Hotkey_list_coords[gr_screen.res][0];		// adjust to full screen space
			if ((z >= Hotkey_wing_icon_x[gr_screen.res]) && (z < (Hotkey_wing_icon_x[gr_screen.res]) + Hotkey_function_field_width[gr_screen.res])) {
				expand_wing();
			}
		}

		if (List_buttons[i].double_clicked()) {
			Selected_line = i + Scroll_offset;
			hotkeys = -1;
			switch (Hotkey_lines[Selected_line].type) {
				case HOTKEY_LINE_WING:
					hotkeys = get_wing_hotkeys(Hotkey_lines[Selected_line].index);
					break;

				case HOTKEY_LINE_SHIP:
				case HOTKEY_LINE_SUBSHIP:
					hotkeys = Hotkey_bits[Hotkey_lines[Selected_line].index];
					break;
			}

			if (hotkeys != -1) {
				if (hotkeys & (1 << Cur_hotkey))
					remove_hotkey();
				else
					add_hotkey(Cur_hotkey);
			}
		}
	}

	GR_MAYBE_CLEAR_RES(Background_bitmap);
	if (Background_bitmap >= 0) {
		gr_set_bitmap(Background_bitmap);
		gr_bitmap(0, 0, GR_RESIZE_MENU);

	} else
		gr_clear();

	Ui_window.draw();
	gr_init_color(&circle_color, 160, 160, 0);

	// draw the big "F10" in the little box	
	gr_set_font(FONT2);
	gr_set_color_fast(&Color_text_normal);
	strcpy_s(buf, Scan_code_text[Key_sets[Cur_hotkey]]);
	gr_get_string_size(&w, &h, buf);
	gr_printf_menu(Hotkey_function_name_coords[gr_screen.res][0] + (Hotkey_function_name_coords[gr_screen.res][2] - w) / 2, Hotkey_function_name_coords[gr_screen.res][1], buf);

	gr_set_font(FONT1);
	line = Scroll_offset;
	while (hotkey_line_query_visible(line)) {
		z = Hotkey_lines[line].index;
		y = Hotkey_list_coords[gr_screen.res][1] + Hotkey_lines[line].y - Hotkey_lines[Scroll_offset].y;
		hotkeys = 0;
		switch (Hotkey_lines[line].type) {
			case HOTKEY_LINE_HEADING:
				gr_set_color_fast(&Color_text_heading);

				gr_get_string_size(&w, &h, Hotkey_lines[line].label);
				i = y + h / 2 - 1;
				gr_line(Hotkey_list_coords[gr_screen.res][0], i, Hotkey_ship_x[gr_screen.res] - 2, i, GR_RESIZE_MENU);
				gr_line(Hotkey_ship_x[gr_screen.res] + w + 1, i, Hotkey_list_coords[gr_screen.res][0] + Hotkey_list_coords[gr_screen.res][2], i, GR_RESIZE_MENU);
				break;

			case HOTKEY_LINE_WING:
				gr_set_bitmap(Wing_bmp);
				bm_get_info(Wing_bmp, NULL, &h, NULL);
				i = y + font_height / 2 - h / 2 - 1;
				gr_bitmap(Hotkey_wing_icon_x[gr_screen.res], i, GR_RESIZE_MENU);

//				i = y + font_height / 2 - 1;
//				gr_set_color_fast(&circle_color);
//				gr_circle(ICON_LIST_X + 4, i, 5, GR_RESIZE_MENU);

//				gr_set_color_fast(&Color_bright);
//				gr_line(ICON_LIST_X, i, ICON_LIST_X + 2, i, GR_RESIZE_MENU);
//				gr_line(ICON_LIST_X + 4, i - 4, ICON_LIST_X + 4, i - 2, GR_RESIZE_MENU);
//				gr_line(ICON_LIST_X + 6, i, ICON_LIST_X + 8, i, GR_RESIZE_MENU);
//				gr_line(ICON_LIST_X + 4, i + 2, ICON_LIST_X + 4, i + 4, GR_RESIZE_MENU);

				hotkeys = get_wing_hotkeys(Hotkey_lines[line].index);
				break;

			case HOTKEY_LINE_SHIP:
			case HOTKEY_LINE_SUBSHIP:
				hotkeys = Hotkey_bits[Hotkey_lines[line].index];
				break;

			default:
				Int3();
		}

		if (Hotkey_lines[line].type != HOTKEY_LINE_HEADING) {
			Assert( (line - Scroll_offset) < LIST_BUTTONS_MAX );
			List_buttons[line - Scroll_offset].update_dimensions(Hotkey_list_coords[gr_screen.res][0], y, Hotkey_list_coords[gr_screen.res][0] + Hotkey_list_coords[gr_screen.res][2] - Hotkey_list_coords[gr_screen.res][0], font_height);
			List_buttons[line - Scroll_offset].enable();
			if (hotkeys & (1 << Cur_hotkey)) {
				gr_set_color_fast(&Color_text_active);

			} else {
				if (line == Selected_line)
					gr_set_color_fast(&Color_text_selected);
				else if (line == select_tease_line)
					gr_set_color_fast(&Color_text_subselected);
				else
					gr_set_color_fast(&Color_text_normal);
			}

		} else {
			Assert( (line - Scroll_offset) < LIST_BUTTONS_MAX );
			List_buttons[line - Scroll_offset].disable();
		}

		// print active hotkeys associated for this line
		if (hotkeys) {
			for (i=0; i<MAX_KEYED_TARGETS; i++) {
				if (hotkeys & (1 << i)) {
					gr_printf_menu(Hotkey_list_coords[gr_screen.res][0] + Hotkey_function_field_width[gr_screen.res]*i, y, Scan_code_text[Key_sets[i]]);
				}
			}
/*
			*buf = 0;
			for (i=0; i<MAX_KEYED_TARGETS; i++) {
				if (hotkeys & (1 << i)) {
					strcat_s(buf, Scan_code_text[Key_sets[i]]);
					strcat_s(buf, ", ");
				}
			}

			Assert(strlen(buf) > 1);
			buf[strlen(buf) - 2] = 0;  // lose the ", " on the end

			gr_force_fit_string(buf, 255, GROUP_LIST_W);
			gr_printf_menu(GROUP_LIST_X, y, buf);*/
		}
	
		// draw ship/wing name
		strcpy_s(buf, Hotkey_lines[line].label);
		end_string_at_first_hash_symbol(buf);
		if (Hotkey_lines[line].type == HOTKEY_LINE_SUBSHIP) {
			// indent
			gr_force_fit_string(buf, 255, Hotkey_list_coords[gr_screen.res][0] + Hotkey_list_coords[gr_screen.res][2] - (Hotkey_ship_x[gr_screen.res]+20));
			gr_printf_menu(Hotkey_ship_x[gr_screen.res]+20, y, buf);
		} else {
			gr_force_fit_string(buf, 255, Hotkey_list_coords[gr_screen.res][0] + Hotkey_list_coords[gr_screen.res][2] - Hotkey_ship_x[gr_screen.res]);
			gr_printf_menu(Hotkey_ship_x[gr_screen.res], y, buf);
		}

		line++;
	}

	i = line - Scroll_offset;
	while (i < LIST_BUTTONS_MAX)
		List_buttons[i++].disable();

	// blit help overlay if active
	help_overlay_maybe_blit(Hotkey_overlay_id, gr_screen.res);

	gr_flip();
}
예제 #8
0
void barracks_init_stats(scoring_struct *stats)
{
	int Max_stat_lines = Num_ship_classes + 23;
	int i;
	float f;
	int score_from_kills = 0;

	//Set up variables
	if(Stat_labels != NULL)
	{
		delete[] Stat_labels;
	}
	if(Stats != NULL)
	{
		delete[] Stats;
	}

	Stat_labels = (char (*)[STAT_COLUMN1_W]) new char[Max_stat_lines * STAT_COLUMN1_W];
	Stats = (char (*)[STAT_COLUMN2_W]) new char[Max_stat_lines * STAT_COLUMN2_W];

	//Now start throwing stuff in
	Num_stat_lines = 0;

	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "*All Time Stats", 50));
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	Stat_labels[Num_stat_lines][0] = 0;
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;	

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary weapon shots:", 51));
	sprintf(Stats[Num_stat_lines], "%u", stats->p_shots_fired);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary weapon hits:", 52));
	sprintf(Stats[Num_stat_lines], "%u", stats->p_shots_hit);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary friendly hits:", 53));
	sprintf(Stats[Num_stat_lines], "%u", stats->p_bonehead_hits);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary hit %:", 54));
	if (stats->p_shots_fired > 0) {
		f = (float) stats->p_shots_hit * 100.0f / (float) stats->p_shots_fired;
	} else {
		f = 0.0f;
	}
	sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary friendly hit %:", 56));
	if (stats->p_bonehead_hits > 0) {
		f = (float) stats->p_bonehead_hits * 100.0f / (float) stats->p_shots_fired;
	} else {
		f = 0.0f;
	}
	sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	Stat_labels[Num_stat_lines][0] = 0;
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary weapon shots:", 57));
	sprintf(Stats[Num_stat_lines], "%u", stats->s_shots_fired);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary weapon hits:", 58));
	sprintf(Stats[Num_stat_lines], "%u", stats->s_shots_hit);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hits:", 59));
	sprintf(Stats[Num_stat_lines], "%u", stats->s_bonehead_hits);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary hit %:", 60));
	if (stats->s_shots_fired > 0) {
		f = (float) stats->s_shots_hit * 100.0f / (float) stats->s_shots_fired;
	} else {
		f = 0.0f;
	}
	sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hit %:", 61));
	if (stats->s_bonehead_hits > 0) {
		f = (float) stats->s_bonehead_hits * 100.0f / (float) stats->s_shots_fired;
	} else {
		f = 0.0f;
	}
	sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	Stat_labels[Num_stat_lines][0] = 0;
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Total kills:", 62));
	sprintf(Stats[Num_stat_lines], "%d", stats->kill_count_ok);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Assists:", 63));
	sprintf(Stats[Num_stat_lines], "%d", stats->assists);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	Stat_labels[Num_stat_lines][0] = 0;
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], "Current Score:");
	sprintf(Stats[Num_stat_lines], "%d", stats->score);
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	Stat_labels[Num_stat_lines][0] = 0;
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	Stat_labels[Num_stat_lines][0] = 0;
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "*Kills by Ship Type", 64));
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	Assert(Num_stat_lines < Max_stat_lines);
	Stat_labels[Num_stat_lines][0] = 0;
	Stats[Num_stat_lines][0] = 0;
	Num_stat_lines++;

	// Goober5000 - make sure we have room for all ships
	Assert((Num_stat_lines + Num_ship_classes) < Max_stat_lines);

	for (i=0; i<Num_ship_classes; i++) {
		if (stats->kills[i]) {
			Assert(Num_stat_lines < Max_stat_lines);

			// Goober5000 - in case above Assert isn't triggered (such as in non-debug builds)
			if (Num_stat_lines >= Max_stat_lines)
			{
				break;
			}

			Assert(strlen(Ship_info[i].name) + 1 < STAT_COLUMN1_W);
			sprintf(Stat_labels[Num_stat_lines], NOX("%s:"), Ship_info[i].name);
			sprintf(Stats[Num_stat_lines], "%d", stats->kills[i]);
			Num_stat_lines++;

			// work out the total score from ship kills
			score_from_kills += stats->kills[i] * Ship_info[i].score;
		}
	}

	// add the score from kills
	Assert((Num_stat_lines + Num_ship_classes) < Max_stat_lines);
	STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Score from kills only:", 1636));
	sprintf(Stats[Num_stat_lines], "%d", score_from_kills);
	Num_stat_lines++;

	for (i=0; i<Num_stat_lines; i++) {
		gr_force_fit_string(Stat_labels[i], Stat_column1_w[gr_screen.res], Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD]);
		gr_force_fit_string(Stats[i], Stat_column2_w[gr_screen.res], Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD]);
	}
}