Skip to content

Make Mirage Island Check PC Pokémon

Deokishisu edited this page Feb 7, 2025 · 3 revisions

Introduction

Mirage Island is an island that appears on Route 130 if a random number drawn once a day matches the first two bytes of a party Pokémon's personality value. Due to the check only considering party Pokémon, maximizing your odds for Mirage Island to appear requires cycling your entire Pokémon collection through your party and checking six at a time. This tutorial will show you how to make the Mirage Island check search the entirety of the player's Pokémon storage for a matching Pokémon in addition to their party.

Code Changes Credit to Deokishisu

In time_events.c, replace your IsMirageIslandPresent() function with this:

bool32 IsMirageIslandPresent(void)
{
    u32 hi = gSaveBlock1Ptr->vars[VAR_MIRAGE_RND_H - VARS_START];
    u32 lo = gSaveBlock1Ptr->vars[VAR_MIRAGE_RND_L - VARS_START];
    u32 rnd = ((hi << 16) | lo) >> 16;
    bool32 species;
    u32 personality;
    int i, j;
    struct Pokemon * curMon = &gPlayerParty[0];
    struct Pokemon * partyEnd = &gPlayerParty[PARTY_SIZE];

    do
    {
        species = curMon->box.hasSpecies;
        if (!species) 
            break;
        personality = curMon->box.personality & 0xFFFF;
        if (personality == rnd)
            return TRUE;
    } while (++curMon < partyEnd);

    struct BoxPokemon * curBoxMon = &gPokemonStoragePtr->boxes1d[0];
    struct BoxPokemon * boxMonEnd = &gPokemonStoragePtr->boxes1d[TOTAL_BOXES_COUNT * IN_BOX_COUNT];

    do {
        species = curBoxMon->hasSpecies;
        if (species) {
            personality = curBoxMon->personality & 0xffff;
            if (personality == rnd) {
                return TRUE;
            }
        }
    } while (++curBoxMon < boxMonEnd);

    return FALSE;
}

In time_events.h, be sure to correct the function definition:

#ifndef GUARD_TIME_EVENTS_H
#define GUARD_TIME_EVENTS_H

void UpdateMirageRnd(u16);
- u8 IsMirageIslandPresent(void);
+ bool32 IsMirageIslandPresent(void);
void UpdateBirchState(u16);

#endif // GUARD_TIME_EVENTS_H

Explanation

This function is written to do everything possible to avoid accessing encrypted mon data and calling the GetMonData-esque functions, as doing so is incredibly slow. Since the original function is grabbing the species only to check for empty slots (SPECIES_NONE) we can do the same by checking the conveniently unencrypted hasSpecies field. Fortunately, the personality field is also unencrypted. In addition, at the top we also directly access the VAR_MIRAGE_RND_H and VAR_MIRAGE_RND_L vars without going through GetMirageRnd's VarGet calls, which eliminates some overhead.

Doing it this way is so fast that there is no noticeable lag when entering Route 130 with full boxes, which is when this check is performed.

Clone this wiki locally