From 328aecc96e690c437e52663a1445417e8aa78df6 Mon Sep 17 00:00:00 2001 From: hondew Date: Tue, 4 Aug 2020 22:37:52 -0400 Subject: Document throwing pokeball continue Document more Doc more funcs Remove workspace Document shiny stars Document PokeBlock Clean up Clean more --- src/battle_anim_pokeball.c | 2490 +++++++++++++++++++++++++++++ src/battle_anim_special.c | 2273 -------------------------- src/battle_controller_link_opponent.c | 8 +- src/battle_controller_link_partner.c | 2 +- src/battle_controller_opponent.c | 8 +- src/battle_controller_player.c | 6 +- src/battle_controller_player_partner.c | 2 +- src/battle_controller_recorded_opponent.c | 8 +- src/battle_controller_recorded_player.c | 6 +- src/battle_controller_wally.c | 4 +- src/battle_script_commands.c | 1 + src/pokeball.c | 50 +- 12 files changed, 2539 insertions(+), 2319 deletions(-) create mode 100755 src/battle_anim_pokeball.c delete mode 100755 src/battle_anim_special.c (limited to 'src') diff --git a/src/battle_anim_pokeball.c b/src/battle_anim_pokeball.c new file mode 100755 index 000000000..32081b7d5 --- /dev/null +++ b/src/battle_anim_pokeball.c @@ -0,0 +1,2490 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_controllers.h" +#include "battle_interface.h" +#include "decompress.h" +#include "dma3.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "m4a.h" +#include "main.h" +#include "palette.h" +#include "pokeball.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "util.h" +#include "constants/items.h" +#include "constants/moves.h" +#include "constants/songs.h" +#include "constants/rgb.h" + +// iwram +u32 gMonShrinkDuration; +u16 gMonShrinkDelta; +u16 gMonShrinkDistance; + +enum { + BALL_ROLL_1, + BALL_PIVOT_1, + BALL_ROLL_2, + BALL_PIVOT_2, + BALL_ROLL_3, + BALL_NEXT_MOVE, + BALL_WAIT_NEXT_SHAKE +}; + +enum { + MON_SHRINK, + MON_SHRINK_STEP, + MON_SHRINK_INVISIBLE, + MON_SHRINK_FREE +}; + +enum { + SHINY_STAR_ENCIRCLE, + SHINY_STAR_DIAGONAL, +}; + +static void sub_8170660(u8); +static void sub_8170A38(u8); +static void AnimTask_ThrowBall_Step(u8); +static void SpriteCB_Ball_Throw(struct Sprite *); +static void AnimTask_ThrowBall_StandingTrainer_Step(u8); +static void Task_PlayerThrow_Wait(u8); +static void SpriteCB_Ball_Arc(struct Sprite *); +static void SpriteCB_Ball_Block(struct Sprite *); +static void SpriteCB_Ball_MonShrink(struct Sprite *); +static void SpriteCB_Ball_MonShrink_Step(struct Sprite *); +static void SpriteCB_Ball_Bounce(struct Sprite *); +static void SpriteCB_Ball_Bounce_Step(struct Sprite *); +static void SpriteCB_Ball_Release(struct Sprite *); +static void SpriteCB_Ball_Wobble(struct Sprite *); +static void SpriteCB_Ball_Wobble_Step(struct Sprite *); +static void SpriteCB_Ball_Capture(struct Sprite *); +static void SpriteCB_Ball_Release_Step(struct Sprite *); +static void SpriteCB_Ball_Capture_Step(struct Sprite *); +static void MakeCaptureStars(struct Sprite *); +static void SpriteCB_Ball_FadeOut(struct Sprite *); +static void DestroySpriteAfterOneFrame(struct Sprite *); +static void LoadBallParticleGfx(u8); +static void SpriteCB_CaptureStar_Flicker(struct Sprite *); +static void SpriteCB_Ball_Release_Wait(struct Sprite *); +static void SpriteCB_Ball_Block_Step(struct Sprite *); +static void PokeBallOpenParticleAnimation_Step1(struct Sprite *); +static void PokeBallOpenParticleAnimation_Step2(struct Sprite *); +static void DestroyBallOpenAnimationParticle(struct Sprite *); +static void FanOutBallOpenParticles_Step1(struct Sprite *); +static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *); +static void PremierBallOpenParticleAnimation_Step1(struct Sprite *); +static void Task_FadeMon_ToBallColor(u8); +static void Task_FadeMon_ToNormal(u8); +static void Task_FadeMon_ToNormal_Step(u8); +static void Task_ShinyStars(u8); +static void SpriteCB_ShinyStars_Encircle(struct Sprite *); +static void SpriteCB_ShinyStars_Diagonal(struct Sprite *); +static void Task_ShinyStars_Wait(u8); +static void SpriteCB_PokeBlock_LiftArm(struct Sprite *); +static void SpriteCB_PokeBlock_Arc(struct Sprite *); +static void SpriteCB_ThrowPokeBlock_Free(struct Sprite *); +static void PokeBallOpenParticleAnimation(u8); +static void GreatBallOpenParticleAnimation(u8); +static void SafariBallOpenParticleAnimation(u8); +static void UltraBallOpenParticleAnimation(u8); +static void MasterBallOpenParticleAnimation(u8); +static void DiveBallOpenParticleAnimation(u8); +static void RepeatBallOpenParticleAnimation(u8); +static void TimerBallOpenParticleAnimation(u8); +static void PremierBallOpenParticleAnimation(u8); +static void SpriteCB_PokeBlock_Throw(struct Sprite *); + +struct CaptureStar +{ + s8 xOffset; + s8 yOffset; + s8 amplitude; +}; + +static const struct CaptureStar sCaptureStars[] = +{ + { + .xOffset = 10, + .yOffset = 2, + .amplitude = -3, + }, + { + .xOffset = 15, + .yOffset = 0, + .amplitude = -4, + }, + { + .xOffset = -10, + .yOffset = 2, + .amplitude = -4, + }, +}; + +#define TAG_PARTICLES_POKEBALL 55020 +#define TAG_PARTICLES_GREATBALL 55021 +#define TAG_PARTICLES_SAFARIBALL 55022 +#define TAG_PARTICLES_ULTRABALL 55023 +#define TAG_PARTICLES_MASTERBALL 55024 +#define TAG_PARTICLES_NETBALL 55025 +#define TAG_PARTICLES_DIVEBALL 55026 +#define TAG_PARTICLES_NESTBALL 55027 +#define TAG_PARTICLES_REPEATBALL 55028 +#define TAG_PARTICLES_TIMERBALL 55029 +#define TAG_PARTICLES_LUXURYBALL 55030 +#define TAG_PARTICLES_PREMIERBALL 55031 + +const struct CompressedSpriteSheet gBallParticleSpritesheets[] = +{ + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_POKEBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_GREATBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_SAFARIBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_ULTRABALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_MASTERBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_NETBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_DIVEBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_NESTBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_REPEATBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_TIMERBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_LUXURYBALL}, + {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_PREMIERBALL}, +}; + +const struct CompressedSpritePalette gBallParticlePalettes[] = +{ + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_POKEBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_GREATBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_SAFARIBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_ULTRABALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_MASTERBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_NETBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_DIVEBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_NESTBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_REPEATBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_TIMERBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_LUXURYBALL}, + {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_PREMIERBALL}, +}; + +const union AnimCmd gAnim_RegularBall[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(0, 1, .hFlip = TRUE), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gAnim_MasterBall[] = +{ + ANIMCMD_FRAME(3, 1), + ANIMCMD_END, +}; + +const union AnimCmd gAnim_NetDiveBall[] = +{ + ANIMCMD_FRAME(4, 1), + ANIMCMD_END, +}; + +const union AnimCmd gAnim_NestBall[] = +{ + ANIMCMD_FRAME(5, 1), + ANIMCMD_END, +}; + +const union AnimCmd gAnim_LuxuryPremierBall[] = +{ + ANIMCMD_FRAME(6, 4), + ANIMCMD_FRAME(7, 4), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gAnim_UltraRepeatTimerBall[] = +{ + ANIMCMD_FRAME(7, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gAnims_BallParticles[] = +{ + gAnim_RegularBall, + gAnim_MasterBall, + gAnim_NetDiveBall, + gAnim_NestBall, + gAnim_LuxuryPremierBall, + gAnim_UltraRepeatTimerBall, +}; + +const u8 gBallParticleAnimNums[] = +{ + [BALL_POKE] = 0, + [BALL_GREAT] = 0, + [BALL_SAFARI] = 0, + [BALL_ULTRA] = 5, + [BALL_MASTER] = 1, + [BALL_NET] = 2, + [BALL_DIVE] = 2, + [BALL_NEST] = 3, + [BALL_REPEAT] = 5, + [BALL_TIMER] = 5, + [BALL_LUXURY] = 4, + [BALL_PREMIER] = 4, +}; + +const TaskFunc gBallParticleAnimationFuncs[] = +{ + PokeBallOpenParticleAnimation, + GreatBallOpenParticleAnimation, + SafariBallOpenParticleAnimation, + UltraBallOpenParticleAnimation, + MasterBallOpenParticleAnimation, + SafariBallOpenParticleAnimation, + DiveBallOpenParticleAnimation, + UltraBallOpenParticleAnimation, + RepeatBallOpenParticleAnimation, + TimerBallOpenParticleAnimation, + GreatBallOpenParticleAnimation, + PremierBallOpenParticleAnimation, +}; + +const struct SpriteTemplate gBallParticlesSpriteTemplates[] = +{ + { + .tileTag = TAG_PARTICLES_POKEBALL, + .paletteTag = TAG_PARTICLES_POKEBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_GREATBALL, + .paletteTag = TAG_PARTICLES_GREATBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_SAFARIBALL, + .paletteTag = TAG_PARTICLES_SAFARIBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_ULTRABALL, + .paletteTag = TAG_PARTICLES_ULTRABALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_MASTERBALL, + .paletteTag = TAG_PARTICLES_MASTERBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_NETBALL, + .paletteTag = TAG_PARTICLES_NETBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_DIVEBALL, + .paletteTag = TAG_PARTICLES_DIVEBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_NESTBALL, + .paletteTag = TAG_PARTICLES_NESTBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_REPEATBALL, + .paletteTag = TAG_PARTICLES_REPEATBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_TIMERBALL, + .paletteTag = TAG_PARTICLES_TIMERBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_LUXURYBALL, + .paletteTag = TAG_PARTICLES_LUXURYBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = TAG_PARTICLES_PREMIERBALL, + .paletteTag = TAG_PARTICLES_PREMIERBALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gAnims_BallParticles, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, +}; + +const u16 gBallOpenFadeColors[] = +{ + [BALL_POKE] = RGB(31, 22, 30), + [BALL_GREAT] = RGB(16, 23, 30), + [BALL_SAFARI] = RGB(23, 30, 20), + [BALL_ULTRA] = RGB(31, 31, 15), + [BALL_MASTER] = RGB(23, 20, 28), + [BALL_NET] = RGB(21, 31, 25), + [BALL_DIVE] = RGB(12, 25, 30), + [BALL_NEST] = RGB(30, 27, 10), + [BALL_REPEAT] = RGB(31, 24, 16), + [BALL_TIMER] = RGB(29, 30, 30), + [BALL_LUXURY] = RGB(31, 17, 10), + [BALL_PREMIER] = RGB(31, 9, 10), + + // Garbage data + RGB(0, 0, 0), + RGB(1, 16, 0), + RGB(3, 0, 1), + RGB(1, 8, 0), + RGB(0, 8, 0), + RGB(3, 8, 1), + RGB(6, 8, 1), + RGB(4, 0, 0), +}; + +const struct SpriteTemplate gPokeblockSpriteTemplate = +{ + .tileTag = ANIM_TAG_POKEBLOCK, + .paletteTag = ANIM_TAG_POKEBLOCK, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_PokeBlock_Throw, +}; + +const union AnimCmd gUnknown_085E5350[] = +{ + ANIMCMD_FRAME(64, 1), + ANIMCMD_END, +}; + +const union AnimCmd *const gUnknown_085E5358[] = { + gUnknown_085E5350, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_085E535C = +{ + .tileTag = ANIM_TAG_ROCKS, + .paletteTag = ANIM_TAG_ROCKS, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gUnknown_085E5358, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_PokeBlock_Throw, +}; + +extern const struct SpriteTemplate gWishStarSpriteTemplate; +extern const struct SpriteTemplate gMiniTwinklingStarSpriteTemplate; + +void unref_sub_8170478(u8 taskId) +{ + struct BattleAnimBgData unknownStruct; + u8 healthBoxSpriteId; + u8 battler; + u8 spriteId1, spriteId2, spriteId3, spriteId4; + + battler = gBattleAnimAttacker; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 0); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + SetAnimBgAttribute(1, BG_ANIM_AREA_OVERFLOW_MODE, 1); + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + + healthBoxSpriteId = gHealthboxSpriteIds[battler]; + spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; + spriteId2 = gSprites[healthBoxSpriteId].data[5]; + spriteId3 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); + spriteId4 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); + gSprites[healthBoxSpriteId].oam.priority = 1; + gSprites[spriteId1].oam.priority = 1; + gSprites[spriteId2].oam.priority = 1; + gSprites[spriteId3] = gSprites[healthBoxSpriteId]; + gSprites[spriteId4] = gSprites[spriteId1]; + gSprites[spriteId3].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[spriteId4].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[spriteId3].callback = SpriteCallbackDummy; + gSprites[spriteId4].callback = SpriteCallbackDummy; + + sub_80A6B30(&unknownStruct); + AnimLoadCompressedBgTilemap(unknownStruct.bgId, gUnknown_08C2EA9C); + AnimLoadCompressedBgGfx(unknownStruct.bgId, gUnknown_08C2EA50, unknownStruct.tilesOffset); + LoadCompressedPalette(gCureBubblesPal, unknownStruct.paletteId << 4, 32); + + gBattle_BG1_X = -gSprites[spriteId3].pos1.x + 32; + gBattle_BG1_Y = -gSprites[spriteId3].pos1.y - 32; + gTasks[taskId].data[1] = 640; + gTasks[taskId].data[0] = spriteId3; + gTasks[taskId].data[2] = spriteId4; + gTasks[taskId].func = sub_8170660; +} + +static void sub_8170660(u8 taskId) +{ + u8 spriteId1, spriteId2; + u8 battler; + + battler = gBattleAnimAttacker; + gTasks[taskId].data[13] += gTasks[taskId].data[1]; + gBattle_BG1_Y += (u16)gTasks[taskId].data[13] >> 8; + gTasks[taskId].data[13] &= 0xFF; + + switch (gTasks[taskId].data[15]) + { + case 0: + if (gTasks[taskId].data[11]++ > 1) + { + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[12]++; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); + if (gTasks[taskId].data[12] == 8) + gTasks[taskId].data[15]++; + } + break; + case 1: + if (++gTasks[taskId].data[10] == 30) + gTasks[taskId].data[15]++; + break; + case 2: + if (gTasks[taskId].data[11]++ > 1) + { + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[12]--; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); + if (gTasks[taskId].data[12] == 0) + { + sub_80A477C(0); + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + + SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0)); + DestroySprite(&gSprites[gTasks[taskId].data[0]]); + DestroySprite(&gSprites[gTasks[taskId].data[2]]); + SetAnimBgAttribute(1, BG_ANIM_AREA_OVERFLOW_MODE, 0); + spriteId1 = gSprites[gHealthboxSpriteIds[battler]].oam.affineParam; + spriteId2 = gSprites[gHealthboxSpriteIds[battler]].data[5]; + gSprites[gHealthboxSpriteIds[battler]].oam.priority = 1; + gSprites[spriteId1].oam.priority = 1; + gSprites[spriteId2].oam.priority = 1; + DestroyAnimVisualTask(taskId); + } + } + break; + } +} + +static void LoadHealthboxPalsForLevelUp(u8 *paletteId1, u8 *paletteId2, u8 battler) +{ + u8 healthBoxSpriteId; + u8 spriteId1, spriteId2; + u16 offset1, offset2; + + healthBoxSpriteId = gHealthboxSpriteIds[battler]; + spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; + spriteId2 = gSprites[healthBoxSpriteId].data[5]; + *paletteId1 = AllocSpritePalette(0xD709); + *paletteId2 = AllocSpritePalette(0xD70A); + + offset1 = (gSprites[healthBoxSpriteId].oam.paletteNum * 16) + 0x100; + offset2 = (gSprites[spriteId2].oam.paletteNum * 16) + 0x100; + LoadPalette(&gPlttBufferUnfaded[offset1], *paletteId1 * 16 + 0x100, 0x20); + LoadPalette(&gPlttBufferUnfaded[offset2], *paletteId2 * 16 + 0x100, 0x20); + + gSprites[healthBoxSpriteId].oam.paletteNum = *paletteId1; + gSprites[spriteId1].oam.paletteNum = *paletteId1; + gSprites[spriteId2].oam.paletteNum = *paletteId2; +} + +void AnimTask_LoadHealthboxPalsForLevelUp(u8 taskId) +{ + u8 paletteId1, paletteId2; + LoadHealthboxPalsForLevelUp(&paletteId1, &paletteId2, gBattleAnimAttacker); + DestroyAnimVisualTask(taskId); +} + +static void FreeHealthboxPalsForLevelUp(u8 battler) +{ + u8 healthBoxSpriteId; + u8 spriteId1, spriteId2; + u8 paletteId1, paletteId2; + + healthBoxSpriteId = gHealthboxSpriteIds[battler]; + spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; + spriteId2 = gSprites[healthBoxSpriteId].data[5]; + + FreeSpritePaletteByTag(0xD709); + FreeSpritePaletteByTag(0xD70A); + paletteId1 = IndexOfSpritePaletteTag(0xD6FF); + paletteId2 = IndexOfSpritePaletteTag(0xD704); + gSprites[healthBoxSpriteId].oam.paletteNum = paletteId1; + gSprites[spriteId1].oam.paletteNum = paletteId1; + gSprites[spriteId2].oam.paletteNum = paletteId2; +} + +void AnimTask_FreeHealthboxPalsForLevelUp(u8 taskId) +{ + FreeHealthboxPalsForLevelUp(gBattleAnimAttacker); + DestroyAnimVisualTask(taskId); +} + +void AnimTask_FlashHealthboxOnLevelUp(u8 taskId) +{ + gTasks[taskId].data[10] = gBattleAnimArgs[0]; + gTasks[taskId].data[11] = gBattleAnimArgs[1]; + gTasks[taskId].func = sub_8170A38; +} + +static void sub_8170A38(u8 taskId) +{ + u8 paletteNum; + u32 paletteOffset, colorOffset; + + gTasks[taskId].data[0]++; + if (gTasks[taskId].data[0]++ >= gTasks[taskId].data[11]) + { + gTasks[taskId].data[0] = 0; + paletteNum = IndexOfSpritePaletteTag(0xD709); + colorOffset = gTasks[taskId].data[10] == 0 ? 6 : 2; + switch (gTasks[taskId].data[1]) + { + case 0: + gTasks[taskId].data[2] += 2; + if (gTasks[taskId].data[2] > 16) + gTasks[taskId].data[2] = 16; + + paletteOffset = paletteNum * 16 + 0x100; + BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); + if (gTasks[taskId].data[2] == 16) + gTasks[taskId].data[1]++; + break; + case 1: + gTasks[taskId].data[2] -= 2; + if (gTasks[taskId].data[2] < 0) + gTasks[taskId].data[2] = 0; + + paletteOffset = paletteNum * 16 + 0x100; + BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); + if (gTasks[taskId].data[2] == 0) + DestroyAnimVisualTask(taskId); + break; + } + } +} + +void AnimTask_SwitchOutShrinkMon(u8 taskId) +{ + u8 spriteId; + + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + switch (gTasks[taskId].data[0]) + { + case 0: + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); + gTasks[taskId].data[10] = 0x100; + gTasks[taskId].data[0]++; + break; + case 1: + gTasks[taskId].data[10] += 0x30; + SetSpriteRotScale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); + SetBattlerSpriteYOffsetFromYScale(spriteId); + if (gTasks[taskId].data[10] >= 0x2D0) + gTasks[taskId].data[0]++; + break; + case 2: + ResetSpriteRotScale(spriteId); + gSprites[spriteId].invisible = TRUE; + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimTask_SwitchOutBallEffect(u8 taskId) +{ + u8 spriteId; + u16 ball; + u8 ballId; + u8 x, y; + u8 priority, subpriority; + u32 selectedPalettes; + + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + ball = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); + else + ball = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); + + ballId = ItemIdToBallId(ball); + switch (gTasks[taskId].data[0]) + { + case 0: + x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); + y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y); + priority = gSprites[spriteId].oam.priority; + subpriority = gSprites[spriteId].subpriority; + gTasks[taskId].data[10] = AnimateBallOpenParticles(x, y + 32, priority, subpriority, ballId); + selectedPalettes = sub_80A75AC(1, 0, 0, 0, 0, 0, 0); + gTasks[taskId].data[11] = LaunchBallFadeMonTask(FALSE, gBattleAnimAttacker, selectedPalettes, ballId); + gTasks[taskId].data[0]++; + break; + case 1: + if (!gTasks[gTasks[taskId].data[10]].isActive && !gTasks[gTasks[taskId].data[11]].isActive) + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimTask_LoadBallGfx(u8 taskId) +{ + u8 ballId = ItemIdToBallId(gLastUsedItem); + LoadBallGfx(ballId); + DestroyAnimVisualTask(taskId); +} + +void AnimTask_FreeBallGfx(u8 taskId) +{ + u8 ballId = ItemIdToBallId(gLastUsedItem); + FreeBallGfx(ballId); + DestroyAnimVisualTask(taskId); +} + +void AnimTask_IsBallBlockedByTrainer(u8 taskId) +{ + if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_TRAINER_BLOCK) + gBattleAnimArgs[ARG_RET_ID] = -1; + else + gBattleAnimArgs[ARG_RET_ID] = 0; + + DestroyAnimVisualTask(taskId); +} + +u8 ItemIdToBallId(u16 ballItem) +{ + switch (ballItem) + { + case ITEM_MASTER_BALL: + return BALL_MASTER; + case ITEM_ULTRA_BALL: + return BALL_ULTRA; + case ITEM_GREAT_BALL: + return BALL_GREAT; + case ITEM_SAFARI_BALL: + return BALL_SAFARI; + case ITEM_NET_BALL: + return BALL_NET; + case ITEM_DIVE_BALL: + return BALL_DIVE; + case ITEM_NEST_BALL: + return BALL_NEST; + case ITEM_REPEAT_BALL: + return BALL_REPEAT; + case ITEM_TIMER_BALL: + return BALL_TIMER; + case ITEM_LUXURY_BALL: + return BALL_LUXURY; + case ITEM_PREMIER_BALL: + return BALL_PREMIER; + case ITEM_POKE_BALL: + default: + return BALL_POKE; + } +} + +#define tSpriteId data[0] + +#define sDuration data[0] +#define sTargetX data[1] +#define sTargetY data[2] + +void AnimTask_ThrowBall(u8 taskId) +{ + u8 ballId; + u8 spriteId; + + ballId = ItemIdToBallId(gLastUsedItem); + spriteId = CreateSprite(&gBallSpriteTemplates[ballId], 32, 80, 29); + gSprites[spriteId].sDuration = 34; + gSprites[spriteId].sTargetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + gSprites[spriteId].sTargetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) - 16; + gSprites[spriteId].callback = SpriteCB_Ball_Throw; + gBattleSpritesDataPtr->animationData->wildMonInvisible = gSprites[gBattlerSpriteIds[gBattleAnimTarget]].invisible; + gTasks[taskId].tSpriteId = spriteId; + gTasks[taskId].func = AnimTask_ThrowBall_Step; +} + +static void AnimTask_ThrowBall_Step(u8 taskId) +{ + u8 spriteId = gTasks[taskId].tSpriteId; + if ((u16)gSprites[spriteId].sDuration == 0xFFFF) + DestroyAnimVisualTask(taskId); +} + +// Safari Zone throw / Wally's throw +void AnimTask_ThrowBall_StandingTrainer(u8 taskId) +{ + s16 x, y; + u8 ballId; + u8 subpriority; + u8 spriteId; + + if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) + { + x = 32; + y = 11; + } + else + { + x = 23; + y = 5; + } + + ballId = ItemIdToBallId(gLastUsedItem); + subpriority = GetBattlerSpriteSubpriority(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)) + 1; + spriteId = CreateSprite(&gBallSpriteTemplates[ballId], x + 32, y | 80, subpriority); + gSprites[spriteId].sDuration = 34; + gSprites[spriteId].sTargetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + gSprites[spriteId].sTargetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) - 16; + gSprites[spriteId].callback = SpriteCallbackDummy; + gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].callback = sub_8039E84; + gTasks[taskId].tSpriteId = spriteId; + gTasks[taskId].func = AnimTask_ThrowBall_StandingTrainer_Step; +} + +static void AnimTask_ThrowBall_StandingTrainer_Step(u8 taskId) +{ + if (gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animCmdIndex == 1) + { + PlaySE12WithPanning(SE_NAGERU, 0); + gSprites[gTasks[taskId].tSpriteId].callback = SpriteCB_Ball_Throw; + CreateTask(Task_PlayerThrow_Wait, 10); + gTasks[taskId].func = AnimTask_ThrowBall_Step; + } +} + +#undef sDuration +#undef sTargetX +#undef sTargetY + +#undef tSpriteId + +static void Task_PlayerThrow_Wait(u8 taskId) +{ + if (gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animEnded) + { + StartSpriteAnim(&gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]], 0); + DestroyTask(taskId); + } +} + +#define sTargetXArg data[1] +#define sTargetYArg data[2] + +#define sOffsetX data[1] // re-use +#define sTargetX data[2] // re-use +#define sOffsetY data[3] +#define sTargetY data[4] +#define sAmplitude data[5] + +static void SpriteCB_Ball_Throw(struct Sprite *sprite) +{ + u16 targetX = sprite->sTargetXArg; + u16 targetY = sprite->sTargetYArg; + + sprite->sOffsetX = sprite->pos1.x; + sprite->sTargetX = targetX; + sprite->sOffsetY = sprite->pos1.y; + sprite->sTargetY = targetY; + sprite->sAmplitude = -40; + InitAnimArcTranslation(sprite); + sprite->callback = SpriteCB_Ball_Arc; +} + +#undef sTargetXArg +#undef sTargetYArg +#undef sOffsetX +#undef sTargetX +#undef sOffsetY +#undef sTargetY +#undef sAmplitude + +#define sTimer data[5] +#define sTaskId data[5] // re-use + +static void SpriteCB_Ball_Arc(struct Sprite *sprite) +{ + s32 i; + u8 ballId; + + if (TranslateAnimHorizontalArc(sprite)) + { + if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_TRAINER_BLOCK) + { + sprite->callback = SpriteCB_Ball_Block; + } + else + { + StartSpriteAnim(sprite, 1); + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + + for (i = 0; i < 8; i++) + sprite->data[i] = 0; + + sprite->sTimer = 0; + sprite->callback = SpriteCB_Ball_MonShrink; + + ballId = ItemIdToBallId(gLastUsedItem); + switch (ballId) + { + case 0 ... POKEBALL_COUNT - 1: + AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballId); + LaunchBallFadeMonTask(FALSE, gBattleAnimTarget, 14, ballId); + break; + } + } + } +} + +static void SpriteCB_Ball_MonShrink(struct Sprite *sprite) +{ + if (++sprite->sTimer == 10) + { + sprite->sTaskId = CreateTask(TaskDummy, 50); + sprite->callback = SpriteCB_Ball_MonShrink_Step; + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].data[1] = 0; + } +} + +#undef sTimer +#undef sTaskId + +#define tState data[0] +#define sTimer data[1] +#define sTaskId data[5] + +static void SpriteCB_Ball_MonShrink_Step(struct Sprite *sprite) +{ + u8 spriteId; + u8 taskId; + + spriteId = gBattlerSpriteIds[gBattleAnimTarget]; + taskId = sprite->sTaskId; + + if (++gTasks[taskId].sTimer == 11) + PlaySE(SE_SUIKOMU); + + switch (gTasks[taskId].tState) + { + case MON_SHRINK: + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); + gTasks[taskId].data[10] = 256; + gMonShrinkDuration = 28; + gMonShrinkDistance = (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) - (sprite->pos1.y + sprite->pos2.y); + gMonShrinkDelta = (u32)(gMonShrinkDistance * 256) / gMonShrinkDuration; + gTasks[taskId].data[2] = gMonShrinkDelta; + gTasks[taskId].tState++; // MON_SHRINK_STEP + break; + case MON_SHRINK_STEP: + gTasks[taskId].data[10] += 32; + SetSpriteRotScale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); + gTasks[taskId].data[3] += gTasks[taskId].data[2]; + gSprites[spriteId].pos2.y = -gTasks[taskId].data[3] >> 8; + if (gTasks[taskId].data[10] >= 1152) + gTasks[taskId].tState++; // MON_SHRINK_INVISIBLE + break; + case MON_SHRINK_INVISIBLE: + ResetSpriteRotScale(spriteId); + gSprites[spriteId].invisible = TRUE; + gTasks[taskId].tState++; // MON_SHRINK_FREE + break; + case MON_SHRINK_FREE: + default: + if (gTasks[taskId].data[1] > 10) + { + DestroyTask(taskId); + StartSpriteAnim(sprite, 2); + sprite->data[5] = 0; + sprite->callback = SpriteCB_Ball_Bounce; + } + break; + } +} + +#undef sTimer +#undef tState +#undef sTaskId + +#define sState data[3] +#define sAmplitude data[4] +#define sPhase data[5] + +static void SpriteCB_Ball_Bounce(struct Sprite *sprite) +{ + s16 phase; + + if (sprite->animEnded) + { + sprite->sState = 0; + sprite->sAmplitude = 40; + sprite->sPhase = 0; + phase = 0; + sprite->pos1.y += Cos(phase, 40); + sprite->pos2.y = -Cos(phase, sprite->sAmplitude); + sprite->callback = SpriteCB_Ball_Bounce_Step; + } +} + +#undef sState +#undef sAmplitude +#undef sPhase + +#define DIRECTION(state) (state & 0xFF) +#define PHASE_DELTA(state) (state >> 8) +#define BOUNCES(state) (state >> 8) +#define FALL(state) (state &= -0x100) +#define RISE_FASTER(state) (state += 257) + +#define BALL_FALLING 0 +#define BALL_RISING 1 + +#define sState data[3] +#define sAmplitude data[4] +#define sPhase data[5] +#define sTimer data[5] // re-use + +// Animates the Poké Ball dropping to ground and bouncing. +static void SpriteCB_Ball_Bounce_Step(struct Sprite *sprite) +{ + bool8 lastBounce; + s16 bounceCount; + + lastBounce = FALSE; + + switch (DIRECTION(sprite->sState)) + { + case BALL_FALLING: + sprite->pos2.y = -Cos(sprite->sPhase, sprite->sAmplitude); + sprite->sPhase += PHASE_DELTA(sprite->sState) + 4; + // Once the ball touches the ground + if (sprite->sPhase >= 64) + { + sprite->sAmplitude -= 10; + RISE_FASTER(sprite->sState); + + bounceCount = BOUNCES(sprite->sState); + if (bounceCount == 4) + lastBounce = TRUE; + + switch (bounceCount) + { + case 1: + PlaySE(SE_KON); + break; + case 2: + PlaySE(SE_KON2); + break; + case 3: + PlaySE(SE_KON3); + break; + default: + PlaySE(SE_KON4); + break; + } + } + break; + case BALL_RISING: + sprite->pos2.y = -Cos(sprite->sPhase, sprite->sAmplitude); + sprite->sPhase -= PHASE_DELTA(sprite->sState) + 4; + // Once ball reaches max height + if (sprite->sPhase <= 0) + { + // Set to BALL_FALLING + sprite->sPhase = 0; + FALL(sprite->sState); + } + break; + } + + if (lastBounce) + { + sprite->sState = 0; + sprite->pos1.y += Cos(64, 40); + sprite->pos2.y = 0; + if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_NO_SHAKES) + { + sprite->sTimer = 0; + sprite->callback = SpriteCB_Ball_Release; + } + else + { + sprite->callback = SpriteCB_Ball_Wobble; + sprite->data[4] = 1; + sprite->data[5] = 0; + } + } +} + +#undef sState +#undef sAmplitude +#undef sPhase +#undef sTimer + +#undef DIRECTION +#undef PHASE_DELTA +#undef BOUNCES +#undef FALL +#undef RISE_FASTER + +#define sTimer data[3] +#define sState data[3] // re-use + +static void SpriteCB_Ball_Wobble(struct Sprite *sprite) +{ + if (++sprite->sTimer == 31) + { + sprite->sState = 0; + sprite->affineAnimPaused = TRUE; + StartSpriteAffineAnim(sprite, BALL_ROTATE_RIGHT); + gBattleSpritesDataPtr->animationData->ballSubpx = 0; + sprite->callback = SpriteCB_Ball_Wobble_Step; + PlaySE(SE_BOWA); + } +} + +#undef sTimer +#undef sState + +#define sState data[3] +#define sDirection data[4] +#define sTimer data[5] + +#define STATE(state) (state & 0xFF) +#define SHAKES(state) (state >> 8) +#define SHAKE_INC(state) (state += 0x100) +#define RESET_STATE(state) (state &= -0x100) + +static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite) +{ + s8 shakes; + u16 frame; + + switch (STATE(sprite->sState)) + { + case BALL_ROLL_1: + // Rolling effect: every frame in the rotation, the sprite shifts 176/256 of a pixel. + if (gBattleSpritesDataPtr->animationData->ballSubpx > 255) + { + sprite->pos2.x += sprite->sDirection; + gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF; + } + else + gBattleSpritesDataPtr->animationData->ballSubpx += 176; + + sprite->sTimer++; + sprite->affineAnimPaused = FALSE; + frame = sprite->sTimer + 7; + if (frame > 14) + { + gBattleSpritesDataPtr->animationData->ballSubpx = 0; + sprite->sState++; // BALL_PIVOT_1 + sprite->sTimer = 0; + } + break; + case BALL_PIVOT_1: + if (++sprite->sTimer == 1) + { + sprite->sTimer = 0; + sprite->sDirection = -sprite->sDirection; + sprite->sState++; // BALL_ROLL_2 + sprite->affineAnimPaused = FALSE; + if (sprite->sDirection < 0) + ChangeSpriteAffineAnim(sprite, BALL_ROTATE_LEFT); + else + ChangeSpriteAffineAnim(sprite, BALL_ROTATE_RIGHT); + } + else + sprite->affineAnimPaused = TRUE; + break; + case BALL_ROLL_2: + if (gBattleSpritesDataPtr->animationData->ballSubpx > 255) + { + sprite->pos2.x += sprite->sDirection; + gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF; + } + else + gBattleSpritesDataPtr->animationData->ballSubpx += 176; + + sprite->sTimer++; + sprite->affineAnimPaused = FALSE; + frame = sprite->sTimer + 12; + if (frame > 24) + { + gBattleSpritesDataPtr->animationData->ballSubpx = 0; + sprite->sState++; // BALL_PIVOT_2 + sprite->sTimer = 0; + } + break; + case BALL_PIVOT_2: + if (sprite->sTimer++ < 0) + { + sprite->affineAnimPaused = TRUE; + break; + } + + sprite->sTimer = 0; + sprite->sDirection = -sprite->sDirection; + sprite->sState++; // BALL_ROLL_3 + sprite->affineAnimPaused = FALSE; + if (sprite->sDirection < 0) + ChangeSpriteAffineAnim(sprite, BALL_ROTATE_LEFT); + else + ChangeSpriteAffineAnim(sprite, BALL_ROTATE_RIGHT); + // fall through + case BALL_ROLL_3: + if (gBattleSpritesDataPtr->animationData->ballSubpx > 0xFF) + { + sprite->pos2.x += sprite->sDirection; + gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF; + } + else + gBattleSpritesDataPtr->animationData->ballSubpx += 176; + + sprite->sTimer++; + sprite->affineAnimPaused = FALSE; + frame = sprite->sTimer + 4; + if (frame > 8) + { + gBattleSpritesDataPtr->animationData->ballSubpx = 0; + sprite->sState++; // BALL_NEXT_MOVE + sprite->sTimer = 0; + sprite->sDirection = -sprite->sDirection; + } + break; + case BALL_NEXT_MOVE: + SHAKE_INC(sprite->sState); + shakes = SHAKES(sprite->sState); + if (shakes == gBattleSpritesDataPtr->animationData->ballThrowCaseId) + { + sprite->affineAnimPaused = TRUE; + sprite->callback = SpriteCB_Ball_Release; + } + else + { + if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_3_SHAKES_SUCCESS && shakes == 3) + { + sprite->callback = SpriteCB_Ball_Capture; + sprite->affineAnimPaused = TRUE; + } + else + { + sprite->sState++; // BALL_WAIT_NEXT_SHAKE + sprite->affineAnimPaused = TRUE; + } + } + break; + case BALL_WAIT_NEXT_SHAKE: + default: + if (++sprite->sTimer == 31) + { + sprite->sTimer = 0; + RESET_STATE(sprite->sState); + StartSpriteAffineAnim(sprite, 3); + if (sprite->sDirection < 0) + StartSpriteAffineAnim(sprite, BALL_ROTATE_LEFT); + else + StartSpriteAffineAnim(sprite, BALL_ROTATE_RIGHT); + + PlaySE(SE_BOWA); + } + break; + } +} + +#undef STATE +#undef SHAKES +#undef SHAKE_INC +#undef RESET_STATE + +#undef sState + +#define sTimer data[5] + +static void SpriteCB_Ball_Release(struct Sprite *sprite) +{ + if (++sprite->sTimer == 31) + { + sprite->data[5] = 0; + sprite->callback = SpriteCB_Ball_Release_Step; + } +} +#undef sTimer + +#define sState data[0] +#define sTimer data[4] + +static void SpriteCB_Ball_Capture(struct Sprite *sprite) +{ + sprite->animPaused = TRUE; + sprite->callback = SpriteCB_Ball_Capture_Step; + sprite->data[3] = 0; + sprite->sTimer = 0; + sprite->data[5] = 0; +} + +// Fade and unfade ball, create star animations, play sound effects +static void SpriteCB_Ball_Capture_Step(struct Sprite *sprite) +{ + u8 *battler = &gBattleAnimTarget; + + sprite->sTimer++; + if (sprite->sTimer == 40) + { + PlaySE(SE_RG_GETTING); + BlendPalettes(0x10000 << sprite->oam.paletteNum, 6, RGB(0, 0, 0)); + MakeCaptureStars(sprite); + } + else if (sprite->sTimer == 60) + { + BeginNormalPaletteFade(0x10000 << sprite->oam.paletteNum, 2, 6, 0, RGB(0, 0, 0)); + } + else if (sprite->sTimer == 95) + { + gDoingBattleAnim = FALSE; + UpdateOamPriorityInAllHealthboxes(1); + m4aMPlayAllStop(); + PlaySE(MUS_RG_FAN6); + } + else if (sprite->sTimer == 315) + { + FreeOamMatrix(gSprites[gBattlerSpriteIds[*battler]].oam.matrixNum); + DestroySprite(&gSprites[gBattlerSpriteIds[*battler]]); + + sprite->sState = 0; + sprite->callback = SpriteCB_Ball_FadeOut; + } +} + +#undef sTimer +#undef sState + +#define sState data[0] +#define sFrame data[0] // re-use + +static void SpriteCB_Ball_FadeOut(struct Sprite *sprite) +{ + u8 paletteIndex; + + switch (sprite->sState) + { + case 0: + sprite->data[1] = 0; + sprite->data[2] = 0; + sprite->oam.objMode = ST_OAM_OBJ_BLEND; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); + paletteIndex = IndexOfSpritePaletteTag(sprite->template->paletteTag); + BeginNormalPaletteFade(1 << (paletteIndex + 0x10), 0, 0, 16, RGB(31, 31, 31)); + sprite->sState++; + break; + case 1: + if (sprite->data[1]++ > 0) + { + sprite->data[1] = 0; + sprite->data[2]++; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[2], sprite->data[2])); + if (sprite->data[2] == 16) + sprite->sState++; + } + break; + case 2: + sprite->invisible = TRUE; + sprite->sState++; + break; + default: + if (!gPaletteFade.active) + { + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + + sprite->sFrame = 0; + sprite->callback = DestroySpriteAfterOneFrame; + } + break; + } +} + +#undef sState +#undef sFrame + +#define sFrame data[0] + +static void DestroySpriteAfterOneFrame(struct Sprite *sprite) +{ + if (sprite->sFrame == 0) + sprite->sFrame = -1; + else + { + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } +} +#undef sFrame + +#define sDuration data[0] +#define sTargetX data[2] +#define sTargetY data[4] +#define sAmplitude data[5] + +static void MakeCaptureStars(struct Sprite *sprite) +{ + u32 i; + u8 subpriority; + + if (sprite->subpriority) + subpriority = sprite->subpriority - 1; + else + { + subpriority = 0; + sprite->subpriority = 1; + } + + LoadBallParticleGfx(BALL_MASTER); + for (i = 0; i < ARRAY_COUNT(sCaptureStars); i++) + { + u8 spriteId = CreateSprite(&gBallParticlesSpriteTemplates[4], sprite->pos1.x, sprite->pos1.y, subpriority); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].sDuration = 24; + gSprites[spriteId].sTargetX = sprite->pos1.x + sCaptureStars[i].xOffset; + gSprites[spriteId].sTargetY = sprite->pos1.y + sCaptureStars[i].yOffset; + gSprites[spriteId].sAmplitude = sCaptureStars[i].amplitude; + InitAnimArcTranslation(&gSprites[spriteId]); + gSprites[spriteId].callback = SpriteCB_CaptureStar_Flicker; + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[BALL_MASTER]); + } + } +} + +#undef sDuration +#undef sTargetX +#undef sTargetY +#undef sAmplitude + +static void SpriteCB_CaptureStar_Flicker(struct Sprite *sprite) +{ + sprite->invisible = !sprite->invisible; + if (TranslateAnimHorizontalArc(sprite)) + DestroySprite(sprite); +} + +#define sFrame data[0] +#define sOffsetY data[1] + +// Poké Ball didn't catch - starts: +// - Ball particle animations +// - Wild mon fade to normal color +// - Wild mon emerge from Poké Ball +static void SpriteCB_Ball_Release_Step(struct Sprite *sprite) +{ + u8 ballId; + + StartSpriteAnim(sprite, 1); + StartSpriteAffineAnim(sprite, 0); + sprite->callback = SpriteCB_Ball_Release_Wait; + + ballId = ItemIdToBallId(gLastUsedItem); + switch (ballId) + { + case 0 ... POKEBALL_COUNT - 1: + AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballId); + LaunchBallFadeMonTask(TRUE, gBattleAnimTarget, 14, ballId); + break; + } + + // Animate Pokémon emerging from Poké Ball + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].invisible = FALSE; + StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimTarget]], 1); + AnimateSprite(&gSprites[gBattlerSpriteIds[gBattleAnimTarget]]); + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].sOffsetY = 4096; +} + +static void SpriteCB_Ball_Release_Wait(struct Sprite *sprite) +{ + bool8 released = FALSE; + + if (sprite->animEnded) + sprite->invisible = TRUE; + + if (gSprites[gBattlerSpriteIds[gBattleAnimTarget]].affineAnimEnded) + { + StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimTarget]], 0); + released = TRUE; + } + else + { + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].sOffsetY -= 288; + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].pos2.y = gSprites[gBattlerSpriteIds[gBattleAnimTarget]].sOffsetY >> 8; + } + + if (sprite->animEnded && released) + { + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].pos2.y = 0; + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].invisible = gBattleSpritesDataPtr->animationData->wildMonInvisible; + sprite->sFrame = 0; + sprite->callback = DestroySpriteAfterOneFrame; + gDoingBattleAnim = 0; + UpdateOamPriorityInAllHealthboxes(1); + } +} + +#undef sFrame +#undef sOffsetY + +static void SpriteCB_Ball_Block(struct Sprite *sprite) +{ + s32 i; + + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + for (i = 0; i < 6; i++) + sprite->data[i] = 0; + + sprite->callback = SpriteCB_Ball_Block_Step; +} + +#define sDy data[0] +#define sDx data[1] + +#define sFrame data[0] // re-use + +// Poké Ball moves down off screen after being blocked. The x-speed oscillates. +static void SpriteCB_Ball_Block_Step(struct Sprite *sprite) +{ + s16 dy = sprite->sDy + 0x800; + s16 dx = sprite->sDx + 0x680; + sprite->pos2.x -= dx >> 8; + sprite->pos2.y += dy >> 8; + sprite->sDy = (sprite->sDy + 0x800) & 0xFF; + sprite->sDx = (sprite->sDx + 0x680) & 0xFF; + + if (sprite->pos1.y + sprite->pos2.y > 160 + || sprite->pos1.x + sprite->pos2.x < -8) + { + sprite->sFrame = 0; + sprite->callback = DestroySpriteAfterOneFrame; + gDoingBattleAnim = 0; + UpdateOamPriorityInAllHealthboxes(1); + } +} + +#undef sDy +#undef sDx + +#undef sFrame + +static void LoadBallParticleGfx(u8 ballId) +{ + u8 taskId; + + if (GetSpriteTileStartByTag(gBallParticleSpritesheets[ballId].tag) == 0xFFFF) + { + LoadCompressedSpriteSheetUsingHeap(&gBallParticleSpritesheets[ballId]); + LoadCompressedSpritePaletteUsingHeap(&gBallParticlePalettes[ballId]); + } +} + +u8 AnimateBallOpenParticles(u8 x, u8 y, u8 priority, u8 subpriority, u8 ballId) +{ + u8 taskId; + + LoadBallParticleGfx(ballId); + taskId = CreateTask(gBallParticleAnimationFuncs[ballId], 5); + gTasks[taskId].data[1] = x; + gTasks[taskId].data[2] = y; + gTasks[taskId].data[3] = priority; + gTasks[taskId].data[4] = subpriority; + gTasks[taskId].data[15] = ballId; + PlaySE(SE_BOWA2); + + return taskId; +} + +static void IncrBallParticleCount(void) +{ + if (gMain.inBattle) + gBattleSpritesDataPtr->animationData->numBallParticles++; +} + +static void PokeBallOpenParticleAnimation(u8 taskId) +{ + u8 spriteId; + u8 x, y; + u8 priority, subpriority; + u8 ballId; + u8 var0; + + ballId = gTasks[taskId].data[15]; + if (gTasks[taskId].data[0] < 16) + { + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = PokeBallOpenParticleAnimation_Step1; + gSprites[spriteId].oam.priority = priority; + + var0 = (u8)gTasks[taskId].data[0]; + if (var0 >= 8) + var0 -= 8; + + gSprites[spriteId].data[0] = var0 * 32; + } + + if (gTasks[taskId].data[0] == 15) + { + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); + return; + } + } + + gTasks[taskId].data[0]++; +} + +static void PokeBallOpenParticleAnimation_Step1(struct Sprite *sprite) +{ + if (sprite->data[1] == 0) + sprite->callback = PokeBallOpenParticleAnimation_Step2; + else + sprite->data[1]--; +} + +static void PokeBallOpenParticleAnimation_Step2(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[1]); + sprite->data[1] += 2; + if (sprite->data[1] == 50) + DestroyBallOpenAnimationParticle(sprite); +} + +static void TimerBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 10; + gSprites[spriteId].data[5] = 2; + gSprites[spriteId].data[6] = 1; + } + } + + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); +} + +static void DiveBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 10; + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 2; + } + } + + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); +} + +// Also used for Net Ball +static void SafariBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 4; + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 1; + } + } + + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); +} + +// Also used for Nest Ball +static void UltraBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 10; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 25; + gSprites[spriteId].data[4] = 5; + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 1; + } + } + + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); +} + +// Also used for Luxury Ball +static void GreatBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + if (gTasks[taskId].data[7]) + { + gTasks[taskId].data[7]--; + } + else + { + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 8; + gSprites[spriteId].data[5] = 2; + gSprites[spriteId].data[6] = 2; + } + } + + gTasks[taskId].data[7] = 8; + if (++gTasks[taskId].data[0] == 2) + { + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); + } + } +} + +static void FanOutBallOpenParticles_Step1(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[2]); + sprite->data[0] = (sprite->data[0] + sprite->data[4]) & 0xFF; + sprite->data[1] += sprite->data[5]; + sprite->data[2] += sprite->data[6]; + if (++sprite->data[3] == 51) + DestroyBallOpenAnimationParticle(sprite); +} + +static void RepeatBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < POKEBALL_COUNT; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = RepeatBallOpenParticleAnimation_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 21; + } + } + + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); +} + +static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0], sprite->data[2])); + sprite->data[0] = (sprite->data[0] + 6) & 0xFF; + sprite->data[1]++; + sprite->data[2]++; + if (++sprite->data[3] == 51) + DestroyBallOpenAnimationParticle(sprite); +} + +static void MasterBallOpenParticleAnimation(u8 taskId) +{ + u8 i, j; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (j = 0; j < 2; j++) + { + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 8; + + if (j == 0) + { + gSprites[spriteId].data[5] = 2; + gSprites[spriteId].data[6] = 1; + } + else + { + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 2; + } + } + } + } + + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); +} + +static void PremierBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballId; + u8 spriteId; + + ballId = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); + if (spriteId != MAX_SPRITES) + { + IncrBallParticleCount(); + StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); + gSprites[spriteId].callback = PremierBallOpenParticleAnimation_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + } + } + + if (!gMain.inBattle) + gSprites[spriteId].data[7] = 1; + + DestroyTask(taskId); +} + +static void PremierBallOpenParticleAnimation_Step1(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0] & 0x3F, sprite->data[2])); + sprite->data[0] = (sprite->data[0] + 10) & 0xFF; + sprite->data[1]++; + sprite->data[2]++; + if (++sprite->data[3] == 51) + DestroyBallOpenAnimationParticle(sprite); +} + +static void DestroyBallOpenAnimationParticle(struct Sprite *sprite) +{ + s32 i, j; + + if (!gMain.inBattle) + { + if (sprite->data[7] == 1) + DestroySpriteAndFreeResources(sprite); + else + DestroySprite(sprite); + } + else + { + gBattleSpritesDataPtr->animationData->numBallParticles--; + if (gBattleSpritesDataPtr->animationData->numBallParticles == 0) + { + for (i = 0; i < POKEBALL_COUNT; i++) + { + if (FuncIsActiveTask(gBallParticleAnimationFuncs[i]) == TRUE) + break; + } + + if (i == POKEBALL_COUNT) + { + for (j = 0; j < POKEBALL_COUNT; j++) + { + FreeSpriteTilesByTag(gBallParticleSpritesheets[j].tag); + FreeSpritePaletteByTag(gBallParticlePalettes[j].tag); + } + } + + DestroySprite(sprite); + } + else + { + DestroySprite(sprite); + } + } +} + +#define tCoeff data[0] +#define tdCoeff data[1] +#define tTimer data[2] +#define tPalOffset data[3] +#define tPaletteLo data[10] +#define tPaletteHi data[11] +#define tBallId data[15] + +u8 LaunchBallFadeMonTask(bool8 unfadeLater, u8 battler, u32 selectedPalettes, u8 ballId) +{ + u8 taskId; + + taskId = CreateTask(Task_FadeMon_ToBallColor, 5); + gTasks[taskId].tBallId = ballId; + gTasks[taskId].tPalOffset = battler; + gTasks[taskId].tPaletteLo = selectedPalettes; + gTasks[taskId].tPaletteHi = selectedPalettes >> 16; + + if (!unfadeLater) + { + BlendPalette(battler * 16 + 0x100, 16, 0, gBallOpenFadeColors[ballId]); + gTasks[taskId].tdCoeff = 1; + } + else + { + BlendPalette(battler * 16 + 0x100, 16, 16, gBallOpenFadeColors[ballId]); + gTasks[taskId].tCoeff = 16; + gTasks[taskId].tdCoeff = -1; + gTasks[taskId].func = Task_FadeMon_ToNormal; + } + + BeginNormalPaletteFade(selectedPalettes, 0, 0, 16, RGB(31, 31, 31)); + return taskId; +} + +static void Task_FadeMon_ToBallColor(u8 taskId) +{ + u8 ballId = gTasks[taskId].tBallId; + + if (gTasks[taskId].tTimer <= 16) + { + BlendPalette(gTasks[taskId].tPalOffset * 16 + 0x100, 16, gTasks[taskId].tCoeff, gBallOpenFadeColors[ballId]); + gTasks[taskId].tCoeff += gTasks[taskId].tdCoeff; + gTasks[taskId].tTimer++; + } + else if (!gPaletteFade.active) + { + u32 selectedPalettes = (u16)gTasks[taskId].tPaletteLo | ((u16)gTasks[taskId].tPaletteHi << 16); + BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB_WHITE); + DestroyTask(taskId); + } +} + +static void Task_FadeMon_ToNormal(u8 taskId) +{ + if (!gPaletteFade.active) + { + u32 selectedPalettes = (u16)gTasks[taskId].tPaletteLo | ((u16)gTasks[taskId].tPaletteHi << 16); + BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB_WHITE); + gTasks[taskId].func = Task_FadeMon_ToNormal_Step; + } +} + +static void Task_FadeMon_ToNormal_Step(u8 taskId) +{ + u8 ballId = gTasks[taskId].tBallId; + + if (gTasks[taskId].tTimer <= 16) + { + BlendPalette(gTasks[taskId].tPalOffset * 16 + 0x100, 16, gTasks[taskId].tCoeff, gBallOpenFadeColors[ballId]); + gTasks[taskId].tCoeff += gTasks[taskId].tdCoeff; + gTasks[taskId].tTimer++; + } + else + { + DestroyTask(taskId); + } +} + +#undef tCoeff +#undef tdCoeff +#undef tTimer +#undef tPalOffset +#undef tPaletteLo +#undef tPaletteHi +#undef tBallId + +// arg0: TRUE to swap to mon, FALSE to swap to substitute +void AnimTask_SwapMonSpriteToFromSubstitute(u8 taskId) +{ + u8 spriteId; + u32 x; + u32 done = FALSE; + + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + switch (gTasks[taskId].data[10]) + { + case 0: + gTasks[taskId].data[11] = gBattleAnimArgs[0]; + gTasks[taskId].data[0] += 0x500; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; + else + gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; + + gTasks[taskId].data[0] &= 0xFF; + x = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x + 32; + if (x > 304) + gTasks[taskId].data[10]++; + break; + case 1: + LoadBattleMonGfxAndAnimate(gBattleAnimAttacker, gTasks[taskId].data[11], spriteId); + gTasks[taskId].data[10]++; + break; + case 2: + gTasks[taskId].data[0] += 0x500; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; + else + gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; + + gTasks[taskId].data[0] &= 0xFF; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + if (gSprites[spriteId].pos2.x <= 0) + { + gSprites[spriteId].pos2.x = 0; + done = TRUE; + } + } + else + { + if (gSprites[spriteId].pos2.x >= 0) + { + gSprites[spriteId].pos2.x = 0; + done = TRUE; + } + } + + if (done) + DestroyAnimVisualTask(taskId); + + break; + } +} + +void AnimTask_SubstituteFadeToInvisible(u8 taskId) +{ + u8 spriteId; + + switch (gTasks[taskId].data[15]) + { + case 0: + if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == B_POSITION_OPPONENT_LEFT) + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + else + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); + gTasks[taskId].data[15]++; + break; + case 1: + if (gTasks[taskId].data[1]++ > 1) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - gTasks[taskId].data[0], gTasks[taskId].data[0])); + if (gTasks[taskId].data[0] == 16) + gTasks[taskId].data[15]++; + } + break; + case 2: + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + RequestDma3Fill(0, (void *)OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * TILE_SIZE_4BPP, 0x800, 1); + ClearBehindSubstituteBit(gBattleAnimAttacker); + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimTask_IsAttackerBehindSubstitute(u8 taskId) +{ + gBattleAnimArgs[ARG_RET_ID] = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].behindSubstitute; + DestroyAnimVisualTask(taskId); +} + +void AnimTask_SetTargetToEffectBattler(u8 taskId) +{ + gBattleAnimTarget = gEffectBattler; + DestroyAnimVisualTask(taskId); +} + +#define tBattler data[0] +#define tStarMove data[1] +#define tStarTimer data[10] +#define tStarIdx data[11] +#define tNumStars data[12] +#define tTimer data[13] + +#define sTaskId data[0] +#define sPhase data[1] // For encircling stars +#define sTimer data[1] // For diagnoal stars + +void TryShinyAnimation(u8 battler, struct Pokemon *mon) +{ + bool8 isShiny; + u32 otId, personality; + u32 shinyValue; + u8 taskCirc, taskDgnl; + + isShiny = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].flag_x80 = 1; + otId = GetMonData(mon, MON_DATA_OT_ID); + personality = GetMonData(mon, MON_DATA_PERSONALITY); + + if (IsBattlerSpriteVisible(battler)) + { + shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); + if (shinyValue < SHINY_ODDS) + isShiny = TRUE; + + if (isShiny) + { + if (GetSpriteTileStartByTag(ANIM_TAG_GOLD_STARS) == 0xFFFF) + { + LoadCompressedSpriteSheetUsingHeap(&gBattleAnimPicTable[ANIM_TAG_GOLD_STARS - ANIM_SPRITES_START]); + LoadCompressedSpritePaletteUsingHeap(&gBattleAnimPaletteTable[ANIM_TAG_GOLD_STARS - ANIM_SPRITES_START]); + } + + taskCirc = CreateTask(Task_ShinyStars, 10); + taskDgnl = CreateTask(Task_ShinyStars, 10); + gTasks[taskCirc].tBattler = battler; + gTasks[taskDgnl].tBattler = battler; + gTasks[taskCirc].tStarMove = SHINY_STAR_ENCIRCLE; + gTasks[taskDgnl].tStarMove = SHINY_STAR_DIAGONAL; + return; + } + } + + gBattleSpritesDataPtr->healthBoxesData[battler].field_1_x1 = 1; +} + +static void Task_ShinyStars(u8 taskId) +{ + u8 battler; + u8 x, y; + u8 spriteId; + u16 timer; + s16 starIdx; + u8 pan; + + if (gTasks[taskId].tTimer < 60) + { + gTasks[taskId].tTimer++; + return; + } + + // Wait until the ball particles have despawned + if (gBattleSpritesDataPtr->animationData->numBallParticles) + return; + + timer = gTasks[taskId].tStarTimer++; + if (timer % 4) // Create sprite 1 of every 4 frames + return; + + battler = gTasks[taskId].tBattler; + x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X); + y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y); + + starIdx = gTasks[taskId].tStarIdx; + if (starIdx == 0) // Big star + { + spriteId = CreateSprite(&gWishStarSpriteTemplate, x, y, 5); + } + else if (starIdx >= 0 && gTasks[taskId].tStarIdx < 4) // Medium star + { + spriteId = CreateSprite(&gMiniTwinklingStarSpriteTemplate, x, y, 5); + gSprites[spriteId].oam.tileNum += 4; + } + else // Small star + { + spriteId = CreateSprite(&gMiniTwinklingStarSpriteTemplate, x, y, 5); + gSprites[spriteId].oam.tileNum += 5; + } + + if (gTasks[taskId].tStarMove == SHINY_STAR_ENCIRCLE) + { + gSprites[spriteId].callback = SpriteCB_ShinyStars_Encircle; + } + else + { + gSprites[spriteId].callback = SpriteCB_ShinyStars_Diagonal; + gSprites[spriteId].pos2.x = -32; + gSprites[spriteId].pos2.y = 32; + gSprites[spriteId].invisible = TRUE; + if (gTasks[taskId].tStarIdx == 0) + { + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + pan = -64; + else + pan = 63; + + PlaySE12WithPanning(SE_REAPOKE, pan); + } + } + + gSprites[spriteId].sTaskId = taskId; + gTasks[taskId].tStarIdx++; + if (spriteId != MAX_SPRITES) + gTasks[taskId].tNumStars++; + + if (gTasks[taskId].tStarIdx == 5) + gTasks[taskId].func = Task_ShinyStars_Wait; +} + +static void Task_ShinyStars_Wait(u8 taskId) +{ + u8 battler; + + if (gTasks[taskId].tNumStars == 0) + { + if (gTasks[taskId].tStarMove == SHINY_STAR_DIAGONAL) + { + battler = gTasks[taskId].tBattler; + gBattleSpritesDataPtr->healthBoxesData[battler].field_1_x1 = 1; + } + + DestroyTask(taskId); + } +} + +static void SpriteCB_ShinyStars_Encircle(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->sPhase, 24); + sprite->pos2.y = Cos(sprite->sPhase, 24); + sprite->sPhase += 12; + if (sprite->sPhase > 255) + { + gTasks[sprite->sTaskId].tNumStars--; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } +} + +static void SpriteCB_ShinyStars_Diagonal(struct Sprite *sprite) +{ + // Delayed four frames to de-sync from encircling stars + if (sprite->sTimer < 4) + sprite->sTimer++; + else + { + sprite->invisible = FALSE; + sprite->pos2.x += 5; + sprite->pos2.y -= 5; + if (sprite->pos2.x > 32) + { + gTasks[sprite->sTaskId].tNumStars--; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } + } +} + +#undef tBattler +#undef tStarMove +#undef tStarTimer +#undef tStarIdx +#undef tNumStars +#undef tTimer + +#undef sTaskId +#undef sPhase +#undef sTimer + +void AnimTask_LoadPokeblockGfx(u8 taskId) +{ + u8 paletteIndex; + + LoadCompressedSpriteSheetUsingHeap(&gBattleAnimPicTable[ANIM_TAG_POKEBLOCK - ANIM_SPRITES_START]); + LoadCompressedSpritePaletteUsingHeap(&gBattleAnimPaletteTable[ANIM_TAG_POKEBLOCK - ANIM_SPRITES_START]); + paletteIndex = IndexOfSpritePaletteTag(ANIM_TAG_POKEBLOCK); // unused + DestroyAnimVisualTask(taskId); +} + +void AnimTask_FreePokeblockGfx(u8 taskId) +{ + FreeSpriteTilesByTag(ANIM_TAG_POKEBLOCK); + FreeSpritePaletteByTag(ANIM_TAG_POKEBLOCK); + DestroyAnimVisualTask(taskId); +} + +#define sDuration data[0] +#define sTargetX data[2] +#define sTargetY data[4] +#define sAmplitude data[5] + +static void SpriteCB_PokeBlock_Throw(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, 0); + sprite->sDuration = 30; + sprite->sTargetX = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), BATTLER_COORD_X) + gBattleAnimArgs[2]; + sprite->sTargetY = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), BATTLER_COORD_Y) + gBattleAnimArgs[3]; + sprite->sAmplitude = -32; + InitAnimArcTranslation(sprite); + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].callback = sub_8039E84; + sprite->callback = SpriteCB_PokeBlock_LiftArm; +} + +#undef sDuration +#undef sTargetX +#undef sTargetY +#undef sAmplitude + +static void SpriteCB_PokeBlock_LiftArm(struct Sprite *sprite) +{ + if (gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].animCmdIndex == 1) + sprite->callback = SpriteCB_PokeBlock_Arc; +} + +static void SpriteCB_PokeBlock_Arc(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + { + sprite->data[0] = 0; + sprite->invisible = TRUE; + sprite->callback = SpriteCB_ThrowPokeBlock_Free; + } +} + +// Destroy after end of player animation +static void SpriteCB_ThrowPokeBlock_Free(struct Sprite *sprite) +{ + if (gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].animEnded) + { + if (++sprite->data[0] > 0) + { + StartSpriteAnim(&gSprites[gBattlerSpriteIds[gBattleAnimAttacker]], 0); + DestroyAnimSprite(sprite); + } + } +} + +void AnimTask_SetAttackerTargetLeftPos(u8 taskId) +{ + switch (gBattleAnimArgs[0]) + { + case 0: + gBattleAnimAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + gBattleAnimTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + break; + case 1: + gBattleAnimAttacker = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + gBattleAnimTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + break; + } + + DestroyAnimVisualTask(taskId); +} + +void AnimTask_GetTrappedMoveAnimId(u8 taskId) +{ + if (gBattleSpritesDataPtr->animationData->animArg == MOVE_FIRE_SPIN) + gBattleAnimArgs[0] = TRAP_ANIM_FIRE_SPIN; + else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_WHIRLPOOL) + gBattleAnimArgs[0] = TRAP_ANIM_WHIRLPOOL; + else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_CLAMP) + gBattleAnimArgs[0] = TRAP_ANIM_CLAMP; + else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_SAND_TOMB) + gBattleAnimArgs[0] = TRAP_ANIM_SAND_TOMB; + else + gBattleAnimArgs[0] = TRAP_ANIM_BIND; + + DestroyAnimVisualTask(taskId); +} + +void AnimTask_GetBattlersFromArg(u8 taskId) +{ + gBattleAnimAttacker = gBattleSpritesDataPtr->animationData->animArg; + gBattleAnimTarget = gBattleSpritesDataPtr->animationData->animArg >> 8; + DestroyAnimVisualTask(taskId); +} diff --git a/src/battle_anim_special.c b/src/battle_anim_special.c deleted file mode 100755 index bf0d1d438..000000000 --- a/src/battle_anim_special.c +++ /dev/null @@ -1,2273 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_controllers.h" -#include "battle_interface.h" -#include "decompress.h" -#include "dma3.h" -#include "gpu_regs.h" -#include "graphics.h" -#include "m4a.h" -#include "main.h" -#include "palette.h" -#include "pokeball.h" -#include "sound.h" -#include "sprite.h" -#include "task.h" -#include "trig.h" -#include "util.h" -#include "constants/items.h" -#include "constants/moves.h" -#include "constants/songs.h" -#include "constants/rgb.h" - -// iwram -int gUnknown_030062DC; -u16 gUnknown_030062E0; -u16 gUnknown_030062E4; - -static void sub_8170660(u8); -static void sub_8170A38(u8); -static void sub_8170EF0(u8); -static void sub_8171104(struct Sprite *); -static void sub_8171030(u8); -static void sub_81710A8(u8); -static void sub_8171134(struct Sprite *); -static void sub_8171CAC(struct Sprite *); -static void sub_81711E8(struct Sprite *); -static void sub_8171240(struct Sprite *); -static void sub_817138C(struct Sprite *); -static void sub_81713D0(struct Sprite *); -static void sub_81717B4(struct Sprite *); -static void sub_81714D4(struct Sprite *); -static void sub_8171520(struct Sprite *); -static void sub_81717D8(struct Sprite *); -static void sub_8171AE4(struct Sprite *); -static void sub_81717F8(struct Sprite *); -static void sub_81719EC(struct Sprite *); -static void sub_81718D8(struct Sprite *); -static void sub_81719C0(struct Sprite *); -static void sub_8171D60(u8); -static void sub_8171AAC(struct Sprite *); -static void sub_8171BAC(struct Sprite *); -static void sub_8171CE8(struct Sprite *); -static void PokeBallOpenParticleAnimation_Step1(struct Sprite *); -static void PokeBallOpenParticleAnimation_Step2(struct Sprite *); -static void DestroyBallOpenAnimationParticle(struct Sprite *); -static void FanOutBallOpenParticles_Step1(struct Sprite *); -static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *); -static void PremierBallOpenParticleAnimation_Step1(struct Sprite *); -static void sub_8172AB0(u8); -static void sub_8172B40(u8); -static void sub_8172B90(u8); -static void sub_8172FEC(u8); -static void sub_81731FC(struct Sprite *); -static void sub_8173250(struct Sprite *); -static void sub_81731B0(u8); -static void sub_817339C(struct Sprite *); -static void sub_81733D4(struct Sprite *); -static void sub_8173400(struct Sprite *); -static void PokeBallOpenParticleAnimation(u8); -static void GreatBallOpenParticleAnimation(u8); -static void SafariBallOpenParticleAnimation(u8); -static void UltraBallOpenParticleAnimation(u8); -static void MasterBallOpenParticleAnimation(u8); -static void DiveBallOpenParticleAnimation(u8); -static void RepeatBallOpenParticleAnimation(u8); -static void TimerBallOpenParticleAnimation(u8); -static void PremierBallOpenParticleAnimation(u8); -static void sub_817330C(struct Sprite *); - -struct BallCaptureSuccessStarData -{ - s8 xOffset; - s8 yOffset; - s8 unk2; -}; - -static const struct BallCaptureSuccessStarData sBallCaptureSuccessStarData[] = -{ - { - .xOffset = 10, - .yOffset = 2, - .unk2 = -3, - }, - { - .xOffset = 15, - .yOffset = 0, - .unk2 = -4, - }, - { - .xOffset = -10, - .yOffset = 2, - .unk2 = -4, - }, -}; - -#define TAG_PARTICLES_POKEBALL 55020 -#define TAG_PARTICLES_GREATBALL 55021 -#define TAG_PARTICLES_SAFARIBALL 55022 -#define TAG_PARTICLES_ULTRABALL 55023 -#define TAG_PARTICLES_MASTERBALL 55024 -#define TAG_PARTICLES_NETBALL 55025 -#define TAG_PARTICLES_DIVEBALL 55026 -#define TAG_PARTICLES_NESTBALL 55027 -#define TAG_PARTICLES_REPEATBALL 55028 -#define TAG_PARTICLES_TIMERBALL 55029 -#define TAG_PARTICLES_LUXURYBALL 55030 -#define TAG_PARTICLES_PREMIERBALL 55031 - -const struct CompressedSpriteSheet gBallParticleSpritesheets[] = -{ - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_POKEBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_GREATBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_SAFARIBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_ULTRABALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_MASTERBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_NETBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_DIVEBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_NESTBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_REPEATBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_TIMERBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_LUXURYBALL}, - {gBattleAnimSpriteGfx_Particles, 0x100, TAG_PARTICLES_PREMIERBALL}, -}; - -const struct CompressedSpritePalette gBallParticlePalettes[] = -{ - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_POKEBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_GREATBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_SAFARIBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_ULTRABALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_MASTERBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_NETBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_DIVEBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_NESTBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_REPEATBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_TIMERBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_LUXURYBALL}, - {gBattleAnimSpritePal_CircleImpact, TAG_PARTICLES_PREMIERBALL}, -}; - -const union AnimCmd gAnim_RegularBall[] = -{ - ANIMCMD_FRAME(0, 1), - ANIMCMD_FRAME(1, 1), - ANIMCMD_FRAME(2, 1), - ANIMCMD_FRAME(0, 1, .hFlip = TRUE), - ANIMCMD_FRAME(2, 1), - ANIMCMD_FRAME(1, 1), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gAnim_MasterBall[] = -{ - ANIMCMD_FRAME(3, 1), - ANIMCMD_END, -}; - -const union AnimCmd gAnim_NetDiveBall[] = -{ - ANIMCMD_FRAME(4, 1), - ANIMCMD_END, -}; - -const union AnimCmd gAnim_NestBall[] = -{ - ANIMCMD_FRAME(5, 1), - ANIMCMD_END, -}; - -const union AnimCmd gAnim_LuxuryPremierBall[] = -{ - ANIMCMD_FRAME(6, 4), - ANIMCMD_FRAME(7, 4), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gAnim_UltraRepeatTimerBall[] = -{ - ANIMCMD_FRAME(7, 4), - ANIMCMD_END, -}; - -const union AnimCmd *const gAnims_BallParticles[] = -{ - gAnim_RegularBall, - gAnim_MasterBall, - gAnim_NetDiveBall, - gAnim_NestBall, - gAnim_LuxuryPremierBall, - gAnim_UltraRepeatTimerBall, -}; - -const u8 gBallParticleAnimNums[] = -{ - [BALL_POKE] = 0, - [BALL_GREAT] = 0, - [BALL_SAFARI] = 0, - [BALL_ULTRA] = 5, - [BALL_MASTER] = 1, - [BALL_NET] = 2, - [BALL_DIVE] = 2, - [BALL_NEST] = 3, - [BALL_REPEAT] = 5, - [BALL_TIMER] = 5, - [BALL_LUXURY] = 4, - [BALL_PREMIER] = 4, -}; - -const TaskFunc gBallParticleAnimationFuncs[] = -{ - PokeBallOpenParticleAnimation, - GreatBallOpenParticleAnimation, - SafariBallOpenParticleAnimation, - UltraBallOpenParticleAnimation, - MasterBallOpenParticleAnimation, - SafariBallOpenParticleAnimation, - DiveBallOpenParticleAnimation, - UltraBallOpenParticleAnimation, - RepeatBallOpenParticleAnimation, - TimerBallOpenParticleAnimation, - GreatBallOpenParticleAnimation, - PremierBallOpenParticleAnimation, -}; - -const struct SpriteTemplate gBallParticlesSpriteTemplates[] = -{ - { - .tileTag = TAG_PARTICLES_POKEBALL, - .paletteTag = TAG_PARTICLES_POKEBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_GREATBALL, - .paletteTag = TAG_PARTICLES_GREATBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_SAFARIBALL, - .paletteTag = TAG_PARTICLES_SAFARIBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_ULTRABALL, - .paletteTag = TAG_PARTICLES_ULTRABALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_MASTERBALL, - .paletteTag = TAG_PARTICLES_MASTERBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_NETBALL, - .paletteTag = TAG_PARTICLES_NETBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_DIVEBALL, - .paletteTag = TAG_PARTICLES_DIVEBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_NESTBALL, - .paletteTag = TAG_PARTICLES_NESTBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_REPEATBALL, - .paletteTag = TAG_PARTICLES_REPEATBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_TIMERBALL, - .paletteTag = TAG_PARTICLES_TIMERBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_LUXURYBALL, - .paletteTag = TAG_PARTICLES_LUXURYBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = TAG_PARTICLES_PREMIERBALL, - .paletteTag = TAG_PARTICLES_PREMIERBALL, - .oam = &gOamData_AffineOff_ObjNormal_8x8, - .anims = gAnims_BallParticles, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, -}; - -const u16 gBallOpenFadeColors[] = -{ - [BALL_POKE] = RGB(31, 22, 30), - [BALL_GREAT] = RGB(16, 23, 30), - [BALL_SAFARI] = RGB(23, 30, 20), - [BALL_ULTRA] = RGB(31, 31, 15), - [BALL_MASTER] = RGB(23, 20, 28), - [BALL_NET] = RGB(21, 31, 25), - [BALL_DIVE] = RGB(12, 25, 30), - [BALL_NEST] = RGB(30, 27, 10), - [BALL_REPEAT] = RGB(31, 24, 16), - [BALL_TIMER] = RGB(29, 30, 30), - [BALL_LUXURY] = RGB(31, 17, 10), - [BALL_PREMIER] = RGB(31, 9, 10), - - // Garbage data - RGB(0, 0, 0), - RGB(1, 16, 0), - RGB(3, 0, 1), - RGB(1, 8, 0), - RGB(0, 8, 0), - RGB(3, 8, 1), - RGB(6, 8, 1), - RGB(4, 0, 0), -}; - -const struct SpriteTemplate gPokeblockSpriteTemplate = -{ - .tileTag = ANIM_TAG_POKEBLOCK, - .paletteTag = ANIM_TAG_POKEBLOCK, - .oam = &gOamData_AffineOff_ObjNormal_16x16, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_817330C, -}; - -const union AnimCmd gUnknown_085E5350[] = -{ - ANIMCMD_FRAME(64, 1), - ANIMCMD_END, -}; - -const union AnimCmd *const gUnknown_085E5358[] = { - gUnknown_085E5350, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_085E535C = -{ - .tileTag = ANIM_TAG_ROCKS, - .paletteTag = ANIM_TAG_ROCKS, - .oam = &gOamData_AffineOff_ObjNormal_32x32, - .anims = gUnknown_085E5358, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_817330C, -}; - -extern const struct SpriteTemplate gWishStarSpriteTemplate; -extern const struct SpriteTemplate gMiniTwinklingStarSpriteTemplate; - -void unref_sub_8170478(u8 taskId) -{ - struct BattleAnimBgData unknownStruct; - u8 healthBoxSpriteId; - u8 battler; - u8 spriteId1, spriteId2, spriteId3, spriteId4; - - battler = gBattleAnimAttacker; - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); - SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); - SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); - SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); - SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 0); - SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); - SetAnimBgAttribute(1, BG_ANIM_AREA_OVERFLOW_MODE, 1); - SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); - - healthBoxSpriteId = gHealthboxSpriteIds[battler]; - spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; - spriteId2 = gSprites[healthBoxSpriteId].data[5]; - spriteId3 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); - spriteId4 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); - gSprites[healthBoxSpriteId].oam.priority = 1; - gSprites[spriteId1].oam.priority = 1; - gSprites[spriteId2].oam.priority = 1; - gSprites[spriteId3] = gSprites[healthBoxSpriteId]; - gSprites[spriteId4] = gSprites[spriteId1]; - gSprites[spriteId3].oam.objMode = ST_OAM_OBJ_WINDOW; - gSprites[spriteId4].oam.objMode = ST_OAM_OBJ_WINDOW; - gSprites[spriteId3].callback = SpriteCallbackDummy; - gSprites[spriteId4].callback = SpriteCallbackDummy; - - sub_80A6B30(&unknownStruct); - AnimLoadCompressedBgTilemap(unknownStruct.bgId, gUnknown_08C2EA9C); - AnimLoadCompressedBgGfx(unknownStruct.bgId, gUnknown_08C2EA50, unknownStruct.tilesOffset); - LoadCompressedPalette(gCureBubblesPal, unknownStruct.paletteId << 4, 32); - - gBattle_BG1_X = -gSprites[spriteId3].pos1.x + 32; - gBattle_BG1_Y = -gSprites[spriteId3].pos1.y - 32; - gTasks[taskId].data[1] = 640; - gTasks[taskId].data[0] = spriteId3; - gTasks[taskId].data[2] = spriteId4; - gTasks[taskId].func = sub_8170660; -} - -static void sub_8170660(u8 taskId) -{ - u8 spriteId1, spriteId2; - u8 battler; - - battler = gBattleAnimAttacker; - gTasks[taskId].data[13] += gTasks[taskId].data[1]; - gBattle_BG1_Y += (u16)gTasks[taskId].data[13] >> 8; - gTasks[taskId].data[13] &= 0xFF; - - switch (gTasks[taskId].data[15]) - { - case 0: - if (gTasks[taskId].data[11]++ > 1) - { - gTasks[taskId].data[11] = 0; - gTasks[taskId].data[12]++; - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); - if (gTasks[taskId].data[12] == 8) - gTasks[taskId].data[15]++; - } - break; - case 1: - if (++gTasks[taskId].data[10] == 30) - gTasks[taskId].data[15]++; - break; - case 2: - if (gTasks[taskId].data[11]++ > 1) - { - gTasks[taskId].data[11] = 0; - gTasks[taskId].data[12]--; - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[12], 16 - gTasks[taskId].data[12])); - if (gTasks[taskId].data[12] == 0) - { - sub_80A477C(0); - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); - SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); - if (!IsContest()) - SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); - - SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); - SetGpuReg(REG_OFFSET_BLDCNT, 0); - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0)); - DestroySprite(&gSprites[gTasks[taskId].data[0]]); - DestroySprite(&gSprites[gTasks[taskId].data[2]]); - SetAnimBgAttribute(1, BG_ANIM_AREA_OVERFLOW_MODE, 0); - spriteId1 = gSprites[gHealthboxSpriteIds[battler]].oam.affineParam; - spriteId2 = gSprites[gHealthboxSpriteIds[battler]].data[5]; - gSprites[gHealthboxSpriteIds[battler]].oam.priority = 1; - gSprites[spriteId1].oam.priority = 1; - gSprites[spriteId2].oam.priority = 1; - DestroyAnimVisualTask(taskId); - } - } - break; - } -} - -static void LoadHealthboxPalsForLevelUp(u8 *paletteId1, u8 *paletteId2, u8 battler) -{ - u8 healthBoxSpriteId; - u8 spriteId1, spriteId2; - u16 offset1, offset2; - - healthBoxSpriteId = gHealthboxSpriteIds[battler]; - spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; - spriteId2 = gSprites[healthBoxSpriteId].data[5]; - *paletteId1 = AllocSpritePalette(0xD709); - *paletteId2 = AllocSpritePalette(0xD70A); - - offset1 = (gSprites[healthBoxSpriteId].oam.paletteNum * 16) + 0x100; - offset2 = (gSprites[spriteId2].oam.paletteNum * 16) + 0x100; - LoadPalette(&gPlttBufferUnfaded[offset1], *paletteId1 * 16 + 0x100, 0x20); - LoadPalette(&gPlttBufferUnfaded[offset2], *paletteId2 * 16 + 0x100, 0x20); - - gSprites[healthBoxSpriteId].oam.paletteNum = *paletteId1; - gSprites[spriteId1].oam.paletteNum = *paletteId1; - gSprites[spriteId2].oam.paletteNum = *paletteId2; -} - -void AnimTask_LoadHealthboxPalsForLevelUp(u8 taskId) -{ - u8 paletteId1, paletteId2; - LoadHealthboxPalsForLevelUp(&paletteId1, &paletteId2, gBattleAnimAttacker); - DestroyAnimVisualTask(taskId); -} - -static void FreeHealthboxPalsForLevelUp(u8 battler) -{ - u8 healthBoxSpriteId; - u8 spriteId1, spriteId2; - u8 paletteId1, paletteId2; - - healthBoxSpriteId = gHealthboxSpriteIds[battler]; - spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; - spriteId2 = gSprites[healthBoxSpriteId].data[5]; - - FreeSpritePaletteByTag(0xD709); - FreeSpritePaletteByTag(0xD70A); - paletteId1 = IndexOfSpritePaletteTag(0xD6FF); - paletteId2 = IndexOfSpritePaletteTag(0xD704); - gSprites[healthBoxSpriteId].oam.paletteNum = paletteId1; - gSprites[spriteId1].oam.paletteNum = paletteId1; - gSprites[spriteId2].oam.paletteNum = paletteId2; -} - -void AnimTask_FreeHealthboxPalsForLevelUp(u8 taskId) -{ - FreeHealthboxPalsForLevelUp(gBattleAnimAttacker); - DestroyAnimVisualTask(taskId); -} - -void AnimTask_FlashHealthboxOnLevelUp(u8 taskId) -{ - gTasks[taskId].data[10] = gBattleAnimArgs[0]; - gTasks[taskId].data[11] = gBattleAnimArgs[1]; - gTasks[taskId].func = sub_8170A38; -} - -static void sub_8170A38(u8 taskId) -{ - u8 paletteNum; - int paletteOffset, colorOffset; - - gTasks[taskId].data[0]++; - if (gTasks[taskId].data[0]++ >= gTasks[taskId].data[11]) - { - gTasks[taskId].data[0] = 0; - paletteNum = IndexOfSpritePaletteTag(0xD709); - colorOffset = gTasks[taskId].data[10] == 0 ? 6 : 2; - switch (gTasks[taskId].data[1]) - { - case 0: - gTasks[taskId].data[2] += 2; - if (gTasks[taskId].data[2] > 16) - gTasks[taskId].data[2] = 16; - - paletteOffset = paletteNum * 16 + 0x100; - BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); - if (gTasks[taskId].data[2] == 16) - gTasks[taskId].data[1]++; - break; - case 1: - gTasks[taskId].data[2] -= 2; - if (gTasks[taskId].data[2] < 0) - gTasks[taskId].data[2] = 0; - - paletteOffset = paletteNum * 16 + 0x100; - BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); - if (gTasks[taskId].data[2] == 0) - DestroyAnimVisualTask(taskId); - break; - } - } -} - -void AnimTask_SwitchOutShrinkMon(u8 taskId) -{ - u8 spriteId; - - spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; - switch (gTasks[taskId].data[0]) - { - case 0: - PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); - gTasks[taskId].data[10] = 0x100; - gTasks[taskId].data[0]++; - break; - case 1: - gTasks[taskId].data[10] += 0x30; - SetSpriteRotScale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); - SetBattlerSpriteYOffsetFromYScale(spriteId); - if (gTasks[taskId].data[10] >= 0x2D0) - gTasks[taskId].data[0]++; - break; - case 2: - ResetSpriteRotScale(spriteId); - gSprites[spriteId].invisible = TRUE; - DestroyAnimVisualTask(taskId); - break; - } -} - -void AnimTask_SwitchOutBallEffect(u8 taskId) -{ - u8 spriteId; - u16 ball; - u8 ballId; - u8 x, y; - u8 priority, subpriority; - u32 selectedPalettes; - - spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - ball = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); - else - ball = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); - - ballId = ItemIdToBallId(ball); - switch (gTasks[taskId].data[0]) - { - case 0: - x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); - y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); - priority = gSprites[spriteId].oam.priority; - subpriority = gSprites[spriteId].subpriority; - gTasks[taskId].data[10] = AnimateBallOpenParticles(x, y + 32, priority, subpriority, ballId); - selectedPalettes = sub_80A75AC(1, 0, 0, 0, 0, 0, 0); - gTasks[taskId].data[11] = LaunchBallFadeMonTask(0, gBattleAnimAttacker, selectedPalettes, ballId); - gTasks[taskId].data[0]++; - break; - case 1: - if (!gTasks[gTasks[taskId].data[10]].isActive && !gTasks[gTasks[taskId].data[11]].isActive) - DestroyAnimVisualTask(taskId); - break; - } -} - -void AnimTask_LoadBallGfx(u8 taskId) -{ - u8 ballId = ItemIdToBallId(gLastUsedItem); - LoadBallGfx(ballId); - DestroyAnimVisualTask(taskId); -} - -void AnimTask_FreeBallGfx(u8 taskId) -{ - u8 ballId = ItemIdToBallId(gLastUsedItem); - FreeBallGfx(ballId); - DestroyAnimVisualTask(taskId); -} - -void AnimTask_IsBallBlockedByTrainer(u8 taskId) -{ - if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_TRAINER_BLOCK) - gBattleAnimArgs[ARG_RET_ID] = -1; - else - gBattleAnimArgs[ARG_RET_ID] = 0; - - DestroyAnimVisualTask(taskId); -} - -u8 ItemIdToBallId(u16 ballItem) -{ - switch (ballItem) - { - case ITEM_MASTER_BALL: - return BALL_MASTER; - case ITEM_ULTRA_BALL: - return BALL_ULTRA; - case ITEM_GREAT_BALL: - return BALL_GREAT; - case ITEM_SAFARI_BALL: - return BALL_SAFARI; - case ITEM_NET_BALL: - return BALL_NET; - case ITEM_DIVE_BALL: - return BALL_DIVE; - case ITEM_NEST_BALL: - return BALL_NEST; - case ITEM_REPEAT_BALL: - return BALL_REPEAT; - case ITEM_TIMER_BALL: - return BALL_TIMER; - case ITEM_LUXURY_BALL: - return BALL_LUXURY; - case ITEM_PREMIER_BALL: - return BALL_PREMIER; - case ITEM_POKE_BALL: - default: - return BALL_POKE; - } -} - -void AnimTask_ThrowBall(u8 taskId) -{ - u8 ballId; - u8 spriteId; - - ballId = ItemIdToBallId(gLastUsedItem); - spriteId = CreateSprite(&gBallSpriteTemplates[ballId], 32, 80, 29); - gSprites[spriteId].data[0] = 34; - gSprites[spriteId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 0); - gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) - 16; - gSprites[spriteId].callback = sub_8171104; - gBattleSpritesDataPtr->animationData->field_9_x2 = gSprites[gBattlerSpriteIds[gBattleAnimTarget]].invisible; - gTasks[taskId].data[0] = spriteId; - gTasks[taskId].func = sub_8170EF0; -} - -static void sub_8170EF0(u8 taskId) -{ - u8 spriteId = gTasks[taskId].data[0]; - if ((u16)gSprites[spriteId].data[0] == 0xFFFF) - DestroyAnimVisualTask(taskId); -} - -// Safari Ball / Wally's ball throw -void AnimTask_ThrowBallSpecial(u8 taskId) -{ - int x, y; - u8 ballId; - u8 subpriority; - u8 spriteId; - - if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) - { - x = 32; - y = 11; - } - else - { - x = 23; - y = 5; - } - - ballId = ItemIdToBallId(gLastUsedItem); - subpriority = GetBattlerSpriteSubpriority(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)) + 1; - spriteId = CreateSprite(&gBallSpriteTemplates[ballId], x + 32, y | 80, subpriority); - gSprites[spriteId].data[0] = 34; - gSprites[spriteId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 0); - gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) - 16; - gSprites[spriteId].callback = SpriteCallbackDummy; - gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].callback = sub_8039E84; - gTasks[taskId].data[0] = spriteId; - gTasks[taskId].func = sub_8171030; -} - -static void sub_8171030(u8 taskId) -{ - if (gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animCmdIndex == 1) - { - PlaySE12WithPanning(SE_NAGERU, 0); - gSprites[gTasks[taskId].data[0]].callback = sub_8171104; - CreateTask(sub_81710A8, 10); - gTasks[taskId].func = sub_8170EF0; - } -} - -static void sub_81710A8(u8 taskId) -{ - if (gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animEnded) - { - StartSpriteAnim(&gSprites[gBattlerSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]], 0); - DestroyTask(taskId); - } -} - -static void sub_8171104(struct Sprite *sprite) -{ - u16 temp = sprite->data[1]; - u16 temp2 = sprite->data[2]; - sprite->data[1] = sprite->pos1.x; - sprite->data[2] = temp; - sprite->data[3] = sprite->pos1.y; - sprite->data[4] = temp2; - sprite->data[5] = -40; - InitAnimArcTranslation(sprite); - sprite->callback = sub_8171134; -} - -static void sub_8171134(struct Sprite *sprite) -{ - int i; - u8 ballId; - - if (TranslateAnimHorizontalArc(sprite)) - { - if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_TRAINER_BLOCK) - { - sprite->callback = sub_8171CAC; - } - else - { - StartSpriteAnim(sprite, 1); - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.x = 0; - sprite->pos2.y = 0; - - for (i = 0; i < 8; i++) - sprite->data[i] = 0; - - sprite->data[5] = 0; - sprite->callback = sub_81711E8; - - ballId = ItemIdToBallId(gLastUsedItem); - switch (ballId) - { - case 0 ... POKEBALL_COUNT - 1: - AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballId); - LaunchBallFadeMonTask(0, gBattleAnimTarget, 14, ballId); - break; - } - } - } -} - -static void sub_81711E8(struct Sprite *sprite) -{ - if (++sprite->data[5] == 10) - { - sprite->data[5] = CreateTask(TaskDummy, 50); - sprite->callback = sub_8171240; - gSprites[gBattlerSpriteIds[gBattleAnimTarget]].data[1] = 0; - } -} - -static void sub_8171240(struct Sprite *sprite) -{ - u8 spriteId; - u8 taskId; - - spriteId = gBattlerSpriteIds[gBattleAnimTarget]; - taskId = sprite->data[5]; - - if (++gTasks[taskId].data[1] == 11) - PlaySE(SE_SUIKOMU); - - switch (gTasks[taskId].data[0]) - { - case 0: - PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); - gTasks[taskId].data[10] = 256; - gUnknown_030062DC = 28; - gUnknown_030062E4 = (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) - (sprite->pos1.y + sprite->pos2.y); - gUnknown_030062E0 = (u32)(gUnknown_030062E4 * 256) / 28; - gTasks[taskId].data[2] = gUnknown_030062E0; - gTasks[taskId].data[0]++; - break; - case 1: - gTasks[taskId].data[10] += 0x20; - SetSpriteRotScale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); - gTasks[taskId].data[3] += gTasks[taskId].data[2]; - gSprites[spriteId].pos2.y = -gTasks[taskId].data[3] >> 8; - if (gTasks[taskId].data[10] >= 0x480) - gTasks[taskId].data[0]++; - break; - case 2: - ResetSpriteRotScale(spriteId); - gSprites[spriteId].invisible = TRUE; - gTasks[taskId].data[0]++; - break; - default: - if (gTasks[taskId].data[1] > 10) - { - DestroyTask(taskId); - StartSpriteAnim(sprite, 2); - sprite->data[5] = 0; - sprite->callback = sub_817138C; - } - break; - } -} - -static void sub_817138C(struct Sprite *sprite) -{ - int angle; - - if (sprite->animEnded) - { - sprite->data[3] = 0; - sprite->data[4] = 40; - sprite->data[5] = 0; - angle = 0; - sprite->pos1.y += Cos(angle, 40); - sprite->pos2.y = -Cos(angle, sprite->data[4]); - sprite->callback = sub_81713D0; - } -} - -static void sub_81713D0(struct Sprite *sprite) -{ - bool8 lastBounce; - int bounceCount; - - lastBounce = 0; - - switch (sprite->data[3] & 0xFF) - { - case 0: - sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); - sprite->data[5] += (sprite->data[3] >> 8) + 4; - if (sprite->data[5] >= 64) - { - sprite->data[4] -= 10; - sprite->data[3] += 257; - - bounceCount = sprite->data[3] >> 8; - if (bounceCount == 4) - lastBounce = 1; - - // Play a different sound effect for each pokeball bounce. - switch (bounceCount) - { - case 1: - PlaySE(SE_KON); - break; - case 2: - PlaySE(SE_KON2); - break; - case 3: - PlaySE(SE_KON3); - break; - default: - PlaySE(SE_KON4); - break; - } - } - break; - case 1: - sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); - sprite->data[5] -= (sprite->data[3] >> 8) + 4; - if (sprite->data[5] <= 0) - { - sprite->data[5] = 0; - sprite->data[3] &= -0x100; - } - break; - } - - if (lastBounce) - { - sprite->data[3] = 0; - sprite->pos1.y += Cos(64, 40); - sprite->pos2.y = 0; - if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_NO_SHAKES) - { - sprite->data[5] = 0; - sprite->callback = sub_81717B4; - } - else - { - sprite->callback = sub_81714D4; - sprite->data[4] = 1; - sprite->data[5] = 0; - } - } -} - -static void sub_81714D4(struct Sprite *sprite) -{ - if (++sprite->data[3] == 31) - { - sprite->data[3] = 0; - sprite->affineAnimPaused = 1; - StartSpriteAffineAnim(sprite, 1); - gBattleSpritesDataPtr->animationData->field_C = 0; - sprite->callback = sub_8171520; - PlaySE(SE_BOWA); - } -} - -static void sub_8171520(struct Sprite *sprite) -{ - s8 state; - u16 var0; - - switch (sprite->data[3] & 0xFF) - { - case 0: - if (gBattleSpritesDataPtr->animationData->field_C > 0xFF) - { - sprite->pos2.x += sprite->data[4]; - gBattleSpritesDataPtr->animationData->field_C &= 0xFF; - } - else - { - gBattleSpritesDataPtr->animationData->field_C += 0xB0; - } - - sprite->data[5]++; - sprite->affineAnimPaused = 0; - var0 = sprite->data[5] + 7; - if (var0 > 14) - { - gBattleSpritesDataPtr->animationData->field_C = 0; - sprite->data[3]++; - sprite->data[5] = 0; - } - break; - case 1: - if (++sprite->data[5] == 1) - { - sprite->data[5] = 0; - sprite->data[4] = -sprite->data[4]; - sprite->data[3]++; - sprite->affineAnimPaused = 0; - if (sprite->data[4] < 0) - ChangeSpriteAffineAnim(sprite, 2); - else - ChangeSpriteAffineAnim(sprite, 1); - } - else - { - sprite->affineAnimPaused = 1; - } - break; - case 2: - if (gBattleSpritesDataPtr->animationData->field_C > 0xFF) - { - sprite->pos2.x += sprite->data[4]; - gBattleSpritesDataPtr->animationData->field_C &= 0xFF; - } - else - { - gBattleSpritesDataPtr->animationData->field_C += 0xB0; - } - - sprite->data[5]++; - sprite->affineAnimPaused = 0; - var0 = sprite->data[5] + 12; - if (var0 > 24) - { - gBattleSpritesDataPtr->animationData->field_C = 0; - sprite->data[3]++; - sprite->data[5] = 0; - } - break; - case 3: - if (sprite->data[5]++ < 0) - { - sprite->affineAnimPaused = 1; - break; - } - - sprite->data[5] = 0; - sprite->data[4] = -sprite->data[4]; - sprite->data[3]++; - sprite->affineAnimPaused = 0; - if (sprite->data[4] < 0) - ChangeSpriteAffineAnim(sprite, 2); - else - ChangeSpriteAffineAnim(sprite, 1); - // fall through - case 4: - if (gBattleSpritesDataPtr->animationData->field_C > 0xFF) - { - sprite->pos2.x += sprite->data[4]; - gBattleSpritesDataPtr->animationData->field_C &= 0xFF; - } - else - { - gBattleSpritesDataPtr->animationData->field_C += 0xB0; - } - - sprite->data[5]++; - sprite->affineAnimPaused = 0; - var0 = sprite->data[5] + 4; - if (var0 > 8) - { - gBattleSpritesDataPtr->animationData->field_C = 0; - sprite->data[3]++; - sprite->data[5] = 0; - sprite->data[4] = -sprite->data[4]; - } - break; - case 5: - sprite->data[3] += 0x100; - state = sprite->data[3] >> 8; - if (state == gBattleSpritesDataPtr->animationData->ballThrowCaseId) - { - sprite->affineAnimPaused = 1; - sprite->callback = sub_81717B4; - } - else - { - if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_3_SHAKES_SUCCESS && state == 3) - { - sprite->callback = sub_81717D8; - sprite->affineAnimPaused = 1; - } - else - { - sprite->data[3]++; - sprite->affineAnimPaused = 1; - } - } - break; - case 6: - default: - if (++sprite->data[5] == 31) - { - sprite->data[5] = 0; - sprite->data[3] &= -0x100; - StartSpriteAffineAnim(sprite, 3); - if (sprite->data[4] < 0) - StartSpriteAffineAnim(sprite, 2); - else - StartSpriteAffineAnim(sprite, 1); - - PlaySE(SE_BOWA); - } - break; - } -} - -static void sub_81717B4(struct Sprite *sprite) -{ - if (++sprite->data[5] == 31) - { - sprite->data[5] = 0; - sprite->callback = sub_8171AE4; - } -} - -static void sub_81717D8(struct Sprite *sprite) -{ - sprite->animPaused = 1; - sprite->callback = sub_81717F8; - sprite->data[3] = 0; - sprite->data[4] = 0; - sprite->data[5] = 0; -} - -static void sub_81717F8(struct Sprite *sprite) -{ - u8 *battler = &gBattleAnimTarget; - - sprite->data[4]++; - if (sprite->data[4] == 40) - { - PlaySE(SE_RG_GETTING); - BlendPalettes(0x10000 << sprite->oam.paletteNum, 6, RGB(0, 0, 0)); - sub_81719EC(sprite); - } - else if (sprite->data[4] == 60) - { - BeginNormalPaletteFade(0x10000 << sprite->oam.paletteNum, 2, 6, 0, RGB(0, 0, 0)); - } - else if (sprite->data[4] == 95) - { - gDoingBattleAnim = 0; - UpdateOamPriorityInAllHealthboxes(1); - m4aMPlayAllStop(); - PlaySE(MUS_RG_FAN6); - } - else if (sprite->data[4] == 315) - { - FreeOamMatrix(gSprites[gBattlerSpriteIds[*battler]].oam.matrixNum); - DestroySprite(&gSprites[gBattlerSpriteIds[*battler]]); - sprite->data[0] = 0; - sprite->callback = sub_81718D8; - } -} - -static void sub_81718D8(struct Sprite *sprite) -{ - u8 paletteIndex; - - switch (sprite->data[0]) - { - case 0: - sprite->data[1] = 0; - sprite->data[2] = 0; - sprite->oam.objMode = ST_OAM_OBJ_BLEND; - SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); - paletteIndex = IndexOfSpritePaletteTag(sprite->template->paletteTag); - BeginNormalPaletteFade(1 << (paletteIndex + 0x10), 0, 0, 16, RGB(31, 31, 31)); - sprite->data[0]++; - break; - case 1: - if (sprite->data[1]++ > 0) - { - sprite->data[1] = 0; - sprite->data[2]++; - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[2], sprite->data[2])); - if (sprite->data[2] == 16) - sprite->data[0]++; - } - break; - case 2: - sprite->invisible = TRUE; - sprite->data[0]++; - break; - default: - if (!gPaletteFade.active) - { - SetGpuReg(REG_OFFSET_BLDCNT, 0); - SetGpuReg(REG_OFFSET_BLDALPHA, 0); - sprite->data[0] = 0; - sprite->callback = sub_81719C0; - } - break; - } -} - -static void sub_81719C0(struct Sprite *sprite) -{ - if (sprite->data[0] == 0) - { - sprite->data[0] = -1; - } - else - { - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } -} - -static void sub_81719EC(struct Sprite *sprite) -{ - u32 i; - u8 subpriority; - - if (sprite->subpriority) - { - subpriority = sprite->subpriority - 1; - } - else - { - subpriority = 0; - sprite->subpriority = 1; - } - - sub_8171D60(4); - for (i = 0; i < 3; i++) - { - u8 spriteId = CreateSprite(&gBallParticlesSpriteTemplates[4], sprite->pos1.x, sprite->pos1.y, subpriority); - if (spriteId != MAX_SPRITES) - { - gSprites[spriteId].data[0] = 24; - gSprites[spriteId].data[2] = sprite->pos1.x + sBallCaptureSuccessStarData[i].xOffset; - gSprites[spriteId].data[4] = sprite->pos1.y + sBallCaptureSuccessStarData[i].yOffset; - gSprites[spriteId].data[5] = sBallCaptureSuccessStarData[i].unk2; - InitAnimArcTranslation(&gSprites[spriteId]); - gSprites[spriteId].callback = sub_8171AAC; - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[4]); - } - } -} - -static void sub_8171AAC(struct Sprite *sprite) -{ - sprite->invisible = !sprite->invisible; - if (TranslateAnimHorizontalArc(sprite)) - DestroySprite(sprite); -} - -static void sub_8171AE4(struct Sprite *sprite) -{ - u8 ballId; - - StartSpriteAnim(sprite, 1); - StartSpriteAffineAnim(sprite, 0); - sprite->callback = sub_8171BAC; - - ballId = ItemIdToBallId(gLastUsedItem); - switch (ballId) - { - case 0 ... POKEBALL_COUNT - 1: - AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballId); - LaunchBallFadeMonTask(1, gBattleAnimTarget, 14, ballId); - break; - } - - gSprites[gBattlerSpriteIds[gBattleAnimTarget]].invisible = FALSE; - StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimTarget]], 1); - AnimateSprite(&gSprites[gBattlerSpriteIds[gBattleAnimTarget]]); - gSprites[gBattlerSpriteIds[gBattleAnimTarget]].data[1] = 0x1000; -} - -static void sub_8171BAC(struct Sprite *sprite) -{ - int next = FALSE; - - if (sprite->animEnded) - sprite->invisible = TRUE; - - if (gSprites[gBattlerSpriteIds[gBattleAnimTarget]].affineAnimEnded) - { - StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimTarget]], 0); - next = TRUE; - } - else - { - gSprites[gBattlerSpriteIds[gBattleAnimTarget]].data[1] -= 288; - gSprites[gBattlerSpriteIds[gBattleAnimTarget]].pos2.y = gSprites[gBattlerSpriteIds[gBattleAnimTarget]].data[1] >> 8; - } - - if (sprite->animEnded && next) - { - gSprites[gBattlerSpriteIds[gBattleAnimTarget]].pos2.y = 0; - gSprites[gBattlerSpriteIds[gBattleAnimTarget]].invisible = gBattleSpritesDataPtr->animationData->field_9_x2; - sprite->data[0] = 0; - sprite->callback = sub_81719C0; - gDoingBattleAnim = 0; - UpdateOamPriorityInAllHealthboxes(1); - } -} - -static void sub_8171CAC(struct Sprite *sprite) -{ - int i; - - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - for (i = 0; i < 6; i++) - sprite->data[i] = 0; - - sprite->callback = sub_8171CE8; -} - -static void sub_8171CE8(struct Sprite *sprite) -{ - s16 var0 = sprite->data[0] + 0x800; - s16 var1 = sprite->data[1] + 0x680; - sprite->pos2.x -= var1 >> 8; - sprite->pos2.y += var0 >> 8; - sprite->data[0] = (sprite->data[0] + 0x800) & 0xFF; - sprite->data[1] = (sprite->data[1] + 0x680) & 0xFF; - - if (sprite->pos1.y + sprite->pos2.y > 160 - || sprite->pos1.x + sprite->pos2.x < -8) - { - sprite->data[0] = 0; - sprite->callback = sub_81719C0; - gDoingBattleAnim = 0; - UpdateOamPriorityInAllHealthboxes(1); - } -} - -static void sub_8171D60(u8 ballId) -{ - u8 taskId; - - if (GetSpriteTileStartByTag(gBallParticleSpritesheets[ballId].tag) == 0xFFFF) - { - LoadCompressedSpriteSheetUsingHeap(&gBallParticleSpritesheets[ballId]); - LoadCompressedSpritePaletteUsingHeap(&gBallParticlePalettes[ballId]); - } -} - -u8 AnimateBallOpenParticles(u8 x, u8 y, u8 priority, u8 subpriority, u8 ballId) -{ - u8 taskId; - - sub_8171D60(ballId); - taskId = CreateTask(gBallParticleAnimationFuncs[ballId], 5); - gTasks[taskId].data[1] = x; - gTasks[taskId].data[2] = y; - gTasks[taskId].data[3] = priority; - gTasks[taskId].data[4] = subpriority; - gTasks[taskId].data[15] = ballId; - PlaySE(SE_BOWA2); - - return taskId; -} - -void sub_8171E20(void) -{ - if (gMain.inBattle) - gBattleSpritesDataPtr->animationData->field_A++; -} - -static void PokeBallOpenParticleAnimation(u8 taskId) -{ - u8 spriteId; - u8 x, y; - u8 priority, subpriority; - u8 ballId; - u8 var0; - - ballId = gTasks[taskId].data[15]; - if (gTasks[taskId].data[0] < 16) - { - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = PokeBallOpenParticleAnimation_Step1; - gSprites[spriteId].oam.priority = priority; - - var0 = (u8)gTasks[taskId].data[0]; - if (var0 >= 8) - var0 -= 8; - - gSprites[spriteId].data[0] = var0 * 32; - } - - if (gTasks[taskId].data[0] == 15) - { - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); - return; - } - } - - gTasks[taskId].data[0]++; -} - -static void PokeBallOpenParticleAnimation_Step1(struct Sprite *sprite) -{ - if (sprite->data[1] == 0) - sprite->callback = PokeBallOpenParticleAnimation_Step2; - else - sprite->data[1]--; -} - -static void PokeBallOpenParticleAnimation_Step2(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], sprite->data[1]); - sprite->data[1] += 2; - if (sprite->data[1] == 50) - DestroyBallOpenAnimationParticle(sprite); -} - -static void TimerBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 10; - gSprites[spriteId].data[5] = 2; - gSprites[spriteId].data[6] = 1; - } - } - - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); -} - -static void DiveBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 10; - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 2; - } - } - - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); -} - -// Also used for Net Ball -static void SafariBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 4; - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 1; - } - } - - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); -} - -// Also used for Nest Ball -static void UltraBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 10; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 25; - gSprites[spriteId].data[4] = 5; - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 1; - } - } - - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); -} - -// Also used for Luxury Ball -static void GreatBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - if (gTasks[taskId].data[7]) - { - gTasks[taskId].data[7]--; - } - else - { - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 8; - gSprites[spriteId].data[5] = 2; - gSprites[spriteId].data[6] = 2; - } - } - - gTasks[taskId].data[7] = 8; - if (++gTasks[taskId].data[0] == 2) - { - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); - } - } -} - -static void FanOutBallOpenParticles_Step1(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], sprite->data[2]); - sprite->data[0] = (sprite->data[0] + sprite->data[4]) & 0xFF; - sprite->data[1] += sprite->data[5]; - sprite->data[2] += sprite->data[6]; - if (++sprite->data[3] == 51) - DestroyBallOpenAnimationParticle(sprite); -} - -static void RepeatBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < POKEBALL_COUNT; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = RepeatBallOpenParticleAnimation_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 21; - } - } - - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); -} - -static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0], sprite->data[2])); - sprite->data[0] = (sprite->data[0] + 6) & 0xFF; - sprite->data[1]++; - sprite->data[2]++; - if (++sprite->data[3] == 51) - DestroyBallOpenAnimationParticle(sprite); -} - -static void MasterBallOpenParticleAnimation(u8 taskId) -{ - u8 i, j; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (j = 0; j < 2; j++) - { - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 8; - - if (j == 0) - { - gSprites[spriteId].data[5] = 2; - gSprites[spriteId].data[6] = 1; - } - else - { - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 2; - } - } - } - } - - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); -} - -static void PremierBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballId; - u8 spriteId; - - ballId = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gBallParticlesSpriteTemplates[ballId], x, y, subpriority); - if (spriteId != MAX_SPRITES) - { - sub_8171E20(); - StartSpriteAnim(&gSprites[spriteId], gBallParticleAnimNums[ballId]); - gSprites[spriteId].callback = PremierBallOpenParticleAnimation_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - } - } - - if (!gMain.inBattle) - gSprites[spriteId].data[7] = 1; - - DestroyTask(taskId); -} - -static void PremierBallOpenParticleAnimation_Step1(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0] & 0x3F, sprite->data[2])); - sprite->data[0] = (sprite->data[0] + 10) & 0xFF; - sprite->data[1]++; - sprite->data[2]++; - if (++sprite->data[3] == 51) - DestroyBallOpenAnimationParticle(sprite); -} - -static void DestroyBallOpenAnimationParticle(struct Sprite *sprite) -{ - int i, j; - - if (!gMain.inBattle) - { - if (sprite->data[7] == 1) - DestroySpriteAndFreeResources(sprite); - else - DestroySprite(sprite); - } - else - { - gBattleSpritesDataPtr->animationData->field_A--; - if (gBattleSpritesDataPtr->animationData->field_A == 0) - { - for (i = 0; i < POKEBALL_COUNT; i++) - { - if (FuncIsActiveTask(gBallParticleAnimationFuncs[i]) == TRUE) - break; - } - - if (i == POKEBALL_COUNT) - { - for (j = 0; j < POKEBALL_COUNT; j++) - { - FreeSpriteTilesByTag(gBallParticleSpritesheets[j].tag); - FreeSpritePaletteByTag(gBallParticlePalettes[j].tag); - } - } - - DestroySprite(sprite); - } - else - { - DestroySprite(sprite); - } - } -} - -u8 LaunchBallFadeMonTask(u8 unfadeLater, u8 battler, u32 selectedPalettes, u8 ballId) -{ - u8 taskId; - - taskId = CreateTask(sub_8172AB0, 5); - gTasks[taskId].data[15] = ballId; - gTasks[taskId].data[3] = battler; - gTasks[taskId].data[10] = selectedPalettes; - gTasks[taskId].data[11] = selectedPalettes >> 16; - - if (!unfadeLater) - { - BlendPalette(battler * 16 + 0x100, 16, 0, gBallOpenFadeColors[ballId]); - gTasks[taskId].data[1] = 1; - } - else - { - BlendPalette(battler * 16 + 0x100, 16, 16, gBallOpenFadeColors[ballId]); - gTasks[taskId].data[0] = 16; - gTasks[taskId].data[1] = -1; - gTasks[taskId].func = sub_8172B40; - } - - BeginNormalPaletteFade(selectedPalettes, 0, 0, 16, RGB(31, 31, 31)); - return taskId; -} - -static void sub_8172AB0(u8 taskId) -{ - u8 ballId = gTasks[taskId].data[15]; - - if (gTasks[taskId].data[2] <= 16) - { - BlendPalette(gTasks[taskId].data[3] * 16 + 0x100, 16, gTasks[taskId].data[0], gBallOpenFadeColors[ballId]); - gTasks[taskId].data[0] += gTasks[taskId].data[1]; - gTasks[taskId].data[2]++; - } - else if (!gPaletteFade.active) - { - u32 selectedPalettes = (u16)gTasks[taskId].data[10] | ((u16)gTasks[taskId].data[11] << 16); - BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB(31, 31, 31)); - DestroyTask(taskId); - } -} - -static void sub_8172B40(u8 taskId) -{ - if (!gPaletteFade.active) - { - u32 selectedPalettes = (u16)gTasks[taskId].data[10] | ((u16)gTasks[taskId].data[11] << 16); - BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB(31, 31, 31)); - gTasks[taskId].func = sub_8172B90; - } -} - -static void sub_8172B90(u8 taskId) -{ - u8 ballId = gTasks[taskId].data[15]; - - if (gTasks[taskId].data[2] <= 16) - { - BlendPalette(gTasks[taskId].data[3] * 16 + 0x100, 16, gTasks[taskId].data[0], gBallOpenFadeColors[ballId]); - gTasks[taskId].data[0] += gTasks[taskId].data[1]; - gTasks[taskId].data[2]++; - } - else - { - DestroyTask(taskId); - } -} - -// arg0: TRUE to swap to mon, FALSE to swap to substitute -void AnimTask_SwapMonSpriteToFromSubstitute(u8 taskId) -{ - u8 spriteId; - u32 x; - u32 done = FALSE; - - spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; - switch (gTasks[taskId].data[10]) - { - case 0: - gTasks[taskId].data[11] = gBattleAnimArgs[0]; - gTasks[taskId].data[0] += 0x500; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; - else - gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; - - gTasks[taskId].data[0] &= 0xFF; - x = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x + 32; - if (x > 304) - gTasks[taskId].data[10]++; - break; - case 1: - LoadBattleMonGfxAndAnimate(gBattleAnimAttacker, gTasks[taskId].data[11], spriteId); - gTasks[taskId].data[10]++; - break; - case 2: - gTasks[taskId].data[0] += 0x500; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; - else - gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; - - gTasks[taskId].data[0] &= 0xFF; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - { - if (gSprites[spriteId].pos2.x <= 0) - { - gSprites[spriteId].pos2.x = 0; - done = TRUE; - } - } - else - { - if (gSprites[spriteId].pos2.x >= 0) - { - gSprites[spriteId].pos2.x = 0; - done = TRUE; - } - } - - if (done) - DestroyAnimVisualTask(taskId); - - break; - } -} - -void AnimTask_SubstituteFadeToInvisible(u8 taskId) -{ - u8 spriteId; - - switch (gTasks[taskId].data[15]) - { - case 0: - if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == B_POSITION_OPPONENT_LEFT) - SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); - else - SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); - - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); - gTasks[taskId].data[15]++; - break; - case 1: - if (gTasks[taskId].data[1]++ > 1) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - gTasks[taskId].data[0], gTasks[taskId].data[0])); - if (gTasks[taskId].data[0] == 16) - gTasks[taskId].data[15]++; - } - break; - case 2: - spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; - RequestDma3Fill(0, (void *)OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * TILE_SIZE_4BPP, 0x800, 1); - ClearBehindSubstituteBit(gBattleAnimAttacker); - DestroyAnimVisualTask(taskId); - break; - } -} - -void AnimTask_IsAttackerBehindSubstitute(u8 taskId) -{ - gBattleAnimArgs[ARG_RET_ID] = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].behindSubstitute; - DestroyAnimVisualTask(taskId); -} - -void AnimTask_SetTargetToEffectBattler(u8 taskId) -{ - gBattleAnimTarget = gEffectBattler; - DestroyAnimVisualTask(taskId); -} - -void sub_8172EF0(u8 battler, struct Pokemon *mon) -{ - int isShiny; - u32 otId, personality; - u32 shinyValue; - u8 taskId1, taskId2; - - isShiny = 0; - gBattleSpritesDataPtr->healthBoxesData[battler].flag_x80 = 1; - otId = GetMonData(mon, MON_DATA_OT_ID); - personality = GetMonData(mon, MON_DATA_PERSONALITY); - - if (IsBattlerSpriteVisible(battler)) - { - shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); - if (shinyValue < SHINY_ODDS) - isShiny = TRUE; - - if (isShiny) - { - if (GetSpriteTileStartByTag(ANIM_TAG_GOLD_STARS) == 0xFFFF) - { - LoadCompressedSpriteSheetUsingHeap(&gBattleAnimPicTable[ANIM_TAG_GOLD_STARS - ANIM_SPRITES_START]); - LoadCompressedSpritePaletteUsingHeap(&gBattleAnimPaletteTable[ANIM_TAG_GOLD_STARS - ANIM_SPRITES_START]); - } - - taskId1 = CreateTask(sub_8172FEC, 10); - taskId2 = CreateTask(sub_8172FEC, 10); - gTasks[taskId1].data[0] = battler; - gTasks[taskId2].data[0] = battler; - gTasks[taskId1].data[1] = 0; - gTasks[taskId2].data[1] = 1; - return; - } - } - - gBattleSpritesDataPtr->healthBoxesData[battler].field_1_x1 = 1; -} - -static void sub_8172FEC(u8 taskId) -{ - u8 battler; - u8 x, y; - u8 spriteId; - u16 counter; - s16 state; - u8 pan; - - if (gTasks[taskId].data[13] < 60) - { - gTasks[taskId].data[13]++; - return; - } - - if (gBattleSpritesDataPtr->animationData->field_A) - return; - - counter = gTasks[taskId].data[10]++; - if (counter & 3) - return; - - battler = gTasks[taskId].data[0]; - x = GetBattlerSpriteCoord(battler, 0); - y = GetBattlerSpriteCoord(battler, 1); - state = gTasks[taskId].data[11]; - if (state == 0) - { - spriteId = CreateSprite(&gWishStarSpriteTemplate, x, y, 5); - } - else if (state >= 0 && gTasks[taskId].data[11] < 4) - { - spriteId = CreateSprite(&gMiniTwinklingStarSpriteTemplate, x, y, 5); - gSprites[spriteId].oam.tileNum += 4; - } - else - { - spriteId = CreateSprite(&gMiniTwinklingStarSpriteTemplate, x, y, 5); - gSprites[spriteId].oam.tileNum += 5; - } - - if (gTasks[taskId].data[1] == 0) - { - gSprites[spriteId].callback = sub_81731FC; - } - else - { - gSprites[spriteId].callback = sub_8173250; - gSprites[spriteId].pos2.x = -32; - gSprites[spriteId].pos2.y = 32; - gSprites[spriteId].invisible = TRUE; - if (gTasks[taskId].data[11] == 0) - { - if (GetBattlerSide(battler) == B_SIDE_PLAYER) - pan = -64; - else - pan = 63; - - PlaySE12WithPanning(SE_REAPOKE, pan); - } - } - - gSprites[spriteId].data[0] = taskId; - gTasks[taskId].data[11]++; - if (spriteId != MAX_SPRITES) - gTasks[taskId].data[12]++; - - if (gTasks[taskId].data[11] == 5) - gTasks[taskId].func = sub_81731B0; -} - -static void sub_81731B0(u8 taskId) -{ - u8 battler; - - if (gTasks[taskId].data[12] == 0) - { - if (gTasks[taskId].data[1] == 1) - { - battler = gTasks[taskId].data[0]; - gBattleSpritesDataPtr->healthBoxesData[battler].field_1_x1 = 1; - } - - DestroyTask(taskId); - } -} - -static void sub_81731FC(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[1], 24); - sprite->pos2.y = Cos(sprite->data[1], 24); - sprite->data[1] += 12; - if (sprite->data[1] > 0xFF) - { - gTasks[sprite->data[0]].data[12]--; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } -} - -static void sub_8173250(struct Sprite *sprite) -{ - if (sprite->data[1] < 4) - { - sprite->data[1]++; - } - else - { - sprite->invisible = FALSE; - sprite->pos2.x += 5; - sprite->pos2.y -= 5; - if (sprite->pos2.x > 32) - { - gTasks[sprite->data[0]].data[12]--; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } - } -} - -void AnimTask_LoadPokeblockGfx(u8 taskId) -{ - u8 paletteIndex; - - LoadCompressedSpriteSheetUsingHeap(&gBattleAnimPicTable[ANIM_TAG_POKEBLOCK - ANIM_SPRITES_START]); - LoadCompressedSpritePaletteUsingHeap(&gBattleAnimPaletteTable[ANIM_TAG_POKEBLOCK - ANIM_SPRITES_START]); - paletteIndex = IndexOfSpritePaletteTag(ANIM_TAG_POKEBLOCK); // unused - DestroyAnimVisualTask(taskId); -} - -void AnimTask_FreePokeblockGfx(u8 taskId) -{ - FreeSpriteTilesByTag(ANIM_TAG_POKEBLOCK); - FreeSpritePaletteByTag(ANIM_TAG_POKEBLOCK); - DestroyAnimVisualTask(taskId); -} - -static void sub_817330C(struct Sprite *sprite) -{ - InitSpritePosToAnimAttacker(sprite, 0); - sprite->data[0] = 30; - sprite->data[2] = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), 0) + gBattleAnimArgs[2]; - sprite->data[4] = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), 1) + gBattleAnimArgs[3]; - sprite->data[5] = -32; - InitAnimArcTranslation(sprite); - gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].callback = sub_8039E84; - sprite->callback = sub_817339C; -} - -static void sub_817339C(struct Sprite *sprite) -{ - if (gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].animCmdIndex == 1) - sprite->callback = sub_81733D4; -} - -static void sub_81733D4(struct Sprite *sprite) -{ - if (TranslateAnimHorizontalArc(sprite)) - { - sprite->data[0] = 0; - sprite->invisible = TRUE; - sprite->callback = sub_8173400; - } -} - -static void sub_8173400(struct Sprite *sprite) -{ - if (gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].animEnded) - { - if (++sprite->data[0] > 0) - { - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gBattleAnimAttacker]], 0); - DestroyAnimSprite(sprite); - } - } -} - -void AnimTask_SetAttackerTargetLeftPos(u8 taskId) -{ - switch (gBattleAnimArgs[0]) - { - case 0: - gBattleAnimAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - gBattleAnimTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - break; - case 1: - gBattleAnimAttacker = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - gBattleAnimTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - break; - } - - DestroyAnimVisualTask(taskId); -} - -void AnimTask_GetTrappedMoveAnimId(u8 taskId) -{ - if (gBattleSpritesDataPtr->animationData->animArg == MOVE_FIRE_SPIN) - gBattleAnimArgs[0] = TRAP_ANIM_FIRE_SPIN; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_WHIRLPOOL) - gBattleAnimArgs[0] = TRAP_ANIM_WHIRLPOOL; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_CLAMP) - gBattleAnimArgs[0] = TRAP_ANIM_CLAMP; - else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_SAND_TOMB) - gBattleAnimArgs[0] = TRAP_ANIM_SAND_TOMB; - else - gBattleAnimArgs[0] = TRAP_ANIM_BIND; - - DestroyAnimVisualTask(taskId); -} - -void AnimTask_GetBattlersFromArg(u8 taskId) -{ - gBattleAnimAttacker = gBattleSpritesDataPtr->animationData->animArg; - gBattleAnimTarget = gBattleSpritesDataPtr->animationData->animArg >> 8; - DestroyAnimVisualTask(taskId); -} diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index ce22c605f..f9b0409e5 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -281,14 +281,14 @@ static void sub_8064734(void) && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1) { - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); } if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].field_1_x1) { - sub_8172EF0(BATTLE_PARTNER(gActiveBattler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); + TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); } @@ -369,7 +369,7 @@ static void sub_8064B04(void) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80) { - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); } else { @@ -497,7 +497,7 @@ static void sub_8064F40(void) if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80) { - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); } if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c index ece4c24bc..536eb6da7 100644 --- a/src/battle_controller_link_partner.c +++ b/src/battle_controller_link_partner.c @@ -383,7 +383,7 @@ static void sub_814B69C(void) if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) { - sub_8172EF0(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); } if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index daf2c260e..7b67aaba4 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -290,9 +290,9 @@ static void sub_805F560(void) bool32 r10 = FALSE; if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1) - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle() && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].field_1_x1) - sub_8172EF0(gActiveBattler ^ BIT_FLANK, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); + TryShinyAnimation(gActiveBattler ^ BIT_FLANK, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x80) @@ -369,7 +369,7 @@ static void sub_805F560(void) static void sub_805F994(void) { if (gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x == 0 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1) - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1) { @@ -481,7 +481,7 @@ static void sub_805FD00(void) static void sub_805FDF0(void) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index fd18c3187..459e4566a 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -977,9 +977,9 @@ static void sub_8058B40(void) bool32 r8 = FALSE; if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - sub_8172EF0(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) - sub_8172EF0(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); + TryShinyAnimation(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) { @@ -1082,7 +1082,7 @@ static void sub_805902C(void) if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) { - sub_8172EF0(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); } if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index 21c1fdd5b..5efb6ffe1 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -568,7 +568,7 @@ static void sub_81BBAE8(void) if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) { - sub_8172EF0(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); } if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index 35383611b..a343246c5 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -263,9 +263,9 @@ static void sub_818686C(void) bool32 r8 = FALSE; if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) - sub_8172EF0(gActiveBattler ^ BIT_FLANK, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); + TryShinyAnimation(gActiveBattler ^ BIT_FLANK, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) { @@ -350,7 +350,7 @@ static void sub_8186C48(void) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80) { - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); } else { @@ -479,7 +479,7 @@ static void sub_8187084(void) if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80) { - sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); } if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index 5f3b3ea65..f77cb3e11 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -280,12 +280,12 @@ static void sub_8189D40(void) if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) { - sub_8172EF0(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); } if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) { - sub_8172EF0(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); + TryShinyAnimation(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); } } @@ -463,7 +463,7 @@ static void sub_818A470(void) if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) { - sub_8172EF0(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); } if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c index a5b1ae2f7..a26694a8e 100644 --- a/src/battle_controller_wally.c +++ b/src/battle_controller_wally.c @@ -286,9 +286,9 @@ static void CompleteOnChosenItem(void) static void sub_816864C(void) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - sub_8172EF0(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) - sub_8172EF0(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); + TryShinyAnimation(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 4e0e087b6..a70288015 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10191,6 +10191,7 @@ static void Cmd_handleballthrow(void) else // not caught { gBattleCommunication[MULTISTRING_CHOOSER] = shakes; + // Maybe inject SpriteCB_TestBallThrow here gBattlescriptCurrInstr = BattleScript_ShakeBallThrow; } } diff --git a/src/pokeball.c b/src/pokeball.c index 1a0561c33..a065be3f0 100644 --- a/src/pokeball.c +++ b/src/pokeball.c @@ -166,43 +166,43 @@ static const union AnimCmd *const sBallAnimSequences[] = sBallAnimSeq6, }; -static const union AffineAnimCmd sBallAffineAnimSeq0[] = +static const union AffineAnimCmd sAffineAnim_BallRotate_0[] = { AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_JUMP(0), }; -static const union AffineAnimCmd sBallAffineAnimSeq1[] = +static const union AffineAnimCmd sAffineAnim_BallRotate_Right[] = { AFFINEANIMCMD_FRAME(0, 0, -3, 1), AFFINEANIMCMD_JUMP(0), }; -static const union AffineAnimCmd sBallAffineAnimSeq2[] = +static const union AffineAnimCmd sAffineAnim_BallRotate_Left[] = { AFFINEANIMCMD_FRAME(0, 0, 3, 1), AFFINEANIMCMD_JUMP(0), }; -static const union AffineAnimCmd sBallAffineAnimSeq3[] = +static const union AffineAnimCmd sAffineAnim_BallRotate_3[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_END, }; -static const union AffineAnimCmd sBallAffineAnimSeq4[] = +static const union AffineAnimCmd sAffineAnim_BallRotate_4[] = { AFFINEANIMCMD_FRAME(0, 0, 25, 1), AFFINEANIMCMD_JUMP(0), }; -static const union AffineAnimCmd *const sBallAffineAnimSequences[] = +static const union AffineAnimCmd *const sAffineAnim_BallRotate[] = { - sBallAffineAnimSeq0, - sBallAffineAnimSeq1, - sBallAffineAnimSeq2, - sBallAffineAnimSeq3, - sBallAffineAnimSeq4, + [BALL_AFFINE_ANIM_0] = sAffineAnim_BallRotate_0, + [BALL_ROTATE_RIGHT] = sAffineAnim_BallRotate_Right, + [BALL_ROTATE_LEFT] = sAffineAnim_BallRotate_Left, + [BALL_AFFINE_ANIM_3] = sAffineAnim_BallRotate_3, + [BALL_AFFINE_ANIM_4] = sAffineAnim_BallRotate_4, }; const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = @@ -213,7 +213,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -222,7 +222,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -231,7 +231,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -240,7 +240,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -249,7 +249,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -258,7 +258,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -267,7 +267,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -276,7 +276,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -285,7 +285,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -294,7 +294,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -303,7 +303,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, { @@ -312,7 +312,7 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] = .oam = &sBallOamData, .anims = sBallAnimSequences, .images = NULL, - .affineAnims = sBallAffineAnimSequences, + .affineAnims = sAffineAnim_BallRotate, .callback = SpriteCB_TestBallThrow, }, }; @@ -446,6 +446,7 @@ static void sub_80756D4(struct Sprite *sprite) sprite->callback = sub_80756E0; } +// Start something for battler static void sub_80756E0(struct Sprite *sprite) { if (++sprite->data[5] == 10) @@ -458,6 +459,7 @@ static void sub_80756E0(struct Sprite *sprite) } } +// Shrink player static void sub_807574C(struct Sprite *sprite) { sprite->data[5]++; @@ -738,7 +740,7 @@ static void SpriteCB_ReleaseMonFromBall(struct Sprite *sprite) StartSpriteAnim(sprite, 1); ballId = ItemIdToBallId(GetBattlerPokeballItemId(battlerId)); AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 0x1C, ballId); - sprite->data[0] = LaunchBallFadeMonTask(1, sprite->sBattler, 14, ballId); + sprite->data[0] = LaunchBallFadeMonTask(TRUE, sprite->sBattler, 14, ballId); sprite->callback = HandleBallAnimEnd; if (gMain.inBattle) -- cgit v1.2.3