// Includes #include "global.h" #include "constants/species.h" #include "sprite.h" #include "trig.h" #include "pokemon_icon.h" #include "pokemon_storage_system.h" // Static type declarations // Static RAM declarations // Static ROM declarations static void sub_8098E68(struct Sprite *sprite); static void sub_8099388(struct Sprite *sprite, u16 a1); static void sub_80993F4(struct Sprite *sprite); static void sub_80999C4(struct Sprite *sprite); static struct Sprite *PSS_SpawnMonIconSprite(u16 species, u32 personality, s16 x, s16 y, u8 priority, u8 subpriority); static void PSS_DestroyMonIconSprite(struct Sprite *sprite); // .rodata const struct OamData gOamData_83B6F2C; const struct SpriteTemplate gSpriteTemplate_83B6F14 = { 0x000f, 0xdac0, &gOamData_83B6F2C, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; const struct OamData gOamData_83B6F2C = { .size = 2 }; const union AffineAnimCmd gSpriteAffineAnim_83B6F34[] = { AFFINEANIMCMD_FRAME(-2, -2, 0, 120), AFFINEANIMCMD_END }; const union AffineAnimCmd gSpriteAffineAnim_83B6F44[] = { AFFINEANIMCMD_FRAME(16, 16, 0, 0), AFFINEANIMCMD_FRAME(16, 16, 0, 15), AFFINEANIMCMD_END }; const union AffineAnimCmd *const gSpriteAffineAnimTable_83B6F5C[] = { gSpriteAffineAnim_83B6F34, gSpriteAffineAnim_83B6F44 }; // .text u8 get_preferred_box(void) { return gPokemonStorage.currentBox; } void ResetPSSMonIconSprites(void) { u16 i; sub_809D51C(); for (i = 0; i < 40; i++) gPokemonStorageSystemPtr->unk_10d0[i] = 0; for (i = 0; i < 40; i++) gPokemonStorageSystemPtr->unk_1120[i] = 0; for (i = 0; i < 6; i++) gPokemonStorageSystemPtr->unk_1038[i] = NULL; for (i = 0; i < 30; i++) gPokemonStorageSystemPtr->unk_1050[i] = NULL; gPokemonStorageSystemPtr->unk_1034 = NULL; gPokemonStorageSystemPtr->unk_0d5c = 0; } void sub_8098BF0(void) { u32 personality = GetMonData(&gPokemonStorageSystemPtr->unk_25b4, MON_DATA_PERSONALITY); gPokemonStorageSystemPtr->unk_1034 = PSS_SpawnMonIconSprite(GetMonData(&gPokemonStorageSystemPtr->unk_25b4, MON_DATA_SPECIES2), personality, 0, 0, 1, 7); gPokemonStorageSystemPtr->unk_1034->callback = sub_80999C4; } void SpawnBoxIconSprites(u8 boxId) { struct BoxPokemon *box = gPokemonStorage.boxes[boxId]; u16 i; u16 k = 0; for (i = 0; i < 5; i++) { u16 j; for (j = 0; j < 6; j++) { u16 species = GetBoxMonData(box, MON_DATA_SPECIES2); if (species != SPECIES_NONE) gPokemonStorageSystemPtr->unk_1050[k] = PSS_SpawnMonIconSprite(species, GetBoxMonData(box, MON_DATA_PERSONALITY), 24 * j + 0x64, 24 * i + 0x2c, 2, 18 - j); else gPokemonStorageSystemPtr->unk_1050[k] = NULL; box++; k++; } } } void sub_8098D20(u8 monId) { struct BoxPokemon *mon = gPokemonStorage.boxes[get_preferred_box()] + monId; u16 species = GetBoxMonData(mon, MON_DATA_SPECIES2); if (species != SPECIES_NONE) { s16 x = 24 * (monId % 6) + 0x64; s16 y = 24 * (monId / 6) + 0x2c; gPokemonStorageSystemPtr->unk_1050[monId] = PSS_SpawnMonIconSprite(species, GetBoxMonData(mon, MON_DATA_PERSONALITY), x, y, 2, 18 - (monId % 6)); } } static void sub_8098DE0(s16 a0) { u16 monId; for (monId = 0; monId < 30; monId++) { if (gPokemonStorageSystemPtr->unk_1050[monId]) { gPokemonStorageSystemPtr->unk_1050[monId]->data[2] = a0; gPokemonStorageSystemPtr->unk_1050[monId]->data[4] = 1; gPokemonStorageSystemPtr->unk_1050[monId]->callback = sub_8098E68; } } } static void sub_8098E24(struct Sprite *sprite) { if (sprite->data[1] != 0) { sprite->data[1]--; sprite->x += sprite->data[2]; } else { gPokemonStorageSystemPtr->unk_1178--; sprite->x = sprite->data[3]; sprite->callback = SpriteCallbackDummy; } } static void sub_8098E68(struct Sprite *sprite) { if (sprite->data[4] != 0) { sprite->data[4]--; } else { sprite->x += sprite->data[2]; sprite->data[5] = sprite->x + sprite->x2; if (sprite->data[5] < 0x45 || sprite->data[5] > 0xfb) sprite->callback = SpriteCallbackDummy; } } static void sub_8098EA0(u8 col) { u16 i; for (i = 0; i < 5; i++) { if (gPokemonStorageSystemPtr->unk_1050[col]) { PSS_DestroyMonIconSprite(gPokemonStorageSystemPtr->unk_1050[col]); gPokemonStorageSystemPtr->unk_1050[col] = NULL; } col += 6; } } static u8 sub_8098EE0(u8 col, u16 a1, s16 a2) { u16 i; u16 x; u16 y; u8 count; u8 x1; u16 curX; y = 0x2c; x = 24 * col + 0x64; curX = x - (a1 + 1) * a2; x1 = 18 - col; count = 0; for (i = 0; i < 5; i++) { u16 species = GetBoxMonData(gPokemonStorage.boxes[gPokemonStorageSystemPtr->unk_117d] + col, MON_DATA_SPECIES2); if (species != SPECIES_NONE) { gPokemonStorageSystemPtr->unk_1050[col] = PSS_SpawnMonIconSprite(species, GetBoxMonData(gPokemonStorage.boxes[gPokemonStorageSystemPtr->unk_117d] + col, MON_DATA_PERSONALITY), curX, y, 2, x1); if (gPokemonStorageSystemPtr->unk_1050[col]) { gPokemonStorageSystemPtr->unk_1050[col]->data[1] = a1; gPokemonStorageSystemPtr->unk_1050[col]->data[2] = a2; gPokemonStorageSystemPtr->unk_1050[col]->data[3] = x; gPokemonStorageSystemPtr->unk_1050[col]->callback = sub_8098E24; count++; } } col += 6; y += 24; } return count; } void sub_809900C(u8 a0, s8 a1) { gPokemonStorageSystemPtr->unk_117c = 0; gPokemonStorageSystemPtr->unk_117d = a0; gPokemonStorageSystemPtr->unk_117b = a1; gPokemonStorageSystemPtr->unk_1172 = 32; gPokemonStorageSystemPtr->unk_1176 = -6 * a1; gPokemonStorageSystemPtr->unk_1178 = 0; if (a1 > 0) gPokemonStorageSystemPtr->unk_117a = 0; else gPokemonStorageSystemPtr->unk_117a = 5; gPokemonStorageSystemPtr->unk_1174 = 24 * gPokemonStorageSystemPtr->unk_117a + 0x64; sub_8098DE0(gPokemonStorageSystemPtr->unk_1176); } bool8 sub_80990AC(void) { if (gPokemonStorageSystemPtr->unk_1172) gPokemonStorageSystemPtr->unk_1172--; switch (gPokemonStorageSystemPtr->unk_117c) { case 0: gPokemonStorageSystemPtr->unk_1174 += gPokemonStorageSystemPtr->unk_1176; if (gPokemonStorageSystemPtr->unk_1174 < 0x41 || gPokemonStorageSystemPtr->unk_1174 > 0xfb) { sub_8098EA0(gPokemonStorageSystemPtr->unk_117a); gPokemonStorageSystemPtr->unk_1174 += 24 * gPokemonStorageSystemPtr->unk_117b; gPokemonStorageSystemPtr->unk_117c++; } break; case 1: gPokemonStorageSystemPtr->unk_1174 += gPokemonStorageSystemPtr->unk_1176; gPokemonStorageSystemPtr->unk_1178 += sub_8098EE0(gPokemonStorageSystemPtr->unk_117a, gPokemonStorageSystemPtr->unk_1172, gPokemonStorageSystemPtr->unk_1176); if ((gPokemonStorageSystemPtr->unk_117b > 0 && gPokemonStorageSystemPtr->unk_117a == 5) || (gPokemonStorageSystemPtr->unk_117b < 0 && gPokemonStorageSystemPtr->unk_117a == 0)) { gPokemonStorageSystemPtr->unk_117c++; } else { gPokemonStorageSystemPtr->unk_117a += gPokemonStorageSystemPtr->unk_117b; gPokemonStorageSystemPtr->unk_117c = 0; } break; case 2: if (gPokemonStorageSystemPtr->unk_1178 == 0) { gPokemonStorageSystemPtr->unk_1172++; return FALSE; } break; default: return FALSE; } return TRUE; } void sub_8099200(bool8 a0) { u16 count; u16 i; u16 species = GetMonData(gPlayerParty + 0, MON_DATA_SPECIES2); u32 personality = GetMonData(gPlayerParty + 0, MON_DATA_PERSONALITY); gPokemonStorageSystemPtr->unk_1038[0] = PSS_SpawnMonIconSprite(species, personality, 0x68, 0x40, 1, 11); count = 1; for (i = 1; i < PARTY_SIZE; i++) { species = GetMonData(gPlayerParty + i, MON_DATA_SPECIES2); if (species != SPECIES_NONE) { personality = GetMonData(gPlayerParty + i, MON_DATA_PERSONALITY); gPokemonStorageSystemPtr->unk_1038[i] = PSS_SpawnMonIconSprite(species, personality, 0x98, (i - 1) * 24 + 0x10, 1, 11); count++; } else { gPokemonStorageSystemPtr->unk_1038[i] = NULL; } } if (!a0) { for (i = 0; i < count; i++) { // this routine assumes party_compaction has been called gPokemonStorageSystemPtr->unk_1038[i]->y -= 0xa0; gPokemonStorageSystemPtr->unk_1038[i]->invisible = TRUE; } } } void sub_8099310(void) { u16 i; u16 count; gPokemonStorageSystemPtr->unk_1171 = 0; for (i = 0, count = 0; i < PARTY_SIZE; i++) { if (gPokemonStorageSystemPtr->unk_1038[i]) { if (i != count) { sub_8099388(gPokemonStorageSystemPtr->unk_1038[i], count); gPokemonStorageSystemPtr->unk_1038[i] = NULL; gPokemonStorageSystemPtr->unk_1171++; } count++; } } } u8 sub_8099374(void) { return gPokemonStorageSystemPtr->unk_1171; } static void sub_8099388(struct Sprite *sprite, u16 a1) { s16 r3; s16 r4; sprite->data[1] = a1; if (a1 == 0) { r3 = 0x68; r4 = 0x40; } else { r3 = 0x98; r4 = 24 * (a1 - 1) + 0x10; } sprite->data[2] = sprite->x << 3; sprite->data[3] = sprite->y << 3; sprite->data[4] = (r3 * 8 - sprite->data[2]) / 8; sprite->data[5] = (r4 * 8 - sprite->data[3]) / 8; sprite->data[6] = 8; sprite->callback = sub_80993F4; } static void sub_80993F4(struct Sprite *sprite) { if (sprite->data[6]) { sprite->data[2] += sprite->data[4]; sprite->data[3] += sprite->data[5]; sprite->x = sprite->data[2] >> 3; sprite->y = sprite->data[3] >> 3; sprite->data[6]--; } else { if (sprite->data[1] == 0) { sprite->x = 0x68; sprite->y = 0x40; } else { sprite->x = 0x98; sprite->y = (sprite->data[1] - 1) * 24 + 0x10; } sprite->callback = SpriteCallbackDummy; gPokemonStorageSystemPtr->unk_1038[sprite->data[1]] = sprite; gPokemonStorageSystemPtr->unk_1171--; } } void sub_8099480(void) { if (gPokemonStorageSystemPtr->unk_1034) { PSS_DestroyMonIconSprite(gPokemonStorageSystemPtr->unk_1034); gPokemonStorageSystemPtr->unk_1034 = NULL; } } void sub_80994A8(s16 y) { u16 i; for (i = 0; i < PARTY_SIZE; i++) { if (gPokemonStorageSystemPtr->unk_1038[i]) { s16 yy; gPokemonStorageSystemPtr->unk_1038[i]->y += y; yy = gPokemonStorageSystemPtr->unk_1038[i]->y + gPokemonStorageSystemPtr->unk_1038[i]->y2 + gPokemonStorageSystemPtr->unk_1038[i]->centerToCornerVecY; if (yy < -0x10 || yy > 0xb0) gPokemonStorageSystemPtr->unk_1038[i]->invisible = TRUE; else gPokemonStorageSystemPtr->unk_1038[i]->invisible = FALSE; } } } void sub_8099520(u8 a0) { if (gPokemonStorageSystemPtr->unk_1038[a0]) { PSS_DestroyMonIconSprite(gPokemonStorageSystemPtr->unk_1038[a0]); gPokemonStorageSystemPtr->unk_1038[a0] = NULL; } } void sub_809954C(void) { u16 i; for (i = 0; i < PARTY_SIZE; i++) { if (gPokemonStorageSystemPtr->unk_1038[i]) { PSS_DestroyMonIconSprite(gPokemonStorageSystemPtr->unk_1038[i]); gPokemonStorageSystemPtr->unk_1038[i] = NULL; } } } void sub_8099584(u8 a0, u8 a1) { if (a0 == 0) { gPokemonStorageSystemPtr->unk_1034 = gPokemonStorageSystemPtr->unk_1038[a1]; gPokemonStorageSystemPtr->unk_1038[a1] = NULL; } else if (a0 == 1) { gPokemonStorageSystemPtr->unk_1034 = gPokemonStorageSystemPtr->unk_1050[a1]; gPokemonStorageSystemPtr->unk_1050[a1] = NULL; } else { return; } gPokemonStorageSystemPtr->unk_1034->callback = sub_80999C4; gPokemonStorageSystemPtr->unk_1034->oam.priority = 1; gPokemonStorageSystemPtr->unk_1034->subpriority = 7; } void sub_809960C(u8 a0, u8 a1) { if (a0 == 14) { gPokemonStorageSystemPtr->unk_1038[a1] = gPokemonStorageSystemPtr->unk_1034; gPokemonStorageSystemPtr->unk_1038[a1]->oam.priority = 1; gPokemonStorageSystemPtr->unk_1038[a1]->subpriority = 11; } else { gPokemonStorageSystemPtr->unk_1050[a1] = gPokemonStorageSystemPtr->unk_1034; gPokemonStorageSystemPtr->unk_1050[a1]->oam.priority = 2; gPokemonStorageSystemPtr->unk_1050[a1]->subpriority = 18 - (a1 % 6); } gPokemonStorageSystemPtr->unk_1034->callback = SpriteCallbackDummy; gPokemonStorageSystemPtr->unk_1034 = NULL; } void sub_80996B0(u8 a0, u8 a1) { if (a0 == 14) gPokemonStorageSystemPtr->unk_10c8 = gPokemonStorageSystemPtr->unk_1038 + a1; else gPokemonStorageSystemPtr->unk_10c8 = gPokemonStorageSystemPtr->unk_1050 + a1; gPokemonStorageSystemPtr->unk_1034->callback = SpriteCallbackDummy; gPokemonStorageSystemPtr->unk_1170 = 0; } bool8 sub_809971C(void) { if (gPokemonStorageSystemPtr->unk_1170 == 16) return FALSE; gPokemonStorageSystemPtr->unk_1170++; if (gPokemonStorageSystemPtr->unk_1170 & 1) { (*gPokemonStorageSystemPtr->unk_10c8)->y--; gPokemonStorageSystemPtr->unk_1034->y++; } (*gPokemonStorageSystemPtr->unk_10c8)->x2 = gSineTable[gPokemonStorageSystemPtr->unk_1170 * 8] / 16; gPokemonStorageSystemPtr->unk_1034->x2 = -(gSineTable[gPokemonStorageSystemPtr->unk_1170 * 8] / 16); if (gPokemonStorageSystemPtr->unk_1170 == 8) { gPokemonStorageSystemPtr->unk_1034->oam.priority = (*gPokemonStorageSystemPtr->unk_10c8)->oam.priority; gPokemonStorageSystemPtr->unk_1034->subpriority = (*gPokemonStorageSystemPtr->unk_10c8)->subpriority; (*gPokemonStorageSystemPtr->unk_10c8)->oam.priority = 1; (*gPokemonStorageSystemPtr->unk_10c8)->subpriority = 7; } if (gPokemonStorageSystemPtr->unk_1170 == 16) { struct Sprite *sprite = gPokemonStorageSystemPtr->unk_1034; gPokemonStorageSystemPtr->unk_1034 = *(gPokemonStorageSystemPtr->unk_10c8); (*gPokemonStorageSystemPtr->unk_10c8) = sprite; gPokemonStorageSystemPtr->unk_1034->callback = sub_80999C4; (*gPokemonStorageSystemPtr->unk_10c8)->callback = SpriteCallbackDummy; } return TRUE; } void sub_809981C(u8 mode, u8 idx) { switch (mode) { case 0: gPokemonStorageSystemPtr->unk_10cc = gPokemonStorageSystemPtr->unk_1038 + idx; break; case 1: gPokemonStorageSystemPtr->unk_10cc = gPokemonStorageSystemPtr->unk_1050 + idx; break; case 2: gPokemonStorageSystemPtr->unk_10cc = &gPokemonStorageSystemPtr->unk_1034; break; default: return; } if (*gPokemonStorageSystemPtr->unk_10cc) { InitSpriteAffineAnim(*gPokemonStorageSystemPtr->unk_10cc); (*gPokemonStorageSystemPtr->unk_10cc)->oam.affineMode = ST_OAM_AFFINE_NORMAL; (*gPokemonStorageSystemPtr->unk_10cc)->affineAnims = gSpriteAffineAnimTable_83B6F5C; StartSpriteAffineAnim(*gPokemonStorageSystemPtr->unk_10cc, 0); } } bool8 sub_80998D8(void) { if (*gPokemonStorageSystemPtr->unk_10cc == NULL || (*gPokemonStorageSystemPtr->unk_10cc)->invisible) return FALSE; if ((*gPokemonStorageSystemPtr->unk_10cc)->affineAnimEnded) { (*gPokemonStorageSystemPtr->unk_10cc)->invisible = TRUE; } return TRUE; } void sub_8099920(void) { if (*gPokemonStorageSystemPtr->unk_10cc) { FreeOamMatrix((*gPokemonStorageSystemPtr->unk_10cc)->oam.matrixNum); PSS_DestroyMonIconSprite(*gPokemonStorageSystemPtr->unk_10cc); *gPokemonStorageSystemPtr->unk_10cc = NULL; } } void sub_8099958(void) { if (*gPokemonStorageSystemPtr->unk_10cc) { (*gPokemonStorageSystemPtr->unk_10cc)->invisible = FALSE; StartSpriteAffineAnim(*gPokemonStorageSystemPtr->unk_10cc, 1); } } bool8 sub_8099990(void) { if (gPokemonStorageSystemPtr->unk_10cc == NULL) return FALSE; if ((*gPokemonStorageSystemPtr->unk_10cc)->affineAnimEnded) gPokemonStorageSystemPtr->unk_10cc = NULL; return TRUE; } static void sub_80999C4(struct Sprite *sprite) { sprite->x = gPokemonStorageSystemPtr->unk_11c0->x; sprite->y = gPokemonStorageSystemPtr->unk_11c0->y + gPokemonStorageSystemPtr->unk_11c0->y2 + 4; } static u16 PSS_LoadSpeciesIconGfx(u16 a0) { u16 i; u16 retval; for (i = 0; i < 40; i++) { if (gPokemonStorageSystemPtr->unk_1120[i] == a0) break; } if (i == 40) { for (i = 0; i < 40; i++) { if (gPokemonStorageSystemPtr->unk_1120[i] == 0) break; } } if (i != 40) { gPokemonStorageSystemPtr->unk_1120[i] = a0; gPokemonStorageSystemPtr->unk_10d0[i]++; retval = i * 16; CpuCopy32(gMonIconTable[a0], BG_CHAR_ADDR(4) + 32 * retval, 0x200); return retval; } return 0xFFFF; } static void PSS_ForgetSpeciesIcon(u16 a0) { u16 i; for (i = 0; i < 40; i++) { if (gPokemonStorageSystemPtr->unk_1120[i] == a0) { if (--gPokemonStorageSystemPtr->unk_10d0[i] == 0) gPokemonStorageSystemPtr->unk_1120[i] = 0; break; } } } static struct Sprite *PSS_SpawnMonIconSprite(u16 species, u32 personality, s16 x, s16 y, u8 priority, u8 subpriority) { struct SpriteTemplate template = gSpriteTemplate_83B6F14; u16 tileNum; u8 spriteId; species = mon_icon_convert_unown_species_id(species, personality); template.paletteTag = 0xdac0 + gMonIconPaletteIndices[species]; tileNum = PSS_LoadSpeciesIconGfx(species); if (tileNum == 0xFFFF) return NULL; spriteId = CreateSprite(&template, x, y, subpriority); if (spriteId == MAX_SPRITES) { PSS_ForgetSpeciesIcon(species); return NULL; } gSprites[spriteId].oam.tileNum = tileNum; gSprites[spriteId].oam.priority = priority; gSprites[spriteId].data[0] = species; return gSprites + spriteId; } static void PSS_DestroyMonIconSprite(struct Sprite *sprite) { PSS_ForgetSpeciesIcon(sprite->data[0]); DestroySprite(sprite); }