mirror of
https://github.com/pret/pokefirered.git
synced 2026-06-02 22:04:27 -05:00
309 lines
9.1 KiB
C
309 lines
9.1 KiB
C
#include "global.h"
|
|
#include "field_specials.h"
|
|
#include "event_data.h"
|
|
#include "wild_encounter.h"
|
|
#include "roamer.h"
|
|
#include "overworld.h"
|
|
#include "pokedex_area_markers.h"
|
|
#include "constants/vars.h"
|
|
#include "constants/region_map.h"
|
|
#include "constants/species.h"
|
|
|
|
struct SeviiDexArea
|
|
{
|
|
const u16 (*lut)[2];
|
|
s32 count;
|
|
};
|
|
|
|
struct RoamerPair
|
|
{
|
|
u16 roamer;
|
|
u16 starter;
|
|
};
|
|
|
|
static s32 GetRoamerIndex(u16 species);
|
|
static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites);
|
|
static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species);
|
|
static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count);
|
|
static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header);
|
|
static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p);
|
|
|
|
static const u16 sDexAreas_Kanto[][2] = {
|
|
{ MAPSEC_PALLET_TOWN, 1 },
|
|
{ MAPSEC_VIRIDIAN_CITY, 2 },
|
|
{ MAPSEC_PEWTER_CITY, 3 },
|
|
{ MAPSEC_CERULEAN_CITY, 4 },
|
|
{ MAPSEC_LAVENDER_TOWN, 5 },
|
|
{ MAPSEC_VERMILION_CITY, 6 },
|
|
{ MAPSEC_CELADON_CITY, 7 },
|
|
{ MAPSEC_FUCHSIA_CITY, 8 },
|
|
{ MAPSEC_CINNABAR_ISLAND, 9 },
|
|
{ MAPSEC_INDIGO_PLATEAU, 10 },
|
|
{ MAPSEC_SAFFRON_CITY, 11 },
|
|
{ MAPSEC_ROUTE_4_FLYDUP, 15 },
|
|
{ MAPSEC_ROUTE_10_FLYDUP, 21 },
|
|
{ MAPSEC_ROUTE_1, 12 },
|
|
{ MAPSEC_ROUTE_2, 13 },
|
|
{ MAPSEC_ROUTE_3, 14 },
|
|
{ MAPSEC_ROUTE_4, 15 },
|
|
{ MAPSEC_ROUTE_5, 16 },
|
|
{ MAPSEC_ROUTE_6, 17 },
|
|
{ MAPSEC_ROUTE_7, 18 },
|
|
{ MAPSEC_ROUTE_8, 19 },
|
|
{ MAPSEC_ROUTE_9, 20 },
|
|
{ MAPSEC_ROUTE_10, 21 },
|
|
{ MAPSEC_ROUTE_11, 22 },
|
|
{ MAPSEC_ROUTE_12, 23 },
|
|
{ MAPSEC_ROUTE_13, 24 },
|
|
{ MAPSEC_ROUTE_14, 25 },
|
|
{ MAPSEC_ROUTE_15, 26 },
|
|
{ MAPSEC_ROUTE_16, 27 },
|
|
{ MAPSEC_ROUTE_17, 28 },
|
|
{ MAPSEC_ROUTE_18, 29 },
|
|
{ MAPSEC_ROUTE_19, 30 },
|
|
{ MAPSEC_ROUTE_20, 31 },
|
|
{ MAPSEC_ROUTE_21, 32 },
|
|
{ MAPSEC_ROUTE_22, 33 },
|
|
{ MAPSEC_ROUTE_23, 34 },
|
|
{ MAPSEC_ROUTE_24, 35 },
|
|
{ MAPSEC_ROUTE_25, 36 },
|
|
{ MAPSEC_VIRIDIAN_FOREST, 37 },
|
|
{ MAPSEC_MT_MOON, 39 },
|
|
{ MAPSEC_S_S_ANNE, 6 },
|
|
{ MAPSEC_UNDERGROUND_PATH, 11 },
|
|
{ MAPSEC_UNDERGROUND_PATH_2, 11 },
|
|
{ MAPSEC_DIGLETTS_CAVE, 38 },
|
|
{ MAPSEC_KANTO_VICTORY_ROAD, 47 },
|
|
{ MAPSEC_ROCKET_HIDEOUT, 7 },
|
|
{ MAPSEC_SILPH_CO, 11 },
|
|
{ MAPSEC_POKEMON_MANSION, 46 },
|
|
{ MAPSEC_KANTO_SAFARI_ZONE, 44 },
|
|
{ MAPSEC_POKEMON_LEAGUE, 47 },
|
|
{ MAPSEC_ROCK_TUNNEL, 41 },
|
|
{ MAPSEC_SEAFOAM_ISLANDS, 45 },
|
|
{ MAPSEC_POKEMON_TOWER, 43 },
|
|
{ MAPSEC_CERULEAN_CAVE, 40 },
|
|
{ MAPSEC_POWER_PLANT, 42 }
|
|
};
|
|
|
|
static const u16 sDexAreas_Sevii1[][2] = {
|
|
{ MAPSEC_KINDLE_ROAD, 55 },
|
|
{ MAPSEC_TREASURE_BEACH, 56 },
|
|
{ MAPSEC_ONE_ISLAND, 48 },
|
|
{ MAPSEC_MT_EMBER, 72 }
|
|
};
|
|
|
|
static const u16 sDexAreas_Sevii2[][2] = {
|
|
{ MAPSEC_CAPE_BRINK, 57 },
|
|
{ MAPSEC_TWO_ISLAND, 49 }
|
|
};
|
|
|
|
static const u16 sDexAreas_Sevii3[][2] = {
|
|
{ MAPSEC_BOND_BRIDGE, 58 },
|
|
{ MAPSEC_THREE_ISLE_PORT, 59 },
|
|
{ MAPSEC_THREE_ISLAND, 50 },
|
|
{ MAPSEC_BERRY_FOREST, 73 },
|
|
{ MAPSEC_THREE_ISLE_PATH, 59 }
|
|
};
|
|
|
|
static const u16 sDexAreas_Sevii4[][2] = {
|
|
{ MAPSEC_FOUR_ISLAND, 51 },
|
|
{ MAPSEC_ICEFALL_CAVE, 74 }
|
|
};
|
|
|
|
static const u16 sDexAreas_Sevii5[][2] = {
|
|
{ MAPSEC_RESORT_GORGEOUS, 60 },
|
|
{ MAPSEC_WATER_LABYRINTH, 61 },
|
|
{ MAPSEC_FIVE_ISLE_MEADOW, 62 },
|
|
{ MAPSEC_MEMORIAL_PILLAR, 63 },
|
|
{ MAPSEC_FIVE_ISLAND, 52 },
|
|
{ MAPSEC_ROCKET_WAREHOUSE, 62 },
|
|
{ MAPSEC_LOST_CAVE, 75 }
|
|
};
|
|
|
|
static const u16 sDexAreas_Sevii6[][2] = {
|
|
{ MAPSEC_OUTCAST_ISLAND, 64 },
|
|
{ MAPSEC_GREEN_PATH, 65 },
|
|
{ MAPSEC_WATER_PATH, 66 },
|
|
{ MAPSEC_RUIN_VALLEY, 67 },
|
|
{ MAPSEC_DOTTED_HOLE, 78 },
|
|
{ MAPSEC_PATTERN_BUSH, 77 },
|
|
{ MAPSEC_ALTERING_CAVE, 76 }
|
|
};
|
|
|
|
static const u16 sDexAreas_Sevii7[][2] = {
|
|
{ MAPSEC_TRAINER_TOWER, 68 },
|
|
{ MAPSEC_CANYON_ENTRANCE, 69 },
|
|
{ MAPSEC_SEVAULT_CANYON, 70 },
|
|
{ MAPSEC_TANOBY_RUINS, 71 },
|
|
{ MAPSEC_MONEAN_CHAMBER, 79 },
|
|
{ MAPSEC_LIPTOO_CHAMBER, 79 },
|
|
{ MAPSEC_WEEPTH_CHAMBER, 79 },
|
|
{ MAPSEC_DILFORD_CHAMBER, 79 },
|
|
{ MAPSEC_SCUFIB_CHAMBER, 79 },
|
|
{ MAPSEC_RIXY_CHAMBER, 79 },
|
|
{ MAPSEC_VIAPOIS_CHAMBER, 79 }
|
|
};
|
|
|
|
static const struct SeviiDexArea sSeviiDexAreas[] = {
|
|
{ sDexAreas_Sevii1, 4 },
|
|
{ sDexAreas_Sevii2, 2 },
|
|
{ sDexAreas_Sevii3, 5 },
|
|
{ sDexAreas_Sevii4, 2 },
|
|
{ sDexAreas_Sevii5, 7 },
|
|
{ sDexAreas_Sevii6, 7 },
|
|
{ sDexAreas_Sevii7, 11 }
|
|
};
|
|
|
|
static const struct RoamerPair sRoamerPairs[] = {
|
|
{ SPECIES_ENTEI, SPECIES_BULBASAUR },
|
|
{ SPECIES_SUICUNE, SPECIES_CHARMANDER },
|
|
{ SPECIES_RAIKOU, SPECIES_SQUIRTLE }
|
|
};
|
|
|
|
s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites)
|
|
{
|
|
s32 areaCount;
|
|
s32 j;
|
|
s32 mapSecId;
|
|
u16 dexAreaSubspriteIdx;
|
|
s32 dexAreaEntryLUTidx;
|
|
s32 seviiAreas;
|
|
s32 alteringCaveCount;
|
|
s32 alteringCaveNum;
|
|
s32 i;
|
|
|
|
if (GetRoamerIndex(species) >= SPECIES_NONE)
|
|
{
|
|
return CountRoamerNests(species, subsprites);
|
|
}
|
|
|
|
seviiAreas = GetUnlockedSeviiAreas();
|
|
alteringCaveCount = 0;
|
|
alteringCaveNum = VarGet(VAR_0x4024);
|
|
if (alteringCaveNum > 8)
|
|
alteringCaveNum = 0;
|
|
for (i = 0, areaCount = 0; gWildMonHeaders[i].mapGroup != 0xFF; i++)
|
|
{
|
|
mapSecId = GetMapSecIdFromWildMonHeader(&gWildMonHeaders[i]);
|
|
if (mapSecId == MAPSEC_ALTERING_CAVE)
|
|
{
|
|
alteringCaveCount++;
|
|
if (alteringCaveNum != alteringCaveCount - 1)
|
|
continue;
|
|
}
|
|
if (PokemonInAnyEncounterTableInMap(&gWildMonHeaders[i], species))
|
|
{
|
|
dexAreaEntryLUTidx = 0;
|
|
while (TryGetMapSecPokedexAreaEntry(mapSecId, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx))
|
|
{
|
|
if (dexAreaSubspriteIdx != 0)
|
|
{
|
|
SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites);
|
|
}
|
|
}
|
|
for (j = 0; j < NELEMS(sSeviiDexAreas); j++)
|
|
{
|
|
if ((seviiAreas >> j) & 1)
|
|
{
|
|
dexAreaEntryLUTidx = 0;
|
|
while (TryGetMapSecPokedexAreaEntry(mapSecId, sSeviiDexAreas[j].lut, sSeviiDexAreas[j].count, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx))
|
|
{
|
|
if (dexAreaSubspriteIdx != 0)
|
|
{
|
|
SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return areaCount;
|
|
}
|
|
|
|
static s32 GetRoamerIndex(u16 species)
|
|
{
|
|
s32 i;
|
|
for (i = 0; i < NELEMS(sRoamerPairs); i++)
|
|
{
|
|
if (sRoamerPairs[i].roamer == species)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites)
|
|
{
|
|
u16 roamerLocation;
|
|
s32 roamerIdx;
|
|
u16 dexAreaSubspriteIdx;
|
|
s32 dexAreaEntryLUTidx;
|
|
|
|
roamerIdx = GetRoamerIndex(species);
|
|
if (roamerIdx < 0)
|
|
return 0;
|
|
if (sRoamerPairs[roamerIdx].starter != ScrSpecial_GetStarter())
|
|
return 0;
|
|
roamerLocation = GetRoamerLocationMapSectionId();
|
|
dexAreaEntryLUTidx = 0;
|
|
if (TryGetMapSecPokedexAreaEntry(roamerLocation, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx))
|
|
{
|
|
if (dexAreaSubspriteIdx != 0)
|
|
{
|
|
SetAreaSubsprite(0, dexAreaSubspriteIdx, subsprites);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species)
|
|
{
|
|
if (PokemonInEncounterTable(data->landMonsInfo, species, 12))
|
|
return TRUE;
|
|
if (PokemonInEncounterTable(data->waterMonsInfo, species, 5))
|
|
return TRUE;
|
|
if (PokemonInEncounterTable(data->fishingMonsInfo, species, 12))
|
|
return TRUE;
|
|
if (PokemonInEncounterTable(data->rockSmashMonsInfo, species, 5))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * info, s32 species, s32 count)
|
|
{
|
|
s32 i;
|
|
if (info != NULL)
|
|
{
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
if (info->wildPokemon[i].species == species)
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header)
|
|
{
|
|
return get_mapheader_by_bank_and_number(header->mapGroup, header->mapNum)->regionMapSectionId;
|
|
}
|
|
|
|
static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p)
|
|
{
|
|
s32 i;
|
|
for (i = *lutIdx_p; i < count; i++)
|
|
{
|
|
if (lut[i][0] == mapSecId)
|
|
{
|
|
*tableIdx_p = lut[i][1];
|
|
*lutIdx_p = i + 1;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|