#include "global.h" #include "battle.h" #include "battle_factory_screen.h" #include "battle_factory.h" #include "sprite.h" #include "event_data.h" #include "overworld.h" #include "random.h" #include "battle_tower.h" #include "text.h" #include "palette.h" #include "task.h" #include "main.h" #include "malloc.h" #include "bg.h" #include "gpu_regs.h" #include "string_util.h" #include "international_string_util.h" #include "window.h" #include "data.h" #include "decompress.h" #include "pokemon_summary_screen.h" #include "sound.h" #include "pokedex.h" #include "util.h" #include "trainer_pokemon_sprites.h" #include "starter_choose.h" #include "strings.h" #include "graphics.h" #include "constants/battle_frontier.h" #include "constants/songs.h" #include "constants/rgb.h" // Select_ refers to the first Pokemon selection screen where you choose your initial 3 rental Pokemon. // Swap_ refers to the subsequent selection screens where you can swap a Pokemon with one from the beaten trainer // Note that, generally, "Action" will refer to the immediate actions that can be taken on each screen, // i.e. selecting a pokemon or selecting the Cancel button // The "Options menu" will refer to the popup menu that shows when some actions have been selected #define SWAP_PLAYER_SCREEN 0 // The screen where the player selects which of their pokemon to swap away #define SWAP_ENEMY_SCREEN 1 // The screen where the player selects which new pokemon from the defeated party to swap for #define SELECTABLE_MONS_COUNT 6 #define PALTAG_BALL_GRAY 0x64 #define PALTAG_BALL_SELECTED 0x65 #define PALTAG_INTERFACE 0x66 #define PALTAG_MON_PIC_BG 0x67 #define GFXTAG_BALL 0x64 #define GFXTAG_ARROW 0x65 #define GFXTAG_MENU_HIGHLIGHT_LEFT 0x66 #define GFXTAG_MENU_HIGHLIGHT_RIGHT 0x67 #define GFXTAG_ACTION_BOX_LEFT 0x68 #define GFXTAG_ACTION_BOX_RIGHT 0x69 #define GFXTAG_ACTION_HIGHLIGHT_LEFT 0x6A #define GFXTAG_ACTION_HIGHLIGHT_MIDDLE 0x6B #define GFXTAG_ACTION_HIGHLIGHT_RIGHT 0x6C #define GFXTAG_MON_PIC_BG_ANIM 0x6D // Tasks in this file universally use data[0] as a state for switches #define tState data[0] // States for both Select/Swap versions of Task_FadeSpeciesName enum { FADESTATE_INIT, FADESTATE_RUN, FADESTATE_DELAY }; struct FactorySelectableMon { u16 monId; u16 ballSpriteId; u8 selectedId; // 0 - not selected, 1 - first pokemon, 2 - second pokemon, 3 - third pokemon struct Pokemon monData; }; struct FactoryMonPic { u8 monSpriteId; u8 bgSpriteId; }; struct FactorySelectScreen { u8 menuCursorPos; u8 menuCursor1SpriteId; u8 menuCursor2SpriteId; u8 cursorPos; u8 cursorSpriteId; u8 selectingMonsState; bool8 fromSummaryScreen; u8 yesNoCursorPos; u8 unused; struct FactorySelectableMon mons[SELECTABLE_MONS_COUNT]; struct FactoryMonPic monPics[FRONTIER_PARTY_SIZE]; // Array so all chosen mons can be shown at once bool8 monPicAnimating; u8 fadeSpeciesNameTaskId; bool8 fadeSpeciesNameActive; u16 speciesNameColorBackup; bool8 fadeSpeciesNameFadeOut; u8 fadeSpeciesNameCoeffDelay; u8 fadeSpeciesNameCoeff; u8 faceSpeciesNameDelay; }; struct SwapScreenAction { u8 id; void (*func)(u8 taskId); }; struct FactorySwapScreen { u8 menuCursorPos; u8 menuCursor1SpriteId; u8 menuCursor2SpriteId; u8 cursorPos; u8 cursorSpriteId; u8 ballSpriteIds[FRONTIER_PARTY_SIZE]; u8 pkmnForSwapButtonSpriteIds[2][3]; // For this and sprite ID array below, [0][i] is the button background, [1][i] is the button highlight u8 cancelButtonSpriteIds[2][2]; u8 playerMonId; u8 enemyMonId; bool8 inEnemyScreen; bool8 fromSummaryScreen; u8 yesNoCursorPos; u8 actionsCount; const struct SwapScreenAction *actionsData; u8 unused1C[4]; bool8 monSwapped; u8 fadeSpeciesNameTaskId; bool8 fadeSpeciesNameActive; u16 speciesNameColorBackup; bool8 fadeSpeciesNameFadeOut; u8 fadeSpeciesNameCoeffDelay; u8 fadeSpeciesNameCoeff; u8 faceSpeciesNameDelay; struct FactoryMonPic monPic; bool8 monPicAnimating; }; static void SpriteCB_Pokeball(struct Sprite *); static void SpriteCB_OpenMonPic(struct Sprite *); static void OpenMonPic(u8 *, bool8 *, bool8); static void HideMonPic(struct FactoryMonPic, bool8 *); static void CloseMonPic(struct FactoryMonPic, bool8 *, bool8); static void Task_OpenMonPic(u8); static void Task_CloseMonPic(u8); // Select screen static void CB2_InitSelectScreen(void); static void Select_SetWinRegs(s16, s16, s16, s16); static void Select_InitMonsData(void); static void Select_InitAllSprites(void); static void Select_ReshowMonSprite(void); static void Select_PrintSelectMonString(void); static void Select_PrintMonSpecies(void); static void Select_PrintMonCategory(void); static void Select_PrintRentalPkmnString(void); static void Select_CopyMonsToPlayerParty(void); static void sub_819C4B4(void); static void Select_ShowYesNoOptions(void); static void sub_819C568(void); static void Select_ShowMenuOptions(void); static void Select_PrintMenuOptions(void); static void Select_PrintYesNoOptions(void); static void Select_Task_FadeSpeciesName(u8); static void sub_819C1D0(u8); static void Select_Task_HandleChooseMons(u8); static void Select_Task_HandleMenu(u8); static void CreateFrontierFactorySelectableMons(u8); static void CreateSlateportTentSelectableMons(u8); static void Select_SetBallSpritePaletteNum(u8); static void sub_819B958(u8); static u8 Select_RunMenuOptionFunc(void); static u8 sub_819BC9C(void); static u8 Select_OptionSummary(void); static u8 Select_OptionOthers(void); static u8 Select_OptionRentDeselect(void); static bool32 Select_AreSpeciesValid(u16); // Swap screen static void CB2_InitSwapScreen(void); static void Swap_DestroyAllSprites(void); static void Swap_ShowYesNoOptions(void); static void Swap_HideActionButtonHighlights(void); static void sub_819EAC0(void); static void Swap_UpdateYesNoCursorPosition(s8); static void Swap_UpdateMenuCursorPosition(s8); static void Swap_ErasePopupMenu(u8); static void sub_819D770(u8); static void Swap_Task_HandleChooseMons(u8); static void sub_819D588(u8); static void Swap_PrintOnInfoWindow(const u8 *); static void Swap_ShowMenuOptions(void); static void Swap_PrintMenuOptions(void); static void Swap_PrintYesNoOptions(void); static void Swap_PrintMonSpecies(void); static void Swap_PrintMonSpecies2(void); static void Swap_PrintMonSpecies3(void); static void Swap_PrintMonCategory(void); static void Swap_InitAllSprites(void); static void Swap_PrintPkmnSwap(void); static void sub_819EADC(void); static void sub_819EAF8(void); static void Swap_ShowSummaryMonSprite(void); static void Swap_UpdateActionCursorPosition(s8); static void Swap_UpdateBallCursorPosition(s8); static void Swap_RunMenuOptionFunc(u8); static void Swap_OptionSwap(u8); static void Swap_OptionSummary(u8); static void Swap_OptionRechoose(u8); static void Swap_RunActionFunc(u8); static void Swap_TaskCantHaveSameMons(u8); static void Swap_CreateMonSprite(void); static void Swap_PrintActionStrings(void); static void Swap_PrintActionStrings2(void); static void Swap_PrintOneActionString(u8); static void Swap_InitActions(u8); static void Swap_HighlightActionButton(u8); static bool8 Swap_AlreadyHasSameSpecies(u8); static void Swap_ActionMon(u8); static void Swap_ActionCancel(u8); static void Swap_ActionPkmnForSwap(u8); // Ewram variables static EWRAM_DATA u8 *sSelectMenuTilesetBuffer = NULL; static EWRAM_DATA u8 *sSelectMonPicBgTilesetBuffer = NULL; static EWRAM_DATA u8 *sSelectMenuTilemapBuffer = NULL; static EWRAM_DATA u8 *sSelectMonPicBgTilemapBuffer = NULL; static EWRAM_DATA struct Pokemon *sFactorySelectMons = NULL; static EWRAM_DATA u8 *sSwapMenuTilesetBuffer = NULL; static EWRAM_DATA u8 *sSwapMonPicBgTilesetBuffer = NULL; static EWRAM_DATA u8 *sSwapMenuTilemapBuffer = NULL; static EWRAM_DATA u8 *sSwapMonPicBgTilemapBuffer = NULL; static struct FactorySelectScreen *sFactorySelectScreen; static void (*sSwap_CurrentOptionFunc)(u8 taskId); static struct FactorySwapScreen *sFactorySwapScreen; u8 (*gFactorySelect_CurrentOptionFunc)(void); static const u16 sPokeballGray_Pal[] = INCBIN_U16("graphics/battle_frontier/factory_screen/pokeball_gray.gbapal"); static const u16 sPokeballSelected_Pal[] = INCBIN_U16("graphics/battle_frontier/factory_screen/pokeball_selected.gbapal"); static const u16 sInterface_Pal[] = INCBIN_U16("graphics/battle_frontier/factory_screen/interface.gbapal"); // Arrow, menu/action highlights, action box, etc static const u8 sPokeball_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/pokeball.4bpp"); // Unused, gPokeballSelection_Gfx used instead static const u8 sArrow_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/arrow.4bpp"); static const u8 sMenuHighlightLeft_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/menu_highlight_left.4bpp"); static const u8 sMenuHighlightRight_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/menu_highlight_right.4bpp"); static const u8 sActionBoxLeft_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/action_box_left.4bpp"); static const u8 sActionBoxRight_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/action_box_right.4bpp"); static const u8 sActionHighlightLeft_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/action_highlight_left.4bpp"); static const u8 sActionHighlightMiddle_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/action_highlight_middle.4bpp"); static const u8 sActionHighlightRight_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/action_highlight_right.4bpp"); static const u8 sMonPicBgAnim_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/mon_pic_bg_anim.4bpp"); static const u8 sMonPicBg_Tilemap[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/mon_pic_bg.bin"); static const u8 sMonPicBg_Gfx[] = INCBIN_U8( "graphics/battle_frontier/factory_screen/mon_pic_bg.4bpp"); static const u16 sMonPicBg_Pal[] = INCBIN_U16("graphics/battle_frontier/factory_screen/mon_pic_bg.gbapal"); static const struct SpriteSheet sSelect_SpriteSheets[] = { {sArrow_Gfx, sizeof(sArrow_Gfx), GFXTAG_ARROW}, {sMenuHighlightLeft_Gfx, sizeof(sMenuHighlightLeft_Gfx), GFXTAG_MENU_HIGHLIGHT_LEFT}, {sMenuHighlightRight_Gfx, sizeof(sMenuHighlightRight_Gfx), GFXTAG_MENU_HIGHLIGHT_RIGHT}, {sMonPicBgAnim_Gfx, sizeof(sMonPicBgAnim_Gfx), GFXTAG_MON_PIC_BG_ANIM}, {}, }; static const struct CompressedSpriteSheet sSelect_BallGfx[] = { {gPokeballSelection_Gfx, 0x800, GFXTAG_BALL}, {}, }; static const struct SpritePalette sSelect_SpritePalettes[] = { {sPokeballGray_Pal, PALTAG_BALL_GRAY}, {sPokeballSelected_Pal, PALTAG_BALL_SELECTED}, {sInterface_Pal, PALTAG_INTERFACE}, {sMonPicBg_Pal, PALTAG_MON_PIC_BG}, {}, }; u8 static (* const sSelect_MenuOptionFuncs[])(void) = { Select_OptionSummary, Select_OptionRentDeselect, Select_OptionOthers }; static const struct BgTemplate sSelect_BgTemplates[] = { { .bg = 0, .charBaseIndex = 0, .mapBaseIndex = 24, .screenSize = 0, .paletteMode = 0, .priority = 0, .baseTile = 0 }, { .bg = 1, .charBaseIndex = 1, .mapBaseIndex = 25, .screenSize = 0, .paletteMode = 0, .priority = 3, .baseTile = 0 }, { .bg = 3, .charBaseIndex = 2, .mapBaseIndex = 27, .screenSize = 0, .paletteMode = 0, .priority = 2, .baseTile = 0 }, }; enum { SELECT_WIN_TITLE, SELECT_WIN_SPECIES, SELECT_WIN_INFO, SELECT_WIN_OPTIONS, SELECT_WIN_YES_NO, SELECT_WIN_MON_CATEGORY, }; static const struct WindowTemplate sSelect_WindowTemplates[] = { [SELECT_WIN_TITLE] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 2, .width = 12, .height = 2, .paletteNum = 15, .baseBlock = 0x0001, }, [SELECT_WIN_SPECIES] = { .bg = 0, .tilemapLeft = 19, .tilemapTop = 2, .width = 11, .height = 2, .paletteNum = 14, .baseBlock = 0x0019, }, [SELECT_WIN_INFO] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 15, .width = 20, .height = 3, .paletteNum = 15, .baseBlock = 0x002f, }, [SELECT_WIN_OPTIONS] = { .bg = 0, .tilemapLeft = 22, .tilemapTop = 14, .width = 8, .height = 6, .paletteNum = 15, .baseBlock = 0x006b, }, [SELECT_WIN_YES_NO] = { .bg = 0, .tilemapLeft = 22, .tilemapTop = 14, .width = 8, .height = 4, .paletteNum = 15, .baseBlock = 0x009b, }, [SELECT_WIN_MON_CATEGORY] = { .bg = 0, .tilemapLeft = 15, .tilemapTop = 0, .width = 15, .height = 2, .paletteNum = 15, .baseBlock = 0x00bb, }, DUMMY_WIN_TEMPLATE, }; static const u16 sSelectText_Pal[] = INCBIN_U16("graphics/battle_frontier/factory_screen/text.gbapal"); static const u8 sMenuOptionTextColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GREY, TEXT_COLOR_TRANSPARENT}; static const u8 sSpeciesNameTextColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_RED, TEXT_COLOR_TRANSPARENT}; static const struct OamData sOam_Select_Pokeball = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(32x32), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(32x32), .tileNum = 0, .priority = 3, .paletteNum = 0, .affineParam = 0, }; static const struct OamData sOam_Select_Arrow = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(16x16), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(16x16), .tileNum = 0, .priority = 3, .paletteNum = 0, .affineParam = 0, }; static const struct OamData sOam_Select_MenuHighlight = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(32x16), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(32x16), .tileNum = 0, .priority = 2, .paletteNum = 0, .affineParam = 0, }; static const struct OamData sOam_Select_MonPicBgAnim = { .y = 0, .affineMode = ST_OAM_AFFINE_DOUBLE, .objMode = ST_OAM_OBJ_BLEND, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(64x64), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(64x64), .tileNum = 0, .priority = 0, .paletteNum = 0, .affineParam = 1, }; static const union AnimCmd sAnim_Select_Interface[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; static const union AnimCmd sAnim_Select_MonPicBgAnim[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; static const union AnimCmd sAnim_Select_Pokeball_Still[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_END, }; static const union AnimCmd sAnim_Select_Pokeball_Moving[] = { ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(0, 32), ANIMCMD_FRAME(16, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_FRAME(32, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_FRAME(16, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_FRAME(32, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_END, }; static const union AnimCmd * const sAnims_Select_Interface[] = { sAnim_Select_Interface, }; static const union AnimCmd * const sAnims_Select_MonPicBgAnim[] = { sAnim_Select_MonPicBgAnim, }; static const union AnimCmd * const sAnims_Select_Pokeball[] = { sAnim_Select_Pokeball_Still, sAnim_Select_Pokeball_Moving, }; static const union AffineAnimCmd gUnknown_0861050C[] = { AFFINEANIMCMD_FRAME(5, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(16, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(32, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(64, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(128, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(256, 5, 0, 0), AFFINEANIMCMD_END, }; static const union AffineAnimCmd gUnknown_0861056C[] = { AFFINEANIMCMD_FRAME(128, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(64, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(32, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(16, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(5, 5, 0, 0), AFFINEANIMCMD_END, }; static const union AffineAnimCmd gUnknown_086105BC[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_END, }; static const union AffineAnimCmd * const sAffineAnims_Select_MonPicBgAnim[] = { gUnknown_0861050C, gUnknown_0861056C, gUnknown_086105BC, }; static const struct SpriteTemplate sSpriteTemplate_Select_Pokeball = { .tileTag = GFXTAG_BALL, .paletteTag = PALTAG_BALL_GRAY, .oam = &sOam_Select_Pokeball, .anims = sAnims_Select_Pokeball, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_Pokeball }; static const struct SpriteTemplate sSpriteTemplate_Select_Arrow = { .tileTag = GFXTAG_ARROW, .paletteTag = PALTAG_INTERFACE, .oam = &sOam_Select_Arrow, .anims = sAnims_Select_Interface, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; static const struct SpriteTemplate sSpriteTemplate_Select_MenuHighlightLeft = { .tileTag = GFXTAG_MENU_HIGHLIGHT_LEFT, .paletteTag = PALTAG_INTERFACE, .oam = &sOam_Select_MenuHighlight, .anims = sAnims_Select_Interface, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; static const struct SpriteTemplate sSpriteTemplate_Select_MenuHighlightRight = { .tileTag = GFXTAG_MENU_HIGHLIGHT_RIGHT, .paletteTag = PALTAG_INTERFACE, .oam = &sOam_Select_MenuHighlight, .anims = sAnims_Select_Interface, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; static const struct SpriteTemplate sSpriteTemplate_Select_MonPicBgAnim = { .tileTag = GFXTAG_MON_PIC_BG_ANIM, .paletteTag = PALTAG_MON_PIC_BG, .oam = &sOam_Select_MonPicBgAnim, .anims = sAnims_Select_MonPicBgAnim, .images = NULL, .affineAnims = sAffineAnims_Select_MonPicBgAnim, .callback = SpriteCallbackDummy }; static const struct SpriteSheet sSwap_SpriteSheets[] = { {sArrow_Gfx, sizeof(sArrow_Gfx), GFXTAG_ARROW}, {sMenuHighlightLeft_Gfx, sizeof(sMenuHighlightLeft_Gfx), GFXTAG_MENU_HIGHLIGHT_LEFT}, {sMenuHighlightRight_Gfx, sizeof(sMenuHighlightRight_Gfx), GFXTAG_MENU_HIGHLIGHT_RIGHT}, {sActionBoxLeft_Gfx, sizeof(sActionBoxLeft_Gfx), GFXTAG_ACTION_BOX_LEFT}, {sActionBoxRight_Gfx, sizeof(sActionBoxRight_Gfx), GFXTAG_ACTION_BOX_RIGHT}, {sActionHighlightLeft_Gfx, 0x100, GFXTAG_ACTION_HIGHLIGHT_LEFT}, {sActionHighlightMiddle_Gfx, sizeof(sActionHighlightMiddle_Gfx), GFXTAG_ACTION_HIGHLIGHT_MIDDLE}, {sActionHighlightRight_Gfx, sizeof(sActionHighlightRight_Gfx), GFXTAG_ACTION_HIGHLIGHT_RIGHT}, {sMonPicBgAnim_Gfx, sizeof(sMonPicBgAnim_Gfx), GFXTAG_MON_PIC_BG_ANIM}, {}, }; static const struct CompressedSpriteSheet sSwap_BallGfx[] = { {gPokeballSelection_Gfx, 0x800, GFXTAG_BALL}, {}, }; static const struct SpritePalette sSwap_SpritePalettes[] = { {sPokeballGray_Pal, PALTAG_BALL_GRAY}, {sPokeballSelected_Pal, PALTAG_BALL_SELECTED}, {sInterface_Pal, PALTAG_INTERFACE}, {sMonPicBg_Pal, PALTAG_MON_PIC_BG}, {}, }; static const struct OamData sOam_Swap_Pokeball = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(32x32), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(32x32), .tileNum = 0, .priority = 3, .paletteNum = 0, .affineParam = 0, }; static const struct OamData sOam_Swap_Arrow = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(16x16), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(16x16), .tileNum = 0, .priority = 3, .paletteNum = 0, .affineParam = 0, }; static const struct OamData sOam_Swap_MenuHighlight = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(32x16), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(32x16), .tileNum = 0, .priority = 2, .paletteNum = 0, .affineParam = 0, }; static const struct OamData sOam_Swap_MonPicBgAnim = { .y = 0, .affineMode = ST_OAM_AFFINE_DOUBLE, .objMode = ST_OAM_OBJ_BLEND, .mosaic = 0, .bpp = ST_OAM_4BPP, .shape = SPRITE_SHAPE(64x64), .x = 0, .matrixNum = 0, .size = SPRITE_SIZE(64x64), .tileNum = 0, .priority = 0, .paletteNum = 0, .affineParam = 1, }; static const union AnimCmd sAnim_Swap_Interface[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; static const union AnimCmd sAnim_Swap_MonPicBgAnim[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; static const union AnimCmd sAnim_Swap_Pokeball_Still[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_END, }; static const union AnimCmd sAnim_Swap_Pokeball_Moving[] = { ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(0, 32), ANIMCMD_FRAME(16, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_FRAME(32, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_FRAME(16, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_FRAME(32, 8), ANIMCMD_FRAME(0, 8), ANIMCMD_END, }; static const union AnimCmd * const sAnims_Swap_Interface[] = { sAnim_Swap_Interface, }; static const union AnimCmd * const sAnims_Swap_MonPicBgAnim[] = { sAnim_Swap_MonPicBgAnim, }; static const union AnimCmd * const sAnims_Swap_Pokeball[] = { sAnim_Swap_Pokeball_Still, sAnim_Swap_Pokeball_Moving, }; static const union AffineAnimCmd gUnknown_08610768[] = { AFFINEANIMCMD_FRAME(5, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(16, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(32, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(64, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(128, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(256, 5, 0, 0), AFFINEANIMCMD_END, }; static const union AffineAnimCmd gUnknown_086107C8[] = { AFFINEANIMCMD_FRAME(128, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(64, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(32, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(16, 5, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_FRAME(5, 5, 0, 0), AFFINEANIMCMD_END, }; static const union AffineAnimCmd gUnknown_08610818[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_END, }; static const union AffineAnimCmd * const sAffineAnims_Swap_MonPicBgAnim[] = { gUnknown_08610768, gUnknown_086107C8, gUnknown_08610818, }; static const struct SpriteTemplate sSpriteTemplate_Swap_Pokeball = { .tileTag = GFXTAG_BALL, .paletteTag = PALTAG_BALL_GRAY, .oam = &sOam_Swap_Pokeball, .anims = sAnims_Swap_Pokeball, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_Pokeball }; static const struct SpriteTemplate sSpriteTemplate_Swap_Arrow = { .tileTag = GFXTAG_ARROW, .paletteTag = PALTAG_INTERFACE, .oam = &sOam_Swap_Arrow, .anims = sAnims_Swap_Interface, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; static const struct SpriteTemplate sSpriteTemplate_Swap_MenuHighlightLeft = { .tileTag = GFXTAG_MENU_HIGHLIGHT_LEFT, .paletteTag = PALTAG_INTERFACE, .oam = &sOam_Swap_MenuHighlight, .anims = sAnims_Swap_Interface, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; static const struct SpriteTemplate sSpriteTemplate_Swap_MenuHighlightRight = { .tileTag = GFXTAG_MENU_HIGHLIGHT_RIGHT, .paletteTag = PALTAG_INTERFACE, .oam = &sOam_Swap_MenuHighlight, .anims = sAnims_Swap_Interface, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; static const struct SpriteTemplate sSpriteTemplate_Swap_MonPicBgAnim = { .tileTag = GFXTAG_MON_PIC_BG_ANIM, .paletteTag = PALTAG_MON_PIC_BG, .oam = &sOam_Swap_MonPicBgAnim, .anims = sAnims_Swap_MonPicBgAnim, .images = NULL, .affineAnims = sAffineAnims_Swap_MonPicBgAnim, .callback = SpriteCallbackDummy }; void static (* const sSwap_MenuOptionFuncs[])(u8 taskId) = { Swap_OptionSummary, Swap_OptionSwap, Swap_OptionRechoose, }; static const struct BgTemplate sSwap_BgTemplates[4] = { { .bg = 0, .charBaseIndex = 0, .mapBaseIndex = 24, .screenSize = 0, .paletteMode = 0, .priority = 1, .baseTile = 0 }, { .bg = 1, .charBaseIndex = 1, .mapBaseIndex = 25, .screenSize = 0, .paletteMode = 0, .priority = 3, .baseTile = 0 }, { .bg = 2, .charBaseIndex = 2, .mapBaseIndex = 26, .screenSize = 0, .paletteMode = 0, .priority = 0, .baseTile = 0 }, { .bg = 3, .charBaseIndex = 2, .mapBaseIndex = 27, .screenSize = 0, .paletteMode = 0, .priority = 2, .baseTile = 0 }, }; enum { SWAP_WIN_TITLE, SWAP_WIN_SPECIES, SWAP_WIN_INFO, SWAP_WIN_OPTIONS, SWAP_WIN_YES_NO, SWAP_WIN_5, SWAP_WIN_6, SWAP_WIN_7, SWAP_WIN_MON_CATEGORY, }; static const struct WindowTemplate sSwap_WindowTemplates[] = { [SWAP_WIN_TITLE] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 2, .width = 12, .height = 2, .paletteNum = 15, .baseBlock = 0x0001, }, [SWAP_WIN_SPECIES] = { .bg = 2, .tilemapLeft = 19, .tilemapTop = 2, .width = 11, .height = 2, .paletteNum = 14, .baseBlock = 0x0019, }, [SWAP_WIN_INFO] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 15, .width = 20, .height = 3, .paletteNum = 15, .baseBlock = 0x002f, }, [SWAP_WIN_OPTIONS] = { .bg = 0, .tilemapLeft = 21, .tilemapTop = 14, .width = 9, .height = 6, .paletteNum = 15, .baseBlock = 0x006b, }, [SWAP_WIN_YES_NO] = { .bg = 0, .tilemapLeft = 22, .tilemapTop = 14, .width = 8, .height = 4, .paletteNum = 15, .baseBlock = 0x00a1, }, [SWAP_WIN_5] = { .bg = 2, .tilemapLeft = 21, .tilemapTop = 15, .width = 9, .height = 5, .paletteNum = 14, .baseBlock = 0x006b, }, [SWAP_WIN_6] = { .bg = 2, .tilemapLeft = 10, .tilemapTop = 2, .width = 4, .height = 2, .paletteNum = 14, .baseBlock = 0x00c1, }, [SWAP_WIN_7] = { .bg = 0, .tilemapLeft = 19, .tilemapTop = 2, .width = 11, .height = 2, .paletteNum = 15, .baseBlock = 0x00c9, }, [SWAP_WIN_MON_CATEGORY] = { .bg = 0, .tilemapLeft = 15, .tilemapTop = 0, .width = 15, .height = 2, .paletteNum = 15, .baseBlock = 0x00df, }, DUMMY_WIN_TEMPLATE, }; static const u16 sSwapText_Pal[] = INCBIN_U16("graphics/battle_frontier/factory_screen/text.gbapal"); // Identical to sSelectText_Pal static const u8 sSwapMenuOptionsTextColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GREY, TEXT_COLOR_TRANSPARENT}; static const u8 sSwapSpeciesNameTextColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_RED, TEXT_COLOR_TRANSPARENT}; #define SWAPACTION_MON 1 #define SWAPACTION_PKMN_FOR_SWAP 2 #define SWAPACTION_CANCEL 3 static const struct SwapScreenAction sSwap_PlayerScreenActions[] = { {.id = SWAPACTION_MON, .func = Swap_ActionMon}, {.id = SWAPACTION_MON, .func = Swap_ActionMon}, {.id = SWAPACTION_MON, .func = Swap_ActionMon}, {.id = SWAPACTION_CANCEL, .func = Swap_ActionCancel}, }; static const struct SwapScreenAction sSwap_EnemyScreenActions[] = { {.id = SWAPACTION_MON, .func = Swap_ActionMon}, {.id = SWAPACTION_MON, .func = Swap_ActionMon}, {.id = SWAPACTION_MON, .func = Swap_ActionMon}, {.id = SWAPACTION_PKMN_FOR_SWAP, .func = Swap_ActionPkmnForSwap}, {.id = SWAPACTION_CANCEL, .func = Swap_ActionCancel}, }; static void SpriteCB_Pokeball(struct Sprite *sprite) { if (sprite->oam.paletteNum == IndexOfSpritePaletteTag(PALTAG_BALL_SELECTED)) { // Pokeball selected, do rocking animation if (sprite->animEnded) { if (sprite->data[0] != 0) { sprite->data[0]--; } else if (Random() % 5 == 0) { StartSpriteAnim(sprite, 0); sprite->data[0] = 32; } else { StartSpriteAnim(sprite, 1); } } else { StartSpriteAnimIfDifferent(sprite, 1); } } else { // Pokeball not selected, remain still StartSpriteAnimIfDifferent(sprite, 0); } } static void CB2_SelectScreen(void) { AnimateSprites(); BuildOamBuffer(); RunTextPrinters(); UpdatePaletteFade(); RunTasks(); } static void VBlankCB_SelectScreen(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } void DoBattleFactorySelectScreen(void) { sFactorySelectScreen = NULL; SetMainCallback2(CB2_InitSelectScreen); } static void CB2_InitSelectScreen(void) { u8 taskId; switch (gMain.state) { case 0: if (sFactorySelectMons != NULL) FREE_AND_SET_NULL(sFactorySelectMons); SetHBlankCallback(NULL); SetVBlankCallback(NULL); CpuFill32(0, (void *)VRAM, VRAM_SIZE); ResetBgsAndClearDma3BusyFlags(0); InitBgsFromTemplates(0, sSelect_BgTemplates, ARRAY_COUNT(sSelect_BgTemplates)); InitWindows(sSelect_WindowTemplates); DeactivateAllTextPrinters(); gMain.state++; break; case 1: sSelectMenuTilesetBuffer = Alloc(0x440); sSelectMonPicBgTilesetBuffer = AllocZeroed(0x440); sSelectMenuTilemapBuffer = Alloc(BG_SCREEN_SIZE); sSelectMonPicBgTilemapBuffer = AllocZeroed(BG_SCREEN_SIZE); ChangeBgX(0, 0, 0); ChangeBgY(0, 0, 0); ChangeBgX(1, 0, 0); ChangeBgY(1, 0, 0); ChangeBgX(3, 0, 0); ChangeBgY(3, 0, 0); SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); SetGpuReg(REG_OFFSET_BLDY, 0); SetGpuReg(REG_OFFSET_MOSAIC, 0); SetGpuReg(REG_OFFSET_WIN0H, 0); SetGpuReg(REG_OFFSET_WIN0V, 0); SetGpuReg(REG_OFFSET_WIN1H, 0); SetGpuReg(REG_OFFSET_WIN1V, 0); SetGpuReg(REG_OFFSET_WININ, 0); SetGpuReg(REG_OFFSET_WINOUT, 0); gMain.state++; break; case 2: ResetPaletteFade(); ResetSpriteData(); ResetTasks(); FreeAllSpritePalettes(); CpuCopy16(gFrontierFactorySelectMenu_Gfx, sSelectMenuTilesetBuffer, 0x440); CpuCopy16(sMonPicBg_Gfx, sSelectMonPicBgTilesetBuffer, 0x60); LoadBgTiles(1, sSelectMenuTilesetBuffer, 0x440, 0); LoadBgTiles(3, sSelectMonPicBgTilesetBuffer, 0x60, 0); CpuCopy16(gFrontierFactorySelectMenu_Tilemap, sSelectMenuTilemapBuffer, BG_SCREEN_SIZE); LoadBgTilemap(1, sSelectMenuTilemapBuffer, BG_SCREEN_SIZE, 0); LoadPalette(gFrontierFactorySelectMenu_Pal, 0, 0x40); LoadPalette(sSelectText_Pal, 0xF0, 8); LoadPalette(sSelectText_Pal, 0xE0, 10); if (sFactorySelectScreen->fromSummaryScreen == TRUE) gPlttBufferUnfaded[228] = sFactorySelectScreen->speciesNameColorBackup; LoadPalette(sMonPicBg_Pal, 0x20, 4); gMain.state++; break; case 3: SetBgTilemapBuffer(3, sSelectMonPicBgTilemapBuffer); CopyToBgTilemapBufferRect(3, sMonPicBg_Tilemap, 11, 4, 8, 8); CopyToBgTilemapBufferRect(3, sMonPicBg_Tilemap, 2, 4, 8, 8); CopyToBgTilemapBufferRect(3, sMonPicBg_Tilemap, 20, 4, 8, 8); CopyBgTilemapBufferToVram(3); gMain.state++; break; case 4: LoadSpritePalettes(sSelect_SpritePalettes); LoadSpriteSheets(sSelect_SpriteSheets); LoadCompressedSpriteSheet(sSelect_BallGfx); ShowBg(0); ShowBg(1); SetVBlankCallback(VBlankCB_SelectScreen); BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_OBJ_1D_MAP); if (sFactorySelectScreen->fromSummaryScreen == TRUE) { Select_SetWinRegs(88, 152, 32, 96); ShowBg(3); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_OBJ); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(11, 4)); } else { HideBg(3); } gMain.state++; break; case 5: if (sFactorySelectScreen->fromSummaryScreen == TRUE) sFactorySelectScreen->cursorPos = gLastViewedMonIndex; Select_InitMonsData(); Select_InitAllSprites(); if (sFactorySelectScreen->fromSummaryScreen == TRUE) Select_ReshowMonSprite(); gMain.state++; break; case 6: Select_PrintSelectMonString(); PutWindowTilemap(SELECT_WIN_INFO); gMain.state++; break; case 7: Select_PrintMonCategory(); PutWindowTilemap(SELECT_WIN_MON_CATEGORY); gMain.state++; break; case 8: Select_PrintMonSpecies(); PutWindowTilemap(SELECT_WIN_SPECIES); gMain.state++; break; case 9: Select_PrintRentalPkmnString(); PutWindowTilemap(SELECT_WIN_TITLE); gMain.state++; break; case 10: sFactorySelectScreen->fadeSpeciesNameTaskId = CreateTask(Select_Task_FadeSpeciesName, 0); if (!sFactorySelectScreen->fromSummaryScreen) { gTasks[sFactorySelectScreen->fadeSpeciesNameTaskId].tState = 0; taskId = CreateTask(Select_Task_HandleChooseMons, 0); gTasks[taskId].tState = 0; } else { gTasks[sFactorySelectScreen->fadeSpeciesNameTaskId].tState = 1; sFactorySelectScreen->fadeSpeciesNameActive = FALSE; taskId = CreateTask(Select_Task_HandleMenu, 0); gTasks[taskId].tState = 13; } SetMainCallback2(CB2_SelectScreen); break; } } static void Select_InitMonsData(void) { u8 i; if (sFactorySelectScreen != NULL) return; sFactorySelectScreen = AllocZeroed(sizeof(*sFactorySelectScreen)); sFactorySelectScreen->cursorPos = 0; sFactorySelectScreen->selectingMonsState = 1; sFactorySelectScreen->fromSummaryScreen = FALSE; for (i = 0; i < SELECTABLE_MONS_COUNT; i++) sFactorySelectScreen->mons[i].selectedId = 0; if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) CreateFrontierFactorySelectableMons(0); else CreateSlateportTentSelectableMons(0); } static void Select_InitAllSprites(void) { u8 i, cursorPos; s16 x; for (i = 0; i < SELECTABLE_MONS_COUNT; i++) { sFactorySelectScreen->mons[i].ballSpriteId = CreateSprite(&sSpriteTemplate_Select_Pokeball, (35 * i) + 32, 64, 1); gSprites[sFactorySelectScreen->mons[i].ballSpriteId].data[0] = 0; Select_SetBallSpritePaletteNum(i); } cursorPos = sFactorySelectScreen->cursorPos; x = gSprites[sFactorySelectScreen->mons[cursorPos].ballSpriteId].pos1.x; sFactorySelectScreen->cursorSpriteId = CreateSprite(&sSpriteTemplate_Select_Arrow, x, 88, 0); sFactorySelectScreen->menuCursor1SpriteId = CreateSprite(&sSpriteTemplate_Select_MenuHighlightLeft, 176, 112, 0); sFactorySelectScreen->menuCursor2SpriteId = CreateSprite(&sSpriteTemplate_Select_MenuHighlightRight, 176, 144, 0); gSprites[sFactorySelectScreen->menuCursor1SpriteId].invisible = TRUE; gSprites[sFactorySelectScreen->menuCursor2SpriteId].invisible = TRUE; gSprites[sFactorySelectScreen->menuCursor1SpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->menuCursor1SpriteId].centerToCornerVecY = 0; gSprites[sFactorySelectScreen->menuCursor2SpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->menuCursor2SpriteId].centerToCornerVecY = 0; } static void Select_DestroyAllSprites(void) { u8 i; for (i = 0; i < SELECTABLE_MONS_COUNT; i++) DestroySprite(&gSprites[sFactorySelectScreen->mons[i].ballSpriteId]); DestroySprite(&gSprites[sFactorySelectScreen->cursorSpriteId]); DestroySprite(&gSprites[sFactorySelectScreen->menuCursor1SpriteId]); DestroySprite(&gSprites[sFactorySelectScreen->menuCursor2SpriteId]); } static void Select_UpdateBallCursorPosition(s8 direction) { u8 cursorPos; if (direction > 0) // Move cursor right. { if (sFactorySelectScreen->cursorPos != SELECTABLE_MONS_COUNT - 1) sFactorySelectScreen->cursorPos++; else sFactorySelectScreen->cursorPos = 0; } else // Move cursor left. { if (sFactorySelectScreen->cursorPos != 0) sFactorySelectScreen->cursorPos--; else sFactorySelectScreen->cursorPos = SELECTABLE_MONS_COUNT - 1; } cursorPos = sFactorySelectScreen->cursorPos; gSprites[sFactorySelectScreen->cursorSpriteId].pos1.x = gSprites[sFactorySelectScreen->mons[cursorPos].ballSpriteId].pos1.x; } static void Select_UpdateMenuCursorPosition(s8 direction) { if (direction > 0) // Move cursor down. { if (sFactorySelectScreen->menuCursorPos != ARRAY_COUNT(sSelect_MenuOptionFuncs) - 1) sFactorySelectScreen->menuCursorPos++; else sFactorySelectScreen->menuCursorPos = 0; } else // Move cursor up. { if (sFactorySelectScreen->menuCursorPos != 0) sFactorySelectScreen->menuCursorPos--; else sFactorySelectScreen->menuCursorPos = ARRAY_COUNT(sSelect_MenuOptionFuncs) - 1; } gSprites[sFactorySelectScreen->menuCursor1SpriteId].pos1.y = (sFactorySelectScreen->menuCursorPos * 16) + 112; gSprites[sFactorySelectScreen->menuCursor2SpriteId].pos1.y = (sFactorySelectScreen->menuCursorPos * 16) + 112; } static void Select_UpdateYesNoCursorPosition(s8 direction) { if (direction > 0) // Move cursor down. { if (sFactorySelectScreen->yesNoCursorPos != 1) sFactorySelectScreen->yesNoCursorPos++; else sFactorySelectScreen->yesNoCursorPos = 0; } else // Move cursor up. { if (sFactorySelectScreen->yesNoCursorPos != 0) sFactorySelectScreen->yesNoCursorPos--; else sFactorySelectScreen->yesNoCursorPos = 1; } gSprites[sFactorySelectScreen->menuCursor1SpriteId].pos1.y = (sFactorySelectScreen->yesNoCursorPos * 16) + 112; gSprites[sFactorySelectScreen->menuCursor2SpriteId].pos1.y = (sFactorySelectScreen->yesNoCursorPos * 16) + 112; } static void Select_HandleMonSelectionChange(void) { u8 i, paletteNum; u8 cursorPos = sFactorySelectScreen->cursorPos; if (sFactorySelectScreen->mons[cursorPos].selectedId) // Deselect a mon. { paletteNum = IndexOfSpritePaletteTag(PALTAG_BALL_GRAY); if (sFactorySelectScreen->selectingMonsState == 3 && sFactorySelectScreen->mons[cursorPos].selectedId == 1) { for (i = 0; i < SELECTABLE_MONS_COUNT; i++) { if (sFactorySelectScreen->mons[i].selectedId == 2) break; } if (i == SELECTABLE_MONS_COUNT) return; else sFactorySelectScreen->mons[i].selectedId = 1; } sFactorySelectScreen->mons[cursorPos].selectedId = 0; sFactorySelectScreen->selectingMonsState--; } else // Select a mon. { paletteNum = IndexOfSpritePaletteTag(PALTAG_BALL_SELECTED); sFactorySelectScreen->mons[cursorPos].selectedId = sFactorySelectScreen->selectingMonsState; sFactorySelectScreen->selectingMonsState++; } gSprites[sFactorySelectScreen->mons[cursorPos].ballSpriteId].oam.paletteNum = paletteNum; } static void Select_SetBallSpritePaletteNum(u8 id) { u8 palNum; if (sFactorySelectScreen->mons[id].selectedId) palNum = IndexOfSpritePaletteTag(PALTAG_BALL_SELECTED); else palNum = IndexOfSpritePaletteTag(PALTAG_BALL_GRAY); gSprites[sFactorySelectScreen->mons[id].ballSpriteId].oam.paletteNum = palNum; } static void Select_Task_OpenSummaryScreen(u8 taskId) { u8 i; u8 currMonId; switch (gTasks[taskId].tState) { case 6: gPlttBufferUnfaded[228] = gPlttBufferFaded[228]; BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); gTasks[taskId].tState = 7; break; case 7: if (!gPaletteFade.active) { DestroyTask(sFactorySelectScreen->fadeSpeciesNameTaskId); HideMonPic(sFactorySelectScreen->monPics[1], &sFactorySelectScreen->monPicAnimating); Select_DestroyAllSprites(); FREE_AND_SET_NULL(sSelectMenuTilesetBuffer); FREE_AND_SET_NULL(sSelectMonPicBgTilesetBuffer); FREE_AND_SET_NULL(sSelectMenuTilemapBuffer); FREE_AND_SET_NULL(sSelectMonPicBgTilemapBuffer); FreeAllWindowBuffers(); gTasks[taskId].tState = 8; } break; case 8: sFactorySelectScreen->speciesNameColorBackup = gPlttBufferUnfaded[228]; DestroyTask(taskId); sFactorySelectScreen->fromSummaryScreen = TRUE; currMonId = sFactorySelectScreen->cursorPos; sFactorySelectMons = AllocZeroed(sizeof(struct Pokemon) * SELECTABLE_MONS_COUNT); for (i = 0; i < SELECTABLE_MONS_COUNT; i++) sFactorySelectMons[i] = sFactorySelectScreen->mons[i].monData; ShowPokemonSummaryScreen(PSS_MODE_LOCK_MOVES, sFactorySelectMons, currMonId, SELECTABLE_MONS_COUNT - 1, CB2_InitSelectScreen); break; } } static void Select_Task_Exit(u8 taskId) { if (sFactorySelectScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case 0: BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); gTasks[taskId].tState++; break; case 1: if (!UpdatePaletteFade()) { Select_CopyMonsToPlayerParty(); DestroyTask(sFactorySelectScreen->fadeSpeciesNameTaskId); Select_DestroyAllSprites(); FREE_AND_SET_NULL(sSelectMenuTilesetBuffer); FREE_AND_SET_NULL(sSelectMenuTilemapBuffer); FREE_AND_SET_NULL(sSelectMonPicBgTilemapBuffer); FREE_AND_SET_NULL(sFactorySelectScreen); FreeAllWindowBuffers(); SetMainCallback2(CB2_ReturnToFieldContinueScript); DestroyTask(taskId); } break; } } static void Select_Task_HandleYesNo(u8 taskId) { if (sFactorySelectScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case 10: sub_819C4B4(); gTasks[taskId].tState = 4; break; case 4: Select_ShowYesNoOptions(); gTasks[taskId].tState = 5; break; case 5: if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); if (sFactorySelectScreen->yesNoCursorPos == 0) { // Selected Yes sub_819C568(); gTasks[taskId].tState = 0; gTasks[taskId].func = Select_Task_Exit; } else { // Selected No sub_819B958(SELECT_WIN_YES_NO); sub_819BC9C(); sFactorySelectScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = 1; gTasks[taskId].func = Select_Task_HandleChooseMons; } } else if (JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); sub_819B958(SELECT_WIN_YES_NO); sub_819BC9C(); sFactorySelectScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = 1; gTasks[taskId].func = Select_Task_HandleChooseMons; } else if (JOY_REPEAT(DPAD_UP)) { PlaySE(SE_SELECT); Select_UpdateYesNoCursorPosition(-1); } else if (JOY_REPEAT(DPAD_DOWN)) { PlaySE(SE_SELECT); Select_UpdateYesNoCursorPosition(1); } break; } } static void Select_Task_HandleMenu(u8 taskId) { switch (gTasks[taskId].tState) { case 2: if (!sFactorySelectScreen->fromSummaryScreen) OpenMonPic(&sFactorySelectScreen->monPics[1].bgSpriteId, &sFactorySelectScreen->monPicAnimating, FALSE); gTasks[taskId].tState = 9; break; case 9: if (sFactorySelectScreen->monPicAnimating != TRUE) { Select_ShowMenuOptions(); sFactorySelectScreen->fromSummaryScreen = FALSE; gTasks[taskId].tState = 3; } break; case 3: if (JOY_NEW(A_BUTTON)) { u8 retVal; PlaySE(SE_SELECT); retVal = Select_RunMenuOptionFunc(); if (retVal == 1) { sFactorySelectScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = 1; gTasks[taskId].func = Select_Task_HandleChooseMons; } else if (retVal == 2) { gTasks[taskId].tState = 10; gTasks[taskId].func = Select_Task_HandleYesNo; } else if (retVal == 3) { gTasks[taskId].tState = 11; gTasks[taskId].func = Select_Task_HandleChooseMons; } else { gTasks[taskId].tState = 6; gTasks[taskId].func = Select_Task_OpenSummaryScreen; } } else if (JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); CloseMonPic(sFactorySelectScreen->monPics[1], &sFactorySelectScreen->monPicAnimating, FALSE); sub_819B958(SELECT_WIN_OPTIONS); sFactorySelectScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = 1; gTasks[taskId].func = Select_Task_HandleChooseMons; } else if (JOY_REPEAT(DPAD_UP)) { PlaySE(SE_SELECT); Select_UpdateMenuCursorPosition(-1); } else if (JOY_REPEAT(DPAD_DOWN)) { PlaySE(SE_SELECT); Select_UpdateMenuCursorPosition(1); } break; case 12: if (!gPaletteFade.active) { if (sFactorySelectScreen->fromSummaryScreen == TRUE) { gPlttBufferFaded[228] = sFactorySelectScreen->speciesNameColorBackup; gPlttBufferUnfaded[228] = gPlttBufferUnfaded[244]; } sFactorySelectScreen->fromSummaryScreen = FALSE; gTasks[taskId].tState = 3; } break; case 13: Select_ShowMenuOptions(); gTasks[taskId].tState = 12; break; } } static void Select_Task_HandleChooseMons(u8 taskId) { if (sFactorySelectScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case 0: if (!gPaletteFade.active) { gTasks[taskId].tState = 1; sFactorySelectScreen->fadeSpeciesNameActive = TRUE; } break; case 1: if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); sFactorySelectScreen->fadeSpeciesNameActive = FALSE; gTasks[taskId].tState = 2; gTasks[taskId].func = Select_Task_HandleMenu; } else if (JOY_REPEAT(DPAD_LEFT)) { PlaySE(SE_SELECT); Select_UpdateBallCursorPosition(-1); Select_PrintMonCategory(); Select_PrintMonSpecies(); } else if (JOY_REPEAT(DPAD_RIGHT)) { PlaySE(SE_SELECT); Select_UpdateBallCursorPosition(1); Select_PrintMonCategory(); Select_PrintMonSpecies(); } break; case 11: if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); CloseMonPic(sFactorySelectScreen->monPics[1], &sFactorySelectScreen->monPicAnimating, FALSE); Select_PrintSelectMonString(); sFactorySelectScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = 1; } break; } } static void CreateFrontierFactorySelectableMons(u8 firstMonId) { u8 i, j = 0; u8 ivs = 0; u8 level = 0; u8 friendship = 0; u32 otId = 0; u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u8 challengeNum = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] / 7; u8 rentalRank = 0; gFacilityTrainerMons = gBattleFrontierMons; if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_50) level = 100; else level = 50; rentalRank = GetNumPastRentalsRank(battleMode, lvlMode); otId = T1_READ_32(gSaveBlock2Ptr->playerTrainerId); for (i = 0; i < SELECTABLE_MONS_COUNT; i++) { u16 monId = gSaveBlock2Ptr->frontier.rentalMons[i].monId; sFactorySelectScreen->mons[i + firstMonId].monId = monId; if (i < rentalRank) ivs = GetFactoryMonFixedIV(challengeNum + 1, 0); else ivs = GetFactoryMonFixedIV(challengeNum, 0); CreateMonWithEVSpreadNatureOTID(&sFactorySelectScreen->mons[i + firstMonId].monData, gFacilityTrainerMons[monId].species, level, gFacilityTrainerMons[monId].nature, ivs, gFacilityTrainerMons[monId].evSpread, otId); friendship = 0; for (j = 0; j < MAX_MON_MOVES; j++) SetMonMoveAvoidReturn(&sFactorySelectScreen->mons[i + firstMonId].monData, gFacilityTrainerMons[monId].moves[j], j); SetMonData(&sFactorySelectScreen->mons[i + firstMonId].monData, MON_DATA_FRIENDSHIP, &friendship); SetMonData(&sFactorySelectScreen->mons[i + firstMonId].monData, MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId]); } } static void CreateSlateportTentSelectableMons(u8 firstMonId) { u8 i, j; u8 ivs = 0; u8 level = 30; u8 friendship = 0; u32 otId = 0; gFacilityTrainerMons = gSlateportBattleTentMons; otId = T1_READ_32(gSaveBlock2Ptr->playerTrainerId); for (i = 0; i < SELECTABLE_MONS_COUNT; i++) { u16 monId = gSaveBlock2Ptr->frontier.rentalMons[i].monId; sFactorySelectScreen->mons[i + firstMonId].monId = monId; CreateMonWithEVSpreadNatureOTID(&sFactorySelectScreen->mons[i + firstMonId].monData, gFacilityTrainerMons[monId].species, level, gFacilityTrainerMons[monId].nature, ivs, gFacilityTrainerMons[monId].evSpread, otId); friendship = 0; for (j = 0; j < MAX_MON_MOVES; j++) SetMonMoveAvoidReturn(&sFactorySelectScreen->mons[i + firstMonId].monData, gFacilityTrainerMons[monId].moves[j], j); SetMonData(&sFactorySelectScreen->mons[i + firstMonId].monData, MON_DATA_FRIENDSHIP, &friendship); SetMonData(&sFactorySelectScreen->mons[i + firstMonId].monData, MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId]); } } static void Select_CopyMonsToPlayerParty(void) { u8 i, j; for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { for (j = 0; j < SELECTABLE_MONS_COUNT; j++) { if (sFactorySelectScreen->mons[j].selectedId == i + 1) { gPlayerParty[i] = sFactorySelectScreen->mons[j].monData; gSaveBlock2Ptr->frontier.rentalMons[i].monId = sFactorySelectScreen->mons[j].monId; gSaveBlock2Ptr->frontier.rentalMons[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY, NULL); gSaveBlock2Ptr->frontier.rentalMons[i].abilityNum = GetBoxMonData(&gPlayerParty[i].box, MON_DATA_ABILITY_NUM, NULL); gSaveBlock2Ptr->frontier.rentalMons[i].ivs = GetBoxMonData(&gPlayerParty[i].box, MON_DATA_ATK_IV, NULL); break; } } } CalculatePlayerPartyCount(); } static void Select_ShowMenuOptions(void) { if (!sFactorySelectScreen->fromSummaryScreen) sFactorySelectScreen->menuCursorPos = 0; gSprites[sFactorySelectScreen->menuCursor1SpriteId].pos1.x = 176; gSprites[sFactorySelectScreen->menuCursor1SpriteId].pos1.y = (sFactorySelectScreen->menuCursorPos * 16) + 112; gSprites[sFactorySelectScreen->menuCursor2SpriteId].pos1.x = 208; gSprites[sFactorySelectScreen->menuCursor2SpriteId].pos1.y = (sFactorySelectScreen->menuCursorPos * 16) + 112; gSprites[sFactorySelectScreen->menuCursor1SpriteId].invisible = FALSE; gSprites[sFactorySelectScreen->menuCursor2SpriteId].invisible = FALSE; Select_PrintMenuOptions(); } static void Select_ShowYesNoOptions(void) { sFactorySelectScreen->yesNoCursorPos = 0; gSprites[sFactorySelectScreen->menuCursor1SpriteId].pos1.x = 176; gSprites[sFactorySelectScreen->menuCursor1SpriteId].pos1.y = 112; gSprites[sFactorySelectScreen->menuCursor2SpriteId].pos1.x = 208; gSprites[sFactorySelectScreen->menuCursor2SpriteId].pos1.y = 112; gSprites[sFactorySelectScreen->menuCursor1SpriteId].invisible = FALSE; gSprites[sFactorySelectScreen->menuCursor2SpriteId].invisible = FALSE; Select_PrintYesNoOptions(); } static void sub_819B958(u8 windowId) { gSprites[sFactorySelectScreen->menuCursor1SpriteId].invisible = TRUE; gSprites[sFactorySelectScreen->menuCursor2SpriteId].invisible = TRUE; FillWindowPixelBuffer(windowId, PIXEL_FILL(0)); CopyWindowToVram(windowId, 2); ClearWindowTilemap(windowId); } static void Select_PrintRentalPkmnString(void) { FillWindowPixelBuffer(SELECT_WIN_TITLE, PIXEL_FILL(0)); AddTextPrinterParameterized(SELECT_WIN_TITLE, 1, gText_RentalPkmn2, 2, 1, 0, NULL); CopyWindowToVram(SELECT_WIN_TITLE, 3); } static void Select_PrintMonSpecies(void) { u16 species; u8 x; u8 monId = sFactorySelectScreen->cursorPos; FillWindowPixelBuffer(SELECT_WIN_SPECIES, PIXEL_FILL(0)); species = GetMonData(&sFactorySelectScreen->mons[monId].monData, MON_DATA_SPECIES, NULL); StringCopy(gStringVar4, gSpeciesNames[species]); x = GetStringRightAlignXOffset(1, gStringVar4, 86); AddTextPrinterParameterized3(SELECT_WIN_SPECIES, 1, x, 1, sSpeciesNameTextColors, 0, gStringVar4); CopyWindowToVram(SELECT_WIN_SPECIES, 2); } static void Select_PrintSelectMonString(void) { const u8 *str = NULL; FillWindowPixelBuffer(SELECT_WIN_INFO, PIXEL_FILL(0)); if (sFactorySelectScreen->selectingMonsState == 1) str = gText_SelectFirstPkmn; else if (sFactorySelectScreen->selectingMonsState == 2) str = gText_SelectSecondPkmn; else if (sFactorySelectScreen->selectingMonsState == 3) str = gText_SelectThirdPkmn; else str = gText_TheseThreePkmnOkay; AddTextPrinterParameterized(SELECT_WIN_INFO, 1, str, 2, 5, 0, NULL); CopyWindowToVram(SELECT_WIN_INFO, 2); } static void Select_PrintCantSelectSameMon(void) { FillWindowPixelBuffer(SELECT_WIN_INFO, PIXEL_FILL(0)); AddTextPrinterParameterized(SELECT_WIN_INFO, 1, gText_CantSelectSamePkmn, 2, 5, 0, NULL); CopyWindowToVram(SELECT_WIN_INFO, 2); } static void Select_PrintMenuOptions(void) { u8 selectedId = sFactorySelectScreen->mons[sFactorySelectScreen->cursorPos].selectedId; PutWindowTilemap(SELECT_WIN_OPTIONS); FillWindowPixelBuffer(SELECT_WIN_OPTIONS, PIXEL_FILL(0)); AddTextPrinterParameterized3(SELECT_WIN_OPTIONS, 1, 7, 1, sMenuOptionTextColors, 0, gText_Summary); if (selectedId != 0) AddTextPrinterParameterized3(SELECT_WIN_OPTIONS, 1, 7, 17, sMenuOptionTextColors, 0, gText_Deselect); else AddTextPrinterParameterized3(SELECT_WIN_OPTIONS, 1, 7, 17, sMenuOptionTextColors, 0, gText_Rent); AddTextPrinterParameterized3(SELECT_WIN_OPTIONS, 1, 7, 33, sMenuOptionTextColors, 0, gText_Others2); CopyWindowToVram(SELECT_WIN_OPTIONS, 3); } static void Select_PrintYesNoOptions(void) { PutWindowTilemap(SELECT_WIN_YES_NO); FillWindowPixelBuffer(SELECT_WIN_YES_NO, PIXEL_FILL(0)); AddTextPrinterParameterized3(SELECT_WIN_YES_NO, 1, 7, 1, sMenuOptionTextColors, 0, gText_Yes2); AddTextPrinterParameterized3(SELECT_WIN_YES_NO, 1, 7, 17, sMenuOptionTextColors, 0, gText_No2); CopyWindowToVram(SELECT_WIN_YES_NO, 3); } static u8 Select_RunMenuOptionFunc(void) { gFactorySelect_CurrentOptionFunc = sSelect_MenuOptionFuncs[sFactorySelectScreen->menuCursorPos]; return gFactorySelect_CurrentOptionFunc(); } static u8 Select_OptionRentDeselect(void) { u8 selectedId = sFactorySelectScreen->mons[sFactorySelectScreen->cursorPos].selectedId; u16 monId = sFactorySelectScreen->mons[sFactorySelectScreen->cursorPos].monId; if (selectedId == 0 && !Select_AreSpeciesValid(monId)) { Select_PrintCantSelectSameMon(); sub_819B958(SELECT_WIN_OPTIONS); return 3; } else { CloseMonPic(sFactorySelectScreen->monPics[1], &sFactorySelectScreen->monPicAnimating, FALSE); Select_HandleMonSelectionChange(); Select_PrintSelectMonString(); sub_819B958(SELECT_WIN_OPTIONS); if (sFactorySelectScreen->selectingMonsState > 3) return 2; else return 1; } } static u8 sub_819BC9C(void) { sub_819C568(); Select_HandleMonSelectionChange(); Select_PrintSelectMonString(); sub_819B958(SELECT_WIN_OPTIONS); if (sFactorySelectScreen->selectingMonsState > 3) return 2; else return 1; } static u8 Select_OptionSummary(void) { return 0; } static u8 Select_OptionOthers(void) { CloseMonPic(sFactorySelectScreen->monPics[1], &sFactorySelectScreen->monPicAnimating, FALSE); sub_819B958(SELECT_WIN_OPTIONS); return 1; } static void Select_PrintMonCategory(void) { u16 species; u8 text[30]; u8 x; u8 monId = sFactorySelectScreen->cursorPos; if (monId < SELECTABLE_MONS_COUNT) { PutWindowTilemap(SELECT_WIN_MON_CATEGORY); FillWindowPixelBuffer(SELECT_WIN_MON_CATEGORY, PIXEL_FILL(0)); species = GetMonData(&sFactorySelectScreen->mons[monId].monData, MON_DATA_SPECIES, NULL); CopyMonCategoryText(SpeciesToNationalPokedexNum(species), text); x = GetStringRightAlignXOffset(1, text, 0x76); AddTextPrinterParameterized(SELECT_WIN_MON_CATEGORY, 1, text, x, 1, 0, NULL); CopyWindowToVram(SELECT_WIN_MON_CATEGORY, 2); } } static void Select_CreateMonSprite(void) { u8 monId = sFactorySelectScreen->cursorPos; struct Pokemon *mon = &sFactorySelectScreen->mons[monId].monData; u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL); sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite_HandleDeoxys(species, otId, personality, TRUE, 88, 32, 15, 0xFFFF); gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecY = 0; sFactorySelectScreen->monPicAnimating = FALSE; } static void Select_SetMonPicAnimating(bool8 animating) { sFactorySelectScreen->monPicAnimating = animating; } static void Select_ReshowMonSprite(void) { struct Pokemon *mon; u16 species; u32 personality, otId; sFactorySelectScreen->monPics[1].bgSpriteId = CreateSprite(&sSpriteTemplate_Select_MonPicBgAnim, 120, 64, 1); StartSpriteAffineAnim(&gSprites[sFactorySelectScreen->monPics[1].bgSpriteId], 2); mon = &sFactorySelectScreen->mons[sFactorySelectScreen->cursorPos].monData; species = GetMonData(mon, MON_DATA_SPECIES, NULL); personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); otId = GetMonData(mon, MON_DATA_OT_ID, NULL); sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite_HandleDeoxys(species, otId, personality, TRUE, 88, 32, 15, 0xFFFF); gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecY = 0; gSprites[sFactorySelectScreen->monPics[1].bgSpriteId].invisible = TRUE; } static void Select_ShowChosenMonsSprites(void) { u8 i, j; for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { for (j = 0; j < SELECTABLE_MONS_COUNT; j++) { if (sFactorySelectScreen->mons[j].selectedId == i + 1) { struct Pokemon *mon = &sFactorySelectScreen->mons[j].monData; u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL); sFactorySelectScreen->monPics[i].monSpriteId = CreateMonPicSprite_HandleDeoxys(species, otId, personality, TRUE, (i * 72) + 16, 32, i + 13, 0xFFFF); gSprites[sFactorySelectScreen->monPics[i].monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->monPics[i].monSpriteId].centerToCornerVecY = 0; break; } } } sFactorySelectScreen->monPicAnimating = FALSE; } static void sub_819C040(struct Sprite *sprite) { u8 taskId; if (sprite->affineAnimEnded && gSprites[sFactorySelectScreen->monPics[0].bgSpriteId].affineAnimEnded && gSprites[sFactorySelectScreen->monPics[2].bgSpriteId].affineAnimEnded) { sprite->invisible = TRUE; gSprites[sFactorySelectScreen->monPics[0].bgSpriteId].invisible = TRUE; gSprites[sFactorySelectScreen->monPics[2].bgSpriteId].invisible = TRUE; taskId = CreateTask(sub_819C1D0, 1); gTasks[taskId].func(taskId); sprite->callback = SpriteCallbackDummy; } } static void sub_819C100(struct Sprite *sprite) { if (sprite->affineAnimEnded && gSprites[sFactorySelectScreen->monPics[0].bgSpriteId].affineAnimEnded && gSprites[sFactorySelectScreen->monPics[2].bgSpriteId].affineAnimEnded) { FreeOamMatrix(sprite->oam.matrixNum); FreeOamMatrix(gSprites[sFactorySelectScreen->monPics[0].bgSpriteId].oam.matrixNum); FreeOamMatrix(gSprites[sFactorySelectScreen->monPics[2].bgSpriteId].oam.matrixNum); sFactorySelectScreen->monPicAnimating = FALSE; DestroySprite(&gSprites[sFactorySelectScreen->monPics[0].bgSpriteId]); DestroySprite(&gSprites[sFactorySelectScreen->monPics[2].bgSpriteId]); DestroySprite(sprite); } } // Task data for sub_819C1D0, sub_819C2D4, Task_CloseMonPic, and Task_OpenMonPic #define tWinLeft data[3] #ifndef UBFIX #define tWinRight data[24] // UB: Typo? Likely meant data[4], 24 is out of bounds #else #define tWinRight data[4] #endif #define tWinTop data[5] #define tWinBottom data[8] #define tSpriteId data[6] // TODO: Clarify, what sprite #define tIsSwapScreen data[7] static void sub_819C1D0(u8 taskId) { struct Task *task = &gTasks[taskId]; switch (task->tState) { case 0: task->tWinLeft = 16; task->tWinRight = DISPLAY_WIDTH - 16; task->tWinTop = 64; task->tWinBottom = 65; SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWinLeft, task->tWinRight)); SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_CLR | WININ_WIN0_OBJ); SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_CLR | WINOUT_WIN01_OBJ); break; case 1: ShowBg(3); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_OBJ); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(11, 4)); break; case 2: task->tWinTop -= 4; task->tWinBottom += 4; if (task->tWinTop <= 32 || task->tWinBottom >= 96) { task->tWinTop = 32; task->tWinBottom = 96; ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); } SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); if (task->tWinTop != 32) return; break; default: DestroyTask(taskId); Select_ShowChosenMonsSprites(); return; } task->tState++; } static void sub_819C2D4(u8 taskId) { struct Task *task = &gTasks[taskId]; switch (task->tState) { default: HideBg(3); gSprites[sFactorySelectScreen->monPics[1].bgSpriteId].invisible = FALSE; gSprites[sFactorySelectScreen->monPics[1].bgSpriteId].callback = sub_819C100; gSprites[sFactorySelectScreen->monPics[0].bgSpriteId].invisible = FALSE; gSprites[sFactorySelectScreen->monPics[0].bgSpriteId].callback = SpriteCallbackDummy; gSprites[sFactorySelectScreen->monPics[2].bgSpriteId].invisible = FALSE; gSprites[sFactorySelectScreen->monPics[2].bgSpriteId].callback = SpriteCallbackDummy; StartSpriteAffineAnim(&gSprites[sFactorySelectScreen->monPics[1].bgSpriteId], 1); StartSpriteAffineAnim(&gSprites[sFactorySelectScreen->monPics[0].bgSpriteId], 1); StartSpriteAffineAnim(&gSprites[sFactorySelectScreen->monPics[2].bgSpriteId], 1); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); DestroyTask(taskId); break; case 0: task->tWinLeft = 16; task->tWinRight = DISPLAY_WIDTH - 16; task->tWinTop = 32; task->tWinBottom = 96; SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWinLeft, task->tWinRight)); SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_CLR | WININ_WIN0_OBJ); SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_CLR | WINOUT_WIN01_OBJ); task->tState++; break; case 1: task->tWinTop += 4; task->tWinBottom -= 4; if (task->tWinTop >= 64 || task->tWinBottom <= 65) { task->tWinTop = 64; task->tWinBottom = 65; } SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); if (task->tWinTop == 64) task->tState++; break; } } static void sub_819C4B4(void) { sFactorySelectScreen->monPics[1].bgSpriteId = CreateSprite(&sSpriteTemplate_Select_MonPicBgAnim, 120, 64, 1); sFactorySelectScreen->monPics[0].bgSpriteId = CreateSprite(&sSpriteTemplate_Select_MonPicBgAnim, 44, 64, 1); sFactorySelectScreen->monPics[2].bgSpriteId = CreateSprite(&sSpriteTemplate_Select_MonPicBgAnim, 196, 64, 1); gSprites[sFactorySelectScreen->monPics[1].bgSpriteId].callback = sub_819C040; gSprites[sFactorySelectScreen->monPics[0].bgSpriteId].callback = SpriteCallbackDummy; gSprites[sFactorySelectScreen->monPics[2].bgSpriteId].callback = SpriteCallbackDummy; sFactorySelectScreen->monPicAnimating = TRUE; } static void sub_819C568(void) { u8 taskId; FreeAndDestroyMonPicSprite(sFactorySelectScreen->monPics[0].monSpriteId); FreeAndDestroyMonPicSprite(sFactorySelectScreen->monPics[1].monSpriteId); FreeAndDestroyMonPicSprite(sFactorySelectScreen->monPics[2].monSpriteId); taskId = CreateTask(sub_819C2D4, 1); gTasks[taskId].func(taskId); sFactorySelectScreen->monPicAnimating = TRUE; } static void Select_SetWinRegs(s16 mWin0H, s16 nWin0H, s16 mWin0V, s16 nWin0V) { SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(mWin0H, nWin0H)); SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(mWin0V, nWin0V)); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_CLR | WININ_WIN0_OBJ); SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_CLR | WINOUT_WIN01_OBJ); } static bool32 Select_AreSpeciesValid(u16 monId) { u8 i, j; u32 species = gFacilityTrainerMons[monId].species; u8 selectState = sFactorySelectScreen->selectingMonsState; for (i = 1; i < selectState; i++) { for (j = 0; j < SELECTABLE_MONS_COUNT; j++) { if (sFactorySelectScreen->mons[j].selectedId == i) { if (gFacilityTrainerMons[sFactorySelectScreen->mons[j].monId].species == species) return FALSE; break; } } } return TRUE; } static void Select_Task_FadeSpeciesName(u8 taskId) { switch (gTasks[taskId].tState) { case FADESTATE_INIT: sFactorySelectScreen->fadeSpeciesNameCoeffDelay = 0; sFactorySelectScreen->fadeSpeciesNameCoeff = 0; sFactorySelectScreen->fadeSpeciesNameFadeOut = TRUE; gTasks[taskId].tState = FADESTATE_RUN; break; case FADESTATE_RUN: if (sFactorySelectScreen->fadeSpeciesNameActive) { if (sFactorySelectScreen->faceSpeciesNameDelay) { gTasks[taskId].tState = FADESTATE_DELAY; } else { sFactorySelectScreen->fadeSpeciesNameCoeffDelay++; if (sFactorySelectScreen->fadeSpeciesNameCoeffDelay > 6) { sFactorySelectScreen->fadeSpeciesNameCoeffDelay = 0; if (!sFactorySelectScreen->fadeSpeciesNameFadeOut) sFactorySelectScreen->fadeSpeciesNameCoeff--; else sFactorySelectScreen->fadeSpeciesNameCoeff++; } BlendPalettes(0x4000, sFactorySelectScreen->fadeSpeciesNameCoeff, 0); if (sFactorySelectScreen->fadeSpeciesNameCoeff > 5) { sFactorySelectScreen->fadeSpeciesNameFadeOut = FALSE; } else if (sFactorySelectScreen->fadeSpeciesNameCoeff == 0) { gTasks[taskId].tState = FADESTATE_DELAY; sFactorySelectScreen->fadeSpeciesNameFadeOut = TRUE; } } } break; case FADESTATE_DELAY: if (sFactorySelectScreen->faceSpeciesNameDelay > 14) { sFactorySelectScreen->faceSpeciesNameDelay = 0; gTasks[taskId].tState = FADESTATE_RUN; } else { sFactorySelectScreen->faceSpeciesNameDelay++; } break; } } // Swap Screen's section begins here. static void Swap_CB2(void) { AnimateSprites(); BuildOamBuffer(); RunTextPrinters(); UpdatePaletteFade(); RunTasks(); } static void Swap_VblankCb(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } static void CopySwappedMonData(void) { u8 friendship; gPlayerParty[sFactorySwapScreen->playerMonId] = gEnemyParty[sFactorySwapScreen->enemyMonId]; friendship = 0; SetMonData(&gPlayerParty[sFactorySwapScreen->playerMonId], MON_DATA_FRIENDSHIP, &friendship); gSaveBlock2Ptr->frontier.rentalMons[sFactorySwapScreen->playerMonId].monId = gSaveBlock2Ptr->frontier.rentalMons[sFactorySwapScreen->enemyMonId + FRONTIER_PARTY_SIZE].monId; gSaveBlock2Ptr->frontier.rentalMons[sFactorySwapScreen->playerMonId].ivs = gSaveBlock2Ptr->frontier.rentalMons[sFactorySwapScreen->enemyMonId + FRONTIER_PARTY_SIZE].ivs; gSaveBlock2Ptr->frontier.rentalMons[sFactorySwapScreen->playerMonId].personality = GetMonData(&gEnemyParty[sFactorySwapScreen->enemyMonId], MON_DATA_PERSONALITY, NULL); gSaveBlock2Ptr->frontier.rentalMons[sFactorySwapScreen->playerMonId].abilityNum = GetBoxMonData(&gEnemyParty[sFactorySwapScreen->enemyMonId].box, MON_DATA_ABILITY_NUM, NULL); } static void Swap_Task_OpenSummaryScreen(u8 taskId) { switch (gTasks[taskId].tState) { case 6: BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); gTasks[taskId].tState = 7; break; case 7: if (!gPaletteFade.active) { DestroyTask(sFactorySwapScreen->fadeSpeciesNameTaskId); HideMonPic(sFactorySwapScreen->monPic, &sFactorySwapScreen->monPicAnimating); Swap_DestroyAllSprites(); FREE_AND_SET_NULL(sSwapMenuTilesetBuffer); FREE_AND_SET_NULL(sSwapMonPicBgTilesetBuffer); FREE_AND_SET_NULL(sSwapMenuTilemapBuffer); FREE_AND_SET_NULL(sSwapMonPicBgTilemapBuffer); FreeAllWindowBuffers(); gTasks[taskId].tState = 8; } break; case 8: DestroyTask(taskId); sFactorySwapScreen->fromSummaryScreen = TRUE; sFactorySwapScreen->speciesNameColorBackup = gPlttBufferUnfaded[244]; ShowPokemonSummaryScreen(PSS_MODE_NORMAL, gPlayerParty, sFactorySwapScreen->cursorPos, FRONTIER_PARTY_SIZE - 1, CB2_InitSwapScreen); break; } } static void Swap_Task_Exit(u8 taskId) { if (sFactorySwapScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case 0: // Set return value for script // TRUE if player kept their current pokemon if (sFactorySwapScreen->monSwapped == TRUE) { gTasks[taskId].tState++; gSpecialVar_Result = FALSE; } else { gTasks[taskId].tState = 2; gSpecialVar_Result = TRUE; } break; case 1: if (sFactorySwapScreen->monSwapped == TRUE) { sFactorySwapScreen->enemyMonId = sFactorySwapScreen->cursorPos; CopySwappedMonData(); } gTasks[taskId].tState++; break; case 2: BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); gTasks[taskId].tState++; break; case 3: if (!UpdatePaletteFade()) { DestroyTask(sFactorySwapScreen->fadeSpeciesNameTaskId); Swap_DestroyAllSprites(); FREE_AND_SET_NULL(sSwapMenuTilesetBuffer); FREE_AND_SET_NULL(sSwapMonPicBgTilesetBuffer); FREE_AND_SET_NULL(sSwapMenuTilemapBuffer); FREE_AND_SET_NULL(sSwapMonPicBgTilemapBuffer); FREE_AND_SET_NULL(sFactorySwapScreen); FreeAllWindowBuffers(); SetMainCallback2(CB2_ReturnToFieldContinueScript); DestroyTask(taskId); } break; } } #define STATE_SHOW_YES_NO 4 #define STATE_HANDLE_INPUT 5 #define tSaidYes data[1] #define tFollowUpTaskState data[5] #define tFollowUpTaskPtrHi data[6] #define tFollowUpTaskPtrLo data[7] static void Swap_Task_HandleYesNo(u8 taskId) { u16 loPtr, hiPtr; if (sFactorySwapScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case STATE_SHOW_YES_NO: Swap_ShowYesNoOptions(); gTasks[taskId].tState = STATE_HANDLE_INPUT; break; case STATE_HANDLE_INPUT: if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); if (sFactorySwapScreen->yesNoCursorPos == 0) { // Selected Yes gTasks[taskId].tSaidYes = TRUE; hiPtr = gTasks[taskId].tFollowUpTaskPtrHi; loPtr = gTasks[taskId].tFollowUpTaskPtrLo; gTasks[taskId].func = (void*)((hiPtr << 16) | loPtr); } else { // Selected No gTasks[taskId].tSaidYes = FALSE; Swap_ErasePopupMenu(SWAP_WIN_YES_NO); hiPtr = gTasks[taskId].tFollowUpTaskPtrHi; loPtr = gTasks[taskId].tFollowUpTaskPtrLo; gTasks[taskId].func = (void*)((hiPtr << 16) | loPtr); } } else if (JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); gTasks[taskId].tSaidYes = FALSE; Swap_ErasePopupMenu(SWAP_WIN_YES_NO); hiPtr = gTasks[taskId].tFollowUpTaskPtrHi; loPtr = gTasks[taskId].tFollowUpTaskPtrLo; gTasks[taskId].func = (void*)((hiPtr << 16) | loPtr); } else if (JOY_REPEAT(DPAD_UP)) { PlaySE(SE_SELECT); Swap_UpdateYesNoCursorPosition(-1); } else if (JOY_REPEAT(DPAD_DOWN)) { PlaySE(SE_SELECT); Swap_UpdateYesNoCursorPosition(1); } break; } } static void Swap_HandleQuitSwappingResposne(u8 taskId) { if (gTasks[taskId].tSaidYes == TRUE) { gTasks[taskId].tState = 0; gTasks[taskId].func = Swap_Task_Exit; } else { gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_Task_HandleChooseMons) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_Task_HandleChooseMons); gTasks[taskId].tFollowUpTaskState = 1; gTasks[taskId].func = sub_819D770; } } static void Swap_AskQuitSwapping(u8 taskId) { if (gTasks[taskId].tState == 0) { Swap_PrintOnInfoWindow(gText_QuitSwapping); sFactorySwapScreen->monSwapped = FALSE; gTasks[taskId].tState = STATE_SHOW_YES_NO; gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_HandleQuitSwappingResposne) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_HandleQuitSwappingResposne); gTasks[taskId].func = Swap_Task_HandleYesNo; } } static void Swap_HandleAcceptMonResponse(u8 taskId) { CloseMonPic(sFactorySwapScreen->monPic, &sFactorySwapScreen->monPicAnimating, TRUE); if (gTasks[taskId].tSaidYes == TRUE) { gTasks[taskId].tState = 0; gTasks[taskId].func = Swap_Task_Exit; } else { gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_Task_HandleChooseMons) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_Task_HandleChooseMons); gTasks[taskId].tFollowUpTaskState = 1; gTasks[taskId].func = sub_819D770; } } static void Swap_AskAcceptMon(u8 taskId) { if (gTasks[taskId].tState == 0) { OpenMonPic(&sFactorySwapScreen->monPic.bgSpriteId, &sFactorySwapScreen->monPicAnimating, TRUE); Swap_PrintOnInfoWindow(gText_AcceptThisPkmn); sFactorySwapScreen->monSwapped = TRUE; gTasks[taskId].tState = STATE_SHOW_YES_NO; gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_HandleAcceptMonResponse) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_HandleAcceptMonResponse); gTasks[taskId].func = Swap_Task_HandleYesNo; } } static void Swap_Task_HandleMenu(u8 taskId) { switch (gTasks[taskId].tState) { case 2: if (!sFactorySwapScreen->fromSummaryScreen) OpenMonPic(&sFactorySwapScreen->monPic.bgSpriteId, &sFactorySwapScreen->monPicAnimating, TRUE); gTasks[taskId].tState = 9; break; case 9: if (sFactorySwapScreen->monPicAnimating != TRUE) { Swap_ShowMenuOptions(); gTasks[taskId].tState = 3; } break; case 3: if (sFactorySwapScreen->monPicAnimating != TRUE) { if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); Swap_RunMenuOptionFunc(taskId); } else if (JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); CloseMonPic(sFactorySwapScreen->monPic, &sFactorySwapScreen->monPicAnimating, TRUE); Swap_ErasePopupMenu(SWAP_WIN_OPTIONS); gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_Task_HandleChooseMons) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_Task_HandleChooseMons); gTasks[taskId].tFollowUpTaskState = 1; gTasks[taskId].func = sub_819D770; } else if (JOY_REPEAT(DPAD_UP)) { Swap_UpdateMenuCursorPosition(-1); } else if (JOY_REPEAT(DPAD_DOWN)) { Swap_UpdateMenuCursorPosition(1); } } break; } } static void Swap_Task_HandleChooseMons(u8 taskId) { switch (gTasks[taskId].tState) { case 0: if (!gPaletteFade.active) { sFactorySwapScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = 1; } break; case 1: if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); sFactorySwapScreen->fadeSpeciesNameActive = FALSE; Swap_PrintMonSpecies2(); sub_819EAC0(); Swap_RunActionFunc(taskId); } else if (JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); sFactorySwapScreen->fadeSpeciesNameActive = FALSE; Swap_PrintMonSpecies2(); sub_819EAC0(); gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_AskQuitSwapping) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_AskQuitSwapping); gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskState = 0; gTasks[taskId].func = sub_819D588; } else if (JOY_REPEAT(DPAD_LEFT)) { Swap_UpdateBallCursorPosition(-1); Swap_PrintMonCategory(); Swap_PrintMonSpecies(); } else if (JOY_REPEAT(DPAD_RIGHT)) { Swap_UpdateBallCursorPosition(1); Swap_PrintMonCategory(); Swap_PrintMonSpecies(); } else if (JOY_REPEAT(DPAD_DOWN)) { Swap_UpdateActionCursorPosition(1); Swap_PrintMonCategory(); Swap_PrintMonSpecies(); } else if (JOY_REPEAT(DPAD_UP)) { Swap_UpdateActionCursorPosition(-1); Swap_PrintMonCategory(); Swap_PrintMonSpecies(); } break; } } static void Swap_Task_FadeSpeciesName(u8 taskId) { switch (gTasks[taskId].tState) { case FADESTATE_INIT: sFactorySwapScreen->fadeSpeciesNameCoeffDelay = 0; sFactorySwapScreen->fadeSpeciesNameCoeff = 0; sFactorySwapScreen->fadeSpeciesNameFadeOut = TRUE; gTasks[taskId].tState = FADESTATE_RUN; break; case FADESTATE_RUN: if (sFactorySwapScreen->fadeSpeciesNameActive) { if (sFactorySwapScreen->faceSpeciesNameDelay) { gTasks[taskId].tState = FADESTATE_DELAY; } else { sFactorySwapScreen->fadeSpeciesNameCoeffDelay++; if (sFactorySwapScreen->fadeSpeciesNameCoeffDelay > 6) { sFactorySwapScreen->fadeSpeciesNameCoeffDelay = 0; if (!sFactorySwapScreen->fadeSpeciesNameFadeOut) sFactorySwapScreen->fadeSpeciesNameCoeff--; else sFactorySwapScreen->fadeSpeciesNameCoeff++; } BlendPalettes(0x4000, sFactorySwapScreen->fadeSpeciesNameCoeff, 0); if (sFactorySwapScreen->fadeSpeciesNameCoeff > 5) { sFactorySwapScreen->fadeSpeciesNameFadeOut = FALSE; } else if (sFactorySwapScreen->fadeSpeciesNameCoeff == 0) { gTasks[taskId].tState = FADESTATE_DELAY; sFactorySwapScreen->fadeSpeciesNameFadeOut = TRUE; } } } break; case FADESTATE_DELAY: if (sFactorySwapScreen->faceSpeciesNameDelay > 14) { sFactorySwapScreen->faceSpeciesNameDelay = 0; gTasks[taskId].tState = FADESTATE_RUN; } else { sFactorySwapScreen->faceSpeciesNameDelay++; } break; } } static void Swap_Task_FadeSpeciesName2(u8 taskId) { switch (gTasks[taskId].tState) { case 0: sFactorySwapScreen->fadeSpeciesNameCoeffDelay = 0; gTasks[taskId].data[4] = 0; gTasks[taskId].tState++; break; case 1: LoadPalette(&gPlttBufferUnfaded[0xF0], 0xE0, 0xA); gTasks[taskId].tState++; break; case 2: if (sFactorySwapScreen->fadeSpeciesNameCoeff > 15) { gTasks[taskId].data[4] = 1; gTasks[taskId].tState++; } sFactorySwapScreen->fadeSpeciesNameCoeffDelay++; if (sFactorySwapScreen->fadeSpeciesNameCoeffDelay > 3) { sFactorySwapScreen->fadeSpeciesNameCoeffDelay = 0; gPlttBufferUnfaded[244] = gPlttBufferFaded[228]; sFactorySwapScreen->fadeSpeciesNameCoeff++; } BlendPalettes(0x4000, sFactorySwapScreen->fadeSpeciesNameCoeff, 0); break; } } static void sub_819D12C(u8 taskId) { s8 i; u8 var_2C; bool8 destroyTask; switch (gTasks[taskId].tState) { case 0: gTasks[taskId].data[1] = 0; gTasks[taskId].data[2] = 0; gTasks[taskId].data[3] = 0; gTasks[taskId].tState = 1; break; case 1: var_2C = 0; for (i = FRONTIER_PARTY_SIZE - 1; i >= 0; i--) { if (i != FRONTIER_PARTY_SIZE - 1) { u8 posX = var_2C - gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x; if (posX == 16 || gTasks[taskId].data[i + 2] == 1) { var_2C = gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x; gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x += 10; } else if (posX > 16) { gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x = gSprites[sFactorySwapScreen->ballSpriteIds[i + 1]].pos1.x - 48; } } else { var_2C = gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x; gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x += 10; } if (gTasks[taskId].data[i + 1] == 1) { if (gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x > (i * 48) + 72) { gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x = (i * 48) + 72; destroyTask = TRUE; } else if (gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x == (i * 48) + 72) { destroyTask = TRUE; } else { destroyTask = FALSE; } } else { destroyTask = FALSE; } if (gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x - 16 > DISPLAY_WIDTH) { var_2C = gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x; gSprites[sFactorySwapScreen->ballSpriteIds[i]].pos1.x = -16; if (sFactorySwapScreen->inEnemyScreen == TRUE) gSprites[sFactorySwapScreen->ballSpriteIds[i]].oam.paletteNum = IndexOfSpritePaletteTag(PALTAG_BALL_SELECTED); else gSprites[sFactorySwapScreen->ballSpriteIds[i]].oam.paletteNum = IndexOfSpritePaletteTag(PALTAG_BALL_GRAY); gTasks[taskId].data[i + 1] = 1; } } if (destroyTask == TRUE) DestroyTask(taskId); break; } } static void sub_819D324(u8 taskId) { u8 i, j; s32 posX = 0; s8 r4 = gTasks[taskId].data[3]; bool8 r1; s16 currPosX; u8 taskId2; if (gTasks[taskId].data[2] == 1) r4 *= -1; switch (gTasks[taskId].tState) { case 0: currPosX = gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0][0]].pos1.x; if (!gTasks[taskId].data[2]) { if (currPosX + r4 < DISPLAY_WIDTH) { r1 = TRUE; } else { r1 = FALSE; posX = DISPLAY_WIDTH; } } else { if (currPosX + r4 > DISPLAY_HEIGHT) { r1 = TRUE; } else { r1 = FALSE; posX = DISPLAY_HEIGHT; } } if (r1 == TRUE) { for (i = 0; i < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0]); i++) { for (j = 0; j < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds); j++) gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[j][i]].pos1.x += r4; } } else { for (j = 0; j < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds); j++) { gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[j][0]].pos1.x = posX; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[j][1]].pos1.x = posX + 16; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[j][2]].pos1.x = posX + 48; } taskId2 = gTasks[taskId].data[1]; gTasks[taskId2].data[3] = 1; DestroyTask(taskId); } break; case 1: currPosX = gSprites[sFactorySwapScreen->cancelButtonSpriteIds[0][0]].pos1.x; if (!gTasks[taskId].data[2]) { if (currPosX + r4 < DISPLAY_WIDTH) { r1 = TRUE; } else { r1 = FALSE; posX = DISPLAY_WIDTH; } } else { if (currPosX + r4 > DISPLAY_HEIGHT + 32) { r1 = TRUE; } else { r1 = FALSE; posX = DISPLAY_HEIGHT + 32; } } if (r1 == TRUE) { for (i = 0; i < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds); i++) { for (j = 0; j < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds[0]); j++) gSprites[sFactorySwapScreen->cancelButtonSpriteIds[j][i]].pos1.x += r4; } } else { for (j = 0; j < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds); j++) { gSprites[sFactorySwapScreen->cancelButtonSpriteIds[j][0]].pos1.x = posX; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[j][1]].pos1.x = posX + 16; } taskId2 = gTasks[taskId].data[1]; gTasks[taskId2].data[4] = 1; DestroyTask(taskId); } break; } } static void sub_819D588(u8 taskId) { u8 anotherTaskId; u16 hiPtr, loPtr; switch (gTasks[taskId].tState) { case 0: LoadPalette(sSwapText_Pal, 0xE0, sizeof(sSwapText_Pal)); Swap_PrintActionStrings(); PutWindowTilemap(SWAP_WIN_5); gTasks[taskId].tState++; break; case 1: Swap_ErasePopupMenu(SWAP_WIN_OPTIONS); gTasks[taskId].tState++; break; case 2: BeginNormalPaletteFade(0x4000, 0, 0, 16, sPokeballGray_Pal[37]); gTasks[taskId].tState++; break; case 3: if (!gPaletteFade.active) { FillWindowPixelBuffer(SWAP_WIN_5, PIXEL_FILL(0)); CopyWindowToVram(SWAP_WIN_5, 2); if (sFactorySwapScreen->inEnemyScreen == TRUE) { anotherTaskId = CreateTask(sub_819D324, 0); gTasks[taskId].data[3] = 0; gTasks[anotherTaskId].data[1] = taskId; gTasks[anotherTaskId].tState = 0; gTasks[anotherTaskId].data[2] = 0; gTasks[anotherTaskId].data[3] = 6; gTasks[taskId].data[2] = 5; gTasks[taskId].tState++; } else { anotherTaskId = CreateTask(sub_819D324, 0); gTasks[taskId].data[3] = 1; gTasks[taskId].data[4] = 0; gTasks[anotherTaskId].data[1] = taskId; gTasks[anotherTaskId].tState = 1; gTasks[anotherTaskId].data[2] = 0; gTasks[anotherTaskId].data[3] = 6; gTasks[taskId].tState += 2; } } break; case 4: if (gTasks[taskId].data[2] == 0) { anotherTaskId = CreateTask(sub_819D324, 0); gTasks[taskId].data[4] = 0; gTasks[anotherTaskId].data[1] = taskId; gTasks[anotherTaskId].tState = 1; gTasks[anotherTaskId].data[2] = 0; gTasks[anotherTaskId].data[3] = 6; gTasks[taskId].tState++; } else { gTasks[taskId].data[2]--; } break; case 5: if (gTasks[taskId].data[3] == 1 && gTasks[taskId].data[4] == 1) { gTasks[taskId].tState = gTasks[taskId].tFollowUpTaskState; hiPtr = gTasks[taskId].tFollowUpTaskPtrHi; loPtr = gTasks[taskId].tFollowUpTaskPtrLo; gTasks[taskId].func = (void *)((hiPtr << 16) | (loPtr)); } break; } } static void sub_819D770(u8 taskId) { u8 anotherTaskId; u16 hiPtr, loPtr; if (sFactorySwapScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case 0: if (sFactorySwapScreen->inEnemyScreen == TRUE) { anotherTaskId = CreateTask(sub_819D324, 0); gTasks[taskId].data[3] = 0; gTasks[anotherTaskId].data[1] = taskId; gTasks[anotherTaskId].tState = 0; gTasks[anotherTaskId].data[2] = 1; gTasks[anotherTaskId].data[3] = 6; gTasks[taskId].data[2] = 10; gTasks[taskId].tState++; } else { anotherTaskId = CreateTask(sub_819D324, 0); gTasks[taskId].data[3] = 1; gTasks[taskId].data[4] = 0; gTasks[anotherTaskId].data[1] = taskId; gTasks[anotherTaskId].tState = 1; gTasks[anotherTaskId].data[2] = 1; gTasks[anotherTaskId].data[3] = 6; gTasks[taskId].tState += 2; } break; case 1: if (gTasks[taskId].data[2] == 0) { anotherTaskId = CreateTask(sub_819D324, 0); gTasks[taskId].data[4] = 0; gTasks[anotherTaskId].data[1] = taskId; gTasks[anotherTaskId].tState = 1; gTasks[anotherTaskId].data[2] = 1; gTasks[anotherTaskId].data[3] = 6; gTasks[taskId].tState++; } else { gTasks[taskId].data[2]--; } break; case 2: if (gTasks[taskId].data[3] == 1 && gTasks[taskId].data[4] == 1) { gPlttBufferFaded[226] = sPokeballGray_Pal[37]; Swap_PrintActionStrings(); PutWindowTilemap(SWAP_WIN_5); gTasks[taskId].tState++; } break; case 3: BeginNormalPaletteFade(0x4000, 0, 16, 0, sPokeballGray_Pal[37]); gTasks[taskId].tState++; break; case 4: if (!gPaletteFade.active) { Swap_PrintOneActionString(0); gTasks[taskId].tState++; } break; case 5: Swap_PrintOneActionString(1); PutWindowTilemap(SWAP_WIN_OPTIONS); gTasks[taskId].tState++; break; case 6: FillWindowPixelBuffer(SWAP_WIN_5, PIXEL_FILL(0)); CopyWindowToVram(SWAP_WIN_5, 2); gTasks[taskId].tState++; break; case 7: if (!sFactorySwapScreen->inEnemyScreen) Swap_PrintOnInfoWindow(gText_SelectPkmnToSwap); else Swap_PrintOnInfoWindow(gText_SelectPkmnToAccept); if (sFactorySwapScreen->cursorPos < FRONTIER_PARTY_SIZE) gSprites[sFactorySwapScreen->cursorSpriteId].invisible = FALSE; Swap_PrintMonCategory(); gTasks[taskId].tState++; break; case 8: Swap_PrintMonSpecies3(); sub_819EADC(); sFactorySwapScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = gTasks[taskId].tFollowUpTaskState; hiPtr = gTasks[taskId].tFollowUpTaskPtrHi; loPtr = gTasks[taskId].tFollowUpTaskPtrLo; gTasks[taskId].func = (void *)((hiPtr << 16) | (loPtr)); break; } } static void sub_819D9EC(u8 taskId) { u8 i; if (sFactorySwapScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case 0: Swap_PrintMonSpecies3(); gTasks[taskId].tState++; break; case 1: sub_819EADC(); gSprites[sFactorySwapScreen->cursorSpriteId].invisible = TRUE; gTasks[taskId].tState++; break; case 2: CreateTask(sub_819D12C, 0); gTasks[sFactorySwapScreen->fadeSpeciesNameTaskId].func = Swap_Task_FadeSpeciesName2; gTasks[taskId].tState++; break; case 3: if (!FuncIsActiveTask(sub_819D12C) && gTasks[sFactorySwapScreen->fadeSpeciesNameTaskId].data[4] == 1) { sub_819EAC0(); if (!sFactorySwapScreen->inEnemyScreen) { Swap_InitActions(SWAP_ENEMY_SCREEN); } else { Swap_InitActions(SWAP_PLAYER_SCREEN); // Hide "Pkmn for Swap" button for (i = 0; i < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0]); i++) gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[1][i]].invisible = TRUE; } gSprites[sFactorySwapScreen->cursorSpriteId].pos1.x = gSprites[sFactorySwapScreen->ballSpriteIds[sFactorySwapScreen->cursorPos]].pos1.x; gTasks[sFactorySwapScreen->fadeSpeciesNameTaskId].func = Swap_Task_FadeSpeciesName; sFactorySwapScreen->fadeSpeciesNameCoeffDelay = 0; sFactorySwapScreen->fadeSpeciesNameCoeff = 6; sFactorySwapScreen->fadeSpeciesNameFadeOut = FALSE; gTasks[sFactorySwapScreen->fadeSpeciesNameTaskId].tState = 1; gTasks[taskId].tState++; } break; case 4: gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_Task_HandleChooseMons) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_Task_HandleChooseMons); gTasks[taskId].tFollowUpTaskState = 1; gTasks[taskId].func = sub_819D770; break; } } static void Swap_InitStruct(void) { if (sFactorySwapScreen == NULL) { sFactorySwapScreen = AllocZeroed(sizeof(*sFactorySwapScreen)); sFactorySwapScreen->cursorPos = 0; sFactorySwapScreen->monPicAnimating = FALSE; sFactorySwapScreen->fromSummaryScreen = FALSE; } } void DoBattleFactorySwapScreen(void) { sFactorySwapScreen = NULL; SetMainCallback2(CB2_InitSwapScreen); } static void CB2_InitSwapScreen(void) { u8 taskId; switch (gMain.state) { case 0: SetHBlankCallback(NULL); SetVBlankCallback(NULL); CpuFill32(0, (void *)VRAM, VRAM_SIZE); ResetBgsAndClearDma3BusyFlags(0); InitBgsFromTemplates(0, sSwap_BgTemplates, ARRAY_COUNT(sSwap_BgTemplates)); InitWindows(sSwap_WindowTemplates); DeactivateAllTextPrinters(); gMain.state++; break; case 1: sSwapMenuTilesetBuffer = Alloc(0x440); sSwapMonPicBgTilesetBuffer = AllocZeroed(0x440); sSwapMenuTilemapBuffer = Alloc(BG_SCREEN_SIZE); sSwapMonPicBgTilemapBuffer = AllocZeroed(BG_SCREEN_SIZE); ChangeBgX(0, 0, 0); ChangeBgY(0, 0, 0); ChangeBgX(1, 0, 0); ChangeBgY(1, 0, 0); ChangeBgX(2, 0, 0); ChangeBgY(2, 0, 0); ChangeBgX(3, 0, 0); ChangeBgY(3, 0, 0); SetGpuReg(REG_OFFSET_BLDY, 0); SetGpuReg(REG_OFFSET_MOSAIC, 0); SetGpuReg(REG_OFFSET_WIN0H, 0); SetGpuReg(REG_OFFSET_WIN0V, 0); SetGpuReg(REG_OFFSET_WIN1H, 0); SetGpuReg(REG_OFFSET_WIN1V, 0); SetGpuReg(REG_OFFSET_WININ, 0); SetGpuReg(REG_OFFSET_WINOUT, 0); gMain.state++; break; case 2: ResetPaletteFade(); ResetSpriteData(); ResetTasks(); FreeAllSpritePalettes(); ResetAllPicSprites(); CpuCopy16(gFrontierFactorySelectMenu_Gfx, sSwapMenuTilesetBuffer, 0x440); CpuCopy16(sMonPicBg_Gfx, sSwapMonPicBgTilesetBuffer, 0x60); LoadBgTiles(1, sSwapMenuTilesetBuffer, 0x440, 0); LoadBgTiles(3, sSwapMonPicBgTilesetBuffer, 0x60, 0); CpuCopy16(gFrontierFactorySelectMenu_Tilemap, sSwapMenuTilemapBuffer, BG_SCREEN_SIZE); LoadBgTilemap(1, sSwapMenuTilemapBuffer, BG_SCREEN_SIZE, 0); LoadPalette(gFrontierFactorySelectMenu_Pal, 0, 0x40); LoadPalette(sSwapText_Pal, 0xF0, sizeof(sSwapText_Pal)); LoadPalette(sSwapText_Pal, 0xE0, sizeof(sSwapText_Pal)); LoadPalette(sMonPicBg_Pal, 0x20, 4); gMain.state++; break; case 3: SetBgTilemapBuffer(3, sSwapMonPicBgTilemapBuffer); CopyToBgTilemapBufferRect(3, sMonPicBg_Tilemap, 11, 4, 8, 8); CopyBgTilemapBufferToVram(3); gMain.state++; break; case 4: LoadSpritePalettes(sSwap_SpritePalettes); LoadSpriteSheets(sSwap_SpriteSheets); LoadCompressedSpriteSheet(sSwap_BallGfx); SetVBlankCallback(Swap_VblankCb); gMain.state++; break; case 5: if (sFactorySwapScreen->fromSummaryScreen == TRUE) sFactorySwapScreen->cursorPos = gLastViewedMonIndex; gMain.state++; break; case 6: Swap_InitStruct(); Swap_InitAllSprites(); if (sFactorySwapScreen->fromSummaryScreen == TRUE) Swap_ShowSummaryMonSprite(); Swap_InitActions(SWAP_PLAYER_SCREEN); gMain.state++; break; case 7: Swap_PrintOnInfoWindow(gText_SelectPkmnToSwap); PutWindowTilemap(SWAP_WIN_INFO); gMain.state++; break; case 8: Swap_PrintMonCategory(); PutWindowTilemap(SWAP_WIN_MON_CATEGORY); gMain.state++; break; case 9: if (!sFactorySwapScreen->fromSummaryScreen) Swap_PrintMonSpecies(); PutWindowTilemap(SWAP_WIN_SPECIES); gMain.state++; break; case 10: Swap_PrintPkmnSwap(); PutWindowTilemap(SWAP_WIN_TITLE); gMain.state++; break; case 11: gMain.state++; break; case 12: if (sFactorySwapScreen->fromSummaryScreen) Swap_PrintMonSpecies2(); gMain.state++; break; case 13: Swap_PrintActionStrings2(); PutWindowTilemap(SWAP_WIN_OPTIONS); gMain.state++; break; case 14: BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); ShowBg(0); ShowBg(1); ShowBg(2); if (sFactorySwapScreen->fromSummaryScreen == TRUE) { ShowBg(3); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_OBJ); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(11, 4)); } else { HideBg(3); } gMain.state++; break; case 15: sFactorySwapScreen->fadeSpeciesNameTaskId = CreateTask(Swap_Task_FadeSpeciesName, 0); if (!sFactorySwapScreen->fromSummaryScreen) { gTasks[sFactorySwapScreen->fadeSpeciesNameTaskId].tState = 0; taskId = CreateTask(Swap_Task_HandleChooseMons, 0); gTasks[taskId].tState = 0; } else { sub_819EAF8(); gTasks[sFactorySwapScreen->fadeSpeciesNameTaskId].tState = 1; sFactorySwapScreen->fadeSpeciesNameActive = FALSE; taskId = CreateTask(Swap_Task_HandleMenu, 0); gTasks[taskId].tState = 2; } SetMainCallback2(Swap_CB2); break; } } static void Swap_InitAllSprites(void) { u8 i; u8 x; struct SpriteTemplate spriteTemplate; spriteTemplate = sSpriteTemplate_Swap_Pokeball; spriteTemplate.paletteTag = PALTAG_BALL_SELECTED; for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { sFactorySwapScreen->ballSpriteIds[i] = CreateSprite(&spriteTemplate, (48 * i) + 72, 64, 1); gSprites[sFactorySwapScreen->ballSpriteIds[i]].data[0] = 0; } sFactorySwapScreen->cursorSpriteId = CreateSprite(&sSpriteTemplate_Swap_Arrow, gSprites[sFactorySwapScreen->ballSpriteIds[sFactorySwapScreen->cursorPos]].pos1.x, 88, 0); sFactorySwapScreen->menuCursor1SpriteId = CreateSprite(&sSpriteTemplate_Swap_MenuHighlightLeft, 176, 112, 0); sFactorySwapScreen->menuCursor2SpriteId = CreateSprite(&sSpriteTemplate_Swap_MenuHighlightRight, 176, 144, 0); gSprites[sFactorySwapScreen->menuCursor1SpriteId].invisible = TRUE; gSprites[sFactorySwapScreen->menuCursor2SpriteId].invisible = TRUE; gSprites[sFactorySwapScreen->menuCursor1SpriteId].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->menuCursor1SpriteId].centerToCornerVecY = 0; gSprites[sFactorySwapScreen->menuCursor2SpriteId].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->menuCursor2SpriteId].centerToCornerVecY = 0; if (sFactorySwapScreen->fromSummaryScreen == TRUE) x = DISPLAY_WIDTH; else x = DISPLAY_WIDTH - 48; // Unusual way to create sprites // The sprite template for the selector arrow is re-used // with the tiles swapped out spriteTemplate = sSpriteTemplate_Swap_Arrow; spriteTemplate.tileTag = GFXTAG_ACTION_BOX_LEFT; sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0][0] = CreateSprite(&spriteTemplate, DISPLAY_WIDTH, 120, 10); spriteTemplate = sSpriteTemplate_Swap_MenuHighlightLeft; spriteTemplate.tileTag = GFXTAG_ACTION_BOX_RIGHT; sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0][1] = CreateSprite(&spriteTemplate, DISPLAY_WIDTH + 16, 120, 10); sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0][2] = CreateSprite(&spriteTemplate, DISPLAY_WIDTH + 48, 120, 10); spriteTemplate = sSpriteTemplate_Swap_Arrow; spriteTemplate.tileTag = GFXTAG_ACTION_HIGHLIGHT_LEFT; sFactorySwapScreen->pkmnForSwapButtonSpriteIds[1][0] = CreateSprite(&spriteTemplate, DISPLAY_WIDTH, 120, 1); spriteTemplate = sSpriteTemplate_Swap_MenuHighlightLeft; spriteTemplate.tileTag = GFXTAG_ACTION_HIGHLIGHT_MIDDLE; sFactorySwapScreen->pkmnForSwapButtonSpriteIds[1][1] = CreateSprite(&spriteTemplate, DISPLAY_WIDTH + 16, 120, 1); spriteTemplate.tileTag = GFXTAG_ACTION_HIGHLIGHT_RIGHT; sFactorySwapScreen->pkmnForSwapButtonSpriteIds[1][2] = CreateSprite(&spriteTemplate, DISPLAY_WIDTH + 48, 120, 1); spriteTemplate = sSpriteTemplate_Swap_Arrow; spriteTemplate.tileTag = GFXTAG_ACTION_BOX_LEFT; sFactorySwapScreen->cancelButtonSpriteIds[0][0] = CreateSprite(&spriteTemplate, x, 144, 10); spriteTemplate = sSpriteTemplate_Swap_MenuHighlightLeft; spriteTemplate.tileTag = GFXTAG_ACTION_BOX_RIGHT; sFactorySwapScreen->cancelButtonSpriteIds[0][1] = CreateSprite(&spriteTemplate, x + 16, 144, 10); spriteTemplate = sSpriteTemplate_Swap_Arrow; spriteTemplate.tileTag = GFXTAG_ACTION_HIGHLIGHT_LEFT; sFactorySwapScreen->cancelButtonSpriteIds[1][0] = CreateSprite(&spriteTemplate, x, 144, 1); spriteTemplate = sSpriteTemplate_Swap_MenuHighlightLeft; spriteTemplate.tileTag = GFXTAG_ACTION_HIGHLIGHT_RIGHT; sFactorySwapScreen->cancelButtonSpriteIds[1][1] = CreateSprite(&spriteTemplate, x + 16, 144, 1); for (i = 0; i < 2; i++) { gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][0]].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][0]].centerToCornerVecY = 0; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][1]].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][1]].centerToCornerVecY = 0; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][2]].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][2]].centerToCornerVecY = 0; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[i][0]].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[i][0]].centerToCornerVecY = 0; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[i][1]].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[i][1]].centerToCornerVecY = 0; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][0]].invisible = TRUE; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][1]].invisible = TRUE; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][2]].invisible = TRUE; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[i][0]].invisible = TRUE; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[i][1]].invisible = TRUE; } gSprites[sFactorySwapScreen->cancelButtonSpriteIds[0][0]].invisible = FALSE; gSprites[sFactorySwapScreen->cancelButtonSpriteIds[0][1]].invisible = FALSE; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0][0]].invisible = FALSE; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0][1]].invisible = FALSE; gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0][2]].invisible = FALSE; } static void Swap_DestroyAllSprites(void) { u8 i, j; for (i = 0; i < FRONTIER_PARTY_SIZE; i++) DestroySprite(&gSprites[sFactorySwapScreen->ballSpriteIds[i]]); DestroySprite(&gSprites[sFactorySwapScreen->cursorSpriteId]); DestroySprite(&gSprites[sFactorySwapScreen->menuCursor1SpriteId]); DestroySprite(&gSprites[sFactorySwapScreen->menuCursor2SpriteId]); for (i = 0; i < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds); i++) { for (j = 0; j < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0]); j++) DestroySprite(&gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[i][j]]); } for (i = 0; i < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds); i++) { for (j = 0; j < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds[0]); j++) DestroySprite(&gSprites[sFactorySwapScreen->cancelButtonSpriteIds[i][j]]); } } static void Swap_HandleActionCursorChange(u8 cursorId) { if (cursorId < FRONTIER_PARTY_SIZE) { // Cursor is on one of the pokemon gSprites[sFactorySwapScreen->cursorSpriteId].invisible = FALSE; Swap_HideActionButtonHighlights(); gSprites[sFactorySwapScreen->cursorSpriteId].pos1.x = gSprites[sFactorySwapScreen->ballSpriteIds[cursorId]].pos1.x; } else { // Cursor is on an action button gSprites[sFactorySwapScreen->cursorSpriteId].invisible = TRUE; Swap_HighlightActionButton(sFactorySwapScreen->actionsData[cursorId].id); } } static void Swap_UpdateBallCursorPosition(s8 direction) { u8 cursorPos; PlaySE(SE_SELECT); if (direction > 0) // Move cursor right. { if (sFactorySwapScreen->cursorPos + 1 != sFactorySwapScreen->actionsCount) sFactorySwapScreen->cursorPos++; else sFactorySwapScreen->cursorPos = 0; } else // Move cursor left. { if (sFactorySwapScreen->cursorPos != 0) sFactorySwapScreen->cursorPos--; else sFactorySwapScreen->cursorPos = sFactorySwapScreen->actionsCount - 1; } cursorPos = sFactorySwapScreen->cursorPos; Swap_HandleActionCursorChange(cursorPos); } static void Swap_UpdateActionCursorPosition(s8 direction) { u8 cursorPos; PlaySE(SE_SELECT); if (direction > 0) // Move cursor down. { if (sFactorySwapScreen->cursorPos < FRONTIER_PARTY_SIZE) sFactorySwapScreen->cursorPos = FRONTIER_PARTY_SIZE; else if (sFactorySwapScreen->cursorPos + 1 != sFactorySwapScreen->actionsCount) sFactorySwapScreen->cursorPos++; else sFactorySwapScreen->cursorPos = 0; } else // Move cursor up. { if (sFactorySwapScreen->cursorPos < FRONTIER_PARTY_SIZE) sFactorySwapScreen->cursorPos = sFactorySwapScreen->actionsCount - 1; else if (sFactorySwapScreen->cursorPos != 0) sFactorySwapScreen->cursorPos--; else sFactorySwapScreen->cursorPos = sFactorySwapScreen->actionsCount - 1; } cursorPos = sFactorySwapScreen->cursorPos; Swap_HandleActionCursorChange(cursorPos); } static void Swap_UpdateYesNoCursorPosition(s8 direction) { if (direction > 0) // Move cursor down. { if (sFactorySwapScreen->yesNoCursorPos != 1) sFactorySwapScreen->yesNoCursorPos++; else sFactorySwapScreen->yesNoCursorPos = 0; } else // Move cursor up. { if (sFactorySwapScreen->yesNoCursorPos != 0) sFactorySwapScreen->yesNoCursorPos--; else sFactorySwapScreen->yesNoCursorPos = 1; } gSprites[sFactorySwapScreen->menuCursor1SpriteId].pos1.y = (sFactorySwapScreen->yesNoCursorPos * 16) + 112; gSprites[sFactorySwapScreen->menuCursor2SpriteId].pos1.y = (sFactorySwapScreen->yesNoCursorPos * 16) + 112; } static void Swap_UpdateMenuCursorPosition(s8 direction) { PlaySE(SE_SELECT); if (direction > 0) // Move cursor down. { if (sFactorySwapScreen->menuCursorPos != ARRAY_COUNT(sSwap_MenuOptionFuncs) - 1) sFactorySwapScreen->menuCursorPos++; else sFactorySwapScreen->menuCursorPos = 0; } else // Move cursor up. { if (sFactorySwapScreen->menuCursorPos != 0) sFactorySwapScreen->menuCursorPos--; else sFactorySwapScreen->menuCursorPos = ARRAY_COUNT(sSwap_MenuOptionFuncs) - 1; } gSprites[sFactorySwapScreen->menuCursor1SpriteId].pos1.y = (sFactorySwapScreen->menuCursorPos * 16) + 112; gSprites[sFactorySwapScreen->menuCursor2SpriteId].pos1.y = (sFactorySwapScreen->menuCursorPos * 16) + 112; } static void Swap_HighlightActionButton(u8 actionId) { u8 i; for (i = 0; i < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0]); i++) { if (actionId == SWAPACTION_PKMN_FOR_SWAP) { // Show button highlight on "Pkmn for Swap" gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[1][i]].invisible = FALSE; // Hide button highlight on Cancel if (i < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds[0])) gSprites[sFactorySwapScreen->cancelButtonSpriteIds[1][i]].invisible = TRUE; } else if (actionId == SWAPACTION_CANCEL) { // Show button highlight on Cancel if (i < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds[0])) gSprites[sFactorySwapScreen->cancelButtonSpriteIds[1][i]].invisible = FALSE; // Hide button highlight on "Pkmn for Swap" gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[1][i]].invisible = TRUE; } } } static void Swap_HideActionButtonHighlights(void) { u8 i; for (i = 0; i < ARRAY_COUNT(sFactorySwapScreen->pkmnForSwapButtonSpriteIds[0]); i++) { // Hide button highlight on "Pkmn for Swap" gSprites[sFactorySwapScreen->pkmnForSwapButtonSpriteIds[1][i]].invisible = TRUE; // Hide button highlight on Cancel if (i < ARRAY_COUNT(sFactorySwapScreen->cancelButtonSpriteIds[0])) gSprites[sFactorySwapScreen->cancelButtonSpriteIds[1][i]].invisible = TRUE; } } static void Swap_ShowMenuOptions(void) { if (sFactorySwapScreen->fromSummaryScreen == TRUE) sFactorySwapScreen->fromSummaryScreen = FALSE; else sFactorySwapScreen->menuCursorPos = 0; gSprites[sFactorySwapScreen->menuCursor1SpriteId].pos1.x = 176; gSprites[sFactorySwapScreen->menuCursor1SpriteId].pos1.y = (sFactorySwapScreen->menuCursorPos * 16) + 112; gSprites[sFactorySwapScreen->menuCursor2SpriteId].pos1.x = 208; gSprites[sFactorySwapScreen->menuCursor2SpriteId].pos1.y = (sFactorySwapScreen->menuCursorPos * 16) + 112; gSprites[sFactorySwapScreen->menuCursor1SpriteId].invisible = FALSE; gSprites[sFactorySwapScreen->menuCursor2SpriteId].invisible = FALSE; Swap_PrintMenuOptions(); } static void Swap_ShowYesNoOptions(void) { sFactorySwapScreen->yesNoCursorPos = 0; gSprites[sFactorySwapScreen->menuCursor1SpriteId].pos1.x = 176; gSprites[sFactorySwapScreen->menuCursor1SpriteId].pos1.y = 112; gSprites[sFactorySwapScreen->menuCursor2SpriteId].pos1.x = 208; gSprites[sFactorySwapScreen->menuCursor2SpriteId].pos1.y = 112; gSprites[sFactorySwapScreen->menuCursor1SpriteId].invisible = FALSE; gSprites[sFactorySwapScreen->menuCursor2SpriteId].invisible = FALSE; Swap_PrintYesNoOptions(); } static void Swap_ErasePopupMenu(u8 windowId) { gSprites[sFactorySwapScreen->menuCursor1SpriteId].invisible = TRUE; gSprites[sFactorySwapScreen->menuCursor2SpriteId].invisible = TRUE; FillWindowPixelBuffer(windowId, PIXEL_FILL(0)); CopyWindowToVram(windowId, 2); ClearWindowTilemap(windowId); } static void sub_819EAC0(void) { PutWindowTilemap(SWAP_WIN_SPECIES); FillWindowPixelBuffer(SWAP_WIN_SPECIES, PIXEL_FILL(0)); CopyWindowToVram(SWAP_WIN_SPECIES, 2); } static void sub_819EADC(void) { PutWindowTilemap(SWAP_WIN_7); FillWindowPixelBuffer(SWAP_WIN_7, PIXEL_FILL(0)); CopyWindowToVram(SWAP_WIN_7, 2); } static void sub_819EAF8(void) { sub_819EAC0(); PutWindowTilemap(SWAP_WIN_5); FillWindowPixelBuffer(SWAP_WIN_5, PIXEL_FILL(0)); CopyWindowToVram(SWAP_WIN_5, 2); } static void Swap_PrintPkmnSwap(void) { FillWindowPixelBuffer(SWAP_WIN_TITLE, PIXEL_FILL(1)); AddTextPrinterParameterized(SWAP_WIN_TITLE, 1, gText_PkmnSwap, 2, 1, 0, NULL); CopyWindowToVram(SWAP_WIN_TITLE, 3); } static void Swap_PrintMonSpecies(void) { u16 species; u8 x; FillWindowPixelBuffer(SWAP_WIN_SPECIES, PIXEL_FILL(0)); if (sFactorySwapScreen->cursorPos >= FRONTIER_PARTY_SIZE) { CopyWindowToVram(SWAP_WIN_SPECIES, 2); } else { u8 monId = sFactorySwapScreen->cursorPos; if (!sFactorySwapScreen->inEnemyScreen) species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, NULL); else species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, NULL); StringCopy(gStringVar4, gSpeciesNames[species]); x = GetStringRightAlignXOffset(1, gStringVar4, 86); AddTextPrinterParameterized3(SWAP_WIN_SPECIES, 1, x, 1, sSwapSpeciesNameTextColors, 0, gStringVar4); CopyWindowToVram(SWAP_WIN_SPECIES, 3); } } static void Swap_PrintOnInfoWindow(const u8 *str) { FillWindowPixelBuffer(SWAP_WIN_INFO, PIXEL_FILL(0)); AddTextPrinterParameterized(SWAP_WIN_INFO, 1, str, 2, 5, 0, NULL); CopyWindowToVram(SWAP_WIN_INFO, 2); } static void Swap_PrintMenuOptions(void) { PutWindowTilemap(SWAP_WIN_OPTIONS); FillWindowPixelBuffer(SWAP_WIN_OPTIONS, PIXEL_FILL(0)); AddTextPrinterParameterized3(SWAP_WIN_OPTIONS, 1, 15, 1, sSwapMenuOptionsTextColors, 0, gText_Summary2); AddTextPrinterParameterized3(SWAP_WIN_OPTIONS, 1, 15, 17, sSwapMenuOptionsTextColors, 0, gText_Swap); AddTextPrinterParameterized3(SWAP_WIN_OPTIONS, 1, 15, 33, sSwapMenuOptionsTextColors, 0, gText_Rechoose); CopyWindowToVram(SWAP_WIN_OPTIONS, 3); } static void Swap_PrintYesNoOptions(void) { PutWindowTilemap(SWAP_WIN_YES_NO); FillWindowPixelBuffer(SWAP_WIN_YES_NO, PIXEL_FILL(0)); AddTextPrinterParameterized3(SWAP_WIN_YES_NO, 1, 7, 1, sSwapMenuOptionsTextColors, 0, gText_Yes3); AddTextPrinterParameterized3(SWAP_WIN_YES_NO, 1, 7, 17, sSwapMenuOptionsTextColors, 0, gText_No3); CopyWindowToVram(SWAP_WIN_YES_NO, 3); } static void Swap_PrintActionString(const u8 *str, u32 y, u32 windowId) { s32 x = GetStringRightAlignXOffset(0, str, 0x46); AddTextPrinterParameterized3(windowId, 0, x, y, sSwapMenuOptionsTextColors, 0, str); } static void Swap_PrintActionStrings(void) { FillWindowPixelBuffer(SWAP_WIN_5, PIXEL_FILL(0)); switch (sFactorySwapScreen->inEnemyScreen) { case TRUE: Swap_PrintActionString(gText_PkmnForSwap, 0, SWAP_WIN_5); case FALSE: Swap_PrintActionString(gText_Cancel3, 24, SWAP_WIN_5); break; } CopyWindowToVram(SWAP_WIN_5, 3); } static void Swap_PrintActionStrings2(void) { FillWindowPixelBuffer(SWAP_WIN_OPTIONS, PIXEL_FILL(0)); switch (sFactorySwapScreen->inEnemyScreen) { case TRUE: Swap_PrintActionString(gText_PkmnForSwap, 8, SWAP_WIN_OPTIONS); case FALSE: Swap_PrintActionString(gText_Cancel3, 32, SWAP_WIN_OPTIONS); break; } CopyWindowToVram(SWAP_WIN_OPTIONS, 3); } static void Swap_PrintOneActionString(u8 which) { switch (which) { case 0: if (sFactorySwapScreen->inEnemyScreen == TRUE) Swap_PrintActionString(gText_PkmnForSwap, 8, SWAP_WIN_OPTIONS); break; case 1: Swap_PrintActionString(gText_Cancel3, 32, SWAP_WIN_OPTIONS); break; } CopyWindowToVram(SWAP_WIN_OPTIONS, 3); } static void Swap_PrintMonSpecies2(void) { u16 species; u8 x; u16 pal[5]; CpuCopy16(sSwapText_Pal, pal, 8); if (!sFactorySwapScreen->fromSummaryScreen) pal[4] = gPlttBufferFaded[228]; else pal[4] = sFactorySwapScreen->speciesNameColorBackup; LoadPalette(pal, 0xF0, sizeof(sSwapText_Pal)); PutWindowTilemap(SWAP_WIN_7); FillWindowPixelBuffer(SWAP_WIN_7, PIXEL_FILL(0)); if (sFactorySwapScreen->cursorPos >= FRONTIER_PARTY_SIZE) { CopyWindowToVram(SWAP_WIN_7, 3); } else { u8 monId = sFactorySwapScreen->cursorPos; if (!sFactorySwapScreen->inEnemyScreen) species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, NULL); else species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, NULL); StringCopy(gStringVar4, gSpeciesNames[species]); x = GetStringRightAlignXOffset(1, gStringVar4, 86); AddTextPrinterParameterized3(SWAP_WIN_7, 1, x, 1, sSwapSpeciesNameTextColors, 0, gStringVar4); CopyWindowToVram(SWAP_WIN_7, 3); } } static void Swap_PrintMonSpecies3(void) { u16 species; u8 x; LoadPalette(sSwapText_Pal, 0xE0, sizeof(sSwapText_Pal)); CpuCopy16(&gPlttBufferUnfaded[240], &gPlttBufferFaded[224], 10); if (sFactorySwapScreen->cursorPos >= FRONTIER_PARTY_SIZE) { CopyWindowToVram(SWAP_WIN_SPECIES, 2); } else { u8 monId = sFactorySwapScreen->cursorPos; if (!sFactorySwapScreen->inEnemyScreen) species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, NULL); else species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, NULL); StringCopy(gStringVar4, gSpeciesNames[species]); x = GetStringRightAlignXOffset(1, gStringVar4, 86); AddTextPrinterParameterized3(SWAP_WIN_SPECIES, 1, x, 1, sSwapSpeciesNameTextColors, 0, gStringVar4); CopyWindowToVram(SWAP_WIN_SPECIES, 3); } } static void Swap_PrintMonCategory(void) { u16 species; u8 text[30]; u8 x; u8 monId = sFactorySwapScreen->cursorPos; FillWindowPixelBuffer(SWAP_WIN_MON_CATEGORY, PIXEL_FILL(0)); if (monId >= FRONTIER_PARTY_SIZE) { CopyWindowToVram(SWAP_WIN_MON_CATEGORY, 2); } else { PutWindowTilemap(SWAP_WIN_MON_CATEGORY); if (!sFactorySwapScreen->inEnemyScreen) species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, NULL); else species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, NULL); CopyMonCategoryText(SpeciesToNationalPokedexNum(species), text); x = GetStringRightAlignXOffset(1, text, 0x76); AddTextPrinterParameterized(SWAP_WIN_MON_CATEGORY, 1, text, x, 1, 0, NULL); CopyWindowToVram(SWAP_WIN_MON_CATEGORY, 2); } } static void Swap_InitActions(u8 id) { if (sFactorySwapScreen->fromSummaryScreen != TRUE) { switch (id) { case SWAP_PLAYER_SCREEN: sFactorySwapScreen->inEnemyScreen = FALSE; sFactorySwapScreen->cursorPos = 0; sFactorySwapScreen->actionsCount = ARRAY_COUNT(sSwap_PlayerScreenActions); sFactorySwapScreen->actionsData = sSwap_PlayerScreenActions; break; case SWAP_ENEMY_SCREEN: sFactorySwapScreen->inEnemyScreen = TRUE; sFactorySwapScreen->cursorPos = 0; sFactorySwapScreen->actionsCount = ARRAY_COUNT(sSwap_EnemyScreenActions); sFactorySwapScreen->actionsData = sSwap_EnemyScreenActions; break; } } } static void Swap_RunMenuOptionFunc(u8 taskId) { sSwap_CurrentOptionFunc = sSwap_MenuOptionFuncs[sFactorySwapScreen->menuCursorPos]; sSwap_CurrentOptionFunc(taskId); } static void Swap_OptionSwap(u8 taskId) { CloseMonPic(sFactorySwapScreen->monPic, &sFactorySwapScreen->monPicAnimating, TRUE); sFactorySwapScreen->playerMonId = sFactorySwapScreen->cursorPos; Swap_ErasePopupMenu(SWAP_WIN_OPTIONS); gTasks[taskId].tState = 0; gTasks[taskId].func = sub_819D9EC; } static void Swap_OptionSummary(u8 taskId) { gTasks[taskId].tState = 6; gTasks[taskId].func = Swap_Task_OpenSummaryScreen; } static void Swap_OptionRechoose(u8 taskId) { CloseMonPic(sFactorySwapScreen->monPic, &sFactorySwapScreen->monPicAnimating, TRUE); Swap_ErasePopupMenu(SWAP_WIN_OPTIONS); gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_Task_HandleChooseMons) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_Task_HandleChooseMons); gTasks[taskId].tFollowUpTaskState = 1; gTasks[taskId].func = sub_819D770; } static void Swap_RunActionFunc(u8 taskId) { sSwap_CurrentOptionFunc = sFactorySwapScreen->actionsData[sFactorySwapScreen->cursorPos].func; sSwap_CurrentOptionFunc(taskId); } static void Swap_ActionCancel(u8 taskId) { gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_AskQuitSwapping) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_AskQuitSwapping); gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskState = 0; gTasks[taskId].func = sub_819D588; } static void Swap_ActionPkmnForSwap(u8 taskId) { gTasks[taskId].tFollowUpTaskPtrHi = (u32)(sub_819D9EC) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(sub_819D9EC); gTasks[taskId].tFollowUpTaskState = 0; gTasks[taskId].tState = 0; gTasks[taskId].func = sub_819D588; } static void Swap_ActionMon(u8 taskId) { if (!sFactorySwapScreen->inEnemyScreen) { gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_Task_HandleMenu) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_Task_HandleMenu); gTasks[taskId].tFollowUpTaskState = 2; } else if (Swap_AlreadyHasSameSpecies(sFactorySwapScreen->cursorPos) == TRUE) { OpenMonPic(&sFactorySwapScreen->monPic.bgSpriteId, &sFactorySwapScreen->monPicAnimating, TRUE); gTasks[taskId].tState = 0; gTasks[taskId].tFollowUpTaskState = 1; gTasks[taskId].func = Swap_TaskCantHaveSameMons; return; } else { gTasks[taskId].tFollowUpTaskPtrHi = (u32)(Swap_AskAcceptMon) >> 16; gTasks[taskId].tFollowUpTaskPtrLo = (u32)(Swap_AskAcceptMon); gTasks[taskId].tFollowUpTaskState = 0; } gTasks[taskId].tState = 0; gTasks[taskId].func = sub_819D588; } #define sIsSwapScreen data[7] static void OpenMonPic(u8 *spriteId, bool8 *animating, bool8 swapScreen) { *spriteId = CreateSprite(&sSpriteTemplate_Swap_MonPicBgAnim, 120, 64, 1); gSprites[*spriteId].callback = SpriteCB_OpenMonPic; gSprites[*spriteId].sIsSwapScreen = swapScreen; *animating = TRUE; } static void Swap_ShowSummaryMonSprite(void) { struct Pokemon *mon; u16 species; u32 personality, otId; sFactorySwapScreen->monPic.bgSpriteId = CreateSprite(&sSpriteTemplate_Swap_MonPicBgAnim, 120, 64, 1); StartSpriteAffineAnim(&gSprites[sFactorySwapScreen->monPic.bgSpriteId], 2); mon = &gPlayerParty[sFactorySwapScreen->cursorPos]; species = GetMonData(mon, MON_DATA_SPECIES, NULL); personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); otId = GetMonData(mon, MON_DATA_OT_ID, NULL); sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite_HandleDeoxys(species, personality, otId, TRUE, 88, 32, 15, 0xFFFF); // BUG: otId and personality should be switched. gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecY = 0; gSprites[sFactorySwapScreen->monPic.bgSpriteId].invisible = TRUE; } static void CloseMonPic(struct FactoryMonPic pic, bool8 *animating, bool8 swapScreen) { u8 taskId; FreeAndDestroyMonPicSprite(pic.monSpriteId); taskId = CreateTask(Task_CloseMonPic, 1); gTasks[taskId].tIsSwapScreen = swapScreen; gTasks[taskId].tSpriteId = pic.bgSpriteId; gTasks[taskId].func(taskId); *animating = TRUE; } static void HideMonPic(struct FactoryMonPic pic, bool8 *animating) { FreeAndDestroyMonPicSprite(pic.monSpriteId); FreeOamMatrix(gSprites[pic.bgSpriteId].oam.matrixNum); DestroySprite(&gSprites[pic.bgSpriteId]); *animating = FALSE; } static void Swap_TaskCantHaveSameMons(u8 taskId) { if (sFactorySwapScreen->monPicAnimating == TRUE) return; switch (gTasks[taskId].tState) { case 0: Swap_PrintOnInfoWindow(gText_SamePkmnInPartyAlready); sFactorySwapScreen->monSwapped = FALSE; gTasks[taskId].tState++; break; case 1: if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); CloseMonPic(sFactorySwapScreen->monPic, &sFactorySwapScreen->monPicAnimating, TRUE); gTasks[taskId].tState++; } break; case 2: if (sFactorySwapScreen->monPicAnimating != TRUE) { FillWindowPixelBuffer(SWAP_WIN_5, PIXEL_FILL(0)); CopyWindowToVram(SWAP_WIN_5, 2); gTasks[taskId].tState++; } break; case 3: Swap_PrintOnInfoWindow(gText_SelectPkmnToAccept); gTasks[taskId].tState++; break; case 4: Swap_PrintMonSpecies3(); sub_819EADC(); sFactorySwapScreen->fadeSpeciesNameActive = TRUE; gTasks[taskId].tState = gTasks[taskId].tFollowUpTaskState; gTasks[taskId].func = Swap_Task_HandleChooseMons; break; } } static bool8 Swap_AlreadyHasSameSpecies(u8 monId) { u8 i; u16 species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, NULL); for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { if (i != sFactorySwapScreen->playerMonId && (u16)(GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL)) == species) return TRUE; } return FALSE; } static void SpriteCB_OpenMonPic(struct Sprite *sprite) { u8 taskId; if (sprite->affineAnimEnded) { sprite->invisible = TRUE; taskId = CreateTask(Task_OpenMonPic, 1); gTasks[taskId].tIsSwapScreen = sprite->sIsSwapScreen; gTasks[taskId].func(taskId); sprite->callback = SpriteCallbackDummy; } } static void sub_819F654(struct Sprite *sprite) { if (sprite->affineAnimEnded) { FreeOamMatrix(sprite->oam.matrixNum); if (sprite->sIsSwapScreen == TRUE) sFactorySwapScreen->monPicAnimating = FALSE; else Select_SetMonPicAnimating(FALSE); DestroySprite(sprite); } } static void Task_OpenMonPic(u8 taskId) { struct Task *task = &gTasks[taskId]; switch (task->tState) { case 0: task->tWinLeft = 88; task->tWinRight = DISPLAY_WIDTH - 88; task->tWinTop = 64; task->tWinBottom = 65; SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWinLeft, task->tWinRight)); SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_CLR | WININ_WIN0_OBJ); SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_CLR | WINOUT_WIN01_OBJ); break; case 1: ShowBg(3); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_OBJ); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(11, 4)); break; case 2: task->tWinTop -= 4; task->tWinBottom += 4; if (task->tWinTop <= 32 || task->tWinBottom >= 96) { task->tWinTop = 32; task->tWinBottom = 96; } SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); if (task->tWinTop != 32) return; break; default: DestroyTask(taskId); // UB: Should not use the task after it has been deleted. if (gTasks[taskId].tIsSwapScreen == TRUE) Swap_CreateMonSprite(); else Select_CreateMonSprite(); return; } task->tState++; } static void Task_CloseMonPic(u8 taskId) { struct Task *task = &gTasks[taskId]; switch (task->tState) { default: HideBg(3); gSprites[task->tSpriteId].sIsSwapScreen = task->tIsSwapScreen; gSprites[task->tSpriteId].invisible = FALSE; gSprites[task->tSpriteId].callback = sub_819F654; StartSpriteAffineAnim(&gSprites[task->tSpriteId], 1); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); DestroyTask(taskId); break; case 0: task->tWinLeft = 88; task->tWinRight = DISPLAY_WIDTH - 88; task->tWinTop = 32; task->tWinBottom = 96; SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->tWinLeft, task->tWinRight)); SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_CLR | WININ_WIN0_OBJ); SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_CLR | WINOUT_WIN01_OBJ); task->tState++; break; case 1: task->tWinTop += 4; task->tWinBottom -= 4; if (task->tWinTop >= 64 || task->tWinBottom <= 65) { task->tWinTop = 64; task->tWinBottom = 65; } SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->tWinTop, task->tWinBottom)); if (task->tWinTop == 64) task->tState++; break; } } static void Swap_CreateMonSprite(void) { struct Pokemon *mon; u16 species; u32 personality, otId; if (!sFactorySwapScreen->inEnemyScreen) mon = &gPlayerParty[sFactorySwapScreen->cursorPos]; else mon = &gEnemyParty[sFactorySwapScreen->cursorPos]; species = GetMonData(mon, MON_DATA_SPECIES, NULL); personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); otId = GetMonData(mon, MON_DATA_OT_ID, NULL); sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite_HandleDeoxys(species, otId, personality, TRUE, 88, 32, 15, 0xFFFF); gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecY = 0; sFactorySwapScreen->monPicAnimating = FALSE; }