wild_pokemon_area and pokedex_area_markers

This commit is contained in:
PikalaxALT
2019-10-04 12:55:48 -04:00
parent 0cf4c9f25c
commit 1f6f5f369b
21 changed files with 615 additions and 807 deletions
+238
View File
@@ -0,0 +1,238 @@
#include "global.h"
#include "malloc.h"
#include "bg.h"
#include "decompress.h"
#include "gpu_regs.h"
#include "palette.h"
#include "task.h"
#include "wild_pokemon_area.h"
#include "pokedex_area_markers.h"
static const u16 sMarkerPal[] = INCBIN_U16("data/pokedex_area_markers/marker.gbapal");
static const u32 sMarkerTiles[] = INCBIN_U32("data/pokedex_area_markers/marker.4bpp.lz");
static const struct Subsprite sSubsprite0 = {
.size = ST_OAM_SIZE_0,
.shape = ST_OAM_SQUARE,
.priority = 1,
.tileOffset = 0
};
static const struct Subsprite sSubsprite1 = {
.size = ST_OAM_SIZE_0,
.shape = ST_OAM_H_RECTANGLE,
.priority = 1,
.tileOffset = 1
};
static const struct Subsprite sSubsprite2 = {
.size = ST_OAM_SIZE_0,
.shape = ST_OAM_V_RECTANGLE,
.priority = 1,
.tileOffset = 3
};
static const struct Subsprite sSubsprite3 = {
.size = ST_OAM_SIZE_2,
.shape = ST_OAM_H_RECTANGLE,
.priority = 1,
.tileOffset = 5
};
static const struct Subsprite sSubsprite4 = {
.size = ST_OAM_SIZE_2,
.shape = ST_OAM_V_RECTANGLE,
.priority = 1,
.tileOffset = 13
};
static const struct Subsprite sSubsprite5 = {
.size = ST_OAM_SIZE_2,
.shape = ST_OAM_H_RECTANGLE,
.priority = 1,
.tileOffset = 21
};
static const struct Subsprite sSubsprite6 = {
.size = ST_OAM_SIZE_2,
.shape = ST_OAM_V_RECTANGLE,
.priority = 1,
.tileOffset = 29
};
static const struct Subsprite *const sSubsprites[] = {
&sSubsprite0,
&sSubsprite1,
&sSubsprite2,
&sSubsprite3,
&sSubsprite4,
&sSubsprite5,
&sSubsprite6
};
static const s8 sSubspriteLookupTable[][4] = {
{ 0, 0x00, 0x00 },
{ 0, 0x36, 0x2c },
{ 0, 0x36, 0x1c },
{ 0, 0x36, 0x0c },
{ 0, 0x5c, 0x0c },
{ 0, 0x6e, 0x18 },
{ 0, 0x5c, 0x24 },
{ 0, 0x4c, 0x18 },
{ 0, 0x4e, 0x34 },
{ 0, 0x36, 0x3e },
{ 0, 0x2a, 0x02 },
{ 0, 0x5c, 0x18 },
{ 2, 0x36, 0x20 },
{ 2, 0x36, 0x10 },
{ 1, 0x3d, 0x0c },
{ 1, 0x4d, 0x0c },
{ 0, 0x5c, 0x12 },
{ 0, 0x5c, 0x1e },
{ 0, 0x54, 0x18 },
{ 1, 0x62, 0x18 },
{ 1, 0x62, 0x0c },
{ 2, 0x6e, 0x0c },
{ 1, 0x62, 0x24 },
{ 4, 0x6a, 0x19 },
{ 1, 0x64, 0x2e },
{ 2, 0x5e, 0x2d },
{ 1, 0x55, 0x34 },
{ 0, 0x44, 0x18 },
{ 4, 0x3e, 0x1a },
{ 1, 0x40, 0x34 },
{ 0, 0x4e, 0x3c },
{ 3, 0x37, 0x3a },
{ 2, 0x36, 0x32 },
{ 1, 0x28, 0x1c },
{ 4, 0x26, 0x04 },
{ 0, 0x5c, 0x04 },
{ 3, 0x5a, 0xfe },
{ 0, 0x33, 0x14 },
{ 1, 0x3d, 0x12 },
{ 0, 0x48, 0x08 },
{ 0, 0x57, 0x08 },
{ 0, 0x70, 0x0e },
{ 0, 0x71, 0x14 },
{ 0, 0x71, 0x19 },
{ 1, 0x4e, 0x2c },
{ 0, 0x41, 0x3c },
{ 0, 0x34, 0x3e },
{ 0, 0x2d, 0x07 },
{ 0, 0x0a, 0x0a },
{ 0, 0x0c, 0x23 },
{ 0, 0x0e, 0x34 },
{ 0, 0x0c, 0x54 },
{ 0, 0x2d, 0x51 },
{ 0, 0x4c, 0x54 },
{ 0, 0x68, 0x52 },
{ 2, 0x0e, 0x02 },
{ 0, 0x0a, 0x0f },
{ 0, 0x0c, 0x1d },
{ 1, 0x02, 0x34 },
{ 1, 0x0c, 0x38 },
{ 1, 0x2c, 0x4a },
{ 1, 0x24, 0x4e },
{ 2, 0x30, 0x50 },
{ 2, 0x34, 0x56 },
{ 0, 0x48, 0x4a },
{ 1, 0x48, 0x4e },
{ 2, 0x51, 0x50 },
{ 0, 0x4c, 0x5c },
{ 0, 0x68, 0x4b },
{ 0, 0x68, 0x56 },
{ 2, 0x6c, 0x53 },
{ 3, 0x60, 0x5a },
{ 0, 0x0e, 0x01 },
{ 0, 0x05, 0x34 },
{ 0, 0x0d, 0x50 },
{ 0, 0x36, 0x4a },
{ 0, 0x45, 0x49 },
{ 0, 0x4c, 0x4d },
{ 0, 0x49, 0x5f },
{ 3, 0x60, 0x5a }
};
static void Task_ShowAreaMarkers(u8 taskId)
{
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
gSprites[data->spr_id].invisible = FALSE;
}
u8 sub_8134230(u16 species, u16 tilesTag, u8 palIdx, u8 y)
{
struct SpriteTemplate spriteTemplate;
struct CompressedSpriteSheet spriteSheet;
u8 taskId;
struct PAM_TaskData * data;
struct Subsprite * subsprites;
spriteSheet.data = sMarkerTiles;
spriteSheet.size = 0x4A0;
spriteSheet.tag = tilesTag;
LoadCompressedSpriteSheet(&spriteSheet);
LoadPalette(sMarkerPal, 0x100 + 16 * palIdx, 0x20);
taskId = CreateTask(Task_ShowAreaMarkers, 0);
data = (void *)gTasks[taskId].data;
data->unk_0C = 0;
data->tilesTag = tilesTag;
data->unk_10 = 0xFFFF;
subsprites = Alloc(120 * sizeof(struct Subsprite));
data->buffer = subsprites;
data->subsprites.subsprites = subsprites;
data->subsprites.subspriteCount = BuildPokedexAreaSubspriteBuffer(species, subsprites);
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_BD);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8));
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_WININ, 0x1F1F);
SetGpuReg(REG_OFFSET_WINOUT, 0x2F3D);
spriteTemplate = gDummySpriteTemplate;
spriteTemplate.tileTag = tilesTag;
data->spr_id = CreateSprite(&spriteTemplate, 104, y + 32, 0);
SetSubspriteTables(&gSprites[data->spr_id], &data->subsprites);
gSprites[data->spr_id].oam.objMode = ST_OAM_OBJ_WINDOW;
gSprites[data->spr_id].oam.paletteNum = palIdx;
gSprites[data->spr_id].subspriteTableNum = 0;
gSprites[data->spr_id].invisible = TRUE;
HideBg(1);
SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
FillBgTilemapBufferRect_Palette0(1, 0x00F, 0, 0, 30, 20);
CopyBgTilemapBufferToVram(1);
ShowBg(1);
return taskId;
}
void sub_81343F4(u8 taskId)
{
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
FreeSpriteTilesByTag(data->tilesTag);
DestroySprite(&gSprites[data->spr_id]);
Free(data->buffer);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_WININ, 0x1F1F);
SetGpuReg(REG_OFFSET_WINOUT, 0x1F1F);
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
HideBg(1);
SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 2);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
CopyBgTilemapBufferToVram(1);
ShowBg(1);
DestroyTask(taskId);
}
void SetAreaSubsprite(s32 i, s32 whichArea, struct Subsprite * subsprites)
{
subsprites[i] = *sSubsprites[sSubspriteLookupTable[whichArea][0]];
subsprites[i].x = sSubspriteLookupTable[whichArea][1];
subsprites[i].y = sSubspriteLookupTable[whichArea][2];
}
u8 sub_81344E0(u8 taskId)
{
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
return data->subsprites.subspriteCount;
}
+308
View File
@@ -0,0 +1,308 @@
#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 * lut_i_p, u16 * table_idx_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 < 3u; 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 * lut_i_p, u16 * table_idx_p)
{
s32 i;
for (i = *lut_i_p; i < count; i++)
{
if (lut[i][0] == mapSecId)
{
*table_idx_p = lut[i][1];
*lut_i_p = i + 1;
return TRUE;
}
}
return FALSE;
}