diff options
Diffstat (limited to 'src/move_tutor_menu.c')
-rw-r--r-- | src/move_tutor_menu.c | 1063 |
1 files changed, 1063 insertions, 0 deletions
diff --git a/src/move_tutor_menu.c b/src/move_tutor_menu.c new file mode 100644 index 000000000..7e1365391 --- /dev/null +++ b/src/move_tutor_menu.c @@ -0,0 +1,1063 @@ +#include "global.h" +#include "contest.h" +#include "data2.h" +#include "ewram.h" +#include "field_fadetransition.h" +#include "main.h" +#include "menu.h" +#include "menu_cursor.h" +#include "move_tutor_menu.h" +#include "overworld.h" +#include "palette.h" +#include "pokemon.h" +#include "pokemon_summary_screen.h" +#include "script.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "strings.h" +#include "strings2.h" +#include "task.h" +#include "trig.h" +#include "constants/songs.h" + +extern u16 gSpecialVar_0x8004; +extern u16 gSpecialVar_0x8005; +extern u8 gTileBuffer[]; + +extern const struct WindowTemplate gMenuTextWindowTemplate; +extern const struct WindowTemplate gMoveTutorMenuFramesWindowTemplate; +extern const u8 *const gContestEffectStrings[]; +extern const u8 *const gMoveDescriptions[]; +extern const u8 gTypeNames[][7]; +extern const u8 *const gContestCategoryNames[]; + +#ifdef GERMAN +extern const u8 deuOtherText_ForgotAndLearned[]; +#endif + +static void InitMoveTutorMenuWaitFade(u8); +static void CB2_InitMoveTutorMenu(void); +static void CB2_MoveTutorMenu(void); +static void MoveTutorMain(void); +static void DrawLearnMoveMenuWindow(void); +static void DrawBattleMoveInfoHeaders(bool8); +static u8 ChangeToContestMoveInfoWindow(void); +static void DrawContestMoveInfoHeaders(bool8); +static u8 ChangeToBattleMoveInfoWindow(void); +static void ResetMoveTutorMenu(void); +static void InitMoveTutorMenuSprites(void); +static void InitMoveTutorMenuStrings(void); +static void HandleMoveTutorMenuInput(void); +static void DrawMoveSelectionWindow(void); +static void DrawMoveInfoWindow(bool8, int); +static void RedrawMoveInfoWindow(void); +static void UpdateMoveTutorMenuCursorPosition(struct Sprite *); + +struct MoveTutorMenu +{ + u8 state; + u8 filler1; + u8 unk2; + u8 spriteIDs[20]; + u8 filler17; + u8 cursorPos; + u8 curMenuChoice; + u8 numMenuChoices; + u8 menuSelection; + u8 previousCursorPos; + bool8 redrawCursor; + bool8 redrawMoveSelectionWindow; + u16 movesToLearn[MAX_MOVE_TUTOR_MOVES]; + u8 filler48[10]; + u8 moveNames[6][25]; + u8 fillerE8[475]; + bool8 redrawMoveInfoWindow; + bool8 showContestInfo; + u8 partyMonIndex; + u8 forgetMoveIndex; +}; + +static struct MoveTutorMenu *sMoveTutorMenu; + +const u16 gMoveTutorMenuArrows_Pal[] = INCBIN_U16("graphics/move_tutor_menu/arrows.gbapal"); + +const u8 gMoveTutorMenuArrows_Gfx[] = INCBIN_U8("graphics/move_tutor_menu/arrows.4bpp"); + +const u8 gMoveTutorMenuWindowFrameDimensions[][4] = +{ + { 0, 0, 9, 13}, + {10, 0, 29, 7}, + { 2, 14, 27, 19}, + {10, 8, 29, 13}, +}; + +struct MoveTutorMoveInfoHeaders +{ + const u8 *text; + u8 left; + u8 right; + u8 index; // unused +}; + +const struct MoveTutorMoveInfoHeaders gMoveTutorMoveInfoHeaders[][4] = +{ + { + {OtherText_Battle, 1, 1, 0}, + {OtherText_Power, 1, 4, 1}, + {OtherText_Accuracy, 1, 9, 2}, + {NULL, 0, 0, 0}, + }, + { + {OtherText_Contest, 1, 1, 0}, + {OtherText_Appeal, 1, 4, 1}, + {OtherText_Jam, 1, 9, 2}, + {NULL, 0, 0, 0}, + }, +}; + +// XXX: What are these for? +const u32 unkDataFF00FFEF = 0xFF00FFEF; +const u8 *const gTileBuffer_ = gTileBuffer; + +const struct OamData gOamData_8402D50 = {.shape = 0}; +const struct OamData gOamData_8402D58 = {.shape = 2}; +const struct OamData gOamData_8402D60 = {.shape = 1}; + +const union AnimCmd gSpriteAnim_8402D68[] = +{ + ANIMCMD_FRAME(2, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402D70[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402D78[] = +{ + gSpriteAnim_8402D68, + gSpriteAnim_8402D70, +}; + +const struct SpriteSheet gMoveTutorMenuArrowsSpriteSheet = {gMoveTutorMenuArrows_Gfx, sizeof(gMoveTutorMenuArrows_Gfx), 5525}; +const struct SpritePalette gMoveTutorMenuArrowsPalette = {gMoveTutorMenuArrows_Pal, 5526}; + +const struct SpriteTemplate gSpriteTemplate_8402D90 = +{ + .tileTag = 5525, + .paletteTag = 5526, + .oam = &gOamData_8402D58, + .anims = gSpriteAnimTable_8402D78, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = UpdateMoveTutorMenuCursorPosition, +}; + +const union AnimCmd gSpriteAnim_8402DA8[] = +{ + ANIMCMD_FRAME(4, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DB0[] = +{ + ANIMCMD_FRAME(6, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402DB8[] = +{ + gSpriteAnim_8402DA8, + gSpriteAnim_8402DB0, +}; + +const struct SpriteTemplate gSpriteTemplate_8402DC0 = +{ + .tileTag = 5525, + .paletteTag = 5526, + .oam = &gOamData_8402D60, + .anims = gSpriteAnimTable_8402DB8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = UpdateMoveTutorMenuCursorPosition, +}; + +const union AnimCmd gSpriteAnim_8402DD8[] = +{ + ANIMCMD_FRAME(8, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DE0[] = +{ + ANIMCMD_FRAME(9, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DE8[] = +{ + ANIMCMD_FRAME(10, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DF0[] = +{ + ANIMCMD_FRAME(11, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402DF8[] = +{ + gSpriteAnim_8402DD8, + gSpriteAnim_8402DE0, + gSpriteAnim_8402DE8, + gSpriteAnim_8402DF0, +}; + +const struct SpriteTemplate gSpriteTemplate_8402E08 = +{ + .tileTag = 5525, + .paletteTag = 5526, + .oam = &gOamData_8402D50, + .anims = gSpriteAnimTable_8402DF8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = UpdateMoveTutorMenuCursorPosition, +}; + +const u8 gString_AkitoMori[] = _("あきと"); // programmer Akito Mori? + +static void VBlankCB_MoveTutorMenu(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +void DisplayMoveTutorMenu(void) +{ + ScriptContext2_Enable(); + CreateTask(InitMoveTutorMenuWaitFade, 10); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); +} + +static void InitMoveTutorMenuWaitFade(u8 taskId) +{ + if (!gPaletteFade.active) + { + SetMainCallback2(CB2_InitMoveTutorMenu); + gFieldCallback = sub_8080990; + DestroyTask(taskId); + } +} + +static void CB2_InitMoveTutorMenu(void) +{ + REG_DISPCNT = 0; + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + sMoveTutorMenu = eMoveTutorMenu; + ResetMoveTutorMenu(); + sMoveTutorMenu->partyMonIndex = gSpecialVar_0x8004; + InitMoveTutorMenuStrings(); + SetVBlankCallback(VBlankCB_MoveTutorMenu); + + Text_LoadWindowTemplate(&gMoveTutorMenuFramesWindowTemplate); + InitMenuWindow(&gMoveTutorMenuFramesWindowTemplate); + Menu_EraseScreen(); + + Text_LoadWindowTemplate(&gMenuTextWindowTemplate); + InitMenuWindow(&gMenuTextWindowTemplate); + Menu_EraseScreen(); + + REG_BG0VOFS = 0; + REG_BG0VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1HOFS = 0; + + LoadSpriteSheet(&gMoveTutorMenuArrowsSpriteSheet); + LoadSpritePalette(&gMoveTutorMenuArrowsPalette); + InitMoveTutorMenuSprites(); + FillPalette(0, 0, 2); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + SetMainCallback2(CB2_MoveTutorMenu); +} + +void CB2_ReturnToMoveTutorMenu(void) +{ + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + sMoveTutorMenu = eMoveTutorMenu; + InitMoveTutorMenuStrings(); + sMoveTutorMenu->forgetMoveIndex = gSpecialVar_0x8005; + SetVBlankCallback(VBlankCB_MoveTutorMenu); + + Text_LoadWindowTemplate(&gMoveTutorMenuFramesWindowTemplate); + InitMenuWindow(&gMoveTutorMenuFramesWindowTemplate); + Menu_EraseScreen(); + + Text_LoadWindowTemplate(&gMenuTextWindowTemplate); + InitMenuWindow(&gMenuTextWindowTemplate); + Menu_EraseScreen(); + + REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_OBJ_1D_MAP; + REG_BG0VOFS = 0; + REG_BG0HOFS = 0; + REG_BG1HOFS = 0; + REG_BG1HOFS = 0; + + LoadSpriteSheet(&gMoveTutorMenuArrowsSpriteSheet); + LoadSpritePalette(&gMoveTutorMenuArrowsPalette); + InitMoveTutorMenuSprites(); + FillPalette(0, 0, 2); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + SetMainCallback2(CB2_MoveTutorMenu); +} + +static void CB2_MoveTutorMenu(void) +{ + MoveTutorMain(); + if (sMoveTutorMenu->redrawCursor) + { + sMoveTutorMenu->redrawCursor = FALSE; + MenuCursor_SetPos814AD7C(0x58, (sMoveTutorMenu->cursorPos * 2 + 1) * 8); + } + if (sMoveTutorMenu->redrawMoveSelectionWindow) + { + sMoveTutorMenu->redrawMoveSelectionWindow = 0; + DrawMoveSelectionWindow(); + } + if (sMoveTutorMenu->redrawMoveInfoWindow) + { + DrawMoveInfoWindow(sMoveTutorMenu->showContestInfo, 1); + sMoveTutorMenu->redrawMoveInfoWindow = FALSE; + } + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void PrintMainMoveTutorMenuText(const u8 *str) +{ + StringExpandPlaceholders(gStringVar4, str); + MenuPrintMessage(gStringVar4, 3, 15); +} + +static void MoveTutorMain(void) +{ + switch (sMoveTutorMenu->state) + { + case 0: + sMoveTutorMenu->state++; + DrawLearnMoveMenuWindow(); + DrawBattleMoveInfoHeaders(FALSE); + DrawMoveSelectionWindow(); + gSprites[1].pos1.x = 0x48; + sMoveTutorMenu->redrawMoveInfoWindow = TRUE; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB(0, 0, 0)); + REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_OBJ_1D_MAP; + break; + case 1: + if (!gPaletteFade.active) + sMoveTutorMenu->state = 4; + break; + case 2: + sMoveTutorMenu->state++; + break; + case 3: + DrawBattleMoveInfoHeaders(FALSE); + DrawMoveSelectionWindow(); + sMoveTutorMenu->redrawMoveInfoWindow = TRUE; + sMoveTutorMenu->state++; + gSprites[1].pos1.x = 0x48; + break; + case 4: + if (!ChangeToContestMoveInfoWindow()) + HandleMoveTutorMenuInput(); + return; + case 5: + DrawContestMoveInfoHeaders(FALSE); + DrawMoveSelectionWindow(); + sMoveTutorMenu->redrawMoveInfoWindow = TRUE; + gSprites[1].pos1.x = 0x48; + sMoveTutorMenu->state++; + break; + case 6: + if (!ChangeToBattleMoveInfoWindow()) + HandleMoveTutorMenuInput(); + break; + case 8: + if (Menu_UpdateWindowText()) + { + DisplayYesNoMenu(21, 7, 1); + sMoveTutorMenu->state++; + } + break; + case 9: + { + s8 selection = Menu_ProcessInputNoWrap_(); + if (selection == 0) + { + RedrawMoveInfoWindow(); + if (GiveMoveToMon(&gPlayerParty[sMoveTutorMenu->partyMonIndex], sMoveTutorMenu->movesToLearn[sMoveTutorMenu->menuSelection]) != 0xFFFF) + { + PrintMainMoveTutorMenuText(gOtherText_PokeLearnedMove); + gSpecialVar_0x8004 = 1; + sMoveTutorMenu->state = 31; + } + else + { + sMoveTutorMenu->state = 16; + } + } + else if (selection == -1 || selection == 1) + { + RedrawMoveInfoWindow(); + if (sMoveTutorMenu->showContestInfo == FALSE) + sMoveTutorMenu->state = 3; + if (sMoveTutorMenu->showContestInfo == TRUE) + sMoveTutorMenu->state = 5; + } + } + break; + case 12: + if (Menu_UpdateWindowText()) + { + DisplayYesNoMenu(21, 7, 1); + sMoveTutorMenu->state++; + } + break; + case 13: + { + s8 selection = Menu_ProcessInputNoWrap_(); + + if (selection == 0) + { + RedrawMoveInfoWindow(); + gSpecialVar_0x8004 = selection; + sMoveTutorMenu->state = 14; + } + else if (selection == -1 || selection == 1) + { + RedrawMoveInfoWindow(); + if (sMoveTutorMenu->showContestInfo == FALSE) + sMoveTutorMenu->state = 3; + if (sMoveTutorMenu->showContestInfo == TRUE) + sMoveTutorMenu->state = 5; + } + } + break; + case 16: + PrintMainMoveTutorMenuText(gOtherText_DeleteOlderMove); + sMoveTutorMenu->state++; + break; + case 17: + if (Menu_UpdateWindowText()) + { + DisplayYesNoMenu(21, 7, 1); + sMoveTutorMenu->state = 18; + } + break; + case 18: + { + s8 var = Menu_ProcessInputNoWrap_(); + + if (var == 0) + { + RedrawMoveInfoWindow(); + PrintMainMoveTutorMenuText(gOtherText_WhichMoveToForget); + sMoveTutorMenu->state = 19; + } + else if (var == -1 || var == 1) + { + RedrawMoveInfoWindow(); + sMoveTutorMenu->state = 24; + } + } + break; + case 24: + PrintMainMoveTutorMenuText(gOtherText_StopLearningMove); + sMoveTutorMenu->state++; + break; + case 25: + if (Menu_UpdateWindowText()) + { + sMoveTutorMenu->state = 26; + DisplayYesNoMenu(21, 7, 1); + } + break; + case 26: + { + s8 var = Menu_ProcessInputNoWrap_(); + + if (var == 0) + { + RedrawMoveInfoWindow(); + sMoveTutorMenu->state = 27; + } + else if (var == -1 || var == 1) + { + RedrawMoveInfoWindow(); + + // What's the point? It gets set to 16, anyway. + if (sMoveTutorMenu->showContestInfo == FALSE) + sMoveTutorMenu->state = 3; + if (sMoveTutorMenu->showContestInfo == TRUE) + sMoveTutorMenu->state = 5; + sMoveTutorMenu->state = 16; + } + } + break; + case 27: + if (Menu_UpdateWindowText()) + { + if (sMoveTutorMenu->showContestInfo == FALSE) + sMoveTutorMenu->state = 3; + if (sMoveTutorMenu->showContestInfo == TRUE) + sMoveTutorMenu->state = 5; + } + break; + case 19: + if (Menu_UpdateWindowText()) + { + sMoveTutorMenu->state = 20; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + } + break; + case 20: + if (!gPaletteFade.active) + { + ShowSelectMovePokemonSummaryScreen(gPlayerParty, sMoveTutorMenu->partyMonIndex, gPlayerPartyCount - 1, CB2_ReturnToMoveTutorMenu, sMoveTutorMenu->movesToLearn[sMoveTutorMenu->menuSelection]); + sMoveTutorMenu->state = 28; + } + break; + case 21: + if (Menu_UpdateWindowText()) + sMoveTutorMenu->state = 14; + break; + case 22: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB(0, 0, 0)); + break; + case 14: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + sMoveTutorMenu->state++; + break; + case 15: + if (!gPaletteFade.active) + SetMainCallback2(c2_exit_to_overworld_2_switch); + break; + case 28: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB(0, 0, 0)); + sMoveTutorMenu->state++; + DrawLearnMoveMenuWindow(); + DrawMoveSelectionWindow(); + if (sMoveTutorMenu->showContestInfo == FALSE) + DrawBattleMoveInfoHeaders(TRUE); + if (sMoveTutorMenu->showContestInfo == TRUE) + { + gSprites[1].pos1.x = 0x48; + DrawContestMoveInfoHeaders(TRUE); + } + DrawMoveInfoWindow(sMoveTutorMenu->showContestInfo, 1); + break; + case 29: + if (!gPaletteFade.active) + { + if (sMoveTutorMenu->forgetMoveIndex == 4) + { + sMoveTutorMenu->state = 24; + } + else + { + u16 moveId = GetMonData(&gPlayerParty[sMoveTutorMenu->partyMonIndex], MON_DATA_MOVE1 + sMoveTutorMenu->forgetMoveIndex); + + StringCopy(gStringVar3, gMoveNames[moveId]); + RemoveMonPPBonus(&gPlayerParty[sMoveTutorMenu->partyMonIndex], sMoveTutorMenu->forgetMoveIndex); + SetMonMoveSlot(&gPlayerParty[sMoveTutorMenu->partyMonIndex], sMoveTutorMenu->movesToLearn[sMoveTutorMenu->menuSelection], sMoveTutorMenu->forgetMoveIndex); + StringCopy(gStringVar2, gMoveNames[sMoveTutorMenu->movesToLearn[sMoveTutorMenu->menuSelection]]); + PrintMainMoveTutorMenuText(gOtherText_ForgotMove123); + sMoveTutorMenu->state = 30; + gSpecialVar_0x8004 = 1; + } + } + break; + case 30: + if (Menu_UpdateWindowText()) + { +#ifdef GERMAN + PrintMainMoveTutorMenuText(deuOtherText_ForgotAndLearned); +#else + PrintMainMoveTutorMenuText(gOtherText_ForgotOrDidNotLearnMove); +#endif + sMoveTutorMenu->state = 31; + PlayFanfare(BGM_FANFA1); + } + break; + case 31: + if (Menu_UpdateWindowText()) + { + PlayFanfare(BGM_FANFA1); + sMoveTutorMenu->state = 32; + } + break; + case 32: + if (IsFanfareTaskInactive()) + sMoveTutorMenu->state = 33; + break; + case 33: + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sMoveTutorMenu->state = 14; + } + break; + } +} + +static void DrawLearnMoveMenuWindow(void) +{ + u32 i; + + BasicInitMenuWindow(&gMoveTutorMenuFramesWindowTemplate); + for (i = 0; i < 4; i++) + { + Menu_DrawStdWindowFrame( + gMoveTutorMenuWindowFrameDimensions[i][0], + gMoveTutorMenuWindowFrameDimensions[i][1], + gMoveTutorMenuWindowFrameDimensions[i][2], + gMoveTutorMenuWindowFrameDimensions[i][3]); + } + BasicInitMenuWindow(&gMenuTextWindowTemplate); +} + +static void DrawBattleMoveInfoHeaders(bool8 noTeachMoveText) +{ + s32 i; + + gSprites[sMoveTutorMenu->spriteIDs[0]].invisible = FALSE; + gSprites[sMoveTutorMenu->spriteIDs[1]].invisible = FALSE; + + for (i = 0; i < 16; i++) + gSprites[sMoveTutorMenu->spriteIDs[i + 4]].invisible = TRUE; + + for (i = 0; gMoveTutorMoveInfoHeaders[0][i].text != NULL; i++) + { + AlignStringInMenuWindow(gTileBuffer, gMoveTutorMoveInfoHeaders[0][i].text, 64, 2); + Menu_PrintText(gTileBuffer, gMoveTutorMoveInfoHeaders[0][i].left, gMoveTutorMoveInfoHeaders[0][i].right); + } + + if (!noTeachMoveText) + sub_8072AB0(gOtherText_TeachWhichMove, 24, 120, 192, 32, 1); +} + +static u8 ChangeToContestMoveInfoWindow(void) +{ + u32 result = (gMain.newKeys & DPAD_LEFT) || (gMain.newKeys & DPAD_RIGHT); + + if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR + && ((gMain.newKeys & L_BUTTON) || (gMain.newKeys & R_BUTTON))) + result++; + + if (result != 0) + { + PlaySE(SE_SELECT); + sMoveTutorMenu->state = 5; + sMoveTutorMenu->showContestInfo = TRUE; + } + + return result; +} + +static void DrawContestMoveInfoHeaders(bool8 noTeachMoveText) +{ + s32 i; + + gSprites[sMoveTutorMenu->spriteIDs[0]].invisible = FALSE; + gSprites[sMoveTutorMenu->spriteIDs[1]].invisible = FALSE; + + for (i = 0; i < 16; i++) + gSprites[sMoveTutorMenu->spriteIDs[i + 4]].invisible = FALSE; + + for (i = 0; gMoveTutorMoveInfoHeaders[0][i].text != NULL; i++) + { + AlignStringInMenuWindow(gTileBuffer, gMoveTutorMoveInfoHeaders[1][i].text, 64, 2); + Menu_PrintText(gTileBuffer, gMoveTutorMoveInfoHeaders[1][i].left, gMoveTutorMoveInfoHeaders[1][i].right); + if (i != 0) + { + Menu_EraseWindowRect( + gMoveTutorMoveInfoHeaders[1][i].left, + gMoveTutorMoveInfoHeaders[1][i].right + 2, + gMoveTutorMoveInfoHeaders[1][i].left + 7, + gMoveTutorMoveInfoHeaders[1][i].right + 3); + } + } + + if (!noTeachMoveText) + sub_8072AB0(gOtherText_TeachWhichMove, 24, 120, 192, 32, 1); +} + +static u8 ChangeToBattleMoveInfoWindow(void) +{ + u32 result = (gMain.newKeys & DPAD_LEFT) || (gMain.newKeys & DPAD_RIGHT); + + if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR + && ((gMain.newKeys & L_BUTTON) || (gMain.newKeys & R_BUTTON))) + result++; + + if (result != 0) + { + PlaySE(SE_SELECT); + sMoveTutorMenu->state = 3; + sMoveTutorMenu->showContestInfo = FALSE; + } + + return result; +} + +static void ResetMoveTutorMenu(void) +{ + s32 i; + + sMoveTutorMenu->state = 0; + sMoveTutorMenu->unk2 = 0; + sMoveTutorMenu->curMenuChoice = 0; + sMoveTutorMenu->cursorPos = 0; + sMoveTutorMenu->previousCursorPos = 0; + sMoveTutorMenu->numMenuChoices = 0; + sMoveTutorMenu->menuSelection = 0; + sMoveTutorMenu->redrawCursor = FALSE; + sMoveTutorMenu->redrawMoveSelectionWindow = 0; + sMoveTutorMenu->redrawMoveInfoWindow = FALSE; + sMoveTutorMenu->showContestInfo = FALSE; + for (i = 0; i < MAX_MOVE_TUTOR_MOVES; i++) + sMoveTutorMenu->movesToLearn[i] = 0; +} + +static void UpdateMoveTutorMenuCursorPosition(struct Sprite *sprite) +{ + s16 var = (sprite->data[1] * 10) & 0xFF; + + switch (sprite->data[0]) + { + case 0: + break; + case 1: + sprite->pos2.x = Sin(var, 3) * sprite->data[2]; + break; + case 2: + sprite->pos2.y = Sin(var, 1) * sprite->data[2]; + break; + } + sprite->data[1]++; +} + +static void InitMoveTutorMenuSprites(void) +{ + s32 i; + + sMoveTutorMenu->spriteIDs[0] = CreateSprite(&gSpriteTemplate_8402D90, 8, 16, 0); + gSprites[sMoveTutorMenu->spriteIDs[0]].data[0] = 1; + gSprites[sMoveTutorMenu->spriteIDs[0]].data[2] = -1; + + sMoveTutorMenu->spriteIDs[1] = CreateSprite(&gSpriteTemplate_8402D90, 72, 16, 0); + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[1]], 1); + gSprites[sMoveTutorMenu->spriteIDs[1]].data[0] = 1; + gSprites[sMoveTutorMenu->spriteIDs[1]].data[2] = 1; + + sMoveTutorMenu->spriteIDs[2] = CreateSprite(&gSpriteTemplate_8402DC0, 160, 4, 0); + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[2]], 1); + gSprites[sMoveTutorMenu->spriteIDs[2]].data[0] = 2; + gSprites[sMoveTutorMenu->spriteIDs[2]].data[2] = -1; + + sMoveTutorMenu->spriteIDs[3] = CreateSprite(&gSpriteTemplate_8402DC0, 160, 60, 0); + gSprites[sMoveTutorMenu->spriteIDs[3]].data[0] = 2; + gSprites[sMoveTutorMenu->spriteIDs[3]].data[2] = 1; + + for (i = 0; i < 8; i++) + { + sMoveTutorMenu->spriteIDs[i + 4] = CreateSprite(&gSpriteTemplate_8402E08, (i - (i / 4) * 4) * 8 + 0x1C, (i / 4) * 8 + 0x34, 0); + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[i + 4]], 2); + } + + for (i = 0; i < 8; i++) + { + sMoveTutorMenu->spriteIDs[i + 12] = CreateSprite(&gSpriteTemplate_8402E08, (i - (i / 4) * 4) * 8 + 0x1C, (i / 4) * 8 + 0x5C, 0); + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[i + 12]], 2); + } + + for (i = 0; i < 20; i++) + gSprites[sMoveTutorMenu->spriteIDs[i]].invisible = TRUE; + + CreateBlendedOutlineCursor(16, 0xFFFF, 12, 0x2D9F, 18); +} + +static void InitMoveTutorMenuStrings(void) +{ + s32 i; + u8 nickname[POKEMON_NAME_LENGTH + 1]; + + sMoveTutorMenu->numMenuChoices = GetMoveTutorMoves(&gPlayerParty[sMoveTutorMenu->partyMonIndex], sMoveTutorMenu->movesToLearn); + for (i = 0; i < sMoveTutorMenu->numMenuChoices; i++) + StringCopy(sMoveTutorMenu->moveNames[i], gMoveNames[sMoveTutorMenu->movesToLearn[i]]); + GetMonData(&gPlayerParty[sMoveTutorMenu->partyMonIndex], MON_DATA_NICKNAME, nickname); + StringCopy10(gStringVar1, nickname); + StringCopy(sMoveTutorMenu->moveNames[sMoveTutorMenu->numMenuChoices], gOtherText_Exit); + sMoveTutorMenu->numMenuChoices++; +} + +static void MoveCursorPos(s8 delta) +{ + sMoveTutorMenu->previousCursorPos = sMoveTutorMenu->cursorPos; + sMoveTutorMenu->cursorPos += delta; + sMoveTutorMenu->redrawCursor = TRUE; +} + +static void HandleMoveTutorMenuInput(void) +{ + if (gMain.newAndRepeatedKeys & DPAD_UP) + { + if (sMoveTutorMenu->menuSelection != 0) + { + PlaySE(SE_SELECT); + sMoveTutorMenu->menuSelection--; + sMoveTutorMenu->redrawMoveInfoWindow = TRUE; + if (sMoveTutorMenu->cursorPos != 0) + { + MoveCursorPos(-1); + } + else if (sMoveTutorMenu->curMenuChoice != 0) + { + sMoveTutorMenu->curMenuChoice--; + sMoveTutorMenu->redrawMoveSelectionWindow++; + } + } + } + else if (gMain.newAndRepeatedKeys & DPAD_DOWN) + { + if (sMoveTutorMenu->menuSelection < sMoveTutorMenu->numMenuChoices - 1) + { + PlaySE(SE_SELECT); + sMoveTutorMenu->menuSelection++; + sMoveTutorMenu->redrawMoveInfoWindow = TRUE; + if (sMoveTutorMenu->cursorPos != 2) + { + MoveCursorPos(1); + } + else if (sMoveTutorMenu->curMenuChoice != sMoveTutorMenu->numMenuChoices - 3) + { + sMoveTutorMenu->curMenuChoice++; + sMoveTutorMenu->redrawMoveSelectionWindow++; + } + } + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (sMoveTutorMenu->menuSelection != sMoveTutorMenu->numMenuChoices - 1) + { + sMoveTutorMenu->state = 8; + StringCopy(gStringVar2, sMoveTutorMenu->moveNames[sMoveTutorMenu->menuSelection]); + StringExpandPlaceholders(gStringVar4, gOtherText_TeachSpecificMove); + MenuPrintMessage(gStringVar4, 3, 15); + } + else + { + StringExpandPlaceholders(gStringVar4, gOtherText_GiveUpTeachingMove); + MenuPrintMessage(gStringVar4, 3, 15); + sMoveTutorMenu->state = 12; + } + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + sMoveTutorMenu->state = 12; + StringExpandPlaceholders(gStringVar4, gOtherText_GiveUpTeachingMove); + MenuPrintMessage(gStringVar4, 3, 15); + } + if (sMoveTutorMenu->numMenuChoices > 3) + { + gSprites[2].invisible = FALSE; + gSprites[3].invisible = FALSE; + if (sMoveTutorMenu->curMenuChoice == 0) + gSprites[2].invisible = TRUE; + else if (sMoveTutorMenu->curMenuChoice == sMoveTutorMenu->numMenuChoices - 3) + gSprites[3].invisible = TRUE; + } +} + +static void DrawMoveSelectionWindow(void) +{ + u8 menuChoice = sMoveTutorMenu->curMenuChoice; + u8 *str = gTileBuffer; + s32 i; + + for (i = 0; i < 3; i++) + { + if (menuChoice >= sMoveTutorMenu->numMenuChoices) + { + str = AlignStringInMenuWindow(str, gEmptyString_81E72B0, 0x90, 0); + } + else if (menuChoice == sMoveTutorMenu->numMenuChoices - 1) + { + str = AlignStringInMenuWindow(str, gOtherText_Exit, 0x90, 0); + } + else + { + u16 moveId = sMoveTutorMenu->movesToLearn[menuChoice]; + + if (sMoveTutorMenu->showContestInfo) + str = AlignStringInMenuWindow(str, gContestCategoryNames[gContestMoves[moveId].contestCategory], 0x27, 0); + else + str = AlignStringInMenuWindow(str, gTypeNames[gBattleMoves[moveId].type], 0x27, 0); + + str = AlignStringInMenuWindow(str, sMoveTutorMenu->moveNames[menuChoice], 0x72, 0); + + str[0] = CHAR_P; + str[1] = CHAR_P; + str[2] = CHAR_SLASH; + str += 3; + + str = AlignInt1InMenuWindow(str, gBattleMoves[moveId].pp, 0x90, 0); + } + *str++ = CHAR_NEWLINE; + menuChoice++; + } + *str = EOS; + Menu_PrintText(gTileBuffer, 11, 1); + MoveCursorPos(0); +} + +static const u8 sMoveInfoTextCoords[7][3] = +{ + {11, 1, 1}, + { 3, 6, 2}, + {24, 1, 3}, + { 3, 11, 4}, + { 5, 4, 5}, + { 3, 6, 6}, + { 3, 11, 7}, +}; + +static const u8 sBattleMoveInfoCoordIds[] = {0, 1, 2, 3}; +static const u8 sContestMoveInfoCoordIds[] = {4, 5, 6}; + +void PrintMoveInfo(u16 moveId, const u8 *moveInfoCoords) +{ + u8 str[0x34]; + u8 numHearts; + u8 i; + + StringCopy(str, gExpandedPlaceholder_Empty); + switch (moveInfoCoords[2]) + { + case 1: + break; + case 2: + if (gBattleMoves[moveId].power < 2) + AlignStringInMenuWindow(str, gOtherText_ThreeDashes2, 32, 2); + else + AlignInt1InMenuWindow(str, gBattleMoves[moveId].power, 32, 2); + Menu_PrintText(str, moveInfoCoords[0], moveInfoCoords[1]); + break; + case 4: + if (gBattleMoves[moveId].accuracy == 0) + AlignStringInMenuWindow(str, gOtherText_ThreeDashes2, 32, 2); + else + AlignInt1InMenuWindow(str, gBattleMoves[moveId].accuracy, 32, 2); + Menu_PrintText(str, moveInfoCoords[0], moveInfoCoords[1]); + break; + case 6: + Menu_EraseWindowRect(moveInfoCoords[0], moveInfoCoords[1], moveInfoCoords[0], moveInfoCoords[1] + 1); + numHearts = gContestEffects[gContestMoves[moveId].effect].appeal / 10; + if (numHearts == 255) + numHearts = 0; + for (i = 0; i < 8; i++) + { + if (i < numHearts) + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[i + 4]], 1); + else + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[i + 4]], 0); + } + break; + case 7: + Menu_EraseWindowRect(moveInfoCoords[0], moveInfoCoords[1], moveInfoCoords[0], moveInfoCoords[1] + 1); + numHearts = gContestEffects[gContestMoves[moveId].effect].jam / 10; + if (numHearts == 255) + numHearts = 0; + for (i = 0; i < 8; i++) + { + if (i < numHearts) + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[i + 12]], 3); + else + StartSpriteAnim(&gSprites[sMoveTutorMenu->spriteIDs[i + 12]], 2); + } + break; + } +} + +static void DrawMoveInfoWindow(bool8 contestInfo, int unused) +{ + u16 i; + + if (sMoveTutorMenu->menuSelection != sMoveTutorMenu->numMenuChoices - 1) + { + u16 moveId = sMoveTutorMenu->movesToLearn[sMoveTutorMenu->menuSelection]; + + if (contestInfo) + { + for (i = 0; i < 16; i++) + gSprites[sMoveTutorMenu->spriteIDs[i + 4]].invisible = FALSE; + for (i = 0; i < 3; i++) + PrintMoveInfo(moveId, sMoveInfoTextCoords[sContestMoveInfoCoordIds[i]]); + sub_8072AB0(gContestEffectStrings[gContestMoves[moveId].effect], 0x58, 0x48, 0x90, 32, 1); + } + else + { + u8 var; + + for (i = 0; i < 4; i++) + PrintMoveInfo(moveId, sMoveInfoTextCoords[sBattleMoveInfoCoordIds[i]]); + var = sub_8072A18(gMoveDescriptions[moveId - 1], 0x58, 0x48, 0x90, 1); + if (var < 2) + { + u8 r1 = var * 2 + 9; + + Menu_BlankWindowRect(11, r1, 28, 12); + } + } + } + else + { + if (contestInfo) + { + Menu_EraseWindowRect(sMoveInfoTextCoords[5][0], sMoveInfoTextCoords[5][1], sMoveInfoTextCoords[5][0], sMoveInfoTextCoords[5][1] + 1); + Menu_EraseWindowRect(sMoveInfoTextCoords[6][0], sMoveInfoTextCoords[6][1], sMoveInfoTextCoords[6][0], sMoveInfoTextCoords[6][1] + 1); + for (i = 0; i < 16; i++) + gSprites[sMoveTutorMenu->spriteIDs[i + 4]].invisible = TRUE; + } + else + { + Menu_EraseWindowRect(sMoveInfoTextCoords[1][0], sMoveInfoTextCoords[1][1], sMoveInfoTextCoords[1][0] + 3, sMoveInfoTextCoords[1][1] + 1); + Menu_EraseWindowRect(sMoveInfoTextCoords[3][0], sMoveInfoTextCoords[3][1], sMoveInfoTextCoords[3][0] + 3, sMoveInfoTextCoords[3][1] + 1); + } + Menu_EraseWindowRect(11, 9, 28, 12); + } +} + +static void RedrawMoveInfoWindow(void) +{ + Menu_EraseWindowRect(21, 7, 27, 12); + DrawMoveInfoWindow(sMoveTutorMenu->showContestInfo, 0); +} |