#include "global.h" #include "battle_party_menu.h" #include "battle.h" #include "item_menu.h" #include "item_use.h" #include "main.h" #include "menu.h" #include "menu_helpers.h" #include "palette.h" #include "party_menu.h" #include "pokemon.h" #include "pokemon_summary_screen.h" #include "rom_8077ABC.h" #include "rom_8094928.h" #include "constants/songs.h" #include "sound.h" #include "string_util.h" #include "strings.h" #include "task.h" #include "text.h" #include "ewram.h" EWRAM_DATA u8 gBattlePartyCurrentOrder[3] = {}; EWRAM_DATA u8 gUnknown_02038473 = 0; extern u8 sub_806BD58(u8, u8); extern void PartyMenuPrintMonsLevelOrStatus(void); extern void nullsub_13(void); extern void sub_802E414(void); extern void sub_80A6DCC(void); extern u8 *sub_8040D08(); extern void SetMonPreventsSwitchingString(void); extern void nullsub_14(); extern u8 sub_803FBBC(void); extern u8 gPlayerPartyCount; extern u8 gBattlersCount; extern u16 gBattlerPartyIndexes[]; extern u8 gBankInMenu; extern u8 gUnknown_0202E8F4; extern u8 gUnknown_0202E8F5; extern u8 gPartyMenuMessage_IsPrinting; extern u8 gUnknown_020384F0; extern void (*gPokemonItemUseCallback)(); //don't know types yet extern struct PokemonStorage gPokemonStorage; extern void nullsub_14(); void sub_8094C98(u8, u8); u8 pokemon_order_func(u8); static void sub_8094998(u8[3], u8); static void sub_8094A74(u8[3], u8, u32); static void sub_8094D60(void); static void Task_809527C(u8); static void Task_80952B4(u8); static void Task_80952E4(u8); static void Task_8095330(u8); static void Task_809538C(void); static void Task_HandlePopupMenuInput(u8); static void Task_BattlePartyMenuSummary(u8 taskId); static void Task_BattlePartyMenuShift(u8 taskId); static void Task_BattlePartyMenuCancel(u8 taskId); static const struct MenuAction2 sBattlePartyMenuActions[] = { {OtherText_Summary, Task_BattlePartyMenuSummary}, {gOtherText_CancelNoTerminator, Task_BattlePartyMenuCancel}, {OtherText_Shift, Task_BattlePartyMenuShift}, {OtherText_SendOut, Task_BattlePartyMenuShift}, }; static const u8 Unknown_83B5FEC[] = {2, 0, 1}; //SHIFT, SUMMARY, CANCEL static const u8 Unknown_83B5FEF[] = {3, 0, 1}; //SEND OUT, SUMMARY, CANCEL static const u8 Unknown_83B5FF2[] = {0, 1}; //SUMMARY, CANCEL static const struct PartyPopupMenu sBattlePartyPopupMenus[] = { {ARRAY_COUNT(Unknown_83B5FEC), 9, Unknown_83B5FEC}, {ARRAY_COUNT(Unknown_83B5FEF), 9, Unknown_83B5FEF}, {ARRAY_COUNT(Unknown_83B5FF2), 9, Unknown_83B5FF2}, }; void unref_sub_8094928(struct PokemonStorage *ptr) { *ptr = gPokemonStorage; } void unref_sub_8094940(struct PokemonStorage *ptr) { gPokemonStorage = *ptr; } void sub_8094958(void) { sub_8094998(gBattlePartyCurrentOrder, sub_803FBBC()); } void sub_8094978(u8 arg1, u8 arg2) { sub_8094A74(gBattleStruct->unk1606C[arg1], arg2, arg1); } static void sub_8094998(u8 arg[3], u8 player_number) { int i; u32 pos; u8 temp[6]; if (IsLinkDoubleBattle() == TRUE) { if (player_number) { *arg = 0x30; arg[1] = 0x45; arg[2] = 0x12; } else { *arg = 0x03; arg[1] = 0x12; arg[2] = 0x45; } } else { if (!IsDoubleBattle()) { pos = 1; *temp = gBattlerPartyIndexes[GetBattlerAtPosition(0)]; for (i = 0; i <= 5; i++) if (i != *temp) temp[pos++] = i; } else { pos = 2; *temp = gBattlerPartyIndexes[GetBattlerAtPosition(0)]; temp[1] = gBattlerPartyIndexes[GetBattlerAtPosition(2)]; for (i = 0; i <= 5; i++) if ((i != *temp) && (i != temp[1])) temp[pos++] = i; } for (i = 0; i <= 2; i++) arg[i] = (temp[i << 1] << 4) | temp[(i << 1) + 1]; } } static void sub_8094A74(u8 arg[3], u8 player_number, u32 arg3) { int i, j; u8 temp[6]; if (!GetBattlerSide(arg3)) { i = GetBattlerAtPosition(0); j = GetBattlerAtPosition(2); } else { i = GetBattlerAtPosition(1); j = GetBattlerAtPosition(3); } if (IsLinkDoubleBattle() == TRUE) { if (player_number) { *arg = 0x30; arg[1] = 0x45; arg[2] = 0x12; } else { *arg = 0x03; arg[1] = 0x12; arg[2] = 0x45; } } else { if (!IsDoubleBattle()) { int pos = 1; *temp = gBattlerPartyIndexes[i]; for (i = 0; i <= 5; i++) if (i != *temp) temp[pos++] = i; } else { int pos = 2; *temp = gBattlerPartyIndexes[i]; temp[1] = gBattlerPartyIndexes[j]; for (i = 0; i <= 5; i++) if ((i != *temp) && (i != temp[1])) temp[pos++] = i; } for (i = 0; i <= 2; i++) arg[i] = (temp[i << 1] << 4) | temp[(i << 1) + 1]; } } void sub_8094B6C(u8 a, u8 b, u8 c) { s32 i; s32 j; u8 temp[6]; u8 r3; u8 r7 = 0; if (IsLinkDoubleBattle()) { u8 *arr = gBattleStruct->unk1606C[a]; for (i = 0, j = 0; i < 3; i++) { temp[j++] = arr[i] >> 4; temp[j++] = arr[i] & 0xF; } r3 = temp[c]; for (i = 0; i < 6; i++) { if (temp[i] == b) { r7 = temp[i]; temp[i] = r3; break; } } if (i != 6) { temp[c] = r7; arr[0] = (temp[0] << 4) | temp[1]; arr[1] = (temp[2] << 4) | temp[3]; arr[2] = (temp[4] << 4) | temp[5]; } } } u8 sub_8094C20(u8 monIndex) { u8 retVal; u8 val = monIndex & 1; monIndex /= 2; if (val) retVal = gBattlePartyCurrentOrder[monIndex] & 0xF; else retVal = gBattlePartyCurrentOrder[monIndex] >> 4; return retVal; } void sub_8094C54(u8 a, u8 b) { u8 val = a & 1; a /= 2; if (val) gBattlePartyCurrentOrder[a] = (gBattlePartyCurrentOrder[a] & 0xF0) | b; else gBattlePartyCurrentOrder[a] = (gBattlePartyCurrentOrder[a] & 0xF) | (b << 4); } void sub_8094C98(u8 a, u8 b) { u8 r4 = sub_8094C20(a); u8 r1 = sub_8094C20(b); sub_8094C54(a, r1); sub_8094C54(b, r4); } u8 pokemon_order_func(u8 a) { u8 i; u8 r2; for (i = 0, r2 = 0; i < 3; i++) { if ((gBattlePartyCurrentOrder[i] >> 4) == a) return r2; r2++; if ((gBattlePartyCurrentOrder[i] & 0xF) == a) return r2; r2++; } return 0; } void pokemon_change_order(void) { u8 i; memcpy(ePartyMenu2.unk0, gPlayerParty, sizeof(gPlayerParty)); for (i = 0; i < 6; i++) { u8 n = pokemon_order_func(i); memcpy(&gPlayerParty[n], &ePartyMenu2.unk0[i], sizeof(struct Pokemon)); } } static void sub_8094D60(void) { struct Pokemon temp[6]; u8 i; memcpy(temp, gPlayerParty, sizeof(gPlayerParty)); for (i = 0; i < 6; i++) { u8 n = sub_8094C20(i); memcpy(&gPlayerParty[n], &temp[i], sizeof(struct Pokemon)); } } void unref_sub_8094DB0(void) { u8 i; u8 r4; for (i = 1; i < 6; i++) { u8 n = sub_8094C20(i); if (GetMonData(&gPlayerParty[n], MON_DATA_SPECIES) != 0 && GetMonData(&gPlayerParty[n], MON_DATA_HP) != 0) { r4 = sub_8094C20(0); sub_8094C98(0, i); SwapPokemon(&gPlayerParty[r4], &gPlayerParty[n]); break; } } } void sub_8094E20(u8 a) { gPaletteFade.bufferTransferDisabled = TRUE; gUnknown_02038473 = a; nullsub_14(); pokemon_change_order(); OpenPartyMenu(PARTY_MENU_TYPE_BATTLE, 0xFF); } void sub_8094E4C(void) { sub_8094E20(3); } bool8 SetUpBattlePartyMenu(void) { switch (ePartyMenu2.pmSetupState) //switch (ePartyMenu2.unk264[0]) { case 0: //TODO: try to get rid of this duplicate code if (IsLinkDoubleBattle() == TRUE) { if (ePartyMenu2.pmMonIndex != 6) { TryCreatePartyMenuMonIcon(ePartyMenu2.menuHandlerTaskId, ePartyMenu2.pmMonIndex, &gPlayerParty[ePartyMenu2.pmMonIndex]); ePartyMenu2.pmMonIndex++; } else { ePartyMenu2.pmMonIndex = 0; ePartyMenu2.pmSetupState++; } } else { if (ePartyMenu2.pmMonIndex < 6) { TryCreatePartyMenuMonIcon(ePartyMenu2.menuHandlerTaskId, ePartyMenu2.pmMonIndex, &gPlayerParty[ePartyMenu2.pmMonIndex]); ePartyMenu2.pmMonIndex++; } else { ePartyMenu2.pmMonIndex = 0; ePartyMenu2.pmSetupState++; } } break; case 1: LoadHeldItemIconGraphics(); ePartyMenu2.pmSetupState++; break; case 2: CreateHeldItemIcons_806DC34(ePartyMenu2.menuHandlerTaskId); ePartyMenu2.pmSetupState++; break; case 3: if (sub_806BD58(ePartyMenu2.menuHandlerTaskId, ePartyMenu2.pmMonIndex) == 1) { ePartyMenu2.pmMonIndex = 0; ePartyMenu2.pmSetupState++; } else ePartyMenu2.pmMonIndex++; break; case 4: PartyMenuPrintMonsLevelOrStatus(); ePartyMenu2.pmSetupState++; break; case 5: PrintPartyMenuMonNicknames(); ePartyMenu2.pmSetupState++; break; case 6: PartyMenuTryPrintMonsHP(); ePartyMenu2.pmSetupState++; break; case 7: nullsub_13(); ePartyMenu2.pmSetupState++; break; case 8: PartyMenuDrawHPBars(); ePartyMenu2.pmSetupState++; break; case 9: if (DrawPartyMonBackground(ePartyMenu2.pmMonIndex) == 1) { ePartyMenu2.pmMonIndex = 0; ePartyMenu2.pmSetupState++; } else ePartyMenu2.pmMonIndex++; break; case 10: if (gUnknown_02038473 == 3) { if (GetItemEffectType(gSpecialVar_ItemId) == 10) ePartyMenu2.promptTextId = 0xFF; else ePartyMenu2.promptTextId = 3; } return TRUE; } return FALSE; } static void sub_8095050(u8 a, u8 b) { if (!GetMonData(&gPlayerParty[b], MON_DATA_IS_EGG)) { if (gUnknown_02038473 == 1) { gTasks[ePartyMenu2.menuHandlerTaskId].data[4] = 1; gTasks[ePartyMenu2.menuHandlerTaskId].data[5] = 1; } else { gTasks[ePartyMenu2.menuHandlerTaskId].data[4] = 0; gTasks[ePartyMenu2.menuHandlerTaskId].data[5] = 0; } } else { gTasks[ePartyMenu2.menuHandlerTaskId].data[4] = 2; gTasks[ePartyMenu2.menuHandlerTaskId].data[5] = 2; } ShowPartyPopupMenu(gTasks[a].data[4], sBattlePartyPopupMenus, sBattlePartyMenuActions, 0); } void HandleBattlePartyMenu(u8 taskId) { if (!gPaletteFade.active) { if (gUnknown_02038473 == 3 && GetItemEffectType(gSpecialVar_ItemId) == 10) { gPokemonItemUseCallback(taskId, gSpecialVar_ItemId, Task_80952E4); return; } switch (HandleDefaultPartyMenuInput(taskId)) { case A_BUTTON: if (gUnknown_02038473 == 3) { if (GetMonData(&gPlayerParty[sub_806CA38(taskId)], MON_DATA_IS_EGG)) PlaySE(SE_FAILURE); else { PartyMenuEraseMsgBoxAndFrame(); gPokemonItemUseCallback(taskId, gSpecialVar_ItemId, Task_80952E4); } } else { PlaySE(SE_SELECT); GetMonNickname(&gPlayerParty[sub_806CA38(taskId)], gStringVar1); sub_8095050(taskId, sub_806CA38(taskId)); SetTaskFuncWithFollowupFunc(taskId, Task_HandlePopupMenuInput, HandleBattlePartyMenu); } break; case B_BUTTON: if (gUnknown_02038473 == 1) PlaySE(SE_FAILURE); else { PlaySE(SE_SELECT); if (gUnknown_02038473 == 3) { gUnknown_0202E8F4 = 0; gTasks[taskId].func = Task_80952E4; } else { gUnknown_0202E8F4 = 0; gTasks[taskId].func = Task_809527C; } } break; } } } static void Task_809527C(u8 taskId) { BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); gTasks[taskId].func = Task_80952B4; } static void Task_80952B4(u8 taskId) { if (!gPaletteFade.active) { sub_8094D60(); DestroyTask(taskId); SetMainCallback2(sub_802E414); } } static void Task_80952E4(u8 taskId) { if (gUnknown_0202E8F4 != 0) Task_809527C(taskId); else { BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); gTasks[taskId].func = Task_8095330; } } static void Task_8095330(u8 taskId) { if (!gPaletteFade.active) { sub_8094D60(); DestroyTask(taskId); sub_80A6DCC(); } } static void Task_809535C(void) { gPaletteFade.bufferTransferDisabled = TRUE; SetPartyMenuSettings(PARTY_MENU_TYPE_BATTLE, 0xFF, HandleBattlePartyMenu, 5); SetMainCallback2(Task_809538C); } static void Task_809538C(void) { do { if (InitPartyMenu() == TRUE) { sub_806C994(ePartyMenu2.menuHandlerTaskId, gUnknown_020384F0); ChangePartyMenuSelection(ePartyMenu2.menuHandlerTaskId, 0); GetMonNickname(&gPlayerParty[gUnknown_020384F0], gStringVar1); sub_8095050(ePartyMenu2.menuHandlerTaskId, gUnknown_020384F0); SetTaskFuncWithFollowupFunc( ePartyMenu2.menuHandlerTaskId, Task_HandlePopupMenuInput, HandleBattlePartyMenu); SetMainCallback2(CB2_PartyMenuMain); return; } } while (sub_80F9344() != 1); } static void Task_HandlePopupMenuInput(u8 taskId) { TaskFunc func; if (!gPaletteFade.active) { if (gMain.newAndRepeatedKeys & DPAD_UP) { PlaySE(SE_SELECT); Menu_MoveCursor(-1); return; } if (gMain.newAndRepeatedKeys & DPAD_DOWN) { PlaySE(SE_SELECT); Menu_MoveCursor(1); return; } if (gMain.newKeys & A_BUTTON) { PlaySE(SE_SELECT); func = PartyMenuGetPopupMenuFunc(gTasks[taskId].data[4], sBattlePartyPopupMenus, sBattlePartyMenuActions, Menu_GetCursorPos()); func(taskId); return; } if (gMain.newKeys & B_BUTTON) { PlaySE(SE_SELECT); Task_BattlePartyMenuCancel(taskId); return; } } } static void Task_80954C0(u8 taskId) { if (gPartyMenuMessage_IsPrinting == 0) Task_BattlePartyMenuCancel(taskId); } static void Task_ShowSummaryScreen(u8 taskId) { u8 partySelection = sub_806CA38(taskId); if (!gPaletteFade.active) { DestroyTask(taskId); ePartyMenu2.unk262 = 1; ShowPokemonSummaryScreen(gPlayerParty, partySelection, gPlayerPartyCount - 1, Task_809535C, PSS_MODE_NO_MOVE_ORDER_EDIT); } } static void Task_BattlePartyMenuSummary(u8 taskId) { sub_806CA38(taskId); //an unused variable was probably set with this. gTasks[taskId].func = Task_ShowSummaryScreen; BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); } static void Task_BattlePartyMenuShift(u8 taskId) { u8 partySelection; u8 i; u8 r4; ClosePartyPopupMenu(gTasks[taskId].data[4], sBattlePartyPopupMenus); partySelection = sub_806CA38(taskId); if (IsLinkDoubleBattle() == TRUE && (partySelection == 1 || partySelection == 4 || partySelection == 5)) { PartyMenuEraseMsgBoxAndFrame(); StringCopy(gStringVar1, sub_8040D08()); StringExpandPlaceholders(gStringVar4, gOtherText_CantSwitchPokeWithYours); DisplayPartyMenuMessage(gStringVar4, 0); gTasks[taskId].func = Task_80954C0; return; } if (GetMonData(&gPlayerParty[partySelection], MON_DATA_HP) == 0) { PartyMenuEraseMsgBoxAndFrame(); GetMonNickname(&gPlayerParty[partySelection], gStringVar1); StringExpandPlaceholders(gStringVar4, gOtherText_NoEnergyLeft); DisplayPartyMenuMessage(gStringVar4, 0); gTasks[taskId].func = Task_80954C0; return; } for (i = 0; i < gBattlersCount; i++) { if (GetBattlerSide(i) == 0 && sub_8094C20(partySelection) == gBattlerPartyIndexes[i]) { PartyMenuEraseMsgBoxAndFrame(); GetMonNickname(&gPlayerParty[partySelection], gStringVar1); StringExpandPlaceholders(gStringVar4, gOtherText_AlreadyBattle); DisplayPartyMenuMessage(gStringVar4, 0); gTasks[taskId].func = Task_80954C0; return; } } if (GetMonData(&gPlayerParty[partySelection], MON_DATA_IS_EGG)) { PartyMenuEraseMsgBoxAndFrame(); StringExpandPlaceholders(gStringVar4, gOtherText_EGGCantBattle); DisplayPartyMenuMessage(gStringVar4, 0); gTasks[taskId].func = Task_80954C0; return; } if (sub_8094C20(partySelection) == gBattleStruct->unk1609D) { PartyMenuEraseMsgBoxAndFrame(); GetMonNickname(&gPlayerParty[partySelection], gStringVar1); StringExpandPlaceholders(gStringVar4, gOtherText_AlreadySelected); DisplayPartyMenuMessage(gStringVar4, 0); gTasks[taskId].func = Task_80954C0; return; } if (gUnknown_02038473 == 4) { PartyMenuEraseMsgBoxAndFrame(); SetMonPreventsSwitchingString(); DisplayPartyMenuMessage(gStringVar4, 0); gTasks[taskId].func = Task_80954C0; return; } if (gUnknown_02038473 == 2) { u8 r0; u8 r4 = gBankInMenu; PartyMenuEraseMsgBoxAndFrame(); r0 = pokemon_order_func(gBattlerPartyIndexes[r4]); GetMonNickname(&gPlayerParty[r0], gStringVar1); StringExpandPlaceholders(gStringVar4, gOtherText_CantBeSwitched); DisplayPartyMenuMessage(gStringVar4, 0); gTasks[taskId].func = Task_80954C0; return; } gUnknown_0202E8F5 = sub_8094C20(partySelection); gUnknown_0202E8F4 = 1; r4 = pokemon_order_func(gBattlerPartyIndexes[gBankInMenu]); sub_8094C98(r4, partySelection); SwapPokemon(&gPlayerParty[r4], &gPlayerParty[partySelection]); gTasks[taskId].func = Task_809527C; } static void Task_BattlePartyMenuCancel(u8 taskId) { Menu_DestroyCursor(); ClosePartyPopupMenu(gTasks[taskId].data[4], sBattlePartyPopupMenus); gTasks[taskId].data[4] = gTasks[taskId].data[5]; PrintPartyMenuPromptText(0, 0); SwitchTaskToFollowupFunc(taskId); }