From 904faa54851ca61486c014705f7f64e440a37681 Mon Sep 17 00:00:00 2001 From: Jonaeru Date: Fri, 7 Feb 2025 15:38:41 +0900 Subject: [PATCH] Add MP Select Random Weapon Menu --- src/game/mplayer/mplayer.c | 46 +++++++++ src/game/mplayer/setup.c | 159 +++++++++++++++++++++++++++++ src/include/data.h | 3 + src/include/game/mplayer/mplayer.h | 3 + 4 files changed, 211 insertions(+) diff --git a/src/game/mplayer/mplayer.c b/src/game/mplayer/mplayer.c index df78ced21..4be0635ad 100644 --- a/src/game/mplayer/mplayer.c +++ b/src/game/mplayer/mplayer.c @@ -48,6 +48,11 @@ struct modeldef *var800acc28[18]; struct mpweaponset g_MpWeaponSets[12]; s32 g_MpWeaponSetNum; +#ifndef PLATFORM_N64 +u8 g_MpWeaponSetRandomFilters[NUM_MPWEAPONS]; +s32 g_MpWeaponRandomFilterNum; +#endif + #if VERSION >= VERSION_NTSC_1_0 const char var7f1b8a00[] = "||||||||||||| Starting game... players %d\n"; #endif @@ -507,6 +512,12 @@ void mpPlayerSetDefaults(s32 playernum, bool autonames) for (i = 0; i < ARRAYCOUNT(g_PlayerConfigsArray); i++) { g_PlayerConfigsArray[playernum].gunfuncs[i] = 0; } + +#ifndef PLATFORM_N64 + for (i = 0; i < ARRAYCOUNT(g_MpWeapons); i++) { + g_MpWeaponSetRandomFilters[i] = 1; + } +#endif } void func0f1881d4(s32 index) @@ -1157,10 +1168,28 @@ void func0f18913c(void) } } +#ifndef PLATFORM_N64 +void mpSetRandomWeapons(u8 weapons[]) +{ + s32 i; + s32 index = 0; + for (i = 0; i < NUM_MPWEAPONS; i++) { + if (g_MpWeaponSetRandomFilters[i] == 1) { + weapons[index] = i; + index++; + } + } + g_MpWeaponRandomFilterNum = index; +} +#endif + void mpApplyWeaponSet(void) { s32 i; u8 *ptr; +#ifndef PLATFORM_N64 + u8 randomweapons[NUM_MPWEAPONS]; +#endif if (g_MpWeaponSetNum >= 0 && g_MpWeaponSetNum < ARRAYCOUNT(g_MpWeaponSets)) { if (challengeIsFeatureUnlocked(g_MpWeaponSets[g_MpWeaponSetNum].requirefeatures[0]) @@ -1198,12 +1227,20 @@ void mpApplyWeaponSet(void) } } } else if (g_MpWeaponSetNum == WEAPONSET_RANDOM) { +#ifdef PLATFORM_N64 s32 numoptions = mpGetNumWeaponOptions(); for (i = 0; i < ARRAYCOUNT(g_MpSetup.weapons); i++) { mpSetWeaponSlot(i, rngRandom() % numoptions); } +#else + mpSetRandomWeapons(randomweapons); + for (i = 0; i < ARRAYCOUNT(g_MpSetup.weapons); i++) { + mpSetWeaponSlot(i, randomweapons[rngRandom() % g_MpWeaponRandomFilterNum]); + } +#endif } else if (g_MpWeaponSetNum == WEAPONSET_RANDOMFIVE) { +#ifdef PLATFORM_N64 s32 numoptions = mpGetNumWeaponOptions() - 2; for (i = 0; i < 5; i++) { @@ -1211,6 +1248,15 @@ void mpApplyWeaponSet(void) } mpSetWeaponSlot(i, mpGetNumWeaponOptions() - 1); +#else + mpSetRandomWeapons(randomweapons); + for (i = 0; i < 5; i++) { + mpSetWeaponSlot(i, randomweapons[rngRandom() % g_MpWeaponRandomFilterNum]); + } + + // Disabled + mpSetWeaponSlot(i, MPWEAPON_DISABLED); +#endif } } diff --git a/src/game/mplayer/setup.c b/src/game/mplayer/setup.c index 380c1b283..4d7f0d5f7 100644 --- a/src/game/mplayer/setup.c +++ b/src/game/mplayer/setup.c @@ -1165,6 +1165,157 @@ struct menudialogdef g_MpSaveSetupExistsMenuDialog = { }; #ifndef PLATFORM_N64 +MenuItemHandlerResult mpSelectRandomWeaponListHandler(s32 operation, struct menuitem *item, union handlerdata *data) +{ + static const char *labels[] = { + "Select Dark", + "Select Classic", + "Select All", + "Select None", + }; + + switch (operation) { + case MENUOP_GETOPTIONCOUNT: + data->list.value = mpGetNumWeaponOptions() + 4; + break; + case MENUOP_GETOPTIONTEXT: + { + s32 numweapons = mpGetNumWeaponOptions(); + + if (data->list.value < numweapons) { + return (uintptr_t) mpGetWeaponLabel(data->list.value); + } else { + return (intptr_t)labels[data->list.value - numweapons]; + } + } + case MENUOP_SET: + { + s32 numweapons = mpGetNumWeaponOptions(); + s32 mpweaponnum = data->list.value; + s32 optionindex = mpweaponnum; + s32 i; + + if (data->list.value < numweapons) { + for (i = 0; i <= mpweaponnum; i++) { + if (challengeIsFeatureUnlocked(g_MpWeapons[i].unlockfeature) == 0) { + mpweaponnum++; + } + + optionindex = mpweaponnum; + } + + if (g_MpWeaponSetRandomFilters[optionindex] == 0) { + g_MpWeaponSetRandomFilters[optionindex] = 1; + } else { + g_MpWeaponSetRandomFilters[optionindex] = 0; + } + } else { + s32 index = data->list.value - numweapons; + + switch (index) { + case 0: + // Select Dark + for (i = 0; i < ARRAYCOUNT(g_MpWeapons); i++) { + if ((i >= MPWEAPON_NONE && i <= MPWEAPON_COMBATBOOST) || i >= MPWEAPON_SHIELD) { + g_MpWeaponSetRandomFilters[i] = 1; + } else { + g_MpWeaponSetRandomFilters[i] = 0; + } + } + break; + case 1: + // Select Classic + for (i = 0; i < ARRAYCOUNT(g_MpWeapons); i++) { + if (i >= MPWEAPON_PP9I && i <= MPWEAPON_RCP45) { + g_MpWeaponSetRandomFilters[i] = 1; + } else { + g_MpWeaponSetRandomFilters[i] = 0; + } + } + break; + case 2: + // Select All + for (i = 0; i < ARRAYCOUNT(g_MpWeapons); i++) { + g_MpWeaponSetRandomFilters[i] = 1; + } + break; + case 3: + // Select None + for (i = 0; i < ARRAYCOUNT(g_MpWeapons); i++) { + g_MpWeaponSetRandomFilters[i] = 0; + } + break; + } + } + } + break; + case MENUOP_GETSELECTEDINDEX: + data->list.value = 0x000fffff; + break; + case MENUOP_GETLISTITEMCHECKBOX: + { + s32 numweapons = mpGetNumWeaponOptions(); + s32 mpweaponnum = data->list.value; + s32 optionindex = mpweaponnum; + s32 i; + + if (data->list.value < numweapons) { + + for (i = 0; i <= mpweaponnum; i++) { + if (challengeIsFeatureUnlocked(g_MpWeapons[i].unlockfeature) == 0) { + mpweaponnum++; + } + + optionindex = mpweaponnum; + } + + data->list.unk04 = g_MpWeaponSetRandomFilters[optionindex]; + } + } + break; + } + + return 0; +} + +struct menuitem g_MpSelectRandomWeaponsMenuItems[] = { + { + MENUITEMTYPE_LIST, + 0, + MENUITEMFLAG_LOCKABLEMINOR, + 0x00000078, + 0x0000004d, + mpSelectRandomWeaponListHandler, + }, + { MENUITEMTYPE_END }, +}; + +struct menudialogdef g_MpSelectRandomWeaponsMenuDialog = { + MENUDIALOGTYPE_DEFAULT, + (uintptr_t)"Select Weapons", + g_MpSelectRandomWeaponsMenuItems, + NULL, + MENUDIALOGFLAG_LITERAL_TEXT, + NULL, +}; + +MenuItemHandlerResult menuhandlerMpSelectRandomWeapons(s32 operation, struct menuitem *item, union handlerdata *data) +{ + switch (operation) { + case MENUOP_CHECKDISABLED: + case MENUOP_CHECKHIDDEN: + if (g_MpWeaponSetNum == WEAPONSET_RANDOM + || g_MpWeaponSetNum == WEAPONSET_RANDOMFIVE) { + return false; + } + return true; + case MENUOP_SET: + menuPushDialog(&g_MpSelectRandomWeaponsMenuDialog); + } + + return 0; +} + MenuItemHandlerResult menuhandlerMpAutoRandomWeapon(s32 operation, struct menuitem *item, union handlerdata *data) { static const char *labels[] = { @@ -1220,6 +1371,14 @@ struct menuitem g_MpWeaponsMenuItems[] = { menuhandlerMpWeaponSetDropdown, }, #ifndef PLATFORM_N64 + { + MENUITEMTYPE_SELECTABLE, + 0, + MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"Select Weapons\n", + 0, + menuhandlerMpSelectRandomWeapons, + }, { MENUITEMTYPE_DROPDOWN, 0, diff --git a/src/include/data.h b/src/include/data.h index 07086603f..d1bf537ca 100644 --- a/src/include/data.h +++ b/src/include/data.h @@ -556,6 +556,9 @@ extern s32 g_MusicDisableMpDeath; extern s32 g_BgunGeMuzzleFlashes; extern s32 g_FileAutoSelect; +extern u8 g_MpWeaponSetRandomFilters[NUM_MPWEAPONS]; +extern s32 g_MpWeaponRandomFilterNum; + #define PLAYER_EXTCFG() g_PlayerExtCfg[g_Vars.currentplayerstats->mpindex & 3] #define PLAYER_DEFAULT_FOV (PLAYER_EXTCFG().fovy) diff --git a/src/include/game/mplayer/mplayer.h b/src/include/game/mplayer/mplayer.h index b2ab42f95..3d2591ca7 100644 --- a/src/include/game/mplayer/mplayer.h +++ b/src/include/game/mplayer/mplayer.h @@ -34,6 +34,9 @@ s32 func0f189058(bool full); s32 func0f189088(void); char *mpGetWeaponSetName(s32 arg0); void func0f18913c(void); +#ifndef PLATFORM_N64 +void mpSetRandomWeapons(u8 weapons[]); +#endif void mpApplyWeaponSet(void); void mpSetWeaponSet(s32 weaponsetnum); void func0f1895e8(void);