mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-06-10 20:58:16 -04:00
5872 lines
126 KiB
C
5872 lines
126 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/camdraw.h"
|
|
#include "game/tex.h"
|
|
#include "game/savebuffer.h"
|
|
#include "game/menu.h"
|
|
#include "game/mainmenu.h"
|
|
#include "game/filemgr.h"
|
|
#include "game/text.h"
|
|
#include "game/music.h"
|
|
#include "game/mplayer/ingame.h"
|
|
#include "game/mplayer/setup.h"
|
|
#include "game/mplayer/scenarios.h"
|
|
#include "game/challenge.h"
|
|
#include "game/lang.h"
|
|
#include "game/mplayer/mplayer.h"
|
|
#include "game/options.h"
|
|
#include "bss.h"
|
|
#include "lib/snd.h"
|
|
#include "lib/vi.h"
|
|
#include "lib/rng.h"
|
|
#include "lib/str.h"
|
|
#include "data.h"
|
|
#include "gbiex.h"
|
|
#include "types.h"
|
|
|
|
struct menuitem g_MpCharacterMenuItems[];
|
|
struct menudialogdef g_MpAddSimulantMenuDialog;
|
|
struct menudialogdef g_MpChangeSimulantMenuDialog;
|
|
struct menudialogdef g_MpChangeTeamNameMenuDialog;
|
|
struct menudialogdef g_MpEditSimulantMenuDialog;
|
|
struct menudialogdef g_MpSaveSetupNameMenuDialog;
|
|
|
|
void func0f17b8f0(void);
|
|
MenuItemHandlerResult menuhandler0017e9d8(s32 operation, struct menuitem *item, union handlerdata *data);
|
|
MenuItemHandlerResult menuhandler_mp_start_challenge(s32 operation, struct menuitem *item, union handlerdata *data);
|
|
MenuItemHandlerResult menuhandler_mp_abort_challenge(s32 operation, struct menuitem *item, union handlerdata *data);
|
|
MenuItemHandlerResult menuhandler0017ec64(s32 operation, struct menuitem *item, union handlerdata *data);
|
|
void mp_close_dialogs_for_new_setup(void);
|
|
|
|
MenuItemHandlerResult menuhandler_mp_drop_out(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menu_pop_dialog();
|
|
menu_pop_dialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_get_current_player_name(struct menuitem *item)
|
|
{
|
|
return g_PlayerConfigsArray[g_MpPlayerNum].base.name;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_teams_label(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKDISABLED) {
|
|
if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_MpDropOutMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_196, // "Are you sure you want to drop out?"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_197, // "Drop Out"
|
|
0,
|
|
menuhandler_mp_drop_out,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_198, // "Cancel"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpDropOutMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_MPMENU_195, // "Drop Out"
|
|
g_MpDropOutMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct mparena g_MpArenas[] = {
|
|
// Stage, unlock, name
|
|
{ STAGE_MP_SKEDAR, 0, L_MPMENU_119 },
|
|
{ STAGE_MP_PIPES, 0, L_MPMENU_120 },
|
|
{ STAGE_MP_RAVINE, MPFEATURE_STAGE_RAVINE, L_MPMENU_121 },
|
|
{ STAGE_MP_G5BUILDING, MPFEATURE_STAGE_G5BUILDING, L_MPMENU_122 },
|
|
{ STAGE_MP_SEWERS, MPFEATURE_STAGE_SEWERS, L_MPMENU_123 },
|
|
{ STAGE_MP_WAREHOUSE, MPFEATURE_STAGE_WAREHOUSE, L_MPMENU_124 },
|
|
{ STAGE_MP_GRID, MPFEATURE_STAGE_GRID, L_MPMENU_125 },
|
|
{ STAGE_MP_RUINS, MPFEATURE_STAGE_RUINS, L_MPMENU_126 },
|
|
{ STAGE_MP_AREA52, 0, L_MPMENU_127 },
|
|
{ STAGE_MP_BASE, MPFEATURE_STAGE_BASE, L_MPMENU_128 },
|
|
{ STAGE_MP_FORTRESS, MPFEATURE_STAGE_FORTRESS, L_MPMENU_130 },
|
|
{ STAGE_MP_VILLA, MPFEATURE_STAGE_VILLA, L_MPMENU_131 },
|
|
{ STAGE_MP_CARPARK, MPFEATURE_STAGE_CARPARK, L_MPMENU_132 },
|
|
{ STAGE_MP_TEMPLE, MPFEATURE_STAGE_TEMPLE, L_MPMENU_133 },
|
|
{ STAGE_MP_COMPLEX, MPFEATURE_STAGE_COMPLEX, L_MPMENU_134 },
|
|
{ STAGE_MP_FELICITY, MPFEATURE_STAGE_FELICITY, L_MPMENU_135 },
|
|
{ 1, 0, L_MPMENU_136 }, // "Random"
|
|
};
|
|
|
|
s32 mp_get_num_stages(void)
|
|
{
|
|
return 17;
|
|
}
|
|
|
|
s16 mp_choose_random_stage(void)
|
|
{
|
|
s32 i;
|
|
s32 numchallengescomplete = 0;
|
|
s32 index;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
if (challenge_is_feature_unlocked(g_MpArenas[i].requirefeature)) {
|
|
numchallengescomplete++;
|
|
}
|
|
}
|
|
|
|
index = random() % numchallengescomplete;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
if (challenge_is_feature_unlocked(g_MpArenas[i].requirefeature)) {
|
|
if (index == 0) {
|
|
return g_MpArenas[i].stagenum;
|
|
}
|
|
|
|
index--;
|
|
}
|
|
}
|
|
|
|
return STAGE_MP_SKEDAR;
|
|
}
|
|
|
|
MenuItemHandlerResult mp_arena_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
struct optiongroup groups[] = {
|
|
{ 0, L_MPMENU_116 }, // "Dark"
|
|
{ 13, L_MPMENU_117 }, // "Classic"
|
|
{ 16, L_MPMENU_118 }, // "Random"
|
|
};
|
|
|
|
s32 i;
|
|
s32 count = 0;
|
|
s32 groupindex;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (challenge_is_feature_unlocked(g_MpArenas[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->list.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (challenge_is_feature_unlocked(g_MpArenas[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
return (s32)lang_get(g_MpArenas[i].name);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_SET:
|
|
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (challenge_is_feature_unlocked(g_MpArenas[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
break;
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
g_MpSetup.stagenum = g_MpArenas[i].stagenum;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (g_MpSetup.stagenum == g_MpArenas[i].stagenum) {
|
|
data->list.value = count;
|
|
}
|
|
|
|
if (challenge_is_feature_unlocked(g_MpArenas[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = 3;
|
|
|
|
if (!challenge_is_feature_unlocked(MPFEATURE_STAGE_COMPLEX)
|
|
&& !challenge_is_feature_unlocked(MPFEATURE_STAGE_TEMPLE)
|
|
&& !challenge_is_feature_unlocked(MPFEATURE_STAGE_FELICITY)) {
|
|
data->list.value--;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
count = data->list.value;
|
|
|
|
if (!challenge_is_feature_unlocked(MPFEATURE_STAGE_COMPLEX)
|
|
&& !challenge_is_feature_unlocked(MPFEATURE_STAGE_TEMPLE)
|
|
&& !challenge_is_feature_unlocked(MPFEATURE_STAGE_FELICITY)
|
|
&& count > 0) {
|
|
count++;
|
|
}
|
|
return (s32)lang_get(groups[count].name);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
groupindex = data->list.value;
|
|
|
|
if (!challenge_is_feature_unlocked(MPFEATURE_STAGE_COMPLEX)
|
|
&& !challenge_is_feature_unlocked(MPFEATURE_STAGE_TEMPLE)
|
|
&& !challenge_is_feature_unlocked(MPFEATURE_STAGE_FELICITY)
|
|
&& groupindex == 1) {
|
|
groupindex++;
|
|
}
|
|
|
|
for (i = 0; i < groups[groupindex].offset; i++) {
|
|
if (challenge_is_feature_unlocked(g_MpArenas[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
data->list.groupstartindex = count;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_control_style(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
u16 labels[] = {
|
|
L_OPTIONS_239, // "1.1"
|
|
L_OPTIONS_240, // "1.2"
|
|
L_OPTIONS_241, // "1.3"
|
|
L_OPTIONS_242, // "1.4"
|
|
};
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = 4;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
return (s32) lang_get(labels[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
options_set_control_mode(g_MpPlayerNum, data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = options_get_control_mode(g_MpPlayerNum);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_weapon_slot(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = mp_get_num_weapon_options();
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
return (s32) mp_get_weapon_label(data->dropdown.value);
|
|
case MENUOP_SET:
|
|
mp_set_weapon_slot(item->param3, data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = mp_get_weapon_slot(item->param3);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_weapon_name_for_slot(struct menuitem *item)
|
|
{
|
|
return mp_get_weapon_label(mp_get_weapon_slot(item->param));
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_weapon_set_dropdown(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = func0f189058(item->param);
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
return (s32) mp_get_weapon_set_name(data->dropdown.value);
|
|
case MENUOP_SET:
|
|
mp_set_weapon_set(data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = mp_get_weapon_set();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_control_checkbox(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 val;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GET:
|
|
if (item->param3 == OPTION_FORWARDPITCH) {
|
|
if ((g_PlayerConfigsArray[g_MpPlayerNum].options & item->param3) == 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
if ((g_PlayerConfigsArray[g_MpPlayerNum].options & item->param3) == 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
case MENUOP_SET:
|
|
val = OPTION_FORWARDPITCH;
|
|
|
|
if (item->param3 == val) {
|
|
if (data->checkbox.value == 0) {
|
|
data->checkbox.value = val;
|
|
} else {
|
|
data->checkbox.value = 0;
|
|
}
|
|
}
|
|
|
|
g_PlayerConfigsArray[g_MpPlayerNum].options &= ~item->param3;
|
|
|
|
if (data->checkbox.value) {
|
|
g_PlayerConfigsArray[g_MpPlayerNum].options |= item->param3;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_aim_control(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
u16 labels[] = {
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
L_MPWEAPONS_276, // "Hold"
|
|
L_MPWEAPONS_277, // "Toggle"
|
|
#else
|
|
L_MPMENU_213, // "Hold"
|
|
L_MPMENU_214, // "Toggle"
|
|
#endif
|
|
};
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = 2;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
return (s32) lang_get(labels[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
options_set_aim_control(g_MpPlayerNum, data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = options_get_aim_control(g_MpPlayerNum);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_checkbox_option(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GET:
|
|
if ((g_MpSetup.options & item->param3) == 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
case MENUOP_SET:
|
|
g_MpSetup.options = g_MpSetup.options & ~item->param3;
|
|
if (data->checkbox.value) {
|
|
g_MpSetup.options = g_MpSetup.options | item->param3;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_teams_enabled(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKDISABLED) {
|
|
if (g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE ||
|
|
g_MpSetup.scenario == MPSCENARIO_KINGOFTHEHILL) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return menuhandler_mp_checkbox_option(operation, item, data);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_display_option_checkbox(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GET:
|
|
if ((g_PlayerConfigsArray[g_MpPlayerNum].base.displayoptions & item->param3) == 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
case MENUOP_SET:
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.displayoptions &= ~(u8)item->param3;
|
|
|
|
if (data->checkbox.value) {
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.displayoptions |= (u8)item->param3;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_confirm_save_chr(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menu_pop_dialog();
|
|
filemgr_push_select_location_dialog(6, FILETYPE_MPPLAYER);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_setup_name(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
char *name = data->keyboard.string;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETTEXT:
|
|
strcpy(name, g_MpSetup.name);
|
|
break;
|
|
case MENUOP_SETTEXT:
|
|
strcpy(g_MpSetup.name, name);
|
|
break;
|
|
case MENUOP_SET:
|
|
filemgr_push_select_location_dialog(7, FILETYPE_MPSETUP);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_save_setup_overwrite(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menu_pop_dialog();
|
|
filemgr_save_or_load(&g_MpSetup.fileguid, FILEOP_SAVE_MPSETUP, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_save_setup_copy(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menu_pop_dialog();
|
|
menu_push_dialog(&g_MpSaveSetupNameMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
char *mp_menu_text_setup_name(struct menuitem *item)
|
|
{
|
|
return g_MpSetup.name;
|
|
}
|
|
#endif
|
|
|
|
MenuItemHandlerResult func0f179b68(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = g_PlayerConfigsArray[g_MpPlayerNum].base.unk18;
|
|
break;
|
|
case MENUOP_SET:
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.unk18 = (u8) data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
sprintf(data->slider.label, "%d%%\n", data->slider.value + 20);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult func0f179c14(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = g_PlayerConfigsArray[g_MpPlayerNum].base.unk1a;
|
|
break;
|
|
case MENUOP_SET:
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.unk1a = (u8) data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
sprintf(data->slider.label, "%d%%\n", data->slider.value + 20);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult func0f179cc0(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = g_PlayerConfigsArray[g_MpPlayerNum].base.unk1c;
|
|
break;
|
|
case MENUOP_SET:
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.unk1c = data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
sprintf(data->slider.label, "%d%%\n", data->slider.value + 25);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult func0f179d6c(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
func0f187fbc(g_MpPlayerNum);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* This function is used by both player body selection and bot body selection.
|
|
*/
|
|
MenuItemHandlerResult mp_character_body_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data, s32 mpbodynum, s32 mpheadnum, bool isplayer)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->carousel.value = mp_get_num_bodies();
|
|
break;
|
|
case MENUOP_11:
|
|
g_Menus[g_MpPlayerNum].menumodel.newanimnum = ANIM_01FC;
|
|
g_Menus[g_MpPlayerNum].menumodel.newparams = MENUMODELPARAMS_SET_MP_HEADBODY(mpheadnum, mpbodynum);
|
|
g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 += g_Vars.diffframe60;
|
|
|
|
if (g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 > TICKS(480)) {
|
|
g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 -= TICKS(480);
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].menumodel.rottimer60 > 0) {
|
|
g_Menus[g_MpPlayerNum].menumodel.rottimer60 -= g_Vars.diffframe60;
|
|
} else {
|
|
#if VERSION >= VERSION_PAL_BETA
|
|
f32 value = g_Menus[g_MpPlayerNum].menumodel.curroty + 0.01f * g_Vars.diffframe60freal;
|
|
#else
|
|
f32 value = g_Menus[g_MpPlayerNum].menumodel.curroty + 0.01f * g_Vars.diffframe60f;
|
|
#endif
|
|
g_Menus[g_MpPlayerNum].menumodel.newroty = value;
|
|
g_Menus[g_MpPlayerNum].menumodel.curroty = value;
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.partvisibility = NULL;
|
|
g_Menus[g_MpPlayerNum].menumodel.zoom = 30;
|
|
break;
|
|
case MENUOP_21:
|
|
if (!challenge_is_feature_unlocked(mp_get_body_required_feature(data->carousel.value))) {
|
|
return 1;
|
|
}
|
|
break;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
case MENUOP_FOCUS:
|
|
g_Menus[g_MpPlayerNum].menumodel.loaddelay = 3;
|
|
break;
|
|
#endif
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->carousel.value = mpbodynum;
|
|
break;
|
|
case MENUOP_SET:
|
|
case MENUOP_CHECKPREFOCUSED:
|
|
g_Menus[g_MpPlayerNum].menumodel.removingpiece = false;
|
|
|
|
menu_configure_model(&g_Menus[g_MpPlayerNum].menumodel, 0, 0, 0, 0, 0, 0, 1, MENUMODELFLAG_HASSCALE);
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curposx = 8.2f;
|
|
g_Menus[g_MpPlayerNum].menumodel.newposx = 8.2f;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curposy = -4.1f;
|
|
g_Menus[g_MpPlayerNum].menumodel.newposy = -4.1f;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curscale = 0.002f;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curroty = -0.2f;
|
|
g_Menus[g_MpPlayerNum].menumodel.newroty = -0.2f;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.rottimer60 = TICKS(60);
|
|
g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 = TICKS(120);
|
|
g_Menus[g_MpPlayerNum].menumodel.loaddelay = 8;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (operation == MENUOP_CHECKPREFOCUSED) {
|
|
g_Menus[g_MpPlayerNum].menumodel.loaddelay = 16;
|
|
}
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_character_body(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum < mp_get_num_heads()) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (!data->carousel.unk04)
|
|
#endif
|
|
{
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum = mp_get_mpheadnum_by_mpbodynum(data->carousel.value);
|
|
}
|
|
}
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum = data->carousel.value;
|
|
func0f17b8f0();
|
|
break;
|
|
case MENUOP_CHECKPREFOCUSED:
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
mp_character_body_menu_handler(operation, item, data,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, true);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
return mp_character_body_menu_handler(operation, item, data,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, true);
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog0017a174(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_OPEN:
|
|
break;
|
|
case MENUOP_CLOSE:
|
|
break;
|
|
case MENUOP_TICK:
|
|
if (g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
|
|
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[1]
|
|
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[2]) {
|
|
union handlerdata data;
|
|
menuhandler_mp_character_body(MENUOP_11, &dialogdef->items[2], &data);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult mp_challenges_list_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
Gfx *gdl;
|
|
struct menuitemrenderdata *renderdata;
|
|
s32 challengeindex;
|
|
s32 x;
|
|
s32 y;
|
|
s32 loopx;
|
|
s32 maxplayers;
|
|
s32 i;
|
|
char *name;
|
|
s32 size = 11;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = challenge_get_auto_focused_index(g_MpPlayerNum);
|
|
break;
|
|
case MENUOP_RENDER:
|
|
maxplayers = 4;
|
|
gdl = data->type19.gdl;
|
|
renderdata = data->type19.renderdata2;
|
|
challengeindex = data->list.unk04;
|
|
|
|
if (IS4MB()) {
|
|
maxplayers = 2;
|
|
}
|
|
|
|
x = renderdata->x + 10;
|
|
y = renderdata->y + 1;
|
|
|
|
gdl = text_begin(gdl);
|
|
|
|
name = challenge_get_name2(g_MpPlayerNum, challengeindex);
|
|
|
|
gdl = text_render_v2(gdl, &x, &y, name,
|
|
g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour,
|
|
vi_get_width(), vi_get_height(), 0, 0);
|
|
|
|
gdl = text_end(gdl);
|
|
|
|
gDPPipeSync(gdl++);
|
|
gDPSetTexturePersp(gdl++, G_TP_NONE);
|
|
gDPSetAlphaCompare(gdl++, G_AC_NONE);
|
|
gDPSetTextureLOD(gdl++, G_TL_TILE);
|
|
gDPSetTextureConvert(gdl++, G_TC_FILT);
|
|
|
|
tex_select(&gdl, &g_TexGeneralConfigs[35], 2, 0, 2, 1, NULL);
|
|
|
|
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
|
|
gDPSetTextureFilter(gdl++, G_TF_POINT);
|
|
|
|
for (i = 0, loopx = 10; i < maxplayers; i++) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (challenge_is_completed_by_player_with_num_players2(g_MpPlayerNum, challengeindex, i + 1)) {
|
|
gDPSetEnvColorViaWord(gdl++, 0xb2efff00 | (renderdata->colour & 0xff) * 255 / 256);
|
|
} else {
|
|
gDPSetEnvColorViaWord(gdl++, 0x30407000 | (renderdata->colour & 0xff) * 255 / 256);
|
|
}
|
|
#else
|
|
if (challenge_is_completed_by_player_with_num_players2(g_MpPlayerNum, challengeindex, i + 1)) {
|
|
gDPSetEnvColorViaWord(gdl++, 0xb2efffff);
|
|
} else {
|
|
gDPSetEnvColorViaWord(gdl++, 0x304070ff);
|
|
}
|
|
#endif
|
|
|
|
gDPSetCombineLERP(gdl++,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0);
|
|
|
|
gSPTextureRectangle(gdl++,
|
|
((renderdata->x + loopx) << 2) * g_UiScaleX,
|
|
(renderdata->y + size) << 2,
|
|
((renderdata->x + size + loopx) << 2) * g_UiScaleX,
|
|
(renderdata->y + size * 2) << 2,
|
|
G_TX_RENDERTILE,
|
|
0, 0x0160, 0x0400 / g_UiScaleX, 0xfc00);
|
|
|
|
loopx += 13;
|
|
}
|
|
|
|
return (s32) gdl;
|
|
case MENUOP_GETOPTIONHEIGHT:
|
|
data->list.value = 26;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char var7f1b7ea8[] = "Menu99 -> Calling Camera Module Start\n";
|
|
const char var7f1b7ed0[] = "Menu99 -> Calling Camera Module Finish\n";
|
|
|
|
char *mp_menu_text_kills(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].kills);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_deaths(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].deaths);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_games_played(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gamesplayed);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_games_won(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gameswon);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_games_lost(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gameslost);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_head_shots(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].headshots);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_medal_accuracy(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].accuracymedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_medal_head_shot(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].headshotmedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_medal_kill_master(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].killmastermedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_medal_survivor(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].survivormedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_ammo_used(struct menuitem *item)
|
|
{
|
|
s32 value = g_PlayerConfigsArray[g_MpPlayerNum].ammoused;
|
|
|
|
if (value > 100000) {
|
|
value = value / 1000;
|
|
|
|
if (value > 100000) {
|
|
value = value / 1000;
|
|
sprintf(g_StringPointer, "%dM\n", value);
|
|
} else {
|
|
sprintf(g_StringPointer, "%dK\n", value);
|
|
}
|
|
} else {
|
|
sprintf(g_StringPointer, "%d\n", value);
|
|
}
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_distance(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%s%s%.1fkm\n", "", "", g_PlayerConfigsArray[g_MpPlayerNum].distance / 10.0f);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_time(struct menuitem *item)
|
|
{
|
|
u32 raw = g_PlayerConfigsArray[g_MpPlayerNum].time;
|
|
s32 secs = raw % 60;
|
|
s32 hours;
|
|
s32 days;
|
|
|
|
if (raw == 0) {
|
|
return "--:--\n";
|
|
}
|
|
|
|
if (raw >= 0x7fffffff) {
|
|
return "==:==\n";
|
|
}
|
|
|
|
raw = raw / 60;
|
|
hours = raw / 60;
|
|
days = hours / 24;
|
|
|
|
if (days == 0) {
|
|
sprintf(g_StringPointer, "%d:%02d.%02d", hours % 24, raw % 60, secs);
|
|
} else {
|
|
sprintf(g_StringPointer, "%d:%02d:%02d", days, hours % 24, raw % 60);
|
|
}
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_accuracy(struct menuitem *item)
|
|
{
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].gamesplayed < 8) {
|
|
return "-\n";
|
|
}
|
|
#endif
|
|
|
|
sprintf(g_StringPointer, "%s%s%.1f%%", "", "", g_PlayerConfigsArray[g_MpPlayerNum].accuracy / 10.0f);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
void mp_format_damage_value(char *dst, f32 damage)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (damage < 1000) {
|
|
sprintf(dst, "%s%s%.1f", "", "", damage);
|
|
} else if (damage < 10000) {
|
|
sprintf(dst, "%s%s%.0f", "", "", damage);
|
|
} else if (damage < 100000) {
|
|
damage = damage / 1000;
|
|
sprintf(dst, "%s%s%.1fK", "", "", damage);
|
|
} else if (damage < 1000000) {
|
|
damage = damage / 1000;
|
|
sprintf(dst, "%s%s%.0fK", "", "", damage);
|
|
} else if (damage < 10000000) {
|
|
damage = damage / 1000;
|
|
damage = damage / 1000;
|
|
sprintf(dst, "%s%s%.1fM", "", "", damage);
|
|
} else {
|
|
damage = damage / 1000;
|
|
damage = damage / 1000;
|
|
sprintf(dst, "%s%s%.0fM", "", "", damage);
|
|
}
|
|
#else
|
|
if (damage > 100000) {
|
|
damage = damage / 1000;
|
|
sprintf(dst, "%s%s%.1fKL", "", "", damage);
|
|
} else {
|
|
sprintf(dst, "%s%s%.1fL", "", "", damage);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
char *mp_menu_text_pain_received(struct menuitem *item)
|
|
{
|
|
mp_format_damage_value(g_StringPointer, g_PlayerConfigsArray[g_MpPlayerNum].painreceived / 10.0f);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mp_menu_text_damage_dealt(struct menuitem *item)
|
|
{
|
|
mp_format_damage_value(g_StringPointer, g_PlayerConfigsArray[g_MpPlayerNum].damagedealt / 10.0f);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
MenuItemHandlerResult mp_medal_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_RENDER) {
|
|
Gfx *gdl = data->type19.gdl;
|
|
struct menuitemrenderdata *renderdata = data->type19.renderdata2;
|
|
u32 colour;
|
|
|
|
gDPPipeSync(gdl++);
|
|
gDPSetTexturePersp(gdl++, G_TP_NONE);
|
|
gDPSetAlphaCompare(gdl++, G_AC_NONE);
|
|
gDPSetTextureLOD(gdl++, G_TL_TILE);
|
|
gDPSetTextureConvert(gdl++, G_TC_FILT);
|
|
gDPSetTextureFilter(gdl++, G_TF_POINT);
|
|
|
|
tex_select(&gdl, &g_TexGeneralConfigs[35], 2, 0, 2, 1, NULL);
|
|
|
|
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
|
|
gDPSetCombineMode(gdl++, G_CC_DECALRGBA, G_CC_DECALRGBA);
|
|
gDPSetTextureFilter(gdl++, G_TF_POINT);
|
|
|
|
switch (item->param) {
|
|
case 0: // KillMaster - red
|
|
colour = 0xff7f7fff;
|
|
break;
|
|
case 1: // Headshot - yellow
|
|
colour = 0xbfbf00ff;
|
|
break;
|
|
case 2: // Accuracy - green
|
|
colour = 0x00ff00ff;
|
|
break;
|
|
case 3: // Survivor - blue
|
|
colour = 0x00bfbfff;
|
|
break;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
colour = (colour & 0xffffff00) | (colour & 0xff) * (renderdata->colour & 0xff) >> 8;
|
|
#endif
|
|
|
|
gDPSetEnvColorViaWord(gdl++, colour);
|
|
|
|
gDPSetCombineLERP(gdl++,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0);
|
|
|
|
gSPTextureRectangle(gdl++,
|
|
((renderdata->x + 9) << 2) * g_UiScaleX, renderdata->y << 2,
|
|
((renderdata->x + 20) << 2) * g_UiScaleX, (renderdata->y + 11) << 2,
|
|
G_TX_RENDERTILE, 0, 0x0160, 1024 / g_UiScaleX, -1024);
|
|
|
|
return (s32) gdl;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_title_stats_for_player_name(struct menudialogdef *dialogdef)
|
|
{
|
|
// "Stats for %s"
|
|
sprintf(g_StringPointer, lang_get(L_MPMENU_145), g_PlayerConfigsArray[g_MpPlayerNum].base.name);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_username_password(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].title != MPPLAYERTITLE_PERFECT) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_MpSavePlayerMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_191, // "Your player file is always saved automatically."
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_192, // "Save a copy now?"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_193, // "No"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_194, // "Yes"
|
|
0,
|
|
menuhandler_mp_confirm_save_chr,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSavePlayerMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_190, // "Confirm"
|
|
g_MpSavePlayerMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSaveSetupNameMenuItems[] = {
|
|
#if VERSION != VERSION_JPN_FINAL
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_189, // "Enter a name for your game setup file:"
|
|
0,
|
|
NULL,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_KEYBOARD,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
menuhandler_mp_setup_name,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSaveSetupNameMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_188, // "Game File Name"
|
|
g_MpSaveSetupNameMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSaveSetupExistsMenuItems[] = {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_MPWEAPONS_230, // "Name:"
|
|
(uintptr_t)&mp_menu_text_setup_name,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT,
|
|
(uintptr_t)&filemgr_menu_text_device_name,
|
|
0,
|
|
NULL,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_184, // "Do you want to save over your original game file?"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_185, // "Save Over Original"
|
|
0,
|
|
menuhandler_mp_save_setup_overwrite,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_186, // "Save Copy"
|
|
0,
|
|
menuhandler_mp_save_setup_copy,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_187, // "Do Not Save"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSaveSetupExistsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_183, // "Save Game Setup"
|
|
g_MpSaveSetupExistsMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpWeaponsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
1,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_174, // "Set:"
|
|
0,
|
|
menuhandler_mp_weapon_set_dropdown,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_MPMENU_175, // "Current Weapon Setup:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_176, // "1:"
|
|
0,
|
|
menuhandler_mp_weapon_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_177, // "2:"
|
|
1,
|
|
menuhandler_mp_weapon_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_178, // "3:"
|
|
2,
|
|
menuhandler_mp_weapon_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_179, // "4:"
|
|
3,
|
|
menuhandler_mp_weapon_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_180, // "5:"
|
|
4,
|
|
menuhandler_mp_weapon_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_181, // "6:"
|
|
5,
|
|
menuhandler_mp_weapon_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_182, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpWeaponsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_173, // "Weapons"
|
|
g_MpWeaponsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpQuickTeamWeaponsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_174, // "Set:"
|
|
0,
|
|
menuhandler_mp_weapon_set_dropdown,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_176, // "1:"
|
|
(uintptr_t)&mp_menu_text_weapon_name_for_slot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
1,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_177, // "2:"
|
|
(uintptr_t)&mp_menu_text_weapon_name_for_slot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
2,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_178, // "3:"
|
|
(uintptr_t)&mp_menu_text_weapon_name_for_slot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
3,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_179, // "4:"
|
|
(uintptr_t)&mp_menu_text_weapon_name_for_slot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
4,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_180, // "5:"
|
|
(uintptr_t)&mp_menu_text_weapon_name_for_slot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_182, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpQuickTeamWeaponsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_173, // "Weapons"
|
|
g_MpQuickTeamWeaponsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpPlayerOptionsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_168, // "Highlight Pickups"
|
|
MPDISPLAYOPTION_HIGHLIGHTPICKUPS,
|
|
menuhandler_mp_display_option_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_169, // "Highlight Players"
|
|
MPDISPLAYOPTION_HIGHLIGHTPLAYERS,
|
|
menuhandler_mp_display_option_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_170, // "Highlight Teams"
|
|
MPDISPLAYOPTION_HIGHLIGHTTEAMS,
|
|
menuhandler_mp_display_option_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_171, // "Radar"
|
|
MPDISPLAYOPTION_RADAR,
|
|
menuhandler_mp_display_option_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_172, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpPlayerOptionsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_167, // "Options"
|
|
g_MpPlayerOptionsMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpControlMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPMENU_200, // "Control Style"
|
|
0,
|
|
menuhandler_mp_control_style,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_201, // "Reverse Pitch"
|
|
OPTION_FORWARDPITCH,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_202, // "Look Ahead"
|
|
OPTION_LOOKAHEAD,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_203, // "Head Roll"
|
|
OPTION_HEADROLL,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_204, // "Auto-Aim"
|
|
OPTION_AUTOAIM,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPMENU_205, // "Aim Control"
|
|
0,
|
|
menuhandler_mp_aim_control,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_206, // "Sight on Screen"
|
|
OPTION_SIGHTONSCREEN,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_207, // "Show Target"
|
|
OPTION_ALWAYSSHOWTARGET,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_208, // "Zoom Range"
|
|
OPTION_SHOWZOOMRANGE,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_209, // "Ammo on Screen"
|
|
OPTION_AMMOONSCREEN,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_210, // "Gun Function"
|
|
OPTION_SHOWGUNFUNCTION,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_211, // "Paintball"
|
|
OPTION_PAINTBALL,
|
|
menuhandler_mp_control_checkbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_212, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpControlMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_199, // "Control"
|
|
g_MpControlMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpCompletedChallengesMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mp_challenges_list_handler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpCompletedChallengesMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_165, // "Completed Challenges"
|
|
g_MpCompletedChallengesMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
NULL,
|
|
};
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
char *mp_menu_text_username_password(struct menuitem *item)
|
|
{
|
|
// Phrases included here to assist people searching the code for them:
|
|
// EnTROpIcDeCAy
|
|
// ZeRo-Tau
|
|
|
|
u8 username[] = {
|
|
'E' + 9 * 1,
|
|
'n' + 9 * 2,
|
|
'T' + 9 * 3,
|
|
'R' + 9 * 4,
|
|
'O' + 9 * 5,
|
|
'p' + 9 * 6,
|
|
'I' + 9 * 7,
|
|
'c' + 9 * 8,
|
|
'D' + 9 * 9,
|
|
'e' + 9 * 10,
|
|
'C' + 9 * 11,
|
|
'A' + 9 * 12,
|
|
'y' + 9 * 13,
|
|
'\n' + 9 * 14,
|
|
'\0' + 9 * 15,
|
|
};
|
|
|
|
u8 password[] = {
|
|
'Z' + 4 * 1,
|
|
'e' + 4 * 2,
|
|
'R' + 4 * 3,
|
|
'o' + 4 * 4,
|
|
'-' + 4 * 5,
|
|
'T' + 4 * 6,
|
|
'a' + 4 * 7,
|
|
'u' + 4 * 8,
|
|
'\n' + 4 * 9,
|
|
'\0' + 4 * 10,
|
|
};
|
|
|
|
u32 stack;
|
|
s32 i;
|
|
|
|
if (item->param == 0) {
|
|
for (i = 0; i < ARRAYCOUNT(username); i++) {
|
|
g_StringPointer[i] = username[i] - i * 9 - 9;
|
|
}
|
|
} else {
|
|
for (i = 0; i < ARRAYCOUNT(password); i++) {
|
|
g_StringPointer[i] = password[i] - i * 4 - 4;
|
|
}
|
|
}
|
|
|
|
return g_StringPointer;
|
|
}
|
|
#endif
|
|
|
|
struct menuitem g_MpPlayerStatsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_146, // "Kills:"
|
|
(uintptr_t)&mp_menu_text_kills,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_147, // "Deaths:"
|
|
(uintptr_t)&mp_menu_text_deaths,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_148, // "Accuracy:"
|
|
(uintptr_t)&mp_menu_text_accuracy,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_149, // "Head Shots:"
|
|
(uintptr_t)&mp_menu_text_head_shots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_150, // "Ammo Used:"
|
|
(uintptr_t)&mp_menu_text_ammo_used,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_151, // "Damage Dealt:"
|
|
(uintptr_t)&mp_menu_text_damage_dealt,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_152, // "Pain Received:"
|
|
(uintptr_t)&mp_menu_text_pain_received,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_153, // "Games Played:"
|
|
(uintptr_t)&mp_menu_text_games_played,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_154, // "Games Won:"
|
|
(uintptr_t)&mp_menu_text_games_won,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_155, // "Games Lost:"
|
|
(uintptr_t)&mp_menu_text_games_lost,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_156, // "Time:"
|
|
(uintptr_t)&mp_menu_text_time,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_157, // "Distance:"
|
|
(uintptr_t)&mp_menu_text_distance,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_MPMENU_158, // "Medals Won:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
2,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
L_MPMENU_159, // "Accuracy:"
|
|
(uintptr_t)&mp_menu_text_medal_accuracy,
|
|
mp_medal_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
1,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
L_MPMENU_160, // "Head Shot:"
|
|
(uintptr_t)&mp_menu_text_medal_head_shot,
|
|
mp_medal_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
L_MPMENU_161, // "KillMaster:"
|
|
(uintptr_t)&mp_menu_text_medal_kill_master,
|
|
mp_medal_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
3,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
L_MPMENU_162, // "Survivor:"
|
|
(uintptr_t)&mp_menu_text_medal_survivor,
|
|
mp_medal_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_163, // "Your Title:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
(uintptr_t)&mp_menu_text_player_title,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_MPWEAPONS_219, // "USERNAME:"
|
|
0,
|
|
menuhandler_mp_username_password,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
(uintptr_t)&mp_menu_text_username_password,
|
|
#else
|
|
0x51f0,
|
|
#endif
|
|
0,
|
|
menuhandler_mp_username_password,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_MPWEAPONS_220, // "PASSWORD:"
|
|
0,
|
|
menuhandler_mp_username_password,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
(VERSION >= VERSION_NTSC_1_0 ? 1 : 0),
|
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
(uintptr_t)&mp_menu_text_username_password,
|
|
#else
|
|
0x51f1,
|
|
#endif
|
|
0,
|
|
menuhandler_mp_username_password,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_164, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpPlayerStatsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(uintptr_t)&mp_menu_title_stats_for_player_name,
|
|
g_MpPlayerStatsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_MpCompletedChallengesMenuDialog,
|
|
};
|
|
|
|
MenuItemHandlerResult mp_character_head_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data, s32 mpheadnum, bool arg4)
|
|
{
|
|
f32 diffframe;
|
|
s32 headnum;
|
|
|
|
static struct modelpartvisibility visibility[] = {
|
|
{ MODELPART_HEAD_SUNGLASSES, false },
|
|
{ MODELPART_HEAD_EYESCLOSED, false },
|
|
{ MODELPART_HEAD_HUDPIECE, false },
|
|
{ 255, false },
|
|
};
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->carousel.value = mp_get_num_heads2();
|
|
break;
|
|
case MENUOP_11:
|
|
#if VERSION >= VERSION_PAL_BETA
|
|
diffframe = g_Menus[g_MpPlayerNum].menumodel.curroty + 0.01f * g_Vars.diffframe60freal;
|
|
#else
|
|
diffframe = g_Menus[g_MpPlayerNum].menumodel.curroty + 0.01f * g_Vars.diffframe60f;
|
|
#endif
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.newroty = diffframe;
|
|
g_Menus[g_MpPlayerNum].menumodel.curroty = diffframe;
|
|
|
|
if (mpheadnum < mp_get_num_heads2()) {
|
|
headnum = mp_get_head_id(mpheadnum);
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.newparams = MENUMODELPARAMS_SET_FILENUM(g_HeadsAndBodies[headnum].filenum);
|
|
g_Menus[g_MpPlayerNum].menumodel.isperfecthead = false;
|
|
} else {
|
|
headnum = mp_get_beau_head_id(phead_get_unk3a4(mpheadnum - mp_get_num_heads2()));
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.newparams = MENUMODELPARAMS_SET_FILENUM(g_HeadsAndBodies[headnum].filenum);
|
|
g_Menus[g_MpPlayerNum].menumodel.isperfecthead = true;
|
|
g_Menus[g_MpPlayerNum].menumodel.perfectheadnum = mpheadnum - mp_get_num_heads2();
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.partvisibility = visibility;
|
|
g_Menus[g_MpPlayerNum].menumodel.zoom = 30;
|
|
break;
|
|
case MENUOP_21:
|
|
if (!challenge_is_feature_unlocked(mp_get_head_required_feature(data->carousel.value))) {
|
|
return 1;
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->carousel.value = mpheadnum;
|
|
break;
|
|
case MENUOP_SET:
|
|
case MENUOP_FOCUS:
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
g_Menus[g_MpPlayerNum].menumodel.loaddelay = 3;
|
|
#endif
|
|
|
|
mp_get_num_heads2();
|
|
|
|
menu_configure_model(&g_Menus[g_MpPlayerNum].menumodel, 0, 0, 0, 0, 0, 0, 1, MENUMODELFLAG_HASSCALE);
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curposx = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.curposy = 0;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.newposx = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.newposy = -3;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curscale = 0.01f;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curroty = -0.3f;
|
|
g_Menus[g_MpPlayerNum].menumodel.newroty = -0.3f;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.newscale = 1;
|
|
g_Menus[g_MpPlayerNum].menumodel.zoom = 30;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_character_head(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum = data->carousel.value;
|
|
}
|
|
|
|
return mp_character_head_menu_handler(operation, item, data, g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, 1);
|
|
}
|
|
|
|
char *mp_menu_text_body_name(struct menuitem *item)
|
|
{
|
|
return mp_get_body_name(g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum);
|
|
}
|
|
|
|
void func0f17b8f0(void)
|
|
{
|
|
func0f0f139c(g_MpCharacterMenuItems, -0.4f);
|
|
}
|
|
|
|
MenuItemHandlerResult mp_player_name_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
char *name = data->keyboard.string;
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETTEXT:
|
|
i = 0;
|
|
|
|
while (g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] != '\n'
|
|
&& g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] != '\0'
|
|
&& i < 11) {
|
|
name[i] = g_PlayerConfigsArray[g_MpPlayerNum].base.name[i];
|
|
i++;
|
|
}
|
|
|
|
while (i < 11) {
|
|
name[i] = '\0';
|
|
i++;
|
|
}
|
|
break;
|
|
case MENUOP_SETTEXT:
|
|
i = 0;
|
|
|
|
while (i < 11 && name[i] != '\0') {
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] = name[i];
|
|
i++;
|
|
}
|
|
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] = '\n';
|
|
i++;
|
|
|
|
while (i < 11) {
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] = '\0';
|
|
i++;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult mp_load_settings_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = mp_get_num_unlocked_presets();
|
|
|
|
if (g_FileLists[1] != NULL) {
|
|
data->list.value += g_FileLists[1]->numfiles;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if (data->list.value < mp_get_num_unlocked_presets()) {
|
|
return (s32)mp_get_preset_name_by_slot(data->list.value);
|
|
}
|
|
if (g_FileLists[1] != NULL) {
|
|
func0f0d564c(g_FileLists[1]->files[data->list.value - mp_get_num_unlocked_presets()].name, g_StringPointer, false);
|
|
return (s32)g_StringPointer;
|
|
}
|
|
break;
|
|
case MENUOP_SET:
|
|
mp_close_dialogs_for_new_setup();
|
|
|
|
if (data->list.value < mp_get_num_unlocked_presets()) {
|
|
mp0f18dec4(data->list.value);
|
|
} else if (g_FileLists[1] != NULL) {
|
|
struct filelistfile *file = &g_FileLists[1]->files[data->list.value - mp_get_num_unlocked_presets()];
|
|
struct fileguid guid;
|
|
|
|
guid.fileid = file->fileid;
|
|
guid.deviceserial = file->deviceserial;
|
|
|
|
filemgr_save_or_load(&guid, FILEOP_LOAD_MPSETUP, 0);
|
|
}
|
|
|
|
if (item->param == 1) {
|
|
if (IS4MB()) {
|
|
func0f0f820c(&g_MpQuickGo4MbMenuDialog, MENUROOT_4MBMAINMENU);
|
|
} else {
|
|
func0f0f820c(&g_MpQuickGoMenuDialog, MENUROOT_MPSETUP);
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->list.value = 0xfffff;
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = 1;
|
|
|
|
if (g_FileLists[1] != NULL) {
|
|
data->list.value += g_FileLists[1]->numdevices;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
if (data->list.value == 0) {
|
|
return (s32)lang_get(L_MPMENU_141); // "Presets"
|
|
}
|
|
if (g_FileLists[1] != NULL) {
|
|
return (s32)filemgr_get_device_name_or_start_index(1, operation, data->list.value - 1);
|
|
}
|
|
break;
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
if (data->list.value == 0) {
|
|
data->list.groupstartindex = 0;
|
|
} else {
|
|
data->list.groupstartindex = mp_get_num_unlocked_presets();
|
|
|
|
if (g_FileLists[1] != NULL) {
|
|
data->list.groupstartindex += filemgr_get_device_name_or_start_index(1, operation, data->list.value - 1);
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_LISTITEMFOCUS:
|
|
if (data->list.value < mp_get_num_unlocked_presets()) {
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = 0xffff;
|
|
} else {
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = data->list.value - mp_get_num_unlocked_presets();
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_mpconfig_marquee(struct menuitem *item)
|
|
{
|
|
char filename[20];
|
|
u16 numsims;
|
|
u16 stagenum;
|
|
u16 scenarionum;
|
|
s32 arenanum;
|
|
s32 i;
|
|
|
|
if (g_Menus[g_MpPlayerNum].mpsetup.slotindex < 0xffff && g_FileLists[1]) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
arenanum = -1;
|
|
#else
|
|
arenanum = 0;
|
|
#endif
|
|
|
|
mpsetupfile_get_overview(g_FileLists[1]->files[g_Menus[g_MpPlayerNum].mpsetup.slotindex].name,
|
|
filename, &numsims, &stagenum, &scenarionum);
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (g_MpArenas[i].stagenum == stagenum) {
|
|
arenanum = i;
|
|
}
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (scenarionum <= 5 && arenanum != -1 && numsims >= 0 && filename[0] != '\0' && numsims <= MAX_BOTS) {
|
|
// "%s: Scenario: %s Arena: %s Simulants: %d"
|
|
sprintf(g_StringPointer, lang_get(L_MPMENU_140),
|
|
filename,
|
|
lang_get(g_MpScenarioOverviews[scenarionum].name),
|
|
lang_get(g_MpArenas[arenanum].name),
|
|
numsims);
|
|
} else {
|
|
return "";
|
|
}
|
|
#else
|
|
// "%s: Scenario: %s Arena: %s Simulants: %d"
|
|
sprintf(g_StringPointer, lang_get(L_MPMENU_140),
|
|
filename,
|
|
lang_get(g_MpScenarioOverviews[scenarionum].name),
|
|
lang_get(g_MpArenas[arenanum].name),
|
|
numsims);
|
|
#endif
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
MenuItemHandlerResult mp_load_player_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 i;
|
|
struct fileguid guid;
|
|
struct filelistfile *file;
|
|
bool available;
|
|
|
|
if (g_FileLists[0] == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = g_FileLists[0]->numfiles;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
filemgr_get_select_name(g_StringPointer, &g_FileLists[0]->files[data->list.value], FILETYPE_MPPLAYER);
|
|
return (s32)g_StringPointer;
|
|
case MENUOP_SET:
|
|
file = &g_FileLists[0]->files[data->list.value];
|
|
available = true;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++) {
|
|
if (file->fileid == g_PlayerConfigsArray[i].fileguid.fileid
|
|
&& file->deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
|
if ((g_MpSetup.chrslots & (1 << i)) == 0) {
|
|
mp_player_set_defaults(i, true);
|
|
} else {
|
|
available = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (available) {
|
|
guid.fileid = file->fileid;
|
|
guid.deviceserial = file->deviceserial;
|
|
|
|
menu_pop_dialog();
|
|
|
|
filemgr_save_or_load(&guid, FILEOP_LOAD_MPPLAYER, g_MpPlayerNum);
|
|
} else {
|
|
filemgr_push_error_dialog(FILEERROR_ALREADYLOADED);
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->list.value = 0xfffff;
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = g_FileLists[0]->numdevices;
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
return filemgr_get_device_name_or_start_index(0, operation, data->list.value);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
data->list.groupstartindex = filemgr_get_device_name_or_start_index(0, operation, data->list.value);
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_time_limit_slider(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = g_MpSetup.timelimit;
|
|
break;
|
|
case MENUOP_SET:
|
|
g_MpSetup.timelimit = data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
if (data->slider.value == 60) {
|
|
sprintf(data->slider.label, lang_get(L_MPMENU_112)); // "No Limit"
|
|
} else {
|
|
sprintf(data->slider.label, lang_get(L_MPMENU_114), data->slider.value + 1); // "%d Min"
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_score_limit_slider(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = g_MpSetup.scorelimit;
|
|
break;
|
|
case MENUOP_SET:
|
|
g_MpSetup.scorelimit = data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
if (data->slider.value == 100) {
|
|
sprintf(data->slider.label, lang_get(L_MPMENU_112)); // "No Limit"
|
|
} else {
|
|
sprintf(data->slider.label, lang_get(L_MPMENU_113), data->slider.value + 1); // "%d"
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_team_score_limit_slider(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = mp_calculate_team_score_limit();
|
|
break;
|
|
case MENUOP_SET:
|
|
g_MpSetup.teamscorelimit = data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
if (data->slider.value == 400) {
|
|
sprintf(data->slider.label, lang_get(L_MPMENU_112)); // "No Limit"
|
|
} else {
|
|
sprintf(data->slider.label, lang_get(L_MPMENU_113), data->slider.value + 1); // "%d"
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_restore_score_defaults(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
func0f187fec();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_handicap_player(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_CHECKHIDDEN:
|
|
if ((g_MpSetup.chrslots & (1 << item->param)) == 0) {
|
|
return 1;
|
|
}
|
|
break;
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = g_PlayerConfigsArray[item->param].handicap;
|
|
break;
|
|
case MENUOP_SET:
|
|
g_PlayerConfigsArray[item->param].handicap = (u16)data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
sprintf(data->slider.label, "%s%s%.00f%%\n", "", "", mp_handicap_to_damage_scale(g_PlayerConfigsArray[item->param].handicap) * 100);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_handicap_player_name(struct menuitem *item)
|
|
{
|
|
if (g_MpSetup.chrslots & (1 << item->param)) {
|
|
return g_PlayerConfigsArray[item->param].base.name;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_restore_handicap_defaults(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++) {
|
|
g_PlayerConfigsArray[i].handicap = 0x80;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_mp_ready(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid && g_PlayerConfigsArray[g_MpPlayerNum].fileguid.deviceserial) {
|
|
filemgr_save_or_load(&g_PlayerConfigsArray[g_MpPlayerNum].fileguid, FILEOP_SAVE_MPPLAYER, g_MpPlayerNum);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_mp_simulant(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_TICK) {
|
|
if ((u8)g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.name[0] == '\0') {
|
|
menu_pop_dialog();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
struct menuitem g_MpCharacterMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_DARKERBG,
|
|
(uintptr_t)&mp_menu_text_body_name,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
0,
|
|
0,
|
|
0x00000022,
|
|
menuhandler_mp_character_head,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
0,
|
|
0,
|
|
0x0000001b,
|
|
menuhandler_mp_character_body,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpCharacterMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_143, // "Character"
|
|
g_MpCharacterMenuItems,
|
|
menudialog0017a174,
|
|
MENUDIALOGFLAG_0002,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpPlayerNameMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_KEYBOARD,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
mp_player_name_menu_handler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpPlayerNameMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_142, // "Player Name"
|
|
g_MpPlayerNameMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpLoadSettingsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
0,
|
|
0x00000078,
|
|
0x00000042,
|
|
mp_load_settings_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(uintptr_t)&mp_menu_text_mpconfig_marquee,
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpLoadSettingsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_139, // "Load Game Settings"
|
|
g_MpLoadSettingsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_CLOSEONSELECT,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpLoadPresetMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
1,
|
|
0,
|
|
0x00000078,
|
|
0x00000042,
|
|
mp_load_settings_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(uintptr_t)&mp_menu_text_mpconfig_marquee,
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpLoadPresetMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_139, // "Load Game Settings"
|
|
g_MpLoadPresetMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpLoadPlayerMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
0,
|
|
0x0000007e,
|
|
0x00000042,
|
|
mp_load_player_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_MPMENU_138, // "B Button to cancel"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpLoadPlayerMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_137, // "Load Player"
|
|
g_MpLoadPlayerMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpArenaMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mp_arena_menu_handler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpArenaMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_115, // "Arena"
|
|
g_MpArenaMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_CLOSEONSELECT | MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpLimitsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_108, // "Time"
|
|
0x0000003c,
|
|
menuhandler_mp_time_limit_slider,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_109, // "Score"
|
|
0x00000064,
|
|
menuhandler_mp_score_limit_slider,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MISC_447, // "Team Score"
|
|
0x00000190,
|
|
menuhandler_mp_team_score_limit_slider,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_110, // "Restore Defaults"
|
|
0,
|
|
menuhandler_mp_restore_score_defaults,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_111, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpLimitsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_107, // "Limits"
|
|
g_MpLimitsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpHandicapsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_handicap_player_name,
|
|
0x000000ff,
|
|
menuhandler_mp_handicap_player,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
1,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_handicap_player_name,
|
|
0x000000ff,
|
|
menuhandler_mp_handicap_player,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
2,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_handicap_player_name,
|
|
0x000000ff,
|
|
menuhandler_mp_handicap_player,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
3,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_handicap_player_name,
|
|
0x000000ff,
|
|
menuhandler_mp_handicap_player,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_110, // "Restore Defaults"
|
|
0,
|
|
menuhandler_mp_restore_handicap_defaults,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_111, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpHandicapsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPWEAPONS_184, // "Player Handicaps"
|
|
g_MpHandicapsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpReadyMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_106, // "...and waiting"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpReadyMenuDialog = {
|
|
MENUDIALOGTYPE_SUCCESS,
|
|
L_MPMENU_105, // "Ready!"
|
|
g_MpReadyMenuItems,
|
|
menudialog_mp_ready,
|
|
MENUDIALOGFLAG_CLOSEONSELECT,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult mp_add_change_simulant_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 i;
|
|
s32 count = 0;
|
|
|
|
struct optiongroup groups[] = {
|
|
{ 0, L_MPMENU_103 }, // "Normal Simulants"
|
|
{ 6, L_MPMENU_104 }, // "Special Simulants"
|
|
};
|
|
|
|
s32 botnum;
|
|
bool creating;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->list.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
return (s32)lang_get(g_BotProfiles[i].name);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_SET:
|
|
botnum = g_Menus[g_MpPlayerNum].mpsetup.slotindex;
|
|
creating = false;
|
|
|
|
if (botnum < 0) {
|
|
botnum = mp_get_slot_for_new_bot();
|
|
creating = 1;
|
|
} else if ((g_MpSetup.chrslots & (1 << (botnum + 4))) == 0) {
|
|
creating = 1;
|
|
}
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
break;
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (creating) {
|
|
mp_create_bot_from_profile(botnum, i);
|
|
} else {
|
|
g_BotConfigsArray[botnum].type = g_BotProfiles[i].type;
|
|
|
|
if (g_BotConfigsArray[botnum].type == BOTTYPE_GENERAL) {
|
|
mp_set_bot_difficulty(botnum, g_BotProfiles[i].difficulty);
|
|
}
|
|
}
|
|
|
|
mp_generate_bot_names();
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotcount = data->list.value;
|
|
break;
|
|
case MENUOP_LISTITEMFOCUS:
|
|
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
break;
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].mpsetup.unke24 = i;
|
|
// fall-through
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->list.value = g_Menus[g_MpPlayerNum].mpsetup.slotcount;
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = 2;
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
return (s32)lang_get(groups[data->list.value].name);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
for (i = 0; i < groups[data->list.value].offset; i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->list.groupstartindex = count;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_simulant_description(struct menuitem *item)
|
|
{
|
|
return lang_get(L_MISC_106 + g_Menus[g_MpPlayerNum].mpsetup.unke24);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_simulant_head(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 start = 0;
|
|
|
|
if (item->param2 == 1) {
|
|
start = mp_get_num_heads();
|
|
}
|
|
|
|
/**
|
|
* Rare developers forgot to add a break statement to the first case,
|
|
* and when they noticed a problem their fix was to add an additional
|
|
* MENUOP_FOCUS check in the next case.
|
|
*/
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum = start + data->carousel.value;
|
|
case MENUOP_FOCUS:
|
|
if (operation == MENUOP_FOCUS
|
|
&& item->param2 == 1
|
|
&& g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum < start) {
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum = start;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return mp_character_head_menu_handler(operation, item, data, g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum, 0);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_simulant_body(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpbodynum = data->carousel.value;
|
|
}
|
|
|
|
return mp_character_body_menu_handler(operation, item, data,
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpbodynum,
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum,
|
|
false);
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog0017ccfc(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_TICK:
|
|
if (g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
|
|
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[0]
|
|
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[1]) {
|
|
union handlerdata data;
|
|
menuhandler_mp_character_body(MENUOP_11, &dialogdef->items[1], &data);
|
|
}
|
|
}
|
|
|
|
return menudialog_mp_simulant(operation, dialogdef, data);
|
|
}
|
|
|
|
MenuItemHandlerResult mp_bot_difficulty_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 count = 0;
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
mp_set_bot_difficulty(g_Menus[g_MpPlayerNum].mpsetup.slotindex, data->dropdown.value);
|
|
mp_generate_bot_names();
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
if (g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty >= 0
|
|
&& g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty < BOTDIFF_DISABLED) {
|
|
data->dropdown.value = g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty;
|
|
} else {
|
|
data->dropdown.value = 0;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
for (i = 0; i < BOTDIFF_DISABLED; i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->dropdown.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < BOTDIFF_DISABLED; i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->dropdown.value) {
|
|
// "Meat", "Easy", "Normal" etc
|
|
return (s32) lang_get(L_MISC_082 + i);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return (s32)"\n";
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_delete_simulant(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
mp_remove_simulant(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
|
|
menu_pop_dialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_title_edit_simulant(struct menudialogdef *dialogdef)
|
|
{
|
|
sprintf(g_StringPointer, "%s", &g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.name);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_change_simulant_type(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
s32 count = 0;
|
|
s32 profilenum = mp_find_bot_profile(
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].type,
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty);
|
|
|
|
for (i = 0; i < profilenum; i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotcount = count;
|
|
|
|
menu_push_dialog(&g_MpChangeSimulantMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_clear_all_simulants(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
for (i = 0; i < MAX_BOTS; i++) {
|
|
mp_remove_simulant(i);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_add_simulant(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = -1;
|
|
menu_push_dialog(&g_MpAddSimulantMenuDialog);
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
if (mp_has_unused_bot_slots() == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_simulant_slot(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = item->param;
|
|
|
|
if ((g_MpSetup.chrslots & (1 << (item->param + 4))) == 0) {
|
|
menu_push_dialog(&g_MpAddSimulantMenuDialog);
|
|
} else if (IS4MB()) {
|
|
menu_push_dialog(&g_MpEditSimulant4MbMenuDialog);
|
|
} else {
|
|
menu_push_dialog(&g_MpEditSimulantMenuDialog);
|
|
}
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (item->param >= 4 && !challenge_is_feature_unlocked(MPFEATURE_8BOTS)) {
|
|
return true;
|
|
}
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
if (!mp_is_sim_slot_enabled(item->param)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_simulant_name(struct menuitem *item)
|
|
{
|
|
s32 index = item->param;
|
|
|
|
if (g_BotConfigsArray[index].base.name[0] == '\0' || (g_MpSetup.chrslots & 1 << (index + 4)) == 0) {
|
|
return "";
|
|
}
|
|
|
|
return g_BotConfigsArray[index].base.name;
|
|
}
|
|
|
|
char *func0f17d3dc(struct menuitem *item)
|
|
{
|
|
s32 index = item->param;
|
|
|
|
if (g_BotConfigsArray[index].base.name[0] == '\0'
|
|
|| ((g_MpSetup.chrslots & 1 << (index + 4)) == 0)) {
|
|
return "";
|
|
}
|
|
|
|
sprintf(g_StringPointer, "%d:\n", index + 1);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_mp_simulants(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotcount = 0;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
struct menuitem g_MpAddChangeSimulantMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0x00000078,
|
|
0x00000042,
|
|
mp_add_change_simulant_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(uintptr_t)&mp_menu_text_simulant_description,
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpAddSimulantMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_101, // "Add Simulant"
|
|
g_MpAddChangeSimulantMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_CLOSEONSELECT | MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menudialogdef g_MpChangeSimulantMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_102, // "Change Simulant"
|
|
g_MpAddChangeSimulantMenuItems,
|
|
menudialog_mp_simulant,
|
|
MENUDIALOGFLAG_CLOSEONSELECT | MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSimulantCharacterMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0,
|
|
0x00000025,
|
|
menuhandler_mp_simulant_head,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0,
|
|
0x0000001b,
|
|
menuhandler_mp_simulant_body,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSimulantCharacterMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_100, // "Simulant Character"
|
|
g_MpSimulantCharacterMenuItems,
|
|
menudialog0017ccfc,
|
|
MENUDIALOGFLAG_0002 | MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpEditSimulantMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_095, // "Difficulty:"
|
|
0,
|
|
mp_bot_difficulty_menu_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_096, // "Change Type..."
|
|
0,
|
|
menuhandler_mp_change_simulant_type,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_097, // "Character..."
|
|
0,
|
|
(void *)&g_MpSimulantCharacterMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_098, // "Delete Simulant"
|
|
0,
|
|
menuhandler_mp_delete_simulant,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_099, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpEditSimulantMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(uintptr_t)&mp_menu_title_edit_simulant,
|
|
g_MpEditSimulantMenuItems,
|
|
menudialog_mp_simulant,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSimulantsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_084, // "Add Simulant..."
|
|
0,
|
|
menuhandler_mp_add_simulant,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_085, // "1:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
0,
|
|
L_MPMENU_086, // "2:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
0,
|
|
L_MPMENU_087, // "3:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
3,
|
|
0,
|
|
L_MPMENU_088, // "4:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
4,
|
|
0,
|
|
L_MPMENU_089, // "5:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
5,
|
|
0,
|
|
L_MPMENU_090, // "6:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
6,
|
|
0,
|
|
L_MPMENU_091, // "7:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
7,
|
|
0,
|
|
L_MPMENU_092, // "8:"
|
|
(uintptr_t)&mp_menu_text_simulant_name,
|
|
menuhandler_mp_simulant_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_093, // "Clear All"
|
|
0,
|
|
menuhandler_mp_clear_all_simulants,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_094, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSimulantsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_083, // "Simulants"
|
|
g_MpSimulantsMenuItems,
|
|
menudialog_mp_simulants,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_mp_n_teams(s32 operation, struct menuitem *item, union handlerdata *data, s32 numteams)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 numchrs = mp_get_num_chrs();
|
|
s32 array[] = {0, 0, 0, 0};
|
|
s32 somevalue = (numchrs + numteams - 1) / numteams;
|
|
s32 teamsremaining = numteams;
|
|
s32 chrsremaining = numchrs;
|
|
s32 start = random() % numchrs;
|
|
|
|
s32 i;
|
|
s32 teamnum;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (!numchrs) {
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
i = (start + 1) % numchrs;
|
|
|
|
do {
|
|
struct mpchrconfig *mpchr = mp_get_chr_config_by_slot_num(i);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (teamsremaining);
|
|
#else
|
|
if (start);
|
|
#endif
|
|
|
|
if (teamsremaining >= chrsremaining) {
|
|
teamnum = random() % numteams;
|
|
|
|
while (true) {
|
|
if (array[teamnum] == 0) {
|
|
mpchr->team = teamnum;
|
|
|
|
array[teamnum]++;
|
|
teamsremaining--;
|
|
chrsremaining--;
|
|
break;
|
|
} else {
|
|
teamnum = (teamnum + 1) % numteams;
|
|
}
|
|
}
|
|
} else {
|
|
teamnum = random() % numteams;
|
|
|
|
while (true) {
|
|
if (array[teamnum] < somevalue) {
|
|
mpchr->team = teamnum;
|
|
|
|
if (array[teamnum] == 0) {
|
|
teamsremaining--;
|
|
}
|
|
|
|
array[teamnum]++;
|
|
chrsremaining--;
|
|
break;
|
|
} else {
|
|
teamnum = (teamnum + 1) % numteams;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (i == start) {
|
|
break;
|
|
}
|
|
|
|
i = (i + 1) % numchrs;
|
|
} while (true);
|
|
|
|
menu_pop_dialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_two_teams(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandler_mp_n_teams(operation, item, data, 2);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_three_teams(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandler_mp_n_teams(operation, item, data, 3);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_four_teams(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandler_mp_n_teams(operation, item, data, 4);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_maximum_teams(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
u8 team = 0;
|
|
|
|
for (i = 0; i != MAX_MPCHRS; i++) {
|
|
if (g_MpSetup.chrslots & (1 << i)) {
|
|
struct mpchrconfig *mpchr = MPCHR(i);
|
|
|
|
mpchr->team = team++;
|
|
|
|
if (team >= scenario_get_max_teams()) {
|
|
team = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
menu_pop_dialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_humans_vs_simulants(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
|
|
for (i = 0; i != MAX_MPCHRS; i++) {
|
|
if (g_MpSetup.chrslots & (1 << i)) {
|
|
struct mpchrconfig *mpchr = MPCHR(i);
|
|
|
|
mpchr->team = i < 4 ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
menu_pop_dialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_human_simulant_pairs(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
u8 team_ids[4] = {0, 1, 2, 3};
|
|
s32 i;
|
|
s32 playerindex = 0;
|
|
s32 simindex = 0;
|
|
|
|
for (i = 0; i != MAX_MPCHRS; i++) {
|
|
if (g_MpSetup.chrslots & (1 << i)) {
|
|
struct mpchrconfig *mpchr = MPCHR(i);
|
|
|
|
if (i < 4) {
|
|
mpchr->team = team_ids[playerindex++];
|
|
} else {
|
|
mpchr->team = team_ids[simindex++];
|
|
|
|
if (simindex >= playerindex) {
|
|
simindex = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
menu_pop_dialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_chr_name_for_team_setup(struct menuitem *item)
|
|
{
|
|
struct mpchrconfig *mpchr = mp_get_chr_config_by_slot_num(item->param);
|
|
|
|
if (mpchr) {
|
|
return mpchr->name;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
MenuItemHandlerResult func0f17dac4(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = scenario_get_max_teams();
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) == 0) {
|
|
return (s32) "\n";
|
|
}
|
|
|
|
return (s32) g_BossFile.teamnames[data->list.value];
|
|
}
|
|
|
|
return menuhandler_mp_teams_label(operation, item, data);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_team_slot(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
struct mpchrconfig *mpchr;
|
|
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
mpchr = mp_get_chr_config_by_slot_num(item->param);
|
|
mpchr->team = data->dropdown.value;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
mpchr = mp_get_chr_config_by_slot_num(item->param);
|
|
|
|
if (!mpchr) {
|
|
data->dropdown.value = 0xff;
|
|
} else {
|
|
data->dropdown.value = mpchr->team;
|
|
}
|
|
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
mpchr = mp_get_chr_config_by_slot_num(item->param);
|
|
|
|
if (!mpchr) {
|
|
return 1;
|
|
}
|
|
|
|
return menuhandler_mp_teams_label(operation, item, data);
|
|
}
|
|
|
|
return func0f17dac4(operation, item, data);
|
|
}
|
|
|
|
char *mp_menu_text_select_tune_or_tunes(struct menuitem *item)
|
|
{
|
|
if (mp_get_using_multiple_tunes()) {
|
|
return lang_get(L_MPMENU_069); // "Select Tune"
|
|
}
|
|
|
|
return lang_get(L_MPMENU_068); // "Select Tunes"
|
|
}
|
|
|
|
struct menuitem g_MpAutoTeamMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_076, // "Two Teams"
|
|
0,
|
|
menuhandler_mp_two_teams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_077, // "Three Teams"
|
|
0,
|
|
menuhandler_mp_three_teams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_078, // "Four Teams"
|
|
0,
|
|
menuhandler_mp_four_teams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_079, // "Maximum Teams"
|
|
0,
|
|
menuhandler_mp_maximum_teams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_080, // "Humans vs. Simulants"
|
|
0,
|
|
menuhandler_mp_humans_vs_simulants,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_081, // "Human-Simulant Pairs"
|
|
0,
|
|
menuhandler_mp_human_simulant_pairs,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_082, // "Cancel"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpAutoTeamMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_075, // "Auto Team"
|
|
g_MpAutoTeamMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpTeamsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_071, // "Teams Enabled"
|
|
0x00000002,
|
|
menuhandler_mp_teams_enabled,
|
|
},
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x85,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_072, // "Teams:"
|
|
0,
|
|
menuhandler_mp_teams_label,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
1,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
2,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
3,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
4,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
5,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
6,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
7,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
8,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
9,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
10,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
11,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
#else
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_072, // "Teams:"
|
|
0,
|
|
menuhandler_mp_teams_label,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
1,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
2,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
3,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
4,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
5,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
6,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
7,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
8,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
9,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
10,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
11,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(uintptr_t)&mp_menu_text_chr_name_for_team_setup,
|
|
0,
|
|
menuhandler_mp_team_slot,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_073, // "Auto Team..."
|
|
0,
|
|
(void *)&g_MpAutoTeamMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_074, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpTeamsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_070, // "Team Control"
|
|
g_MpTeamsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
u32 var80085ce8[] = {
|
|
L_MISC_166, // "Random"
|
|
L_MISC_167, // "Select All"
|
|
L_MISC_168, // "Select None"
|
|
L_MISC_169, // "Randomize"
|
|
};
|
|
|
|
/**
|
|
* List handler for the select tune dialog.
|
|
*
|
|
* If multiple tracks are disabled, the listing contains the track listing plus
|
|
* one item for Randomize.
|
|
*
|
|
* If multiple tracks are disabled, the listing contains the track listing plus
|
|
* 3 items for Select All, Select None and Randomize.
|
|
*/
|
|
MenuItemHandlerResult mp_select_tune_list_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = mp_get_num_unlocked_tracks();
|
|
|
|
if (mp_get_using_multiple_tunes()) {
|
|
data->list.value += 3;
|
|
} else {
|
|
data->list.value++;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
{
|
|
s32 numtracks = mp_get_num_unlocked_tracks();
|
|
|
|
if (data->list.value < numtracks) {
|
|
return (s32) mp_get_track_name(data->list.value);
|
|
}
|
|
|
|
if (mp_get_using_multiple_tunes()) {
|
|
return (s32) lang_get(var80085ce8[1 + data->list.value - numtracks]);
|
|
}
|
|
|
|
return (s32) lang_get(var80085ce8[data->list.value - numtracks]);
|
|
}
|
|
case MENUOP_SET:
|
|
{
|
|
s32 numtracks = mp_get_num_unlocked_tracks();
|
|
|
|
if (data->list.value < numtracks) {
|
|
if (data->list.unk04 == 0) {
|
|
mp_set_track_slot_enabled(data->list.value);
|
|
}
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
} else if (mp_get_using_multiple_tunes()) {
|
|
s32 index = data->list.value - numtracks;
|
|
|
|
switch (index) {
|
|
case 0:
|
|
mp_enable_all_multi_tracks();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
case 1:
|
|
mp_disable_all_multi_tracks();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
case 2:
|
|
mp_randomise_multi_tracks();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
}
|
|
} else {
|
|
mp_set_track_to_random();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
if (mp_get_using_multiple_tunes()) {
|
|
data->list.value = 0x000fffff;
|
|
} else {
|
|
s32 slotnum = mp_get_current_track_slot_num();
|
|
|
|
if (slotnum < 0) {
|
|
data->list.value = mp_get_num_unlocked_tracks();
|
|
} else {
|
|
data->list.value = slotnum;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_LISTITEMFOCUS:
|
|
if (data->list.value < mp_get_num_unlocked_tracks()) {
|
|
music_start_track_as_menu(mp_get_track_music_num(data->list.value));
|
|
}
|
|
break;
|
|
case MENUOP_GETLISTITEMCHECKBOX:
|
|
{
|
|
s32 numtracks = mp_get_num_unlocked_tracks();
|
|
|
|
if (mp_get_using_multiple_tunes() && data->list.value < numtracks) {
|
|
data->list.unk04 = mp_is_multi_track_slot_enabled(data->list.value);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_mp_select_tune(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_MusicInterval240 = 80;
|
|
}
|
|
|
|
if (operation == MENUOP_CLOSE) {
|
|
g_MusicInterval240 = 15;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
char *mp_menu_text_current_track(struct menuitem *item)
|
|
{
|
|
s32 slotnum;
|
|
|
|
if (mp_get_using_multiple_tunes()) {
|
|
return lang_get(L_MPMENU_066); // "Multiple Tunes"
|
|
}
|
|
|
|
slotnum = mp_get_current_track_slot_num();
|
|
|
|
if (slotnum >= 0) {
|
|
return mp_get_track_name(slotnum);
|
|
}
|
|
|
|
return lang_get(L_MPMENU_067); // "Random"
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_multiple_tunes(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GET:
|
|
return mp_get_using_multiple_tunes();
|
|
case MENUOP_SET:
|
|
mp_set_using_multiple_tunes(data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult mp_team_name_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
char *name = data->keyboard.string;
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETTEXT:
|
|
i = 0;
|
|
|
|
while (g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] != '\n'
|
|
&& g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] != '\0'
|
|
&& i < 11) {
|
|
name[i] = g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i];
|
|
i++;
|
|
}
|
|
|
|
while (i < 11) {
|
|
name[i] = '\0';
|
|
i++;
|
|
}
|
|
break;
|
|
case MENUOP_SETTEXT:
|
|
i = 0;
|
|
|
|
while (i < 11 && name[i] != '\0') {
|
|
g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] = name[i];
|
|
i++;
|
|
}
|
|
|
|
g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] = '\n';
|
|
i++;
|
|
|
|
while (i < 11) {
|
|
g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] = '\0';
|
|
i++;
|
|
}
|
|
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* item->param2 is a text ID for that team's colour. The text IDs for team
|
|
* colours are consecutive, so the index of the team is determined by
|
|
* subtracting the first team's colour text ID.
|
|
*/
|
|
char *mp_menu_text_team_name(struct menuitem *item)
|
|
{
|
|
s32 index = item->param2;
|
|
index -= L_OPTIONS_008;
|
|
|
|
return g_BossFile.teamnames[index];
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_team_name_slot(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = item->param2 - 0x5608;
|
|
menu_push_dialog(&g_MpChangeTeamNameMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *func0f17e318(struct menudialogdef *dialogdef)
|
|
{
|
|
sprintf(g_StringPointer, lang_get(L_MPMENU_056), challenge_get_name_by_slot(g_Menus[g_MpPlayerNum].mpsetup.slotindex));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
/**
|
|
* An "Accept" item somewhere. Probably accepting a challenge.
|
|
*/
|
|
MenuItemHandlerResult menuhandler0017e38c(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
challenge_unset_current();
|
|
#endif
|
|
|
|
menu_pop_dialog();
|
|
challenge_set_current_by_slot(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog0017e3fc(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_OPEN:
|
|
g_Menus[g_MpPlayerNum].menumodel.curparams = 0;
|
|
|
|
g_Menus[g_MpPlayerNum].training.mpconfig = challenge_load_by_slot(
|
|
g_Menus[g_MpPlayerNum].training.unke1c,
|
|
g_Menus[g_MpPlayerNum].menumodel.allocstart,
|
|
g_Menus[g_MpPlayerNum].menumodel.alloclen);
|
|
break;
|
|
case MENUOP_CLOSE:
|
|
break;
|
|
case MENUOP_TICK:
|
|
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
|
|
menu_pop_dialog();
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_MpSelectTunesMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mp_select_tune_list_handler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSelectTunesMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(uintptr_t)&mp_menu_text_select_tune_or_tunes,
|
|
g_MpSelectTunesMenuItems,
|
|
menudialog_mp_select_tune,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSoundtrackMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_063, // "Current:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&mp_menu_text_current_track,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
(uintptr_t)&mp_menu_text_select_tune_or_tunes,
|
|
0,
|
|
(void *)&g_MpSelectTunesMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_064, // "Multiple Tunes"
|
|
0,
|
|
menuhandler_mp_multiple_tunes,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_065, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSoundtrackMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_062, // "Soundtrack"
|
|
g_MpSoundtrackMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpChangeTeamNameMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_KEYBOARD,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
mp_team_name_menu_handler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpChangeTeamNameMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_061, // "Change Team Name"
|
|
g_MpChangeTeamNameMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpTeamNamesMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_008, // "Red"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_009, // "Yellow"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_010, // "Blue"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_011, // "Magenta"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_012, // "Cyan"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_013, // "Orange"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_014, // "Pink"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_015, // "Brown"
|
|
(uintptr_t)&mp_menu_text_team_name,
|
|
menuhandler_mp_team_name_slot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_060, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpTeamNamesMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_059, // "Team Names"
|
|
g_MpTeamNamesMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpConfirmChallengeViaListOrDetailsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SCROLLABLE,
|
|
DESCRIPTION_MPCONFIG,
|
|
0,
|
|
0x0000007c,
|
|
PAL ? 0x41 : 0x37,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_057, // "Accept"
|
|
0,
|
|
menuhandler0017e38c,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_058, // "Cancel"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpConfirmChallengeViaListOrDetailsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(uintptr_t)&func0f17e318,
|
|
g_MpConfirmChallengeViaListOrDetailsMenuItems,
|
|
menudialog0017e3fc,
|
|
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpChallengesListOrDetailsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mp_challenges_list_menu_handler,
|
|
},
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
2,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LABEL_ALTCOLOUR,
|
|
0x7f179198,
|
|
0,
|
|
(void *)0x7f1790a8,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_SCROLLABLE,
|
|
DESCRIPTION_MPCHALLENGE,
|
|
0,
|
|
0x0000007c,
|
|
PAL ? 0x41 : 0x37,
|
|
menuhandler0017e9d8,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
menuhandler0017e9d8,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_171, // "Start Challenge"
|
|
0,
|
|
menuhandler_mp_start_challenge,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_051, // "Abort Challenge"
|
|
0,
|
|
menuhandler_mp_abort_challenge,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpChallengeListOrDetailsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
(uintptr_t)&mp_menu_text_challenge_name,
|
|
#else
|
|
0x5032,
|
|
#endif
|
|
g_MpChallengesListOrDetailsMenuItems,
|
|
mp_combat_challenges_menu_dialog,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
0x00000808,
|
|
#else
|
|
MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
#endif
|
|
NULL,
|
|
};
|
|
|
|
struct menudialogdef g_MpAdvancedSetupViaAdvChallengeMenuDialog;
|
|
|
|
struct menudialogdef g_MpChallengeListOrDetailsViaAdvChallengeMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
(uintptr_t)&mp_menu_text_challenge_name,
|
|
#else
|
|
0x5032,
|
|
#endif
|
|
g_MpChallengesListOrDetailsMenuItems,
|
|
mp_combat_challenges_menu_dialog,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
0x00000808,
|
|
&g_MpAdvancedSetupViaAdvChallengeMenuDialog,
|
|
#else
|
|
MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
&g_MpAdvancedSetupMenuDialog,
|
|
#endif
|
|
};
|
|
|
|
struct menuitem g_MpConfirmChallengeMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SCROLLABLE,
|
|
DESCRIPTION_MPCONFIG,
|
|
0,
|
|
0x0000007c,
|
|
PAL ? 0x41 : 0x37,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_057, // "Accept"
|
|
0,
|
|
menuhandler0017ec64,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_058, // "Cancel"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpConfirmChallengeMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(uintptr_t)&func0f17e318,
|
|
g_MpConfirmChallengeMenuItems,
|
|
menudialog0017e3fc,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult mp_challenges_list_menu_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
Gfx *gdl;
|
|
struct menuitemrenderdata *renderdata;
|
|
s32 x;
|
|
s32 y;
|
|
s32 maxchrs;
|
|
s32 marginleft;
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
|
|
return 1;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = challenge_get_num_available();
|
|
break;
|
|
case MENUOP_SET:
|
|
if (data->list.unk04 != 0) {
|
|
data->list.unk04 = 2;
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = data->list.value;
|
|
|
|
if (item->param == 0) {
|
|
menu_push_dialog(&g_MpConfirmChallengeViaListOrDetailsMenuDialog);
|
|
} else if (IS4MB()) {
|
|
menu_push_dialog(&g_MpConfirmChallenge4MbMenuDialog);
|
|
} else {
|
|
menu_push_dialog(&g_MpConfirmChallengeMenuDialog);
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->list.value = 0xfffff;
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = 0;
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
return 0;
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
data->list.groupstartindex = 0;
|
|
break;
|
|
case MENUOP_RENDER:
|
|
gdl = data->type19.gdl;
|
|
renderdata = data->type19.renderdata2;
|
|
marginleft = 10;
|
|
maxchrs = 4;
|
|
|
|
if (IS4MB()) {
|
|
maxchrs = 2;
|
|
}
|
|
|
|
x = renderdata->x + 10;
|
|
y = renderdata->y + 1;
|
|
|
|
gdl = text_begin(gdl);
|
|
gdl = text_render_v2(gdl, &x, &y, challenge_get_name_by_slot(data->type19.unk04), g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, vi_get_width(), vi_get_height(), 0, 0);
|
|
gdl = text_end(gdl);
|
|
|
|
gDPPipeSync(gdl++);
|
|
gDPSetTexturePersp(gdl++, G_TP_NONE);
|
|
gDPSetAlphaCompare(gdl++, G_AC_NONE);
|
|
gDPSetTextureLOD(gdl++, G_TL_TILE);
|
|
gDPSetTextureConvert(gdl++, G_TC_FILT);
|
|
|
|
tex_select(&gdl, &g_TexGeneralConfigs[35], 2, 0, 2, 1, NULL);
|
|
|
|
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
|
|
gDPSetTextureFilter(gdl++, G_TF_POINT);
|
|
|
|
for (i = 0; i < maxchrs; i++) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (challenge_is_completed_by_any_chr_with_num_players_by_slot(data->type19.unk04, i + 1)) {
|
|
gDPSetEnvColorViaWord(gdl++, (renderdata->colour & 0xff) * 0xff >> 8 | 0xffe56500);
|
|
} else {
|
|
gDPSetEnvColorViaWord(gdl++, (renderdata->colour & 0xff) * 0xff >> 8 | 0x43430000);
|
|
}
|
|
#else
|
|
if (challenge_is_completed_by_any_chr_with_num_players_by_slot(data->type19.unk04, i + 1)) {
|
|
gDPSetEnvColorViaWord(gdl++, 0xffe565ff);
|
|
} else {
|
|
gDPSetEnvColorViaWord(gdl++, 0x434300ff);
|
|
}
|
|
#endif
|
|
|
|
gDPSetCombineLERP(gdl++,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0,
|
|
TEXEL0, 0, ENVIRONMENT, 0);
|
|
|
|
gSPTextureRectangle(gdl++,
|
|
((renderdata->x + marginleft) << 2) * g_UiScaleX, (renderdata->y + 11) << 2,
|
|
((renderdata->x + marginleft + 11) << 2) * g_UiScaleX, (renderdata->y + 22) << 2,
|
|
G_TX_RENDERTILE, 0, 0x0160, 1024 / g_UiScaleX, -1024);
|
|
|
|
marginleft += 13;
|
|
}
|
|
return (s32)gdl;
|
|
case MENUOP_GETOPTIONHEIGHT:
|
|
data->list.value = 26;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* This is for a separator and fixed height thing in the dialog at:
|
|
* Combat Simulator > Advanced Setup > Challenges > pick one > Accept
|
|
*/
|
|
MenuItemHandlerResult menuhandler0017e9d8(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_abort_challenge(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_SET) {
|
|
challenge_remove_player_lock();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_start_challenge(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return true;
|
|
}
|
|
}
|
|
if (operation == MENUOP_SET) {
|
|
menu_push_dialog(&g_MpReadyMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_challenge_name(struct menuitem *item)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return lang_get(L_MPMENU_050); // "Combat Challenges"
|
|
}
|
|
#endif
|
|
|
|
sprintf(g_StringPointer, "%s:\n", challenge_get_name(challenge_get_current()));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
MenuDialogHandlerResult mp_combat_challenges_menu_dialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_TICK) {
|
|
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE
|
|
&& g_Menus[g_MpPlayerNum].curdialog
|
|
&& g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
|
|
&& !challenge_is_loaded()) {
|
|
g_Menus[g_MpPlayerNum].menumodel.curparams = 0x4fac5ace;
|
|
|
|
challenge_load_and_store_current(
|
|
g_Menus[g_MpPlayerNum].menumodel.allocstart,
|
|
g_Menus[g_MpPlayerNum].menumodel.alloclen);
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_CLOSE) {
|
|
if (g_Menus[g_MpPlayerNum].menumodel.curparams == 0x4fac5ace) {
|
|
challenge_unset_current();
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler0017ec64(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
challenge_set_current_by_slot(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
|
|
func0f0f820c(&g_MpQuickGoMenuDialog, 3);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_MpChallengesMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
1,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mp_challenges_list_menu_handler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpChallengesMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_050, // "Combat Challenges"
|
|
g_MpChallengesMenuItems,
|
|
mp_combat_challenges_menu_dialog,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_mp_lock(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
u16 labels[] = {
|
|
L_MPMENU_045, // "None"
|
|
L_MPMENU_046, // "Last Winner"
|
|
L_MPMENU_047, // "Last Loser"
|
|
L_MPMENU_048, // "Random"
|
|
};
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = mp_get_lock_type() == MPLOCKTYPE_CHALLENGE ? 1 : 5;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if (mp_get_lock_type() == MPLOCKTYPE_CHALLENGE) {
|
|
return (s32) lang_get(L_MPMENU_049); // "Challenge"
|
|
}
|
|
if (data->dropdown.value <= 3) {
|
|
return (s32) lang_get(labels[data->dropdown.value]);
|
|
}
|
|
if (mp_get_lock_type() == MPLOCKTYPE_PLAYER) {
|
|
return (s32) g_PlayerConfigsArray[mp_get_lock_player_num()].base.name;
|
|
}
|
|
return (s32) mp_get_current_player_name(item);
|
|
case MENUOP_SET:
|
|
if (mp_get_lock_type() != MPLOCKTYPE_CHALLENGE) {
|
|
mp_set_lock(data->dropdown.value, g_MpPlayerNum);
|
|
}
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = mp_get_lock_type() == MPLOCKTYPE_CHALLENGE ? 0 : mp_get_lock_type();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_save_player(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid == 0) {
|
|
filemgr_push_select_location_dialog(6, FILETYPE_MPPLAYER);
|
|
} else {
|
|
menu_push_dialog(&g_MpSavePlayerMenuDialog);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_save_player_or_copy(struct menuitem *item)
|
|
{
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid == 0) {
|
|
return lang_get(L_MPMENU_038); // "Save Player"
|
|
}
|
|
|
|
return lang_get(L_MPMENU_039); // "Save Copy of Player"
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler0017ef30(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
if (g_Vars.stagenum == STAGE_CITRAINING) {
|
|
if (IS4MB()) {
|
|
func0f0f820c(&g_CiMenuViaPauseMenuDialog, 2);
|
|
} else {
|
|
func0f0f820c(&g_CiMenuViaPcMenuDialog, 2);
|
|
}
|
|
} else {
|
|
func0f0f820c(&g_SoloMissionPauseMenuDialog, 2);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_save_settings(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
if (g_MpSetup.fileguid.fileid == 0) {
|
|
menu_push_dialog(&g_MpSaveSetupNameMenuDialog);
|
|
} else {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
filemgr_set_device1_by_serial(g_MpSetup.fileguid.deviceserial);
|
|
#endif
|
|
|
|
menu_push_dialog(&g_MpSaveSetupExistsMenuDialog);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mp_menu_text_arena_name(struct menuitem *item)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i != ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (g_MpArenas[i].stagenum == g_MpSetup.stagenum) {
|
|
return lang_get(g_MpArenas[i].name);
|
|
}
|
|
}
|
|
|
|
return "\n";
|
|
}
|
|
|
|
char *mp_menu_text_weapon_set_name(struct menuitem *item)
|
|
{
|
|
return mp_get_weapon_set_name(mp_get_weapon_set());
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_mp_game_setup(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Vars.mpsetupmenu = MPSETUPMENU_ADVSETUP;
|
|
g_Vars.usingadvsetup = true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_mp_quick_go(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Vars.mpsetupmenu = MPSETUPMENU_QUICKGO;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void mp_configure_quick_team_players(void)
|
|
{
|
|
s32 i;
|
|
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_NONE) {
|
|
for (i = 0; i < MAX_BOTS; i++) {
|
|
mp_remove_simulant(i);
|
|
}
|
|
|
|
switch (g_Vars.mpquickteam) {
|
|
case MPQUICKTEAM_PLAYERSONLY:
|
|
g_MpSetup.options &= ~MPOPTION_TEAMSENABLED;
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSANDSIMS:
|
|
g_MpSetup.options &= ~MPOPTION_TEAMSENABLED;
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSTEAMS:
|
|
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++) {
|
|
g_PlayerConfigsArray[i].base.team = g_Vars.mpplayerteams[i];
|
|
}
|
|
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSVSSIMS:
|
|
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++) {
|
|
g_PlayerConfigsArray[i].base.team = 0;
|
|
}
|
|
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSIMTEAMS:
|
|
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++) {
|
|
g_PlayerConfigsArray[i].base.team = i;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void mp_configure_quick_team_simulants(void)
|
|
{
|
|
struct mpchrconfig *mpchr;
|
|
s32 numchrs;
|
|
s32 botnum;
|
|
s32 i;
|
|
s32 j;
|
|
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_NONE) {
|
|
switch (g_Vars.mpquickteam) {
|
|
case MPQUICKTEAM_PLAYERSANDSIMS:
|
|
for (i = 0; i < g_Vars.mpquickteamnumsims; i++) {
|
|
botnum = mp_get_slot_for_new_bot();
|
|
|
|
if (botnum >= 0) {
|
|
mp_create_bot_from_profile(botnum, g_Vars.mpsimdifficulty);
|
|
}
|
|
}
|
|
|
|
mp_generate_bot_names();
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSVSSIMS:
|
|
for (i = 0; i < g_Vars.mpquickteamnumsims; i++) {
|
|
botnum = mp_get_slot_for_new_bot();
|
|
|
|
if (botnum >= 0) {
|
|
mp_create_bot_from_profile(botnum, g_Vars.mpsimdifficulty);
|
|
}
|
|
}
|
|
|
|
mp_generate_bot_names();
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_BotConfigsArray); i++) {
|
|
g_BotConfigsArray[i].base.team = 1;
|
|
}
|
|
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSIMTEAMS:
|
|
for (i = mp_get_num_chrs() - 1; i >= 0; i--) {
|
|
mpchr = mp_get_chr_config_by_slot_num(i);
|
|
|
|
for (j = 0; j < g_Vars.unk0004a0; j++) {
|
|
botnum = mp_get_slot_for_new_bot();
|
|
|
|
if (botnum >= 0) {
|
|
mp_create_bot_from_profile(botnum, g_Vars.mpsimdifficulty);
|
|
g_BotConfigsArray[botnum].base.team = mpchr->team;
|
|
}
|
|
}
|
|
}
|
|
|
|
mp_generate_bot_names();
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSONLY:
|
|
case MPQUICKTEAM_PLAYERSTEAMS:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void func0f17f428(void)
|
|
{
|
|
mp_configure_quick_team_players();
|
|
|
|
if (IS4MB()) {
|
|
func0f0f820c(&g_MpQuickGo4MbMenuDialog, MENUROOT_4MBMAINMENU);
|
|
} else {
|
|
func0f0f820c(&g_MpQuickGoMenuDialog, MENUROOT_MPSETUP);
|
|
}
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_finished_setup(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (operation == MENUOP_CHECKPREFOCUSED) {
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
if (operation == MENUOP_SET) {
|
|
func0f17f428();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_quick_team_separator(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_Vars.mpquickteam == MPQUICKTEAM_PLAYERSONLY) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_player_team(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
data->dropdown.value = scenario_get_max_teams();
|
|
#else
|
|
data->dropdown.value = MAX_TEAMS;
|
|
#endif
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
return (s32) &g_BossFile.teamnames[data->dropdown.value];
|
|
case MENUOP_SET:
|
|
g_Vars.mpplayerteams[item->param] = data->dropdown.value;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
if (g_Vars.mpplayerteams[item->param] >= scenario_get_max_teams()) {
|
|
g_Vars.mpplayerteams[item->param] %= scenario_get_max_teams();
|
|
}
|
|
#endif
|
|
data->dropdown.value = g_Vars.mpplayerteams[item->param];
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSTEAMS) {
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_number_of_simulants(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = !challenge_is_feature_unlocked(MPFEATURE_8BOTS) ? 4 : MAX_BOTS;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
sprintf(g_StringPointer, "%d\n", data->dropdown.value + 1);
|
|
return (s32) g_StringPointer;
|
|
case MENUOP_SET:
|
|
g_Vars.mpquickteamnumsims = data->dropdown.value + 1;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = g_Vars.mpquickteamnumsims - 1;
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSANDSIMS
|
|
&& g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSVSSIMS) {
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_simulants_per_team(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = 2;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
sprintf(g_StringPointer, "%d\n", data->dropdown.value + 1);
|
|
return (s32) g_StringPointer;
|
|
case MENUOP_SET:
|
|
g_Vars.unk0004a0 = data->dropdown.value + 1;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = g_Vars.unk0004a0 - 1;
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSIMTEAMS) {
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult mp_quick_team_simulant_difficulty_handler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 count = 0;
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
for (i = 0; i < NUM_BOTDIFFS; i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->dropdown.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < NUM_BOTDIFFS; i++) {
|
|
if (challenge_is_feature_unlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->dropdown.value) {
|
|
return (s32) lang_get(i + L_MISC_082);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_SET:
|
|
g_Vars.mpsimdifficulty = data->dropdown.value;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = g_Vars.mpsimdifficulty;
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSANDSIMS
|
|
&& g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSVSSIMS
|
|
&& g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSIMTEAMS) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_quick_team_option(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Vars.mpquickteam = item->param;
|
|
|
|
if (mp_get_weapon_set() >= func0f189058(0)) {
|
|
mp_set_weapon_set(0);
|
|
}
|
|
|
|
if (g_Vars.mpquickteam == MPQUICKTEAM_PLAYERSONLY ||
|
|
g_Vars.mpquickteam == MPQUICKTEAM_PLAYERSANDSIMS) {
|
|
if (g_MpSetup.scenario == MPSCENARIO_KINGOFTHEHILL ||
|
|
g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE) {
|
|
g_MpSetup.scenario = MPSCENARIO_COMBAT;
|
|
}
|
|
}
|
|
|
|
menu_push_dialog(&g_MpQuickTeamGameSetupMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_combat_simulator(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Vars.waitingtojoin[0] = false;
|
|
g_Vars.waitingtojoin[1] = false;
|
|
g_Vars.waitingtojoin[2] = false;
|
|
g_Vars.waitingtojoin[3] = false;
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].curdialog
|
|
&& g_Menus[g_MpPlayerNum].curdialog->definition == &g_CombatSimulatorMenuDialog
|
|
&& operation == MENUOP_TICK) {
|
|
g_Vars.mpsetupmenu = MPSETUPMENU_GENERAL;
|
|
g_Vars.mpquickteam = MPQUICKTEAM_NONE;
|
|
g_Vars.usingadvsetup = false;
|
|
challenge_unset_current();
|
|
challenge_remove_player_lock();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mp_advanced_setup(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
func0f0f820c(&g_MpAdvancedSetupMenuDialog, 3);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* When a player is loading a saved setup, check which dialogs the other players
|
|
* have open and close them if they no longer apply or need to be updated.
|
|
*/
|
|
void mp_close_dialogs_for_new_setup(void)
|
|
{
|
|
s32 i;
|
|
s32 prevplayernum = g_MpPlayerNum;
|
|
s32 j;
|
|
s32 k;
|
|
|
|
// Loop through each player
|
|
for (i = 0; i < MAX_PLAYERS; i++) {
|
|
g_MpPlayerNum = i;
|
|
|
|
// If they have a menu open
|
|
if (g_Menus[g_MpPlayerNum].curdialog) {
|
|
bool ok = false;
|
|
|
|
// Repeat the following steps until we've stopped finding dialogs
|
|
// that should be closed
|
|
while (!ok) {
|
|
ok = true;
|
|
|
|
// Loop through each layer of menus
|
|
for (j = 0; j < g_Menus[g_MpPlayerNum].depth; j++) {
|
|
// Loop through the siblings (left/right) in this layer
|
|
for (k = 0; k < g_Menus[g_MpPlayerNum].layers[j].numsiblings; k++) {
|
|
if (g_Menus[g_MpPlayerNum].layers[j].siblings[k]) {
|
|
struct menudialogdef *dialogdef = g_Menus[g_MpPlayerNum].layers[j].siblings[k]->definition;
|
|
|
|
if (dialogdef == &g_MpSaveSetupNameMenuDialog) ok = false;
|
|
if (dialogdef == &g_MpSaveSetupExistsMenuDialog) ok = false;
|
|
if (dialogdef == &g_MpAddSimulantMenuDialog) ok = false;
|
|
if (dialogdef == &g_MpChangeSimulantMenuDialog) ok = false;
|
|
if (dialogdef == &g_MpEditSimulantMenuDialog) ok = false;
|
|
if (dialogdef == &g_MpCombatOptionsMenuDialog) ok = false;
|
|
if (dialogdef == &g_HtbOptionsMenuDialog) ok = false;
|
|
if (dialogdef == &g_CtcOptionsMenuDialog) ok = false;
|
|
if (dialogdef == &g_KohOptionsMenuDialog) ok = false;
|
|
if (dialogdef == &g_HtmOptionsMenuDialog) ok = false;
|
|
if (dialogdef == &g_PacOptionsMenuDialog) ok = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Close the leaf layer
|
|
if (!ok) {
|
|
menu_pop_dialog();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
g_MpPlayerNum = prevplayernum;
|
|
}
|
|
|
|
struct menudialogdef g_MpAbortMenuDialog;
|
|
|
|
struct menuitem g_MpStuffMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_041, // "Soundtrack"
|
|
0,
|
|
(void *)&g_MpSoundtrackMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_042, // "Team Names"
|
|
0,
|
|
(void *)&g_MpTeamNamesMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_044, // "Lock"
|
|
0,
|
|
menuhandler_mp_lock,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_216, // "Ratio"
|
|
0,
|
|
menuhandler_screen_ratio,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_154, // "Split"
|
|
0,
|
|
menuhandler_screen_split,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_036, // "Start Game"
|
|
0,
|
|
(void *)&g_MpReadyMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_037, // "Drop Out"
|
|
0,
|
|
(void *)&g_MpDropOutMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_027, // "Abort Game"
|
|
0,
|
|
(void *)&g_MpAbortMenuDialog,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpStuffMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_040, // "Stuff"
|
|
g_MpStuffMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
&g_MpChallengeListOrDetailsMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_MpStuffViaAdvChallengeMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_040, // "Stuff"
|
|
g_MpStuffMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpPlayerSetup234MenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_030, // "Name"
|
|
(uintptr_t)&mp_get_current_player_name,
|
|
(void *)&g_MpPlayerNameMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_031, // "Character"
|
|
0,
|
|
(void *)&g_MpCharacterMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_033, // "Control"
|
|
0,
|
|
(void *)&g_MpControlMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_034, // "Player Options"
|
|
0,
|
|
(void *)&g_MpPlayerOptionsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_035, // "Statistics"
|
|
0,
|
|
(void *)&g_MpPlayerStatsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_029, // "Load Player"
|
|
0,
|
|
(void *)&g_MpLoadPlayerMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
(uintptr_t)&mp_menu_text_save_player_or_copy,
|
|
0,
|
|
menuhandler_mp_save_player,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpPlayerSetupViaAdvMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_028, // "Player Setup"
|
|
g_MpPlayerSetup234MenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
&g_MpStuffMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_MpPlayerSetupViaAdvChallengeMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_028, // "Player Setup"
|
|
g_MpPlayerSetup234MenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
&g_MpStuffViaAdvChallengeMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_MpPlayerSetupViaQuickGoMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_028, // "Player Setup"
|
|
g_MpPlayerSetup234MenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpAbortMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_053, // "Are you sure you want to abort the game?"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_054, // "Abort"
|
|
0,
|
|
menuhandler0017ef30,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_055, // "Cancel"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpAbortMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_MPMENU_052, // "Abort"
|
|
g_MpAbortMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpAdvancedSetupMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_019, // "Scenario"
|
|
(uintptr_t)&mp_menu_text_scenario_short_name,
|
|
(void *)&g_MpScenarioMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_021, // "Options"
|
|
0,
|
|
menuhandler_mp_open_options,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_020, // "Arena"
|
|
(uintptr_t)&mp_menu_text_arena_name,
|
|
(void *)&g_MpArenaMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_023, // "Weapons"
|
|
0,
|
|
(void *)&g_MpWeaponsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_024, // "Limits"
|
|
0,
|
|
(void *)&g_MpLimitsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPWEAPONS_184, // "Player Handicaps"
|
|
0,
|
|
(void *)&g_MpHandicapsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_025, // "Simulants"
|
|
0,
|
|
(void *)&g_MpSimulantsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_022, // "Teams"
|
|
0,
|
|
(void *)&g_MpTeamsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_018, // "Load Settings"
|
|
0,
|
|
(void *)&g_MpLoadSettingsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_026, // "Save Settings"
|
|
0,
|
|
menuhandler_mp_save_settings,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpAdvancedSetupMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_017, // "Game Setup"
|
|
g_MpAdvancedSetupMenuItems,
|
|
menudialog_mp_game_setup,
|
|
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
&g_MpPlayerSetupViaAdvMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_MpAdvancedSetupViaAdvChallengeMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_017, // "Game Setup"
|
|
g_MpAdvancedSetupMenuItems,
|
|
menudialog_mp_game_setup,
|
|
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
&g_MpPlayerSetupViaAdvChallengeMenuDialog,
|
|
};
|
|
|
|
struct menuitem g_MpQuickGoMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MISC_456, // "Start Game"
|
|
0,
|
|
(void *)&g_MpReadyMenuDialog,
|
|
},
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_029, // "Load Player"
|
|
0,
|
|
(void *)&g_MpLoadPlayerMenuDialog,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MISC_458, // "Player Settings"
|
|
0,
|
|
(void *)&g_MpPlayerSetupViaQuickGoMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MISC_457, // "Drop Out"
|
|
0,
|
|
(void *)&g_MpDropOutMenuDialog,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpQuickGoMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MISC_460, // "Quick Go"
|
|
g_MpQuickGoMenuItems,
|
|
menudialog_mp_quick_go,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpQuickTeamGameSetupMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_019, // "Scenario"
|
|
(uintptr_t)&mp_menu_text_scenario_short_name,
|
|
(void *)&g_MpQuickTeamScenarioMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_021, // "Options"
|
|
0,
|
|
menuhandler_mp_open_options,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_020, // "Arena"
|
|
(uintptr_t)&mp_menu_text_arena_name,
|
|
(void *)&g_MpArenaMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_023, // "Weapons"
|
|
(uintptr_t)&mp_menu_text_weapon_set_name,
|
|
(void *)&g_MpQuickTeamWeaponsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_024, // "Limits"
|
|
0,
|
|
(void *)&g_MpLimitsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
menuhandler_quick_team_separator,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_449, // "Player 1 Team"
|
|
0,
|
|
menuhandler_player_team,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
1,
|
|
0,
|
|
L_MISC_450, // "Player 2 Team"
|
|
0,
|
|
menuhandler_player_team,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
2,
|
|
0,
|
|
L_MISC_451, // "Player 3 Team"
|
|
0,
|
|
menuhandler_player_team,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
3,
|
|
0,
|
|
L_MISC_452, // "Player 4 Team"
|
|
0,
|
|
menuhandler_player_team,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_453, // "Number Of Simulants"
|
|
0,
|
|
menuhandler_mp_number_of_simulants,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_454, // "Simulants Per Team"
|
|
0,
|
|
menuhandler_mp_simulants_per_team,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_455, // "Simulant Difficulty"
|
|
0,
|
|
mp_quick_team_simulant_difficulty_handler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MISC_448, // "Finished Setup"
|
|
0,
|
|
menuhandler_mp_finished_setup,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_026, // "Save Settings"
|
|
0,
|
|
menuhandler_mp_save_settings,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpQuickTeamGameSetupMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_017, // "Game Setup"
|
|
g_MpQuickTeamGameSetupMenuItems,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpQuickTeamMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_463, // "Players Only"
|
|
0,
|
|
menuhandler_mp_quick_team_option,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_464, // "Players and Simulants"
|
|
0,
|
|
menuhandler_mp_quick_team_option,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_465, // "Player Teams"
|
|
0,
|
|
menuhandler_mp_quick_team_option,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
3,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_466, // "Players vs. Simulants"
|
|
0,
|
|
menuhandler_mp_quick_team_option,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
4,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_467, // "Player-Simulant Teams"
|
|
0,
|
|
menuhandler_mp_quick_team_option,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpQuickTeamMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MISC_462, // "Quick Team"
|
|
g_MpQuickTeamMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_CombatSimulatorMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_MISC_441, // "Challenges"
|
|
0,
|
|
(void *)&g_MpChallengesMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_MISC_442, // "Load/Preset Games"
|
|
0x00000001,
|
|
(void *)&g_MpLoadPresetMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_MISC_443, // "Quick Start"
|
|
0x00000002,
|
|
(void *)&g_MpQuickTeamMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_444, // "Advanced Setup"
|
|
0x00000003,
|
|
menuhandler_mp_advanced_setup,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_CombatSimulatorMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MISC_445, // "Combat Simulator"
|
|
g_CombatSimulatorMenuItems,
|
|
menudialog_combat_simulator,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
void func0f17fcb0(s32 silent)
|
|
{
|
|
g_Menus[g_MpPlayerNum].playernum = g_MpPlayerNum;
|
|
|
|
if (IS4MB()) {
|
|
menu_push_root_dialog(&g_AdvancedSetup4MbMenuDialog, MENUROOT_4MBMAINMENU);
|
|
func0f0f8300();
|
|
} else {
|
|
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
|
|
menu_push_root_dialog(&g_MpChallengeListOrDetailsViaAdvChallengeMenuDialog, MENUROOT_MPSETUP);
|
|
} else {
|
|
menu_push_root_dialog(&g_MpAdvancedSetupMenuDialog, MENUROOT_MPSETUP);
|
|
}
|
|
|
|
func0f0f8300();
|
|
}
|
|
|
|
if (!silent) {
|
|
// Explosion sound
|
|
snd_start(var80095200, SFX_EXPLOSION_809A, NULL, -1, -1, -1, -1, -1);
|
|
}
|
|
}
|