From 85197eda5eb21ecff463f77b68a1fd7263ae8d89 Mon Sep 17 00:00:00 2001 From: RavePossum <145081120+ravepossum@users.noreply.github.com> Date: Sat, 19 Oct 2024 08:43:05 -0400 Subject: [PATCH] Move Relearner and Renaming From Summary Screen (#5513) * implement move relearner in summary screen * implement renaming in summary screen * Enable summary screen rename and relearn by default * Store original callback when opening screen to invoke later, hide rename/relearn for mons being moved in PC * add a config to not restore full PP when relearning from summary screen * hide summary relearner option if mon has no relearnable moves * add note not to decap RELEARN string * re-static function that now no longer needs to be accessible elsewhere * Fix move relearner not showing up if you first select a mon with no moves * The great curly brace massacre of 2024 (PR feedback) * sprinkling in some parentheses * PR feedback 2 (curly braces & whitespace) --- include/config/pokemon.h | 3 + include/move_relearner.h | 3 + include/pokemon_summary_screen.h | 13 ++ include/strings.h | 3 + src/move_relearner.c | 45 ++++++- src/pokemon_storage_system.c | 2 +- src/pokemon_summary_screen.c | 216 +++++++++++++++++++++++++------ src/strings.c | 2 + 8 files changed, 240 insertions(+), 47 deletions(-) diff --git a/include/config/pokemon.h b/include/config/pokemon.h index 14271fe4e4..311e7c7fe9 100644 --- a/include/config/pokemon.h +++ b/include/config/pokemon.h @@ -58,6 +58,9 @@ #define P_ONLY_OBTAINABLE_SHINIES FALSE // If TRUE, Pokémon encountered in the Battle Pyramid won't be shiny. #define P_NO_SHINIES_WITHOUT_POKEBALLS FALSE // If TRUE, Pokémon encountered when the player is out of Poké Balls won't be shiny #define P_SHOW_DYNAMIC_TYPES FALSE // If TRUE, all moves with dynamic type changes will be reflected as their current type in battle/summary screens instead of just select ones like in vanilla. +#define P_SUMMARY_SCREEN_MOVE_RELEARNER TRUE // If TRUE, shows an option for Pokémon to relearn moves on the summary screen moves page. +#define P_SUMMARY_MOVE_RELEARNER_FULL_PP TRUE // If TRUE, the move relearner in the summary screen restores relearned moves' PP to full. +#define P_SUMMARY_SCREEN_RENAME TRUE // If TRUE, an option to change Pokémon nicknames replaces the cancel prompt on the summary screen info page. // Learnset helper toggles #define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/teachable.py using the included JSON files based on available TMs and tutors. diff --git a/include/move_relearner.h b/include/move_relearner.h index 903c80ac7a..c97b3894b1 100644 --- a/include/move_relearner.h +++ b/include/move_relearner.h @@ -4,5 +4,8 @@ void TeachMoveRelearnerMove(void); void MoveRelearnerShowHideHearts(s32); void MoveRelearnerShowHideCategoryIcon(s32); +void CB2_InitLearnMove(void); + +extern u8 gOriginSummaryScreenPage; #endif //GUARD_MOVE_RELEARNER_H diff --git a/include/pokemon_summary_screen.h b/include/pokemon_summary_screen.h index 924702baf9..fe299c48b4 100755 --- a/include/pokemon_summary_screen.h +++ b/include/pokemon_summary_screen.h @@ -11,6 +11,7 @@ extern const struct CompressedSpriteSheet gSpriteSheet_MoveTypes; extern const struct CompressedSpriteSheet gSpriteSheet_CategoryIcons; extern const struct SpritePalette gSpritePal_CategoryIcons; extern const struct SpriteTemplate gSpriteTemplate_CategoryIcons; +extern MainCallback gInitialSummaryScreenCallback; void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void)); void ShowSelectMovePokemonSummaryScreen(struct Pokemon *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void), u16 newMove); @@ -25,7 +26,19 @@ enum PokemonSummaryScreenMode SUMMARY_MODE_NORMAL, SUMMARY_MODE_LOCK_MOVES, SUMMARY_MODE_BOX, + SUMMARY_MODE_BOX_CURSOR, // mon is being moved in PC SUMMARY_MODE_SELECT_MOVE, + SUMMARY_MODE_RELEARNER_BATTLE, // returning from move relearner initiated from battle moves page + SUMMARY_MODE_RELEARNER_CONTEST, // returning from move relearner initiated from contest moves page +}; + +enum PokemonSummaryScreenPage +{ + PSS_PAGE_INFO, + PSS_PAGE_SKILLS, + PSS_PAGE_BATTLE_MOVES, + PSS_PAGE_CONTEST_MOVES, + PSS_PAGE_COUNT, }; #endif // GUARD_POKEMON_SUMMARY_SCREEN_H diff --git a/include/strings.h b/include/strings.h index b1078bed0a..45bbeb9707 100644 --- a/include/strings.h +++ b/include/strings.h @@ -2708,4 +2708,7 @@ extern const u8 gText_PM[]; extern const u8 gText_PlayerScurriedToCenter[]; extern const u8 gText_PlayerScurriedBackHome[]; +extern const u8 gText_Relearn[]; // move relearner from summary screen +extern const u8 gText_Rename[]; // change nickname from summary screen + #endif // GUARD_STRINGS_H diff --git a/src/move_relearner.c b/src/move_relearner.c index 817dbd16e0..a4cc778a45 100644 --- a/src/move_relearner.c +++ b/src/move_relearner.c @@ -17,6 +17,7 @@ #include "menu_specialized.h" #include "overworld.h" #include "palette.h" +#include "party_menu.h" #include "pokemon_summary_screen.h" #include "script.h" #include "sound.h" @@ -184,6 +185,8 @@ static EWRAM_DATA struct { bool8 showContestInfo; } sMoveRelearnerMenuSate = {0}; +EWRAM_DATA u8 gOriginSummaryScreenPage = 0; // indicates summary screen page that the move relearner was opened from (if opened from PSS) + static const u16 sUI_Pal[] = INCBIN_U16("graphics/interface/ui_learn_move.gbapal"); // The arrow sprites in this spritesheet aren't used. The scroll-arrow system provides its own @@ -354,7 +357,6 @@ static void CreateLearnableMovesList(void); static void CreateUISprites(void); static void CB2_MoveRelearnerMain(void); static void Task_WaitForFadeOut(u8 taskId); -static void CB2_InitLearnMove(void); static void CB2_InitLearnMoveReturnFromSelectMove(void); static void InitMoveRelearnerBackgroundLayers(void); static void AddScrollArrows(void); @@ -391,7 +393,7 @@ static void Task_WaitForFadeOut(u8 taskId) } } -static void CB2_InitLearnMove(void) +void CB2_InitLearnMove(void) { ResetSpriteData(); FreeAllSpritePalettes(); @@ -402,11 +404,11 @@ static void CB2_InitLearnMove(void) SetVBlankCallback(VBlankCB_MoveRelearner); InitMoveRelearnerBackgroundLayers(); - InitMoveRelearnerWindows(FALSE); + InitMoveRelearnerWindows(gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES); sMoveRelearnerMenuSate.listOffset = 0; sMoveRelearnerMenuSate.listRow = 0; - sMoveRelearnerMenuSate.showContestInfo = FALSE; + sMoveRelearnerMenuSate.showContestInfo = gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES; CreateLearnableMovesList(); @@ -482,12 +484,17 @@ static void DoMoveRelearnerMain(void) case MENU_STATE_FADE_TO_BLACK: sMoveRelearnerStruct->state++; HideHeartSpritesAndShowTeachMoveText(FALSE); + if (gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES) + MoveRelearnerShowHideHearts(GetCurrentSelectedMove()); BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); break; case MENU_STATE_WAIT_FOR_FADE: if (!gPaletteFade.active) { - sMoveRelearnerStruct->state = MENU_STATE_IDLE_BATTLE_MODE; + if (gOriginSummaryScreenPage == PSS_PAGE_CONTEST_MOVES) + sMoveRelearnerStruct->state = MENU_STATE_IDLE_CONTEST_MODE; + else + sMoveRelearnerStruct->state = MENU_STATE_IDLE_BATTLE_MODE; } break; case MENU_STATE_UNREACHABLE: @@ -681,8 +688,28 @@ static void DoMoveRelearnerMain(void) case MENU_STATE_RETURN_TO_FIELD: if (!gPaletteFade.active) { + if (gInitialSummaryScreenCallback != NULL) + { + switch (gOriginSummaryScreenPage) + { + case PSS_PAGE_BATTLE_MOVES: + ShowPokemonSummaryScreen(SUMMARY_MODE_RELEARNER_BATTLE, gPlayerParty, sMoveRelearnerStruct->partyMon, gPlayerPartyCount - 1, gInitialSummaryScreenCallback); + break; + case PSS_PAGE_CONTEST_MOVES: + ShowPokemonSummaryScreen(SUMMARY_MODE_RELEARNER_CONTEST, gPlayerParty, sMoveRelearnerStruct->partyMon, gPlayerPartyCount - 1, gInitialSummaryScreenCallback); + break; + default: + ShowPokemonSummaryScreen(SUMMARY_MODE_NORMAL, gPlayerParty, sMoveRelearnerStruct->partyMon, gPlayerPartyCount - 1, gInitialSummaryScreenCallback); + break; + } + gOriginSummaryScreenPage = 0; + } + else + { + SetMainCallback2(CB2_ReturnToField); + } + FreeMoveRelearnerResources(); - SetMainCallback2(CB2_ReturnToField); } break; case MENU_STATE_FADE_FROM_SUMMARY_SCREEN: @@ -709,10 +736,14 @@ static void DoMoveRelearnerMain(void) else { u16 moveId = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_MOVE1 + sMoveRelearnerStruct->moveSlot); - + u8 originalPP = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); + StringCopy(gStringVar3, GetMoveName(moveId)); RemoveMonPPBonus(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->moveSlot); SetMonMoveSlot(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove(), sMoveRelearnerStruct->moveSlot); + u8 newPP = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot); + if (!P_SUMMARY_MOVE_RELEARNER_FULL_PP && gOriginSummaryScreenPage != 0 && originalPP < newPP) + SetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot, &originalPP); StringCopy(gStringVar2, GetMoveName(GetCurrentSelectedMove())); PrintMessageWithPlaceholders(gText_MoveRelearnerAndPoof); sMoveRelearnerStruct->state = MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE; diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c index 088b90fd6b..05ac5816da 100644 --- a/src/pokemon_storage_system.c +++ b/src/pokemon_storage_system.c @@ -6798,7 +6798,7 @@ static void InitSummaryScreenData(void) sStorage->summaryMon.mon = &sSavedMovingMon; sStorage->summaryStartPos = 0; sStorage->summaryMaxPos = 0; - sStorage->summaryScreenMode = SUMMARY_MODE_NORMAL; + sStorage->summaryScreenMode = SUMMARY_MODE_BOX_CURSOR; } else if (sCursorArea == CURSOR_AREA_IN_PARTY) { diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 06efd2ee42..d20e3299d2 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -24,6 +24,8 @@ #include "menu.h" #include "menu_helpers.h" #include "mon_markings.h" +#include "move_relearner.h" +#include "naming_screen.h" #include "party_menu.h" #include "palette.h" #include "pokeball.h" @@ -50,14 +52,6 @@ #include "constants/rgb.h" #include "constants/songs.h" -enum { - PSS_PAGE_INFO, - PSS_PAGE_SKILLS, - PSS_PAGE_BATTLE_MOVES, - PSS_PAGE_CONTEST_MOVES, - PSS_PAGE_COUNT, -}; - // Screen titles (upper left) #define PSS_LABEL_WINDOW_POKEMON_INFO_TITLE 0 #define PSS_LABEL_WINDOW_POKEMON_SKILLS_TITLE 1 @@ -65,7 +59,7 @@ enum { #define PSS_LABEL_WINDOW_CONTEST_MOVES_TITLE 3 // Button control text (upper right) -#define PSS_LABEL_WINDOW_PROMPT_CANCEL 4 +#define PSS_LABEL_WINDOW_PROMPT_CANCEL 4 // Also handles the "rename" prompt if P_SUMMARY_SCREEN_RENAME is true #define PSS_LABEL_WINDOW_PROMPT_INFO 5 #define PSS_LABEL_WINDOW_PROMPT_SWITCH 6 #define PSS_LABEL_WINDOW_UNUSED1 7 @@ -83,7 +77,7 @@ enum { // Moves screen #define PSS_LABEL_WINDOW_MOVES_POWER_ACC 14 // Also contains the power and accuracy values #define PSS_LABEL_WINDOW_MOVES_APPEAL_JAM 15 -#define PSS_LABEL_WINDOW_UNUSED2 16 +#define PSS_LABEL_WINDOW_PROMPT_RELEARN 16 // Above/below the pokemon's portrait (left) #define PSS_LABEL_WINDOW_PORTRAIT_DEX_NUMBER 17 @@ -187,7 +181,7 @@ static EWRAM_DATA struct PokemonSummaryScreenData u8 secondMoveIndex; bool8 lockMovesFlag; // This is used to prevent the player from changing position of moves in a battle or when trading. u8 bgDisplayOrder; // Determines the order page backgrounds are loaded while scrolling between them - u8 filler40CA; + u8 relearnableMovesNum; u8 windowIds[8]; u8 spriteIds[SPRITE_ARR_ID_COUNT]; bool8 handleDeoxys; @@ -199,6 +193,7 @@ static EWRAM_DATA struct PokemonSummaryScreenData EWRAM_DATA u8 gLastViewedMonIndex = 0; static EWRAM_DATA u8 sMoveSlotToReplace = 0; ALIGNED(4) static EWRAM_DATA u8 sAnimDelayTaskId = 0; +EWRAM_DATA MainCallback gInitialSummaryScreenCallback = NULL; // stores callback from the first time the screen is opened from the party or PC menu // forward declarations static bool8 LoadGraphics(void); @@ -320,6 +315,11 @@ static void DestroyMoveSelectorSprites(u8); static void SetMainMoveSelectorColor(u8); static void KeepMoveSelectorVisible(u8); static void SummaryScreen_DestroyAnimDelayTask(void); +static bool32 ShouldShowMoveRelearner(void); +static bool32 ShouldShowRename(void); +static void ShowCancelOrRenamePrompt(void); +static void CB2_ReturnToSummaryScreenFromNamingScreen(void); +static void CB2_PssChangePokemonNickname(void); static const struct BgTemplate sBgTemplates[] = { @@ -535,13 +535,13 @@ static const struct WindowTemplate sSummaryTemplate[] = .paletteNum = 6, .baseBlock = 367, }, - [PSS_LABEL_WINDOW_UNUSED2] = { + [PSS_LABEL_WINDOW_PROMPT_RELEARN] = { .bg = 0, .tilemapLeft = 22, - .tilemapTop = 4, - .width = 0, + .tilemapTop = 2, + .width = 8, .height = 2, - .paletteNum = 6, + .paletteNum = 15, .baseBlock = 387, }, [PSS_LABEL_WINDOW_PORTRAIT_DEX_NUMBER] = { @@ -551,7 +551,7 @@ static const struct WindowTemplate sSummaryTemplate[] = .width = 5, .height = 2, .paletteNum = 7, - .baseBlock = 387, + .baseBlock = 403, }, [PSS_LABEL_WINDOW_PORTRAIT_NICKNAME] = { .bg = 0, @@ -560,7 +560,7 @@ static const struct WindowTemplate sSummaryTemplate[] = .width = 9, .height = 2, .paletteNum = 6, - .baseBlock = 397, + .baseBlock = 413, }, [PSS_LABEL_WINDOW_PORTRAIT_SPECIES] = { .bg = 0, @@ -569,7 +569,7 @@ static const struct WindowTemplate sSummaryTemplate[] = .width = 9, .height = 4, .paletteNum = 6, - .baseBlock = 415, + .baseBlock = 431, }, [PSS_LABEL_WINDOW_END] = DUMMY_WIN_TEMPLATE }; @@ -582,7 +582,7 @@ static const struct WindowTemplate sPageInfoTemplate[] = .width = 11, .height = 2, .paletteNum = 6, - .baseBlock = 451, + .baseBlock = 467, }, [PSS_DATA_WINDOW_INFO_ID] = { .bg = 0, @@ -591,7 +591,7 @@ static const struct WindowTemplate sPageInfoTemplate[] = .width = 7, .height = 2, .paletteNum = 6, - .baseBlock = 473, + .baseBlock = 489, }, [PSS_DATA_WINDOW_INFO_ABILITY] = { .bg = 0, @@ -600,7 +600,7 @@ static const struct WindowTemplate sPageInfoTemplate[] = .width = 18, .height = 4, .paletteNum = 6, - .baseBlock = 487, + .baseBlock = 503, }, [PSS_DATA_WINDOW_INFO_MEMO] = { .bg = 0, @@ -609,7 +609,7 @@ static const struct WindowTemplate sPageInfoTemplate[] = .width = 18, .height = 6, .paletteNum = 6, - .baseBlock = 559, + .baseBlock = 575, }, }; static const struct WindowTemplate sPageSkillsTemplate[] = @@ -621,7 +621,7 @@ static const struct WindowTemplate sPageSkillsTemplate[] = .width = 10, .height = 2, .paletteNum = 6, - .baseBlock = 451, + .baseBlock = 467, }, [PSS_DATA_WINDOW_SKILLS_RIBBON_COUNT] = { .bg = 0, @@ -630,7 +630,7 @@ static const struct WindowTemplate sPageSkillsTemplate[] = .width = 10, .height = 2, .paletteNum = 6, - .baseBlock = 471, + .baseBlock = 487, }, [PSS_DATA_WINDOW_SKILLS_STATS_LEFT] = { .bg = 0, @@ -639,7 +639,7 @@ static const struct WindowTemplate sPageSkillsTemplate[] = .width = 6, .height = 6, .paletteNum = 6, - .baseBlock = 491, + .baseBlock = 507, }, [PSS_DATA_WINDOW_SKILLS_STATS_RIGHT] = { .bg = 0, @@ -648,7 +648,7 @@ static const struct WindowTemplate sPageSkillsTemplate[] = .width = 3, .height = 6, .paletteNum = 6, - .baseBlock = 527, + .baseBlock = 543, }, [PSS_DATA_WINDOW_EXP] = { .bg = 0, @@ -657,7 +657,7 @@ static const struct WindowTemplate sPageSkillsTemplate[] = .width = 6, .height = 4, .paletteNum = 6, - .baseBlock = 545, + .baseBlock = 561, }, }; static const struct WindowTemplate sPageMovesTemplate[] = // This is used for both battle and contest moves @@ -669,7 +669,7 @@ static const struct WindowTemplate sPageMovesTemplate[] = // This is used for bo .width = 9, .height = 10, .paletteNum = 6, - .baseBlock = 451, + .baseBlock = 467, }, [PSS_DATA_WINDOW_MOVE_PP] = { .bg = 0, @@ -678,7 +678,7 @@ static const struct WindowTemplate sPageMovesTemplate[] = // This is used for bo .width = 6, .height = 10, .paletteNum = 8, - .baseBlock = 541, + .baseBlock = 557, }, [PSS_DATA_WINDOW_MOVE_DESCRIPTION] = { .bg = 0, @@ -687,7 +687,7 @@ static const struct WindowTemplate sPageMovesTemplate[] = // This is used for bo .width = 20, .height = 4, .paletteNum = 6, - .baseBlock = 601, + .baseBlock = 617, }, }; static const u8 sTextColors[][3] = @@ -1166,6 +1166,8 @@ void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, sMonSummaryScreen->curMonIndex = monIndex; sMonSummaryScreen->maxMonIndex = maxMonIndex; sMonSummaryScreen->callback = callback; + if (gInitialSummaryScreenCallback == NULL) + gInitialSummaryScreenCallback = callback; if (mode == SUMMARY_MODE_BOX) sMonSummaryScreen->isBoxMon = TRUE; @@ -1176,6 +1178,9 @@ void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, { case SUMMARY_MODE_NORMAL: case SUMMARY_MODE_BOX: + case SUMMARY_MODE_BOX_CURSOR: + case SUMMARY_MODE_RELEARNER_BATTLE: + case SUMMARY_MODE_RELEARNER_CONTEST: sMonSummaryScreen->minPageIndex = 0; sMonSummaryScreen->maxPageIndex = PSS_PAGE_COUNT - 1; break; @@ -1191,7 +1196,13 @@ void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, break; } - sMonSummaryScreen->currPageIndex = sMonSummaryScreen->minPageIndex; + if (mode == SUMMARY_MODE_RELEARNER_BATTLE) + sMonSummaryScreen->currPageIndex = PSS_PAGE_BATTLE_MOVES; + else if (mode == SUMMARY_MODE_RELEARNER_CONTEST) + sMonSummaryScreen->currPageIndex = PSS_PAGE_CONTEST_MOVES; + else + sMonSummaryScreen->currPageIndex = sMonSummaryScreen->minPageIndex; + sMonSummaryScreen->categoryIconSpriteId = 0xFF; SummaryScreen_SetAnimDelayTaskId(TASK_NONE); @@ -1533,6 +1544,7 @@ static bool8 ExtractMonDataToSummaryStruct(struct Pokemon *mon) sum->ribbonCount = GetMonData(mon, MON_DATA_RIBBON_COUNT); sum->teraType = GetMonData(mon, MON_DATA_TERA_TYPE); sum->isShiny = GetMonData(mon, MON_DATA_IS_SHINY); + sMonSummaryScreen->relearnableMovesNum = P_SUMMARY_SCREEN_MOVE_RELEARNER ? GetNumberOfRelearnableMoves(mon) : 0; return TRUE; } sMonSummaryScreen->switchCounter++; @@ -1541,7 +1553,9 @@ static bool8 ExtractMonDataToSummaryStruct(struct Pokemon *mon) static void SetDefaultTilemaps(void) { - if (sMonSummaryScreen->currPageIndex != PSS_PAGE_BATTLE_MOVES && sMonSummaryScreen->currPageIndex != PSS_PAGE_CONTEST_MOVES) + if ((sMonSummaryScreen->currPageIndex != PSS_PAGE_BATTLE_MOVES && sMonSummaryScreen->currPageIndex != PSS_PAGE_CONTEST_MOVES) + || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_BATTLE + || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_CONTEST) { HandlePowerAccTilemap(0, 0xFF); HandleAppealJamTilemap(0, 0xFF, 0); @@ -1558,9 +1572,36 @@ static void SetDefaultTilemaps(void) ClearWindowTilemap(PSS_LABEL_WINDOW_POKEMON_SKILLS_STATUS); } + // these blocks handle preparing the gfx to return straight to the respective move info screens + if (sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_BATTLE) + { + SetBgTilemapBuffer(1, sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_SKILLS][0]); + SetBgTilemapBuffer(2, sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_BATTLE_MOVES][0]); + SetBgAttribute(1, BG_ATTR_PRIORITY, 2); + SetBgAttribute(2, BG_ATTR_PRIORITY, 1); + ChangeBgX(1, 0x10000, BG_COORD_ADD); + ChangeBgX(2, 0x10000, BG_COORD_ADD); + ShowBg(1); + ShowBg(2); + } + else if (sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_CONTEST) + { + sMonSummaryScreen->bgDisplayOrder = 1; + SetBgTilemapBuffer(1, sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_CONTEST_MOVES][0]); + SetBgTilemapBuffer(2, sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_BATTLE_MOVES][0]); + SetBgAttribute(1, BG_ATTR_PRIORITY, 1); + SetBgAttribute(2, BG_ATTR_PRIORITY, 2); + ChangeBgX(1, 0x10000, BG_COORD_ADD); + ChangeBgX(2, 0x10000, BG_COORD_ADD); + ShowBg(1); + ShowBg(2); + } + if (sMonSummaryScreen->summary.ailment == AILMENT_NONE) HandleStatusTilemap(0, 0xFF); - else if (sMonSummaryScreen->currPageIndex != PSS_PAGE_BATTLE_MOVES && sMonSummaryScreen->currPageIndex != PSS_PAGE_CONTEST_MOVES) + else if ((sMonSummaryScreen->currPageIndex != PSS_PAGE_BATTLE_MOVES && sMonSummaryScreen->currPageIndex != PSS_PAGE_CONTEST_MOVES) + || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_BATTLE + || sMonSummaryScreen->mode == SUMMARY_MODE_RELEARNER_CONTEST) PutWindowTilemap(PSS_LABEL_WINDOW_POKEMON_SKILLS_STATUS); LimitEggSummaryPageDisplay(); @@ -1583,6 +1624,8 @@ static void CloseSummaryScreen(u8 taskId) { if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE && !gPaletteFade.active) { + if (sMonSummaryScreen->callback == gInitialSummaryScreenCallback) + gInitialSummaryScreenCallback = NULL; SetMainCallback2(sMonSummaryScreen->callback); gLastViewedMonIndex = sMonSummaryScreen->curMonIndex; SummaryScreen_DestroyAnimDelayTask(); @@ -1623,6 +1666,12 @@ static void Task_HandleInput(u8 taskId) { if (sMonSummaryScreen->currPageIndex == PSS_PAGE_INFO) { + if (ShouldShowRename()) + { + sMonSummaryScreen->callback = CB2_PssChangePokemonNickname; + gSpecialVar_0x8004 = sMonSummaryScreen->curMonIndex; + } + StopPokemonAnimations(); PlaySE(SE_SELECT); BeginCloseSummaryScreen(taskId); @@ -1640,6 +1689,17 @@ static void Task_HandleInput(u8 taskId) PlaySE(SE_SELECT); BeginCloseSummaryScreen(taskId); } + else if (JOY_NEW(START_BUTTON) + && ShouldShowMoveRelearner() + && (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES || sMonSummaryScreen->currPageIndex == PSS_PAGE_CONTEST_MOVES)) + { + sMonSummaryScreen->callback = CB2_InitLearnMove; + gSpecialVar_0x8004 = sMonSummaryScreen->curMonIndex; + gOriginSummaryScreenPage = sMonSummaryScreen->currPageIndex; + StopPokemonAnimations(); + PlaySE(SE_SELECT); + BeginCloseSummaryScreen(taskId); + } else if (DEBUG_POKEMON_SPRITE_VISUALIZER && JOY_NEW(SELECT_BUTTON) && !gMain.inBattle) { sMonSummaryScreen->callback = CB2_Pokemon_Sprite_Visualizer; @@ -1722,7 +1782,20 @@ static void Task_ChangeSummaryMon(u8 taskId) break; case 4: if (ExtractMonDataToSummaryStruct(&sMonSummaryScreen->currentMon) == FALSE) + { return; + } + else + { + if (P_SUMMARY_SCREEN_MOVE_RELEARNER + && (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES || sMonSummaryScreen->currPageIndex == PSS_PAGE_CONTEST_MOVES)) + { + if (ShouldShowMoveRelearner()) + PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); + else + ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); + } + } break; case 5: RemoveAndCreateMonMarkingsSprite(&sMonSummaryScreen->currentMon); @@ -1753,6 +1826,12 @@ static void Task_ChangeSummaryMon(u8 taskId) case 11: PrintPageSpecificText(sMonSummaryScreen->currPageIndex); LimitEggSummaryPageDisplay(); + if (P_SUMMARY_SCREEN_RENAME && sMonSummaryScreen->currPageIndex == PSS_PAGE_INFO) + { + FillWindowPixelBuffer(PSS_LABEL_WINDOW_PROMPT_CANCEL, PIXEL_FILL(0)); + ShowCancelOrRenamePrompt(); + PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_CANCEL); + } break; case 12: gSprites[sMonSummaryScreen->spriteIds[SPRITE_ARR_ID_MON]].data[2] = 0; @@ -1969,6 +2048,8 @@ static void SwitchToMoveSelection(u8 taskId) if (!sMonSummaryScreen->lockMovesFlag) { ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_INFO); + if (ShouldShowMoveRelearner()) + ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_SWITCH); } TilemapFiveMovesDisplay(sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_BATTLE_MOVES][0], 3, FALSE); @@ -2099,6 +2180,8 @@ static void CloseMoveSelectMode(u8 taskId) DestroyMoveSelectorSprites(SPRITE_ARR_ID_MOVE_SELECTOR1); ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_SWITCH); PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_INFO); + if (ShouldShowMoveRelearner()) + PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); PrintMoveDetails(0); TilemapFiveMovesDisplay(sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_BATTLE_MOVES][0], 3, TRUE); TilemapFiveMovesDisplay(sMonSummaryScreen->bgTilemapBuffers[PSS_PAGE_CONTEST_MOVES][0], 1, TRUE); @@ -2925,12 +3008,7 @@ static void PrintPageNamesAndStats(void) PrintTextOnWindow(PSS_LABEL_WINDOW_BATTLE_MOVES_TITLE, gText_BattleMoves, 2, 1, 0, 1); PrintTextOnWindow(PSS_LABEL_WINDOW_CONTEST_MOVES_TITLE, gText_ContestMoves, 2, 1, 0, 1); - stringXPos = GetStringRightAlignXOffset(FONT_NORMAL, gText_Cancel2, 62); - iconXPos = stringXPos - 16; - if (iconXPos < 0) - iconXPos = 0; - PrintAOrBButtonIcon(PSS_LABEL_WINDOW_PROMPT_CANCEL, FALSE, iconXPos); - PrintTextOnWindow(PSS_LABEL_WINDOW_PROMPT_CANCEL, gText_Cancel2, stringXPos, 1, 0, 0); + ShowCancelOrRenamePrompt(); stringXPos = GetStringRightAlignXOffset(FONT_NORMAL, gText_Info, 62); iconXPos = stringXPos - 16; @@ -2967,6 +3045,7 @@ static void PrintPageNamesAndStats(void) PrintTextOnWindow(PSS_LABEL_WINDOW_MOVES_POWER_ACC, gText_Accuracy2, 0, 17, 0, 1); PrintTextOnWindow(PSS_LABEL_WINDOW_MOVES_APPEAL_JAM, gText_Appeal, 0, 1, 0, 1); PrintTextOnWindow(PSS_LABEL_WINDOW_MOVES_APPEAL_JAM, gText_Jam, 0, 17, 0, 1); + PrintTextOnWindowWithFont(PSS_LABEL_WINDOW_PROMPT_RELEARN, gText_Relearn, 0, 4, 0, 0, FONT_SMALL); } static void PutPageWindowTilemaps(u8 page) @@ -3003,6 +3082,8 @@ static void PutPageWindowTilemaps(u8 page) else { PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_INFO); + if (ShouldShowMoveRelearner()) + PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); } break; case PSS_PAGE_CONTEST_MOVES: @@ -3015,6 +3096,8 @@ static void PutPageWindowTilemaps(u8 page) else { PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_INFO); + if (ShouldShowMoveRelearner()) + PutWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); } break; } @@ -3054,6 +3137,8 @@ static void ClearPageWindowTilemaps(u8 page) else { ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_INFO); + if (ShouldShowMoveRelearner()) + ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); } break; case PSS_PAGE_CONTEST_MOVES: @@ -3065,6 +3150,8 @@ static void ClearPageWindowTilemaps(u8 page) else { ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_INFO); + if (ShouldShowMoveRelearner()) + ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); } break; } @@ -4297,3 +4384,54 @@ static void KeepMoveSelectorVisible(u8 firstSpriteId) gSprites[spriteIds[i]].invisible = FALSE; } } + +static inline bool32 ShouldShowMoveRelearner(void) +{ + return (P_SUMMARY_SCREEN_MOVE_RELEARNER + && !sMonSummaryScreen->lockMovesFlag + && sMonSummaryScreen->mode != SUMMARY_MODE_BOX + && sMonSummaryScreen->mode != SUMMARY_MODE_BOX_CURSOR + && sMonSummaryScreen->relearnableMovesNum > 0 + && !InBattleFactory() + && !InSlateportBattleTent()); +} + +static inline bool32 ShouldShowRename(void) +{ + return (P_SUMMARY_SCREEN_RENAME + && !sMonSummaryScreen->lockMovesFlag + && !sMonSummaryScreen->summary.isEgg + && sMonSummaryScreen->mode != SUMMARY_MODE_BOX + && sMonSummaryScreen->mode != SUMMARY_MODE_BOX_CURSOR + && !InBattleFactory() + && !InSlateportBattleTent() + && GetPlayerIDAsU32() == sMonSummaryScreen->summary.OTID); +} + +static void ShowCancelOrRenamePrompt(void) +{ + const u8 *promptText = ShouldShowRename() ? gText_Rename : gText_Cancel2; + + int stringXPos = GetStringRightAlignXOffset(FONT_NORMAL, promptText, 62); + int iconXPos = stringXPos - 16; + if (iconXPos < 0) + iconXPos = 0; + + PrintAOrBButtonIcon(PSS_LABEL_WINDOW_PROMPT_CANCEL, FALSE, iconXPos); + PrintTextOnWindow(PSS_LABEL_WINDOW_PROMPT_CANCEL, promptText, stringXPos, 1, 0, 0); +} + +static void CB2_ReturnToSummaryScreenFromNamingScreen(void) +{ + SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2); + ShowPokemonSummaryScreen(SUMMARY_MODE_NORMAL, gPlayerParty, gSpecialVar_0x8004, gPlayerPartyCount - 1, gInitialSummaryScreenCallback); +} + +static void CB2_PssChangePokemonNickname(void) +{ + GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3); + GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2); + DoNamingScreen(NAMING_SCREEN_NICKNAME, gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES, NULL), + GetMonGender(&gPlayerParty[gSpecialVar_0x8004]), GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_PERSONALITY, NULL), + CB2_ReturnToSummaryScreenFromNamingScreen); +} diff --git a/src/strings.c b/src/strings.c index 05cbdd81e1..b886ac639f 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1567,3 +1567,5 @@ const u8 gText_Fertilize[] = _("FERTILIZE"); const u8 gText_PlantBerry[] = _("PLANT BERRY"); const u8 gText_AM[] = _("AM"); const u8 gText_PM[] = _("PM"); +const u8 gText_Relearn[] = _("{START_BUTTON} RELEARN"); // future note: don't decap this, because it mimics the summary screen BG graphics which will not get decapped +const u8 gText_Rename[] = _("RENAME");