Skip large gaps in Pokédex - Pawkkie/Team-Aquas-Asset-Repo GitHub Wiki
By te_on.
If you catch a Pokémon with a high dex number, there's a good chance you'll need to scroll a long ways in the Pokédex before reaching its entry.
With a few code changes, you can eliminate that giant gap to look like this:
Click here if you just want to see a diff of the changes. Or you can download the patch file here.
Customization
SKIP_TRESHOLD
(default 4)
By default, skips will only trigger when there are more than 4 unseen Pokémon between two seen Pokémon. You can change this behavior by changing the value of SKIP_THRESHOLD
. The larger the value, the bigger the gap needs to be to trigger a skip.
Vanilla Pokédex
For the regular Emerald Pokédex, you will be modifying src/pokedex.c
.
WIN_VU_METER,
};
+static const u8 sText_TripleBullet[] = _("···");
+
// For scrolling search parameter
#define MAX_SEARCH_PARAM_ON_SCREEN 6
#define MAX_SEARCH_PARAM_CURSOR_POS (MAX_SEARCH_PARAM_ON_SCREEN - 1)
#define MAX_MONS_ON_SCREEN 4
#define LIST_SCROLL_STEP 16
+#define SKIP_THRESHOLD 4 // Number of Pokémon to check are unseen before triggering a skip
+#define SHOW_TRIPLE_BULLET 0xFFFE // Used to indicate sText_TripleBullet should be displayed (0xFFFE is an invalid dex number)
+
#define POKEBALL_ROTATION_TOP 64
#define POKEBALL_ROTATION_BOTTOM (POKEBALL_ROTATION_TOP - 16)
static void CreatePokedexList(u8 dexMode, u8 order)
{
u32 vars[3]; //I have no idea why three regular variables are stored in an array, but whatever.
#define temp_dexCount vars[0]
#define temp_isHoennDex vars[1]
#define temp_dexNum vars[2]
- s32 i;
+ s32 i, j;
+ u16 monSeen;
sPokedexView->pokemonListCount = 0;
...
case ORDER_NUMERICAL:
if (temp_isHoennDex)
{
- for (i = 0; i < temp_dexCount; i++)
+ s16 r5;
+ for (i = 0, r5 = 0; i < temp_dexCount; i++)
{
temp_dexNum = HoennToNationalOrder(i + 1);
- sPokedexView->pokedexList[i].dexNum = temp_dexNum;
- sPokedexView->pokedexList[i].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
- sPokedexView->pokedexList[i].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
- if (sPokedexView->pokedexList[i].seen)
- sPokedexView->pokemonListCount = i + 1;
+ monSeen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
+ if (!monSeen && i < temp_dexCount - 1 - SKIP_THRESHOLD)
+ {
+ // Check if the next SKIP_THRESHOLD entries are also unseen
+ for (j = 1; j <= SKIP_THRESHOLD; j++)
+ {
+ if (GetSetPokedexFlag(HoennToNationalOrder(i + j), FLAG_GET_SEEN))
+ break;
+ }
+ if (j == SKIP_THRESHOLD + 1)
+ {
+ // Loop until the next seen entry
+ do
+ {
+ i++;
+ monSeen = GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_SEEN);
+ } while (!monSeen && i < temp_dexCount - 1);
+
+ temp_dexNum = HoennToNationalOrder(i + 1);
+ sPokedexView->pokedexList[r5].dexNum = 0;
+ sPokedexView->pokedexList[r5].seen = FALSE;
+ sPokedexView->pokedexList[r5].owned = FALSE;
+ r5++;
+ }
+ }
+ sPokedexView->pokedexList[r5].dexNum = temp_dexNum;
+ sPokedexView->pokedexList[r5].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
+ sPokedexView->pokedexList[r5].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
+ if (sPokedexView->pokedexList[r5].seen)
+ sPokedexView->pokemonListCount = r5 + 1;
+ r5++;
}
}
else
{
s16 r5, r10;
for (i = 0, r5 = 0, r10 = 0; i < temp_dexCount; i++)
{
temp_dexNum = i + 1;
- if (GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN))
+ monSeen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
+ if (monSeen)
r10 = 1;
if (r10)
{
+ if (!monSeen && i < temp_dexCount - 1 - SKIP_THRESHOLD)
+ {
+ // Check if the next SKIP_THRESHOLD entries are also unseen
+ for (j = 1; j <= SKIP_THRESHOLD; j++)
+ {
+ if (GetSetPokedexFlag(i + j + 1, FLAG_GET_SEEN))
+ break;
+ }
+ if (j == SKIP_THRESHOLD + 1)
+ {
+ // Loop until the next seen entry
+ while (i < temp_dexCount - 1 && !GetSetPokedexFlag(i + 1, FLAG_GET_SEEN))
+ {
+ i++;
+ }
+
+ temp_dexNum = i + 1;
+ sPokedexView->pokedexList[r5].dexNum = 0;
+ sPokedexView->pokedexList[r5].seen = FALSE;
+ sPokedexView->pokedexList[r5].owned = FALSE;
+ r5++;
+ }
+ }
sPokedexView->pokedexList[r5].dexNum = temp_dexNum;
sPokedexView->pokedexList[r5].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
sPokedexView->pokedexList[r5].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
static void CreateMonListEntry(u8 position, u16 b, u16 ignored)
{
...
case 0: // Initial
default:
...
ClearMonListEntry(17, i * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
{
- CreateMonDexNum(entryNum, 0x12, i * 2, ignored);
+ CreateMonDexNum(entryNum, 0x12, i * 2, FALSE);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, 0x11, i * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, 0x16, i * 2);
}
else
{
- CreateMonDexNum(entryNum, 0x12, i * 2, ignored);
+ CreateMonDexNum(entryNum, 0x12, i * 2, sPokedexView->pokedexList[entryNum].dexNum == 0);
CreateCaughtBall(FALSE, 0x11, i * 2, ignored);
- CreateMonName(0, 0x16, i * 2);
+ CreateMonName(sPokedexView->pokedexList[entryNum].dexNum == 0 ? SHOW_TRIPLE_BULLET : 0, 0x16, i * 2);
}
}
entryNum++;
...
case 1: // Up
...
ClearMonListEntry(17, sPokedexView->listVOffset * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
{
- CreateMonDexNum(entryNum, 18, sPokedexView->listVOffset * 2, ignored);
+ CreateMonDexNum(entryNum, 18, sPokedexView->listVOffset * 2, FALSE);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, 0x11, sPokedexView->listVOffset * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, 0x16, sPokedexView->listVOffset * 2);
}
else
{
- CreateMonDexNum(entryNum, 18, sPokedexView->listVOffset * 2, ignored);
+ CreateMonDexNum(entryNum, 18, sPokedexView->listVOffset * 2, sPokedexView->pokedexList[entryNum].dexNum == 0);
CreateCaughtBall(FALSE, 17, sPokedexView->listVOffset * 2, ignored);
- CreateMonName(0, 0x16, sPokedexView->listVOffset * 2);
+ CreateMonName(sPokedexView->pokedexList[entryNum].dexNum == 0 ? SHOW_TRIPLE_BULLET : 0, 0x16, sPokedexView->listVOffset * 2);
}
}
break;
...
case 2: // Down
...
ClearMonListEntry(17, vOffset * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
{
- CreateMonDexNum(entryNum, 18, vOffset * 2, ignored);
+ CreateMonDexNum(entryNum, 18, vOffset * 2, FALSE);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, 0x11, vOffset * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, 0x16, vOffset * 2);
}
else
{
- CreateMonDexNum(entryNum, 18, vOffset * 2, ignored);
+ CreateMonDexNum(entryNum, 18, vOffset * 2, sPokedexView->pokedexList[entryNum].dexNum == 0);
CreateCaughtBall(FALSE, 0x11, vOffset * 2, ignored);
- CreateMonName(0, 0x16, vOffset * 2);
+ CreateMonName(sPokedexView->pokedexList[entryNum].dexNum == 0 ? SHOW_TRIPLE_BULLET : 0, 0x16, vOffset * 2);
}
}
break;
}
CopyWindowToVram(0, COPYWIN_GFX);
}
-static void CreateMonDexNum(u16 entryNum, u8 left, u8 top, u16 unused)
+static void CreateMonDexNum(u16 entryNum, u8 left, u8 top, u16 skip)
{
u8 text[7];
u16 dexNum, offset = 2;
dexNum = sPokedexView->pokedexList[entryNum].dexNum;
if (sPokedexView->dexMode == DEX_MODE_HOENN)
dexNum = NationalToHoennOrder(dexNum);
- memcpy(text, sText_No0000, ARRAY_COUNT(sText_No0000));
- if (NATIONAL_DEX_COUNT > 999 && sPokedexView->dexMode != DEX_MODE_HOENN)
+ if (skip)
{
- text[2] = CHAR_0 + dexNum / 1000;
- offset++;
+ text[0] = EOS;
+ }
+ else
+ {
+ memcpy(text, sText_No0000, ARRAY_COUNT(sText_No0000));
+ if (NATIONAL_DEX_COUNT > 999 && sPokedexView->dexMode != DEX_MODE_HOENN)
+ {
+ text[2] = CHAR_0 + dexNum / 1000;
+ offset++;
+ }
+ text[offset++] = CHAR_0 + (dexNum % 1000) / 100;
+ text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) / 10;
+ text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) % 10;
+ text[offset++] = EOS;
}
- text[offset++] = CHAR_0 + (dexNum % 1000) / 100;
- text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) / 10;
- text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) % 10;
- text[offset++] = EOS;
PrintMonDexNum(0, FONT_NARROW, text, left, top);
}
static u8 CreateMonName(u16 num, u8 left, u8 top)
{
const u8 *str;
- num = NationalPokedexNumToSpecies(num);
- if (num)
- str = GetSpeciesName(num);
+ if (num == SHOW_TRIPLE_BULLET)
+ {
+ str = sText_TripleBullet;
+ }
else
- str = sText_TenDashes;
+ {
+ num = NationalPokedexNumToSpecies(num);
+ if (num)
+ str = GetSpeciesName(num);
+ else
+ str = sText_TenDashes;
+ }
PrintMonName(0, FONT_NARROW, str, left, top);
return StringLength(str);
}
HGSS Pokédex
For the HGSS Pokédex, you will be modifying src/pokedex_plus_hgss.c
. Changes are very similar to those in src/pokedex.c
.
static const u8 sText_No0000[] = _("0000");
static const u8 sCaughtBall_Gfx[] = INCBIN_U8("graphics/pokedex/caught_ball.4bpp");
static const u8 sText_TenDashes[] = _("----------");
+static const u8 sText_TripleBullet[] = _(" ···");
ALIGNED(4) static const u8 sExpandedPlaceholder_PokedexDescription[] = _("");
static const u16 sSizeScreenSilhouette_Pal[] = INCBIN_U16("graphics/pokedex/size_silhouette.gbapal");
#define LIST_SCROLL_STEP 16
+#define SKIP_THRESHOLD 4 // Number of Pokémon to check are unseen before triggering a skip
+#define SHOW_TRIPLE_BULLET 0xFFFE // Used to indicate sText_TripleBullet should be displayed (0xFFFE is an invalid dex number)
+
#define POKEBALL_ROTATION_TOP 64
#define POKEBALL_ROTATION_BOTTOM (POKEBALL_ROTATION_TOP - 16)
static void CreatePokedexList(u8 dexMode, u8 order)
{
u32 vars[3]; //I have no idea why three regular variables are stored in an array, but whatever.
#define temp_dexCount vars[0]
#define temp_isHoennDex vars[1]
#define temp_dexNum vars[2]
- s16 i;
+ s16 i, j;
+ u16 monSeen;
sPokedexView->pokemonListCount = 0;
...
case ORDER_NUMERICAL:
if (temp_isHoennDex)
{
- for (i = 0; i < temp_dexCount; i++)
+ s16 r5;
+ for (i = 0, r5 = 0; i < temp_dexCount; i++)
{
temp_dexNum = HoennToNationalOrder(i + 1);
- sPokedexView->pokedexList[i].dexNum = temp_dexNum;
- sPokedexView->pokedexList[i].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
- sPokedexView->pokedexList[i].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
- if (sPokedexView->pokedexList[i].seen)
- sPokedexView->pokemonListCount = i + 1;
+ monSeen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
+ if (!monSeen && i < temp_dexCount - 1 - SKIP_THRESHOLD)
+ {
+ // Check if the next SKIP_THRESHOLD entries are also unseen
+ for (j = 1; j <= SKIP_THRESHOLD; j++)
+ {
+ if (GetSetPokedexFlag(HoennToNationalOrder(i + j), FLAG_GET_SEEN))
+ break;
+ }
+ if (j == SKIP_THRESHOLD + 1)
+ {
+ // Loop until the next seen entry
+ do
+ {
+ i++;
+ monSeen = GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_SEEN);
+ } while (!monSeen && i < temp_dexCount - 1);
+
+ temp_dexNum = HoennToNationalOrder(i + 1);
+ sPokedexView->pokedexList[r5].dexNum = 0;
+ sPokedexView->pokedexList[r5].seen = FALSE;
+ sPokedexView->pokedexList[r5].owned = FALSE;
+ r5++;
+ }
+ }
+ sPokedexView->pokedexList[r5].dexNum = temp_dexNum;
+ sPokedexView->pokedexList[r5].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
+ sPokedexView->pokedexList[r5].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
+ if (sPokedexView->pokedexList[r5].seen)
+ sPokedexView->pokemonListCount = r5 + 1;
+ r5++;
}
}
else
{
s16 r5, r10;
for (i = 0, r5 = 0, r10 = 0; i < temp_dexCount; i++)
{
temp_dexNum = i + 1;
- if (GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN))
+ monSeen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
+ if (monSeen)
r10 = 1;
if (r10)
{
+ if (!monSeen && i < temp_dexCount - 1 - SKIP_THRESHOLD)
+ {
+ // Check if the next SKIP_THRESHOLD entries are also unseen
+ for (j = 1; j <= SKIP_THRESHOLD; j++)
+ {
+ if (GetSetPokedexFlag(i + j + 1, FLAG_GET_SEEN))
+ break;
+ }
+ if (j == SKIP_THRESHOLD + 1)
+ {
+ // Loop until the next seen entry
+ while (i < temp_dexCount - 1 && !GetSetPokedexFlag(i + 1, FLAG_GET_SEEN))
+ {
+ i++;
+ }
+
+ temp_dexNum = i + 1;
+ sPokedexView->pokedexList[r5].dexNum = 0;
+ sPokedexView->pokedexList[r5].seen = FALSE;
+ sPokedexView->pokedexList[r5].owned = FALSE;
+ r5++;
+ }
+ }
sPokedexView->pokedexList[r5].dexNum = temp_dexNum;
sPokedexView->pokedexList[r5].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
sPokedexView->pokedexList[r5].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
static void CreateMonListEntry(u8 position, u16 b, u16 ignored)
{
...
case 0: // Initial
default:
...
ClearMonListEntry(MON_LIST_X, i * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
{
- CreateMonDexNum(entryNum, MON_LIST_X+1, i * 2, ignored);
+ CreateMonDexNum(entryNum, MON_LIST_X+1, i * 2, FALSE);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, MON_LIST_X, i * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, MON_LIST_X + 5, i * 2);
}
else
{
- CreateMonDexNum(entryNum, MON_LIST_X+1, i * 2, ignored);
+ CreateMonDexNum(entryNum, MON_LIST_X+1, i * 2, sPokedexView->pokedexList[entryNum].dexNum == 0);
CreateCaughtBall(FALSE, MON_LIST_X, i * 2, ignored);
- CreateMonName(0, MON_LIST_X + 5, i * 2);
+ CreateMonName(sPokedexView->pokedexList[entryNum].dexNum == 0 ? SHOW_TRIPLE_BULLET : 0, MON_LIST_X + 5, i * 2);
}
}
entryNum++;
}
break;
case 1: // Up
...
ClearMonListEntry(MON_LIST_X, sPokedexView->listVOffset * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
{
- CreateMonDexNum(entryNum, MON_LIST_X+1, sPokedexView->listVOffset * 2, ignored);
+ CreateMonDexNum(entryNum, MON_LIST_X+1, sPokedexView->listVOffset * 2, FALSE);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, MON_LIST_X, sPokedexView->listVOffset * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, MON_LIST_X + 5, sPokedexView->listVOffset * 2);
}
else
{
- CreateMonDexNum(entryNum, MON_LIST_X+1, sPokedexView->listVOffset * 2, ignored);
+ CreateMonDexNum(entryNum, MON_LIST_X+1, sPokedexView->listVOffset * 2, sPokedexView->pokedexList[entryNum].dexNum == 0);
CreateCaughtBall(FALSE, MON_LIST_X, sPokedexView->listVOffset * 2, ignored);
- CreateMonName(0, MON_LIST_X + 5, sPokedexView->listVOffset * 2);
+ CreateMonName(sPokedexView->pokedexList[entryNum].dexNum == 0 ? SHOW_TRIPLE_BULLET : 0, MON_LIST_X + 5, sPokedexView->listVOffset * 2);
}
}
break;
case 2: // Down
ClearMonListEntry(MON_LIST_X, vOffset * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
{
- CreateMonDexNum(entryNum, MON_LIST_X+1, vOffset * 2, ignored);
+ CreateMonDexNum(entryNum, MON_LIST_X+1, vOffset * 2, FALSE);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, MON_LIST_X, vOffset * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, MON_LIST_X + 5, vOffset * 2);
}
else
{
- CreateMonDexNum(entryNum, MON_LIST_X+1, vOffset * 2, ignored);
+ CreateMonDexNum(entryNum, MON_LIST_X+1, vOffset * 2, sPokedexView->pokedexList[entryNum].dexNum == 0);
CreateCaughtBall(FALSE, MON_LIST_X, vOffset * 2, ignored);
- CreateMonName(0, MON_LIST_X + 5, vOffset * 2);
+ CreateMonName(sPokedexView->pokedexList[entryNum].dexNum == 0 ? SHOW_TRIPLE_BULLET : 0, MON_LIST_X + 5, vOffset * 2);
}
}
break;
-static void CreateMonDexNum(u16 entryNum, u8 left, u8 top, u16 unused)
+static void CreateMonDexNum(u16 entryNum, u8 left, u8 top, u16 skip)
{
u8 text[5];
u16 dexNum, offset = 0;
dexNum = sPokedexView->pokedexList[entryNum].dexNum;
if (sPokedexView->dexMode == DEX_MODE_HOENN)
dexNum = NationalToHoennOrder(dexNum);
memcpy(text, sText_No0000, ARRAY_COUNT(sText_No0000));
- if (NATIONAL_DEX_COUNT > 999 && sPokedexView->dexMode != DEX_MODE_HOENN)
+ if (skip)
+ {
+ text[offset++] = EOS;
+ }
+ else
{
- text[0] = CHAR_0 + dexNum / 1000;
- offset++;
+ if (NATIONAL_DEX_COUNT > 999 && sPokedexView->dexMode != DEX_MODE_HOENN)
+ {
+ text[0] = CHAR_0 + dexNum / 1000;
+ offset++;
+ }
+ text[offset++] = CHAR_0 + (dexNum % 1000) / 100;
+ text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) / 10;
+ text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) % 10;
+ text[offset++] = EOS;
}
- text[offset++] = CHAR_0 + (dexNum % 1000) / 100;
- text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) / 10;
- text[offset++] = CHAR_0 + ((dexNum % 1000) % 100) % 10;
- text[offset++] = EOS;
PrintMonDexNumAndName(0, FONT_NARROW, text, left, top);
}
static u8 CreateMonName(u16 num, u8 left, u8 top)
{
const u8 *str;
-
- num = NationalPokedexNumToSpecies(num);
- if (num)
- str = GetSpeciesName(num);
+ if (num == SHOW_TRIPLE_BULLET)
+ {
+ str = sText_TripleBullet;
+ }
else
- str = sText_TenDashes;
+ {
+ num = NationalPokedexNumToSpecies(num);
+ if (num)
+ str = GetSpeciesName(num);
+ else
+ str = sText_TenDashes;
+ }
PrintMonDexNumAndName_2(0, FONT_NARROW, str, left, top);
return StringLength(str);
}