From fc4aa4fff7c77878068c6b6923f0e71d4aefd47f Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 15 Dec 2022 16:00:33 -0500 Subject: [PATCH] Sync trade anim --- graphics/trade/ball.png | Bin 464 -> 0 bytes .../trade/{unknown_DDB444.pal => cursor.pal} | 0 graphics/trade/{buttons.png => cursor.png} | Bin graphics/trade/{misc.pal => link_mon.pal} | 0 .../trade/{glow1.png => link_mon_glow.png} | Bin .../trade/{glow2.png => link_mon_shadow.png} | Bin .../trade/{unknown_DDCF04.bin => menu.bin} | Bin graphics/trade/unknown_338EA4.pal | 15 - .../unused_DDCEE4.bin => trade/unused.bin} | Bin .../trade/{unknown_3308C0.pal => unused1.pal} | 0 ...3379A0.bin => wireless_signal_closeup.bin} | Bin include/pokemon.h | 2 +- src/graphics.c | 8 +- src/pokemon.c | 2 +- src/pokemon_summary_screen.c | 4 +- src/trade.c | 2 +- src/trade_scene.c | 2195 +++++++++-------- 17 files changed, 1117 insertions(+), 1111 deletions(-) delete mode 100644 graphics/trade/ball.png rename graphics/trade/{unknown_DDB444.pal => cursor.pal} (100%) rename graphics/trade/{buttons.png => cursor.png} (100%) rename graphics/trade/{misc.pal => link_mon.pal} (100%) rename graphics/trade/{glow1.png => link_mon_glow.png} (100%) rename graphics/trade/{glow2.png => link_mon_shadow.png} (100%) rename graphics/trade/{unknown_DDCF04.bin => menu.bin} (100%) delete mode 100644 graphics/trade/unknown_338EA4.pal rename graphics/{unused/unused_DDCEE4.bin => trade/unused.bin} (100%) rename graphics/trade/{unknown_3308C0.pal => unused1.pal} (100%) rename graphics/trade/{unknown_3379A0.bin => wireless_signal_closeup.bin} (100%) diff --git a/graphics/trade/ball.png b/graphics/trade/ball.png deleted file mode 100644 index 97cc86a6f79c9d20b0cbb2f5de67003c0aa9d97c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 464 zcmeAS@N?(olHy`uVBq!ia0vp^0ziC#g&9cxfBdf&NErn9gt-3y|G$}mVGRSrRZY$R zbE<*dDO096Iyy>7NC4TGAggAYHvw5N+>h(+(-s|WL%4S3iR@+>!Vryo*zwsK1qY?9f&>fg7{zriTB3Jve^PzFVKGByk~(*-;Hq;kVwV2So@=|Z^n8WD5#wLI|9%|$aZh8eZIy=H-LB>9=6~|2 zp6XgqKKJfNzYUMZ(n#=IfmonIconSpriteId = CreateMonIcon(species, SpriteCallbackDummy, 24, 32, 0, personality, 1); } - if (!IsPokeSpriteNotFlipped(species)) + if (!IsMonSpriteNotFlipped(species)) gSprites[sMonSummaryScreen->monIconSpriteId].hFlip = TRUE; else gSprites[sMonSummaryScreen->monIconSpriteId].hFlip = FALSE; diff --git a/src/trade.c b/src/trade.c index 1ec5c5d11..e7de8d22d 100644 --- a/src/trade.c +++ b/src/trade.c @@ -1423,7 +1423,7 @@ static void SetActiveMenuOptions(void) } else { - // Absent partner pokemno + // Absent partner pokemon sTradeMenu->optionsActive[i + PARTY_SIZE] = FALSE; } } diff --git a/src/trade_scene.c b/src/trade_scene.c index 3f2b1952e..47d5f191c 100644 --- a/src/trade_scene.c +++ b/src/trade_scene.c @@ -34,15 +34,24 @@ #include "constants/region_map_sections.h" #include "constants/moves.h" -#define TAG_GLOW1_TILES 5550 -#define TAG_GLOW_PAL 5551 -#define TAG_GLOW2_TILES 5552 -#define TAG_UNUSED_5553 5553 -#define TAG_CABLE_END_TILES 5554 -#define TAG_GBA_PAL 5555 -#define TAG_GBA_SCREEN_TILES 5556 -#define TAG_BALL_TILES 5557 -#define TAG_BALL_PAL 5558 +// Values for signaling to/from the link partner +enum { + STATUS_NONE, + STATUS_READY, + STATUS_CANCEL, +}; + +enum { + GFXTAG_LINK_MON_GLOW = 5550, + PALTAG_LINK_MON, + GFXTAG_LINK_MON_SHADOW, + TAG_UNUSED, + GFXTAG_CABLE_END, + PALTAG_GBA, + GFXTAG_GBA_SCREEN, + GFXTAG_POKEBALL, + PALTAG_POKEBALL, +}; struct InGameTrade { /*0x00*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; @@ -50,7 +59,7 @@ struct InGameTrade { /*0x0E*/ u8 ivs[NUM_STATS]; /*0x14*/ u8 abilityNum; /*0x18*/ u32 otId; - /*0x1C*/ u8 conditions[5]; + /*0x1C*/ u8 conditions[CONTEST_CATEGORIES_COUNT]; /*0x24*/ u32 personality; /*0x28*/ u16 heldItem; /*0x2A*/ u8 mailNum; @@ -60,31 +69,31 @@ struct InGameTrade { /*0x38*/ u16 requestedSpecies; }; -struct TradeAnimationResources { - /*0x00*/ struct Pokemon mon; +struct { + /*0x00*/ struct Pokemon tempMon; // Used as a temp variable when swapping Pokémon /*0x64*/ u32 timer; /*0x68*/ u32 monPersonalities[2]; /*0x70*/ u8 filler_70[2]; - /*0x72*/ u8 tradeStatus1; - /*0x73*/ u8 tradeStatus2; + /*0x72*/ u8 playerFinishStatus; + /*0x73*/ u8 partnerFinishStatus; /*0x74*/ u16 linkData[10]; /*0x88*/ u8 linkTimeoutCheck1; /*0x89*/ u8 linkTimeoutCheck2; /*0x8A*/ u16 linkTimeoutTimer; - /*0x8C*/ u16 unk_8C; - /*0x8E*/ u8 pokePicSpriteIdxs[2]; - /*0x90*/ u8 tradeGlow1SpriteId; - /*0x91*/ u8 gbaScreenSpriteId; - /*0x92*/ u8 linkCableEndSpriteId; + /*0x8C*/ u16 neverRead_8C; + /*0x8E*/ u8 monSpriteIds[2]; + /*0x90*/ u8 connectionSpriteId1; // Multi-purpose sprite ids used during the transfer sequence + /*0x91*/ u8 connectionSpriteId2; + /*0x92*/ u8 cableEndSpriteId; /*0x93*/ u8 scheduleLinkTransfer; /*0x94*/ u16 state; /*0x96*/ u8 filler_96[0xD2 - 0x96]; - /*0xD2*/ u8 pokeballSpriteId; - /*0xD3*/ u8 pokeballSpriteId2; + /*0xD2*/ u8 releasePokeballSpriteId; + /*0xD3*/ u8 bouncingPokeballSpriteId; /*0xD4*/ u16 bg2texX; /*0xD6*/ u16 bg2texY; - /*0xD8*/ u16 unk_D8; - /*0xDA*/ u16 unk_DA; + /*0xD8*/ u16 neverRead_D8; + /*0xDA*/ u16 neverRead_DA; /*0xDC*/ u16 bg2srcX; /*0xDE*/ u16 bg2srcY; /*0xE0*/ s16 bg1vofs; @@ -95,10 +104,10 @@ struct TradeAnimationResources { /*0xEA*/ u16 bg2Zoom; /*0xEC*/ u16 bg2alpha; /*0xEE*/ bool8 isLinkTrade; - /*0xF0*/ u16 tradeSpecies[2]; + /*0xF0*/ u16 monSpecies[2]; /*0xF4*/ u16 cachedMapMusic; /*0xF6*/ u8 unk_F6; - /*0xF8*/ u16 monSpecies[2]; + /*0xF8*/ u16 questLogSpecies[2]; /*0xFC*/ u8 linkPartnerName[7]; /*0x103*/ u8 filler_103[1]; /*0x104*/ u8 textColor[3]; @@ -108,159 +117,157 @@ struct TradeAnimationResources { /*0x10A*/ u8 win0top; /*0x10B*/ u8 win0right; /*0x10C*/ u8 win0bottom; -}; +} static EWRAM_DATA * sTradeAnim = NULL; -static EWRAM_DATA struct TradeAnimationResources * sTradeData = NULL; - -static void SpriteCB_TradeGlowCable(struct Sprite *sprite); -static void SpriteCB_TradeGlowWireless(struct Sprite *sprite); -static void SpriteCB_TradeGlowCore(struct Sprite *sprite); -static void SpriteCB_GameLinkCableEnd_Outbound(struct Sprite *sprite); -static void SpriteCB_GameLinkCableEnd_Inbound(struct Sprite *sprite); -static void SpriteCB_TradeGBAScreen(struct Sprite *sprite); +static void SpriteCB_LinkMonGlow(struct Sprite *sprite); +static void SpriteCB_LinkMonGlowWireless(struct Sprite *sprite); +static void SpriteCB_LinkMonShadow(struct Sprite *sprite); +static void SpriteCB_CableEndSending(struct Sprite *sprite); +static void SpriteCB_CableEndReceiving(struct Sprite *sprite); +static void SpriteCB_GbaScreen(struct Sprite *sprite); static void TradeAnimInit_LoadGfx(void); -static void CB2_RunTradeAnim_InGameTrade(void); +static void CB2_InGameTrade(void); static void SetTradeSequenceBgGpuRegs(u8 idx); static void LoadTradeGbaSpriteGfx(void); static void TradeBufferOTnameAndNicknames(void); static u8 DoTradeAnim(void); static u8 DoTradeAnim_Cable(void); static u8 DoTradeAnim_Wireless(void); -static void SpriteCB_TradePokeball_Default(struct Sprite *sprite); -static void SpriteCB_TradePokeball_Outbound(struct Sprite *sprite); -static void SpriteCB_TradePokeball_Outbound2(struct Sprite *sprite); -static void SpriteCB_TradePokeball_Inbound(struct Sprite *sprite); +static void SpriteCB_BouncingPokeball(struct Sprite *sprite); +static void SpriteCB_BouncingPokeballDepart(struct Sprite *sprite); +static void SpriteCB_BouncingPokeballDepartEnd(struct Sprite *sprite); +static void SpriteCB_BouncingPokeballArrive(struct Sprite *sprite); static void BufferInGameTradeMonName(void); static void GetInGameTradeMail(struct Mail * mail, const struct InGameTrade * inGameTrade); -static void CB2_RunTradeAnim_LinkTrade(void); -static void CB2_WaitAndAckTradeComplete(void); -static void CB2_HandleTradeEnded(void); -static void LinkTrade_TearDownAssets(void); -static void Task_WaitFadeAndStartInGameTradeAnim(u8 taskId); +static void CB2_UpdateLinkTrade(void); +static void CB2_WaitTradeComplete(void); +static void CB2_SaveAndEndTrade(void); +static void CB2_FreeTradeAnim(void); +static void Task_InGameTrade(u8 taskId); static void CheckPartnersMonForRibbons(void); static void Task_AnimateWirelessSignal(u8 taskId); static void Task_OpenCenterWhiteColumn(u8 taskId); static void Task_CloseCenterWhiteColumn(u8 taskId); -static const u16 sTradeBallPalette[] = INCBIN_U16("graphics/trade/ball.gbapal"); -static const u8 sTradeBallTiles[] = INCBIN_U8("graphics/trade/ball.4bpp"); -static const u8 sPokeballSymbolTiles[] = INCBIN_U8("graphics/trade/pokeball_symbol.8bpp"); -static const u16 sCableCloseupMap[] = INCBIN_U16("graphics/trade/cable_closeup_map.bin"); -static const u16 sPokeballSymbolMap[] = INCBIN_U16("graphics/trade/pokeball_symbol_map.bin"); -static const u16 sUnref_083308C0[] = INCBIN_U16("graphics/trade/unknown_3308C0.gbapal"); -static const u16 sTradeGbaPal[] = INCBIN_U16("graphics/trade/gba.gbapal"); -static const u16 sShadowPalette[] = INCBIN_U16("graphics/trade/shadow.gbapal"); -static const u16 sBlackPalette[] = INCBIN_U16("graphics/trade/black.gbapal"); -static const u16 sTradeGlowPal[] = INCBIN_U16("graphics/trade/misc.gbapal"); -static const u8 sTradeGlow1Tiles[] = INCBIN_U8("graphics/trade/glow1.4bpp"); -static const u8 sTradeGlow2Tiles[] = INCBIN_U8("graphics/trade/glow2.4bpp"); -static const u8 sTradeCableEndTiles[] = INCBIN_U8("graphics/trade/cable_end.4bpp"); -static const u8 sTradeGBAScreenTiles[] = INCBIN_U8("graphics/trade/gba_screen.4bpp"); -const u16 gTradeOrHatchMonShadowTilemap[] = INCBIN_U16("graphics/trade/shadow_map.bin"); -static const u8 sGbaAffineTiles[] = INCBIN_U8("graphics/trade/gba_affine.8bpp"); -static const u8 sFiller_08335760[64] = {}; -static const u8 sGbaAffineMapCable[] = INCBIN_U8("graphics/trade/gba_affine_map_cable.bin"); -static const u8 sGbaAffineMapWireless[] = INCBIN_U8("graphics/trade/gba_affine_map_wireless.bin"); -static const u16 sGbaMapWireless[] = INCBIN_U16("graphics/trade/gba_map_wireless.bin"); -static const u16 sGbaMapCable[] = INCBIN_U16("graphics/trade/gba_map_cable.bin"); -static const u32 sWirelessCloseupMap[] = INCBIN_U32("graphics/trade/unknown_3379A0.bin.lz"); +static const u16 sPokeball_Pal[] = INCBIN_U16("graphics/trade/pokeball.gbapal"); +static const u8 sPokeball_Gfx[] = INCBIN_U8("graphics/trade/pokeball.4bpp"); +static const u8 sPokeballSymbol_Gfx[] = INCBIN_U8("graphics/trade/pokeball_symbol.8bpp"); // Unused +static const u16 sCableCloseup_Map[] = INCBIN_U16("graphics/trade/cable_closeup_map.bin"); +static const u16 sPokeballSymbol_Map[] = INCBIN_U16("graphics/trade/pokeball_symbol_map.bin"); +static const u16 sUnusedPal1[] = INCBIN_U16("graphics/trade/unused1.gbapal"); +static const u16 sGba_Pal[] = INCBIN_U16("graphics/trade/gba.gbapal"); +static const u16 sShadowPalette[] = INCBIN_U16("graphics/trade/shadow.gbapal"); +static const u16 sBlackPalette[] = INCBIN_U16("graphics/trade/black.gbapal"); +static const u16 sLinkMon_Pal[] = INCBIN_U16("graphics/trade/link_mon.gbapal"); +static const u8 sLinkMonGlow_Gfx[] = INCBIN_U8("graphics/trade/link_mon_glow.4bpp"); +static const u8 sLinkMonShadow_Gfx[] = INCBIN_U8("graphics/trade/link_mon_shadow.4bpp"); +static const u8 sCableEnd_Gfx[] = INCBIN_U8("graphics/trade/cable_end.4bpp"); +static const u8 sGbaScreen_Gfx[] = INCBIN_U8("graphics/trade/gba_screen.4bpp"); +const u16 gTradeOrHatchMonShadowTilemap[] = INCBIN_U16("graphics/trade/shadow_map.bin"); +static const u8 sGbaAffine_Gfx[] = INCBIN_U8("graphics/trade/gba_affine.8bpp"); +static const u8 sEmptyGfx[64] = {}; +static const u8 sGbaAffineMapCable[] = INCBIN_U8("graphics/trade/gba_affine_map_cable.bin"); +static const u8 sGbaAffineMapWireless[] = INCBIN_U8("graphics/trade/gba_affine_map_wireless.bin"); +static const u16 sGbaMapWireless[] = INCBIN_U16("graphics/trade/gba_map_wireless.bin"); +static const u16 sGbaMapCable[] = INCBIN_U16("graphics/trade/gba_map_cable.bin"); +static const u32 sWirelessCloseup_Map[] = INCBIN_U32("graphics/trade/wireless_signal_closeup.bin.lz"); static const u16 sWirelessSignalAnimPals_Outbound[] = INCBIN_U16("graphics/trade/wireless_signal_send.gbapal"); -static const u16 sWirelessSignalAnimPals_Inbound[] = INCBIN_U16("graphics/trade/wireless_signal_receive.gbapal"); -static const u16 sWirelessSignalAnimPals_Off[] = INCBIN_U16("graphics/trade/black.gbapal"); -static const u32 sWirelessSignal4bpp[] = INCBIN_U32("graphics/trade/wireless_signal.4bpp.lz"); -static const u32 sWirelessSignalTilemap[] = INCBIN_U32("graphics/trade/wireless_signal.bin.lz"); +static const u16 sWirelessSignalAnimPals_Inbound[] = INCBIN_U16("graphics/trade/wireless_signal_receive.gbapal"); +static const u16 sWirelessSignalAnimPals_Off[] = INCBIN_U16("graphics/trade/black.gbapal"); +static const u32 sWirelessSignal4bpp[] = INCBIN_U32("graphics/trade/wireless_signal.4bpp.lz"); +static const u32 sWirelessSignalTilemap[] = INCBIN_U32("graphics/trade/wireless_signal.bin.lz"); -static const struct OamData gOamData_826CD00 = { +static const struct OamData sOamData_Pokeball = { .affineMode = ST_OAM_AFFINE_NORMAL, .shape = SPRITE_SHAPE(16x16), .size = SPRITE_SIZE(16x16) }; -static const union AnimCmd gAnimCmd_826CD08[] = { - ANIMCMD_FRAME(0x00, 3), - ANIMCMD_FRAME(0x04, 3), - ANIMCMD_FRAME(0x08, 3), - ANIMCMD_FRAME(0x0c, 3), - ANIMCMD_FRAME(0x10, 3), - ANIMCMD_FRAME(0x14, 3), - ANIMCMD_FRAME(0x18, 3), - ANIMCMD_FRAME(0x1c, 3), - ANIMCMD_FRAME(0x20, 3), - ANIMCMD_FRAME(0x24, 3), - ANIMCMD_FRAME(0x28, 3), - ANIMCMD_FRAME(0x2c, 3), +static const union AnimCmd sAnim_Pokeball_SpinOnce[] = { + ANIMCMD_FRAME( 0, 3), + ANIMCMD_FRAME( 4, 3), + ANIMCMD_FRAME( 8, 3), + ANIMCMD_FRAME(12, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(20, 3), + ANIMCMD_FRAME(24, 3), + ANIMCMD_FRAME(28, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(36, 3), + ANIMCMD_FRAME(40, 3), + ANIMCMD_FRAME(44, 3), ANIMCMD_LOOP(1), - ANIMCMD_FRAME(0x00, 3), + ANIMCMD_FRAME( 0, 3), ANIMCMD_END }; -static const union AnimCmd gAnimCmd_826CD44[] = { - ANIMCMD_FRAME(0x00, 3), - ANIMCMD_FRAME(0x04, 3), - ANIMCMD_FRAME(0x08, 3), - ANIMCMD_FRAME(0x0c, 3), - ANIMCMD_FRAME(0x10, 3), - ANIMCMD_FRAME(0x14, 3), - ANIMCMD_FRAME(0x18, 3), - ANIMCMD_FRAME(0x1c, 3), - ANIMCMD_FRAME(0x20, 3), - ANIMCMD_FRAME(0x24, 3), - ANIMCMD_FRAME(0x28, 3), - ANIMCMD_FRAME(0x2c, 3), +static const union AnimCmd sAnim_Pokeball_SpinTwice[] = { + ANIMCMD_FRAME( 0, 3), + ANIMCMD_FRAME( 4, 3), + ANIMCMD_FRAME( 8, 3), + ANIMCMD_FRAME(12, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(20, 3), + ANIMCMD_FRAME(24, 3), + ANIMCMD_FRAME(28, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(36, 3), + ANIMCMD_FRAME(40, 3), + ANIMCMD_FRAME(44, 3), ANIMCMD_LOOP(2), - ANIMCMD_FRAME(0x00, 3), + ANIMCMD_FRAME( 0, 3), ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_826CD80[] = { - gAnimCmd_826CD08, - gAnimCmd_826CD44 +static const union AnimCmd *const sAnims_Pokeball[] = { + sAnim_Pokeball_SpinOnce, + sAnim_Pokeball_SpinTwice }; -static const union AffineAnimCmd gAffineAnimCmd_826CD88[] = { +static const union AffineAnimCmd sAffineAnim_Pokeball_Normal[] = { AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_END }; -static const union AffineAnimCmd gAffineAnimCmd_826CD98[] = { +static const union AffineAnimCmd sAffineAnim_Pokeball_Squish[] = { AFFINEANIMCMD_FRAME(-8, 0, 0, 20), AFFINEANIMCMD_END }; -static const union AffineAnimCmd gAffineAnimCmd_826CDA8[] = { +static const union AffineAnimCmd sAffineAnim_Pokeball_Unsquish[] = { AFFINEANIMCMD_FRAME(96, 256, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 0, 5), AFFINEANIMCMD_FRAME(8, 0, 0, 20), AFFINEANIMCMD_END }; -static const union AffineAnimCmd *const gSpriteAffineAnimTable_826CDC8[] = { - gAffineAnimCmd_826CD88, - gAffineAnimCmd_826CD98, - gAffineAnimCmd_826CDA8 +static const union AffineAnimCmd *const sAffineAnims_Pokeball[] = { + sAffineAnim_Pokeball_Normal, + sAffineAnim_Pokeball_Squish, + sAffineAnim_Pokeball_Unsquish }; -static const struct SpriteSheet sTradeBallSpriteSheet = { - sTradeBallTiles, - 0x600, - TAG_BALL_TILES +static const struct SpriteSheet sPokeBallSpriteSheet = { + .data = sPokeball_Gfx, + .size = sizeof(sPokeball_Gfx), + .tag = GFXTAG_POKEBALL }; static const struct SpritePalette sTradeBallSpritePal = { - sTradeBallPalette, - TAG_BALL_PAL + .data = sPokeball_Pal, + .tag = PALTAG_POKEBALL }; -static const struct SpriteTemplate sTradePokeballSpriteTemplate = { - .tileTag = TAG_BALL_TILES, - .paletteTag = TAG_BALL_PAL, - .oam = &gOamData_826CD00, - .anims = gSpriteAnimTable_826CD80, - .affineAnims = gSpriteAffineAnimTable_826CDC8, - .callback = SpriteCB_TradePokeball_Default +static const struct SpriteTemplate sSpriteTemplate_Pokeball = { + .tileTag = GFXTAG_POKEBALL, + .paletteTag = PALTAG_POKEBALL, + .oam = &sOamData_Pokeball, + .anims = sAnims_Pokeball, + .affineAnims = sAffineAnims_Pokeball, + .callback = SpriteCB_BouncingPokeball }; -static const struct OamData gOamData_826CDFC = { +static const struct OamData sOamData_LinkMonGlow = { .affineMode = ST_OAM_AFFINE_NORMAL, .objMode = ST_OAM_OBJ_BLEND, .shape = SPRITE_SHAPE(32x32), @@ -268,179 +275,184 @@ static const struct OamData gOamData_826CDFC = { .priority = 1 }; -static const union AnimCmd gAnimCmd_826CE04[] = { - ANIMCMD_FRAME(0, 5, .hFlip = TRUE, .vFlip = TRUE), +static const union AnimCmd sAnim_LinkMonGlow[] = { + ANIMCMD_FRAME(0, 5, .hFlip = TRUE, .vFlip = TRUE), // ? The graphic is a perfect circle, no need to flip ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_826CE0C[] = { - gAnimCmd_826CE04 +static const union AnimCmd *const sAnims_LinkMonGlow[] = { + sAnim_LinkMonGlow }; -static const union AffineAnimCmd gAffineAnimCmd_826CE10[] = { +static const union AffineAnimCmd sAffineAnim_LinkMonGlow[] = { AFFINEANIMCMD_FRAME(-10, -10, 0, 5), AFFINEANIMCMD_FRAME( 10, 10, 0, 5), AFFINEANIMCMD_JUMP(0) }; -static const union AffineAnimCmd *const gSpriteAffineAnimTable_826CE28[] = { - gAffineAnimCmd_826CE10 +static const union AffineAnimCmd *const sAffineAnims_LinkMonGlow[] = { + sAffineAnim_LinkMonGlow }; -static const struct SpriteSheet sTradeGlow1SpriteSheet = { - sTradeGlow1Tiles, - 0x200, - TAG_GLOW1_TILES +static const struct SpriteSheet sSpriteSheet_LinkMonGlow = { + .data = sLinkMonGlow_Gfx, + .size = sizeof(sLinkMonGlow_Gfx), + .tag = GFXTAG_LINK_MON_GLOW }; -static const struct SpritePalette sTradeGlowSpritePal = { - sTradeGlowPal, - TAG_GLOW_PAL +static const struct SpritePalette sSpritePalette_LinkMon = { + .data = sLinkMon_Pal, + .tag = PALTAG_LINK_MON }; -static const struct SpritePalette sTradeGbaSpritePal = { - sTradeGbaPal, - TAG_GBA_PAL +static const struct SpritePalette sSpritePalette_Gba = { + .data = sGba_Pal, + .tag = PALTAG_GBA }; -static const struct SpriteTemplate sTradeGlow1SpriteTemplate = { - .tileTag = TAG_GLOW1_TILES, - .paletteTag = TAG_GLOW_PAL, - .oam = &gOamData_826CDFC, - .anims = gSpriteAnimTable_826CE0C, - .affineAnims = gSpriteAffineAnimTable_826CE28, - .callback = SpriteCB_TradeGlowCable +static const struct SpriteTemplate sSpriteTemplate_LinkMonGlow = { + .tileTag = GFXTAG_LINK_MON_GLOW, + .paletteTag = PALTAG_LINK_MON, + .oam = &sOamData_LinkMonGlow, + .anims = sAnims_LinkMonGlow, + .affineAnims = sAffineAnims_LinkMonGlow, + .callback = SpriteCB_LinkMonGlow }; -static const struct OamData gOamData_826CE5C = { +static const struct OamData sOamData_LinkMonShadow = { .shape = SPRITE_SHAPE(16x32), .size = SPRITE_SIZE(16x32), .priority = 1 }; -static const union AnimCmd gAnimCmd_826CE64[] = { +static const union AnimCmd sAnim_LinkMonShadow_Big[] = { ANIMCMD_FRAME(0, 5, .hFlip = TRUE, .vFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd gAnimCmd_826CE6C[] = { +static const union AnimCmd sAnim_LinkMonShadow_Small[] = { ANIMCMD_FRAME(8, 5, .hFlip = TRUE, .vFlip = TRUE), ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_826CE74[] = { - gAnimCmd_826CE64, - gAnimCmd_826CE6C +enum { + ANIM_LINKMON_BIG, + ANIM_LINKMON_SMALL, }; -static const struct SpriteSheet sTradeGlow2SpriteSheet = { - sTradeGlow2Tiles, - 0x300, - TAG_GLOW2_TILES +static const union AnimCmd *const sAnims_LinkMonShadow[] = { + [ANIM_LINKMON_BIG] = sAnim_LinkMonShadow_Big, + [ANIM_LINKMON_SMALL] = sAnim_LinkMonShadow_Small, }; -static const struct SpriteTemplate sGlowBallSpriteTemplate = { - .tileTag = TAG_GLOW2_TILES, - .paletteTag = TAG_GLOW_PAL, - .oam = &gOamData_826CE5C, - .anims = gSpriteAnimTable_826CE74, +static const struct SpriteSheet sSpriteSheet_LinkMonShadow = { + .data = sLinkMonShadow_Gfx, + .size = 0x300, + .tag = GFXTAG_LINK_MON_SHADOW +}; + +static const struct SpriteTemplate sSpriteTemplate_LinkMonShadow = { + .tileTag = GFXTAG_LINK_MON_SHADOW, + .paletteTag = PALTAG_LINK_MON, + .oam = &sOamData_LinkMonShadow, + .anims = sAnims_LinkMonShadow, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_TradeGlowCore + .callback = SpriteCB_LinkMonShadow }; -static const struct OamData gOamData_826CE9C = { +static const struct OamData sOamData_CableEnd = { .shape = SPRITE_SHAPE(16x32), .size = SPRITE_SIZE(16x32), .priority = 1 }; -static const union AnimCmd gAnimCmd_826CEA4[] = { +static const union AnimCmd sAnim_CableEnd[] = { ANIMCMD_FRAME(0, 10), ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_826CEAC[] = { - gAnimCmd_826CEA4 +static const union AnimCmd *const sAnims_CableEnd[] = { + sAnim_CableEnd }; -static const struct SpriteSheet sTradeCableEndSpriteSheet = { - sTradeCableEndTiles, - 0x100, - TAG_CABLE_END_TILES +static const struct SpriteSheet sSpriteSheet_CableEnd = { + .data = sCableEnd_Gfx, + .size = 0x100, + .tag = GFXTAG_CABLE_END }; -static const struct SpriteTemplate sGameLinkCableEndSpriteTemplate = { - .tileTag = TAG_CABLE_END_TILES, - .paletteTag = TAG_GBA_PAL, - .oam = &gOamData_826CE9C, - .anims = gSpriteAnimTable_826CEAC, +static const struct SpriteTemplate sSpriteTemplate_CableEnd = { + .tileTag = GFXTAG_CABLE_END, + .paletteTag = PALTAG_GBA, + .oam = &sOamData_CableEnd, + .anims = sAnims_CableEnd, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_GameLinkCableEnd_Outbound + .callback = SpriteCB_CableEndSending }; -static const struct OamData gOamData_826CED0 = { +static const struct OamData sOamData_GbaScreen = { .shape = SPRITE_SHAPE(64x32), .size = SPRITE_SIZE(64x32), .priority = 1 }; -static const union AnimCmd gAnimCmd_826CED8[] = { - ANIMCMD_FRAME(0x00, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x20, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x40, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x60, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x40, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x20, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x00, 2, .hFlip = TRUE, .vFlip = TRUE), +static const union AnimCmd sAnim_GbaScreen_Long[] = { + ANIMCMD_FRAME( 0, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(32, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(64, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(96, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(64, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(32, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME( 0, 2, .hFlip = TRUE, .vFlip = TRUE), ANIMCMD_LOOP(8), ANIMCMD_END }; -static const union AnimCmd gAnimCmd_826CEFC[] = { - ANIMCMD_FRAME(0x00, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x20, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x40, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x60, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x40, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x20, 2, .hFlip = TRUE, .vFlip = TRUE), - ANIMCMD_FRAME(0x00, 2, .hFlip = TRUE, .vFlip = TRUE), +static const union AnimCmd sAnim_GbaScreen_Short[] = { + ANIMCMD_FRAME( 0, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(32, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(64, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(96, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(64, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME(32, 2, .hFlip = TRUE, .vFlip = TRUE), + ANIMCMD_FRAME( 0, 2, .hFlip = TRUE, .vFlip = TRUE), ANIMCMD_LOOP(2), ANIMCMD_END }; -static const union AnimCmd *const gSpriteAnimTable_826CF20[] = { - gAnimCmd_826CED8 +static const union AnimCmd *const sAnims_GbaScreen_Long[] = { + sAnim_GbaScreen_Long }; -static const union AnimCmd *const gSpriteAnimTable_826CF24[] = { - gAnimCmd_826CEFC +static const union AnimCmd *const sAnims_GbaScreen_Short[] = { + sAnim_GbaScreen_Short }; static const struct SpriteSheet sTradeGBAScreenSpriteSheet = { - sTradeGBAScreenTiles, - 0x1000, - TAG_GBA_SCREEN_TILES + .data = sGbaScreen_Gfx, + .size = sizeof(sGbaScreen_Gfx), + .tag = GFXTAG_GBA_SCREEN }; -static const struct SpriteTemplate sTradeGBAScreenSpriteTemplate1 = { - .tileTag = TAG_GBA_SCREEN_TILES, - .paletteTag = TAG_GBA_PAL, - .oam = &gOamData_826CED0, - .anims = gSpriteAnimTable_826CF20, +static const struct SpriteTemplate sSpriteTemplate_GbaScreenFlash_Long = { + .tileTag = GFXTAG_GBA_SCREEN, + .paletteTag = PALTAG_GBA, + .oam = &sOamData_GbaScreen, + .anims = sAnims_GbaScreen_Long, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_TradeGBAScreen + .callback = SpriteCB_GbaScreen }; -static const struct SpriteTemplate sTradeGBAScreenSpriteTemplate2 = { - .tileTag = TAG_GBA_SCREEN_TILES, - .paletteTag = TAG_GBA_PAL, - .oam = &gOamData_826CED0, - .anims = gSpriteAnimTable_826CF24, +static const struct SpriteTemplate sSpriteTemplate_GbaScreenFlash_Short = { + .tileTag = GFXTAG_GBA_SCREEN, + .paletteTag = PALTAG_GBA, + .oam = &sOamData_GbaScreen, + .anims = sAnims_GbaScreen_Short, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_TradeGBAScreen + .callback = SpriteCB_GbaScreen }; -static const u16 sTradeGlow2PaletteAnimTable[] = { +static const u16 sLinkMonShadow_Pal[] = { RGB(18, 24, 31), RGB(18, 24, 31), RGB(18, 24, 31), @@ -455,13 +467,13 @@ static const u16 sTradeGlow2PaletteAnimTable[] = { RGB(31, 31, 31) }; -static const union AffineAnimCmd gAffineAnimCmd_826CF78[] = { +static const union AffineAnimCmd sAffineAnim_CrossingMonPic[] = { AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0), AFFINEANIMCMD_JUMP(0) }; -static const union AffineAnimCmd *const sSpriteAffineAnimTable_PlayerPokePicAlt[] = { - gAffineAnimCmd_826CF78 +static const union AffineAnimCmd *const sAffineAnims_CrossingMonPics[] = { + sAffineAnim_CrossingMonPic }; #include "data/ingame_trades.h" @@ -590,66 +602,58 @@ static const u8 sWirelessSignalAnimParams[][2] = { {16, -1} }; -// Sprite callback for link cable trade glow -static void SpriteCB_TradeGlowCable(struct Sprite *sprite) +static void SpriteCB_LinkMonGlow(struct Sprite *sprite) { - sprite->data[0]++; - if (sprite->data[0] == 10) + if (++sprite->data[0] == 10) { PlaySE(SE_BALL); sprite->data[0] = 0; } } -// Sprite callback for wireless trade glow -static void SpriteCB_TradeGlowWireless(struct Sprite *sprite) +static void SpriteCB_LinkMonGlowWireless(struct Sprite *sprite) { - if (!sprite->invisible) + if (!sprite->invisible && ++sprite->data[0] == 10) { - sprite->data[0]++; - if (sprite->data[0] == 10) - { - PlaySE(SE_M_SWAGGER2); - sprite->data[0] = 0; - } + PlaySE(SE_M_SWAGGER2); + sprite->data[0] = 0; } } // Palette flash for trade glow core -static void SpriteCB_TradeGlowCore(struct Sprite *sprite) +static void SpriteCB_LinkMonShadow(struct Sprite *sprite) { if (sprite->data[1] == 0) { - sprite->data[0]++; - if (sprite->data[0] == 12) + if (++sprite->data[0] == 12) sprite->data[0] = 0; - LoadPalette(&sTradeGlow2PaletteAnimTable[sprite->data[0]], 16 * (sprite->oam.paletteNum + 16) + 4, 2); + LoadPalette(&sLinkMonShadow_Pal[sprite->data[0]], 16 * (sprite->oam.paletteNum + 16) + 4, 2); } } -// Move down for 10 frames -static void SpriteCB_GameLinkCableEnd_Outbound(struct Sprite *sprite) +// Move cable down offscreen +static void SpriteCB_CableEndSending(struct Sprite *sprite) { sprite->data[0]++; sprite->y2++; + if (sprite->data[0] == 10) DestroySprite(sprite); } -// Move up for 10 frames -static void SpriteCB_GameLinkCableEnd_Inbound(struct Sprite *sprite) +// Move cable up onscreen +static void SpriteCB_CableEndReceiving(struct Sprite *sprite) { sprite->data[0]++; sprite->y2--; + if (sprite->data[0] == 10) DestroySprite(sprite); } -// Play a sound every 15 frames -static void SpriteCB_TradeGBAScreen(struct Sprite *sprite) +static void SpriteCB_GbaScreen(struct Sprite *sprite) { - sprite->data[0]++; - if (sprite->data[0] == 15) + if (++sprite->data[0] == 15) { PlaySE(SE_M_MINIMIZE); sprite->data[0] = 0; @@ -659,7 +663,7 @@ static void SpriteCB_TradeGBAScreen(struct Sprite *sprite) static void SetTradeBGAffine(void) { struct BgAffineDstData affine; - DoBgAffineSet(&affine, sTradeData->bg2texX * 0x100, sTradeData->bg2texY * 0x100, sTradeData->bg2srcX, sTradeData->bg2srcY, sTradeData->sXY, sTradeData->sXY, sTradeData->bg2alpha); + DoBgAffineSet(&affine, sTradeAnim->bg2texX * 0x100, sTradeAnim->bg2texY * 0x100, sTradeAnim->bg2srcX, sTradeAnim->bg2srcY, sTradeAnim->sXY, sTradeAnim->sXY, sTradeAnim->bg2alpha); SetGpuReg(REG_OFFSET_BG2PA, affine.pa); SetGpuReg(REG_OFFSET_BG2PB, affine.pb); SetGpuReg(REG_OFFSET_BG2PC, affine.pc); @@ -668,18 +672,18 @@ static void SetTradeBGAffine(void) SetGpuReg(REG_OFFSET_BG2Y, affine.dy); } -static void TradeAnim_UpdateBgRegs(void) +static void SetTradeGpuRegs(void) { u16 dispcnt; - SetGpuReg(REG_OFFSET_BG1VOFS, sTradeData->bg1vofs); - SetGpuReg(REG_OFFSET_BG1HOFS, sTradeData->bg1hofs); + SetGpuReg(REG_OFFSET_BG1VOFS, sTradeAnim->bg1vofs); + SetGpuReg(REG_OFFSET_BG1HOFS, sTradeAnim->bg1hofs); dispcnt = GetGpuReg(REG_OFFSET_DISPCNT); if ((dispcnt & 7) == DISPCNT_MODE_0) { - SetGpuReg(REG_OFFSET_BG2VOFS, sTradeData->bg2vofs); - SetGpuReg(REG_OFFSET_BG2HOFS, sTradeData->bg2hofs); + SetGpuReg(REG_OFFSET_BG2VOFS, sTradeAnim->bg2vofs); + SetGpuReg(REG_OFFSET_BG2HOFS, sTradeAnim->bg2hofs); } else { @@ -689,86 +693,86 @@ static void TradeAnim_UpdateBgRegs(void) static void VBlankCB_TradeAnim(void) { - TradeAnim_UpdateBgRegs(); + SetTradeGpuRegs(); LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } -static void InitLinkTimeoutTracker(void) +static void ClearLinkTimeoutTimer(void) { - sTradeData->linkTimeoutTimer = 0; - sTradeData->linkTimeoutCheck1 = 0; - sTradeData->linkTimeoutCheck2 = 0; + sTradeAnim->linkTimeoutTimer = 0; + sTradeAnim->linkTimeoutCheck1 = 0; + sTradeAnim->linkTimeoutCheck2 = 0; } static void CheckLinkTimeout(void) { - if (sTradeData->linkTimeoutCheck1 == sTradeData->linkTimeoutCheck2) - sTradeData->linkTimeoutTimer++; + if (sTradeAnim->linkTimeoutCheck1 == sTradeAnim->linkTimeoutCheck2) + sTradeAnim->linkTimeoutTimer++; else - sTradeData->linkTimeoutTimer = 0; + sTradeAnim->linkTimeoutTimer = 0; - if (sTradeData->linkTimeoutTimer > 300) + if (sTradeAnim->linkTimeoutTimer > 300) { CloseLink(); SetMainCallback2(CB2_LinkError); - sTradeData->linkTimeoutTimer = 0; - sTradeData->linkTimeoutCheck2 = 0; - sTradeData->linkTimeoutCheck1 = 0; + sTradeAnim->linkTimeoutTimer = 0; + sTradeAnim->linkTimeoutCheck2 = 0; + sTradeAnim->linkTimeoutCheck1 = 0; } - sTradeData->linkTimeoutCheck2 = sTradeData->linkTimeoutCheck1; + sTradeAnim->linkTimeoutCheck2 = sTradeAnim->linkTimeoutCheck1; } -static u32 GetMultiplayerIdOfLinkTrade(void) +static u32 TradeGetMultiplayerId(void) { if (gReceivedRemoteLinkPlayers) return GetMultiplayerId(); return 0; } -static void LoadTradeMonPic(u8 whichParty, u8 action) +static void LoadTradeMonPic(u8 whichParty, u8 state) { int pos = 0; struct Pokemon * mon = NULL; u16 species; u32 personality; - if (whichParty == 0) + if (whichParty == TRADE_PLAYER) { - mon = &gPlayerParty[gSelectedTradeMonPositions[0]]; - pos = 1; + mon = &gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]]; + pos = B_POSITION_OPPONENT_LEFT; } - /*else*/ if (whichParty == 1) + if (whichParty == TRADE_PARTNER) { - mon = &gEnemyParty[gSelectedTradeMonPositions[1] % PARTY_SIZE]; - pos = 3; + mon = &gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE]; + pos = B_POSITION_OPPONENT_RIGHT; } - switch (action) + switch (state) { case 0: // Load graphics species = GetMonData(mon, MON_DATA_SPECIES2); personality = GetMonData(mon, MON_DATA_PERSONALITY); - if (whichParty == 0) + if (whichParty == TRADE_PLAYER) HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites[1], species, personality); else HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites[whichParty * 2 + 1], species, personality); LoadCompressedSpritePalette(GetMonSpritePalStruct(mon)); - sTradeData->tradeSpecies[whichParty] = species; - sTradeData->monPersonalities[whichParty] = personality; + sTradeAnim->monSpecies[whichParty] = species; + sTradeAnim->monPersonalities[whichParty] = personality; break; case 1: // Create sprite SetMultiuseSpriteTemplateToPokemon(GetMonSpritePalStruct(mon)->tag, pos); - sTradeData->pokePicSpriteIdxs[whichParty] = CreateSprite(&gMultiuseSpriteTemplate, 120, 60, 6); - gSprites[sTradeData->pokePicSpriteIdxs[whichParty]].invisible = TRUE; - gSprites[sTradeData->pokePicSpriteIdxs[whichParty]].callback = SpriteCallbackDummy; + sTradeAnim->monSpriteIds[whichParty] = CreateSprite(&gMultiuseSpriteTemplate, 120, 60, 6); + gSprites[sTradeAnim->monSpriteIds[whichParty]].invisible = TRUE; + gSprites[sTradeAnim->monSpriteIds[whichParty]].callback = SpriteCallbackDummy; break; } } @@ -780,37 +784,37 @@ void CB2_LinkTrade(void) case 0: if (!gReceivedRemoteLinkPlayers) { - gLinkType = 0x1144; + gLinkType = LINKTYPE_TRADE_DISCONNECTED; CloseLink(); } - sTradeData = AllocZeroed(sizeof(struct TradeAnimationResources)); + sTradeAnim = AllocZeroed(sizeof(*sTradeAnim)); AllocateMonSpritesGfx(); ResetTasks(); ResetSpriteData(); FreeAllSpritePalettes(); SetVBlankCallback(VBlankCB_TradeAnim); TradeAnimInit_LoadGfx(); - InitLinkTimeoutTracker(); + ClearLinkTimeoutTimer(); gMain.state++; - sTradeData->unk_8C = 0; - sTradeData->state = 0; - sTradeData->isLinkTrade = TRUE; - sTradeData->bg2texX = 64; - sTradeData->bg2texY = 64; - sTradeData->unk_D8 = 0; - sTradeData->unk_DA = 0; - sTradeData->bg2srcX = 120; - sTradeData->bg2srcY = 80; - sTradeData->sXY = 256; - sTradeData->bg2alpha = 0; + sTradeAnim->neverRead_8C = 0; + sTradeAnim->state = 0; + sTradeAnim->isLinkTrade = TRUE; + sTradeAnim->bg2texX = 64; + sTradeAnim->bg2texY = 64; + sTradeAnim->neverRead_D8 = 0; + sTradeAnim->neverRead_DA = 0; + sTradeAnim->bg2srcX = DISPLAY_WIDTH / 2; + sTradeAnim->bg2srcY = DISPLAY_HEIGHT / 2; + sTradeAnim->sXY = 256; + sTradeAnim->bg2alpha = 0; break; case 1: if (!gReceivedRemoteLinkPlayers) { - sTradeData->isCableTrade = TRUE; + sTradeAnim->isCableTrade = TRUE; OpenLink(); gMain.state++; - sTradeData->timer = 0; + sTradeAnim->timer = 0; } else { @@ -818,10 +822,9 @@ void CB2_LinkTrade(void) } break; case 2: - sTradeData->timer++; - if (sTradeData->timer > 60) + if (++sTradeAnim->timer > 60) { - sTradeData->timer = 0; + sTradeAnim->timer = 0; gMain.state++; } break; @@ -830,8 +833,7 @@ void CB2_LinkTrade(void) { if (GetLinkPlayerCount_2() >= GetSavedPlayerCount()) { - sTradeData->timer++; - if (sTradeData->timer > 30) + if (++sTradeAnim->timer > 30) { CheckShouldAdvanceLinkState(); gMain.state++; @@ -849,43 +851,41 @@ void CB2_LinkTrade(void) break; case 4: CheckLinkTimeout(); - if (gReceivedRemoteLinkPlayers == 1 && IsLinkPlayerDataExchangeComplete() == 1) - { + if (gReceivedRemoteLinkPlayers == TRUE && IsLinkPlayerDataExchangeComplete() == TRUE) gMain.state++; - } break; case 5: - sTradeData->tradeStatus1 = 0; - sTradeData->tradeStatus2 = 0; - sTradeData->scheduleLinkTransfer = 0; - LoadTradeMonPic(0, 0); + sTradeAnim->playerFinishStatus = 0; + sTradeAnim->partnerFinishStatus = 0; + sTradeAnim->scheduleLinkTransfer = 0; + LoadTradeMonPic(TRADE_PLAYER, 0); gMain.state++; break; case 6: - LoadTradeMonPic(0, 1); + LoadTradeMonPic(TRADE_PLAYER, 1); gMain.state++; break; case 7: - LoadTradeMonPic(1, 0); + LoadTradeMonPic(TRADE_PARTNER, 0); gMain.state++; break; case 8: - LoadTradeMonPic(1, 1); + LoadTradeMonPic(TRADE_PARTNER, 1); LinkTradeDrawWindow(); gMain.state++; break; case 9: LoadTradeGbaSpriteGfx(); - LoadSpriteSheet(&sTradeBallSpriteSheet); + LoadSpriteSheet(&sPokeBallSpriteSheet); LoadSpritePalette(&sTradeBallSpritePal); gMain.state++; break; case 10: BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); ShowBg(0); - sTradeData->monSpecies[0] = GetMonData(&gPlayerParty[gSelectedTradeMonPositions[0]], MON_DATA_SPECIES2); - sTradeData->monSpecies[1] = GetMonData(&gEnemyParty[gSelectedTradeMonPositions[1] % 6], MON_DATA_SPECIES2); - memcpy(sTradeData->linkPartnerName, gLinkPlayers[GetMultiplayerId() ^ 1].name, 7); + sTradeAnim->questLogSpecies[TRADE_PLAYER] = GetMonData(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], MON_DATA_SPECIES2); + sTradeAnim->questLogSpecies[TRADE_PARTNER] = GetMonData(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], MON_DATA_SPECIES2); + memcpy(sTradeAnim->linkPartnerName, gLinkPlayers[GetMultiplayerId() ^ 1].name, PLAYER_NAME_LENGTH); gMain.state++; break; case 11: @@ -901,7 +901,7 @@ void CB2_LinkTrade(void) LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); } - SetMainCallback2(CB2_RunTradeAnim_LinkTrade); + SetMainCallback2(CB2_UpdateLinkTrade); } break; } @@ -929,7 +929,7 @@ static void TradeAnimInit_LoadGfx(void) { SetGpuReg(REG_OFFSET_DISPCNT, 0); ResetBgsAndClearDma3BusyFlags(FALSE); - InitBgsFromTemplates(0, sBgTemplates, NELEMS(sBgTemplates)); + InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); ChangeBgX(0, 0, 0); ChangeBgY(0, 0, 0); SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE)); @@ -949,54 +949,54 @@ static void TradeAnimInit_LoadGfx(void) LoadCompressedPalette(gBattleInterface_Textbox_Pal, 0x000, 0x20); } -static void CB2_InitTradeAnim_InGameTrade(void) +static void CB2_InitInGameTrade(void) { u8 otName[11]; switch (gMain.state) { case 0: - gSelectedTradeMonPositions[0] = gSpecialVar_0x8005; - gSelectedTradeMonPositions[1] = 6; + gSelectedTradeMonPositions[TRADE_PLAYER] = gSpecialVar_0x8005; + gSelectedTradeMonPositions[TRADE_PARTNER] = PARTY_SIZE; StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName); GetMonData(&gEnemyParty[0], MON_DATA_OT_NAME, otName); StringCopy(gLinkPlayers[1].name, otName); - sTradeData = AllocZeroed(sizeof(*sTradeData)); + sTradeAnim = AllocZeroed(sizeof(*sTradeAnim)); AllocateMonSpritesGfx(); ResetTasks(); ResetSpriteData(); FreeAllSpritePalettes(); SetVBlankCallback(VBlankCB_TradeAnim); TradeAnimInit_LoadGfx(); - sTradeData->isLinkTrade = FALSE; - sTradeData->unk_8C = 0; - sTradeData->state = 0; - sTradeData->bg2texX = 64; - sTradeData->bg2texY = 64; - sTradeData->unk_D8 = 0; - sTradeData->unk_DA = 0; - sTradeData->bg2srcX = 120; - sTradeData->bg2srcY = 80; - sTradeData->sXY = 256; - sTradeData->bg2alpha = 0; - sTradeData->timer = 0; + sTradeAnim->isLinkTrade = FALSE; + sTradeAnim->neverRead_8C = 0; + sTradeAnim->state = 0; + sTradeAnim->bg2texX = 64; + sTradeAnim->bg2texY = 64; + sTradeAnim->neverRead_D8 = 0; + sTradeAnim->neverRead_DA = 0; + sTradeAnim->bg2srcX = DISPLAY_WIDTH / 2; + sTradeAnim->bg2srcY = DISPLAY_HEIGHT / 2; + sTradeAnim->sXY = 256; + sTradeAnim->bg2alpha = 0; + sTradeAnim->timer = 0; gMain.state = 5; break; case 5: - LoadTradeMonPic(0, 0); + LoadTradeMonPic(TRADE_PLAYER, 0); gMain.state++; break; case 6: - LoadTradeMonPic(0, 1); + LoadTradeMonPic(TRADE_PLAYER, 1); gMain.state++; break; case 7: - LoadTradeMonPic(1, 0); + LoadTradeMonPic(TRADE_PARTNER, 0); ShowBg(0); gMain.state++; break; case 8: - LoadTradeMonPic(1, 1); + LoadTradeMonPic(TRADE_PARTNER, 1); FillWindowPixelBuffer(0, PIXEL_FILL(15)); PutWindowTilemap(0); CopyWindowToVram(0, COPYWIN_FULL); @@ -1004,7 +1004,7 @@ static void CB2_InitTradeAnim_InGameTrade(void) break; case 9: LoadTradeGbaSpriteGfx(); - LoadSpriteSheet(&sTradeBallSpriteSheet); + LoadSpriteSheet(&sPokeBallSpriteSheet); LoadSpritePalette(&sTradeBallSpritePal); gMain.state++; break; @@ -1019,7 +1019,7 @@ static void CB2_InitTradeAnim_InGameTrade(void) gMain.state++; break; case 12: - SetMainCallback2(CB2_RunTradeAnim_InGameTrade); + SetMainCallback2(CB2_InGameTrade); break; } @@ -1030,7 +1030,7 @@ static void CB2_InitTradeAnim_InGameTrade(void) UpdatePaletteFade(); } -static void ReceivedMonSetPokedexFlags(u8 partyIdx) +static void UpdatePokedexForReceivedMon(u8 partyIdx) { struct Pokemon * mon = &gPlayerParty[partyIdx]; @@ -1044,7 +1044,7 @@ static void ReceivedMonSetPokedexFlags(u8 partyIdx) } } -static void RS_TryEnableNationalPokedex(void) +static void TryEnableNationalDexFromLinkPartner(void) { u8 mpId = GetMultiplayerId(); // Originally in Ruby but commented out @@ -1064,45 +1064,44 @@ static void TradeMons(u8 playerPartyIdx, u8 partnerPartyIdx) u16 partnerMail = GetMonData(partnerMon, MON_DATA_MAIL); // The mail attached to the sent Pokemon no longer exists in your file. - if (playerMail != 0xFF) + if (playerMail != MAIL_NONE) ClearMailStruct(&gSaveBlock1Ptr->mail[playerMail]); - // This is where the actual trade happens!! - sTradeData->mon = *playerMon; - *playerMon = *partnerMon; - *partnerMon = sTradeData->mon; + SWAP(*playerMon, *partnerMon, sTradeAnim->tempMon); // By default, a Pokemon received from a trade will have 70 Friendship. + // Eggs use Friendship to track egg cycles, so don't set this on Eggs. friendship = 70; if (!GetMonData(playerMon, MON_DATA_IS_EGG)) SetMonData(playerMon, MON_DATA_FRIENDSHIP, &friendship); // Associate your partner's mail with the Pokemon they sent over. - if (partnerMail != 0xFF) + if (partnerMail != MAIL_NONE) GiveMailToMon2(playerMon, &gLinkPartnerMail[partnerMail]); - ReceivedMonSetPokedexFlags(playerPartyIdx); + UpdatePokedexForReceivedMon(playerPartyIdx); if (gReceivedRemoteLinkPlayers) - RS_TryEnableNationalPokedex(); + TryEnableNationalDexFromLinkPartner(); } static void HandleLinkDataSend(void) { - switch (sTradeData->scheduleLinkTransfer) + switch (sTradeAnim->scheduleLinkTransfer) { case 1: if (IsLinkTaskFinished()) { - SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, 20); - sTradeData->scheduleLinkTransfer++; + SendBlock(BitmaskAllOtherLinkPlayers(), sTradeAnim->linkData, sizeof(sTradeAnim->linkData)); + sTradeAnim->scheduleLinkTransfer++; } + // fallthrough case 2: - sTradeData->scheduleLinkTransfer = 0; + sTradeAnim->scheduleLinkTransfer = 0; break; } } -static void CB2_RunTradeAnim_InGameTrade(void) +static void CB2_InGameTrade(void) { DoTradeAnim(); RunTasks(); @@ -1117,8 +1116,8 @@ static void SetTradeSequenceBgGpuRegs(u8 state) switch (state) { case 0: - sTradeData->bg2vofs = 0; - sTradeData->bg2hofs = 0xB4; + sTradeAnim->bg2vofs = 0; + sTradeAnim->bg2hofs = 0xB4; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(1) | BGCNT_SCREENBASE(18) | BGCNT_TXT512x256); LoadPalette(gTradeGba2_Pal, 0x10, 0x60); @@ -1126,12 +1125,12 @@ static void SetTradeSequenceBgGpuRegs(u8 state) DmaCopy16Defvars(3, gTradeOrHatchMonShadowTilemap, (void *)BG_SCREEN_ADDR(18), 0x1000); break; case 1: - sTradeData->bg1hofs = 0; - sTradeData->bg1vofs = 0x15C; + sTradeAnim->bg1hofs = 0; + sTradeAnim->bg1vofs = 0x15C; SetGpuReg(REG_OFFSET_BG1VOFS, 0x15C); SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(5) | BGCNT_TXT256x512); SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(1) | BGCNT_SCREENBASE(18) | BGCNT_TXT256x512); - if (sTradeData->isCableTrade) + if (sTradeAnim->isCableTrade) { DmaCopy16Defvars(3, sGbaMapCable, (void *)BG_SCREEN_ADDR(5), 0x1000); } @@ -1143,18 +1142,18 @@ static void SetTradeSequenceBgGpuRegs(u8 state) SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); break; case 2: - sTradeData->bg1vofs = 0; - sTradeData->bg1hofs = 0; - if (!sTradeData->isCableTrade) + sTradeAnim->bg1vofs = 0; + sTradeAnim->bg1hofs = 0; + if (!sTradeAnim->isCableTrade) { SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); - LZ77UnCompVram(sWirelessCloseupMap, (void *)BG_SCREEN_ADDR(5)); + LZ77UnCompVram(sWirelessCloseup_Map, (void *)BG_SCREEN_ADDR(5)); BlendPalettes(0x000000008, 0x10, RGB_BLACK); } else { SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); - DmaCopy16Defvars(3, sCableCloseupMap, (void *)BG_SCREEN_ADDR(5), 0x800); + DmaCopy16Defvars(3, sCableCloseup_Map, (void *)BG_SCREEN_ADDR(5), 0x800); BlendPalettes(0x00000001, 0x10, RGB_BLACK); } break; @@ -1162,19 +1161,19 @@ static void SetTradeSequenceBgGpuRegs(u8 state) LoadPalette(sWirelessSignalAnimPals_Off, 0x30, 0x20); LZ77UnCompVram(sWirelessSignal4bpp, BG_CHAR_ADDR(1)); LZ77UnCompVram(sWirelessSignalTilemap, BG_SCREEN_ADDR(18)); - sTradeData->bg2vofs = 0x50; + sTradeAnim->bg2vofs = 0x50; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); break; case 4: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(3) | BGCNT_CHARBASE(1) | BGCNT_256COLOR | BGCNT_SCREENBASE(18) | BGCNT_AFF128x128); - sTradeData->bg2texX = 0x40; - sTradeData->bg2texY = 0x5C; - sTradeData->sXY = 0x20; - sTradeData->bg2Zoom = 0x400; - sTradeData->bg2alpha = 0; - DmaCopyLarge16(3, sGbaAffineTiles, (void *)BG_CHAR_ADDR(1), 0x2840, 0x1000); - if (sTradeData->isCableTrade) + sTradeAnim->bg2texX = 0x40; + sTradeAnim->bg2texY = 0x5C; + sTradeAnim->sXY = 0x20; + sTradeAnim->bg2Zoom = 0x400; + sTradeAnim->bg2alpha = 0; + DmaCopyLarge16(3, sGbaAffine_Gfx, (void *)BG_CHAR_ADDR(1), 0x2840, 0x1000); + if (sTradeAnim->isCableTrade) { DmaCopy16Defvars(3, sGbaAffineMapCable, (void *)BG_SCREEN_ADDR(18), 0x100); } @@ -1184,21 +1183,21 @@ static void SetTradeSequenceBgGpuRegs(u8 state) } break; case 5: - sTradeData->bg1vofs = 0; - sTradeData->bg1hofs = 0; + sTradeAnim->bg1vofs = 0; + sTradeAnim->bg1hofs = 0; break; case 6: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(3) | BGCNT_CHARBASE(1) | BGCNT_256COLOR | BGCNT_SCREENBASE(18) | BGCNT_TXT256x256); - sTradeData->bg2texX = 0x40; - sTradeData->bg2texY = 0x5C; - sTradeData->sXY = 0x100; - sTradeData->bg2Zoom = 0x80; - sTradeData->bg2srcX = 0x78; - sTradeData->bg2srcY = 0x50; - sTradeData->bg2alpha = 0; - DmaCopyLarge16(3, sGbaAffineTiles, BG_CHAR_ADDR(1), 0x2840, 0x1000); - if (sTradeData->isCableTrade) + sTradeAnim->bg2texX = 0x40; + sTradeAnim->bg2texY = 0x5C; + sTradeAnim->sXY = 0x100; + sTradeAnim->bg2Zoom = 0x80; + sTradeAnim->bg2srcX = 0x78; + sTradeAnim->bg2srcY = 0x50; + sTradeAnim->bg2alpha = 0; + DmaCopyLarge16(3, sGbaAffine_Gfx, BG_CHAR_ADDR(1), 0x2840, 0x1000); + if (sTradeAnim->isCableTrade) { DmaCopy16Defvars(3, sGbaAffineMapCable, (void *)BG_SCREEN_ADDR(18), 0x100); } @@ -1208,8 +1207,8 @@ static void SetTradeSequenceBgGpuRegs(u8 state) } break; case 7: - sTradeData->bg2vofs = 0; - sTradeData->bg2hofs = 0; + sTradeAnim->bg2vofs = 0; + sTradeAnim->bg2hofs = 0; SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(1) | BGCNT_SCREENBASE(18) | BGCNT_TXT512x256); LoadPalette(gTradeGba2_Pal, 0x10, 0x60); @@ -1221,12 +1220,12 @@ static void SetTradeSequenceBgGpuRegs(u8 state) static void LoadTradeGbaSpriteGfx(void) { - LoadSpriteSheet(&sTradeGlow1SpriteSheet); - LoadSpriteSheet(&sTradeGlow2SpriteSheet); - LoadSpriteSheet(&sTradeCableEndSpriteSheet); + LoadSpriteSheet(&sSpriteSheet_LinkMonGlow); + LoadSpriteSheet(&sSpriteSheet_LinkMonShadow); + LoadSpriteSheet(&sSpriteSheet_CableEnd); LoadSpriteSheet(&sTradeGBAScreenSpriteSheet); - LoadSpritePalette(&sTradeGlowSpritePal); - LoadSpritePalette(&sTradeGbaSpritePal); + LoadSpritePalette(&sSpritePalette_LinkMon); + LoadSpritePalette(&sSpritePalette_Gba); } static void TradeBufferOTnameAndNicknames(void) @@ -1234,13 +1233,13 @@ static void TradeBufferOTnameAndNicknames(void) u8 nickname[20]; u8 mpId; const struct InGameTrade * inGameTrade; - if (sTradeData->isLinkTrade) + if (sTradeAnim->isLinkTrade) { mpId = GetMultiplayerId(); StringCopy(gStringVar1, gLinkPlayers[mpId ^ 1].name); - GetMonData(&gEnemyParty[gSelectedTradeMonPositions[1] % 6], MON_DATA_NICKNAME, nickname); + GetMonData(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], MON_DATA_NICKNAME, nickname); StringCopy_Nickname(gStringVar3, nickname); - GetMonData(&gPlayerParty[gSelectedTradeMonPositions[0]], MON_DATA_NICKNAME, nickname); + GetMonData(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], MON_DATA_NICKNAME, nickname); StringCopy_Nickname(gStringVar2, nickname); } else @@ -1253,414 +1252,478 @@ static void TradeBufferOTnameAndNicknames(void) } } +// returns TRUE if it finished a link trade, FALSE if it finished an in-game trade or if sequence is still going static bool8 DoTradeAnim(void) { - if (sTradeData->isCableTrade) + if (sTradeAnim->isCableTrade) return DoTradeAnim_Cable(); else return DoTradeAnim_Wireless(); } +// Below are the states for the main switch in DoTradeAnim_Cable and DoTradeAnim_Wireless +// When DoTradeAnim_Wireless has a unique version of a state used by DoTradeAnim_Cable, it adds the below modifier +#define STATE_WIRELESS 100 +enum { + STATE_START, + STATE_MON_SLIDE_IN, + // 2-9 unused + STATE_SEND_MSG = 10, + STATE_BYE_BYE, + STATE_POKEBALL_DEPART, + STATE_POKEBALL_DEPART_WAIT, + STATE_FADE_OUT_TO_GBA_SEND, + // 15-19 unused + STATE_WAIT_FADE_OUT_TO_GBA_SEND = 20, + STATE_FADE_IN_TO_GBA_SEND, + STATE_WAIT_FADE_IN_TO_GBA_SEND, + STATE_GBA_ZOOM_OUT, + STATE_GBA_FLASH_SEND, + STATE_GBA_STOP_FLASH_SEND, + STATE_PAN_AWAY_GBA, + STATE_CREATE_LINK_MON_LEAVING, + STATE_LINK_MON_TRAVEL_OUT, + STATE_FADE_OUT_TO_CROSSING, + STATE_WAIT_FADE_OUT_TO_CROSSING, + STATE_FADE_IN_TO_CROSSING, + STATE_WAIT_FADE_IN_TO_CROSSING, + STATE_CROSSING_LINK_MONS_ENTER, + STATE_CROSSING_BLEND_WHITE_1, + STATE_CROSSING_BLEND_WHITE_2, + STATE_CROSSING_BLEND_WHITE_3, + STATE_CROSSING_CREATE_MON_PICS, + STATE_CROSSING_MON_PICS_MOVE, + STATE_CROSSING_LINK_MONS_EXIT, + STATE_CREATE_LINK_MON_ARRIVING, + STATE_FADE_OUT_TO_GBA_RECV, + STATE_WAIT_FADE_OUT_TO_GBA_RECV, + STATE_LINK_MON_TRAVEL_IN, + STATE_PAN_TO_GBA, + STATE_DESTROY_LINK_MON, + STATE_LINK_MON_ARRIVED_DELAY, + STATE_MOVE_GBA_TO_CENTER, + STATE_GBA_FLASH_RECV, + STATE_UNUSED, + STATE_GBA_STOP_FLASH_RECV, + STATE_GBA_ZOOM_IN, + STATE_FADE_OUT_TO_NEW_MON, + // 53-59 unused + STATE_WAIT_FADE_OUT_TO_NEW_MON = 60, + STATE_FADE_IN_TO_NEW_MON, + STATE_WAIT_FADE_IN_TO_NEW_MON, + STATE_POKEBALL_ARRIVE, + STATE_FADE_POKEBALL_TO_NORMAL, + STATE_POKEBALL_ARRIVE_WAIT, + STATE_SHOW_NEW_MON, + STATE_NEW_MON_MSG, + STATE_TAKE_CARE_OF_MON, + STATE_AFTER_NEW_MON_DELAY, + STATE_CHECK_RIBBONS, + STATE_END_LINK_TRADE, + STATE_TRY_EVOLUTION, + STATE_FADE_OUT_END, + STATE_WAIT_FADE_OUT_END, + // Special states + STATE_GBA_FLASH_SEND_WIRELESS = STATE_GBA_FLASH_SEND + STATE_WIRELESS, + STATE_GBA_STOP_FLASH_SEND_WIRELESS, + STATE_WAIT_WIRELESS_SIGNAL_SEND, + STATE_PAN_TO_GBA_WIRELESS = STATE_PAN_TO_GBA + STATE_WIRELESS, + STATE_DESTROY_LINK_MON_WIRELESS, + STATE_WAIT_WIRELESS_SIGNAL_RECV, + STATE_DELAY_FOR_MON_ANIM = 167, + STATE_LINK_MON_TRAVEL_OFFSCREEN = 200, + STATE_WAIT_FOR_MON_CRY = 267, +}; + static bool8 DoTradeAnim_Cable(void) { u16 evoTarget; - switch (sTradeData->state) + switch (sTradeAnim->state) { - case 0: - gSprites[sTradeData->pokePicSpriteIdxs[0]].invisible = FALSE; - gSprites[sTradeData->pokePicSpriteIdxs[0]].x2 = -180; - gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 = gMonFrontPicCoords[sTradeData->tradeSpecies[0]].y_offset; - sTradeData->state++; - sTradeData->cachedMapMusic = GetCurrentMapMusic(); + case STATE_START: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 = -180; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PLAYER]].y_offset; + sTradeAnim->state++; + sTradeAnim->cachedMapMusic = GetCurrentMapMusic(); PlayNewMapMusic(MUS_EVOLUTION); break; - case 1: - if (sTradeData->bg2hofs > 0) + case STATE_MON_SLIDE_IN: + if (sTradeAnim->bg2hofs > 0) { - gSprites[sTradeData->pokePicSpriteIdxs[0]].x2 += 3; - sTradeData->bg2hofs -= 3; + // Sliding + gSprites[sTradeAnim->monSpriteIds[0]].x2 += 3; + sTradeAnim->bg2hofs -= 3; } else { - gSprites[sTradeData->pokePicSpriteIdxs[0]].x2 = 0; - sTradeData->bg2hofs = 0; - sTradeData->state = 10; + // Pokémon has arrived onscreen + gSprites[sTradeAnim->monSpriteIds[0]].x2 = 0; + sTradeAnim->bg2hofs = 0; + sTradeAnim->state = STATE_SEND_MSG; } break; - case 10: + case STATE_SEND_MSG: StringExpandPlaceholders(gStringVar4, gText_XWillBeSentToY); DrawTextOnTradeWindow(0, gStringVar4, 0); - if (sTradeData->tradeSpecies[0] != SPECIES_EGG) - { - PlayCry_Normal(sTradeData->tradeSpecies[0], 0); - } + if (sTradeAnim->monSpecies[TRADE_PLAYER] != SPECIES_EGG) + PlayCry_Normal(sTradeAnim->monSpecies[TRADE_PLAYER], 0); - sTradeData->state = 11; - sTradeData->timer = 0; + sTradeAnim->state = STATE_BYE_BYE; + sTradeAnim->timer = 0; break; - case 11: - if (++sTradeData->timer == 80) + case STATE_BYE_BYE: + if (++sTradeAnim->timer == 80) { - sTradeData->pokeballSpriteId = CreateTradePokeballSprite(sTradeData->pokePicSpriteIdxs[0], gSprites[sTradeData->pokePicSpriteIdxs[0]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); - sTradeData->state++; + sTradeAnim->releasePokeballSpriteId = CreateTradePokeballSprite(sTradeAnim->monSpriteIds[TRADE_PLAYER], gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_ByeByeVar1); DrawTextOnTradeWindow(0, gStringVar4, 0); } break; - case 12: - if (gSprites[sTradeData->pokeballSpriteId].callback == SpriteCallbackDummy) + case STATE_POKEBALL_DEPART: + if (gSprites[sTradeAnim->releasePokeballSpriteId].callback == SpriteCallbackDummy) { - sTradeData->pokeballSpriteId2 = CreateSprite(&sTradePokeballSpriteTemplate, 120, 32, 0); - gSprites[sTradeData->pokeballSpriteId2].callback = SpriteCB_TradePokeball_Outbound; - DestroySprite(&gSprites[sTradeData->pokeballSpriteId]); - sTradeData->state++; + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, 32, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballDepart; + DestroySprite(&gSprites[sTradeAnim->releasePokeballSpriteId]); + sTradeAnim->state++; } break; - case 13: + case STATE_POKEBALL_DEPART_WAIT: // The game waits here for the sprite to finish its animation sequence. break; - case 14: + case STATE_FADE_OUT_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = 20; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_GBA_SEND; break; - case 20: + case STATE_WAIT_FADE_OUT_TO_GBA_SEND: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(4); FillWindowPixelBuffer(0, PIXEL_FILL(15)); CopyWindowToVram(0, COPYWIN_FULL); - sTradeData->state++; + sTradeAnim->state++; } break; - case 21: + case STATE_FADE_IN_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 22: + case STATE_WAIT_FADE_IN_TO_GBA_SEND: if (!gPaletteFade.active) - { - sTradeData->state = 23; - } + sTradeAnim->state = STATE_GBA_ZOOM_OUT; break; - case 23: - if (sTradeData->bg2Zoom > 0x100) + case STATE_GBA_ZOOM_OUT: + if (sTradeAnim->bg2Zoom > 0x100) { - sTradeData->bg2Zoom -= 0x34; + sTradeAnim->bg2Zoom -= 0x34; } else { SetTradeSequenceBgGpuRegs(1); - sTradeData->bg2Zoom = 0x80; - sTradeData->state++; - sTradeData->timer = 0; + sTradeAnim->bg2Zoom = 0x80; + sTradeAnim->state++; + sTradeAnim->timer = 0; } - sTradeData->sXY = 0x8000 / sTradeData->bg2Zoom; + sTradeAnim->sXY = 0x8000 / sTradeAnim->bg2Zoom; break; - case 24: - if (++sTradeData->timer > 20) + case STATE_GBA_FLASH_SEND: + if (++sTradeAnim->timer > 20) { SetTradeBGAffine(); - sTradeData->gbaScreenSpriteId = CreateSprite(&sTradeGBAScreenSpriteTemplate1, 120, 80, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); + sTradeAnim->state++; } break; - case 25: - if (gSprites[sTradeData->gbaScreenSpriteId].animEnded) + case STATE_GBA_STOP_FLASH_SEND: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 4)); - sTradeData->state++; + sTradeAnim->state++; } break; - case 26: - if (--sTradeData->bg1vofs == 316) - { - sTradeData->state++; - } - if (sTradeData->bg1vofs == 328) - { - sTradeData->linkCableEndSpriteId = CreateSprite(&sGameLinkCableEndSpriteTemplate, 128, 65, 0); - } + case STATE_PAN_AWAY_GBA: + if (--sTradeAnim->bg1vofs == 316) + sTradeAnim->state++; + + if (sTradeAnim->bg1vofs == 328) + sTradeAnim->cableEndSpriteId = CreateSprite(&sSpriteTemplate_CableEnd, 128, 65, 0); break; - case 27: - sTradeData->tradeGlow1SpriteId = CreateSprite(&sTradeGlow1SpriteTemplate, 128, 80, 3); - sTradeData->gbaScreenSpriteId = CreateSprite(&sGlowBallSpriteTemplate, 128, 80, 0); - StartSpriteAnim(&gSprites[sTradeData->gbaScreenSpriteId], 1); - sTradeData->state++; + case STATE_CREATE_LINK_MON_LEAVING: + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 128, 80, 3); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 128, 80, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], ANIM_LINKMON_SMALL); + sTradeAnim->state++; break; - case 28: - if ((sTradeData->bg1vofs -= 2) == 166) - { - sTradeData->state = 200; - } + case STATE_LINK_MON_TRAVEL_OUT: + if ((sTradeAnim->bg1vofs -= 2) == 166) + sTradeAnim->state = STATE_LINK_MON_TRAVEL_OFFSCREEN; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); break; - case 200: - gSprites[sTradeData->tradeGlow1SpriteId].y -= 2; - gSprites[sTradeData->gbaScreenSpriteId].y -= 2; - if (gSprites[sTradeData->tradeGlow1SpriteId].y < -8) - { - sTradeData->state = 29; - } + case STATE_LINK_MON_TRAVEL_OFFSCREEN: + gSprites[sTradeAnim->connectionSpriteId1].y -= 2; + gSprites[sTradeAnim->connectionSpriteId2].y -= 2; + if (gSprites[sTradeAnim->connectionSpriteId1].y < -8) + sTradeAnim->state = STATE_FADE_OUT_TO_CROSSING; break; - case 29: + case STATE_FADE_OUT_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state = 30; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_CROSSING; break; - case 30: + case STATE_WAIT_FADE_OUT_TO_CROSSING: if (!gPaletteFade.active) { - DestroySprite(&gSprites[sTradeData->tradeGlow1SpriteId]); - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(2); - sTradeData->state++; + sTradeAnim->state++; } break; - case 31: + case STATE_FADE_IN_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->tradeGlow1SpriteId = CreateSprite(&sGlowBallSpriteTemplate, 111, 170, 0); - sTradeData->gbaScreenSpriteId = CreateSprite(&sGlowBallSpriteTemplate, 129, -10, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 111, 170, 0); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 129, -10, 0); + sTradeAnim->state++; break; - case 32: + case STATE_WAIT_FADE_IN_TO_CROSSING: if (!gPaletteFade.active) { PlaySE(SE_WARP_OUT); - sTradeData->state++; + sTradeAnim->state++; } - gSprites[sTradeData->tradeGlow1SpriteId].y2 -= 3; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 3; + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; break; - case 33: - gSprites[sTradeData->tradeGlow1SpriteId].y2 -= 3; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 3; - if (gSprites[sTradeData->tradeGlow1SpriteId].y2 <= -90) + case STATE_CROSSING_LINK_MONS_ENTER: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -90) { - gSprites[sTradeData->tradeGlow1SpriteId].data[1] = 1; - gSprites[sTradeData->gbaScreenSpriteId].data[1] = 1; - sTradeData->state++; + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 1; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 1; + sTradeAnim->state++; } break; - case 34: + case STATE_CROSSING_BLEND_WHITE_1: BlendPalettes(0x1, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case 35: + case STATE_CROSSING_BLEND_WHITE_2: BlendPalettes(0x1, 0, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case 36: + case STATE_CROSSING_BLEND_WHITE_3: BlendPalettes(0x1, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case 37: - if (!IsPokeSpriteNotFlipped(sTradeData->tradeSpecies[0])) + case STATE_CROSSING_CREATE_MON_PICS: + if (!IsMonSpriteNotFlipped(sTradeAnim->monSpecies[TRADE_PLAYER])) { - gSprites[sTradeData->pokePicSpriteIdxs[0]].affineAnims = sSpriteAffineAnimTable_PlayerPokePicAlt; - gSprites[sTradeData->pokePicSpriteIdxs[0]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; - CalcCenterToCornerVec(&gSprites[sTradeData->pokePicSpriteIdxs[0]], 0, 3, 3); - StartSpriteAffineAnim(&gSprites[sTradeData->pokePicSpriteIdxs[0]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].affineAnims = sAffineAnims_CrossingMonPics; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + CalcCenterToCornerVec(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], SPRITE_SHAPE(64x64), SPRITE_SIZE(64x64), ST_OAM_AFFINE_DOUBLE); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } else { - StartSpriteAffineAnim(&gSprites[sTradeData->pokePicSpriteIdxs[0]], 0); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } - StartSpriteAffineAnim(&gSprites[sTradeData->pokePicSpriteIdxs[1]], 0); - gSprites[sTradeData->pokePicSpriteIdxs[0]].x = 60; - gSprites[sTradeData->pokePicSpriteIdxs[1]].x = 180; - gSprites[sTradeData->pokePicSpriteIdxs[0]].y = 192; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y = -32; - gSprites[sTradeData->pokePicSpriteIdxs[0]].invisible = FALSE; - gSprites[sTradeData->pokePicSpriteIdxs[1]].invisible = FALSE; - sTradeData->state++; + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x = 60; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 180; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y = 192; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = -32; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = FALSE; + sTradeAnim->state++; break; - case 38: - gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 -= 3; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y2 += 3; - if (gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 < -160 && gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 >= -163) + case STATE_CROSSING_MON_PICS_MOVE: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 -= 3; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 += 3; + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -DISPLAY_HEIGHT + && gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 >= -DISPLAY_HEIGHT - 3) { PlaySE(SE_WARP_IN); } - if (gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 < -222) + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -222) { - gSprites[sTradeData->tradeGlow1SpriteId].data[1] = 0; - gSprites[sTradeData->gbaScreenSpriteId].data[1] = 0; - sTradeData->state++; - gSprites[sTradeData->pokePicSpriteIdxs[0]].invisible = TRUE; - gSprites[sTradeData->pokePicSpriteIdxs[1]].invisible = TRUE; + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 0; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 0; + sTradeAnim->state++; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = TRUE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = TRUE; BlendPalettes(0x1, 0, RGB_WHITEALPHA); } break; - case 39: - gSprites[sTradeData->tradeGlow1SpriteId].y2 -= 3; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 3; - if (gSprites[sTradeData->tradeGlow1SpriteId].y2 <= -222) + case STATE_CROSSING_LINK_MONS_EXIT: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -222) { BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state++; - DestroySprite(&gSprites[sTradeData->tradeGlow1SpriteId]); - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + sTradeAnim->state++; + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); } break; - case 40: + case STATE_CREATE_LINK_MON_ARRIVING: if (!gPaletteFade.active) { - sTradeData->state++; + sTradeAnim->state++; SetTradeSequenceBgGpuRegs(1); - sTradeData->bg1vofs = 166; - sTradeData->tradeGlow1SpriteId = CreateSprite(&sTradeGlow1SpriteTemplate, 128, -20, 3); - sTradeData->gbaScreenSpriteId = CreateSprite(&sGlowBallSpriteTemplate, 128, -20, 0); - StartSpriteAnim(&gSprites[sTradeData->gbaScreenSpriteId], 1); + sTradeAnim->bg1vofs = 166; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 128, -20, 3); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 128, -20, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], ANIM_LINKMON_SMALL); } break; - case 41: + case STATE_FADE_OUT_TO_GBA_RECV: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 42: + case STATE_WAIT_FADE_OUT_TO_GBA_RECV: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) + sTradeAnim->state++; + break; + case STATE_LINK_MON_TRAVEL_IN: + gSprites[sTradeAnim->connectionSpriteId1].y2 += 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 + gSprites[sTradeAnim->connectionSpriteId1].y == 64) + sTradeAnim->state++; + break; + case STATE_PAN_TO_GBA: + if ((sTradeAnim->bg1vofs += 2) > 316) { - sTradeData->state++; + sTradeAnim->bg1vofs = 316; + sTradeAnim->state++; } break; - case 43: - gSprites[sTradeData->tradeGlow1SpriteId].y2 += 3; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 3; - if (gSprites[sTradeData->tradeGlow1SpriteId].y2 + gSprites[sTradeData->tradeGlow1SpriteId].y == 64) + case STATE_DESTROY_LINK_MON: + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); + sTradeAnim->state++; + sTradeAnim->timer = 0; + break; + case STATE_LINK_MON_ARRIVED_DELAY: + if (++sTradeAnim->timer == 10) + sTradeAnim->state++; + break; + case STATE_MOVE_GBA_TO_CENTER: + if (++sTradeAnim->bg1vofs > 348) { - sTradeData->state++; + sTradeAnim->bg1vofs = 348; + sTradeAnim->state++; + } + if (sTradeAnim->bg1vofs == 328 && sTradeAnim->isCableTrade) + { + sTradeAnim->cableEndSpriteId = CreateSprite(&sSpriteTemplate_CableEnd, 128, 65, 0); + gSprites[sTradeAnim->cableEndSpriteId].callback = SpriteCB_CableEndReceiving; } break; - case 44: - if ((sTradeData->bg1vofs += 2) > 316) - { - sTradeData->bg1vofs = 316; - sTradeData->state++; - } + case STATE_GBA_FLASH_RECV: + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); + sTradeAnim->state = STATE_GBA_STOP_FLASH_RECV; break; - case 45: - DestroySprite(&gSprites[sTradeData->tradeGlow1SpriteId]); - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); - sTradeData->state++; - sTradeData->timer = 0; - break; - case 46: - if (++sTradeData->timer == 10) + case STATE_GBA_STOP_FLASH_RECV: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - sTradeData->state++; - } - break; - case 47: - if (++sTradeData->bg1vofs > 348) - { - sTradeData->bg1vofs = 348; - sTradeData->state++; - } - if (sTradeData->bg1vofs == 328 && sTradeData->isCableTrade) - { - sTradeData->linkCableEndSpriteId = CreateSprite(&sGameLinkCableEndSpriteTemplate, 128, 65, 0); - gSprites[sTradeData->linkCableEndSpriteId].callback = SpriteCB_GameLinkCableEnd_Inbound; - } - break; - case 48: - sTradeData->gbaScreenSpriteId = CreateSprite(&sTradeGBAScreenSpriteTemplate1, 120, 80, 0); - sTradeData->state = 50; - break; - case 50: - if (gSprites[sTradeData->gbaScreenSpriteId].animEnded) - { - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(6); - sTradeData->state++; + sTradeAnim->state++; PlaySE(SE_M_SAND_ATTACK); } break; - case 51: - if (sTradeData->bg2Zoom < 0x400) + case STATE_GBA_ZOOM_IN: + if (sTradeAnim->bg2Zoom < 0x400) { - sTradeData->bg2Zoom += 0x34; + sTradeAnim->bg2Zoom += 0x34; } else { - sTradeData->bg2Zoom = 0x400; - sTradeData->state++; + sTradeAnim->bg2Zoom = 0x400; + sTradeAnim->state++; } - sTradeData->sXY = 0x8000 / sTradeData->bg2Zoom; + sTradeAnim->sXY = 0x8000 / sTradeAnim->bg2Zoom; break; - case 52: + case STATE_FADE_OUT_TO_NEW_MON: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = 60; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_NEW_MON; break; - case 60: + case STATE_WAIT_FADE_OUT_TO_NEW_MON: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(5); SetTradeSequenceBgGpuRegs(7); gPaletteFade.bufferTransferDisabled = TRUE; - sTradeData->state++; + sTradeAnim->state++; } break; - case 61: + case STATE_FADE_IN_TO_NEW_MON: gPaletteFade.bufferTransferDisabled = FALSE; BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 62: + case STATE_WAIT_FADE_IN_TO_NEW_MON: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) { - sTradeData->state++; + sTradeAnim->state++; } break; - case 63: - sTradeData->pokeballSpriteId2 = CreateSprite(&sTradePokeballSpriteTemplate, 120, -8, 0); - gSprites[sTradeData->pokeballSpriteId2].data[3] = 74; - gSprites[sTradeData->pokeballSpriteId2].callback = SpriteCB_TradePokeball_Inbound; - StartSpriteAnim(&gSprites[sTradeData->pokeballSpriteId2], 1); - StartSpriteAffineAnim(&gSprites[sTradeData->pokeballSpriteId2], 2); - BlendPalettes(1 << (16 + gSprites[sTradeData->pokeballSpriteId2].oam.paletteNum), 16, RGB_WHITEALPHA); - sTradeData->state++; - sTradeData->timer = 0; + case STATE_POKEBALL_ARRIVE: + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, -8, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].data[3] = 74; + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballArrive; + StartSpriteAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 1); + StartSpriteAffineAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 2); + BlendPalettes(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 16, RGB_WHITEALPHA); + sTradeAnim->state++; + sTradeAnim->timer = 0; break; - case 64: - BeginNormalPaletteFade(1 << (16 + gSprites[sTradeData->pokeballSpriteId2].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); - sTradeData->state++; + case STATE_FADE_POKEBALL_TO_NORMAL: + BeginNormalPaletteFade(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); + sTradeAnim->state++; break; - case 65: - if (gSprites[sTradeData->pokeballSpriteId2].callback == SpriteCallbackDummy) + case STATE_POKEBALL_ARRIVE_WAIT: + if (gSprites[sTradeAnim->bouncingPokeballSpriteId].callback == SpriteCallbackDummy) { - HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeData->tradeSpecies[1]], gMonSpritesGfxPtr->sprites[3], sTradeData->tradeSpecies[1], sTradeData->monPersonalities[1]); - sTradeData->state++; + HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeAnim->monSpecies[TRADE_PARTNER]], + gMonSpritesGfxPtr->sprites[B_POSITION_OPPONENT_RIGHT], + sTradeAnim->monSpecies[TRADE_PARTNER], + sTradeAnim->monPersonalities[TRADE_PARTNER]); + sTradeAnim->state++; } break; - case 66: - gSprites[sTradeData->pokePicSpriteIdxs[1]].x = 120; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y = gMonFrontPicCoords[sTradeData->tradeSpecies[1]].y_offset + 60; - gSprites[sTradeData->pokePicSpriteIdxs[1]].x2 = 0; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y2 = 0; - StartSpriteAnim(&gSprites[sTradeData->pokePicSpriteIdxs[1]], 0); - CreatePokeballSpriteToReleaseMon(sTradeData->pokePicSpriteIdxs[1], gSprites[sTradeData->pokePicSpriteIdxs[1]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF); - FreeSpriteOamMatrix(&gSprites[sTradeData->pokeballSpriteId2]); - DestroySprite(&gSprites[sTradeData->pokeballSpriteId2]); - sTradeData->state++; + case STATE_SHOW_NEW_MON: + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 120; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PARTNER]].y_offset + 60; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x2 = 0; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 = 0; + StartSpriteAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF); + FreeSpriteOamMatrix(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + DestroySprite(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + sTradeAnim->state++; break; - case 67: + case STATE_NEW_MON_MSG: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | @@ -1668,86 +1731,72 @@ static bool8 DoTradeAnim_Cable(void) DISPCNT_OBJ_ON); StringExpandPlaceholders(gStringVar4, gText_XSentOverY); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->state = 167; - sTradeData->timer = 0; + sTradeAnim->state = STATE_DELAY_FOR_MON_ANIM; + sTradeAnim->timer = 0; break; - // 167 and 267 are extra cases added in for animations - case 167: - if (++sTradeData->timer > 60) + case STATE_DELAY_FOR_MON_ANIM: + if (++sTradeAnim->timer > 60) { - if (sTradeData->tradeSpecies[1] != SPECIES_EGG) - { - PlayCry_Normal(sTradeData->tradeSpecies[1], 0); - } - sTradeData->state = 267; - sTradeData->timer = 0; + if (sTradeAnim->monSpecies[TRADE_PARTNER] != SPECIES_EGG) + PlayCry_Normal(sTradeAnim->monSpecies[TRADE_PARTNER], 0); + sTradeAnim->state = STATE_WAIT_FOR_MON_CRY; + sTradeAnim->timer = 0; } break; - case 267: + case STATE_WAIT_FOR_MON_CRY: if (IsCryFinished()) - { - sTradeData->state = 68; - } + sTradeAnim->state = STATE_TAKE_CARE_OF_MON; break; - case 68: - if (++sTradeData->timer == 10) - { + case STATE_TAKE_CARE_OF_MON: + if (++sTradeAnim->timer == 10) PlayFanfare(MUS_EVOLVED); - } - if (sTradeData->timer == 250) + + if (sTradeAnim->timer == 250) { - sTradeData->state++; + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_TakeGoodCareOfX); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->timer = 0; + sTradeAnim->timer = 0; } break; - case 69: - if (++sTradeData->timer == 60) - { - sTradeData->state++; - } + case STATE_AFTER_NEW_MON_DELAY: + if (++sTradeAnim->timer == 60) + sTradeAnim->state++; break; - case 70: + case STATE_CHECK_RIBBONS: CheckPartnersMonForRibbons(); - sTradeData->state++; + sTradeAnim->state++; break; - case 71: - if (sTradeData->isLinkTrade) - { + case STATE_END_LINK_TRADE: + if (sTradeAnim->isLinkTrade) return TRUE; - } else if (JOY_NEW(A_BUTTON)) - { - sTradeData->state++; - } + sTradeAnim->state++; break; - case 72: // Only if in-game trade + case STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution TradeMons(gSpecialVar_0x8005, 0); - gCB2_AfterEvolution = CB2_RunTradeAnim_InGameTrade; - evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[0]], EVO_MODE_TRADE, ITEM_NONE); + gCB2_AfterEvolution = CB2_InGameTrade; + evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE); if (evoTarget != SPECIES_NONE) - { - TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[0]], evoTarget, sTradeData->pokePicSpriteIdxs[1], gSelectedTradeMonPositions[0]); - } - sTradeData->state++; + TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[1], gSelectedTradeMonPositions[TRADE_PLAYER]); + sTradeAnim->state++; break; - case 73: + case STATE_FADE_OUT_END: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 74: + case STATE_WAIT_FADE_OUT_END: if (!gPaletteFade.active) { - PlayNewMapMusic(sTradeData->cachedMapMusic); - if (sTradeData) + PlayNewMapMusic(sTradeAnim->cachedMapMusic); + if (sTradeAnim) { FreeAllWindowBuffers(); Free(GetBgTilemapBuffer(3)); Free(GetBgTilemapBuffer(1)); Free(GetBgTilemapBuffer(0)); FreeMonSpritesGfx(); - FREE_AND_SET_NULL(sTradeData); + FREE_AND_SET_NULL(sTradeAnim); } SetMainCallback2(CB2_ReturnToField); BufferInGameTradeMonName(); @@ -1758,430 +1807,423 @@ static bool8 DoTradeAnim_Cable(void) return FALSE; } +// Task data for Task_AnimateWirelessSignal +#define tIdx data[0] +#define tCounter data[1] +#define tSignalComingBack data[2] + static bool8 DoTradeAnim_Wireless(void) { u16 evoTarget; - switch (sTradeData->state) + switch (sTradeAnim->state) { - case 0: - gSprites[sTradeData->pokePicSpriteIdxs[0]].invisible = FALSE; - gSprites[sTradeData->pokePicSpriteIdxs[0]].x2 = -180; - gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 = gMonFrontPicCoords[sTradeData->tradeSpecies[0]].y_offset; - sTradeData->state++; - sTradeData->cachedMapMusic = GetCurrentMapMusic(); + case STATE_START: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 = -180; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PLAYER]].y_offset; + sTradeAnim->state++; + sTradeAnim->cachedMapMusic = GetCurrentMapMusic(); PlayNewMapMusic(MUS_EVOLUTION); break; - case 1: - if (sTradeData->bg2hofs > 0) + case STATE_MON_SLIDE_IN: + if (sTradeAnim->bg2hofs > 0) { - gSprites[sTradeData->pokePicSpriteIdxs[0]].x2 += 3; - sTradeData->bg2hofs -= 3; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 += 3; + sTradeAnim->bg2hofs -= 3; } else { - gSprites[sTradeData->pokePicSpriteIdxs[0]].x2 = 0; - sTradeData->bg2hofs = 0; - sTradeData->state = 10; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 = 0; + sTradeAnim->bg2hofs = 0; + sTradeAnim->state = STATE_SEND_MSG; } break; - case 10: + case STATE_SEND_MSG: StringExpandPlaceholders(gStringVar4, gText_XWillBeSentToY); DrawTextOnTradeWindow(0, gStringVar4, 0); - if (sTradeData->tradeSpecies[0] != SPECIES_EGG) - { - PlayCry_Normal(sTradeData->tradeSpecies[0], 0); - } + if (sTradeAnim->monSpecies[TRADE_PLAYER] != SPECIES_EGG) + PlayCry_Normal(sTradeAnim->monSpecies[TRADE_PLAYER], 0); - sTradeData->state = 11; - sTradeData->timer = 0; + sTradeAnim->state = STATE_BYE_BYE; + sTradeAnim->timer = 0; break; - case 11: - if (++sTradeData->timer == 80) + case STATE_BYE_BYE: + if (++sTradeAnim->timer == 80) { - sTradeData->pokeballSpriteId = CreateTradePokeballSprite(sTradeData->pokePicSpriteIdxs[0], gSprites[sTradeData->pokePicSpriteIdxs[0]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); - sTradeData->state++; + sTradeAnim->releasePokeballSpriteId = CreateTradePokeballSprite(sTradeAnim->monSpriteIds[TRADE_PLAYER], gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_ByeByeVar1); DrawTextOnTradeWindow(0, gStringVar4, 0); } break; - case 12: - if (gSprites[sTradeData->pokeballSpriteId].callback == SpriteCallbackDummy) + case STATE_POKEBALL_DEPART: + if (gSprites[sTradeAnim->releasePokeballSpriteId].callback == SpriteCallbackDummy) { - sTradeData->pokeballSpriteId2 = CreateSprite(&sTradePokeballSpriteTemplate, 120, 32, 0); - gSprites[sTradeData->pokeballSpriteId2].callback = SpriteCB_TradePokeball_Outbound; - DestroySprite(&gSprites[sTradeData->pokeballSpriteId]); - sTradeData->state++; + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, 32, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballDepart; + DestroySprite(&gSprites[sTradeAnim->releasePokeballSpriteId]); + sTradeAnim->state++; } break; - case 13: + case STATE_POKEBALL_DEPART_WAIT: // The game waits here for the sprite to finish its animation sequence. break; - case 14: + case STATE_FADE_OUT_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = 20; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_GBA_SEND; break; - case 20: + case STATE_WAIT_FADE_OUT_TO_GBA_SEND: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(4); FillWindowPixelBuffer(0, PIXEL_FILL(15)); CopyWindowToVram(0, COPYWIN_FULL); - sTradeData->state++; + sTradeAnim->state++; } break; - case 21: + case STATE_FADE_IN_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 22: + case STATE_WAIT_FADE_IN_TO_GBA_SEND: if (!gPaletteFade.active) - { - sTradeData->state = 23; - } + sTradeAnim->state = STATE_GBA_ZOOM_OUT; break; - case 23: - if (sTradeData->bg2Zoom > 0x100) + case STATE_GBA_ZOOM_OUT: + if (sTradeAnim->bg2Zoom > 0x100) { - sTradeData->bg2Zoom -= 0x34; + sTradeAnim->bg2Zoom -= 0x34; } else { SetTradeSequenceBgGpuRegs(1); - sTradeData->bg2Zoom = 0x80; - sTradeData->state = 124; - sTradeData->timer = 0; + sTradeAnim->bg2Zoom = 0x80; + sTradeAnim->state = STATE_GBA_FLASH_SEND_WIRELESS; + sTradeAnim->timer = 0; } - sTradeData->sXY = 0x8000 / sTradeData->bg2Zoom; + sTradeAnim->sXY = 0x8000 / sTradeAnim->bg2Zoom; break; - case 124: - if (++sTradeData->timer > 20) + case STATE_GBA_FLASH_SEND_WIRELESS: + if (++sTradeAnim->timer > 20) { SetTradeSequenceBgGpuRegs(3); - sTradeData->gbaScreenSpriteId = CreateSprite(&sTradeGBAScreenSpriteTemplate2, 120, 80, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Short, 120, 80, 0); + sTradeAnim->state++; } break; - case 125: - if (gSprites[sTradeData->gbaScreenSpriteId].animEnded) + case STATE_GBA_STOP_FLASH_SEND_WIRELESS: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT1_OBJ | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG2); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 4)); + + // Start wireless signal effect CreateTask(Task_AnimateWirelessSignal, 5); - sTradeData->state++; + sTradeAnim->state++; } break; - case 126: + case STATE_WAIT_WIRELESS_SIGNAL_SEND: if (!FuncIsActiveTask(Task_AnimateWirelessSignal)) - { - sTradeData->state = 26; - } + sTradeAnim->state = STATE_PAN_AWAY_GBA; break; - case 26: - if (--sTradeData->bg1vofs == 316) - { - sTradeData->state++; - } + case STATE_PAN_AWAY_GBA: + if (--sTradeAnim->bg1vofs == 316) + sTradeAnim->state++; break; - case 27: - sTradeData->tradeGlow1SpriteId = CreateSprite(&sTradeGlow1SpriteTemplate, 120, 80, 3); - gSprites[sTradeData->tradeGlow1SpriteId].callback = SpriteCB_TradeGlowWireless; - sTradeData->gbaScreenSpriteId = CreateSprite(&sGlowBallSpriteTemplate, 120, 80, 0); - StartSpriteAnim(&gSprites[sTradeData->gbaScreenSpriteId], 1); - sTradeData->state++; + case STATE_CREATE_LINK_MON_LEAVING: + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 120, 80, 3); + gSprites[sTradeAnim->connectionSpriteId1].callback = SpriteCB_LinkMonGlowWireless; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 120, 80, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], ANIM_LINKMON_SMALL); + sTradeAnim->state++; break; - case 28: - if ((sTradeData->bg1vofs -= 3) == 166) - { - sTradeData->state = 200; - } + case STATE_LINK_MON_TRAVEL_OUT: + if ((sTradeAnim->bg1vofs -= 3) == 166) + sTradeAnim->state = STATE_LINK_MON_TRAVEL_OFFSCREEN; + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); break; - case 200: - gSprites[sTradeData->tradeGlow1SpriteId].y -= 2; - gSprites[sTradeData->gbaScreenSpriteId].y -= 2; - if (gSprites[sTradeData->tradeGlow1SpriteId].y < -8) - { - sTradeData->state = 29; - } + case STATE_LINK_MON_TRAVEL_OFFSCREEN: + gSprites[sTradeAnim->connectionSpriteId1].y -= 2; + gSprites[sTradeAnim->connectionSpriteId2].y -= 2; + if (gSprites[sTradeAnim->connectionSpriteId1].y < -8) + sTradeAnim->state = STATE_FADE_OUT_TO_CROSSING; break; - case 29: + case STATE_FADE_OUT_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state = 30; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_CROSSING; break; - case 30: + case STATE_WAIT_FADE_OUT_TO_CROSSING: if (!gPaletteFade.active) { - DestroySprite(&gSprites[sTradeData->tradeGlow1SpriteId]); - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(2); - sTradeData->state++; + sTradeAnim->state++; } break; - case 31: + case STATE_FADE_IN_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->tradeGlow1SpriteId = CreateSprite(&sGlowBallSpriteTemplate, 111, 170, 0); - sTradeData->gbaScreenSpriteId = CreateSprite(&sGlowBallSpriteTemplate, 129, -10, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 111, 170, 0); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 129, -10, 0); + sTradeAnim->state++; break; - case 32: + case STATE_WAIT_FADE_IN_TO_CROSSING: if (!gPaletteFade.active) { PlaySE(SE_WARP_OUT); - sTradeData->state++; + sTradeAnim->state++; } - gSprites[sTradeData->tradeGlow1SpriteId].y2 -= 3; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 3; + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; break; - case 33: - gSprites[sTradeData->tradeGlow1SpriteId].y2 -= 3; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 3; - if (gSprites[sTradeData->tradeGlow1SpriteId].y2 <= -90) + case STATE_CROSSING_LINK_MONS_ENTER: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -90) { - gSprites[sTradeData->tradeGlow1SpriteId].data[1] = 1; - gSprites[sTradeData->gbaScreenSpriteId].data[1] = 1; - sTradeData->state++; + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 1; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 1; + sTradeAnim->state++; CreateTask(Task_OpenCenterWhiteColumn, 5); } break; - case 34: + case STATE_CROSSING_BLEND_WHITE_1: BlendPalettes(0x8, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case 35: + case STATE_CROSSING_BLEND_WHITE_2: BlendPalettes(0x8, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case 36: + case STATE_CROSSING_BLEND_WHITE_3: BlendPalettes(0x8, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case 37: - if (!IsPokeSpriteNotFlipped(sTradeData->tradeSpecies[0])) + case STATE_CROSSING_CREATE_MON_PICS: + if (!IsMonSpriteNotFlipped(sTradeAnim->monSpecies[TRADE_PLAYER])) { - gSprites[sTradeData->pokePicSpriteIdxs[0]].affineAnims = sSpriteAffineAnimTable_PlayerPokePicAlt; - gSprites[sTradeData->pokePicSpriteIdxs[0]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; - CalcCenterToCornerVec(&gSprites[sTradeData->pokePicSpriteIdxs[0]], 0, 3, 3); - StartSpriteAffineAnim(&gSprites[sTradeData->pokePicSpriteIdxs[0]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].affineAnims = sAffineAnims_CrossingMonPics; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + CalcCenterToCornerVec(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], SPRITE_SHAPE(64x64), SPRITE_SIZE(64x64), ST_OAM_AFFINE_DOUBLE); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } else { - StartSpriteAffineAnim(&gSprites[sTradeData->pokePicSpriteIdxs[0]], 0); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } - StartSpriteAffineAnim(&gSprites[sTradeData->pokePicSpriteIdxs[1]], 0); - gSprites[sTradeData->pokePicSpriteIdxs[0]].x = 40; - gSprites[sTradeData->pokePicSpriteIdxs[1]].x = 200; - gSprites[sTradeData->pokePicSpriteIdxs[0]].y = 192; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y = -32; - gSprites[sTradeData->pokePicSpriteIdxs[0]].invisible = FALSE; - gSprites[sTradeData->pokePicSpriteIdxs[1]].invisible = FALSE; - sTradeData->state++; + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x = 40; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 200; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y = 192; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = -32; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = FALSE; + sTradeAnim->state++; break; - case 38: - gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 -= 3; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y2 += 3; - if (gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 < -160 && gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 >= -163) + case STATE_CROSSING_MON_PICS_MOVE: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 -= 3; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 += 3; + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -DISPLAY_HEIGHT + && gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 >= -DISPLAY_HEIGHT - 3) { PlaySE(SE_WARP_IN); } - if (gSprites[sTradeData->pokePicSpriteIdxs[0]].y2 < -222) + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -222) { - gSprites[sTradeData->tradeGlow1SpriteId].data[1] = 0; - gSprites[sTradeData->gbaScreenSpriteId].data[1] = 0; - sTradeData->state++; - gSprites[sTradeData->pokePicSpriteIdxs[0]].invisible = TRUE; - gSprites[sTradeData->pokePicSpriteIdxs[1]].invisible = TRUE; + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 0; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 0; + sTradeAnim->state++; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = TRUE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = TRUE; CreateTask(Task_CloseCenterWhiteColumn, 5); } break; - case 39: - gSprites[sTradeData->tradeGlow1SpriteId].y2 -= 3; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 3; - if (gSprites[sTradeData->tradeGlow1SpriteId].y2 <= -222) + case STATE_CROSSING_LINK_MONS_EXIT: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -222) { BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state++; - DestroySprite(&gSprites[sTradeData->tradeGlow1SpriteId]); - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + sTradeAnim->state++; + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); } break; - case 40: + case STATE_CREATE_LINK_MON_ARRIVING: if (!gPaletteFade.active) { - sTradeData->state++; + sTradeAnim->state++; SetTradeSequenceBgGpuRegs(1); - sTradeData->bg1vofs = 166; + sTradeAnim->bg1vofs = 166; SetTradeSequenceBgGpuRegs(3); - sTradeData->bg2vofs = 412; - sTradeData->tradeGlow1SpriteId = CreateSprite(&sTradeGlow1SpriteTemplate, 120, -20, 3); - gSprites[sTradeData->tradeGlow1SpriteId].callback = SpriteCB_TradeGlowWireless; - sTradeData->gbaScreenSpriteId = CreateSprite(&sGlowBallSpriteTemplate, 120, -20, 0); - StartSpriteAnim(&gSprites[sTradeData->gbaScreenSpriteId], 1); + sTradeAnim->bg2vofs = 412; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 120, -20, 3); + gSprites[sTradeAnim->connectionSpriteId1].callback = SpriteCB_LinkMonGlowWireless; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 120, -20, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], 1); } break; - case 41: + case STATE_FADE_OUT_TO_GBA_RECV: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 42: + case STATE_WAIT_FADE_OUT_TO_GBA_RECV: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) + sTradeAnim->state++; + break; + case STATE_LINK_MON_TRAVEL_IN: + gSprites[sTradeAnim->connectionSpriteId1].y2 += 4; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 4; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 + gSprites[sTradeAnim->connectionSpriteId1].y == 64) { - sTradeData->state++; + sTradeAnim->state = STATE_PAN_TO_GBA_WIRELESS; + sTradeAnim->timer = 0; } break; - case 43: - gSprites[sTradeData->tradeGlow1SpriteId].y2 += 4; - gSprites[sTradeData->gbaScreenSpriteId].y2 += 4; - if (gSprites[sTradeData->tradeGlow1SpriteId].y2 + gSprites[sTradeData->tradeGlow1SpriteId].y == 64) - { - sTradeData->state = 144; - sTradeData->timer = 0; - } - break; - case 144: + case STATE_PAN_TO_GBA_WIRELESS: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); - sTradeData->bg1vofs += 3; - sTradeData->bg2vofs += 3; - if (++sTradeData->timer == 10) + sTradeAnim->bg1vofs += 3; + sTradeAnim->bg2vofs += 3; + if (++sTradeAnim->timer == 10) { u8 taskId = CreateTask(Task_AnimateWirelessSignal, 5); - gTasks[taskId].data[2] = TRUE; + gTasks[taskId].tSignalComingBack = TRUE; } - if (sTradeData->bg1vofs > 316) + if (sTradeAnim->bg1vofs > 316) { - sTradeData->bg1vofs = 316; - sTradeData->state++; + sTradeAnim->bg1vofs = 316; + sTradeAnim->state++; } break; - case 145: - DestroySprite(&gSprites[sTradeData->tradeGlow1SpriteId]); - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); - sTradeData->state++; - sTradeData->timer = 0; + case STATE_DESTROY_LINK_MON_WIRELESS: + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); + sTradeAnim->state++; + sTradeAnim->timer = 0; break; - case 146: + case STATE_WAIT_WIRELESS_SIGNAL_RECV: if (!FuncIsActiveTask(Task_AnimateWirelessSignal)) { - sTradeData->state = 46; - sTradeData->timer = 0; + sTradeAnim->state = STATE_LINK_MON_ARRIVED_DELAY; + sTradeAnim->timer = 0; } break; - case 46: - if (++sTradeData->timer == 10) + case STATE_LINK_MON_ARRIVED_DELAY: + if (++sTradeAnim->timer == 10) + sTradeAnim->state++; + break; + case STATE_MOVE_GBA_TO_CENTER: + if (++sTradeAnim->bg1vofs > 348) { - sTradeData->state++; + sTradeAnim->bg1vofs = 348; + sTradeAnim->state++; } break; - case 47: - if (++sTradeData->bg1vofs > 348) - { - sTradeData->bg1vofs = 348; - sTradeData->state++; - } + case STATE_GBA_FLASH_RECV: + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); + sTradeAnim->state = STATE_GBA_STOP_FLASH_RECV; break; - case 48: - sTradeData->gbaScreenSpriteId = CreateSprite(&sTradeGBAScreenSpriteTemplate1, 120, 80, 0); - sTradeData->state = 50; - break; - case 50: - if (gSprites[sTradeData->gbaScreenSpriteId].animEnded) + case STATE_GBA_STOP_FLASH_RECV: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - DestroySprite(&gSprites[sTradeData->gbaScreenSpriteId]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(6); - sTradeData->state++; + sTradeAnim->state++; PlaySE(SE_M_SAND_ATTACK); } break; - case 51: - if (sTradeData->bg2Zoom < 0x400) + case STATE_GBA_ZOOM_IN: + if (sTradeAnim->bg2Zoom < 0x400) { - sTradeData->bg2Zoom += 0x34; + sTradeAnim->bg2Zoom += 0x34; } else { - sTradeData->bg2Zoom = 0x400; - sTradeData->state++; + sTradeAnim->bg2Zoom = 0x400; + sTradeAnim->state++; } - sTradeData->sXY = 0x8000 / sTradeData->bg2Zoom; + sTradeAnim->sXY = 0x8000 / sTradeAnim->bg2Zoom; break; - case 52: + case STATE_FADE_OUT_TO_NEW_MON: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = 60; + sTradeAnim->state = 60; break; - - case 60: + case STATE_WAIT_FADE_OUT_TO_NEW_MON: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(5); SetTradeSequenceBgGpuRegs(7); gPaletteFade.bufferTransferDisabled = TRUE; - sTradeData->state++; + sTradeAnim->state++; } break; - case 61: + case STATE_FADE_IN_TO_NEW_MON: gPaletteFade.bufferTransferDisabled = FALSE; BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 62: + case STATE_WAIT_FADE_IN_TO_NEW_MON: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) + sTradeAnim->state++; + break; + case STATE_POKEBALL_ARRIVE: + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, -8, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].data[3] = 74; + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballArrive; + StartSpriteAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 1); + StartSpriteAffineAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 2); + BlendPalettes(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 16, RGB_WHITEALPHA); + sTradeAnim->state++; + sTradeAnim->timer = 0; + break; + case STATE_FADE_POKEBALL_TO_NORMAL: + BeginNormalPaletteFade(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); + sTradeAnim->state++; + break; + case STATE_POKEBALL_ARRIVE_WAIT: + if (gSprites[sTradeAnim->bouncingPokeballSpriteId].callback == SpriteCallbackDummy) { - sTradeData->state++; + HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeAnim->monSpecies[TRADE_PARTNER]], + gMonSpritesGfxPtr->sprites[B_POSITION_OPPONENT_RIGHT], + sTradeAnim->monSpecies[TRADE_PARTNER], + sTradeAnim->monPersonalities[TRADE_PARTNER]); + sTradeAnim->state++; } break; - case 63: - sTradeData->pokeballSpriteId2 = CreateSprite(&sTradePokeballSpriteTemplate, 120, -8, 0); - gSprites[sTradeData->pokeballSpriteId2].data[3] = 74; - gSprites[sTradeData->pokeballSpriteId2].callback = SpriteCB_TradePokeball_Inbound; - StartSpriteAnim(&gSprites[sTradeData->pokeballSpriteId2], 1); - StartSpriteAffineAnim(&gSprites[sTradeData->pokeballSpriteId2], 2); - BlendPalettes(1 << (16 + gSprites[sTradeData->pokeballSpriteId2].oam.paletteNum), 16, RGB_WHITEALPHA); - sTradeData->state++; - sTradeData->timer = 0; + case STATE_SHOW_NEW_MON: + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 120; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PARTNER]].y_offset + 60; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x2 = 0; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 = 0; + StartSpriteAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF); + FreeSpriteOamMatrix(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + DestroySprite(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + sTradeAnim->state++; break; - case 64: - BeginNormalPaletteFade(1 << (16 + gSprites[sTradeData->pokeballSpriteId2].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); - sTradeData->state++; - break; - case 65: - if (gSprites[sTradeData->pokeballSpriteId2].callback == SpriteCallbackDummy) - { - HandleLoadSpecialPokePic(&gMonFrontPicTable[sTradeData->tradeSpecies[1]], gMonSpritesGfxPtr->sprites[3], sTradeData->tradeSpecies[1], sTradeData->monPersonalities[1]); - sTradeData->state++; - } - break; - case 66: - gSprites[sTradeData->pokePicSpriteIdxs[1]].x = 120; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y = gMonFrontPicCoords[sTradeData->tradeSpecies[1]].y_offset + 60; - gSprites[sTradeData->pokePicSpriteIdxs[1]].x2 = 0; - gSprites[sTradeData->pokePicSpriteIdxs[1]].y2 = 0; - StartSpriteAnim(&gSprites[sTradeData->pokePicSpriteIdxs[1]], 0); - CreatePokeballSpriteToReleaseMon(sTradeData->pokePicSpriteIdxs[1], gSprites[sTradeData->pokePicSpriteIdxs[1]].oam.paletteNum, 120, 84, 2, 1, 20, 0xFFFFF); - FreeSpriteOamMatrix(&gSprites[sTradeData->pokeballSpriteId2]); - DestroySprite(&gSprites[sTradeData->pokeballSpriteId2]); - sTradeData->state++; - break; - case 67: + case STATE_NEW_MON_MSG: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | @@ -2189,86 +2231,72 @@ static bool8 DoTradeAnim_Wireless(void) DISPCNT_OBJ_ON); StringExpandPlaceholders(gStringVar4, gText_XSentOverY); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->state = 167; - sTradeData->timer = 0; + sTradeAnim->state = STATE_DELAY_FOR_MON_ANIM; + sTradeAnim->timer = 0; break; - // 167 and 267 are extra cases added in for animations - case 167: - if (++sTradeData->timer > 60) + case STATE_DELAY_FOR_MON_ANIM: + if (++sTradeAnim->timer > 60) { - if (sTradeData->tradeSpecies[1] != SPECIES_EGG) - { - PlayCry_Normal(sTradeData->tradeSpecies[1], 0); - } - sTradeData->state = 267; - sTradeData->timer = 0; + if (sTradeAnim->monSpecies[TRADE_PARTNER] != SPECIES_EGG) + PlayCry_Normal(sTradeAnim->monSpecies[TRADE_PARTNER], 0); + sTradeAnim->state = STATE_WAIT_FOR_MON_CRY; + sTradeAnim->timer = 0; } break; - case 267: + case STATE_WAIT_FOR_MON_CRY: if (IsCryFinished()) - { - sTradeData->state = 68; - } + sTradeAnim->state = STATE_TAKE_CARE_OF_MON; break; - case 68: - if (++sTradeData->timer == 10) - { + case STATE_TAKE_CARE_OF_MON: + if (++sTradeAnim->timer == 10) PlayFanfare(MUS_EVOLVED); - } - if (sTradeData->timer == 250) + + if (sTradeAnim->timer == 250) { - sTradeData->state++; + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_TakeGoodCareOfX); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->timer = 0; + sTradeAnim->timer = 0; } break; - case 69: - if (++sTradeData->timer == 60) - { - sTradeData->state++; - } + case STATE_AFTER_NEW_MON_DELAY: + if (++sTradeAnim->timer == 60) + sTradeAnim->state++; break; - case 70: + case STATE_CHECK_RIBBONS: CheckPartnersMonForRibbons(); - sTradeData->state++; + sTradeAnim->state++; break; - case 71: - if (sTradeData->isLinkTrade) - { + case STATE_END_LINK_TRADE: + if (sTradeAnim->isLinkTrade) return TRUE; - } else if (JOY_NEW(A_BUTTON)) - { - sTradeData->state++; - } + sTradeAnim->state++; break; - case 72: // Only if in-game trade + case STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution TradeMons(gSpecialVar_0x8005, 0); - gCB2_AfterEvolution = CB2_RunTradeAnim_InGameTrade; - evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[0]], EVO_MODE_TRADE, ITEM_NONE); + gCB2_AfterEvolution = CB2_InGameTrade; + evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE); if (evoTarget != SPECIES_NONE) - { - TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[0]], evoTarget, sTradeData->pokePicSpriteIdxs[1], gSelectedTradeMonPositions[0]); - } - sTradeData->state++; + TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + sTradeAnim->state++; break; - case 73: + case STATE_FADE_OUT_END: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case 74: + case STATE_WAIT_FADE_OUT_END: if (!gPaletteFade.active) { - PlayNewMapMusic(sTradeData->cachedMapMusic); - if (sTradeData) + PlayNewMapMusic(sTradeAnim->cachedMapMusic); + if (sTradeAnim) { FreeAllWindowBuffers(); Free(GetBgTilemapBuffer(3)); Free(GetBgTilemapBuffer(1)); Free(GetBgTilemapBuffer(0)); FreeMonSpritesGfx(); - FREE_AND_SET_NULL(sTradeData); + FREE_AND_SET_NULL(sTradeAnim); } SetMainCallback2(CB2_ReturnToField); BufferInGameTradeMonName(); @@ -2279,7 +2307,9 @@ static bool8 DoTradeAnim_Wireless(void) return FALSE; } -static void CB2_TryEvolveAfterTrade(void) +// Try to evolve a Pokémon received in a link trade +// In-game trades resolve evolution during the trade sequence, in STATE_TRY_EVOLUTION +static void CB2_TryLinkTradeEvolution(void) { u16 evoSpecies; switch (gMain.state) @@ -2289,13 +2319,13 @@ static void CB2_TryEvolveAfterTrade(void) gSoftResetDisabled = TRUE; break; case 4: - gCB2_AfterEvolution = CB2_HandleTradeEnded; - evoSpecies = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[0]], EVO_MODE_TRADE, 0); + gCB2_AfterEvolution = CB2_SaveAndEndTrade; + evoSpecies = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, 0); if (evoSpecies != SPECIES_NONE) - TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[0]], evoSpecies, sTradeData->pokePicSpriteIdxs[1], gSelectedTradeMonPositions[0]); + TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoSpecies, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); else - SetMainCallback2(CB2_HandleTradeEnded); - gSelectedTradeMonPositions[0] = 0xFF; + SetMainCallback2(CB2_SaveAndEndTrade); + gSelectedTradeMonPositions[TRADE_PLAYER] = 0xFF; break; } if (!HasLinkErrorOccurred()) @@ -2308,25 +2338,25 @@ static void CB2_TryEvolveAfterTrade(void) static void HandleLinkDataReceive(void) { u8 recvStatus; - GetMultiplayerIdOfLinkTrade(); + TradeGetMultiplayerId(); // no effect call, ret val ignored recvStatus = GetBlockReceivedStatus(); if (recvStatus & (1 << 0)) { - if (gBlockRecvBuffer[0][0] == 0xDCBA) - SetMainCallback2(CB2_TryEvolveAfterTrade); - if (gBlockRecvBuffer[0][0] == 0xABCD) - sTradeData->tradeStatus1 = 1; + if (gBlockRecvBuffer[0][0] == LINKCMD_CONFIRM_FINISH_TRADE) + SetMainCallback2(CB2_TryLinkTradeEvolution); + if (gBlockRecvBuffer[0][0] == LINKCMD_READY_FINISH_TRADE) + sTradeAnim->playerFinishStatus = STATUS_READY; ResetBlockReceivedFlag(0); } if (recvStatus & (1 << 1)) { - if (gBlockRecvBuffer[1][0] == 0xABCD) - sTradeData->tradeStatus2 = 1; + if (gBlockRecvBuffer[1][0] == LINKCMD_READY_FINISH_TRADE) + sTradeAnim->partnerFinishStatus = STATUS_READY; ResetBlockReceivedFlag(1); } } -static void SpriteCB_TradePokeball_Default(struct Sprite *sprite) +static void SpriteCB_BouncingPokeball(struct Sprite *sprite) { sprite->y += sprite->data[0] / 10; sprite->data[5] += sprite->data[1]; @@ -2347,39 +2377,36 @@ static void SpriteCB_TradePokeball_Default(struct Sprite *sprite) } } -static void SpriteCB_TradePokeball_Outbound(struct Sprite *sprite) +static void SpriteCB_BouncingPokeballDepart(struct Sprite *sprite) { sprite->y2 += sTradeBallVerticalVelocityTable[sprite->data[0]]; if (sprite->data[0] == 22) PlaySE(SE_BALL_BOUNCE_1); - sprite->data[0]++; - if (sprite->data[0] == 44) + if (++sprite->data[0] == 44) { PlaySE(SE_M_MEGA_KICK); - sprite->callback = SpriteCB_TradePokeball_Outbound2; + sprite->callback = SpriteCB_BouncingPokeballDepartEnd; sprite->data[0] = 0; BeginNormalPaletteFade(1 << (sprite->oam.paletteNum + 16), -1, 0, 16, RGB_WHITEALPHA); } } -static void SpriteCB_TradePokeball_Outbound2(struct Sprite *sprite) +static void SpriteCB_BouncingPokeballDepartEnd(struct Sprite *sprite) { if (sprite->data[1] == 20) StartSpriteAffineAnim(sprite, 1); - sprite->data[1]++; - if (sprite->data[1] > 20) + if (++sprite->data[1] > 20) { sprite->y2 -= sTradeBallVerticalVelocityTable[sprite->data[0]]; - sprite->data[0]++; - if (sprite->data[0] == 23) + if (++sprite->data[0] == 23) { DestroySprite(sprite); - sTradeData->state = 14; + sTradeAnim->state = 14; } } } -static void SpriteCB_TradePokeball_Inbound(struct Sprite *sprite) +static void SpriteCB_BouncingPokeballArrive(struct Sprite *sprite) { if (sprite->data[2] == 0) { @@ -2400,8 +2427,7 @@ static void SpriteCB_TradePokeball_Inbound(struct Sprite *sprite) if (sprite->data[0] == 107) PlaySE(SE_BALL_BOUNCE_4); sprite->y2 += sTradeBallVerticalVelocityTable[sprite->data[0]]; - sprite->data[0]++; - if (sprite->data[0] == 108) + if (++sprite->data[0] == 108) sprite->callback = SpriteCallbackDummy; } } @@ -2436,7 +2462,7 @@ static void CreateInGameTradePokemonInternal(u8 playerSlot, u8 inGameTradeIdx) u8 metLocation = METLOC_IN_GAME_TRADE; struct Pokemon * tradeMon = &gEnemyParty[0]; u8 mailNum; - CreateMon(tradeMon, inGameTrade->species, level, 32, TRUE, inGameTrade->personality, TRUE, inGameTrade->otId); + CreateMon(tradeMon, inGameTrade->species, level, USE_RANDOM_IVS, TRUE, inGameTrade->personality, TRUE, inGameTrade->otId); SetMonData(tradeMon, MON_DATA_HP_IV, &inGameTrade->ivs[0]); SetMonData(tradeMon, MON_DATA_ATK_IV, &inGameTrade->ivs[1]); SetMonData(tradeMon, MON_DATA_DEF_IV, &inGameTrade->ivs[2]); @@ -2499,16 +2525,16 @@ void CreateInGameTradePokemon(void) CreateInGameTradePokemonInternal(gSpecialVar_0x8005, gSpecialVar_0x8004); } -static void CB2_RunTradeAnim_LinkTrade(void) +static void CB2_UpdateLinkTrade(void) { if (DoTradeAnim() == TRUE) { - DestroySprite(&gSprites[sTradeData->pokePicSpriteIdxs[0]]); - FreeSpriteOamMatrix(&gSprites[sTradeData->pokePicSpriteIdxs[1]]); - TradeMons(gSelectedTradeMonPositions[0], gSelectedTradeMonPositions[1] % 6); - sTradeData->linkData[0] = 0xABCD; - sTradeData->scheduleLinkTransfer = 1; - SetMainCallback2(CB2_WaitAndAckTradeComplete); + DestroySprite(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]]); + FreeSpriteOamMatrix(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]]); + TradeMons(gSelectedTradeMonPositions[TRADE_PLAYER], gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE); + sTradeAnim->linkData[0] = LINKCMD_READY_FINISH_TRADE; + sTradeAnim->scheduleLinkTransfer = 1; + SetMainCallback2(CB2_WaitTradeComplete); } HandleLinkDataSend(); HandleLinkDataReceive(); @@ -2519,16 +2545,18 @@ static void CB2_RunTradeAnim_LinkTrade(void) UpdatePaletteFade(); } -static void CB2_WaitAndAckTradeComplete(void) +static void CB2_WaitTradeComplete(void) { - u8 mpId = GetMultiplayerIdOfLinkTrade(); + u8 mpId = TradeGetMultiplayerId(); HandleLinkDataReceive(); - if (mpId == 0 && sTradeData->tradeStatus1 == 1 && sTradeData->tradeStatus2 == 1) + if (mpId == 0 + && sTradeAnim->playerFinishStatus == STATUS_READY + && sTradeAnim->partnerFinishStatus == STATUS_READY) { - sTradeData->linkData[0] = 0xDCBA; - SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, 20); - sTradeData->tradeStatus1 = 2; - sTradeData->tradeStatus2 = 2; + sTradeAnim->linkData[0] = LINKCMD_CONFIRM_FINISH_TRADE; + SendBlock(BitmaskAllOtherLinkPlayers(), sTradeAnim->linkData, sizeof(sTradeAnim->linkData)); + sTradeAnim->playerFinishStatus = STATUS_CANCEL; + sTradeAnim->partnerFinishStatus = STATUS_CANCEL; } RunTasks(); AnimateSprites(); @@ -2536,7 +2564,7 @@ static void CB2_WaitAndAckTradeComplete(void) UpdatePaletteFade(); } -static void CB2_HandleTradeEnded(void) +static void CB2_SaveAndEndTrade(void) { switch (gMain.state) { @@ -2548,24 +2576,20 @@ static void CB2_HandleTradeEnded(void) case 1: SetLinkStandbyCallback(); gMain.state = 100; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 100: - if (++sTradeData->timer > 180) + if (++sTradeAnim->timer > 180) { gMain.state = 101; - sTradeData->timer = 0; + sTradeAnim->timer = 0; } if (IsLinkTaskFinished()) - { gMain.state = 2; - } break; case 101: if (IsLinkTaskFinished()) - { gMain.state = 2; - } break; case 2: gMain.state = 50; @@ -2575,11 +2599,11 @@ static void CB2_HandleTradeEnded(void) case 50: if (InUnionRoom()) { - SetQuestLogEvent(QL_EVENT_LINK_TRADED_UNION, sTradeData->monSpecies); + SetQuestLogEvent(QL_EVENT_LINK_TRADED_UNION, sTradeAnim->questLogSpecies); } else { - SetQuestLogEvent(QL_EVENT_LINK_TRADED, sTradeData->monSpecies); + SetQuestLogEvent(QL_EVENT_LINK_TRADED, sTradeAnim->questLogSpecies); IncrementGameStat(GAME_STAT_POKEMON_TRADES); } if (gWirelessCommType) @@ -2587,13 +2611,11 @@ static void CB2_HandleTradeEnded(void) SetContinueGameWarpStatusToDynamicWarp(); LinkFullSave_Init(); gMain.state++; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 51: - if (++sTradeData->timer == 5) - { + if (++sTradeAnim->timer == 5) gMain.state++; - } break; case 52: if (LinkFullSave_WriteSector()) @@ -2603,38 +2625,35 @@ static void CB2_HandleTradeEnded(void) } else { - sTradeData->timer = 0; + // Save isn't finished, delay again + sTradeAnim->timer = 0; gMain.state = 51; } break; case 4: LinkFullSave_ReplaceLastSector(); gMain.state = 40; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 40: - if (++sTradeData->timer > 50) + if (++sTradeAnim->timer > 50) { if (GetMultiplayerId() == 0) - { - sTradeData->timer = Random() % 30; - } + sTradeAnim->timer = Random() % 30; else - { - sTradeData->timer = 0; - } + sTradeAnim->timer = 0; gMain.state = 41; } break; case 41: - if (sTradeData->timer == 0) + if (sTradeAnim->timer == 0) { SetLinkStandbyCallback(); gMain.state = 42; } else { - sTradeData->timer--; + sTradeAnim->timer--; } break; case 42: @@ -2645,7 +2664,7 @@ static void CB2_HandleTradeEnded(void) } break; case 5: - if (++sTradeData->timer > 60) + if (++sTradeAnim->timer > 60) { gMain.state++; SetLinkStandbyCallback(); @@ -2669,13 +2688,9 @@ static void CB2_HandleTradeEnded(void) if (IsBGMStopped() == TRUE) { if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu) - { SetLinkStandbyCallback(); - } else - { SetCloseLinkCallback(); - } gMain.state++; } break; @@ -2685,13 +2700,13 @@ static void CB2_HandleTradeEnded(void) if (IsLinkRfuTaskFinished()) { gSoftResetDisabled = FALSE; - SetMainCallback2(LinkTrade_TearDownAssets); + SetMainCallback2(CB2_FreeTradeAnim); } } else if (!gReceivedRemoteLinkPlayers) { gSoftResetDisabled = FALSE; - SetMainCallback2(LinkTrade_TearDownAssets); + SetMainCallback2(CB2_FreeTradeAnim); } break; } @@ -2704,7 +2719,7 @@ static void CB2_HandleTradeEnded(void) UpdatePaletteFade(); } -static void LinkTrade_TearDownAssets(void) +static void CB2_FreeTradeAnim(void) { if (!gPaletteFade.active) { @@ -2713,7 +2728,7 @@ static void LinkTrade_TearDownAssets(void) Free(GetBgTilemapBuffer(1)); Free(GetBgTilemapBuffer(0)); FreeMonSpritesGfx(); - FREE_AND_SET_NULL(sTradeData); + FREE_AND_SET_NULL(sTradeAnim); if (gWirelessCommType != 0) DestroyWirelessStatusIndicatorSprite(); SetMainCallback2(gMain.savedCallback); @@ -2727,16 +2742,16 @@ static void LinkTrade_TearDownAssets(void) void DoInGameTradeScene(void) { LockPlayerFieldControls(); - CreateTask(Task_WaitFadeAndStartInGameTradeAnim, 10); + CreateTask(Task_InGameTrade, 10); BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); HelpSystem_Disable(); } -static void Task_WaitFadeAndStartInGameTradeAnim(u8 taskId) +static void Task_InGameTrade(u8 taskId) { if (!gPaletteFade.active) { - SetMainCallback2(CB2_InitTradeAnim_InGameTrade); + SetMainCallback2(CB2_InitInGameTrade); gFieldCallback = FieldCB_ContinueScriptHandleMusic; DestroyTask(taskId); } @@ -2744,13 +2759,12 @@ static void Task_WaitFadeAndStartInGameTradeAnim(u8 taskId) static void CheckPartnersMonForRibbons(void) { - u8 nRibbons = 0; + u8 numRibbons = 0; u8 i; - for (i = 0; i < 12; i++) - { - nRibbons += GetMonData(&gEnemyParty[gSelectedTradeMonPositions[1] % 6], MON_DATA_CHAMPION_RIBBON + i); - } - if (nRibbons != 0) + for (i = 0; i < (MON_DATA_UNUSED_RIBBONS - MON_DATA_CHAMPION_RIBBON); i++) + numRibbons += GetMonData(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], MON_DATA_CHAMPION_RIBBON + i); + + if (numRibbons != 0) FlagSet(FLAG_SYS_RIBBON_GET); } @@ -2762,53 +2776,62 @@ void LoadTradeAnimGfx(void) void DrawTextOnTradeWindow(u8 windowId, const u8 *str, s8 speed) { FillWindowPixelBuffer(windowId, PIXEL_FILL(15)); - sTradeData->textColor[0] = 15; - sTradeData->textColor[1] = 1; - sTradeData->textColor[2] = 6; - AddTextPrinterParameterized4(windowId, FONT_NORMAL, 0, 2, 0, 2, sTradeData->textColor, speed, str); + sTradeAnim->textColor[0] = 15; + sTradeAnim->textColor[1] = 1; + sTradeAnim->textColor[2] = 6; + AddTextPrinterParameterized4(windowId, FONT_NORMAL, 0, 2, 0, 2, sTradeAnim->textColor, speed, str); CopyWindowToVram(windowId, COPYWIN_FULL); } static void Task_AnimateWirelessSignal(u8 taskId) { s16 *data = gTasks[taskId].data; - u16 r2 = 16 * sWirelessSignalAnimParams[data[0]][0]; - if (data[2] == 0) + u16 paletteIdx = 16 * sWirelessSignalAnimParams[tIdx][0]; + + if (!tSignalComingBack) { - if (r2 == 0x100) + if (paletteIdx == 0x100) LoadPalette(sWirelessSignalAnimPals_Off, 0x30, 0x20); else - LoadPalette(&sWirelessSignalAnimPals_Outbound[r2], 0x30, 0x20); + LoadPalette(&sWirelessSignalAnimPals_Outbound[paletteIdx], 0x30, 0x20); } else { - if (r2 == 0x100) + if (paletteIdx == 0x100) LoadPalette(sWirelessSignalAnimPals_Off, 0x30, 0x20); else - LoadPalette(&sWirelessSignalAnimPals_Inbound[r2], 0x30, 0x20); + LoadPalette(&sWirelessSignalAnimPals_Inbound[paletteIdx], 0x30, 0x20); } - if (sWirelessSignalAnimParams[data[0]][0] == 0 && data[1] == 0) + + if (sWirelessSignalAnimParams[tIdx][0] == 0 && tCounter == 0) PlaySE(SE_M_HEAL_BELL); - if (data[1] == sWirelessSignalAnimParams[data[0]][1]) + + if (tCounter == sWirelessSignalAnimParams[tIdx][1]) { - data[0]++; - data[1] = 0; - if (sWirelessSignalAnimParams[data[0]][1] == 0xFF) + tIdx++; + tCounter = 0; + if (sWirelessSignalAnimParams[tIdx][1] == 0xFF) DestroyTask(taskId); } else - data[1]++; + { + tCounter++; + } } +#undef tIdx +#undef tCounter +#undef tSignalComingBack + static void Task_OpenCenterWhiteColumn(u8 taskId) { s16 *data = gTasks[taskId].data; if (data[0] == 0) { - sTradeData->win0left = sTradeData->win0right = 120; - sTradeData->win0top = 0; - sTradeData->win0bottom = 160; + sTradeAnim->win0left = sTradeAnim->win0right = DISPLAY_WIDTH / 2; + sTradeAnim->win0top = 0; + sTradeAnim->win0bottom = DISPLAY_HEIGHT; SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_OBJ); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG0 | @@ -2816,17 +2839,15 @@ static void Task_OpenCenterWhiteColumn(u8 taskId) WININ_WIN0_OBJ); } - SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeData->win0left, sTradeData->win0right)); - SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeData->win0top, sTradeData->win0bottom)); + SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeAnim->win0left, sTradeAnim->win0right)); + SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeAnim->win0top, sTradeAnim->win0bottom)); data[0]++; - sTradeData->win0left -= 5; - sTradeData->win0right += 5; + sTradeAnim->win0left -= 5; + sTradeAnim->win0right += 5; - if (sTradeData->win0left < 80) - { + if (sTradeAnim->win0left < 80) DestroyTask(taskId); - } } static void Task_CloseCenterWhiteColumn(u8 taskId) @@ -2835,24 +2856,24 @@ static void Task_CloseCenterWhiteColumn(u8 taskId) if (data[0] == 0) { - sTradeData->win0left = 80; - sTradeData->win0right = 160; + sTradeAnim->win0left = 80; + sTradeAnim->win0right = DISPLAY_WIDTH - 80; SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_OBJ); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG0 | WININ_WIN0_BG1 | WININ_WIN0_OBJ); } - SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeData->win0left, sTradeData->win0right)); - SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeData->win0top, sTradeData->win0bottom)); + SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeAnim->win0left, sTradeAnim->win0right)); + SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeAnim->win0top, sTradeAnim->win0bottom)); - if (sTradeData->win0left != 120) + if (sTradeAnim->win0left != DISPLAY_WIDTH / 2) { data[0]++; - sTradeData->win0left += 5; - sTradeData->win0right -= 5; + sTradeAnim->win0left += 5; + sTradeAnim->win0right -= 5; - if (sTradeData->win0left >= 116) + if (sTradeAnim->win0left > DISPLAY_WIDTH / 2 - 5) BlendPalettes(0x8, 0, RGB_WHITEALPHA); } else