mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-10 04:31:34 -10:00
* Allow Display Name to be used in Kills Stats by Ship Class Currently, the display that is shown for kills by ship type does not use display name of the ship class, which makes the ship classes look different than the other areas where they are displayed throughout the game. This PR fixes that by using display name when rendering the kill stats. Note, this PR does not edit the pilot file structure at all, it simply just tunes how the names are displayed/rendered. Importantly though, display names do not have to be unique, while the ship class names do. Thus, this PR also consolidates the number of kills of ship classes with the same display name (For example, FotG uses classes like `X-wing#Red` and `X-wing#Blue`, but both have the same display name of `X-wing`, so this consolidation means FSO will simple display `X-wing` with the sum. Overall, mods not using display name will be unaffected, while mods that do use display name will now have it properly work in the barracks and debrief rendering. Tested and works as expected. * remove flag for now * move assert * use handy get_display_name
1721 lines
51 KiB
C++
1721 lines
51 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#include <cctype>
|
|
|
|
|
|
#include "cfile/cfile.h"
|
|
#include "freespace.h"
|
|
#include "gamehelp/contexthelp.h"
|
|
#include "gamesequence/gamesequence.h"
|
|
#include "gamesnd/gamesnd.h"
|
|
#include "globalincs/alphacolors.h"
|
|
#include "graphics/font.h"
|
|
#include "io/key.h"
|
|
#include "io/mouse.h"
|
|
#include "menuui/barracks.h"
|
|
#include "menuui/playermenu.h"
|
|
#include "mission/missioncampaign.h"
|
|
#include "osapi/osregistry.h"
|
|
#include "parse/parselo.h"
|
|
#include "pilotfile/pilotfile.h"
|
|
#include "playerman/managepilot.h"
|
|
#include "playerman/player.h"
|
|
#include "popup/popup.h"
|
|
#include "ship/ship.h"
|
|
#include "ui/ui.h"
|
|
#include "barracks.h"
|
|
#include "mod_table/mod_table.h"
|
|
|
|
|
|
// stats defines
|
|
//#define NUM_STAT_LINES (21 + MAX_SHIP_CLASSES) // Goober5000
|
|
#define STAT_COLUMN1_W 40*2 // as we might use Unicode //ksotar
|
|
#define STAT_COLUMN2_W 10
|
|
|
|
static int Stat_column1_w[GR_NUM_RESOLUTIONS] =
|
|
{
|
|
40, // GR_640
|
|
40 // GR_1024
|
|
};
|
|
|
|
static int Stat_column2_w[GR_NUM_RESOLUTIONS] =
|
|
{
|
|
10, // GR_640
|
|
10 // GR_1024
|
|
};
|
|
|
|
// constants for coordinate lookup
|
|
#define BARRACKS_X_COORD 0
|
|
#define BARRACKS_Y_COORD 1
|
|
#define BARRACKS_W_COORD 2
|
|
#define BARRACKS_H_COORD 3
|
|
|
|
// area ints
|
|
|
|
// pilot selection field
|
|
static int Barracks_list_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{ // GR_640
|
|
42, 34, 400, 90
|
|
},
|
|
{ // GR_1024
|
|
45, 51, 646, 144
|
|
}
|
|
};
|
|
|
|
// pilot stats field
|
|
static int Barracks_stats_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{ // GR_640
|
|
32, 212, 240, 250
|
|
},
|
|
{ // GR_1024
|
|
42, 351, 240, 400
|
|
}
|
|
};
|
|
|
|
|
|
static int Barracks_stats2_coords[GR_NUM_RESOLUTIONS][3] = {
|
|
{ // GR_640
|
|
276, 212, 81 // X2, , W2
|
|
},
|
|
{ // GR_1024
|
|
286, 351, 81 // X2, , W2
|
|
}
|
|
};
|
|
|
|
// pilot picture field
|
|
static int Barracks_image_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{ // GR_640
|
|
461, 23, 160, 120
|
|
},
|
|
{ // GR_1024
|
|
782, 58, 160, 120
|
|
}
|
|
};
|
|
|
|
// pilot picture # of # location
|
|
static int Barracks_image_number_coords[GR_NUM_RESOLUTIONS][2] = {
|
|
{ // GR_640
|
|
461, 145
|
|
},
|
|
{ // GR_1024
|
|
732, 239
|
|
}
|
|
};
|
|
|
|
// pilot squad logo field
|
|
int Barracks_squad_coords[GR_NUM_RESOLUTIONS][4] = {
|
|
{ // GR_640
|
|
495, 177, 128, 128
|
|
},
|
|
{ // GR_1024
|
|
829, 323, 128, 128
|
|
}
|
|
};
|
|
|
|
// pilot squad # of # location
|
|
int Barracks_squad_number_coords[GR_NUM_RESOLUTIONS][2] = {
|
|
{ // GR_640
|
|
492, 307
|
|
},
|
|
{ // GR_1024
|
|
794, 500
|
|
}
|
|
};
|
|
|
|
// button defines
|
|
#define BARRACKS_NUM_BUTTONS 19
|
|
|
|
// pilot selection buttons
|
|
#define B_PILOT_CREATE_BUTTON 0 // B_PILOT_CREATE_BUTTON
|
|
#define B_PILOT_SCROLL_UP_BUTTON 1 // B_PILOT_SCROLL_UP_BUTTON
|
|
#define B_PILOT_SCROLL_DOWN_BUTTON 2 // B_PILOT_SCROLL_DOWN_BUTTON
|
|
#define B_PILOT_DELETE_BUTTON 11 // B_PILOT_B_PILOT_DELETE_BUTTON
|
|
#define B_PILOT_SET_ACTIVE_BUTTON 12 // B_PILOT_B_PILOT_SET_ACTIVE_BUTTON
|
|
#define B_PILOT_CLONE_BUTTON 13 // B_PILOT_B_PILOT_CLONE_BUTTON
|
|
#define B_PILOT_SINGLE_MODE_BUTTON 14 // B_PILOT_SINGLE_MODE_BUTTON
|
|
#define B_PILOT_MULTI_MODE_BUTTON 15 // B_PILOT_MULTI_MODE_BUTTON
|
|
#define B_PILOT_CONVERT_BUTTON 16 // B_PILOT_B_PILOT_CONVERT_BUTTON
|
|
|
|
// squad logo picture buttons
|
|
#define B_SQUAD_PREV_BUTTON 17
|
|
#define B_SQUAD_NEXT_BUTTON 18
|
|
|
|
// pilot picture buttons
|
|
#define B_PIC_PREV_PILOT_BUTTON 3 // B_PILOT_B_PIC_PREV_PILOT_BUTTON
|
|
#define B_PIC_NEXT_PILOT_BUTTON 4 // B_PILOT_B_PIC_NEXT_PILOT_BUTTON
|
|
|
|
// pilot stat buttons
|
|
#define B_STATS_MEDAL_BUTTON 8 // B_STATS_MEDAL_BUTTON
|
|
#define B_STATS_SCROLL_DOWN_BUTTON 9 // B_STATS_SCROLL_DOWN_BUTTON
|
|
#define B_STATS_SCROLL_UP_BUTTON 10 // B_STATS_SCROLL_UP_BUTTON
|
|
|
|
// general buttons
|
|
#define B_ACCEPT_BUTTON 5 // B_B_ACCEPT_BUTTON
|
|
#define B_HELP_BUTTON 6 // B_B_HELP_BUTTON
|
|
#define B_OPTION_BUTTON 7 // B_OPTION_BUTTON
|
|
|
|
//XSTR:OFF
|
|
// bitmaps defs
|
|
static const char *Barracks_bitmap_fname[GR_NUM_RESOLUTIONS] = {
|
|
"Barracks", // GR_640
|
|
"2_Barracks" // GR_1024
|
|
};
|
|
|
|
static const char *Barracks_bitmap_mask_fname[GR_NUM_RESOLUTIONS] = {
|
|
"Barracks-M", // GR_640
|
|
"2_Barracks-M" // GR_1024
|
|
};
|
|
|
|
//XSTR:ON
|
|
|
|
#define BARRACKS_IMAGE_NOT_LOADED -2
|
|
|
|
struct barracks_bitmaps {
|
|
char *filename;
|
|
int x, y;
|
|
int b;
|
|
};
|
|
|
|
static int Background_bitmap = -1;
|
|
static UI_WINDOW Ui_window;
|
|
static UI_BUTTON List_region;
|
|
static UI_INPUTBOX Inputbox;
|
|
|
|
static barracks_buttons Buttons[GR_NUM_RESOLUTIONS][BARRACKS_NUM_BUTTONS] = {
|
|
//XSTR:OFF
|
|
{ // GR_640
|
|
barracks_buttons("BAB_00", 8, 122, 11, 157, 0),
|
|
barracks_buttons("BAB_01", 323, 130, 0, 0, 1, 1),
|
|
barracks_buttons("BAB_02", 350, 130, 0, 0, 2, 1),
|
|
barracks_buttons("BAB_03", 559, 143, 0, 0, 3, 1),
|
|
barracks_buttons("BAB_04", 598, 143, 0, 0, 4, 1),
|
|
barracks_buttons("BAB_05", 571, 425, 578, 413, 5),
|
|
barracks_buttons("BAB_06", 533, 425, 500, 438, 6),
|
|
barracks_buttons("BAB_07", 533, 453, 481, 465, 7),
|
|
barracks_buttons("BAB_08", 361, 425, 401, 465, 8),
|
|
barracks_buttons("BAB_09", 0, 267, 0, 0, 9, 1),
|
|
barracks_buttons("BAB_10", 0, 224, 0, 0, 10,1),
|
|
barracks_buttons("BAB_11", 120, 122, 123, 157, 11),
|
|
barracks_buttons("BAB_12", 376, 124, 378, 163, 12),
|
|
barracks_buttons("BAB_13", 66, 122, 69, 157, 13),
|
|
barracks_buttons("BAB_14", 323, 0, 324, 25, 14),
|
|
barracks_buttons("BAB_15", 372, 0, 374, 25, 15),
|
|
barracks_buttons("BAB_16", 180, 122, 182, 157, 16),
|
|
barracks_buttons("BAB_17", 559, 306, 0, 0, 17),
|
|
barracks_buttons("BAB_18", 598, 306, 0, 0, 18)
|
|
},
|
|
{ // GR_1024
|
|
barracks_buttons("2_BAB_00", 14, 196, 35, 252, 0),
|
|
barracks_buttons("2_BAB_01", 518, 209, 0, 0, 1, 1),
|
|
barracks_buttons("2_BAB_02", 561, 209, 0, 0, 2, 1),
|
|
barracks_buttons("2_BAB_03", 896, 229, 0, 0, 3, 1),
|
|
barracks_buttons("2_BAB_04", 958, 229, 0, 0, 4, 1),
|
|
barracks_buttons("2_BAB_05", 914, 681, 932, 665, 5),
|
|
barracks_buttons("2_BAB_06", 854, 681, 800, 704, 6),
|
|
barracks_buttons("2_BAB_07", 854, 724, 778, 743, 7),
|
|
barracks_buttons("2_BAB_08", 579, 681, 641, 743, 8),
|
|
barracks_buttons("2_BAB_09", 0, 428, 0, 0, 9, 1),
|
|
barracks_buttons("2_BAB_10", 0, 360, 0, 0, 10,1),
|
|
barracks_buttons("2_BAB_11", 193, 196, 214, 252, 11),
|
|
barracks_buttons("2_BAB_12", 602, 200, 617, 262, 12),
|
|
barracks_buttons("2_BAB_13", 107, 196, 128, 252, 13),
|
|
barracks_buttons("2_BAB_14", 517, 0, 532, 40, 14),
|
|
barracks_buttons("2_BAB_15", 596, 0, 614, 40, 15),
|
|
barracks_buttons("2_BAB_16", 289, 196, 309, 252, 16),
|
|
barracks_buttons("2_BAB_17", 896, 491, 0, 0, 17),
|
|
barracks_buttons("2_BAB_18", 958, 491, 0, 0, 18)
|
|
}
|
|
//XSTR:ON
|
|
};
|
|
|
|
|
|
// FIXME add to strings.tbl, set correct coords
|
|
#define BARRACKS_NUM_TEXT 2
|
|
UI_XSTR Barracks_text[GR_NUM_RESOLUTIONS][BARRACKS_NUM_TEXT] = {
|
|
{
|
|
// GR_640
|
|
{ "Barracks", 1434, 17, 7, UI_XSTR_COLOR_GREEN, -1, NULL },
|
|
{ "Pilot Stats", 1435, 17, 180, UI_XSTR_COLOR_GREEN, -1, NULL }
|
|
},
|
|
{
|
|
// GR_1024
|
|
{ "Barracks", 1434, 27, 11, UI_XSTR_COLOR_GREEN, -1, NULL },
|
|
{ "Pilot Stats", 1435, 27, 288, UI_XSTR_COLOR_GREEN, -1, NULL }
|
|
}
|
|
};
|
|
|
|
|
|
static size_t Num_stat_lines;
|
|
static char (*Stat_labels)[STAT_COLUMN1_W];
|
|
static char (*Stats)[STAT_COLUMN2_W];
|
|
static uint16_t Stats_max_width; // If Unicode language is used then we adapt stats width for new words/strings length
|
|
static uint16_t Stats_X2; // And numbers position adapted as well
|
|
|
|
|
|
static int Player_sel_mode;
|
|
|
|
static player *Cur_pilot;
|
|
static int Num_pilots;
|
|
static int Selected_line;
|
|
static char Pilots_arr[MAX_PILOTS][MAX_FILENAME_LEN];
|
|
static char *Pilots[MAX_PILOTS];
|
|
static int Pic_number;
|
|
static int Pic_squad_number;
|
|
static bool Barracks_callsign_enter_mode;
|
|
static int Pilot_ranks[MAX_PILOTS];
|
|
static int List_scroll_offset;
|
|
static int Stats_scroll_offset;
|
|
static int Clone_flag;
|
|
static int Pilot_images[MAX_PILOT_IMAGES];
|
|
static int Pilot_squad_images[MAX_PILOT_IMAGES];
|
|
static int Rank_pips_bitmaps;
|
|
static int Rank_pips_count;
|
|
|
|
int Barracks_overlay_id;
|
|
|
|
void barracks_squad_change_popup();
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------
|
|
//
|
|
// BARRACKS screen
|
|
//
|
|
|
|
#define STRCPY1(a, b) do { \
|
|
Assert(strlen(b) < STAT_COLUMN1_W); \
|
|
strcpy_s(a, b); \
|
|
} while (false)
|
|
|
|
void barracks_init_stats(scoring_struct *stats)
|
|
{
|
|
size_t Max_stat_lines = Ship_info.size() + 23;
|
|
size_t 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_shots_fired > 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_shots_fired > 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);
|
|
strcpy_s(Stat_labels[Num_stat_lines], XSTR("Current Score:", 1583));
|
|
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 + Ship_info.size()) < Max_stat_lines);
|
|
|
|
// wookieejedi - Show kills by ship type, but if using display name
|
|
// then consolidate values for similarly named entries
|
|
std::map<SCP_string, int, SCP_string_lcase_less_than> kill_map;
|
|
i = 0;
|
|
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); i++, ++it) {
|
|
if (stats->kills[i]) {
|
|
// wookieejedi - consolidate by display name or ship class name
|
|
const char* name_key = it->get_display_name();
|
|
Assert(strlen(name_key) + 1 < STAT_COLUMN1_W);
|
|
kill_map[name_key] += stats->kills[i];
|
|
score_from_kills += stats->kills[i] * it->score;
|
|
}
|
|
}
|
|
|
|
// wookieejedi - now display the kills per ship type
|
|
for (const auto& [name, count] : kill_map) {
|
|
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(name.length() + 1 < STAT_COLUMN1_W);
|
|
sprintf(Stat_labels[Num_stat_lines], NOX("%s:"), name.c_str());
|
|
sprintf(Stats[Num_stat_lines], "%d", count);
|
|
Num_stat_lines++;
|
|
}
|
|
|
|
// add the score from kills
|
|
Assert((Num_stat_lines + 1) < 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++;
|
|
|
|
int w;
|
|
Stats_max_width = 0;
|
|
Stats_X2 = 0;
|
|
if (Unicode_text_mode && (gr_screen.res != GR_640)) {
|
|
for (i = 0; i < Num_stat_lines; i++) { // Find the longest string in labels to base list appearance on that
|
|
gr_get_string_size(&w, nullptr, Stat_labels[i]);
|
|
if (Stats_max_width < w)
|
|
Stats_max_width = (uint16_t)w;
|
|
}
|
|
Stats_max_width += 20;
|
|
Stats_X2 = Stats_max_width + 46;
|
|
}
|
|
else {
|
|
Stats_max_width = (uint16_t) Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD];
|
|
Stats_X2 = (uint16_t) Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD];
|
|
for (i = 0; i < Num_stat_lines; i++) {
|
|
font::force_fit_string(Stat_labels[i], Stat_column1_w[gr_screen.res], Stats_max_width);
|
|
font::force_fit_string(Stats[i], Stat_column2_w[gr_screen.res], Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// sets or clears hotkeys for pilot selection.
|
|
void barracks_set_hotkeys(bool pilot_text_enter_mode)
|
|
{
|
|
Buttons[gr_screen.res][B_PILOT_SCROLL_UP_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_UP : -1);
|
|
Buttons[gr_screen.res][B_PILOT_SCROLL_DOWN_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_DOWN : -1);
|
|
|
|
Buttons[gr_screen.res][B_PILOT_CREATE_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_C : -1);
|
|
Buttons[gr_screen.res][B_PILOT_SET_ACTIVE_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_ENTER : -1);
|
|
Buttons[gr_screen.res][B_PILOT_DELETE_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_DELETE : -1);
|
|
|
|
Buttons[gr_screen.res][B_PIC_PREV_PILOT_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_LEFT : -1);
|
|
Buttons[gr_screen.res][B_PIC_NEXT_PILOT_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_RIGHT : -1);
|
|
|
|
Buttons[gr_screen.res][B_ACCEPT_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_CTRLED | KEY_ENTER : -1);
|
|
}
|
|
|
|
// strip the possible .pcx extension off a filename
|
|
void barracks_strip_pcx(char *str)
|
|
{
|
|
const size_t EXT_LEN = 4;
|
|
size_t flen = strlen(str);
|
|
|
|
if ((flen > 4) && !stricmp(str + flen - EXT_LEN, ".pcx")) {
|
|
str[flen - EXT_LEN] = '\0';
|
|
}
|
|
}
|
|
|
|
// new pilot name has focus, so update stats/pic to that pilot
|
|
int barracks_new_pilot_selected()
|
|
{
|
|
char stripped[MAX_FILENAME_LEN+1] = "";
|
|
|
|
// save the previous pilot first, so changes to it are kept
|
|
if (strlen(Cur_pilot->callsign)) {
|
|
Pilot.save_player(Cur_pilot);
|
|
}
|
|
|
|
// check if we have a valid pilot hilighted. If so, attempt to active it
|
|
if ((Num_pilots < 1) || (Selected_line < 0) || (Selected_line >= Num_pilots)) {
|
|
Cur_pilot->callsign[0] = 0; // this indicates no pilot active
|
|
return -1;
|
|
}
|
|
|
|
// check if the pilot is valid
|
|
// Also prompt if pilot has version mismatch
|
|
if (!valid_pilot(Pilots[Selected_line])) {
|
|
// pilot not valid or user opted not to select
|
|
Cur_pilot->callsign[0] = 0;
|
|
return -1;
|
|
}
|
|
|
|
if ( !Pilot.load_player(Pilots[Selected_line], Cur_pilot) ) {
|
|
// could not load, bail
|
|
Cur_pilot->callsign[0] = 0; // this indicates no pilot active
|
|
return -1;
|
|
}
|
|
|
|
if (!Pilot.load_savefile(Cur_pilot, Cur_pilot->current_campaign)) {
|
|
// set single player squad image to multi if campaign can't be loaded
|
|
strcpy_s(Cur_pilot->s_squad_filename, Cur_pilot->m_squad_filename);
|
|
}
|
|
|
|
// init stuff to reflect new pilot
|
|
int i;
|
|
scoring_struct pstats;
|
|
|
|
Pilot.export_stats(&pstats);
|
|
barracks_init_stats(&pstats);
|
|
|
|
strcpy_s(stripped, Cur_pilot->image_filename);
|
|
barracks_strip_pcx(stripped);
|
|
for (i=0; i<Num_pilot_images; i++) {
|
|
if (!stricmp(stripped, Pilot_image_names[i])) {
|
|
break;
|
|
}
|
|
}
|
|
Pic_number = i;
|
|
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
strcpy_s(stripped, Cur_pilot->m_squad_filename);
|
|
} else {
|
|
strcpy_s(stripped, Cur_pilot->s_squad_filename);
|
|
}
|
|
barracks_strip_pcx(stripped);
|
|
for ( i=0; i<Num_pilot_squad_images; i++) {
|
|
if (!stricmp(stripped, Pilot_squad_image_names[i])) {
|
|
break;
|
|
}
|
|
}
|
|
Pic_squad_number = i;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void barracks_set_callsign_enter_mode(bool set_callsign_enter_mode)
|
|
{
|
|
// set global mode variable
|
|
Barracks_callsign_enter_mode = set_callsign_enter_mode;
|
|
|
|
// disable/enable all buttons
|
|
for (int idx=0; idx<BARRACKS_NUM_BUTTONS; idx++) {
|
|
// don't ever mess with the prev and next squad logo buttons
|
|
if((idx != B_SQUAD_PREV_BUTTON) && (idx != B_SQUAD_NEXT_BUTTON)){
|
|
Buttons[gr_screen.res][idx].button.enable(!set_callsign_enter_mode);
|
|
}
|
|
}
|
|
|
|
// enable/disable hotkeys
|
|
barracks_set_hotkeys(!set_callsign_enter_mode);
|
|
// disable/enable inputbox
|
|
Inputbox.enable(set_callsign_enter_mode);
|
|
// hide/unhide inputbox
|
|
Inputbox.hide(!set_callsign_enter_mode);
|
|
}
|
|
|
|
// creates a new pilot file
|
|
void barracks_create_new_pilot()
|
|
{
|
|
// check if too many pilots
|
|
if (Num_pilots >= MAX_PILOTS) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
// play sound for pilot creation
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
|
|
// only write pilot file if there is an active pilot
|
|
if (strlen(Player->callsign)) {
|
|
Pilot.save_player(Player);
|
|
}
|
|
|
|
// move other pilot names and ranks down to make room for the new one
|
|
int idx = Num_pilots;
|
|
Assert(Num_pilots >= 0);
|
|
while (idx--) {
|
|
strcpy(Pilots[idx + 1], Pilots[idx]);
|
|
Pilot_ranks[idx + 1] = Pilot_ranks[idx];
|
|
}
|
|
|
|
Selected_line = 0;
|
|
Num_pilots++;
|
|
Pilots[Selected_line][0] = 0;
|
|
Pilot_ranks[Selected_line] = 0;
|
|
List_scroll_offset = 0;
|
|
|
|
// set mode to accept pilot name text
|
|
barracks_set_callsign_enter_mode(true);
|
|
// set focus to input box
|
|
Inputbox.set_focus();
|
|
// set initial pilot name to ""
|
|
Inputbox.set_text("");
|
|
// reset size of input box to only 1 line
|
|
Inputbox.update_dimensions(Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_W_COORD], gr_get_font_height());
|
|
}
|
|
|
|
// exiting screen without canceling, so load in the new pilot selected here
|
|
int barracks_pilot_accepted()
|
|
{
|
|
// check if pilot active. If not, don't allow accept.
|
|
if (!Cur_pilot->callsign[0]){
|
|
return -1;
|
|
}
|
|
|
|
// check that pilot is OK
|
|
if (!valid_pilot(Cur_pilot->callsign)) {
|
|
return -1;
|
|
}
|
|
|
|
// set pilot image
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
player_set_squad_bitmap(Cur_pilot, Cur_pilot->m_squad_filename, true);
|
|
} else {
|
|
player_set_squad_bitmap(Cur_pilot, Cur_pilot->s_squad_filename, false);
|
|
}
|
|
|
|
// MWA -- I think that we should be writing Cur_pilot here.
|
|
Pilot.save_player(Cur_pilot);
|
|
|
|
os_config_write_string(NULL, "LastPlayer", Cur_pilot->callsign);
|
|
|
|
// set the local multi options from the player flags
|
|
multi_options_init_globals();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void barracks_accept_pilot(player* plr, bool changeState) {
|
|
// set pilot image
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
player_set_squad_bitmap(plr, plr->m_squad_filename, true);
|
|
} else {
|
|
player_set_squad_bitmap(plr, plr->s_squad_filename, false);
|
|
}
|
|
|
|
// MWA -- I think that we should be writing plr here.
|
|
Pilot.save_player(plr);
|
|
|
|
Player = &Players[Player_num];
|
|
Player->assign(plr);
|
|
|
|
// set the local multi options from the player flags
|
|
multi_options_init_globals();
|
|
|
|
os_config_write_string(nullptr, "LastPlayer", plr->callsign);
|
|
|
|
if (changeState) {
|
|
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
|
}
|
|
}
|
|
|
|
// scroll up barracks pilot list one line
|
|
void barracks_scroll_callsign_up()
|
|
{
|
|
if (Selected_line > 0) {
|
|
Selected_line--;
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
|
|
if ((Selected_line >= 0) && (Selected_line < List_scroll_offset)) {
|
|
List_scroll_offset = Selected_line;
|
|
}
|
|
}
|
|
|
|
// scroll down barracks pilot list one line
|
|
void barracks_scroll_callsign_down()
|
|
{
|
|
if (Selected_line < Num_pilots - 1) {
|
|
Selected_line++;
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
|
|
// num_pilots_to_fill_height is the number of pilots that can fit in given height
|
|
int num_pilots_to_fill_height = Barracks_list_coords[gr_screen.res][BARRACKS_H_COORD] / gr_get_font_height();
|
|
if (Selected_line >= List_scroll_offset + num_pilots_to_fill_height) {
|
|
List_scroll_offset++;
|
|
}
|
|
}
|
|
|
|
// scroll up barracks stats list one line
|
|
void barracks_scroll_stats_up()
|
|
{
|
|
if (Stats_scroll_offset > 0) {
|
|
Stats_scroll_offset--;
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
}
|
|
|
|
// scroll down barracks stats list one line
|
|
void barracks_scroll_stats_down()
|
|
{
|
|
int font_height = gr_get_font_height();
|
|
|
|
if (Stats_scroll_offset + Barracks_stats_coords[gr_screen.res][BARRACKS_H_COORD] / font_height < static_cast<int>(Num_stat_lines)) {
|
|
Stats_scroll_offset++;
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
}
|
|
|
|
// show previous pilot pic
|
|
void barracks_prev_pic()
|
|
{
|
|
// check if no pilot images or no pilot selected
|
|
if ((Num_pilot_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
// reset pilot pic number
|
|
Pic_number--;
|
|
if (Pic_number < 0) {
|
|
Pic_number = Num_pilot_images - 1;
|
|
}
|
|
|
|
// copy pilot pic filename into pilot struct
|
|
if ((Pic_number >= 0) && (Pic_number < Num_pilot_images)) {
|
|
strcpy_s(Cur_pilot->image_filename, Pilot_image_names[Pic_number]);
|
|
}
|
|
|
|
// play scroll sound
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
}
|
|
|
|
// show next pilot pic
|
|
void barracks_next_pic()
|
|
{
|
|
// check if no pilot images or no pilot selected
|
|
if ((Num_pilot_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
// reset pilot pic number
|
|
Pic_number++;
|
|
if (Pic_number >= Num_pilot_images){
|
|
Pic_number = 0;
|
|
}
|
|
|
|
// copy pilot pic filename into pilot struct
|
|
if ((Pic_number >= 0) && (Pic_number < Num_pilot_images)){
|
|
strcpy_s(Cur_pilot->image_filename, Pilot_image_names[Pic_number]);
|
|
}
|
|
|
|
// play scroll sound
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
}
|
|
|
|
// show previous squad pic
|
|
void barracks_prev_squad_pic()
|
|
{
|
|
// check if no squad images or no pilot selected
|
|
if ((Num_pilot_squad_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
// reset squad pic number
|
|
Pic_squad_number--;
|
|
if (Pic_squad_number < 0) {
|
|
Pic_squad_number = Num_pilot_squad_images - 1;
|
|
}
|
|
|
|
// copy squad pic filename into pilot struct
|
|
if ((Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)) {
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
strcpy_s(Cur_pilot->m_squad_filename, Pilot_squad_image_names[Pic_squad_number]);
|
|
} else {
|
|
strcpy_s(Cur_pilot->s_squad_filename, Pilot_squad_image_names[Pic_squad_number]);
|
|
}
|
|
}
|
|
|
|
// play scroll sound
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
}
|
|
|
|
// show next squad pic
|
|
void barracks_next_squad_pic()
|
|
{
|
|
// check if no squad images or no pilot selected
|
|
if ((Num_pilot_squad_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
// reset squad pic number
|
|
Pic_squad_number++;
|
|
if (Pic_squad_number >= Num_pilot_squad_images){
|
|
Pic_squad_number = 0;
|
|
}
|
|
|
|
// copy squad pic filename into pilot struct
|
|
if ((Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)){
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
strcpy_s(Cur_pilot->m_squad_filename, Pilot_squad_image_names[Pic_squad_number]);
|
|
} else {
|
|
strcpy_s(Cur_pilot->s_squad_filename, Pilot_squad_image_names[Pic_squad_number]);
|
|
}
|
|
}
|
|
|
|
// play scroll sound
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
}
|
|
|
|
void barracks_delete_pilot()
|
|
{
|
|
char buf[MAX_FILENAME_LEN];
|
|
int active = 0;
|
|
|
|
if (!Num_pilots) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
if (Player_sel_mode == PLAYER_SELECT_MODE_MULTI) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
popup(PF_TITLE_BIG | PF_TITLE_RED | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Disabled!\n\nMulti and single player pilots are now identical. "
|
|
"Deleting a multi-player pilot will also delete all single-player data for that pilot.\n\nAs a safety precaution, pilots can only be "
|
|
"deleted from the single-player menu.", 1598));
|
|
return;
|
|
}
|
|
|
|
int popup_rval = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_NO, POPUP_YES, XSTR( "Warning!\n\nAre you sure you wish to delete this pilot?", 65));
|
|
if (popup_rval != 1) {
|
|
return;
|
|
}
|
|
|
|
if (!stricmp(Pilots[Selected_line], Cur_pilot->callsign)) {
|
|
active = 1;
|
|
}
|
|
|
|
strcpy_s(buf, Pilots[Selected_line]);
|
|
|
|
auto del_rval = delete_pilot_file(buf);
|
|
|
|
if ( !del_rval ) {
|
|
popup(PF_USE_AFFIRMATIVE_ICON | PF_TITLE_BIG | PF_TITLE_RED, 1, POPUP_OK, XSTR("Error\nFailed to delete pilot file. File may be read-only.", 1599));
|
|
return;
|
|
} else {
|
|
if (active) {
|
|
Cur_pilot->callsign[0] = 0;
|
|
}
|
|
}
|
|
|
|
for (int i=Selected_line; i<Num_pilots-1; i++) {
|
|
strcpy(Pilots[i], Pilots[i + 1]);
|
|
Pilot_ranks[i] = Pilot_ranks[i + 1];
|
|
}
|
|
|
|
Num_pilots--;
|
|
if (Selected_line >= Num_pilots) {
|
|
Selected_line = Num_pilots - 1;
|
|
}
|
|
|
|
if (active) {
|
|
if (Selected_line >= 0) {
|
|
barracks_new_pilot_selected();
|
|
} else {
|
|
Cur_pilot->callsign[0] = 0;
|
|
}
|
|
}
|
|
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
}
|
|
|
|
// Filter out pilots of wrong type (which shouldn't be in the directory we are checking, but just to be safe..)
|
|
int barracks_pilot_filter(const char *filename)
|
|
{
|
|
bool r = false;
|
|
int rank = 0;
|
|
|
|
r = Pilot.verify(filename, &rank);
|
|
|
|
if (rank >= Rank_pips_count)
|
|
rank = Rank_pips_count - 1;
|
|
|
|
if (r) {
|
|
Pilot_ranks[Num_pilots++] = rank;
|
|
}
|
|
|
|
return (int)r;
|
|
}
|
|
|
|
// callback handler for the squadon selection buttons when they are disabled (in single player)
|
|
void barracks_squad_change_popup()
|
|
{
|
|
// show a popup
|
|
popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR("You cannot change your squadron in Single Player mode.", 1445));
|
|
}
|
|
|
|
|
|
void barracks_init_player_stuff(int mode)
|
|
{
|
|
int i, j;
|
|
|
|
// determine if we should be looking for single or multiplayers at the outset
|
|
Player_sel_mode = mode;
|
|
|
|
// single player specific stuff
|
|
if (mode == PLAYER_SELECT_MODE_SINGLE) {
|
|
Game_mode &= ~GM_MULTIPLAYER;
|
|
Game_mode |= GM_NORMAL;
|
|
|
|
// disable squad logo switching
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.hide();
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.disable();
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.set_disabled_action(barracks_squad_change_popup);
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.hide();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.disable();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.set_disabled_action(barracks_squad_change_popup);
|
|
}
|
|
// multiplayer specific stuff
|
|
else if (mode == PLAYER_SELECT_MODE_MULTI) {
|
|
Game_mode &= ~GM_NORMAL;
|
|
Game_mode |= GM_MULTIPLAYER;
|
|
|
|
// enable squad logo switching
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.enable();
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.unhide();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.enable();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.unhide();
|
|
}
|
|
|
|
// get the list of pilots based upon whether we're in single or multiplayer mode
|
|
// moved down here so pilotfile::verify knows which Game_mode to get ranks for
|
|
Num_pilots = 0;
|
|
Get_file_list_filter = barracks_pilot_filter;
|
|
|
|
Num_pilots =
|
|
cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_PLAYERS, NOX("*.json"), CF_SORT_TIME,
|
|
nullptr, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT);
|
|
|
|
int ranks[MAX_PILOTS];
|
|
|
|
for (i=0; i<Num_pilots; i++) {
|
|
for (j=0; j<Num_pilots; j++) {
|
|
if (!strcmp(Pilots[i], Pilots_arr[j])) {
|
|
ranks[i] = Pilot_ranks[j];
|
|
break;
|
|
}
|
|
}
|
|
Assert(j < Num_pilots); // Pilot not found? How is that possible?
|
|
}
|
|
|
|
for (i=0; i<Num_pilots; i++) {
|
|
Pilot_ranks[i] = ranks[i];
|
|
}
|
|
|
|
Selected_line = List_scroll_offset = 0;
|
|
barracks_new_pilot_selected();
|
|
|
|
}
|
|
|
|
void barracks_button_pressed(int n)
|
|
{
|
|
switch (n) {
|
|
case B_PILOT_SCROLL_UP_BUTTON:
|
|
barracks_scroll_callsign_up();
|
|
break;
|
|
|
|
case B_PILOT_SCROLL_DOWN_BUTTON:
|
|
barracks_scroll_callsign_down();
|
|
break;
|
|
|
|
case B_STATS_SCROLL_UP_BUTTON:
|
|
barracks_scroll_stats_up();
|
|
break;
|
|
|
|
case B_STATS_SCROLL_DOWN_BUTTON:
|
|
barracks_scroll_stats_down();
|
|
break;
|
|
|
|
case B_PIC_PREV_PILOT_BUTTON:
|
|
barracks_prev_pic();
|
|
break;
|
|
|
|
case B_PIC_NEXT_PILOT_BUTTON:
|
|
barracks_next_pic();
|
|
break;
|
|
|
|
case B_SQUAD_PREV_BUTTON:
|
|
barracks_prev_squad_pic();
|
|
break;
|
|
|
|
case B_SQUAD_NEXT_BUTTON:
|
|
barracks_next_squad_pic();
|
|
break;
|
|
|
|
case B_PILOT_SET_ACTIVE_BUTTON:
|
|
if (barracks_new_pilot_selected()){
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
|
|
// if it's just the missing campaign file that failed for us then don't give the second popup
|
|
if (Campaign_file_missing) {
|
|
break;
|
|
}
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::SCROLL);
|
|
|
|
// we now have a new pilot, so try to load its current campaign, falling back if necessary
|
|
mission_load_up_campaign(true);
|
|
|
|
if (Campaign_file_missing) {
|
|
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found. Please select another...", 1600));
|
|
gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case B_ACCEPT_BUTTON:
|
|
if (Num_pilots && !barracks_pilot_accepted()) {
|
|
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
|
|
|
|
// we now have a new pilot, so try to load its current campaign, falling back if necessary
|
|
mission_load_up_campaign(true);
|
|
|
|
if (Campaign_file_missing) {
|
|
popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR( "The currently active campaign cannot be found. Please select another...", 1600));
|
|
gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM);
|
|
} else {
|
|
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
|
}
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
|
|
// if it's just the missing campaign file that failed for us then don't give the second popup
|
|
if (Campaign_file_missing) {
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case B_PILOT_CLONE_BUTTON:
|
|
if (Num_pilots < 1) {
|
|
gamesnd_play_error_beep();
|
|
break;
|
|
}
|
|
|
|
Clone_flag = 1;
|
|
barracks_create_new_pilot();
|
|
break;
|
|
|
|
case B_PILOT_CONVERT_BUTTON: {
|
|
/* New Pilot code no longer needs a conversion function. */
|
|
popup(PF_TITLE_BIG | PF_TITLE_BLUE | PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK,
|
|
XSTR("Disabled!\n\n\nMulti and Single Player Pilot files are now identical.\n\n"
|
|
"Conversion between the two is no longer necessary.", 1601));
|
|
/* // no actual conversion with new pilot code
|
|
if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
|
|
barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI);
|
|
} else {
|
|
// make sure we don't carry over the multi flag
|
|
if (Cur_pilot->flags & PLAYER_FLAGS_IS_MULTI) {
|
|
Cur_pilot->flags &= ~PLAYER_FLAGS_IS_MULTI;
|
|
}
|
|
barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE);
|
|
}
|
|
|
|
gamesnd_play_iface(SND_USER_SELECT); */
|
|
break;
|
|
}
|
|
|
|
case B_PILOT_CREATE_BUTTON:
|
|
Clone_flag = 0;
|
|
barracks_create_new_pilot();
|
|
break;
|
|
|
|
case B_HELP_BUTTON:
|
|
launch_context_help();
|
|
gamesnd_play_iface(InterfaceSounds::HELP_PRESSED);
|
|
break;
|
|
|
|
case B_OPTION_BUTTON:
|
|
gamesnd_play_iface(InterfaceSounds::SWITCH_SCREENS);
|
|
gameseq_post_event(GS_EVENT_OPTIONS_MENU);
|
|
break;
|
|
|
|
case B_STATS_MEDAL_BUTTON:
|
|
gamesnd_play_iface(InterfaceSounds::SWITCH_SCREENS);
|
|
gameseq_post_event(GS_EVENT_VIEW_MEDALS);
|
|
break;
|
|
|
|
case B_PILOT_DELETE_BUTTON:
|
|
barracks_delete_pilot();
|
|
break;
|
|
|
|
case B_PILOT_SINGLE_MODE_BUTTON:
|
|
if (Player_sel_mode != PLAYER_SELECT_MODE_SINGLE) {
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
// make sure we don't carry over the multi flag
|
|
if (Cur_pilot->flags & PLAYER_FLAGS_IS_MULTI) {
|
|
Cur_pilot->flags &= ~PLAYER_FLAGS_IS_MULTI;
|
|
Cur_pilot->player_was_multi = 0;
|
|
}
|
|
Pilot.save_player(Cur_pilot);
|
|
barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE);
|
|
}
|
|
break;
|
|
|
|
case B_PILOT_MULTI_MODE_BUTTON:
|
|
if (Player_sel_mode != PLAYER_SELECT_MODE_MULTI) {
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
Cur_pilot->flags |= PLAYER_FLAGS_IS_MULTI;
|
|
Cur_pilot->player_was_multi = 1;
|
|
Pilot.save_player(Cur_pilot);
|
|
barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void barracks_display_pilot_callsigns(int prospective_pilot)
|
|
{
|
|
int y = 0;
|
|
int cur_pilot_idx = List_scroll_offset;
|
|
|
|
int multi = 0;
|
|
if (Player_sel_mode == PLAYER_SELECT_MODE_MULTI) {
|
|
multi = 1;
|
|
}
|
|
|
|
int font_height = gr_get_font_height();
|
|
while (y + font_height <= Barracks_list_coords[gr_screen.res][BARRACKS_H_COORD]) {
|
|
if (cur_pilot_idx >= Num_pilots)
|
|
break;
|
|
|
|
if (!stricmp(Cur_pilot->callsign, Pilots[cur_pilot_idx]) && multi) {
|
|
gr_set_color_fast(&Color_text_active);
|
|
} else {
|
|
if (cur_pilot_idx == Selected_line) {
|
|
gr_set_color_fast(&Color_text_selected);
|
|
} else if (cur_pilot_idx == prospective_pilot) {
|
|
gr_set_color_fast(&Color_text_subselected);
|
|
} else {
|
|
gr_set_color_fast(&Color_text_normal);
|
|
}
|
|
}
|
|
|
|
gr_printf_menu(Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", Pilots[cur_pilot_idx]);
|
|
gr_set_bitmap(Rank_pips_bitmaps + Pilot_ranks[cur_pilot_idx]);
|
|
gr_bitmap(Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD] - 34, Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD] + y, GR_RESIZE_MENU);
|
|
|
|
y += font_height;
|
|
cur_pilot_idx++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void barracks_display_pilot_stats()
|
|
{
|
|
int y = 0;
|
|
int z = Stats_scroll_offset;
|
|
int font_height = gr_get_font_height();
|
|
char *str;
|
|
int i, w, h;
|
|
while (y + font_height <= Barracks_stats_coords[gr_screen.res][BARRACKS_H_COORD]) {
|
|
if (z >= (int)Num_stat_lines) {
|
|
break;
|
|
}
|
|
|
|
str = Stat_labels[z];
|
|
if (*str == '*') {
|
|
gr_set_color_fast(&Color_text_heading);
|
|
str++;
|
|
|
|
gr_get_string_size(&w, &h, str);
|
|
i = Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y + h / 2 - 1;
|
|
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD], i, Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width - w - 2, i, GR_RESIZE_MENU);
|
|
gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width + 1, i, Stats_X2 + Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD], i, GR_RESIZE_MENU);
|
|
|
|
} else {
|
|
gr_set_color_fast(&Color_text_normal);
|
|
}
|
|
|
|
gr_get_string_size(&w, NULL, str);
|
|
gr_printf_menu(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Stats_max_width - w, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
|
|
str = Stats[z];
|
|
if (*str) {
|
|
gr_printf_menu(Stats_X2, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
|
|
}
|
|
|
|
y += font_height;
|
|
z++;
|
|
}
|
|
}
|
|
|
|
|
|
// process pilot callsign
|
|
void barracks_accept_new_pilot_callsign()
|
|
{
|
|
char buf[CALLSIGN_LEN + 1];
|
|
char name[MAX_FILENAME_LEN];
|
|
int i;
|
|
|
|
int z = 0;
|
|
Inputbox.get_text(buf);
|
|
drop_white_space(buf);
|
|
|
|
if (!isalpha(*buf)) {
|
|
z = 1;
|
|
} else {
|
|
for (i=1; buf[i]; i++) {
|
|
if (!isalpha(buf[i]) && !isdigit(buf[i]) && !strchr(VALID_PILOT_CHARS, buf[i])) {
|
|
z = 1;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i=1; i<Num_pilots; i++) {
|
|
if (!stricmp(buf, Pilots[i])) {
|
|
z = 1;
|
|
if (pilot_verify_overwrite() == 1) {
|
|
strcpy_s(name, Pilots[Selected_line]);
|
|
for (z=i; z<Num_pilots-1; z++) {
|
|
strcpy(Pilots[z], Pilots[z + 1]);
|
|
Pilot_ranks[z] = Pilot_ranks[z + 1];
|
|
}
|
|
|
|
Num_pilots--;
|
|
delete_pilot_file(name);
|
|
z = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!*buf || (i < Num_pilots)) { // duplicate name, alert user
|
|
z = 1;
|
|
}
|
|
|
|
if (z) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
return;
|
|
}
|
|
|
|
strcpy(Pilots[0], buf);
|
|
strcpy_s(Cur_pilot->callsign, buf);
|
|
init_new_pilot(Cur_pilot, !Clone_flag);
|
|
|
|
// again, make sure we set his flags correctly to ensure that he gets saved to the proper directory and gets
|
|
// displayed correctly
|
|
if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
|
|
Cur_pilot->flags &= ~(PLAYER_FLAGS_IS_MULTI);
|
|
Cur_pilot->player_was_multi = 0;
|
|
} else {
|
|
Cur_pilot->flags |= PLAYER_FLAGS_IS_MULTI;
|
|
Cur_pilot->stats.flags |= STATS_FLAG_MULTIPLAYER;
|
|
Cur_pilot->player_was_multi = 1;
|
|
}
|
|
|
|
if ( !(Game_mode & GM_STANDALONE_SERVER) ) {
|
|
Pilot.save_player(Cur_pilot);
|
|
}
|
|
|
|
Selected_line = 0;
|
|
barracks_new_pilot_selected();
|
|
barracks_set_callsign_enter_mode(false);
|
|
}
|
|
|
|
|
|
// draw pilot image and clean up afterwards
|
|
void barracks_draw_pilot_pic()
|
|
{
|
|
// draw pilot pic
|
|
if (Cur_pilot->callsign[0] && (Pic_number >= 0) && (Pic_number < Num_pilot_images)) {
|
|
if (Pilot_images[Pic_number] >= 0) {
|
|
// JAS: This code is hacked to allow the animation to use all 256 colors
|
|
gr_set_bitmap(Pilot_images[Pic_number]);
|
|
gr_bitmap(Barracks_image_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_image_coords[gr_screen.res][BARRACKS_Y_COORD], GR_RESIZE_MENU);
|
|
|
|
// print number of the current pic
|
|
char buf[40];
|
|
sprintf(buf, XSTR( "%d of %d", 71), Pic_number + 1, Num_pilot_images);
|
|
gr_printf_menu(Barracks_image_number_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_image_number_coords[gr_screen.res][BARRACKS_Y_COORD], "%s", buf);
|
|
}
|
|
} else {
|
|
Pic_number = -1;
|
|
}
|
|
}
|
|
|
|
// draw squad image and clean up afterwards
|
|
void barracks_draw_squad_pic()
|
|
{
|
|
char buf[40];
|
|
|
|
// draw pilot pic
|
|
if (Cur_pilot->callsign[0] && (Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)) {
|
|
if (Pilot_squad_images[Pic_squad_number] >= 0) {
|
|
// JAS: This code is hacked to allow the animation to use all 256 colors
|
|
gr_set_bitmap(Pilot_squad_images[Pic_squad_number]);
|
|
gr_bitmap(Barracks_squad_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_squad_coords[gr_screen.res][BARRACKS_Y_COORD], GR_RESIZE_MENU);
|
|
|
|
// print number of current squad pic
|
|
if(Player_sel_mode != PLAYER_SELECT_MODE_SINGLE){
|
|
sprintf(buf,XSTR( "%d of %d", 71), Pic_squad_number+1, Num_pilot_squad_images);
|
|
gr_printf_menu(Barracks_squad_number_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_squad_number_coords[gr_screen.res][BARRACKS_Y_COORD], "%s", buf);
|
|
}
|
|
}
|
|
} else {
|
|
Pic_squad_number = -1;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
void barracks_init()
|
|
{
|
|
//Set these to null, 'cause they aren't allocated yet.
|
|
Stat_labels = NULL;
|
|
Stats = NULL;
|
|
|
|
UI_WINDOW *w = &Ui_window;
|
|
|
|
// save current pilot file, so we don't possibly loose it.
|
|
Pilot.save_player();
|
|
|
|
// create interface
|
|
Ui_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0);
|
|
Ui_window.set_mask_bmap(Barracks_bitmap_mask_fname[gr_screen.res]);
|
|
|
|
// load background bitmap
|
|
Background_bitmap = bm_load(Barracks_bitmap_fname[gr_screen.res]);
|
|
if(Background_bitmap < 0){
|
|
// we failed to load the bitmap - this is very bad
|
|
Int3();
|
|
}
|
|
|
|
// create buttons
|
|
int i;
|
|
for (i=0; i<BARRACKS_NUM_BUTTONS; i++) {
|
|
// create the object
|
|
Buttons[gr_screen.res][i].button.create(&Ui_window, "", Buttons[gr_screen.res][i].x, Buttons[gr_screen.res][i].y, 60, 30, Buttons[gr_screen.res][i].repeat, 1);
|
|
|
|
// set the sound to play when highlighted
|
|
Buttons[gr_screen.res][i].button.set_highlight_action(common_play_highlight_sound);
|
|
|
|
// set the ani for the button
|
|
Buttons[gr_screen.res][i].button.set_bmaps(Buttons[gr_screen.res][i].filename);
|
|
|
|
// set the hotspot
|
|
Buttons[gr_screen.res][i].button.link_hotspot(Buttons[gr_screen.res][i].hotspot);
|
|
}
|
|
|
|
// add all strings
|
|
w->add_XSTR("Create", 1034, Buttons[gr_screen.res][0].text_x, Buttons[gr_screen.res][0].text_y, &Buttons[gr_screen.res][0].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Accept", 1035, Buttons[gr_screen.res][5].text_x, Buttons[gr_screen.res][5].text_y, &Buttons[gr_screen.res][5].button, UI_XSTR_COLOR_PINK);
|
|
w->add_XSTR("Help", 928, Buttons[gr_screen.res][6].text_x, Buttons[gr_screen.res][6].text_y, &Buttons[gr_screen.res][6].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Options",1036, Buttons[gr_screen.res][7].text_x, Buttons[gr_screen.res][7].text_y, &Buttons[gr_screen.res][7].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Medals", 1037, Buttons[gr_screen.res][8].text_x, Buttons[gr_screen.res][8].text_y, &Buttons[gr_screen.res][8].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Remove", 1038, Buttons[gr_screen.res][11].text_x, Buttons[gr_screen.res][11].text_y, &Buttons[gr_screen.res][11].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Select", 1552, Buttons[gr_screen.res][12].text_x, Buttons[gr_screen.res][12].text_y, &Buttons[gr_screen.res][12].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Clone", 1040, Buttons[gr_screen.res][13].text_x, Buttons[gr_screen.res][13].text_y, &Buttons[gr_screen.res][13].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Single", 1041, Buttons[gr_screen.res][14].text_x, Buttons[gr_screen.res][14].text_y, &Buttons[gr_screen.res][14].button, UI_XSTR_COLOR_GREEN);
|
|
w->add_XSTR("Multi", 1042, Buttons[gr_screen.res][15].text_x, Buttons[gr_screen.res][15].text_y, &Buttons[gr_screen.res][15].button, UI_XSTR_COLOR_GREEN);
|
|
// w->add_XSTR("Convert",1043, Buttons[gr_screen.res][16].text_x, Buttons[gr_screen.res][16].text_y, &Buttons[gr_screen.res][16].button, UI_XSTR_COLOR_GREEN);
|
|
for(i=0; i<BARRACKS_NUM_TEXT; i++) {
|
|
w->add_XSTR(&Barracks_text[gr_screen.res][i]);
|
|
}
|
|
|
|
// button for selecting pilot
|
|
List_region.create(&Ui_window, "", Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_W_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_H_COORD], 0, 1);
|
|
List_region.hide();
|
|
|
|
// create input box (for new pilot)
|
|
Inputbox.create(&Ui_window, Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_W_COORD], CALLSIGN_LEN - 1, "", UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_KEYTHRU | UI_INPUTBOX_FLAG_LETTER_FIRST);
|
|
Inputbox.set_valid_chars(VALID_PILOT_CHARS);
|
|
Inputbox.disable();
|
|
Inputbox.hide();
|
|
|
|
// load in help overlay bitmap
|
|
Barracks_overlay_id = help_overlay_get_index(BARRACKS_OVERLAY);
|
|
help_overlay_set_state(Barracks_overlay_id,gr_screen.res,0);
|
|
|
|
// other init stuff
|
|
Barracks_callsign_enter_mode = 0;
|
|
List_scroll_offset = Stats_scroll_offset = Pic_number = Pic_squad_number = Selected_line = 0;
|
|
Cur_pilot = &Players[Player_num];
|
|
|
|
// disable squad logo selection buttons in single player
|
|
if(!(Cur_pilot->flags & PLAYER_FLAGS_IS_MULTI)){
|
|
// squad logo picture buttons
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.hide();
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.disable();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.hide();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.disable();
|
|
} else {
|
|
// squad logo picture buttons
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.enable();
|
|
Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.unhide();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.enable();
|
|
Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.unhide();
|
|
}
|
|
|
|
// set up hotkeys for buttons so we draw the correct animation frame when a key is pressed
|
|
barracks_set_hotkeys(1);
|
|
|
|
// load ramp pips
|
|
Rank_pips_bitmaps = bm_load_animation("IconRankMini.ani", &Rank_pips_count);
|
|
|
|
// load up the pilot pic list
|
|
pilot_load_pic_list();
|
|
pilot_load_squad_pic_list();
|
|
|
|
// don't load pilot images yet
|
|
for (i=0; i<MAX_PILOT_IMAGES; i++) {
|
|
Pilot_images[i] = BARRACKS_IMAGE_NOT_LOADED; // while -1 is can't load
|
|
Pilot_squad_images[i] = BARRACKS_IMAGE_NOT_LOADED;
|
|
}
|
|
|
|
// init stats
|
|
barracks_init_stats(&Cur_pilot->stats);
|
|
|
|
// base the mode we're in (single or multi) on the status of the currently selected pilot
|
|
barracks_init_player_stuff((Game_mode & GM_MULTIPLAYER) == GM_MULTIPLAYER);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
void barracks_do_frame(float /*frametime*/)
|
|
{
|
|
int k = Ui_window.process();
|
|
|
|
if ( k > 0 ) {
|
|
if ( help_overlay_active(Barracks_overlay_id) ) {
|
|
help_overlay_set_state(Barracks_overlay_id,gr_screen.res,0);
|
|
k = 0;
|
|
}
|
|
}
|
|
|
|
// pilot that mouse is over
|
|
int prospective_pilot = -1;
|
|
int i;
|
|
|
|
// Entering pilot callsign
|
|
if (Barracks_callsign_enter_mode) {
|
|
// set focus to inputbox
|
|
Inputbox.set_focus();
|
|
|
|
switch (k) {
|
|
case KEY_ESC:
|
|
// cancel create pilot
|
|
Num_pilots--;
|
|
for (i=0; i<Num_pilots; i++) {
|
|
strcpy(Pilots[i], Pilots[i + 1]);
|
|
Pilot_ranks[i] = Pilot_ranks[i + 1];
|
|
}
|
|
|
|
barracks_set_callsign_enter_mode(false);
|
|
break;
|
|
|
|
case KEY_ENTER:
|
|
barracks_accept_new_pilot_callsign();
|
|
break;
|
|
}
|
|
} else {
|
|
// not entering pilot callsign
|
|
switch (k) {
|
|
case KEY_ENTER:
|
|
if (barracks_new_pilot_selected()) {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
}
|
|
break;
|
|
|
|
case KEY_ESC: // cancel
|
|
if (!help_overlay_active(Barracks_overlay_id)) {
|
|
if (Num_pilots && !barracks_pilot_accepted()) {
|
|
gameseq_post_event(GS_EVENT_MAIN_MENU);
|
|
} else {
|
|
gamesnd_play_iface(InterfaceSounds::GENERAL_FAIL);
|
|
}
|
|
} else {
|
|
// kill the overlay
|
|
help_overlay_set_state(Barracks_overlay_id,gr_screen.res,0);
|
|
}
|
|
break;
|
|
|
|
case KEY_TAB: // switch mode (simgle/multi)
|
|
if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
|
|
Cur_pilot->flags |= PLAYER_FLAGS_IS_MULTI;
|
|
Cur_pilot->player_was_multi = 1;
|
|
Pilot.save_player(Cur_pilot);
|
|
barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI);
|
|
} else {
|
|
// make sure we don't carry over the multi flag
|
|
Cur_pilot->flags &= ~PLAYER_FLAGS_IS_MULTI;
|
|
Cur_pilot->player_was_multi = 0;
|
|
Pilot.save_player(Cur_pilot);
|
|
barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE);
|
|
}
|
|
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
break;
|
|
|
|
case KEY_F1: // show help overlay
|
|
gamesnd_play_iface(InterfaceSounds::HELP_PRESSED);
|
|
break;
|
|
|
|
case KEY_F2: // goto options screen
|
|
gamesnd_play_iface(InterfaceSounds::SWITCH_SCREENS);
|
|
gameseq_post_event(GS_EVENT_OPTIONS_MENU);
|
|
break;
|
|
} // end switch
|
|
|
|
// process buttons
|
|
for (i=0; i<BARRACKS_NUM_BUTTONS; i++) {
|
|
if (Buttons[gr_screen.res][i].button.pressed()) {
|
|
barracks_button_pressed(i);
|
|
}
|
|
}
|
|
|
|
// if mouse is over a pilot, find index into Pilots array
|
|
if (List_region.is_mouse_on()) {
|
|
int y;
|
|
List_region.get_mouse_pos(NULL, &y);
|
|
int pilot_index = List_scroll_offset + (y / gr_get_font_height());
|
|
if ((pilot_index >= 0) && (pilot_index < Num_pilots)) {
|
|
prospective_pilot = pilot_index;
|
|
}
|
|
}
|
|
|
|
// if mouse clicked in list region, find index into Pilots array
|
|
if (List_region.pressed()) {
|
|
if (prospective_pilot != -1) {
|
|
Selected_line = prospective_pilot;
|
|
gamesnd_play_iface(InterfaceSounds::USER_SELECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check mouse over help
|
|
if (mouse_down(CC_bind(CID_MOUSE, MOUSE_LEFT_BUTTON))) {
|
|
help_overlay_set_state(Barracks_overlay_id, gr_screen.res, 0);
|
|
}
|
|
|
|
// do pilot pic stuff
|
|
if ((Pic_number >= 0) && (Pic_number < Num_pilot_images)) {
|
|
if (Pilot_images[Pic_number] == BARRACKS_IMAGE_NOT_LOADED) { // haven't tried loading it yet
|
|
Pilot_images[Pic_number] = bm_load(Pilot_image_names[Pic_number]);
|
|
if (Pilot_images[Pic_number] >= 0) {
|
|
int w, h;
|
|
|
|
bm_get_info(Pilot_images[Pic_number], &w, &h, NULL);
|
|
// check for invalid pilot pic file
|
|
if ((w != PLAYER_PILOT_PIC_W) || (h != PLAYER_PILOT_PIC_H)) {
|
|
bm_release(Pilot_images[Pic_number]);
|
|
Pilot_images[Pic_number] = -1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
Pic_number = -1;
|
|
}
|
|
|
|
// do squad pic stuff
|
|
if ((Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)) {
|
|
if (Pilot_squad_images[Pic_squad_number] == BARRACKS_IMAGE_NOT_LOADED) { // haven't tried loading it yet
|
|
Pilot_squad_images[Pic_squad_number] = bm_load_duplicate(Pilot_squad_image_names[Pic_squad_number]);
|
|
if (Pilot_squad_images[Pic_squad_number] >= 0) {
|
|
int w, h;
|
|
|
|
bm_get_info(Pilot_squad_images[Pic_squad_number], &w, &h, NULL);
|
|
// check for invalid pilot pic file
|
|
if ((w != PLAYER_SQUAD_PIC_W) || (h != PLAYER_SQUAD_PIC_H)) {
|
|
bm_release(Pilot_squad_images[Pic_squad_number]);
|
|
Pilot_squad_images[Pic_squad_number] = -1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
Pic_squad_number = -1;
|
|
}
|
|
|
|
// draw the background, etc
|
|
gr_reset_clip();
|
|
GR_MAYBE_CLEAR_RES(Background_bitmap);
|
|
if (Background_bitmap >= 0) {
|
|
gr_set_bitmap(Background_bitmap);
|
|
gr_bitmap(0, 0, GR_RESIZE_MENU);
|
|
}
|
|
|
|
// draw pilot image and clean up afterwards
|
|
barracks_draw_pilot_pic();
|
|
barracks_draw_squad_pic();
|
|
|
|
// draw the window
|
|
Ui_window.draw();
|
|
|
|
// light up the correct mode button (single or multi)
|
|
if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
|
|
Buttons[gr_screen.res][B_PILOT_SINGLE_MODE_BUTTON].button.draw_forced(2);
|
|
} else {
|
|
Buttons[gr_screen.res][B_PILOT_MULTI_MODE_BUTTON].button.draw_forced(2);
|
|
}
|
|
|
|
// write out pilot call signs
|
|
barracks_display_pilot_callsigns(prospective_pilot);
|
|
|
|
// write out current pilot stats
|
|
barracks_display_pilot_stats();
|
|
|
|
// blit help overlay if active
|
|
help_overlay_maybe_blit(Barracks_overlay_id, gr_screen.res);
|
|
|
|
// flip the page
|
|
gr_flip();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
void barracks_close()
|
|
{
|
|
// destroy window
|
|
Ui_window.destroy();
|
|
|
|
// release background bitmap
|
|
if (Background_bitmap >= 0) {
|
|
bm_release(Background_bitmap);
|
|
}
|
|
|
|
// release rank pip bitmaps
|
|
bm_release(Rank_pips_bitmaps);
|
|
|
|
// release pilot pic bitmaps
|
|
for (int i=0; i<Num_pilot_images; i++) {
|
|
if (Pilot_images[i] >= 0) {
|
|
bm_release(Pilot_images[i]);
|
|
}
|
|
}
|
|
|
|
if(Stat_labels != NULL)
|
|
{
|
|
delete[] Stat_labels;
|
|
Stat_labels = NULL;
|
|
}
|
|
if(Stats != NULL)
|
|
{
|
|
delete[] Stats;
|
|
Stats = NULL;
|
|
}
|
|
|
|
game_flush();
|
|
}
|