Skip to content

Allow Move Relearner to Teach Moves that Pre Evolutions Know

voloved edited this page Apr 6, 2023 · 5 revisions

By devolov

Goal: Make it so reteaching a move through the move relearner allows for moves that the Pre-Evoltuions know to still be taught.
For example, if you have a level 60 Clyster and want to reteach it Ice Beam, you cannot in the normal game. That's because Shellder learns Ice Beam at level 49, but Cloyster never learns it. This will make it so the moves of all Pre-evoluions are in the move tutor's menu.

pokeemerald_modern-0

In pokemon.h, we define MAX_LEVEL_DIFF_PRE_EV.
This constant is how many levels less than the current level that the Pokemon can learn a pre-evolved move.
Ex: if the current mon is lvl 55 and MAX_LEVEL_DIFF_PRE_EV is 5, then only moves at or less than 50 for prevolved mon will be counted.
This is because Pokemon often learn moves faster when not evolved, so this avoids evolving and giving a large move pool.

#define MAX_LEVEL_UP_MOVES       20
+#define MAX_LEVEL_DIFF_PRE_EV   5

#define MON_MALE       0x00
#define MON_FEMALE     0xFE

In pokemon.c:

static bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId);
static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
static bool8 ShouldSkipFriendshipChange(void);
+static u16 GetPreEvolution(u16 species);

EWRAM_DATA static u8 sLearningMoveTableID = 0;
EWRAM_DATA u8 gPlayerPartyCount = 0;
    else
    {
        u32 mask = 1 << (tm - 32);
        return gTMHMLearnsets[species][1] & mask;
    }
}

+static u16 GetPreEvolution(u16 species){
+    int i, j;
+
+    for (i = 1; i < NUM_SPECIES; i++)
+    {
+        for (j = 0; j < EVOS_PER_MON; j++)
+        {
+            if (gEvolutionTable[i][j].targetSpecies == species)
+                return i;
+        }
+    }
+    return SPECIES_NONE;
+}
+
u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves)
{
    u16 learnedMoves[MAX_MON_MOVES];
    u8 numMoves = 0;
    u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
    u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
+    u8 preEvLvl = (level > MAX_LEVEL_DIFF_PRE_EV) ? (level - MAX_LEVEL_DIFF_PRE_EV) : 1;
    int i, j, k;

    for (i = 0; i < MAX_MON_MOVES; i++)
        learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);

    for (i = 0; i < MAX_LEVEL_UP_MOVES; i++)
    {
        u16 moveLevel;

        if (gLevelUpLearnsets[species][i] == LEVEL_UP_END)
+{
+            i = 0;
+            level = preEvLvl;
+            species = GetPreEvolution(species);
+        }
+
+        if (species == SPECIES_NONE)
            break;

        moveLevel = gLevelUpLearnsets[species][i] & LEVEL_UP_MOVE_LV;

        if (moveLevel <= (level << 9))
        {
u8 GetNumberOfRelearnableMoves(struct Pokemon *mon)
{
    u16 learnedMoves[MAX_MON_MOVES];
    u16 moves[MAX_LEVEL_UP_MOVES];
    u8 numMoves = 0;
    u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
    u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
+    u8 preEvLvl = (level > MAX_LEVEL_DIFF_PRE_EV) ? (level - MAX_LEVEL_DIFF_PRE_EV) : 1;
    int i, j, k;

    if (species == SPECIES_EGG)
        return 0;

    for (i = 0; i < MAX_MON_MOVES; i++)
        learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);

    for (i = 0; i < MAX_LEVEL_UP_MOVES; i++)
    {
        u16 moveLevel;

        if (gLevelUpLearnsets[species][i] == LEVEL_UP_END)
+        {
+            i = 0;
+            level = preEvLvl;
+            species = GetPreEvolution(species);
+        }
+
+        if (species == SPECIES_NONE)
            break;

        moveLevel = gLevelUpLearnsets[species][i] & LEVEL_UP_MOVE_LV;

        if (moveLevel <= (level << 9))
Clone this wiki locally