5851 lines
120 KiB
C
5851 lines
120 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/game_1531a0.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;
|
|
|
|
s32 menuhandlerMpDropOut(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpGetCurrentPlayerName(struct menuitem *item)
|
|
{
|
|
return g_PlayerConfigsArray[g_MpPlayerNum].base.name;
|
|
}
|
|
|
|
s32 menuhandlerMpTeamsLabel(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,
|
|
menuhandlerMpDropOut,
|
|
},
|
|
{
|
|
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 mpGetNumStages(void)
|
|
{
|
|
return 17;
|
|
}
|
|
|
|
s16 mpChooseRandomStage(void)
|
|
{
|
|
s32 i;
|
|
s32 numchallengescomplete = 0;
|
|
s32 index;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
if (challengeIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
|
|
numchallengescomplete++;
|
|
}
|
|
}
|
|
|
|
index = random() % numchallengescomplete;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
if (challengeIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
|
|
if (index == 0) {
|
|
return g_MpArenas[i].stagenum;
|
|
}
|
|
|
|
index--;
|
|
}
|
|
}
|
|
|
|
return STAGE_MP_SKEDAR;
|
|
}
|
|
|
|
s32 mpArenaMenuHandler(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 (challengeIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->list.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (challengeIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
return (s32)langGet(g_MpArenas[i].name);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_SET:
|
|
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (challengeIsFeatureUnlocked(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 (challengeIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = 3;
|
|
|
|
if (!challengeIsFeatureUnlocked(MPFEATURE_STAGE_COMPLEX)
|
|
&& !challengeIsFeatureUnlocked(MPFEATURE_STAGE_TEMPLE)
|
|
&& !challengeIsFeatureUnlocked(MPFEATURE_STAGE_FELICITY)) {
|
|
data->list.value--;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
count = data->list.value;
|
|
|
|
if (!challengeIsFeatureUnlocked(MPFEATURE_STAGE_COMPLEX)
|
|
&& !challengeIsFeatureUnlocked(MPFEATURE_STAGE_TEMPLE)
|
|
&& !challengeIsFeatureUnlocked(MPFEATURE_STAGE_FELICITY)
|
|
&& count > 0) {
|
|
count++;
|
|
}
|
|
return (s32)langGet(groups[count].name);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
groupindex = data->list.value;
|
|
|
|
if (!challengeIsFeatureUnlocked(MPFEATURE_STAGE_COMPLEX)
|
|
&& !challengeIsFeatureUnlocked(MPFEATURE_STAGE_TEMPLE)
|
|
&& !challengeIsFeatureUnlocked(MPFEATURE_STAGE_FELICITY)
|
|
&& groupindex == 1) {
|
|
groupindex++;
|
|
}
|
|
|
|
for (i = 0; i < groups[groupindex].offset; i++) {
|
|
if (challengeIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
data->list.groupstartindex = count;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpControlStyle(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) langGet(labels[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
optionsSetControlMode(g_MpPlayerNum, data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = optionsGetControlMode(g_MpPlayerNum);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpWeaponSlot(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = mpGetNumWeaponOptions();
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
return (s32) mpGetWeaponLabel(data->dropdown.value);
|
|
case MENUOP_SET:
|
|
mpSetWeaponSlot(item->param3, data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = mpGetWeaponSlot(item->param3);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextWeaponNameForSlot(struct menuitem *item)
|
|
{
|
|
return mpGetWeaponLabel(mpGetWeaponSlot(item->param));
|
|
}
|
|
|
|
s32 menuhandlerMpWeaponSetDropdown(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) mpGetWeaponSetName(data->dropdown.value);
|
|
case MENUOP_SET:
|
|
mpSetWeaponSet(data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = mpGetWeaponSet();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpControlCheckbox(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;
|
|
}
|
|
|
|
s32 menuhandlerMpAimControl(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) langGet(labels[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
optionsSetAimControl(g_MpPlayerNum, data->dropdown.value);
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = optionsGetAimControl(g_MpPlayerNum);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpCheckboxOption(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;
|
|
}
|
|
|
|
s32 menuhandlerMpTeamsEnabled(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 menuhandlerMpCheckboxOption(operation, item, data);
|
|
}
|
|
|
|
s32 menuhandlerMpDisplayOptionCheckbox(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;
|
|
}
|
|
|
|
s32 menuhandlerMpConfirmSaveChr(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
filemgrPushSelectLocationDialog(6, FILETYPE_MPPLAYER);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpSetupName(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:
|
|
filemgrPushSelectLocationDialog(7, FILETYPE_MPSETUP);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpSaveSetupOverwrite(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
filemgrSaveOrLoad(&g_MpSetup.fileguid, FILEOP_SAVE_MPSETUP, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpSaveSetupCopy(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
menuPushDialog(&g_MpSaveSetupNameMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
char *mpMenuTextSetupName(struct menuitem *item)
|
|
{
|
|
return g_MpSetup.name;
|
|
}
|
|
#endif
|
|
|
|
s32 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;
|
|
}
|
|
|
|
s32 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;
|
|
}
|
|
|
|
s32 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;
|
|
}
|
|
|
|
s32 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.
|
|
*/
|
|
s32 mpCharacterBodyMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data, s32 mpheadnum, s32 mpbodynum, bool isplayer)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->carousel.value = mpGetNumBodies();
|
|
break;
|
|
case MENUOP_11:
|
|
g_Menus[g_MpPlayerNum].unk840.unk05c = 0x1fc;
|
|
g_Menus[g_MpPlayerNum].unk840.unk00c = mpbodynum << 16 | 0xffff | mpheadnum << 24;
|
|
g_Menus[g_MpPlayerNum].unk840.unk574 += g_Vars.diffframe60;
|
|
|
|
if (g_Menus[g_MpPlayerNum].unk840.unk574 > TICKS(480)) {
|
|
g_Menus[g_MpPlayerNum].unk840.unk574 -= TICKS(480);
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].unk840.unk578 > 0) {
|
|
g_Menus[g_MpPlayerNum].unk840.unk578 -= g_Vars.diffframe60;
|
|
} else {
|
|
#if VERSION >= VERSION_PAL_BETA
|
|
f32 value = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60freal;
|
|
#else
|
|
f32 value = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60f;
|
|
#endif
|
|
g_Menus[g_MpPlayerNum].unk840.unk54c = value;
|
|
g_Menus[g_MpPlayerNum].unk840.unk524 = value;
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.partvisibility = NULL;
|
|
g_Menus[g_MpPlayerNum].unk840.unk554 = 30;
|
|
break;
|
|
case MENUOP_21:
|
|
if (!challengeIsFeatureUnlocked(mpGetBodyRequiredFeature(data->carousel.value))) {
|
|
return 1;
|
|
}
|
|
break;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
case MENUOP_FOCUS:
|
|
g_Menus[g_MpPlayerNum].unk840.unk000 = 3;
|
|
break;
|
|
#endif
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->carousel.value = mpheadnum;
|
|
break;
|
|
case MENUOP_SET:
|
|
case MENUOP_CHECKPREFOCUSED:
|
|
g_Menus[g_MpPlayerNum].unk840.unk580 = 0;
|
|
|
|
func0f0f372c(&g_Menus[g_MpPlayerNum].unk840, 0, 0, 0, 0, 0, 0, 1, 1);
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.unk510 = 8.2f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk514 = -4.1f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk53c = -4.1f;
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.unk538 = 8.2f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk51c = 0.002f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk524 = -0.2f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk54c = -0.2f;
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.unk578 = TICKS(60);
|
|
g_Menus[g_MpPlayerNum].unk840.unk574 = TICKS(120);
|
|
g_Menus[g_MpPlayerNum].unk840.unk000 = 8;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (operation == MENUOP_CHECKPREFOCUSED) {
|
|
g_Menus[g_MpPlayerNum].unk840.unk000 = 16;
|
|
}
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpCharacterBody(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum < mpGetNumHeads()) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (!data->carousel.unk04)
|
|
#endif
|
|
{
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum = mpGetMpheadnumByMpbodynum(data->carousel.value);
|
|
}
|
|
}
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum = data->carousel.value;
|
|
func0f17b8f0();
|
|
break;
|
|
case MENUOP_CHECKPREFOCUSED:
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
mpCharacterBodyMenuHandler(operation, item, data,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, true);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
return mpCharacterBodyMenuHandler(operation, item, data,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum,
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, true);
|
|
}
|
|
|
|
s32 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;
|
|
menuhandlerMpCharacterBody(MENUOP_11, &dialogdef->items[2], &data);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 mpChallengesListHandler(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 = challengeGetAutoFocusedIndex(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 = text0f153628(gdl);
|
|
|
|
name = xhallengeGetName(g_MpPlayerNum, challengeindex);
|
|
|
|
gdl = textRenderProjected(gdl, &x, &y, name,
|
|
g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour,
|
|
viGetWidth(), viGetHeight(), 0, 0);
|
|
|
|
gdl = text0f153780(gdl);
|
|
|
|
gDPPipeSync(gdl++);
|
|
gDPSetTexturePersp(gdl++, G_TP_NONE);
|
|
gDPSetAlphaCompare(gdl++, G_AC_NONE);
|
|
gDPSetTextureLOD(gdl++, G_TL_TILE);
|
|
gDPSetTextureConvert(gdl++, G_TC_FILT);
|
|
|
|
texSelect(&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 (challengeIsCompletedByPlayerWithNumPlayers2(g_MpPlayerNum, challengeindex, i + 1)) {
|
|
gDPSetEnvColorViaWord(gdl++, 0xb2efff00 | (renderdata->colour & 0xff) * 255 / 256);
|
|
} else {
|
|
gDPSetEnvColorViaWord(gdl++, 0x30407000 | (renderdata->colour & 0xff) * 255 / 256);
|
|
}
|
|
#else
|
|
if (challengeIsCompletedByPlayerWithNumPlayers2(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_ScaleX,
|
|
(renderdata->y + size) << 2,
|
|
((renderdata->x + size + loopx) << 2) * g_ScaleX,
|
|
(renderdata->y + size * 2) << 2,
|
|
G_TX_RENDERTILE,
|
|
0, 0x0160, 0x0400 / g_ScaleX, 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 *mpMenuTextKills(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].kills);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextDeaths(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].deaths);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextGamesPlayed(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gamesplayed);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextGamesWon(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gameswon);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextGamesLost(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gameslost);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextHeadShots(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].headshots);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextMedalAccuracy(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].accuracymedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextMedalHeadShot(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].headshotmedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextMedalKillMaster(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].killmastermedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextMedalSurvivor(struct menuitem *item)
|
|
{ \
|
|
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].survivormedals);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextAmmoUsed(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 *mpMenuTextDistance(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%s%s%.1fkm\n", "", "", g_PlayerConfigsArray[g_MpPlayerNum].distance / 10.0f);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextTime(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 *mpMenuTextAccuracy(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 mpFormatDamageValue(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 *mpMenuTextPainReceived(struct menuitem *item)
|
|
{
|
|
mpFormatDamageValue(g_StringPointer, g_PlayerConfigsArray[g_MpPlayerNum].painreceived / 10.0f);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *mpMenuTextDamageDealt(struct menuitem *item)
|
|
{
|
|
mpFormatDamageValue(g_StringPointer, g_PlayerConfigsArray[g_MpPlayerNum].damagedealt / 10.0f);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
s32 mpMedalMenuHandler(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);
|
|
|
|
texSelect(&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_ScaleX, renderdata->y << 2,
|
|
((renderdata->x + 20) << 2) * g_ScaleX, (renderdata->y + 11) << 2,
|
|
G_TX_RENDERTILE, 0, 0x0160, 1024 / g_ScaleX, -1024);
|
|
|
|
return (s32) gdl;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTitleStatsForPlayerName(struct menudialogdef *dialogdef)
|
|
{
|
|
// "Stats for %s"
|
|
sprintf(g_StringPointer, langGet(L_MPMENU_145), g_PlayerConfigsArray[g_MpPlayerNum].base.name);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
s32 menuhandlerMpUsernamePassword(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,
|
|
menuhandlerMpConfirmSaveChr,
|
|
},
|
|
{ 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,
|
|
menuhandlerMpSetupName,
|
|
},
|
|
{ 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:"
|
|
(u32)&mpMenuTextSetupName,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT,
|
|
(u32)&filemgrMenuTextDeviceName,
|
|
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,
|
|
menuhandlerMpSaveSetupOverwrite,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_186, // "Save Copy"
|
|
0,
|
|
menuhandlerMpSaveSetupCopy,
|
|
},
|
|
{
|
|
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,
|
|
menuhandlerMpWeaponSetDropdown,
|
|
},
|
|
{
|
|
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,
|
|
menuhandlerMpWeaponSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_177, // "2:"
|
|
0x00000001,
|
|
menuhandlerMpWeaponSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_178, // "3:"
|
|
0x00000002,
|
|
menuhandlerMpWeaponSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_179, // "4:"
|
|
0x00000003,
|
|
menuhandlerMpWeaponSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_180, // "5:"
|
|
0x00000004,
|
|
menuhandlerMpWeaponSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_DROPDOWN_BELOW | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_MPWEAPONSLOT,
|
|
L_MPMENU_181, // "6:"
|
|
0x00000005,
|
|
menuhandlerMpWeaponSlot,
|
|
},
|
|
{
|
|
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,
|
|
menuhandlerMpWeaponSetDropdown,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_176, // "1:"
|
|
(u32)&mpMenuTextWeaponNameForSlot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
1,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_177, // "2:"
|
|
(u32)&mpMenuTextWeaponNameForSlot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
2,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_178, // "3:"
|
|
(u32)&mpMenuTextWeaponNameForSlot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
3,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_179, // "4:"
|
|
(u32)&mpMenuTextWeaponNameForSlot,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
4,
|
|
MENUITEMFLAG_00000002,
|
|
L_MPMENU_180, // "5:"
|
|
(u32)&mpMenuTextWeaponNameForSlot,
|
|
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,
|
|
menuhandlerMpDisplayOptionCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_169, // "Highlight Players"
|
|
MPDISPLAYOPTION_HIGHLIGHTPLAYERS,
|
|
menuhandlerMpDisplayOptionCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_170, // "Highlight Teams"
|
|
MPDISPLAYOPTION_HIGHLIGHTTEAMS,
|
|
menuhandlerMpDisplayOptionCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_171, // "Radar"
|
|
MPDISPLAYOPTION_RADAR,
|
|
menuhandlerMpDisplayOptionCheckbox,
|
|
},
|
|
{
|
|
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,
|
|
menuhandlerMpControlStyle,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_201, // "Reverse Pitch"
|
|
OPTION_FORWARDPITCH,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_202, // "Look Ahead"
|
|
OPTION_LOOKAHEAD,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_203, // "Head Roll"
|
|
OPTION_HEADROLL,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_204, // "Auto-Aim"
|
|
OPTION_AUTOAIM,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPMENU_205, // "Aim Control"
|
|
0,
|
|
menuhandlerMpAimControl,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_206, // "Sight on Screen"
|
|
OPTION_SIGHTONSCREEN,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_207, // "Show Target"
|
|
OPTION_ALWAYSSHOWTARGET,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_208, // "Zoom Range"
|
|
OPTION_SHOWZOOMRANGE,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_209, // "Ammo on Screen"
|
|
OPTION_AMMOONSCREEN,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_210, // "Gun Function"
|
|
OPTION_SHOWGUNFUNCTION,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPMENU_211, // "Paintball"
|
|
OPTION_PAINTBALL,
|
|
menuhandlerMpControlCheckbox,
|
|
},
|
|
{
|
|
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,
|
|
mpChallengesListHandler,
|
|
},
|
|
{ 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 *mpMenuTextUsernamePassword(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:"
|
|
(u32)&mpMenuTextKills,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_147, // "Deaths:"
|
|
(u32)&mpMenuTextDeaths,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_148, // "Accuracy:"
|
|
(u32)&mpMenuTextAccuracy,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_149, // "Head Shots:"
|
|
(u32)&mpMenuTextHeadShots,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_150, // "Ammo Used:"
|
|
(u32)&mpMenuTextAmmoUsed,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_151, // "Damage Dealt:"
|
|
(u32)&mpMenuTextDamageDealt,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_152, // "Pain Received:"
|
|
(u32)&mpMenuTextPainReceived,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_153, // "Games Played:"
|
|
(u32)&mpMenuTextGamesPlayed,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_154, // "Games Won:"
|
|
(u32)&mpMenuTextGamesWon,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_155, // "Games Lost:"
|
|
(u32)&mpMenuTextGamesLost,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_156, // "Time:"
|
|
(u32)&mpMenuTextTime,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_157, // "Distance:"
|
|
(u32)&mpMenuTextDistance,
|
|
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:"
|
|
(u32)&mpMenuTextMedalAccuracy,
|
|
mpMedalMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
1,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
L_MPMENU_160, // "Head Shot:"
|
|
(u32)&mpMenuTextMedalHeadShot,
|
|
mpMedalMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
L_MPMENU_161, // "KillMaster:"
|
|
(u32)&mpMenuTextMedalKillMaster,
|
|
mpMedalMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
3,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
L_MPMENU_162, // "Survivor:"
|
|
(u32)&mpMenuTextMedalSurvivor,
|
|
mpMedalMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_163, // "Your Title:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE,
|
|
(u32)&mpMenuTextPlayerTitle,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_MPWEAPONS_219, // "USERNAME:"
|
|
0,
|
|
menuhandlerMpUsernamePassword,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
(u32)&mpMenuTextUsernamePassword,
|
|
#else
|
|
0x51f0,
|
|
#endif
|
|
0,
|
|
menuhandlerMpUsernamePassword,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT,
|
|
L_MPWEAPONS_220, // "PASSWORD:"
|
|
0,
|
|
menuhandlerMpUsernamePassword,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
(VERSION >= VERSION_NTSC_1_0 ? 1 : 0),
|
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
(u32)&mpMenuTextUsernamePassword,
|
|
#else
|
|
0x51f1,
|
|
#endif
|
|
0,
|
|
menuhandlerMpUsernamePassword,
|
|
},
|
|
{
|
|
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,
|
|
(u32)&mpMenuTitleStatsForPlayerName,
|
|
g_MpPlayerStatsMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_MpCompletedChallengesMenuDialog,
|
|
};
|
|
|
|
s32 mpCharacterHeadMenuHandler(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 = mpGetNumHeads2();
|
|
break;
|
|
case MENUOP_11:
|
|
#if VERSION >= VERSION_PAL_BETA
|
|
diffframe = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60freal;
|
|
#else
|
|
diffframe = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60f;
|
|
#endif
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.unk54c = diffframe;
|
|
g_Menus[g_MpPlayerNum].unk840.unk524 = diffframe;
|
|
|
|
if (mpheadnum < mpGetNumHeads2()) {
|
|
headnum = mpGetHeadId(mpheadnum);
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.unk00c = g_HeadsAndBodies[headnum].filenum;
|
|
g_Menus[g_MpPlayerNum].unk840.unk5b1_01 = false;
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.unk574 = 0;
|
|
g_Menus[g_MpPlayerNum].unk840.partvisibility = visibility;
|
|
g_Menus[g_MpPlayerNum].unk840.unk554 = 30;
|
|
break;
|
|
case MENUOP_21:
|
|
if (!challengeIsFeatureUnlocked(mpGetHeadRequiredFeature(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].unk840.unk000 = 3;
|
|
#endif
|
|
|
|
mpGetNumHeads2();
|
|
|
|
func0f0f372c(&g_Menus[g_MpPlayerNum].unk840, 0, 0, 0, 0, 0, 0, 1, 1);
|
|
|
|
g_Menus[g_MpPlayerNum].unk840.unk510 = 0;
|
|
g_Menus[g_MpPlayerNum].unk840.unk514 = 0;
|
|
g_Menus[g_MpPlayerNum].unk840.unk53c = -3;
|
|
g_Menus[g_MpPlayerNum].unk840.unk538 = 0;
|
|
g_Menus[g_MpPlayerNum].unk840.unk51c = 0.01f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk524 = -0.3f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk54c = -0.3f;
|
|
g_Menus[g_MpPlayerNum].unk840.unk544 = 1;
|
|
g_Menus[g_MpPlayerNum].unk840.unk554 = 30;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpCharacterHead(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum = data->carousel.value;
|
|
}
|
|
|
|
return mpCharacterHeadMenuHandler(operation, item, data, g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, 1);
|
|
}
|
|
|
|
char *mpMenuTextBodyName(struct menuitem *item)
|
|
{
|
|
return mpGetBodyName(g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum);
|
|
}
|
|
|
|
void func0f17b8f0(void)
|
|
{
|
|
func0f0f139c(g_MpCharacterMenuItems, -0.4f);
|
|
}
|
|
|
|
s32 mpPlayerNameMenuHandler(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;
|
|
}
|
|
|
|
s32 mpLoadSettingsMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = mpGetNumUnlockedPresets();
|
|
|
|
if (g_FileLists[1] != NULL) {
|
|
data->list.value += g_FileLists[1]->numfiles;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if (data->list.value < mpGetNumUnlockedPresets()) {
|
|
return (s32)mpGetPresetNameBySlot(data->list.value);
|
|
}
|
|
if (g_FileLists[1] != NULL) {
|
|
func0f0d564c(g_FileLists[1]->files[data->list.value - mpGetNumUnlockedPresets()].name, g_StringPointer, false);
|
|
return (s32)g_StringPointer;
|
|
}
|
|
break;
|
|
case MENUOP_SET:
|
|
mpCloseDialogsForNewSetup();
|
|
|
|
if (data->list.value < mpGetNumUnlockedPresets()) {
|
|
mp0f18dec4(data->list.value);
|
|
} else if (g_FileLists[1] != NULL) {
|
|
struct filelistfile *file = &g_FileLists[1]->files[data->list.value - mpGetNumUnlockedPresets()];
|
|
struct fileguid guid;
|
|
|
|
guid.fileid = file->fileid;
|
|
guid.deviceserial = file->deviceserial;
|
|
|
|
filemgrSaveOrLoad(&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)langGet(L_MPMENU_141); // "Presets"
|
|
}
|
|
if (g_FileLists[1] != NULL) {
|
|
return (s32)filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1);
|
|
}
|
|
break;
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
if (data->list.value == 0) {
|
|
data->list.groupstartindex = 0;
|
|
} else {
|
|
data->list.groupstartindex = mpGetNumUnlockedPresets();
|
|
|
|
if (g_FileLists[1] != NULL) {
|
|
data->list.groupstartindex += filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1);
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_LISTITEMFOCUS:
|
|
if (data->list.value < mpGetNumUnlockedPresets()) {
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = 0xffff;
|
|
} else {
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = data->list.value - mpGetNumUnlockedPresets();
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextMpconfigMarquee(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
|
|
|
|
mpsetupfileGetOverview(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, langGet(L_MPMENU_140),
|
|
filename,
|
|
langGet(g_MpScenarioOverviews[scenarionum].name),
|
|
langGet(g_MpArenas[arenanum].name),
|
|
numsims);
|
|
} else {
|
|
return "";
|
|
}
|
|
#else
|
|
// "%s: Scenario: %s Arena: %s Simulants: %d"
|
|
sprintf(g_StringPointer, langGet(L_MPMENU_140),
|
|
filename,
|
|
langGet(g_MpScenarioOverviews[scenarionum].name),
|
|
langGet(g_MpArenas[arenanum].name),
|
|
numsims);
|
|
#endif
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
s32 mpLoadPlayerMenuHandler(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:
|
|
filemgrGetSelectName(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 < 4; i++) {
|
|
if (file->fileid == g_PlayerConfigsArray[i].fileguid.fileid
|
|
&& file->deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) {
|
|
if ((g_MpSetup.chrslots & (1 << i)) == 0) {
|
|
mpPlayerSetDefaults(i, true);
|
|
} else {
|
|
available = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (available) {
|
|
guid.fileid = file->fileid;
|
|
guid.deviceserial = file->deviceserial;
|
|
|
|
menuPopDialog();
|
|
|
|
filemgrSaveOrLoad(&guid, FILEOP_LOAD_MPPLAYER, g_MpPlayerNum);
|
|
} else {
|
|
filemgrPushErrorDialog(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 filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
data->list.groupstartindex = filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value);
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpTimeLimitSlider(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, langGet(L_MPMENU_112)); // "No Limit"
|
|
} else {
|
|
sprintf(data->slider.label, langGet(L_MPMENU_114), data->slider.value + 1); // "%d Min"
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpScoreLimitSlider(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, langGet(L_MPMENU_112)); // "No Limit"
|
|
} else {
|
|
sprintf(data->slider.label, langGet(L_MPMENU_113), data->slider.value + 1); // "%d"
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpTeamScoreLimitSlider(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = mpCalculateTeamScoreLimit();
|
|
break;
|
|
case MENUOP_SET:
|
|
g_MpSetup.teamscorelimit = data->slider.value;
|
|
break;
|
|
case MENUOP_GETSLIDERLABEL:
|
|
if (data->slider.value == 400) {
|
|
sprintf(data->slider.label, langGet(L_MPMENU_112)); // "No Limit"
|
|
} else {
|
|
sprintf(data->slider.label, langGet(L_MPMENU_113), data->slider.value + 1); // "%d"
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpRestoreScoreDefaults(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
func0f187fec();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpHandicapPlayer(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", "", "", mpHandicapToDamageScale(g_PlayerConfigsArray[item->param].handicap) * 100);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextHandicapPlayerName(struct menuitem *item)
|
|
{
|
|
if (g_MpSetup.chrslots & (1 << item->param)) {
|
|
return g_PlayerConfigsArray[item->param].base.name;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
s32 menuhandlerMpRestoreHandicapDefaults(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
g_PlayerConfigsArray[i].handicap = 0x80;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menudialogMpReady(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) {
|
|
filemgrSaveOrLoad(&g_PlayerConfigsArray[g_MpPlayerNum].fileguid, FILEOP_SAVE_MPPLAYER, g_MpPlayerNum);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 menudialogMpSimulant(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') {
|
|
menuPopDialog();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
struct menuitem g_MpCharacterMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_DARKERBG,
|
|
(u32)&mpMenuTextBodyName,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
0,
|
|
0,
|
|
0x00000022,
|
|
menuhandlerMpCharacterHead,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
0,
|
|
0,
|
|
0x0000001b,
|
|
menuhandlerMpCharacterBody,
|
|
},
|
|
{ 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,
|
|
mpPlayerNameMenuHandler,
|
|
},
|
|
{ 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,
|
|
mpLoadSettingsMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(u32)&mpMenuTextMpconfigMarquee,
|
|
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,
|
|
mpLoadSettingsMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(u32)&mpMenuTextMpconfigMarquee,
|
|
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,
|
|
mpLoadPlayerMenuHandler,
|
|
},
|
|
{
|
|
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,
|
|
mpArenaMenuHandler,
|
|
},
|
|
{ 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,
|
|
menuhandlerMpTimeLimitSlider,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_109, // "Score"
|
|
0x00000064,
|
|
menuhandlerMpScoreLimitSlider,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MISC_447, // "Team Score"
|
|
0x00000190,
|
|
menuhandlerMpTeamScoreLimitSlider,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_110, // "Restore Defaults"
|
|
0,
|
|
menuhandlerMpRestoreScoreDefaults,
|
|
},
|
|
{
|
|
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,
|
|
(u32)&mpMenuTextHandicapPlayerName,
|
|
0x000000ff,
|
|
menuhandlerMpHandicapPlayer,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
1,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextHandicapPlayerName,
|
|
0x000000ff,
|
|
menuhandlerMpHandicapPlayer,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
2,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextHandicapPlayerName,
|
|
0x000000ff,
|
|
menuhandlerMpHandicapPlayer,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
3,
|
|
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextHandicapPlayerName,
|
|
0x000000ff,
|
|
menuhandlerMpHandicapPlayer,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_110, // "Restore Defaults"
|
|
0,
|
|
menuhandlerMpRestoreHandicapDefaults,
|
|
},
|
|
{
|
|
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,
|
|
menudialogMpReady,
|
|
MENUDIALOGFLAG_CLOSEONSELECT,
|
|
NULL,
|
|
};
|
|
|
|
s32 mpAddChangeSimulantMenuHandler(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 (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->list.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
|
|
if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
return (s32)langGet(g_BotProfiles[i].name);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_SET:
|
|
botnum = g_Menus[g_MpPlayerNum].mpsetup.slotindex;
|
|
creating = false;
|
|
|
|
if (botnum < 0) {
|
|
botnum = mpGetSlotForNewBot();
|
|
creating = 1;
|
|
} else if ((g_MpSetup.chrslots & (1 << (botnum + 4))) == 0) {
|
|
creating = 1;
|
|
}
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
|
|
if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->list.value) {
|
|
break;
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (creating) {
|
|
mpCreateBotFromProfile(botnum, i);
|
|
} else {
|
|
g_BotConfigsArray[botnum].type = g_BotProfiles[i].type;
|
|
|
|
if (g_BotConfigsArray[botnum].type == BOTTYPE_GENERAL) {
|
|
mpSetBotDifficulty(botnum, g_BotProfiles[i].difficulty);
|
|
}
|
|
}
|
|
|
|
mpGenerateBotNames();
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotcount = data->list.value;
|
|
break;
|
|
case MENUOP_LISTITEMFOCUS:
|
|
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
|
|
if (challengeIsFeatureUnlocked(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)langGet(groups[data->list.value].name);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
for (i = 0; i < groups[data->list.value].offset; i++) {
|
|
if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->list.groupstartindex = count;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextSimulantDescription(struct menuitem *item)
|
|
{
|
|
return langGet(L_MISC_106 + g_Menus[g_MpPlayerNum].mpsetup.unke24);
|
|
}
|
|
|
|
s32 menuhandlerMpSimulantHead(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 start = 0;
|
|
|
|
if (item->param2 == 1) {
|
|
start = mpGetNumHeads();
|
|
}
|
|
|
|
/**
|
|
* 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 mpCharacterHeadMenuHandler(operation, item, data, g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum, 0);
|
|
}
|
|
|
|
s32 menuhandlerMpSimulantBody(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 mpCharacterBodyMenuHandler(operation, item, data,
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpbodynum,
|
|
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum,
|
|
false);
|
|
}
|
|
|
|
s32 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;
|
|
menuhandlerMpCharacterBody(MENUOP_11, &dialogdef->items[1], &data);
|
|
}
|
|
}
|
|
|
|
return menudialogMpSimulant(operation, dialogdef, data);
|
|
}
|
|
|
|
s32 mpBotDifficultyMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 count = 0;
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
mpSetBotDifficulty(g_Menus[g_MpPlayerNum].mpsetup.slotindex, data->dropdown.value);
|
|
mpGenerateBotNames();
|
|
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 (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->dropdown.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < BOTDIFF_DISABLED; i++) {
|
|
if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->dropdown.value) {
|
|
// "Meat", "Easy", "Normal" etc
|
|
return (s32) langGet(L_MISC_082 + i);
|
|
}
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return (s32)"\n";
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpDeleteSimulant(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
mpRemoveSimulant(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTitleEditSimulant(struct menudialogdef *dialogdef)
|
|
{
|
|
sprintf(g_StringPointer, "%s", &g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.name);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
s32 menuhandlerMpChangeSimulantType(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
s32 count = 0;
|
|
s32 profilenum = mpFindBotProfile(
|
|
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 (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotcount = count;
|
|
|
|
menuPushDialog(&g_MpChangeSimulantMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpClearAllSimulants(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 i;
|
|
for (i = 0; i < MAX_BOTS; i++) {
|
|
mpRemoveSimulant(i);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpAddSimulant(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = -1;
|
|
menuPushDialog(&g_MpAddSimulantMenuDialog);
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
if (mpHasUnusedBotSlots() == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpSimulantSlot(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) {
|
|
menuPushDialog(&g_MpAddSimulantMenuDialog);
|
|
} else if (IS4MB()) {
|
|
menuPushDialog(&g_MpEditSimulant4MbMenuDialog);
|
|
} else {
|
|
menuPushDialog(&g_MpEditSimulantMenuDialog);
|
|
}
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (item->param >= 4 && !challengeIsFeatureUnlocked(MPFEATURE_8BOTS)) {
|
|
return true;
|
|
}
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
if (!mpIsSimSlotEnabled(item->param)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextSimulantName(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;
|
|
}
|
|
|
|
s32 menudialogMpSimulants(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,
|
|
mpAddChangeSimulantMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(u32)&mpMenuTextSimulantDescription,
|
|
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,
|
|
menudialogMpSimulant,
|
|
MENUDIALOGFLAG_CLOSEONSELECT | MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSimulantCharacterMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0,
|
|
0x00000025,
|
|
menuhandlerMpSimulantHead,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CAROUSEL,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0,
|
|
0x0000001b,
|
|
menuhandlerMpSimulantBody,
|
|
},
|
|
{ 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,
|
|
mpBotDifficultyMenuHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_096, // "Change Type..."
|
|
0,
|
|
menuhandlerMpChangeSimulantType,
|
|
},
|
|
{
|
|
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,
|
|
menuhandlerMpDeleteSimulant,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_MPMENU_099, // "Back"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpEditSimulantMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(u32)&mpMenuTitleEditSimulant,
|
|
g_MpEditSimulantMenuItems,
|
|
menudialogMpSimulant,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSimulantsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_084, // "Add Simulant..."
|
|
0,
|
|
menuhandlerMpAddSimulant,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_085, // "1:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
0,
|
|
L_MPMENU_086, // "2:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
0,
|
|
L_MPMENU_087, // "3:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
3,
|
|
0,
|
|
L_MPMENU_088, // "4:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
4,
|
|
0,
|
|
L_MPMENU_089, // "5:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
5,
|
|
0,
|
|
L_MPMENU_090, // "6:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
6,
|
|
0,
|
|
L_MPMENU_091, // "7:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
7,
|
|
0,
|
|
L_MPMENU_092, // "8:"
|
|
(u32)&mpMenuTextSimulantName,
|
|
menuhandlerMpSimulantSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_093, // "Clear All"
|
|
0,
|
|
menuhandlerMpClearAllSimulants,
|
|
},
|
|
{
|
|
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,
|
|
menudialogMpSimulants,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
s32 menuhandlerMpNTeams(s32 operation, struct menuitem *item, union handlerdata *data, s32 numteams)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 numchrs = mpGetNumChrs();
|
|
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 = mpGetChrConfigBySlotNum(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);
|
|
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpTwoTeams(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandlerMpNTeams(operation, item, data, 2);
|
|
}
|
|
|
|
s32 menuhandlerMpThreeTeams(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandlerMpNTeams(operation, item, data, 3);
|
|
}
|
|
|
|
s32 menuhandlerMpFourTeams(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandlerMpNTeams(operation, item, data, 4);
|
|
}
|
|
|
|
s32 menuhandlerMpMaximumTeams(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 >= scenarioGetMaxTeams()) {
|
|
team = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpHumansVsSimulants(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;
|
|
}
|
|
}
|
|
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpHumanSimulantPairs(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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextChrNameForTeamSetup(struct menuitem *item)
|
|
{
|
|
struct mpchrconfig *mpchr = mpGetChrConfigBySlotNum(item->param);
|
|
|
|
if (mpchr) {
|
|
return mpchr->name;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
s32 func0f17dac4(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = scenarioGetMaxTeams();
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) == 0) {
|
|
return (s32) "\n";
|
|
}
|
|
|
|
return (s32) g_BossFile.teamnames[data->list.value];
|
|
}
|
|
|
|
return menuhandlerMpTeamsLabel(operation, item, data);
|
|
}
|
|
|
|
s32 menuhandlerMpTeamSlot(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
struct mpchrconfig *mpchr;
|
|
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
mpchr = mpGetChrConfigBySlotNum(item->param);
|
|
mpchr->team = data->dropdown.value;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
mpchr = mpGetChrConfigBySlotNum(item->param);
|
|
|
|
if (!mpchr) {
|
|
data->dropdown.value = 0xff;
|
|
} else {
|
|
data->dropdown.value = mpchr->team;
|
|
}
|
|
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
mpchr = mpGetChrConfigBySlotNum(item->param);
|
|
|
|
if (!mpchr) {
|
|
return 1;
|
|
}
|
|
|
|
return menuhandlerMpTeamsLabel(operation, item, data);
|
|
}
|
|
|
|
return func0f17dac4(operation, item, data);
|
|
}
|
|
|
|
char *mpMenuTextSelectTuneOrTunes(struct menuitem *item)
|
|
{
|
|
if (mpGetUsingMultipleTunes()) {
|
|
return langGet(L_MPMENU_069); // "Select Tune"
|
|
}
|
|
|
|
return langGet(L_MPMENU_068); // "Select Tunes"
|
|
}
|
|
|
|
struct menuitem g_MpAutoTeamMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_076, // "Two Teams"
|
|
0,
|
|
menuhandlerMpTwoTeams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_077, // "Three Teams"
|
|
0,
|
|
menuhandlerMpThreeTeams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_078, // "Four Teams"
|
|
0,
|
|
menuhandlerMpFourTeams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_079, // "Maximum Teams"
|
|
0,
|
|
menuhandlerMpMaximumTeams,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_080, // "Humans vs. Simulants"
|
|
0,
|
|
menuhandlerMpHumansVsSimulants,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_081, // "Human-Simulant Pairs"
|
|
0,
|
|
menuhandlerMpHumanSimulantPairs,
|
|
},
|
|
{
|
|
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,
|
|
menuhandlerMpTeamsEnabled,
|
|
},
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x85,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_072, // "Teams:"
|
|
0,
|
|
menuhandlerMpTeamsLabel,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
1,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
2,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
3,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
4,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
5,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
6,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
7,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
8,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
9,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
10,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
11,
|
|
MENUITEMFLAG_ADJUSTWIDTH | MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
#else
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_LESSLEFTPADDING,
|
|
L_MPMENU_072, // "Teams:"
|
|
0,
|
|
menuhandlerMpTeamsLabel,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
1,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
2,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
3,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
4,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
5,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
6,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
7,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
8,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
9,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
10,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
11,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
(u32)&mpMenuTextChrNameForTeamSetup,
|
|
0,
|
|
menuhandlerMpTeamSlot,
|
|
},
|
|
#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.
|
|
*/
|
|
s32 mpSelectTuneListHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = mpGetNumUnlockedTracks();
|
|
|
|
if (mpGetUsingMultipleTunes()) {
|
|
data->list.value += 3;
|
|
} else {
|
|
data->list.value++;
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
{
|
|
s32 numtracks = mpGetNumUnlockedTracks();
|
|
|
|
if (data->list.value < numtracks) {
|
|
return (s32) mpGetTrackName(data->list.value);
|
|
}
|
|
|
|
if (mpGetUsingMultipleTunes()) {
|
|
return (s32) langGet(var80085ce8[1 + data->list.value - numtracks]);
|
|
}
|
|
|
|
return (s32) langGet(var80085ce8[data->list.value - numtracks]);
|
|
}
|
|
case MENUOP_SET:
|
|
{
|
|
s32 numtracks = mpGetNumUnlockedTracks();
|
|
|
|
if (data->list.value < numtracks) {
|
|
if (data->list.unk04 == 0) {
|
|
mpSetTrackSlotEnabled(data->list.value);
|
|
}
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
} else if (mpGetUsingMultipleTunes()) {
|
|
s32 index = data->list.value - numtracks;
|
|
|
|
switch (index) {
|
|
case 0:
|
|
mpEnableAllMultiTracks();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
case 1:
|
|
mpDisableAllMultiTracks();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
case 2:
|
|
mpRandomiseMultiTracks();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
}
|
|
} else {
|
|
mpSetTrackToRandom();
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
if (mpGetUsingMultipleTunes()) {
|
|
data->list.value = 0x000fffff;
|
|
} else {
|
|
s32 slotnum = mpGetCurrentTrackSlotNum();
|
|
|
|
if (slotnum < 0) {
|
|
data->list.value = mpGetNumUnlockedTracks();
|
|
} else {
|
|
data->list.value = slotnum;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_LISTITEMFOCUS:
|
|
if (data->list.value < mpGetNumUnlockedTracks()) {
|
|
musicStartTrackAsMenu(mpGetTrackMusicNum(data->list.value));
|
|
}
|
|
break;
|
|
case MENUOP_GETLISTITEMCHECKBOX:
|
|
{
|
|
s32 numtracks = mpGetNumUnlockedTracks();
|
|
|
|
if (mpGetUsingMultipleTunes() && data->list.value < numtracks) {
|
|
data->list.unk04 = mpIsMultiTrackSlotEnabled(data->list.value);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menudialogMpSelectTune(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
var800840e0 = 80;
|
|
}
|
|
|
|
if (operation == MENUOP_CLOSE) {
|
|
var800840e0 = 15;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
char *mpMenuTextCurrentTrack(struct menuitem *item)
|
|
{
|
|
s32 slotnum;
|
|
|
|
if (mpGetUsingMultipleTunes()) {
|
|
return langGet(L_MPMENU_066); // "Multiple Tunes"
|
|
}
|
|
|
|
slotnum = mpGetCurrentTrackSlotNum();
|
|
|
|
if (slotnum >= 0) {
|
|
return mpGetTrackName(slotnum);
|
|
}
|
|
|
|
return langGet(L_MPMENU_067); // "Random"
|
|
}
|
|
|
|
s32 menuhandlerMpMultipleTunes(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GET:
|
|
return mpGetUsingMultipleTunes();
|
|
case MENUOP_SET:
|
|
mpSetUsingMultipleTunes(data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 mpTeamNameMenuHandler(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 *mpMenuTextTeamName(struct menuitem *item)
|
|
{
|
|
s32 index = item->param2;
|
|
index -= L_OPTIONS_008;
|
|
|
|
return g_BossFile.teamnames[index];
|
|
}
|
|
|
|
s32 menuhandlerMpTeamNameSlot(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Menus[g_MpPlayerNum].mpsetup.slotindex = item->param2 - 0x5608;
|
|
menuPushDialog(&g_MpChangeTeamNameMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *func0f17e318(struct menudialogdef *dialogdef)
|
|
{
|
|
sprintf(g_StringPointer, langGet(L_MPMENU_056), challengeGetNameBySlot(g_Menus[g_MpPlayerNum].mpsetup.slotindex));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
/**
|
|
* An "Accept" item somewhere. Probably accepting a challenge.
|
|
*/
|
|
s32 menuhandler0017e38c(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
challengeUnsetCurrent();
|
|
#endif
|
|
|
|
menuPopDialog();
|
|
challengeSetCurrentBySlot(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menudialog0017e3fc(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_OPEN:
|
|
g_Menus[g_MpPlayerNum].unk840.unk010 = 0;
|
|
|
|
g_Menus[g_MpPlayerNum].training.mpconfig = challengeLoadBySlot(
|
|
g_Menus[g_MpPlayerNum].training.unke1c,
|
|
g_Menus[g_MpPlayerNum].unk840.unk004,
|
|
g_Menus[g_MpPlayerNum].unk840.unk008);
|
|
break;
|
|
case MENUOP_CLOSE:
|
|
break;
|
|
case MENUOP_TICK:
|
|
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
|
|
menuPopDialog();
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_MpSelectTunesMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mpSelectTuneListHandler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpSelectTunesMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(u32)&mpMenuTextSelectTuneOrTunes,
|
|
g_MpSelectTunesMenuItems,
|
|
menudialogMpSelectTune,
|
|
MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpSoundtrackMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_MPMENU_063, // "Current:"
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
0,
|
|
L_OPTIONS_003, // ""
|
|
(u32)&mpMenuTextCurrentTrack,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
(u32)&mpMenuTextSelectTuneOrTunes,
|
|
0,
|
|
(void *)&g_MpSelectTunesMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_064, // "Multiple Tunes"
|
|
0,
|
|
menuhandlerMpMultipleTunes,
|
|
},
|
|
{
|
|
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,
|
|
mpTeamNameMenuHandler,
|
|
},
|
|
{ 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"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_009, // "Yellow"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_010, // "Blue"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_011, // "Magenta"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_012, // "Cyan"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_013, // "Orange"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_014, // "Pink"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_OPTIONS_015, // "Brown"
|
|
(u32)&mpMenuTextTeamName,
|
|
menuhandlerMpTeamNameSlot,
|
|
},
|
|
{
|
|
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,
|
|
(u32)&func0f17e318,
|
|
g_MpConfirmChallengeViaListOrDetailsMenuItems,
|
|
menudialog0017e3fc,
|
|
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_MPLOCKABLE,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpChallengesListOrDetailsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mpChallengesListMenuHandler,
|
|
},
|
|
#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,
|
|
menuhandlerMpStartChallenge,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_051, // "Abort Challenge"
|
|
0,
|
|
menuhandlerMpAbortChallenge,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpChallengeListOrDetailsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
(u32)&mpMenuTextChallengeName,
|
|
#else
|
|
0x5032,
|
|
#endif
|
|
g_MpChallengesListOrDetailsMenuItems,
|
|
mpCombatChallengesMenuDialog,
|
|
#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
|
|
(u32)&mpMenuTextChallengeName,
|
|
#else
|
|
0x5032,
|
|
#endif
|
|
g_MpChallengesListOrDetailsMenuItems,
|
|
mpCombatChallengesMenuDialog,
|
|
#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,
|
|
(u32)&func0f17e318,
|
|
g_MpConfirmChallengeMenuItems,
|
|
menudialog0017e3fc,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
s32 mpChallengesListMenuHandler(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 = challengeGetNumAvailable();
|
|
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) {
|
|
menuPushDialog(&g_MpConfirmChallengeViaListOrDetailsMenuDialog);
|
|
} else if (IS4MB()) {
|
|
menuPushDialog(&g_MpConfirmChallenge4MbMenuDialog);
|
|
} else {
|
|
menuPushDialog(&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 = text0f153628(gdl);
|
|
gdl = textRenderProjected(gdl, &x, &y, challengeGetNameBySlot(data->type19.unk04), g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 0);
|
|
gdl = text0f153780(gdl);
|
|
|
|
gDPPipeSync(gdl++);
|
|
gDPSetTexturePersp(gdl++, G_TP_NONE);
|
|
gDPSetAlphaCompare(gdl++, G_AC_NONE);
|
|
gDPSetTextureLOD(gdl++, G_TL_TILE);
|
|
gDPSetTextureConvert(gdl++, G_TC_FILT);
|
|
|
|
texSelect(&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 (challengeIsCompletedByAnyChrWithNumPlayersBySlot(data->type19.unk04, i + 1)) {
|
|
gDPSetEnvColorViaWord(gdl++, (renderdata->colour & 0xff) * 0xff >> 8 | 0xffe56500);
|
|
} else {
|
|
gDPSetEnvColorViaWord(gdl++, (renderdata->colour & 0xff) * 0xff >> 8 | 0x43430000);
|
|
}
|
|
#else
|
|
if (challengeIsCompletedByAnyChrWithNumPlayersBySlot(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_ScaleX, (renderdata->y + 11) << 2,
|
|
((renderdata->x + marginleft + 11) << 2) * g_ScaleX, (renderdata->y + 22) << 2,
|
|
G_TX_RENDERTILE, 0, 0x0160, 1024 / g_ScaleX, -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
|
|
*/
|
|
s32 menuhandler0017e9d8(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpAbortChallenge(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_SET) {
|
|
challengeRemovePlayerLock();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpStartChallenge(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return true;
|
|
}
|
|
}
|
|
if (operation == MENUOP_SET) {
|
|
menuPushDialog(&g_MpReadyMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextChallengeName(struct menuitem *item)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
|
|
return langGet(L_MPMENU_050); // "Combat Challenges"
|
|
}
|
|
#endif
|
|
|
|
sprintf(g_StringPointer, "%s:\n", challengeGetName(challengeGetCurrent()));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
s32 mpCombatChallengesMenuDialog(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
|
|
&& !challengeIsLoaded()) {
|
|
g_Menus[g_MpPlayerNum].unk840.unk010 = 0x4fac5ace;
|
|
|
|
challengeLoadAndStoreCurrent(
|
|
g_Menus[g_MpPlayerNum].unk840.unk004,
|
|
g_Menus[g_MpPlayerNum].unk840.unk008);
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_CLOSE) {
|
|
if (g_Menus[g_MpPlayerNum].unk840.unk010 == 0x4fac5ace) {
|
|
challengeUnsetCurrent();
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandler0017ec64(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
challengeSetCurrentBySlot(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
|
|
func0f0f820c(&g_MpQuickGoMenuDialog, 3);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_MpChallengesMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
1,
|
|
MENUITEMFLAG_LIST_CUSTOMRENDER,
|
|
0x00000078,
|
|
0x0000004d,
|
|
mpChallengesListMenuHandler,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpChallengesMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_050, // "Combat Challenges"
|
|
g_MpChallengesMenuItems,
|
|
mpCombatChallengesMenuDialog,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
s32 menuhandlerMpLock(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 = mpGetLockType() == MPLOCKTYPE_CHALLENGE ? 1 : 5;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if (mpGetLockType() == MPLOCKTYPE_CHALLENGE) {
|
|
return (s32) langGet(L_MPMENU_049); // "Challenge"
|
|
}
|
|
if (data->dropdown.value <= 3) {
|
|
return (s32) langGet(labels[data->dropdown.value]);
|
|
}
|
|
if (mpGetLockType() == MPLOCKTYPE_PLAYER) {
|
|
return (s32) g_PlayerConfigsArray[mpGetLockPlayerNum()].base.name;
|
|
}
|
|
return (s32) mpGetCurrentPlayerName(item);
|
|
case MENUOP_SET:
|
|
if (mpGetLockType() != MPLOCKTYPE_CHALLENGE) {
|
|
mpSetLock(data->dropdown.value, g_MpPlayerNum);
|
|
}
|
|
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = mpGetLockType() == MPLOCKTYPE_CHALLENGE ? 0 : mpGetLockType();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpSavePlayer(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid == 0) {
|
|
filemgrPushSelectLocationDialog(6, FILETYPE_MPPLAYER);
|
|
} else {
|
|
menuPushDialog(&g_MpSavePlayerMenuDialog);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextSavePlayerOrCopy(struct menuitem *item)
|
|
{
|
|
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid == 0) {
|
|
return langGet(L_MPMENU_038); // "Save Player"
|
|
}
|
|
|
|
return langGet(L_MPMENU_039); // "Save Copy of Player"
|
|
}
|
|
|
|
s32 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;
|
|
}
|
|
|
|
s32 menuhandlerMpSaveSettings(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
if (g_MpSetup.fileguid.fileid == 0) {
|
|
menuPushDialog(&g_MpSaveSetupNameMenuDialog);
|
|
} else {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
filemgrSetDevice1BySerial(g_MpSetup.fileguid.deviceserial);
|
|
#endif
|
|
|
|
menuPushDialog(&g_MpSaveSetupExistsMenuDialog);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *mpMenuTextArenaName(struct menuitem *item)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i != ARRAYCOUNT(g_MpArenas); i++) {
|
|
if (g_MpArenas[i].stagenum == g_MpSetup.stagenum) {
|
|
return langGet(g_MpArenas[i].name);
|
|
}
|
|
}
|
|
|
|
return "\n";
|
|
}
|
|
|
|
char *mpMenuTextWeaponSetName(struct menuitem *item)
|
|
{
|
|
return mpGetWeaponSetName(mpGetWeaponSet());
|
|
}
|
|
|
|
s32 menudialogMpGameSetup(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Vars.mpsetupmenu = MPSETUPMENU_ADVSETUP;
|
|
g_Vars.usingadvsetup = true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 menudialogMpQuickGo(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_OPEN) {
|
|
g_Vars.mpsetupmenu = MPSETUPMENU_QUICKGO;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void mpConfigureQuickTeamPlayers(void)
|
|
{
|
|
s32 i;
|
|
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_NONE) {
|
|
for (i = 0; i < MAX_BOTS; i++) {
|
|
mpRemoveSimulant(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 < 4; i++) {
|
|
g_PlayerConfigsArray[i].base.team = g_Vars.mpplayerteams[i];
|
|
}
|
|
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSVSSIMS:
|
|
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
g_PlayerConfigsArray[i].base.team = 0;
|
|
}
|
|
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSIMTEAMS:
|
|
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
g_PlayerConfigsArray[i].base.team = i;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void mpConfigureQuickTeamSimulants(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 = mpGetSlotForNewBot();
|
|
|
|
if (botnum >= 0) {
|
|
mpCreateBotFromProfile(botnum, g_Vars.mpsimdifficulty);
|
|
}
|
|
}
|
|
|
|
mpGenerateBotNames();
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSVSSIMS:
|
|
for (i = 0; i < g_Vars.mpquickteamnumsims; i++) {
|
|
botnum = mpGetSlotForNewBot();
|
|
|
|
if (botnum >= 0) {
|
|
mpCreateBotFromProfile(botnum, g_Vars.mpsimdifficulty);
|
|
}
|
|
}
|
|
|
|
mpGenerateBotNames();
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_BotConfigsArray); i++) {
|
|
g_BotConfigsArray[i].base.team = 1;
|
|
}
|
|
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSIMTEAMS:
|
|
for (i = mpGetNumChrs() - 1; i >= 0; i--) {
|
|
mpchr = mpGetChrConfigBySlotNum(i);
|
|
|
|
for (j = 0; j < g_Vars.unk0004a0; j++) {
|
|
botnum = mpGetSlotForNewBot();
|
|
|
|
if (botnum >= 0) {
|
|
mpCreateBotFromProfile(botnum, g_Vars.mpsimdifficulty);
|
|
g_BotConfigsArray[botnum].base.team = mpchr->team;
|
|
}
|
|
}
|
|
}
|
|
|
|
mpGenerateBotNames();
|
|
break;
|
|
case MPQUICKTEAM_PLAYERSONLY:
|
|
case MPQUICKTEAM_PLAYERSTEAMS:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void func0f17f428(void)
|
|
{
|
|
mpConfigureQuickTeamPlayers();
|
|
|
|
if (IS4MB()) {
|
|
func0f0f820c(&g_MpQuickGo4MbMenuDialog, MENUROOT_4MBMAINMENU);
|
|
} else {
|
|
func0f0f820c(&g_MpQuickGoMenuDialog, MENUROOT_MPSETUP);
|
|
}
|
|
}
|
|
|
|
s32 menuhandlerMpFinishedSetup(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;
|
|
}
|
|
|
|
s32 menuhandlerQuickTeamSeparator(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_Vars.mpquickteam == MPQUICKTEAM_PLAYERSONLY) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerPlayerTeam(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
data->dropdown.value = scenarioGetMaxTeams();
|
|
#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] >= scenarioGetMaxTeams()) {
|
|
g_Vars.mpplayerteams[item->param] %= scenarioGetMaxTeams();
|
|
}
|
|
#endif
|
|
data->dropdown.value = g_Vars.mpplayerteams[item->param];
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSTEAMS) {
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpNumberOfSimulants(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->dropdown.value = !challengeIsFeatureUnlocked(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;
|
|
}
|
|
|
|
s32 menuhandlerMpSimulantsPerTeam(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;
|
|
}
|
|
|
|
s32 mpQuickTeamSimulantDifficultyHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 count = 0;
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
for (i = 0; i < 6; i++) {
|
|
if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
data->dropdown.value = count;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
for (i = 0; i < 6; i++) {
|
|
if (challengeIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
|
|
if (count == data->dropdown.value) {
|
|
return (s32) langGet(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 != 1 && g_Vars.mpquickteam != 3 && g_Vars.mpquickteam != 4) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menuhandlerMpQuickTeamOption(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Vars.mpquickteam = item->param;
|
|
|
|
if (mpGetWeaponSet() >= func0f189058(0)) {
|
|
mpSetWeaponSet(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;
|
|
}
|
|
}
|
|
|
|
menuPushDialog(&g_MpQuickTeamGameSetupMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 menudialogCombatSimulator(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;
|
|
challengeUnsetCurrent();
|
|
challengeRemovePlayerLock();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 menuhandlerMpAdvancedSetup(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 mpCloseDialogsForNewSetup(void)
|
|
{
|
|
s32 i;
|
|
s32 prevplayernum = g_MpPlayerNum;
|
|
s32 j;
|
|
s32 k;
|
|
|
|
// Loop through each player
|
|
for (i = 0; i < 4; 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) {
|
|
menuPopDialog();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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,
|
|
menuhandlerMpLock,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_216, // "Ratio"
|
|
0,
|
|
menuhandlerScreenRatio,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_154, // "Split"
|
|
0,
|
|
menuhandlerScreenSplit,
|
|
},
|
|
{
|
|
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"
|
|
(u32)&mpGetCurrentPlayerName,
|
|
(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,
|
|
(u32)&mpMenuTextSavePlayerOrCopy,
|
|
0,
|
|
menuhandlerMpSavePlayer,
|
|
},
|
|
{ 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"
|
|
(u32)&mpMenuTextScenarioShortName,
|
|
(void *)&g_MpScenarioMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_021, // "Options"
|
|
0,
|
|
menuhandlerMpOpenOptions,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_020, // "Arena"
|
|
(u32)&mpMenuTextArenaName,
|
|
(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,
|
|
menuhandlerMpSaveSettings,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MpAdvancedSetupMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_017, // "Game Setup"
|
|
g_MpAdvancedSetupMenuItems,
|
|
menudialogMpGameSetup,
|
|
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
|
|
&g_MpPlayerSetupViaAdvMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_MpAdvancedSetupViaAdvChallengeMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPMENU_017, // "Game Setup"
|
|
g_MpAdvancedSetupMenuItems,
|
|
menudialogMpGameSetup,
|
|
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,
|
|
menudialogMpQuickGo,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_MpQuickTeamGameSetupMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_LOCKABLEMINOR,
|
|
L_MPMENU_019, // "Scenario"
|
|
(u32)&mpMenuTextScenarioShortName,
|
|
(void *)&g_MpQuickTeamScenarioMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPMENU_021, // "Options"
|
|
0,
|
|
menuhandlerMpOpenOptions,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_020, // "Arena"
|
|
(u32)&mpMenuTextArenaName,
|
|
(void *)&g_MpArenaMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_023, // "Weapons"
|
|
(u32)&mpMenuTextWeaponSetName,
|
|
(void *)&g_MpQuickTeamWeaponsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
|
|
L_MPMENU_024, // "Limits"
|
|
0,
|
|
(void *)&g_MpLimitsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
menuhandlerQuickTeamSeparator,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_449, // "Player 1 Team"
|
|
0,
|
|
menuhandlerPlayerTeam,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
1,
|
|
0,
|
|
L_MISC_450, // "Player 2 Team"
|
|
0,
|
|
menuhandlerPlayerTeam,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
2,
|
|
0,
|
|
L_MISC_451, // "Player 3 Team"
|
|
0,
|
|
menuhandlerPlayerTeam,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
3,
|
|
0,
|
|
L_MISC_452, // "Player 4 Team"
|
|
0,
|
|
menuhandlerPlayerTeam,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_453, // "Number Of Simulants"
|
|
0,
|
|
menuhandlerMpNumberOfSimulants,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_454, // "Simulants Per Team"
|
|
0,
|
|
menuhandlerMpSimulantsPerTeam,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MISC_455, // "Simulant Difficulty"
|
|
0,
|
|
mpQuickTeamSimulantDifficultyHandler,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MISC_448, // "Finished Setup"
|
|
0,
|
|
menuhandlerMpFinishedSetup,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
|
|
L_MPMENU_026, // "Save Settings"
|
|
0,
|
|
menuhandlerMpSaveSettings,
|
|
},
|
|
{ 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,
|
|
menuhandlerMpQuickTeamOption,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_464, // "Players and Simulants"
|
|
0,
|
|
menuhandlerMpQuickTeamOption,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x00000082,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_465, // "Player Teams"
|
|
0,
|
|
menuhandlerMpQuickTeamOption,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
3,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_466, // "Players vs. Simulants"
|
|
0,
|
|
menuhandlerMpQuickTeamOption,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
4,
|
|
MENUITEMFLAG_BIGFONT,
|
|
L_MISC_467, // "Player-Simulant Teams"
|
|
0,
|
|
menuhandlerMpQuickTeamOption,
|
|
},
|
|
{ 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,
|
|
menuhandlerMpAdvancedSetup,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_CombatSimulatorMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MISC_445, // "Combat Simulator"
|
|
g_CombatSimulatorMenuItems,
|
|
menudialogCombatSimulator,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
void func0f17fcb0(s32 silent)
|
|
{
|
|
g_Menus[g_MpPlayerNum].playernum = g_MpPlayerNum;
|
|
|
|
if (IS4MB()) {
|
|
menuPushRootDialog(&g_AdvancedSetup4MbMenuDialog, MENUROOT_4MBMAINMENU);
|
|
func0f0f8300();
|
|
} else {
|
|
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
|
|
menuPushRootDialog(&g_MpChallengeListOrDetailsViaAdvChallengeMenuDialog, MENUROOT_MPSETUP);
|
|
} else {
|
|
menuPushRootDialog(&g_MpAdvancedSetupMenuDialog, MENUROOT_MPSETUP);
|
|
}
|
|
|
|
func0f0f8300();
|
|
}
|
|
|
|
if (!silent) {
|
|
// Explosion sound
|
|
sndStart(var80095200, SFX_EXPLOSION_809A, NULL, -1, -1, -1, -1, -1);
|
|
}
|
|
}
|