From 6db75af62556e9d930c8bbb3d66fd0f09bceb359 Mon Sep 17 00:00:00 2001 From: PCG <75729017+PCG06@users.noreply.github.com> Date: Sun, 14 Dec 2025 19:02:52 +0530 Subject: [PATCH] Fix Summary screen lag with move relearner when there's a lot of TMs (#8503) --- include/item.h | 23 +++- include/pokemon.h | 16 +-- include/pokemon_summary_screen.h | 2 - src/item.c | 13 -- src/party_menu.c | 28 ++-- src/pokemon.c | 224 ++++++++++++++++++++++--------- src/pokemon_summary_screen.c | 45 +++---- 7 files changed, 224 insertions(+), 127 deletions(-) diff --git a/include/item.h b/include/item.h index 7d446e0fbc..d548643af8 100644 --- a/include/item.h +++ b/include/item.h @@ -130,6 +130,8 @@ extern const struct TmHmIndexKey gTMHMItemMoveIds[]; #define UNPACK_ITEM_TO_HM_INDEX(_hm) case CAT(ITEM_HM_, _hm): return CAT(ENUM_TM_HM_, _hm) + 1; #define UNPACK_ITEM_TO_TM_MOVE_ID(_tm) case CAT(ITEM_TM_, _tm): return CAT(MOVE_, _tm); #define UNPACK_ITEM_TO_HM_MOVE_ID(_hm) case CAT(ITEM_HM_, _hm): return CAT(MOVE_, _hm); +#define UNPACK_TM_MOVE_TO_ITEM_ID(_move) case CAT(MOVE_, _move): return CAT(ITEM_TM_, _move); +#define UNPACK_HM_MOVE_TO_ITEM_ID(_move) case CAT(MOVE_, _move): return CAT(ITEM_HM_, _move); static inline enum TMHMIndex GetItemTMHMIndex(u16 item) { @@ -165,10 +167,29 @@ static inline u16 GetItemTMHMMoveId(u16 item) } } +static inline enum TMHMItemId GetTMHMItemIdFromMoveId(u16 move) +{ + switch (move) + { + /* Expands to: + * case MOVE_FOCUS_PUNCH: + * return ITEM_TM_FOCUS_PUNCH; + * case MOVE_DRAGON_CLAW: + * return ITEM_TM_DRAGON_CLAW; + * etc */ + FOREACH_TM(UNPACK_TM_MOVE_TO_ITEM_ID) + FOREACH_HM(UNPACK_HM_MOVE_TO_ITEM_ID) + default: + return ITEM_NONE; + } +} + #undef UNPACK_ITEM_TO_TM_INDEX #undef UNPACK_ITEM_TO_HM_INDEX #undef UNPACK_ITEM_TO_TM_MOVE_ID #undef UNPACK_ITEM_TO_HM_MOVE_ID +#undef UNPACK_TM_MOVE_TO_ITEM_ID +#undef UNPACK_HM_MOVE_TO_ITEM_ID static inline enum TMHMItemId GetTMHMItemId(enum TMHMIndex index) { @@ -180,8 +201,6 @@ static inline u16 GetTMHMMoveId(enum TMHMIndex index) return gTMHMItemMoveIds[index].moveId; } -enum TMHMItemId GetTMHMItemIdFromMoveId(u16 move); - void BagPocket_SetSlotData(struct BagPocket *pocket, u32 pocketPos, struct ItemSlot newSlot); struct ItemSlot BagPocket_GetSlotData(struct BagPocket *pocket, u32 pocketPos); diff --git a/include/pokemon.h b/include/pokemon.h index 68d855545f..bc6af2a48e 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -841,14 +841,14 @@ void UpdatePartyPokerusTime(u16 days); void PartySpreadPokerus(struct Pokemon *party); bool8 TryIncrementMonLevel(struct Pokemon *mon); u8 CanLearnTeachableMove(u16 species, u16 move); -u8 GetRelearnerLevelUpMoves(struct Pokemon *mon, u16 *moves); -u8 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves); -u8 GetRelearnerTMMoves(struct Pokemon *mon, u16 *moves); -u8 GetRelearnerTutorMoves(struct Pokemon *mon, u16 *moves); -u8 GetNumberOfLevelUpMoves(struct Pokemon *mon); -u8 GetNumberOfEggMoves(struct Pokemon *mon); -u8 GetNumberOfTMMoves(struct Pokemon *mon); -u8 GetNumberOfTutorMoves(struct Pokemon *mon); +u32 GetRelearnerLevelUpMoves(struct Pokemon *mon, u16 *moves); +u32 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves); +u32 GetRelearnerTMMoves(struct Pokemon *mon, u16 *moves); +u32 GetRelearnerTutorMoves(struct Pokemon *mon, u16 *moves); +bool32 HasRelearnerLevelUpMoves(struct Pokemon *mon); +bool32 HasRelearnerEggMoves(struct Pokemon *mon); +bool32 HasRelearnerTMMoves(struct Pokemon *mon); +bool32 HasRelearnerTutorMoves(struct Pokemon *mon); u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves); u16 SpeciesToPokedexNum(u16 species); bool32 IsSpeciesInHoennDex(u16 species); diff --git a/include/pokemon_summary_screen.h b/include/pokemon_summary_screen.h index db4c0e89ad..6c4128dba4 100755 --- a/include/pokemon_summary_screen.h +++ b/include/pokemon_summary_screen.h @@ -57,7 +57,5 @@ u8 GetMoveSlotToReplace(void); void SummaryScreen_SetAnimDelayTaskId(u8 taskId); void ShowRelearnPrompt(void); void TryUpdateRelearnType(enum IncrDecrUpdateValues delta); -u32 GetCurrentRelearnMovesCount(void); -u32 GetRelearnMovesCount(enum MoveRelearnerStates state); #endif // GUARD_POKEMON_SUMMARY_SCREEN_H diff --git a/src/item.c b/src/item.c index c3e4f23a83..d9de596eab 100644 --- a/src/item.c +++ b/src/item.c @@ -88,19 +88,6 @@ static inline void NONNULL BagPocket_SetSlotDataPC(struct BagPocket *pocket, u32 pocket->itemSlots[pocketPos].quantity = newSlot.quantity; } -enum TMHMItemId GetTMHMItemIdFromMoveId(u16 move) -{ - if (move == MOVE_NONE) - return 0; - - for (u16 i = 0; i < NUM_ALL_MACHINES; i++) - { - if (GetTMHMMoveId(i + 1) == move) - return GetTMHMItemId(i + 1); - } - return 0; -} - struct ItemSlot NONNULL BagPocket_GetSlotData(struct BagPocket *pocket, u32 pocketPos) { switch (pocket->id) diff --git a/src/party_menu.c b/src/party_menu.c index 8498a80e97..6c1be78b45 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -1099,16 +1099,16 @@ static void DisplayPartyPokemonDataForRelearner(u8 slot) switch (gMoveRelearnerState) { case MOVE_RELEARNER_EGG_MOVES: - hasMoves = (GetNumberOfEggMoves(mon) > 0); + hasMoves = HasRelearnerEggMoves(mon); break; case MOVE_RELEARNER_TM_MOVES: - hasMoves = (GetNumberOfTMMoves(mon) > 0); + hasMoves = HasRelearnerTMMoves(mon); break; case MOVE_RELEARNER_TUTOR_MOVES: - hasMoves = (GetNumberOfTutorMoves(mon) > 0); + hasMoves = HasRelearnerTutorMoves(mon); break; default: - hasMoves = (GetNumberOfLevelUpMoves(mon) > 0); + hasMoves = HasRelearnerLevelUpMoves(mon); break; } @@ -2876,8 +2876,8 @@ static void SetPartyMonFieldSelectionActions(struct Pokemon *mons, u8 slotId) if (P_PARTY_MOVE_RELEARNER && (GetMonData(&mons[slotId], MON_DATA_SPECIES) - && (GetNumberOfLevelUpMoves(&mons[slotId]) || GetNumberOfEggMoves(&mons[slotId]) - || GetNumberOfTMMoves(&mons[slotId]) || GetNumberOfTutorMoves(&mons[slotId])))) + && (HasRelearnerLevelUpMoves(&mons[slotId]) || HasRelearnerEggMoves(&mons[slotId]) + || HasRelearnerTMMoves(&mons[slotId]) || HasRelearnerTutorMoves(&mons[slotId])))) AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_SUB_MOVES); // Add field moves to action list @@ -2907,24 +2907,24 @@ static void SetPartyMonFieldSelectionActions(struct Pokemon *mons, u8 slotId) static void SetPartyMonLearnMoveSelectionActions(struct Pokemon *mons, u8 slotId) { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && GetNumberOfLevelUpMoves(&mons[slotId]) > 0) + if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerLevelUpMoves(&mons[slotId])) AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_LEVEL_UP_MOVES); if (P_ENABLE_MOVE_RELEARNERS || (P_FLAG_EGG_MOVES != 0 && FlagGet(P_FLAG_EGG_MOVES))) { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && GetNumberOfEggMoves(&mons[slotId]) > 0) + if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerEggMoves(&mons[slotId])) AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_EGG_MOVES); } if (P_ENABLE_MOVE_RELEARNERS || P_TM_MOVES_RELEARNER) { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && GetNumberOfTMMoves(&mons[slotId]) > 0) + if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerTMMoves(&mons[slotId])) AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_TM_MOVES); } if (P_ENABLE_MOVE_RELEARNERS || (P_FLAG_TUTOR_MOVES != 0 && FlagGet(P_FLAG_TUTOR_MOVES))) { - if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && GetNumberOfTutorMoves(&mons[slotId]) > 0) + if (GetMonData(&mons[slotId], MON_DATA_SPECIES) != SPECIES_NONE && HasRelearnerTutorMoves(&mons[slotId])) AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_TUTOR_MOVES); } @@ -7968,16 +7968,16 @@ static void CB2_ChooseMonForMoveRelearner(void) switch(gMoveRelearnerState) { case MOVE_RELEARNER_EGG_MOVES: - gSpecialVar_0x8005 = GetNumberOfEggMoves(&gPlayerParty[gSpecialVar_0x8004]); + gSpecialVar_0x8005 = HasRelearnerEggMoves(&gPlayerParty[gSpecialVar_0x8004]); break; case MOVE_RELEARNER_TM_MOVES: - gSpecialVar_0x8005 = GetNumberOfTMMoves(&gPlayerParty[gSpecialVar_0x8004]); + gSpecialVar_0x8005 = HasRelearnerTMMoves(&gPlayerParty[gSpecialVar_0x8004]); break; case MOVE_RELEARNER_TUTOR_MOVES: - gSpecialVar_0x8005 = GetNumberOfTutorMoves(&gPlayerParty[gSpecialVar_0x8004]); + gSpecialVar_0x8005 = HasRelearnerTutorMoves(&gPlayerParty[gSpecialVar_0x8004]); break; default: - gSpecialVar_0x8005 = GetNumberOfLevelUpMoves(&gPlayerParty[gSpecialVar_0x8004]); + gSpecialVar_0x8005 = HasRelearnerLevelUpMoves(&gPlayerParty[gSpecialVar_0x8004]); break; } } diff --git a/src/pokemon.c b/src/pokemon.c index 16c3844527..b33b2363ef 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -5740,32 +5740,32 @@ static void QuickSortMoves(u16 *moves, s32 left, s32 right) QuickSortMoves(moves, i, right); } -static void SortMovesAlphabetically(u16 *moves, u8 numMoves) +static void SortMovesAlphabetically(u16 *moves, u32 numMoves) { if (numMoves > 1) QuickSortMoves(moves, 0, numMoves - 1); } -u8 GetRelearnerLevelUpMoves(struct Pokemon *mon, u16 *moves) +u32 GetRelearnerLevelUpMoves(struct Pokemon *mon, u16 *moves) { u16 learnedMoves[MAX_MON_MOVES] = {0}; - u8 numMoves = 0; - u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); - u8 level = (P_ENABLE_ALL_LEVEL_UP_MOVES ? MAX_LEVEL : GetMonData(mon, MON_DATA_LEVEL, 0)); + u32 numMoves = 0; + u32 species = GetMonData(mon, MON_DATA_SPECIES, 0); + u32 level = (P_ENABLE_ALL_LEVEL_UP_MOVES ? MAX_LEVEL : GetMonData(mon, MON_DATA_LEVEL, 0)); - for (u8 i = 0; i < MAX_MON_MOVES; i++) + for (u32 i = 0; i < MAX_MON_MOVES; i++) learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); do { const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); - for (u16 i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++) + for (u32 i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++) { if (learnset[i].level > level) - continue; + break; - u16 j; + u32 j; for (j = 0; j < MAX_MON_MOVES; j++) { if (learnedMoves[j] == learnset[i].move) @@ -5794,11 +5794,14 @@ u8 GetRelearnerLevelUpMoves(struct Pokemon *mon, u16 *moves) return numMoves; } -u8 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves) +u32 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves) { - u16 learnedMoves[MAX_MON_MOVES] = {0}; - u8 numMoves = 0; - u16 species = GetMonData(mon, MON_DATA_SPECIES); + if (!FlagGet(P_FLAG_EGG_MOVES) && !P_ENABLE_MOVE_RELEARNERS) + return 0; + + u32 learnedMoves[MAX_MON_MOVES] = {0}; + u32 numMoves = 0; + u32 species = GetMonData(mon, MON_DATA_SPECIES); while (GetSpeciesPreEvolution(species) != SPECIES_NONE) species = GetSpeciesPreEvolution(species); @@ -5807,12 +5810,12 @@ u8 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves) if (eggMoves == sNoneEggMoveLearnset) return numMoves; - for (u8 i = 0; i < MAX_MON_MOVES; i++) + for (u32 i = 0; i < MAX_MON_MOVES; i++) learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); - for (u16 i = 0; eggMoves[i] != MOVE_UNAVAILABLE; i++) + for (u32 i = 0; eggMoves[i] != MOVE_UNAVAILABLE; i++) { - u16 j; + u32 j; for (j = 0; j < MAX_MON_MOVES; j++) { if (learnedMoves[j] == eggMoves[i]) @@ -5838,28 +5841,35 @@ u8 GetRelearnerEggMoves(struct Pokemon *mon, u16 *moves) return numMoves; } -u8 GetRelearnerTMMoves(struct Pokemon *mon, u16 *moves) +u32 GetRelearnerTMMoves(struct Pokemon *mon, u16 *moves) { - u16 learnedMoves[MAX_MON_MOVES] = {0}; - u8 numMoves = 0; - u16 species = GetMonData(mon, MON_DATA_SPECIES); - u16 allMoves[NUM_ALL_MACHINES]; - u16 totalMoveCount = 0; + if (!P_TM_MOVES_RELEARNER) + return 0; - for (u16 i = 0; i < NUM_ALL_MACHINES; i++) + u32 learnedMoves[MAX_MON_MOVES] = {0}; + u32 numMoves = 0; + u32 species = GetMonData(mon, MON_DATA_SPECIES); + u16 allMoves[NUM_ALL_MACHINES]; + u32 totalMoveCount = 0; + + for (u32 i = 0; i < NUM_ALL_MACHINES; i++) { enum TMHMItemId item = GetTMHMItemId(i + 1); - u16 move = GetTMHMMoveId(i + 1); + u32 move = GetTMHMMoveId(i + 1); + + if (move == MOVE_NONE) + continue; + if ((P_ENABLE_ALL_TM_MOVES || CheckBagHasItem(item, 1)) && CanLearnTeachableMove(species, move) && move != MOVE_NONE) allMoves[totalMoveCount++] = move; } - for (u8 i = 0; i < MAX_MON_MOVES; i++) + for (u32 i = 0; i < MAX_MON_MOVES; i++) learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); - for (u16 i = 0; i < totalMoveCount; i++) + for (u32 i = 0; i < totalMoveCount; i++) { - u16 j; + u32 j; for (j = 0; j < MAX_MON_MOVES; j++) { if (learnedMoves[j] == allMoves[i]) @@ -5885,24 +5895,27 @@ u8 GetRelearnerTMMoves(struct Pokemon *mon, u16 *moves) return numMoves; } -u8 GetRelearnerTutorMoves(struct Pokemon *mon, u16 *moves) +u32 GetRelearnerTutorMoves(struct Pokemon *mon, u16 *moves) { + if (!FlagGet(P_FLAG_TUTOR_MOVES) && !P_ENABLE_MOVE_RELEARNERS) + return 0; + #if P_TUTOR_MOVES_ARRAY u16 learnedMoves[MAX_MON_MOVES] = {0}; - u8 numMoves = 0; - u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); + u32 numMoves = 0; + u32 species = GetMonData(mon, MON_DATA_SPECIES, 0); - for (u8 i = 0; i < MAX_MON_MOVES; i++) + for (u32 i = 0; i < MAX_MON_MOVES; i++) learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); - for (u16 i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++) + for (u32 i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++) { - u16 move = gTutorMoves[i]; + u32 move = gTutorMoves[i]; if (!CanLearnTeachableMove(species, move)) continue; - u16 j; + u32 j; for (j = 0; j < MAX_MON_MOVES; j++) { if (learnedMoves[j] == move) @@ -5931,60 +5944,145 @@ u8 GetRelearnerTutorMoves(struct Pokemon *mon, u16 *moves) #endif // P_TUTOR_MOVES_ARRAY } -u8 GetNumberOfLevelUpMoves(struct Pokemon *mon) +static inline bool32 DoesMonHaveMove(const u16 *moves, u16 move) { - u16 moves[MAX_RELEARNER_MOVES] = {0}; - u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); - - if (species == SPECIES_EGG) - return 0; - - return GetRelearnerLevelUpMoves(mon, moves); + for (u32 i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] == move) + return TRUE; + } + return FALSE; } -u8 GetNumberOfEggMoves(struct Pokemon *mon) +bool32 HasRelearnerLevelUpMoves(struct Pokemon *mon) +{ + u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); + + if (species == SPECIES_EGG) + return FALSE; + + u16 learnedMoves[MAX_MON_MOVES]; + + for (u32 i = 0; i < MAX_MON_MOVES; i++) + learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); + + u32 level = (P_ENABLE_ALL_LEVEL_UP_MOVES ? MAX_LEVEL : GetMonData(mon, MON_DATA_LEVEL, 0)); + + do + { + const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); + + for (u32 i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++) + { + if (learnset[i].level > level) + break; + + if (!DoesMonHaveMove(learnedMoves, learnset[i].move)) + return TRUE; + } + + species = (P_PRE_EVO_MOVES ? GetSpeciesPreEvolution(species) : SPECIES_NONE); + + } while (species != SPECIES_NONE); + + return FALSE; +} + +bool32 HasRelearnerEggMoves(struct Pokemon *mon) { if (!FlagGet(P_FLAG_EGG_MOVES) && !P_ENABLE_MOVE_RELEARNERS) - return 0; + return FALSE; - u16 moves[EGG_MOVES_ARRAY_COUNT] = {0}; - u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); + u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); if (species == SPECIES_EGG) - return 0; + return FALSE; - return GetRelearnerEggMoves(mon, moves); + u16 learnedMoves[MAX_MON_MOVES]; + + for (u32 i = 0; i < MAX_MON_MOVES; i++) + learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); + + while (GetSpeciesPreEvolution(species) != SPECIES_NONE) + species = GetSpeciesPreEvolution(species); + + const u16 *eggMoves = GetSpeciesEggMoves(species); + if (eggMoves == sNoneEggMoveLearnset) + return FALSE; + + for (u32 i = 0; eggMoves[i] != MOVE_UNAVAILABLE; i++) + { + if (!DoesMonHaveMove(learnedMoves, eggMoves[i])) + return TRUE; + } + + return FALSE; } -u8 GetNumberOfTMMoves(struct Pokemon *mon) +bool32 HasRelearnerTMMoves(struct Pokemon *mon) { if (!P_TM_MOVES_RELEARNER) - return 0; + return FALSE; - if (!P_ENABLE_ALL_TM_MOVES && !IsBagPocketNonEmpty(POCKET_TM_HM)) - return 0; - - u16 moves[MAX_RELEARNER_MOVES] = {0}; - u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); + u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); if (species == SPECIES_EGG) - return 0; + return FALSE; - return GetRelearnerTMMoves(mon, moves); + u16 learnedMoves[MAX_MON_MOVES]; + + for (u32 i = 0; i < MAX_MON_MOVES; i++) + learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); + + for (u32 i = 0; i < NUM_ALL_MACHINES; i++) + { + enum TMHMItemId item = GetTMHMItemId(i + 1); + u32 move = GetTMHMMoveId(i + 1); + + if (move == MOVE_NONE) + continue; + + if (!P_ENABLE_ALL_TM_MOVES || !CheckBagHasItem(item, 1)) + continue; + + if (!CanLearnTeachableMove(species, move)) + continue; + + if (!DoesMonHaveMove(learnedMoves, move)) + return TRUE; + } + + return FALSE; } -u8 GetNumberOfTutorMoves(struct Pokemon *mon) +bool32 HasRelearnerTutorMoves(struct Pokemon *mon) { if (!FlagGet(P_FLAG_TUTOR_MOVES) && !P_ENABLE_MOVE_RELEARNERS) - return 0; + return FALSE; - u16 moves[MAX_RELEARNER_MOVES] = {0}; - u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); +#if P_TUTOR_MOVES_ARRAY + u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); if (species == SPECIES_EGG) - return 0; + return FALSE; - return GetRelearnerTutorMoves(mon, moves); + u16 learnedMoves[MAX_MON_MOVES]; + + for (u32 i = 0; i < MAX_MON_MOVES; i++) + learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); + + for (u32 i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++) + { + u32 move = gTutorMoves[i]; + + if (!CanLearnTeachableMove(species, move)) + continue; + + if (!DoesMonHaveMove(learnedMoves, move)) + return TRUE; + } +#endif + return FALSE; } u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves) diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index ca94df5321..56d9cd0943 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -181,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 relearnableMovesNum; + bool8 hasRelearnableMoves; u8 windowIds[8]; u8 spriteIds[SPRITE_ARR_ID_COUNT]; bool8 handleDeoxys; @@ -1902,36 +1902,31 @@ void ExtractMonSkillEvData(struct Pokemon *mon, struct PokeSummary *sum) sum->speed = GetMonData(mon, MON_DATA_SPEED_EV); } -u32 GetRelearnMovesCount(enum MoveRelearnerStates state) +bool32 HasAnyRelearnableMoves(enum MoveRelearnerStates state) { struct Pokemon *mon = &sMonSummaryScreen->currentMon; switch (state) { case MOVE_RELEARNER_EGG_MOVES: - return GetNumberOfEggMoves(mon); + return HasRelearnerEggMoves(mon); case MOVE_RELEARNER_TM_MOVES: - return GetNumberOfTMMoves(mon); + return HasRelearnerTMMoves(mon); case MOVE_RELEARNER_TUTOR_MOVES: - return GetNumberOfTutorMoves(mon); + return HasRelearnerTutorMoves(mon); case MOVE_RELEARNER_LEVEL_UP_MOVES: - return GetNumberOfLevelUpMoves(mon); + return HasRelearnerLevelUpMoves(mon); default: - return 0; + return FALSE; } } -u32 GetCurrentRelearnMovesCount(void) -{ - return GetRelearnMovesCount(gMoveRelearnerState); -} - bool32 NoMovesAvailableToRelearn(void) { u32 zeroCounter = 0; for (enum MoveRelearnerStates state = MOVE_RELEARNER_LEVEL_UP_MOVES; state < MOVE_RELEARNER_COUNT; state++) { - if (GetRelearnMovesCount(state) == 0) + if (!HasAnyRelearnableMoves(state)) zeroCounter++; } @@ -1960,7 +1955,7 @@ bool32 CheckRelearnerStateFlag(enum MoveRelearnerStates state) void TryUpdateRelearnType(enum IncrDecrUpdateValues delta) { - u32 moveCount = 0; + bool32 hasRelearnableMoves = FALSE; u32 zeroCounter = 0; enum MoveRelearnerStates state = gMoveRelearnerState; @@ -1970,7 +1965,7 @@ void TryUpdateRelearnType(enum IncrDecrUpdateValues delta) && !FlagGet(P_FLAG_EGG_MOVES) && !FlagGet(P_FLAG_TUTOR_MOVES))) { - sMonSummaryScreen->relearnableMovesNum = GetRelearnMovesCount(MOVE_RELEARNER_LEVEL_UP_MOVES); + sMonSummaryScreen->hasRelearnableMoves = HasAnyRelearnableMoves(MOVE_RELEARNER_LEVEL_UP_MOVES); return; } @@ -1980,15 +1975,15 @@ void TryUpdateRelearnType(enum IncrDecrUpdateValues delta) { default: case TRY_SET_UPDATE: - moveCount = GetCurrentRelearnMovesCount(); - if (moveCount == 0) + hasRelearnableMoves = HasAnyRelearnableMoves(gMoveRelearnerState); + if (!hasRelearnableMoves) { delta = TRY_INCREMENT; continue; } else { - sMonSummaryScreen->relearnableMovesNum = moveCount; + sMonSummaryScreen->hasRelearnableMoves = hasRelearnableMoves; return; } // should never reach this, but just in case @@ -2004,16 +1999,16 @@ void TryUpdateRelearnType(enum IncrDecrUpdateValues delta) if (!CheckRelearnerStateFlag(state)) continue; - moveCount = GetRelearnMovesCount(state); - if (moveCount != 0) + hasRelearnableMoves = HasAnyRelearnableMoves(state); + if (hasRelearnableMoves) { gMoveRelearnerState = state; - sMonSummaryScreen->relearnableMovesNum = moveCount; + sMonSummaryScreen->hasRelearnableMoves = hasRelearnableMoves; return; } zeroCounter++; - } while (zeroCounter <= MOVE_RELEARNER_COUNT && moveCount == 0); + } while (zeroCounter <= MOVE_RELEARNER_COUNT && !hasRelearnableMoves); } static void ChangeSummaryPokemon(u8 taskId, s8 delta) @@ -2274,7 +2269,7 @@ static void ChangePage(u8 taskId, s8 delta) } // to prevent nothing showing - if (currPageIndex >= PSS_PAGE_BATTLE_MOVES && sMonSummaryScreen->relearnableMovesNum == 0) + if (currPageIndex >= PSS_PAGE_BATTLE_MOVES && !sMonSummaryScreen->hasRelearnableMoves) TryUpdateRelearnType(TRY_SET_UPDATE); else ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN); @@ -4809,7 +4804,7 @@ static inline bool32 ShouldShowMoveRelearner(void) && !sMonSummaryScreen->isBoxMon && sMonSummaryScreen->mode != SUMMARY_MODE_BOX && sMonSummaryScreen->mode != SUMMARY_MODE_BOX_CURSOR - && sMonSummaryScreen->relearnableMovesNum > 0 + && sMonSummaryScreen->hasRelearnableMoves && !InBattleFactory() && !InSlateportBattleTent() && !NoMovesAvailableToRelearn()); @@ -4918,7 +4913,7 @@ void ShowRelearnPrompt(void) return; } - if (GetCurrentRelearnMovesCount() == 0) + if (!HasAnyRelearnableMoves(gMoveRelearnerState)) return; const u8* relearnText;