#include "global.h" #include "malloc.h" #include "battle_anim.h" #include "battle_interface.h" #include "decompress.h" #include "gpu_regs.h" #include "graphics.h" #include "main.h" #include "math_util.h" #include "palette.h" #include "random.h" #include "scanline_effect.h" #include "sound.h" #include "trig.h" #include "util.h" #include "constants/rgb.h" #include "constants/songs.h" EWRAM_DATA s16 gUnknown_0203A0F8[4] = {0}; void AnimMovePowderParticle(struct Sprite *); void AnimPowerAbsorptionOrb(struct Sprite *); void AnimSolarbeamBigOrb(struct Sprite *); void AnimSolarbeamSmallOrb(struct Sprite *); void AnimAbsorptionOrb(struct Sprite *); void AnimHyperBeamOrb(struct Sprite *); void AnimSporeParticle(struct Sprite *); void AnimPetalDanceBigFlower(struct Sprite *); void AnimPetalDanceSmallFlower(struct Sprite *); void AnimRazorLeafParticle(struct Sprite *); void AnimLeechSeed(struct Sprite *); void AnimTranslateLinearSingleSineWave(struct Sprite *); void AnimMoveTwisterParticle(struct Sprite *); void AnimConstrictBinding(struct Sprite *); void AnimMimicOrb(struct Sprite *); void AnimIngrainRoot(struct Sprite *); void AnimFrenzyPlantRoot(struct Sprite *); void AnimIngrainOrb(struct Sprite *); void AnimPresent(struct Sprite *); void AnimKnockOffItem(struct Sprite *); void AnimPresentHealParticle(struct Sprite *); void AnimItemSteal(struct Sprite *); void AnimTrickBag(struct Sprite *); void AnimFlyingParticle(struct Sprite *); void AnimNeedleArmSpike(struct Sprite *); void sub_81009F8(struct Sprite *); void AnimWhipHit(struct Sprite *); void sub_8100A94(struct Sprite *); void AnimCuttingSlice(struct Sprite *); void AnimAirCutterSlice(struct Sprite *); void sub_8100E1C(struct Sprite *); void AnimProtect(struct Sprite *); void AnimMilkBottle(struct Sprite *); void AnimGrantingStars(struct Sprite *); void AnimSparkingStars(struct Sprite *); void sub_8101440(struct Sprite *); void AnimSleepLetterZ(struct Sprite *); void AnimLockOnTarget(struct Sprite *); void AnimLockOnMoveTarget(struct Sprite *); void AnimBowMon(struct Sprite *); void sub_8101B90(struct Sprite *); void AnimSlashSlice(struct Sprite *); void AnimFalseSwipeSlice(struct Sprite *); void AnimFalseSwipePositionedSlice(struct Sprite *); void AnimEndureEnergy(struct Sprite *); void AnimSharpenSphere(struct Sprite *); void AnimConversion(struct Sprite *); void AnimConversion2(struct Sprite *); void AnimMoon(struct Sprite *); void AnimMoonlightSparkle(struct Sprite *); void AnimHornHit(struct Sprite *); void AnimSuperFang(struct Sprite *); void AnimWavyMusicNotes(struct Sprite *); void AnimFlyingMusicNotes(struct Sprite *); void AnimBellyDrumHand(struct Sprite *); void AnimSlowFlyingMusicNotes(struct Sprite *); void AnimThoughtBubble(struct Sprite *); void AnimMetronomeFinger(struct Sprite *); void AnimFollowMeFinger(struct Sprite *); void AnimTauntFinger(struct Sprite *); static void AnimMovePowderParticleStep(struct Sprite *); static void AnimSolarbeamSmallOrbStep(struct Sprite *); static void AnimAbsorptionOrbStep(struct Sprite *); static void AnimHyperBeamOrbStep(struct Sprite *); static void AnimLeechSeedStep(struct Sprite *); static void AnimLeechSeedSprouts(struct Sprite *); static void AnimSporeParticleStep(struct Sprite *); static void AnimPetalDanceBigFlowerStep(struct Sprite *); static void AnimPetalDanceSmallFlowerStep(struct Sprite *); static void AnimRazorLeafParticleStep1(struct Sprite *); static void AnimRazorLeafParticleStep2(struct Sprite *); static void AnimTranslateLinearSingleSineWaveStep(struct Sprite *); static void AnimMoveTwisterParticleStep(struct Sprite *); static void AnimConstrictBindingStep1(struct Sprite *); static void AnimConstrictBindingStep2(struct Sprite *); static void AnimTask_DuplicateAndShrinkToPosStep1(u8); static void AnimTask_DuplicateAndShrinkToPosStep2(u8); static void AnimItemStealStep3(struct Sprite *); static void AnimRootFlickerOut(struct Sprite *); static void AnimTrickBagStep1(struct Sprite *); static void AnimTrickBagStep2(struct Sprite *); static void AnimTrickBagStep3(struct Sprite *); static void AnimTask_LeafBladeStep(u8); static s16 LeafBladeGetPosFactor(struct Sprite *); static void AnimTask_LeafBladeStep2(struct Task *, u8); static void AnimTask_LeafBladeStep2_Callback(struct Sprite *); static void AnimFlyingParticleStep(struct Sprite *); static void AnimNeedleArmSpikeStep(struct Sprite *); static void AnimSliceStep(struct Sprite *); static void sub_8100E80(struct Sprite *); static void AnimProtectStep(struct Sprite *); static void AnimMilkBottleStep1(struct Sprite *); static void AnimMilkBottleStep2(struct Sprite *, int, int); static void sub_81014A0(struct Sprite *); static void AnimSleepLetterZStep(struct Sprite *); static void AnimLockOnTargetStep1(struct Sprite *); static void AnimLockOnTargetStep2(struct Sprite *); static void AnimLockOnTargetStep3(struct Sprite *); static void AnimLockOnTargetStep4(struct Sprite *); static void AnimLockOnTargetStep5(struct Sprite *); static void AnimLockOnTargetStep6(struct Sprite *); static void AnimBowMonStep1(struct Sprite *); static void AnimBowMonStep1_Callback(struct Sprite *); static void AnimBowMonStep2(struct Sprite *); static void AnimBowMonStep3(struct Sprite *); static void AnimBowMonStep4(struct Sprite *); static void AnimBowMonStep3_Callback(struct Sprite *); static void sub_8101BA0(struct Sprite *); static void AnimTask_SkullBashPositionSet(u8); static void AnimTask_SkullBashPositionReset(u8); static void AnimFalseSwipeSliceStep1(struct Sprite *); static void AnimFalseSwipeSliceStep2(struct Sprite *); static void AnimFalseSwipeSliceStep3(struct Sprite *); static void AnimEndureEnergyStep(struct Sprite *); static void AnimSharpenSphereStep(struct Sprite *); static void AnimConversion2Step(struct Sprite *); static void AnimMoonStep(struct Sprite *); static void AnimMoonlightSparkleStep(struct Sprite *); static void AnimHornHitStep(struct Sprite *); static void AnimTask_DoubleTeamStep(u8); static void AnimTask_DoubleTeamCallback(struct Sprite *); static void AnimWavyMusicNotesGetNextPos(s16, s16, s16 *, s16 *, s8); static void AnimWavyMusicNotesStep(struct Sprite *); static void AnimFlyingMusicNotesStep(struct Sprite *); static void AnimSlowFlyingMusicNotesStep(struct Sprite *); static void AnimThoughtBubbleStep(struct Sprite *); static void AnimMetronomeFingerStep(struct Sprite *); static void AnimFollowMeFingerStep1(struct Sprite *); static void AnimFollowMeFingerStep2(struct Sprite *); static void AnimTauntFingerStep1(struct Sprite *); static void AnimTauntFingerStep2(struct Sprite *); const union AnimCmd gPowderParticlesAnimCmds[] = { ANIMCMD_FRAME(0, 5), ANIMCMD_FRAME(2, 5), ANIMCMD_FRAME(4, 5), ANIMCMD_FRAME(6, 5), ANIMCMD_FRAME(8, 5), ANIMCMD_FRAME(10, 5), ANIMCMD_FRAME(12, 5), ANIMCMD_FRAME(14, 5), ANIMCMD_JUMP(0), }; const union AnimCmd *const gPowderParticlesAnimTable[] = { gPowderParticlesAnimCmds, }; const struct SpriteTemplate gSleepPowderParticleSpriteTemplate = { .tileTag = ANIM_TAG_SLEEP_POWDER, .paletteTag = ANIM_TAG_SLEEP_POWDER, .oam = &gOamData_AffineOff_ObjNormal_8x16, .anims = gPowderParticlesAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimMovePowderParticle, }; const struct SpriteTemplate gStunSporeParticleSpriteTemplate = { .tileTag = ANIM_TAG_STUN_SPORE, .paletteTag = ANIM_TAG_STUN_SPORE, .oam = &gOamData_AffineOff_ObjNormal_8x16, .anims = gPowderParticlesAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimMovePowderParticle, }; const struct SpriteTemplate gPoisonPowderParticleSpriteTemplate = { .tileTag = ANIM_TAG_POISON_POWDER, .paletteTag = ANIM_TAG_POISON_POWDER, .oam = &gOamData_AffineOff_ObjNormal_8x16, .anims = gPowderParticlesAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimMovePowderParticle, }; const union AnimCmd gSolarbeamBigOrbAnimCmds1[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; const union AnimCmd gSolarbeamBigOrbAnimCmds2[] = { ANIMCMD_FRAME(1, 1), ANIMCMD_END, }; const union AnimCmd gSolarbeamBigOrbAnimCmds3[] = { ANIMCMD_FRAME(2, 1), ANIMCMD_END, }; const union AnimCmd gSolarbeamBigOrbAnimCmds4[] = { ANIMCMD_FRAME(3, 1), ANIMCMD_END, }; const union AnimCmd gSolarbeamBigOrbAnimCmds5[] = { ANIMCMD_FRAME(4, 1), ANIMCMD_END, }; const union AnimCmd gSolarbeamBigOrbAnimCmds6[] = { ANIMCMD_FRAME(5, 1), ANIMCMD_END, }; const union AnimCmd gSolarbeamBigOrbAnimCmds7[] = { ANIMCMD_FRAME(6, 1), ANIMCMD_END, }; const union AnimCmd gSolarbeamSmallOrbAnimCms[] = { ANIMCMD_FRAME(7, 1), ANIMCMD_END, }; const union AnimCmd gPowerAbsorptionOrbAnimCmds[] = { ANIMCMD_FRAME(8, 1), ANIMCMD_END, }; const union AnimCmd *const gSolarbeamBigOrbAnimTable[] = { gSolarbeamBigOrbAnimCmds1, gSolarbeamBigOrbAnimCmds2, gSolarbeamBigOrbAnimCmds3, gSolarbeamBigOrbAnimCmds4, gSolarbeamBigOrbAnimCmds5, gSolarbeamBigOrbAnimCmds6, gSolarbeamBigOrbAnimCmds7, }; const union AnimCmd *const gSolarbeamSmallOrbAnimTable[] = { gSolarbeamSmallOrbAnimCms, }; const union AnimCmd *const gPowerAbsorptionOrbAnimTable[] = { gPowerAbsorptionOrbAnimCmds, }; const union AffineAnimCmd gPowerAbsorptionOrbAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(-5, -5, 0, 1), AFFINEANIMCMD_JUMP(0), }; const union AffineAnimCmd *const gPowerAbsorptionOrbAffineAnimTable[] = { gPowerAbsorptionOrbAffineAnimCmds, }; const struct SpriteTemplate gPowerAbsorptionOrbSpriteTemplate = { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, .oam = &gOamData_AffineNormal_ObjBlend_16x16, .anims = gPowerAbsorptionOrbAnimTable, .images = NULL, .affineAnims = gPowerAbsorptionOrbAffineAnimTable, .callback = AnimPowerAbsorptionOrb, }; const struct SpriteTemplate gSolarbeamBigOrbSpriteTemplate = { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, .oam = &gOamData_AffineOff_ObjNormal_8x8, .anims = gSolarbeamBigOrbAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSolarbeamBigOrb, }; const struct SpriteTemplate gSolarbeamSmallOrbSpriteTemplate = { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, .oam = &gOamData_AffineOff_ObjNormal_8x8, .anims = gSolarbeamSmallOrbAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSolarbeamSmallOrb, }; const union AffineAnimCmd gStockpileAbsorptionOrbAffineCmds[] = { AFFINEANIMCMD_FRAME(320, 320, 0, 0), AFFINEANIMCMD_FRAME(-14, -14, 0, 1), AFFINEANIMCMD_JUMP(1), }; const union AffineAnimCmd *const gStockpileAbsorptionOrbAffineAnimTable[] = { gStockpileAbsorptionOrbAffineCmds, }; const struct SpriteTemplate gStockpileAbsorptionOrbSpriteTemplate = { .tileTag = ANIM_TAG_GRAY_ORB, .paletteTag = ANIM_TAG_GRAY_ORB, .oam = &gOamData_AffineDouble_ObjNormal_8x8, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gStockpileAbsorptionOrbAffineAnimTable, .callback = AnimPowerAbsorptionOrb, }; const union AffineAnimCmd gAbsorptionOrbAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(-5, -5, 0, 1), AFFINEANIMCMD_JUMP(0), }; const union AffineAnimCmd *const gAbsorptionOrbAffineAnimTable[] = { gAbsorptionOrbAffineAnimCmds, }; const struct SpriteTemplate gAbsorptionOrbSpriteTemplate = { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, .oam = &gOamData_AffineNormal_ObjBlend_16x16, .anims = gPowerAbsorptionOrbAnimTable, .images = NULL, .affineAnims = gAbsorptionOrbAffineAnimTable, .callback = AnimAbsorptionOrb, }; const struct SpriteTemplate gHyperBeamOrbSpriteTemplate = { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, .oam = &gOamData_AffineOff_ObjNormal_8x8, .anims = gSolarbeamBigOrbAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimHyperBeamOrb, }; const union AnimCmd gLeechSeedAnimCmds1[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; const union AnimCmd gLeechSeedAnimCmds2[] = { ANIMCMD_FRAME(4, 7), ANIMCMD_FRAME(8, 7), ANIMCMD_JUMP(0), }; const union AnimCmd *const gLeechSeedAnimTable[] = { gLeechSeedAnimCmds1, gLeechSeedAnimCmds2, }; const struct SpriteTemplate gLeechSeedSpriteTemplate = { .tileTag = ANIM_TAG_SEED, .paletteTag = ANIM_TAG_SEED, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gLeechSeedAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimLeechSeed, }; const union AnimCmd gSporeParticleAnimCmds1[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; const union AnimCmd gSporeParticleAnimCmds2[] = { ANIMCMD_FRAME(4, 7), ANIMCMD_END, }; const union AnimCmd *const gSporeParticleAnimTable[] = { gSporeParticleAnimCmds1, gSporeParticleAnimCmds2, }; const struct SpriteTemplate gSporeParticleSpriteTemplate = { .tileTag = ANIM_TAG_SPORE, .paletteTag = ANIM_TAG_SPORE, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gSporeParticleAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSporeParticle, }; const union AnimCmd gPetalDanceBigFlowerAnimCmds[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; const union AnimCmd gPetalDanceSmallFlowerAnimCmds[] = { ANIMCMD_FRAME(4, 1), ANIMCMD_END, }; const union AnimCmd *const gPetalDanceBigFlowerAnimTable[] = { gPetalDanceBigFlowerAnimCmds, }; const union AnimCmd *const gPetalDanceSmallFlowerAnimTable[] = { gPetalDanceSmallFlowerAnimCmds, }; const struct SpriteTemplate gPetalDanceBigFlowerSpriteTemplate = { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gPetalDanceBigFlowerAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimPetalDanceBigFlower, }; const struct SpriteTemplate gPetalDanceSmallFlowerSpriteTemplate = { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, .oam = &gOamData_AffineOff_ObjNormal_8x8, .anims = gPetalDanceSmallFlowerAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimPetalDanceSmallFlower, }; const union AnimCmd gRazorLeafParticleAnimCmds1[] = { ANIMCMD_FRAME(0, 5), ANIMCMD_FRAME(4, 5), ANIMCMD_FRAME(8, 5), ANIMCMD_FRAME(12, 5), ANIMCMD_FRAME(16, 5), ANIMCMD_FRAME(20, 5), ANIMCMD_FRAME(16, 5), ANIMCMD_FRAME(12, 5), ANIMCMD_FRAME(8, 5), ANIMCMD_FRAME(4, 5), ANIMCMD_JUMP(0), }; const union AnimCmd gRazorLeafParticleAnimCmds2[] = { ANIMCMD_FRAME(24, 5), ANIMCMD_FRAME(28, 5), ANIMCMD_FRAME(32, 5), ANIMCMD_END, }; const union AnimCmd *const gRazorLeafParticleAnimTable[] = { gRazorLeafParticleAnimCmds1, gRazorLeafParticleAnimCmds2, }; const struct SpriteTemplate gRazorLeafParticleSpriteTemplate = { .tileTag = ANIM_TAG_LEAF, .paletteTag = ANIM_TAG_LEAF, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gRazorLeafParticleAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimRazorLeafParticle, }; const struct SpriteTemplate gTwisterLeafParticleSpriteTemplate = { .tileTag = ANIM_TAG_LEAF, .paletteTag = ANIM_TAG_LEAF, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gRazorLeafParticleAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimMoveTwisterParticle, }; const union AnimCmd gRazorLeafCutterAnimCmds[] = { ANIMCMD_FRAME(0, 3), ANIMCMD_FRAME(0, 3, .hFlip = TRUE), ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE), ANIMCMD_FRAME(0, 3, .vFlip = TRUE), ANIMCMD_JUMP(0), }; const union AnimCmd *const gRazorLeafCutterAnimTable[] = { gRazorLeafCutterAnimCmds, }; const struct SpriteTemplate gRazorLeafCutterSpriteTemplate = { .tileTag = ANIM_TAG_RAZOR_LEAF, .paletteTag = ANIM_TAG_RAZOR_LEAF, .oam = &gOamData_AffineOff_ObjNormal_32x16, .anims = gRazorLeafCutterAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimTranslateLinearSingleSineWave, }; const union AffineAnimCmd gSwiftStarAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_JUMP(0), }; const union AffineAnimCmd *const gSwiftStarAffineAnimTable[] = { gSwiftStarAffineAnimCmds, }; const struct SpriteTemplate gSwiftStarSpriteTemplate = { .tileTag = ANIM_TAG_YELLOW_STAR, .paletteTag = ANIM_TAG_YELLOW_STAR, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gSwiftStarAffineAnimTable, .callback = AnimTranslateLinearSingleSineWave, }; const union AnimCmd gConstrictBindingAnimCmds1[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(64, 4), ANIMCMD_FRAME(96, 4), ANIMCMD_END, }; const union AnimCmd gConstrictBindingAnimCmds2[] = { ANIMCMD_FRAME(0, 4, .hFlip = TRUE), ANIMCMD_FRAME(32, 4, .hFlip = TRUE), ANIMCMD_FRAME(64, 4, .hFlip = TRUE), ANIMCMD_FRAME(96, 4, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gConstrictBindingAnimTable[] = { gConstrictBindingAnimCmds1, gConstrictBindingAnimCmds2, }; const union AffineAnimCmd gConstrictBindingAffineAnimCmds1[] = { AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_FRAME(-11, 0, 0, 6), AFFINEANIMCMD_FRAME(11, 0, 0, 6), AFFINEANIMCMD_END, }; const union AffineAnimCmd gConstrictBindingAffineAnimCmds2[] = { AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0), AFFINEANIMCMD_FRAME(11, 0, 0, 6), AFFINEANIMCMD_FRAME(-11, 0, 0, 6), AFFINEANIMCMD_END, }; const union AffineAnimCmd *const gConstrictBindingAffineAnimTable[] = { gConstrictBindingAffineAnimCmds1, gConstrictBindingAffineAnimCmds2, }; const struct SpriteTemplate gConstrictBindingSpriteTemplate = { .tileTag = ANIM_TAG_TENDRILS, .paletteTag = ANIM_TAG_TENDRILS, .oam = &gOamData_AffineNormal_ObjNormal_64x32, .anims = gConstrictBindingAnimTable, .images = NULL, .affineAnims = gConstrictBindingAffineAnimTable, .callback = AnimConstrictBinding, }; const union AffineAnimCmd gMimicOrbAffineAnimCmds1[] = { AFFINEANIMCMD_FRAME(0, 0, 0, 0), AFFINEANIMCMD_FRAME(48, 48, 0, 14), AFFINEANIMCMD_END, }; const union AffineAnimCmd gMimicOrbAffineAnimCmds2[] = { AFFINEANIMCMD_FRAME(-16, -16, 0, 1), AFFINEANIMCMD_JUMP(0), }; const union AffineAnimCmd *const gMimicOrbAffineAnimTable[] = { gMimicOrbAffineAnimCmds1, gMimicOrbAffineAnimCmds2, }; const struct SpriteTemplate gMimicOrbSpriteTemplate = { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, .oam = &gOamData_AffineDouble_ObjNormal_16x16, .anims = gPowerAbsorptionOrbAnimTable, .images = NULL, .affineAnims = gMimicOrbAffineAnimTable, .callback = AnimMimicOrb, }; const union AnimCmd gIngrainRootAnimCmds1[] = { ANIMCMD_FRAME(0, 7), ANIMCMD_FRAME(16, 7), ANIMCMD_FRAME(32, 7), ANIMCMD_FRAME(48, 7), ANIMCMD_END, }; const union AnimCmd gIngrainRootAnimCmds2[] = { ANIMCMD_FRAME(0, 7, .hFlip = TRUE), ANIMCMD_FRAME(16, 7, .hFlip = TRUE), ANIMCMD_FRAME(32, 7, .hFlip = TRUE), ANIMCMD_FRAME(48, 7, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gIngrainRootAnimCmds3[] = { ANIMCMD_FRAME(0, 7), ANIMCMD_FRAME(16, 7), ANIMCMD_FRAME(32, 7), ANIMCMD_END, }; const union AnimCmd gIngrainRootAnimCmds4[] = { ANIMCMD_FRAME(0, 7, .hFlip = TRUE), ANIMCMD_FRAME(16, 7, .hFlip = TRUE), ANIMCMD_FRAME(32, 7, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gIngrainRootAnimTable[] = { gIngrainRootAnimCmds1, gIngrainRootAnimCmds2, gIngrainRootAnimCmds3, gIngrainRootAnimCmds4, }; const struct SpriteTemplate gIngrainRootSpriteTemplate = { .tileTag = ANIM_TAG_ROOTS, .paletteTag = ANIM_TAG_ROOTS, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gIngrainRootAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimIngrainRoot, }; const struct SpriteTemplate gFrenzyPlantRootSpriteTemplate = { .tileTag = ANIM_TAG_ROOTS, .paletteTag = ANIM_TAG_ROOTS, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gIngrainRootAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimFrenzyPlantRoot, }; const union AnimCmd gIngrainOrbAnimCmds[] = { ANIMCMD_FRAME(3, 3), ANIMCMD_FRAME(0, 5), ANIMCMD_JUMP(0), }; const union AnimCmd *const gIngrainOrbAnimTable[] = { gIngrainOrbAnimCmds, }; const struct SpriteTemplate gIngrainOrbSpriteTemplate = { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, .oam = &gOamData_AffineOff_ObjNormal_8x8, .anims = gIngrainOrbAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimIngrainOrb, }; const union AnimCmd gFallingBagAnimCmds[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_END, }; const union AnimCmd *const gFallingBagAnimTable[] = { gFallingBagAnimCmds, }; const union AffineAnimCmd gFallingBagAffineAnimCmds1[] = { AFFINEANIMCMD_FRAME(0, 0, -4, 10), AFFINEANIMCMD_FRAME(0, 0, 4, 20), AFFINEANIMCMD_FRAME(0, 0, -4, 10), AFFINEANIMCMD_END, }; const union AffineAnimCmd gFallingBagAffineAnimCmds2[] = { AFFINEANIMCMD_FRAME(0, 0, -1, 2), AFFINEANIMCMD_FRAME(0, 0, 1, 4), AFFINEANIMCMD_FRAME(0, 0, -1, 4), AFFINEANIMCMD_FRAME(0, 0, 1, 4), AFFINEANIMCMD_FRAME(0, 0, -1, 4), AFFINEANIMCMD_FRAME(0, 0, 1, 2), AFFINEANIMCMD_END, }; const union AffineAnimCmd *const gFallingBagAffineAnimTable[] = { gFallingBagAffineAnimCmds1, gFallingBagAffineAnimCmds2, }; const struct SpriteTemplate gPresentSpriteTemplate = { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gFallingBagAnimTable, .images = NULL, .affineAnims = gFallingBagAffineAnimTable, .callback = AnimPresent, }; const struct SpriteTemplate gKnockOffItemSpriteTemplate = { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gFallingBagAnimTable, .images = NULL, .affineAnims = gFallingBagAffineAnimTable, .callback = AnimKnockOffItem, }; const union AnimCmd gPresentHealParticleAnimCmds[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(4, 4), ANIMCMD_FRAME(8, 4), ANIMCMD_FRAME(12, 4), ANIMCMD_END, }; const union AnimCmd *const gPresentHealParticleAnimTable[] = { gPresentHealParticleAnimCmds, }; const struct SpriteTemplate gPresentHealParticleSpriteTemplate = { .tileTag = ANIM_TAG_GREEN_SPARKLE, .paletteTag = ANIM_TAG_GREEN_SPARKLE, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gPresentHealParticleAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimPresentHealParticle, }; const struct SpriteTemplate gItemStealSpriteTemplate = { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gFallingBagAnimTable, .images = NULL, .affineAnims = gFallingBagAffineAnimTable, .callback = AnimItemSteal, }; const union AffineAnimCmd gTrickBagAffineAnimCmds1[] = { AFFINEANIMCMD_FRAME(0, 0, 0, 3), AFFINEANIMCMD_END, }; const union AffineAnimCmd gTrickBagAffineAnimCmds2[] = { AFFINEANIMCMD_FRAME(0, -10, 0, 3), AFFINEANIMCMD_FRAME(0, -6, 0, 3), AFFINEANIMCMD_FRAME(0, -2, 0, 3), AFFINEANIMCMD_FRAME(0, 0, 0, 3), AFFINEANIMCMD_FRAME(0, 2, 0, 3), AFFINEANIMCMD_FRAME(0, 6, 0, 3), AFFINEANIMCMD_FRAME(0, 10, 0, 3), AFFINEANIMCMD_END, }; const union AffineAnimCmd *const gTrickBagAffineAnimTable[] = { gTrickBagAffineAnimCmds1, gTrickBagAffineAnimCmds2, gFallingBagAffineAnimCmds1, gFallingBagAffineAnimCmds2, }; const struct SpriteTemplate gTrickBagSpriteTemplate = { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gFallingBagAnimTable, .images = NULL, .affineAnims = gTrickBagAffineAnimTable, .callback = AnimTrickBag, }; const s8 gTrickBagCoordinates[][3] = { {5, 24, 1}, {0, 4, 0}, {8, 16, -1}, {0, 2, 0}, {8, 16, 1}, {0, 2, 0}, {8, 16, 1}, {0, 2, 0}, {8, 16, 1}, {0, 16, 0}, {0, 0, 127}, }; const union AnimCmd gLeafBladeAnimCmds1[] = { ANIMCMD_FRAME(28, 1), ANIMCMD_END, }; const union AnimCmd gLeafBladeAnimCmds2[] = { ANIMCMD_FRAME(32, 1), ANIMCMD_END, }; const union AnimCmd gLeafBladeAnimCmds3[] = { ANIMCMD_FRAME(20, 1), ANIMCMD_END, }; const union AnimCmd gLeafBladeAnimCmds4[] = { ANIMCMD_FRAME(28, 1, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gLeafBladeAnimCmds5[] = { ANIMCMD_FRAME(16, 1), ANIMCMD_END, }; const union AnimCmd gLeafBladeAnimCmds6[] = { ANIMCMD_FRAME(16, 1, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gLeafBladeAnimCmds7[] = { ANIMCMD_FRAME(28, 1), ANIMCMD_END, }; const union AnimCmd *const gLeafBladeAnimTable[] = { gLeafBladeAnimCmds1, gLeafBladeAnimCmds2, gLeafBladeAnimCmds3, gLeafBladeAnimCmds4, gLeafBladeAnimCmds5, gLeafBladeAnimCmds6, gLeafBladeAnimCmds7, }; const struct SpriteTemplate gLeafBladeSpriteTemplate = { .tileTag = ANIM_TAG_LEAF, .paletteTag = ANIM_TAG_LEAF, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gLeafBladeAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; const union AffineAnimCmd gAromatherapyBigFlowerAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 4, 1), AFFINEANIMCMD_JUMP(1), }; const union AffineAnimCmd *const gAromatherapyBigFlowerAffineAnimTable[] = { gAromatherapyBigFlowerAffineAnimCmds, }; const struct SpriteTemplate gAromatherapySmallFlowerSpriteTemplate = { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, .oam = &gOamData_AffineOff_ObjNormal_8x8, .anims = gPetalDanceSmallFlowerAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimFlyingParticle, }; const struct SpriteTemplate gAromatherapyBigFlowerSpriteTemplate = { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, .oam = &gOamData_AffineNormal_ObjNormal_16x16, .anims = gPetalDanceBigFlowerAnimTable, .images = NULL, .affineAnims = gAromatherapyBigFlowerAffineAnimTable, .callback = AnimFlyingParticle, }; const union AffineAnimCmd gSilverWindBigSparkAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_FRAME(0, 0, -10, 1), AFFINEANIMCMD_JUMP(1), }; const union AffineAnimCmd gSilverWindMediumSparkAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(192, 192, 0, 0), AFFINEANIMCMD_FRAME(0, 0, -12, 1), AFFINEANIMCMD_JUMP(1), }; const union AffineAnimCmd gSilverWindSmallSparkAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(143, 143, 0, 0), AFFINEANIMCMD_FRAME(0, 0, -15, 1), AFFINEANIMCMD_JUMP(1), }; const union AffineAnimCmd *const gSilverWindBigSparkAffineAnimTable[] = { gSilverWindBigSparkAffineAnimCmds, }; const union AffineAnimCmd *const gSilverWindMediumSparkAffineAnimTable[] = { gSilverWindMediumSparkAffineAnimCmds, }; const union AffineAnimCmd *const gSilverWindSmallSparkAffineAnimTable[] = { gSilverWindSmallSparkAffineAnimCmds, }; const struct SpriteTemplate gSilverWindBigSparkSpriteTemplate = { .tileTag = ANIM_TAG_SPARKLE_6, .paletteTag = ANIM_TAG_SPARKLE_6, .oam = &gOamData_AffineNormal_ObjNormal_16x16, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gSilverWindBigSparkAffineAnimTable, .callback = AnimFlyingParticle, }; const struct SpriteTemplate gSilverWindMediumSparkSpriteTemplate = { .tileTag = ANIM_TAG_SPARKLE_6, .paletteTag = ANIM_TAG_SPARKLE_6, .oam = &gOamData_AffineNormal_ObjNormal_16x16, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gSilverWindMediumSparkAffineAnimTable, .callback = AnimFlyingParticle, }; const struct SpriteTemplate gSilverWindSmallSparkSpriteTemplate = { .tileTag = ANIM_TAG_SPARKLE_6, .paletteTag = ANIM_TAG_SPARKLE_6, .oam = &gOamData_AffineNormal_ObjNormal_16x16, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gSilverWindSmallSparkAffineAnimTable, .callback = AnimFlyingParticle, }; const u16 gMagicalLeafBlendColors[] = { RGB(31, 0, 0), RGB(31, 19, 0), RGB(31, 31, 0), RGB(0, 31, 0), RGB(5, 14, 31), RGB(22, 10, 31), RGB(22, 21, 31), }; const struct SpriteTemplate gNeedleArmSpikeSpriteTemplate = { .tileTag = ANIM_TAG_GREEN_SPIKE, .paletteTag = ANIM_TAG_GREEN_SPIKE, .oam = &gOamData_AffineNormal_ObjNormal_16x16, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimNeedleArmSpike, }; const union AnimCmd gWhipAnimCmds1[] = { ANIMCMD_FRAME(64, 3), ANIMCMD_FRAME(80, 3), ANIMCMD_FRAME(96, 3), ANIMCMD_FRAME(112, 6), ANIMCMD_END, }; const union AnimCmd gWhipAnimCmds2[] = { ANIMCMD_FRAME(64, 3, .hFlip = TRUE), ANIMCMD_FRAME(80, 3, .hFlip = TRUE), ANIMCMD_FRAME(96, 3, .hFlip = TRUE), ANIMCMD_FRAME(112, 6, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gWhipAnimTable[] = { gWhipAnimCmds1, gWhipAnimCmds2, }; const struct SpriteTemplate gSlamHitSpriteTemplate = { .tileTag = ANIM_TAG_SLAM_HIT, .paletteTag = ANIM_TAG_SLAM_HIT, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gWhipAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimWhipHit, }; const struct SpriteTemplate gVineWhipSpriteTemplate = { .tileTag = ANIM_TAG_WHIP_HIT, .paletteTag = ANIM_TAG_WHIP_HIT, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gWhipAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimWhipHit, }; const union AnimCmd gUnknown_08592900[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(48, 4), ANIMCMD_FRAME(64, 5), ANIMCMD_END, }; const union AnimCmd *const gUnknown_08592918[] = { gUnknown_08592900, }; // Unused const struct SpriteTemplate gUnknown_0859291C = { .tileTag = ANIM_TAG_HIT, .paletteTag = ANIM_TAG_HIT, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gUnknown_08592918, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_81009F8, }; // Unused const struct SpriteTemplate gUnknown_08592934 = { .tileTag = ANIM_TAG_HIT_2, .paletteTag = ANIM_TAG_HIT_2, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gUnknown_08592918, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_81009F8, }; const union AffineAnimCmd gUnknown_0859294C[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gUnknown_0859295C[] = { AFFINEANIMCMD_FRAME(256, 256, 32, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gUnknown_0859296C[] = { AFFINEANIMCMD_FRAME(256, 256, 64, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gUnknown_0859297C[] = { AFFINEANIMCMD_FRAME(256, 256, 96, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gUnknown_0859298C[] = { AFFINEANIMCMD_FRAME(256, 256, -128, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gUnknown_0859299C[] = { AFFINEANIMCMD_FRAME(256, 256, -96, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gUnknown_085929AC[] = { AFFINEANIMCMD_FRAME(256, 256, -64, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gUnknown_085929BC[] = { AFFINEANIMCMD_FRAME(256, 256, -32, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd *const gUnknown_085929CC[] = { gUnknown_0859294C, gUnknown_0859295C, gUnknown_0859296C, gUnknown_0859297C, gUnknown_0859298C, gUnknown_0859299C, gUnknown_085929AC, gUnknown_085929BC, }; // Unused const struct SpriteTemplate gUnknown_085929EC = { .tileTag = ANIM_TAG_HANDS_AND_FEET, .paletteTag = ANIM_TAG_HANDS_AND_FEET, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gUnknown_085929CC, .callback = sub_8100A94, }; const union AnimCmd gCuttingSliceAnimCmds[] = { ANIMCMD_FRAME(0, 5), ANIMCMD_FRAME(16, 5), ANIMCMD_FRAME(32, 5), ANIMCMD_FRAME(48, 5), ANIMCMD_END, }; const union AnimCmd *const gCuttingSliceAnimTable[] = { gCuttingSliceAnimCmds, }; const struct SpriteTemplate gCuttingSliceSpriteTemplate = { .tileTag = ANIM_TAG_CUT, .paletteTag = ANIM_TAG_CUT, .oam = &gOamData_AffineOff_ObjBlend_32x32, .anims = gCuttingSliceAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimCuttingSlice, }; const struct SpriteTemplate gAirCutterSliceSpriteTemplate = { .tileTag = ANIM_TAG_CUT, .paletteTag = ANIM_TAG_CUT, .oam = &gOamData_AffineOff_ObjBlend_32x32, .anims = gCuttingSliceAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimAirCutterSlice, }; const union AnimCmd gUnknown_08592A4C[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A54[] = { ANIMCMD_FRAME(4, 1), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A5C[] = { ANIMCMD_FRAME(8, 1), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A64[] = { ANIMCMD_FRAME(12, 1), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A6C[] = { ANIMCMD_FRAME(16, 1), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A74[] = { ANIMCMD_FRAME(20, 1), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A7C[] = { ANIMCMD_FRAME(0, 1, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A84[] = { ANIMCMD_FRAME(4, 1, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A8C[] = { ANIMCMD_FRAME(8, 1, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gUnknown_08592A94[] = { ANIMCMD_FRAME(12, 1, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gUnknown_08592A9C[] = { gUnknown_08592A4C, gUnknown_08592A54, gUnknown_08592A5C, gUnknown_08592A64, gUnknown_08592A6C, gUnknown_08592A74, gUnknown_08592A7C, gUnknown_08592A84, gUnknown_08592A8C, gUnknown_08592A94, }; // Unused const struct SpriteTemplate gUnknown_08592AC4 = { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gUnknown_08592A9C, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_8100E1C, }; const struct SpriteTemplate gProtectSpriteTemplate = { .tileTag = ANIM_TAG_PROTECT, .paletteTag = ANIM_TAG_PROTECT, .oam = &gOamData_AffineOff_ObjBlend_64x64, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimProtect, }; const union AffineAnimCmd gMilkBottleAffineAnimCmds1[] = { AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd gMilkBottleAffineAnimCmds2[] = { AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 12), AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6), AFFINEANIMCMD_FRAME(0x0, 0x0, -2, 24), AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6), AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 12), AFFINEANIMCMD_JUMP(0), }; const union AffineAnimCmd *const gMilkBottleAffineAnimTable[] = { gMilkBottleAffineAnimCmds1, gMilkBottleAffineAnimCmds2, }; const struct SpriteTemplate gMilkBottleSpriteTemplate = { .tileTag = ANIM_TAG_MILK_BOTTLE, .paletteTag = ANIM_TAG_MILK_BOTTLE, .oam = &gOamData_AffineNormal_ObjBlend_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gMilkBottleAffineAnimTable, .callback = AnimMilkBottle, }; const union AnimCmd gGrantingStarsAnimCmds[] = { ANIMCMD_FRAME(0, 7), ANIMCMD_FRAME(16, 7), ANIMCMD_FRAME(32, 7), ANIMCMD_FRAME(48, 7), ANIMCMD_FRAME(64, 7), ANIMCMD_FRAME(80, 7), ANIMCMD_FRAME(96, 7), ANIMCMD_FRAME(112, 7), ANIMCMD_JUMP(0), }; const union AnimCmd *const gGrantingStarsAnimTable[] = { gGrantingStarsAnimCmds, }; const struct SpriteTemplate gGrantingStarsSpriteTemplate = { .tileTag = ANIM_TAG_SPARKLE_2, .paletteTag = ANIM_TAG_SPARKLE_2, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gGrantingStarsAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimGrantingStars, }; const struct SpriteTemplate gSparklingStarsSpriteTemplate = { .tileTag = ANIM_TAG_SPARKLE_2, .paletteTag = ANIM_TAG_SPARKLE_2, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gGrantingStarsAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSparkingStars, }; const union AnimCmd gUnknown_08592BAC[] = { ANIMCMD_FRAME(0, 10), ANIMCMD_FRAME(4, 10), ANIMCMD_FRAME(8, 10), ANIMCMD_FRAME(12, 10), ANIMCMD_FRAME(16, 26), ANIMCMD_FRAME(16, 5), ANIMCMD_FRAME(20, 5), ANIMCMD_FRAME(24, 15), ANIMCMD_END, }; const union AnimCmd gUnknown_08592BD0[] = { ANIMCMD_FRAME(0, 10, .hFlip = TRUE), ANIMCMD_FRAME(4, 10, .hFlip = TRUE), ANIMCMD_FRAME(8, 10, .hFlip = TRUE), ANIMCMD_FRAME(12, 10, .hFlip = TRUE), ANIMCMD_FRAME(16, 26, .hFlip = TRUE), ANIMCMD_FRAME(16, 5, .hFlip = TRUE), ANIMCMD_FRAME(20, 5, .hFlip = TRUE), ANIMCMD_FRAME(24, 15, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gUnknown_08592BF4[] = { gUnknown_08592BAC, gUnknown_08592BD0, }; // Unused const struct SpriteTemplate gUnknown_08592BFC = { .tileTag = ANIM_TAG_BUBBLE_BURST, .paletteTag = ANIM_TAG_BUBBLE_BURST, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gUnknown_08592BF4, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_8101440, }; const union AnimCmd gSleepLetterZAnimCmds[] = { ANIMCMD_FRAME(0, 40), ANIMCMD_END, }; const union AnimCmd *const gSleepLetterZAnimTable[] = { gSleepLetterZAnimCmds, }; const union AffineAnimCmd gSleepLetterZAffineAnimCmds1[] = { AFFINEANIMCMD_FRAME(0x14, 0x14, -30, 0), AFFINEANIMCMD_FRAME(0x8, 0x8, 1, 24), AFFINEANIMCMD_END, }; const union AffineAnimCmd gSleepLetterZAffineAnimCmds1_2[] = { AFFINEANIMCMD_LOOP(0), AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 24), AFFINEANIMCMD_LOOP(10), }; const union AffineAnimCmd gSleepLetterZAffineAnimCmds2[] = { AFFINEANIMCMD_FRAME(0x14, 0x14, 30, 0), AFFINEANIMCMD_FRAME(0x8, 0x8, -1, 24), AFFINEANIMCMD_END, }; const union AffineAnimCmd gSleepLetterZAffineAnimCmds2_2[] = { AFFINEANIMCMD_LOOP(0), AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 24), AFFINEANIMCMD_LOOP(10), }; const union AffineAnimCmd *const gSleepLetterZAffineAnimTable[] = { gSleepLetterZAffineAnimCmds1, gSleepLetterZAffineAnimCmds2, }; const struct SpriteTemplate gSleepLetterZSpriteTemplate = { .tileTag = ANIM_TAG_LETTER_Z, .paletteTag = ANIM_TAG_LETTER_Z, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gSleepLetterZAnimTable, .images = NULL, .affineAnims = gSleepLetterZAffineAnimTable, .callback = AnimSleepLetterZ, }; const struct SpriteTemplate gLockOnTargetSpriteTemplate = { .tileTag = ANIM_TAG_LOCK_ON, .paletteTag = ANIM_TAG_LOCK_ON, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimLockOnTarget, }; const struct SpriteTemplate gLockOnMoveTargetSpriteTemplate = { .tileTag = ANIM_TAG_LOCK_ON, .paletteTag = ANIM_TAG_LOCK_ON, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimLockOnMoveTarget, }; const s8 gInclineMonCoordTable[][2] = { { 64, 64}, { 0, -64}, {-64, 64}, { 32, -32}, }; const struct SpriteTemplate gBowMonSpriteTemplate = { .tileTag = 0, .paletteTag = 0, .oam = &gDummyOamData, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimBowMon, }; // Unused const struct SpriteTemplate gUnknown_08592CF0 = { .tileTag = 0, .paletteTag = 0, .oam = &gDummyOamData, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_8101B90, }; const union AnimCmd gSlashSliceAnimCmds1[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(48, 4), ANIMCMD_END, }; const union AnimCmd gSlashSliceAnimCmds2[] = { ANIMCMD_FRAME(48, 4), ANIMCMD_END, }; const union AnimCmd *const gSlashSliceAnimTable[] = { gSlashSliceAnimCmds1, gSlashSliceAnimCmds2, }; const struct SpriteTemplate gSlashSliceSpriteTemplate = { .tileTag = ANIM_TAG_SLASH, .paletteTag = ANIM_TAG_SLASH, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gSlashSliceAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSlashSlice, }; const struct SpriteTemplate gFalseSwipeSliceSpriteTemplate = { .tileTag = ANIM_TAG_SLASH_2, .paletteTag = ANIM_TAG_SLASH_2, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gSlashSliceAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimFalseSwipeSlice, }; const struct SpriteTemplate gFalseSwipePositionedSliceSpriteTemplate = { .tileTag = ANIM_TAG_SLASH_2, .paletteTag = ANIM_TAG_SLASH_2, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gSlashSliceAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimFalseSwipePositionedSlice, }; const union AnimCmd gEndureEnergyAnimCmds[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(8, 12), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(24, 4), ANIMCMD_END, }; const union AnimCmd *const gEndureEnergyAnimTable[] = { gEndureEnergyAnimCmds, }; const struct SpriteTemplate gEndureEnergySpriteTemplate = { .tileTag = ANIM_TAG_FOCUS_ENERGY, .paletteTag = ANIM_TAG_FOCUS_ENERGY, .oam = &gOamData_AffineOff_ObjNormal_16x32, .anims = gEndureEnergyAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimEndureEnergy, }; const union AnimCmd gSharpenSphereAnimCmds[] = { ANIMCMD_FRAME(0, 18), ANIMCMD_FRAME(0, 6), ANIMCMD_FRAME(16, 18), ANIMCMD_FRAME(0, 6), ANIMCMD_FRAME(16, 6), ANIMCMD_FRAME(32, 18), ANIMCMD_FRAME(16, 6), ANIMCMD_FRAME(32, 6), ANIMCMD_FRAME(48, 18), ANIMCMD_FRAME(32, 6), ANIMCMD_FRAME(48, 6), ANIMCMD_FRAME(64, 18), ANIMCMD_FRAME(48, 6), ANIMCMD_FRAME(64, 54), ANIMCMD_END, }; const union AnimCmd *const gSharpenSphereAnimTable[] = { gSharpenSphereAnimCmds, }; const struct SpriteTemplate gSharpenSphereSpriteTemplate = { .tileTag = ANIM_TAG_SPHERE_TO_CUBE, .paletteTag = ANIM_TAG_SPHERE_TO_CUBE, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gSharpenSphereAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSharpenSphere, }; const struct SpriteTemplate gOctazookaBallSpriteTemplate = { .tileTag = ANIM_TAG_BLACK_BALL, .paletteTag = ANIM_TAG_BLACK_BALL, .oam = &gOamData_AffineOff_ObjNormal_8x8, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = TranslateAnimSpriteToTargetMonLocation, }; const union AnimCmd gOctazookaAnimCmds[] = { ANIMCMD_FRAME(0, 3), ANIMCMD_FRAME(16, 3), ANIMCMD_FRAME(32, 3), ANIMCMD_FRAME(48, 3), ANIMCMD_FRAME(64, 3), ANIMCMD_END, }; const union AnimCmd *const gOctazookaAnimTable[] = { gOctazookaAnimCmds, }; const struct SpriteTemplate gOctazookaSmokeSpriteTemplate = { .tileTag = ANIM_TAG_GRAY_SMOKE, .paletteTag = ANIM_TAG_GRAY_SMOKE, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gOctazookaAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSpriteOnMonPos, }; const union AnimCmd gConversionAnimCmds[] = { ANIMCMD_FRAME(3, 5), ANIMCMD_FRAME(2, 5), ANIMCMD_FRAME(1, 5), ANIMCMD_FRAME(0, 5), ANIMCMD_END, }; const union AnimCmd *const gConversionAnimTable[] = { gConversionAnimCmds, }; const union AffineAnimCmd gConversionAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), AFFINEANIMCMD_END, }; const union AffineAnimCmd *const gConversionAffineAnimTable[] = { gConversionAffineAnimCmds, }; const struct SpriteTemplate gConversionSpriteTemplate = { .tileTag = ANIM_TAG_CONVERSION, .paletteTag = ANIM_TAG_CONVERSION, .oam = &gOamData_AffineDouble_ObjBlend_8x8, .anims = gConversionAnimTable, .images = NULL, .affineAnims = gConversionAffineAnimTable, .callback = AnimConversion, }; const union AnimCmd gConversion2AnimCmds[] = { ANIMCMD_FRAME(0, 5), ANIMCMD_FRAME(1, 5), ANIMCMD_FRAME(2, 5), ANIMCMD_FRAME(3, 5), ANIMCMD_END, }; const union AnimCmd *const gConversion2AnimTable[] = { gConversion2AnimCmds, }; const struct SpriteTemplate gConversion2SpriteTemplate = { .tileTag = ANIM_TAG_CONVERSION, .paletteTag = ANIM_TAG_CONVERSION, .oam = &gOamData_AffineDouble_ObjBlend_8x8, .anims = gConversion2AnimTable, .images = NULL, .affineAnims = gConversionAffineAnimTable, .callback = AnimConversion2, }; const struct SpriteTemplate gMoonSpriteTemplate = { .tileTag = ANIM_TAG_MOON, .paletteTag = ANIM_TAG_MOON, .oam = &gOamData_AffineOff_ObjBlend_64x64, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimMoon, }; const union AnimCmd gMoonlightSparkleAnimCmds[] = { ANIMCMD_FRAME(0, 8), ANIMCMD_FRAME(4, 8), ANIMCMD_FRAME(8, 8), ANIMCMD_FRAME(12, 8), ANIMCMD_JUMP(0), }; const union AnimCmd *const gMoonlightSparkleAnimTable[] = { gMoonlightSparkleAnimCmds, }; const struct SpriteTemplate gMoonlightSparkleSpriteTemplate = { .tileTag = ANIM_TAG_GREEN_SPARKLE, .paletteTag = ANIM_TAG_GREEN_SPARKLE, .oam = &gOamData_AffineOff_ObjNormal_16x16, .anims = gMoonlightSparkleAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimMoonlightSparkle, }; const union AnimCmd gHealingBlueStarAnimCmds[] = { ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(16, 2), ANIMCMD_FRAME(32, 2), ANIMCMD_FRAME(48, 3), ANIMCMD_FRAME(64, 5), ANIMCMD_FRAME(80, 3), ANIMCMD_FRAME(96, 2), ANIMCMD_FRAME(0, 2), ANIMCMD_END, }; const union AnimCmd *const gHealingBlueStarAnimTable[] = { gHealingBlueStarAnimCmds, }; const struct SpriteTemplate gHealingBlueStarSpriteTemplate = { .tileTag = ANIM_TAG_BLUE_STAR, .paletteTag = ANIM_TAG_BLUE_STAR, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gHealingBlueStarAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSpriteOnMonPos, }; const struct SpriteTemplate gHornHitSpriteTemplate = { .tileTag = ANIM_TAG_HORN_HIT, .paletteTag = ANIM_TAG_HORN_HIT, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimHornHit, }; const union AnimCmd gSuperFangAnimCmds[] = { ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(16, 2), ANIMCMD_FRAME(32, 2), ANIMCMD_FRAME(48, 2), ANIMCMD_END, }; const union AnimCmd *const gSuperFangAnimTable[] = { gSuperFangAnimCmds, }; const struct SpriteTemplate gSuperFangSpriteTemplate = { .tileTag = ANIM_TAG_FANG_ATTACK, .paletteTag = ANIM_TAG_FANG_ATTACK, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gSuperFangAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimSuperFang, }; const union AnimCmd gWavyMusicNotesAnimCmds1[] = { ANIMCMD_FRAME(0, 10), ANIMCMD_END, }; const union AnimCmd gWavyMusicNotesAnimCmds2[] = { ANIMCMD_FRAME(4, 10), ANIMCMD_END, }; const union AnimCmd gWavyMusicNotesAnimCmds3[] = { ANIMCMD_FRAME(8, 41), ANIMCMD_END, }; const union AnimCmd gWavyMusicNotesAnimCmds4[] = { ANIMCMD_FRAME(12, 10), ANIMCMD_END, }; const union AnimCmd gWavyMusicNotesAnimCmds5[] = { ANIMCMD_FRAME(16, 10), ANIMCMD_END, }; const union AnimCmd gWavyMusicNotesAnimCmds6[] = { ANIMCMD_FRAME(20, 10), ANIMCMD_END, }; const union AnimCmd gWavyMusicNotesAnimCmds7[] = { ANIMCMD_FRAME(0, 10, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gWavyMusicNotesAnimCmds8[] = { ANIMCMD_FRAME(4, 10, .vFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gMusicNotesAnimTable[] = { gWavyMusicNotesAnimCmds1, gWavyMusicNotesAnimCmds2, gWavyMusicNotesAnimCmds3, gWavyMusicNotesAnimCmds4, gWavyMusicNotesAnimCmds5, gWavyMusicNotesAnimCmds6, gWavyMusicNotesAnimCmds7, gWavyMusicNotesAnimCmds8, }; const union AffineAnimCmd gWavyMusicNotesAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(0xC, 0xC, 0, 16), AFFINEANIMCMD_FRAME(0xFFF4, 0xFFF4, 0, 16), AFFINEANIMCMD_JUMP(0), }; const union AffineAnimCmd *const gMusicNotesAffineAnimTable[] = { gWavyMusicNotesAffineAnimCmds, }; const struct SpriteTemplate gWavyMusicNotesSpriteTemplate = { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_AffineDouble_ObjNormal_16x16, .anims = gMusicNotesAnimTable, .images = NULL, .affineAnims = gMusicNotesAffineAnimTable, .callback = AnimWavyMusicNotes, }; const u16 gParticlesColorBlendTable[][6] = { {ANIM_TAG_MUSIC_NOTES, RGB(31, 31, 31), RGB(31, 26, 28), RGB(31, 22, 26), RGB(31, 17, 24), RGB(31, 13, 22)}, {ANIM_TAG_BENT_SPOON, RGB(31, 31, 31), RGB(25, 31, 26), RGB(20, 31, 21), RGB(15, 31, 16), RGB(10, 31, 12)}, {ANIM_TAG_SPHERE_TO_CUBE, RGB(31, 31, 31), RGB(31, 31, 24), RGB(31, 31, 17), RGB(31, 31, 10), RGB(31, 31, 3)}, {ANIM_TAG_LARGE_FRESH_EGG, RGB(31, 31, 31), RGB(26, 28, 31), RGB(21, 26, 31), RGB(16, 24, 31), RGB(12, 22, 31)}, }; const struct SpriteTemplate gFastFlyingMusicNotesSpriteTemplate = { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_AffineDouble_ObjNormal_16x16, .anims = gMusicNotesAnimTable, .images = NULL, .affineAnims = gMusicNotesAffineAnimTable, .callback = AnimFlyingMusicNotes, }; const struct SpriteTemplate gBellyDrumHandSpriteTemplate = { .tileTag = ANIM_TAG_PURPLE_HAND_OUTLINE, .paletteTag = ANIM_TAG_PURPLE_HAND_OUTLINE, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimBellyDrumHand, }; const union AffineAnimCmd gSlowFlyingMusicNotesAffineAnimCmds[] = { AFFINEANIMCMD_FRAME(0xA0, 0xA0, 0, 0), AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 1), AFFINEANIMCMD_JUMP(1), }; const union AffineAnimCmd *const gSlowFlyingMusicNotesAffineAnimTable[] = { gSlowFlyingMusicNotesAffineAnimCmds, }; const struct SpriteTemplate gSlowFlyingMusicNotesSpriteTemplate = { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_AffineDouble_ObjNormal_16x16, .anims = gMusicNotesAnimTable, .images = NULL, .affineAnims = gSlowFlyingMusicNotesAffineAnimTable, .callback = AnimSlowFlyingMusicNotes, }; const union AnimCmd gMetronomeThroughtBubbleAnimCmds1[] = { ANIMCMD_FRAME(0, 2, .hFlip = TRUE), ANIMCMD_FRAME(16, 2, .hFlip = TRUE), ANIMCMD_FRAME(32, 2, .hFlip = TRUE), ANIMCMD_FRAME(48, 2, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gMetronomeThroughtBubbleAnimCmds3[] = { ANIMCMD_FRAME(48, 2, .hFlip = TRUE), ANIMCMD_FRAME(32, 2, .hFlip = TRUE), ANIMCMD_FRAME(16, 2, .hFlip = TRUE), ANIMCMD_FRAME(0, 2, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gMetronomeThroughtBubbleAnimCmds2[] = { ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(16, 2), ANIMCMD_FRAME(32, 2), ANIMCMD_FRAME(48, 2), ANIMCMD_END, }; const union AnimCmd gMetronomeThroughtBubbleAnimCmds4[] = { ANIMCMD_FRAME(48, 2), ANIMCMD_FRAME(32, 2), ANIMCMD_FRAME(16, 2), ANIMCMD_FRAME(0, 2), ANIMCMD_END, }; const union AnimCmd *const gMetronomeThroughtBubbleAnimTable[] = { gMetronomeThroughtBubbleAnimCmds1, gMetronomeThroughtBubbleAnimCmds2, gMetronomeThroughtBubbleAnimCmds3, gMetronomeThroughtBubbleAnimCmds4, }; const struct SpriteTemplate gThoughtBubbleSpriteTemplate = { .tileTag = ANIM_TAG_THOUGHT_BUBBLE, .paletteTag = ANIM_TAG_THOUGHT_BUBBLE, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gMetronomeThroughtBubbleAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimThoughtBubble, }; const union AffineAnimCmd gMetronomeFingerAffineAnimCmds1[] = { AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0), AFFINEANIMCMD_FRAME(0x1E, 0x1E, 0, 8), AFFINEANIMCMD_END, }; const union AffineAnimCmd gMetronomeFingerAffineAnimCmds2[] = { AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 11), AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 11), AFFINEANIMCMD_LOOP(2), AFFINEANIMCMD_FRAME(0xFFE2, 0xFFE2, 0, 8), AFFINEANIMCMD_END, }; const union AffineAnimCmd gMetronomeFingerAffineAnimCmds2_2[] = { AFFINEANIMCMD_FRAME(16, 16, 0, 0), AFFINEANIMCMD_FRAME(30, 30, 0, 8), AFFINEANIMCMD_FRAME(0, 0, 0, 16), AFFINEANIMCMD_LOOP(0), AFFINEANIMCMD_FRAME(0, 0, 4, 11), AFFINEANIMCMD_FRAME(0, 0, -4, 11), AFFINEANIMCMD_LOOP(2), AFFINEANIMCMD_FRAME(-30, -30, 0, 8), AFFINEANIMCMD_END, }; const union AffineAnimCmd *const gMetronomeFingerAffineAnimTable[] = { gMetronomeFingerAffineAnimCmds1, gMetronomeFingerAffineAnimCmds2, }; const struct SpriteTemplate gMetronomeFingerSpriteTemplate = { .tileTag = ANIM_TAG_FINGER, .paletteTag = ANIM_TAG_FINGER, .oam = &gOamData_AffineDouble_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gMetronomeFingerAffineAnimTable, .callback = AnimMetronomeFinger, }; const struct SpriteTemplate gFollowMeFingerSpriteTemplate = { .tileTag = ANIM_TAG_FINGER, .paletteTag = ANIM_TAG_FINGER, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gMetronomeFingerAffineAnimTable, .callback = AnimFollowMeFinger, }; const union AnimCmd gTauntFingerAnimCmds1[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; const union AnimCmd gTauntFingerAnimCmds2[] = { ANIMCMD_FRAME(0, 1, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd gTauntFingerAnimCmds3[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), ANIMCMD_FRAME(32, 4), ANIMCMD_END, }; const union AnimCmd gTauntFingerAnimCmds4[] = { ANIMCMD_FRAME(0, 4, .hFlip = TRUE), ANIMCMD_FRAME(16, 4, .hFlip = TRUE), ANIMCMD_FRAME(32, 4, .hFlip = TRUE), ANIMCMD_FRAME(16, 4, .hFlip = TRUE), ANIMCMD_FRAME(0, 4, .hFlip = TRUE), ANIMCMD_FRAME(16, 4, .hFlip = TRUE), ANIMCMD_FRAME(32, 4, .hFlip = TRUE), ANIMCMD_END, }; const union AnimCmd *const gTauntFingerAnimTable[] = { gTauntFingerAnimCmds1, gTauntFingerAnimCmds2, gTauntFingerAnimCmds3, gTauntFingerAnimCmds4, }; const struct SpriteTemplate gTauntFingerSpriteTemplate = { .tileTag = ANIM_TAG_FINGER_2, .paletteTag = ANIM_TAG_FINGER_2, .oam = &gOamData_AffineOff_ObjNormal_32x32, .anims = gTauntFingerAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = AnimTauntFinger, }; // Animates the falling particles that horizontally wave back and forth. // Used by Sleep Powder, Stun Spore, and Poison Powder. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: total duration in frames // arg 3: vertical movement speed (sub-pixel value) // arg 4: wave amplitude // arg 5: wave speed void AnimMovePowderParticle(struct Sprite* sprite) { sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = gBattleAnimArgs[3]; if (GetBattlerSide(gBattleAnimAttacker)) { sprite->data[3] = -gBattleAnimArgs[4]; } else { sprite->data[3] = gBattleAnimArgs[4]; } sprite->data[4] = gBattleAnimArgs[5]; sprite->callback = AnimMovePowderParticleStep; } static void AnimMovePowderParticleStep(struct Sprite* sprite) { if (sprite->data[0] > 0) { sprite->data[0]--; sprite->pos2.y = sprite->data[2] >> 8; sprite->data[2] += sprite->data[1]; sprite->pos2.x = Sin(sprite->data[5], sprite->data[3]); sprite->data[5] = (sprite->data[5] + sprite->data[4]) & 0xFF; } else { DestroyAnimSprite(sprite); } } // Moves an energy orb towards the center of the mon. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: duration void AnimPowerAbsorptionOrb(struct Sprite* sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); sprite->callback = StartAnimLinearTranslation; StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); } // Moves an orb in a straight line towards the target mon. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: duration // arg 3: sprite anim number void AnimSolarbeamBigOrb(struct Sprite* sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); StartSpriteAnim(sprite, gBattleAnimArgs[3]); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); sprite->callback = StartAnimLinearTranslation; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } // Moves a small orb in a wavy pattern towards the target mon. // The small orb "circles" the big orbs in AnimSolarbeamBigOrb. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: duration // arg 3: initial wave offset void AnimSolarbeamSmallOrb(struct Sprite* sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = sprite->pos1.x; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); InitAnimLinearTranslation(sprite); sprite->data[5] = gBattleAnimArgs[3]; sprite->callback = AnimSolarbeamSmallOrbStep; sprite->callback(sprite); } static void AnimSolarbeamSmallOrbStep(struct Sprite* sprite) { if (AnimTranslateLinear(sprite)) { DestroySprite(sprite); } else { if (sprite->data[5] > 0x7F) sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + 1; else sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + 6; sprite->pos2.x += Sin(sprite->data[5], 5); sprite->pos2.y += Cos(sprite->data[5], 14); sprite->data[5] = (sprite->data[5] + 15) & 0xFF; } } // Creates 15 small secondary orbs used in the solarbeam anim effect. // There is a 7-frame delay between each of them. // No args. void AnimTask_CreateSmallSolarbeamOrbs(u8 taskId) { if (--gTasks[taskId].data[0] == -1) { gTasks[taskId].data[1]++; gTasks[taskId].data[0] = 6; gBattleAnimArgs[0] = 15; gBattleAnimArgs[1] = 0; gBattleAnimArgs[2] = 80; gBattleAnimArgs[3] = 0; CreateSpriteAndAnimate(&gSolarbeamSmallOrbSpriteTemplate, 0, 0, GetBattlerSpriteSubpriority(gBattleAnimTarget) + 1); } if (gTasks[taskId].data[1] == 15) DestroyAnimVisualTask(taskId); } // Moves an orb from the target mon to the attacking mon in an arc-like fashion. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: wave amplitude // arg 3: wave period (lower means faster wave) void AnimAbsorptionOrb(struct Sprite* sprite) { InitSpritePosToAnimTarget(sprite, TRUE); sprite->data[0] = gBattleAnimArgs[3]; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); sprite->data[5] = gBattleAnimArgs[2]; InitAnimArcTranslation(sprite); sprite->callback = AnimAbsorptionOrbStep; } static void AnimAbsorptionOrbStep(struct Sprite* sprite) { if (TranslateAnimHorizontalArc(sprite)) DestroyAnimSprite(sprite); } // Moves an orb in a wave-like fashion towards the target mon. The wave's // properties and the sprite anim are randomly determined. void AnimHyperBeamOrb(struct Sprite* sprite) { u16 speed; u16 animNum = Random2(); StartSpriteAnim(sprite, animNum % 8); sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) sprite->pos1.x -= 20; else sprite->pos1.x += 20; speed = Random2(); sprite->data[0] = (speed & 31) + 64; sprite->data[1] = sprite->pos1.x; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); InitAnimFastLinearTranslationWithSpeed(sprite); sprite->data[5] = Random2() & 0xFF; sprite->data[6] = sprite->subpriority; sprite->callback = AnimHyperBeamOrbStep; sprite->callback(sprite); } static void AnimHyperBeamOrbStep(struct Sprite* sprite) { if (AnimFastTranslateLinear(sprite)) { DestroyAnimSprite(sprite); } else { sprite->pos2.y += Cos(sprite->data[5], 12); if (sprite->data[5] < 0x7F) sprite->subpriority = sprite->data[6]; else sprite->subpriority = sprite->data[6] + 1; sprite->data[5] += 24; sprite->data[5] &= 0xFF; } } // seed (sprouts a sapling from a seed.) // Used by Leech Seed. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: target x pixel offset // arg 3: target y pixel offset // arg 4: duration // arg 5: wave amplitude void AnimLeechSeed(struct Sprite* sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) gBattleAnimArgs[2] = -gBattleAnimArgs[2]; sprite->data[0] = gBattleAnimArgs[4]; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[2]; sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[3]; sprite->data[5] = gBattleAnimArgs[5]; InitAnimArcTranslation(sprite); sprite->callback = AnimLeechSeedStep; } static void AnimLeechSeedStep(struct Sprite* sprite) { if (TranslateAnimHorizontalArc(sprite)) { sprite->invisible = 1; sprite->data[0] = 10; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData6(sprite, AnimLeechSeedSprouts); } } static void AnimLeechSeedSprouts(struct Sprite* sprite) { sprite->invisible = 0; StartSpriteAnim(sprite, 1); sprite->data[0] = 60; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } // Moves a spore particle in a halo around the target mon. // The sprite's priority is updated to give the effect of going // behind the mon's sprite. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: initial wave offset // arg 3: duration // arg 4: blend (0 = off, 1 = on) void AnimSporeParticle(struct Sprite* sprite) { InitSpritePosToAnimTarget(sprite, TRUE); StartSpriteAnim(sprite, gBattleAnimArgs[4]); if (gBattleAnimArgs[4] == 1) sprite->oam.objMode = ST_OAM_OBJ_BLEND; sprite->data[0] = gBattleAnimArgs[3]; sprite->data[1] = gBattleAnimArgs[2]; sprite->callback = AnimSporeParticleStep; sprite->callback(sprite); } static void AnimSporeParticleStep(struct Sprite* sprite) { sprite->pos2.x = Sin(sprite->data[1], 32); sprite->pos2.y = Cos(sprite->data[1], -3) + ((sprite->data[2] += 24) >> 8); if ((u16)(sprite->data[1] - 0x40) < 0x80) { sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget); } else { u8 priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1; if (priority > 3) priority = 3; sprite->oam.priority = priority; } sprite->data[1] += 2; sprite->data[1] &= 0xFF; if (--sprite->data[0] == -1) DestroyAnimSprite(sprite); } // In a double battle, Updates the mon sprite background priorities to allow // the circling effect controlled by AnimSporeParticle. // No args. void AnimTask_SporeDoubleBattle(u8 taskId) { if (IsContest() || !IsDoubleBattle()) { DestroyAnimVisualTask(taskId); } else { if (GetBattlerSpriteBGPriorityRank(gBattleAnimTarget) == 1) SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 3); else SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); DestroyAnimVisualTask(taskId); } } // Rotates a big flower around the attacking mon, and slowly floats // downward. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: target y pixel offset // arg 3: duration void AnimPetalDanceBigFlower(struct Sprite* sprite) { InitSpritePosToAnimAttacker(sprite, FALSE); sprite->data[0] = gBattleAnimArgs[3]; sprite->data[1] = sprite->pos1.x; sprite->data[2] = sprite->pos1.x; sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2]; InitAnimLinearTranslation(sprite); sprite->data[5] = 0x40; sprite->callback = AnimPetalDanceBigFlowerStep; sprite->callback(sprite); } static void AnimPetalDanceBigFlowerStep(struct Sprite* sprite) { if (!AnimTranslateLinear(sprite)) { sprite->pos2.x += Sin(sprite->data[5], 32); sprite->pos2.y += Cos(sprite->data[5], -5); if ((u16)(sprite->data[5] - 0x40) < 0x80) sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 1; else sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) + 1; sprite->data[5] = (sprite->data[5] + 5) & 0xFF; } else { DestroyAnimSprite(sprite); } } // Slowly floats a small flower downard, while swaying from right to left. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: target y pixel offset // arg 3: duration void AnimPetalDanceSmallFlower(struct Sprite* sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); sprite->data[0] = gBattleAnimArgs[3]; sprite->data[1] = sprite->pos1.x; sprite->data[2] = sprite->pos1.x; sprite->data[3] = sprite->pos1.y; sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2]; InitAnimLinearTranslation(sprite); sprite->data[5] = 0x40; sprite->callback = AnimPetalDanceSmallFlowerStep; sprite->callback(sprite); } static void AnimPetalDanceSmallFlowerStep(struct Sprite* sprite) { if (!AnimTranslateLinear(sprite)) { sprite->pos2.x += Sin(sprite->data[5], 8); if ((u16)(sprite->data[5] - 59) < 5 || (u16)(sprite->data[5] - 187) < 5) sprite->oam.matrixNum ^= ST_OAM_HFLIP; sprite->data[5] += 5; sprite->data[5] &= 0xFF; } else { DestroyAnimSprite(sprite); } } // Shoots a leaf upward, then floats it downward while swaying back and forth. // arg 0: upward x delta per frame // arg 1: upward y delta per frame // arg 2: upward duration void AnimRazorLeafParticle(struct Sprite* sprite) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); sprite->data[0] = gBattleAnimArgs[0]; sprite->data[1] = gBattleAnimArgs[1]; sprite->data[2] = gBattleAnimArgs[2]; sprite->callback = AnimRazorLeafParticleStep1; } static void AnimRazorLeafParticleStep1(struct Sprite* sprite) { if (!sprite->data[2]) { if (sprite->data[1] & 1) { sprite->data[0] = 0x80; sprite->data[1] = 0; sprite->data[2] = 0; } else { sprite->data[0] = 0; sprite->data[1] = 0; sprite->data[2] = 0; } sprite->callback = AnimRazorLeafParticleStep2; } else { sprite->data[2]--; sprite->pos1.x += sprite->data[0]; sprite->pos1.y += sprite->data[1]; } } static void AnimRazorLeafParticleStep2(struct Sprite* sprite) { if (GetBattlerSide(gBattleAnimAttacker)) sprite->pos2.x = -Sin(sprite->data[0], 25); else sprite->pos2.x = Sin(sprite->data[0], 25); sprite->data[0] += 2; sprite->data[0] &= 0xFF; sprite->data[1]++; if (!(sprite->data[1] & 1)) sprite->pos2.y++; if (sprite->data[1] > 80) DestroyAnimSprite(sprite); } // Animates a sprite that moves linearly from one location to another, with a // single-cycle sine wave added to the y position along the way. // Used by Razor Leaf and Magical Leaf. // arg 0: initial x offset // arg 1: initial y offset // arg 2: target x offset // arg 3: target y offset // arg 4: translation duration // arg 5: wave amplitude // arg 6: target between double battle opponents (boolean) void AnimTranslateLinearSingleSineWave(struct Sprite* sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) gBattleAnimArgs[2] = -gBattleAnimArgs[2]; sprite->data[0] = gBattleAnimArgs[4]; if (!gBattleAnimArgs[6]) { sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2]; sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3]; } else { SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->data[2], &sprite->data[4]); sprite->data[2] += gBattleAnimArgs[2]; sprite->data[4] += gBattleAnimArgs[3]; } sprite->data[5] = gBattleAnimArgs[5]; InitAnimArcTranslation(sprite); if (GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)) sprite->data[0] = 1; else sprite->data[0] = 0; sprite->callback = AnimTranslateLinearSingleSineWaveStep; } static void AnimTranslateLinearSingleSineWaveStep(struct Sprite* sprite) { bool8 destroy = FALSE; s16 a = sprite->data[0]; s16 b = sprite->data[7]; s16 r0; sprite->data[0] = 1; TranslateAnimHorizontalArc(sprite); r0 = sprite->data[7]; sprite->data[0] = a; if (b > 200 && r0 < 56 && sprite->oam.affineParam == 0) sprite->oam.affineParam++; if (sprite->oam.affineParam && sprite->data[0]) { sprite->invisible ^= 1; sprite->oam.affineParam++; if (sprite->oam.affineParam == 30) destroy = TRUE; } if (sprite->pos1.x + sprite->pos2.x > 256 || sprite->pos1.x + sprite->pos2.x < -16 || sprite->pos1.y + sprite->pos2.y > 160 || sprite->pos1.y + sprite->pos2.y < -16) destroy = TRUE; if (destroy) DestroyAnimSprite(sprite); } // Animates particles in the Twister move animation. // arg 0: duration // arg 1: total y delta (the particles rise upward) // arg 2: wave period (higher means faster wave) // arg 3: wave amplitude // arg 4: speedup frame (particles move faster at the end of the animation) void AnimMoveTwisterParticle(struct Sprite* sprite) { if (IsDoubleBattle() == TRUE) SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->pos1.x, &sprite->pos1.y); sprite->pos1.y += 32; sprite->data[0] = gBattleAnimArgs[0]; sprite->data[1] = gBattleAnimArgs[1]; sprite->data[2] = gBattleAnimArgs[2]; sprite->data[3] = gBattleAnimArgs[3]; sprite->data[4] = gBattleAnimArgs[4]; sprite->callback = AnimMoveTwisterParticleStep; } static void AnimMoveTwisterParticleStep(struct Sprite* sprite) { if (sprite->data[1] == 0xFF) { sprite->pos1.y -= 2; } else if (sprite->data[1] > 0) { sprite->pos1.y -= 2; sprite->data[1] -= 2; } sprite->data[5] += sprite->data[2]; if (sprite->data[0] < sprite->data[4]) sprite->data[5] += sprite->data[2]; sprite->data[5] &= 0xFF; sprite->pos2.x = Cos(sprite->data[5], sprite->data[3]); sprite->pos2.y = Sin(sprite->data[5], 5); if (sprite->data[5] < 0x80) sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) - 1; else sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1; if (--sprite->data[0] == 0) DestroyAnimSprite(sprite); } // Squeezes a constricting "rope" several times via affine animations. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: affine anim num // arg 3: num squeezes void AnimConstrictBinding(struct Sprite* sprite) { InitSpritePosToAnimTarget(sprite, FALSE); sprite->affineAnimPaused = 1; StartSpriteAffineAnim(sprite, gBattleAnimArgs[2]); sprite->data[6] = gBattleAnimArgs[2]; sprite->data[7] = gBattleAnimArgs[3]; sprite->callback = AnimConstrictBindingStep1; } static void AnimConstrictBindingStep1(struct Sprite* sprite) { u8 spriteId; if ((u16)gBattleAnimArgs[ARG_RET_ID] == 0xFFFF) { sprite->affineAnimPaused = 0; spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); sprite->data[0] = 0x100; sprite->callback = AnimConstrictBindingStep2; } } static void AnimConstrictBindingStep2(struct Sprite* sprite) { u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); if (!sprite->data[2]) sprite->data[0] += 11; else sprite->data[0] -= 11; if (++sprite->data[1] == 6) { sprite->data[1] = 0; sprite->data[2] ^= 1; } if (sprite->affineAnimEnded) { if (--sprite->data[7] > 0) StartSpriteAffineAnim(sprite, sprite->data[6]); else DestroyAnimSprite(sprite); } } void AnimTask_ShrinkTargetCopy(u8 taskId) { u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); if (gSprites[spriteId].invisible) { DestroyAnimVisualTask(taskId); } else { PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND); gTasks[taskId].data[14] = gSprites[spriteId].oam.priority; gSprites[spriteId].oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget); spriteId = GetAnimBattlerSpriteId(ANIM_DEF_PARTNER); gTasks[taskId].data[15] = gSprites[spriteId].oam.priority; gSprites[spriteId].oam.priority = GetBattlerSpriteBGPriority(BATTLE_PARTNER(gBattleAnimTarget)); gTasks[taskId].data[0] = gBattleAnimArgs[0]; gTasks[taskId].data[1] = gBattleAnimArgs[1]; gTasks[taskId].data[11] = 0x100; gTasks[taskId].func = AnimTask_DuplicateAndShrinkToPosStep1; } } static void AnimTask_DuplicateAndShrinkToPosStep1(u8 taskId) { u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); gTasks[taskId].data[10] += gTasks[taskId].data[0]; gSprites[spriteId].pos2.x = gTasks[taskId].data[10] >> 8; if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER) gSprites[spriteId].pos2.x = -gSprites[spriteId].pos2.x; gTasks[taskId].data[11] += 16; SetSpriteRotScale(spriteId, gTasks[taskId].data[11], gTasks[taskId].data[11], 0); SetBattlerSpriteYOffsetFromYScale(spriteId); if (--gTasks[taskId].data[1] == 0) { gTasks[taskId].data[0] = 0; gTasks[taskId].func = AnimTask_DuplicateAndShrinkToPosStep2; } } static void AnimTask_DuplicateAndShrinkToPosStep2(u8 taskId) { if ((u16)gBattleAnimArgs[ARG_RET_ID] == 0xFFFF) { if (gTasks[taskId].data[0] == 0) { u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); ResetSpriteRotScale(spriteId); gSprites[spriteId].pos2.x = 0; gSprites[spriteId].pos2.y = 0; gSprites[spriteId].oam.priority = gTasks[taskId].data[14]; spriteId = GetAnimBattlerSpriteId(ANIM_DEF_PARTNER); gSprites[spriteId].oam.priority = gTasks[taskId].data[15]; gTasks[taskId].data[0]++; return; } } else { if (gTasks[taskId].data[0] == 0) return; } gTasks[taskId].data[0]++; if (gTasks[taskId].data[0] == 3) DestroyAnimVisualTask(taskId); } // Moves an orb from the target mon to the attacking mon. // arg 0: initial x pixel offset // arg 1: initial y pixel offset void AnimMimicOrb(struct Sprite* sprite) { switch (sprite->data[0]) { case 0: if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) gBattleAnimArgs[0] *= -1; sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[0]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[1]; sprite->invisible = 1; sprite->data[0]++; break; case 1: sprite->invisible = 0; if (sprite->affineAnimEnded) { ChangeSpriteAffineAnim(sprite, 1); sprite->data[0] = 25; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); sprite->callback = InitAndRunAnimFastLinearTranslation; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); break; } } } // Animates a root that flickers away after some time. // arg 0: x pixel offset // arg 1: y pixel offset // arg 2: sprite subpriority offset // arg 3: sprite anim num // arg 4: duration void AnimIngrainRoot(struct Sprite* sprite) { if (!sprite->data[0]) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y); sprite->pos2.x = gBattleAnimArgs[0]; sprite->pos2.y = gBattleAnimArgs[1]; sprite->subpriority = gBattleAnimArgs[2] + 30; StartSpriteAnim(sprite, gBattleAnimArgs[3]); sprite->data[2] = gBattleAnimArgs[4]; sprite->data[0]++; if (sprite->pos1.y + sprite->pos2.y > 120) sprite->pos1.y += sprite->pos2.y + sprite->pos1.y - 120; } sprite->callback = AnimRootFlickerOut; } // Places a root on the path to the target mon that flickers away after some time. // arg 0: percent along the path to the target mon // arg 1: x pixel offset // arg 2: y pixel offset // arg 3: sprite subpriority offset // arg 4: sprite anum num // arg 5: duration void AnimFrenzyPlantRoot(struct Sprite *sprite) { s16 attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); s16 attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); s16 targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); s16 targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); targetX -= attackerX; targetY -= attackerY; sprite->pos1.x = attackerX + targetX * gBattleAnimArgs[0] / 100; sprite->pos1.y = attackerY + targetY * gBattleAnimArgs[0] / 100; sprite->pos2.x = gBattleAnimArgs[1]; sprite->pos2.y = gBattleAnimArgs[2]; sprite->subpriority = gBattleAnimArgs[3] + 30; StartSpriteAnim(sprite, gBattleAnimArgs[4]); sprite->data[2] = gBattleAnimArgs[5]; sprite->callback = AnimRootFlickerOut; gUnknown_0203A0F8[0] = sprite->pos1.x; gUnknown_0203A0F8[1] = sprite->pos1.y; gUnknown_0203A0F8[2] = targetX; gUnknown_0203A0F8[3] = targetY; } static void AnimRootFlickerOut(struct Sprite* sprite) { if (++sprite->data[0] > (sprite->data[2] - 10)) sprite->invisible = sprite->data[0] % 2; if (sprite->data[0] > sprite->data[2]) DestroyAnimSprite(sprite); } // Moves an orb in a fast wavy path. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: horizontal velocity // arg 3: wave amplitude // arg 4: duration void AnimIngrainOrb(struct Sprite* sprite) { if (!sprite->data[0]) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[0]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + gBattleAnimArgs[1]; sprite->data[1] = gBattleAnimArgs[2]; sprite->data[2] = gBattleAnimArgs[3]; sprite->data[3] = gBattleAnimArgs[4]; } sprite->data[0]++; sprite->pos2.x = sprite->data[1] * sprite->data[0]; sprite->pos2.y = Sin((sprite->data[0] * 20) & 0xFF, sprite->data[2]); if (sprite->data[0] > sprite->data[3]) DestroyAnimSprite(sprite); } static void sub_80FF9B8(struct Sprite* sprite, s16 c) { int a = (sprite->pos1.x << 8) | sprite->pos1.y; int b = (sprite->data[6] << 8) | sprite->data[7]; c <<= 8; sprite->data[5] = a; sprite->data[6] = b; sprite->data[7] = c; } bool8 moveAlongLinearPath(struct Sprite* sprite) { u16 xStartPos = (u8)(sprite->data[5] >> 8); u16 yStartPos = (u8)sprite->data[5]; s32 xEndPos = (u8)(sprite->data[6] >> 8); s32 yEndPos = (u8)sprite->data[6]; s16 totalTime = sprite->data[7] >> 8; s16 currentTime = sprite->data[7] & 0xFF; s16 yEndPos_2; s16 r0; s32 var1; s32 vaxEndPos; if (xEndPos == 0) xEndPos = -32; else if (xEndPos == 255) xEndPos = 272; yEndPos_2 = yEndPos - yStartPos; r0 = xEndPos - xStartPos; var1 = r0 * currentTime / totalTime; vaxEndPos = yEndPos_2 * currentTime / totalTime; sprite->pos1.x = var1 + xStartPos; sprite->pos1.y = vaxEndPos + yStartPos; if (++currentTime == totalTime) return TRUE; sprite->data[7] = (totalTime << 8) | currentTime; return FALSE; } void AnimItemStealStep2(struct Sprite* sprite) { if (sprite->data[0] == 10) StartSpriteAffineAnim(sprite, 1); sprite->data[0]++; if (sprite->data[0] > 50) DestroyAnimSprite(sprite); } static void AnimItemStealStep1(struct Sprite* sprite) { sprite->data[0] += sprite->data[3] * 128 / sprite->data[4]; if (sprite->data[0] >= 128) { sprite->data[1]++; sprite->data[0] = 0; } sprite->pos2.y = Sin(sprite->data[0] + 128, 30 - sprite->data[1] * 8); if (moveAlongLinearPath(sprite)) { sprite->pos2.y = 0; sprite->data[0] = 0; sprite->callback = AnimItemStealStep2; } } void AnimPresent(struct Sprite* sprite) { s16 targetX; s16 targetY; InitSpritePosToAnimAttacker(sprite, FALSE); targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y); if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget) { sprite->data[6] = targetX; sprite->data[7] = targetY + 10; sub_80FF9B8(sprite, 60); sprite->data[3] = 1; } else { sprite->data[6] = targetX; sprite->data[7] = targetY + 10; sub_80FF9B8(sprite, 60); sprite->data[3] = 3; } sprite->data[4] = 60; sprite->callback = AnimItemStealStep1; } static void sub_80FFB90(struct Sprite* sprite) { int zero; sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]); zero = 0; if (sprite->data[0] > 0x7F) { sprite->data[1]++; sprite->data[0] = zero; } sprite->pos2.y = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8); if (moveAlongLinearPath(sprite)) { sprite->pos2.y = zero; sprite->data[0] = zero; DestroyAnimSprite(sprite); } } void AnimKnockOffItem(struct Sprite* sprite) { s16 targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y); if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) { sprite->data[6] = 0; sprite->data[7] = targetY + 10; sub_80FF9B8(sprite, 40); sprite->data[3] = 3; sprite->data[4] = 60; sprite->callback = AnimItemStealStep1; } else { sprite->data[6] = 255; sprite->data[7] = targetY + 10; if (IsContest()) sprite->data[6] = 0; sub_80FF9B8(sprite, 40); sprite->data[3] = 3; sprite->data[4] = 60; sprite->callback = sub_80FFB90; } } // Animates a heal particle upward. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: vertical velocity // arg 3: unused void AnimPresentHealParticle(struct Sprite* sprite) { if (!sprite->data[0]) { InitSpritePosToAnimTarget(sprite, FALSE); sprite->data[1] = gBattleAnimArgs[2]; } sprite->data[0]++; sprite->pos2.y = sprite->data[1] * sprite->data[0]; if (sprite->animEnded) DestroyAnimSprite(sprite); } void AnimItemSteal(struct Sprite* sprite) { s16 attackerX; s16 attackerY; InitSpritePosToAnimTarget(sprite, FALSE); attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y); if (BATTLE_PARTNER(gBattleAnimTarget) == gBattleAnimAttacker) { sprite->data[6] = attackerX; sprite->data[7] = attackerY + 10; sub_80FF9B8(sprite, 60); sprite->data[3] = 1; } else { sprite->data[6] = attackerX; sprite->data[7] = attackerY + 10; sub_80FF9B8(sprite, 60); sprite->data[3] = 3; } sprite->data[4] = 60; sprite->callback = AnimItemStealStep3; } static void AnimItemStealStep3(struct Sprite* sprite) { int zero; sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]); zero = 0; if (sprite->data[0] > 127) { sprite->data[1]++; sprite->data[0] = zero; } sprite->pos2.y = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8); if (sprite->pos2.y == 0) PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(63)); if (moveAlongLinearPath(sprite)) { sprite->pos2.y = 0; sprite->data[0] = 0; sprite->callback = AnimItemStealStep2; PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(-64)); } } // Moves a bag in a circular motion. // arg 0: y position // arg 1: initial wave offset void AnimTrickBag(struct Sprite* sprite) { int a; int b; if (!sprite->data[0]) { if (!IsContest()) { sprite->data[1] = gBattleAnimArgs[1]; sprite->pos1.x = 120; } else { a = gBattleAnimArgs[1] - 32; if (a < 0) b = gBattleAnimArgs[1] + 0xDF; else b = a; sprite->data[1] = a - ((b >> 8) << 8); sprite->pos1.x = 70; } sprite->pos1.y = gBattleAnimArgs[0]; sprite->data[2] = gBattleAnimArgs[0]; sprite->data[4] = 20; sprite->pos2.x = Cos(sprite->data[1], 60); sprite->pos2.y = Sin(sprite->data[1], 20); sprite->callback = AnimTrickBagStep1; if (sprite->data[1] > 0 && sprite->data[1] < 192) sprite->subpriority = 31; else sprite->subpriority = 29; } } static void AnimTrickBagStep1(struct Sprite* sprite) { switch (sprite->data[3]) { case 0: if (sprite->data[2] > 78) { sprite->data[3] = 1; StartSpriteAffineAnim(sprite, 1); break; } else { sprite->data[2] += sprite->data[4] / 10; sprite->data[4] += 3; sprite->pos1.y = sprite->data[2]; break; } break; case 1: if (sprite->data[3] && sprite->affineAnimEnded) { sprite->data[0] = 0; sprite->data[2] = 0; sprite->callback = AnimTrickBagStep2; } break; } } static void AnimTrickBagStep2(struct Sprite* sprite) { if (sprite->data[2] == gTrickBagCoordinates[sprite->data[0]][1]) { if (gTrickBagCoordinates[sprite->data[0]][2] == 127) { sprite->data[0] = 0; sprite->callback = AnimTrickBagStep3; } sprite->data[2] = 0; sprite->data[0]++; } else { sprite->data[2]++; sprite->data[1] = (gTrickBagCoordinates[sprite->data[0]][0] * gTrickBagCoordinates[sprite->data[0]][2] + sprite->data[1]) & 0xFF; if (!IsContest()) { if ((u16)(sprite->data[1] - 1) < 191) sprite->subpriority = 31; else sprite->subpriority = 29; } sprite->pos2.x = Cos(sprite->data[1], 60); sprite->pos2.y = Sin(sprite->data[1], 20); } } static void AnimTrickBagStep3(struct Sprite* sprite) { if (sprite->data[0] > 20) DestroyAnimSprite(sprite); sprite->invisible = sprite->data[0] % 2; sprite->data[0]++; } void AnimTask_LeafBlade(u8 taskId) { struct Task *task = &gTasks[taskId]; task->data[4] = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 1; task->data[6] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); task->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); task->data[10] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH); task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT); task->data[5] = (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) ? 1 : -1; task->data[9] = 56 - (task->data[5] * 64); task->data[8] = task->data[7] - task->data[9] + task->data[6]; task->data[2] = CreateSprite(&gLeafBladeSpriteTemplate, task->data[8], task->data[9], task->data[4]); if (task->data[2] == MAX_SPRITES) DestroyAnimVisualTask(taskId); gSprites[task->data[2]].data[0] = 10; gSprites[task->data[2]].data[1] = task->data[8]; gSprites[task->data[2]].data[2] = task->data[6] - (task->data[10] / 2 + 10) * task->data[5]; gSprites[task->data[2]].data[3] = task->data[9]; gSprites[task->data[2]].data[4] = task->data[7] + (task->data[11] / 2 + 10) * task->data[5]; gSprites[task->data[2]].data[5] = LeafBladeGetPosFactor(&gSprites[task->data[2]]); InitAnimArcTranslation(&gSprites[task->data[2]]); task->func = AnimTask_LeafBladeStep; } static void AnimTask_LeafBladeStep(u8 taskId) { struct Task* task = &gTasks[taskId]; struct Sprite* sprite = &gSprites[task->data[2]]; int a = task->data[0]; switch (a) { case 4: AnimTask_LeafBladeStep2(task, taskId); if (TranslateAnimHorizontalArc(sprite)) { task->data[15] = 5; task->data[0] = 0xFF; } break; case 8: AnimTask_LeafBladeStep2(task, taskId); if (TranslateAnimHorizontalArc(sprite)) { task->data[15] = 9; task->data[0] = 0xFF; } break; case 0: AnimTask_LeafBladeStep2(task, taskId); if (TranslateAnimHorizontalArc(sprite)) { task->data[15] = 1; task->data[0] = 0xFF; } break; case 1: sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.x = 0; sprite->pos2.y = 0; sprite->data[0] = 10; sprite->data[1] = sprite->pos1.x; sprite->data[2] = task->data[6]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = task->data[7]; sprite->data[5] = LeafBladeGetPosFactor(sprite); task->data[4] += 2; task->data[3] = a; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); InitAnimArcTranslation(sprite); task->data[0]++; break; case 2: AnimTask_LeafBladeStep2(task, taskId); if (TranslateAnimHorizontalArc(sprite)) { task->data[15] = 3; task->data[0] = 0xFF; } break; case 3: sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.x = 0; sprite->pos2.y = 0; sprite->data[0] = 10; sprite->data[1] = sprite->pos1.x; sprite->data[2] = task->data[6] - ((task->data[10] / 2) + 10) * task->data[5]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = task->data[7] - ((task->data[11] / 2) + 10) * task->data[5]; sprite->data[5] = LeafBladeGetPosFactor(sprite); task->data[3] = 2; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); InitAnimArcTranslation(sprite); task->data[0]++; break; case 5: sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.x = 0; sprite->pos2.y = 0; sprite->data[0] = 10; sprite->data[1] = sprite->pos1.x; sprite->data[2] = task->data[6] + ((task->data[10] / 2) + 10) * task->data[5]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = task->data[7] + ((task->data[11] / 2) + 10) * task->data[5]; sprite->data[5] = LeafBladeGetPosFactor(sprite); task->data[4] -= 2; task->data[3] = 3; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); InitAnimArcTranslation(sprite); task->data[0]++; break; case 6: AnimTask_LeafBladeStep2(task, taskId); if (TranslateAnimHorizontalArc(sprite)) { task->data[15] = 7; task->data[0] = 0xFF; } break; case 7: sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.x = 0; sprite->pos2.y = 0; sprite->data[0] = 10; sprite->data[1] = sprite->pos1.x; sprite->data[2] = task->data[6]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = task->data[7]; sprite->data[5] = LeafBladeGetPosFactor(sprite); task->data[4] += 2; task->data[3] = 4; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); InitAnimArcTranslation(sprite); task->data[0]++; break; case 9: sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.x = 0; sprite->pos2.y = 0; sprite->data[0] = 10; sprite->data[1] = sprite->pos1.x; sprite->data[2] = task->data[6] - ((task->data[10] / 2) + 10) * task->data[5]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = task->data[7] + ((task->data[11] / 2) + 10) * task->data[5]; sprite->data[5] = LeafBladeGetPosFactor(sprite); task->data[3] = 5; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); InitAnimArcTranslation(sprite); task->data[0]++; break; case 10: AnimTask_LeafBladeStep2(task, taskId); if (TranslateAnimHorizontalArc(sprite)) { task->data[15] = 11; task->data[0] = 0xFF; } break; case 11: { sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.x = 0; sprite->pos2.y = 0; sprite->data[0] = 10; sprite->data[1] = sprite->pos1.x; sprite->data[2] = task->data[8]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = task->data[9]; sprite->data[5] = LeafBladeGetPosFactor(sprite); task->data[4] -= 2; task->data[3] = 6; sprite->subpriority = task->data[4]; StartSpriteAnim(sprite, task->data[3]); InitAnimArcTranslation(sprite); task->data[0]++; break; } case 12: AnimTask_LeafBladeStep2(task, taskId); if (TranslateAnimHorizontalArc(sprite)) { DestroySprite(sprite); task->data[0]++; } break; case 13: if (task->data[12] == 0) DestroyAnimVisualTask(taskId); break; case 0xFF: if (++task->data[1] > 5) { task->data[1] = 0; task->data[0] = task->data[15]; } break; } } static s16 LeafBladeGetPosFactor(struct Sprite* sprite) { s16 var = 8; if (sprite->data[4] < sprite->pos1.y) var = -var; return var; } static void AnimTask_LeafBladeStep2(struct Task* task, u8 taskId) { task->data[14]++; if (task->data[14] > 0) { u8 spriteId; s16 spriteX; s16 spriteY; task->data[14] = 0; spriteX = gSprites[task->data[2]].pos1.x + gSprites[task->data[2]].pos2.x; spriteY = gSprites[task->data[2]].pos1.y + gSprites[task->data[2]].pos2.y; spriteId = CreateSprite(&gLeafBladeSpriteTemplate, spriteX, spriteY, task->data[4]); if (spriteId != MAX_SPRITES) { gSprites[spriteId].data[6] = taskId; gSprites[spriteId].data[7] = 12; gTasks[taskId].data[12]++; gSprites[spriteId].data[0] = task->data[13] & 1; gTasks[taskId].data[13]++; StartSpriteAnim(&gSprites[spriteId], task->data[3]); gSprites[spriteId].subpriority = task->data[4]; gSprites[spriteId].callback = AnimTask_LeafBladeStep2_Callback; } } } static void AnimTask_LeafBladeStep2_Callback(struct Sprite* sprite) { sprite->data[0]++; if (sprite->data[0] > 1) { sprite->data[0] = 0; sprite->invisible ^= 1; sprite->data[1]++; if (sprite->data[1] > 8) { gTasks[sprite->data[6]].data[sprite->data[7]]--; DestroySprite(sprite); } } } void AnimFlyingParticle(struct Sprite* sprite) { u8 battler; if (!gBattleAnimArgs[6]) battler = gBattleAnimAttacker; else battler = gBattleAnimTarget; if (GetBattlerSide(battler) != B_SIDE_PLAYER) { sprite->data[4] = 0; sprite->data[2] = gBattleAnimArgs[3]; sprite->pos1.x = 0xFFF0; } else { sprite->data[4] = 1; sprite->data[2] = -gBattleAnimArgs[3]; sprite->pos1.x = 0x100; } sprite->data[1] = gBattleAnimArgs[1]; sprite->data[0] = gBattleAnimArgs[2]; sprite->data[3] = gBattleAnimArgs[4]; switch (gBattleAnimArgs[5]) { case 0: sprite->pos1.y = gBattleAnimArgs[0]; sprite->oam.priority = GetBattlerSpriteBGPriority(battler); break; case 1: sprite->pos1.y = gBattleAnimArgs[0]; sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1; break; case 2: sprite->pos1.y = GetBattlerSpriteCoord(battler, 3) + gBattleAnimArgs[0]; sprite->oam.priority = GetBattlerSpriteBGPriority(battler); break; case 3: sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[0]; GetAnimBattlerSpriteId(ANIM_TARGET); sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1; break; } sprite->callback = AnimFlyingParticleStep; } static void AnimFlyingParticleStep(struct Sprite* sprite) { int a = sprite->data[7]; sprite->data[7]++; sprite->pos2.y = (sprite->data[1] * gSineTable[sprite->data[0]]) >> 8; sprite->pos2.x = sprite->data[2] * a; sprite->data[0] = (sprite->data[3] * a) & 0xFF; if (!sprite->data[4]) { if (sprite->pos2.x + sprite->pos1.x <= 0xF7) return; } else { if (sprite->pos2.x + sprite->pos1.x > -16) return; } DestroySpriteAndMatrix(sprite); } void AnimTask_CycleMagicalLeafPal(u8 taskId) { struct Task* task = &gTasks[taskId]; switch (task->data[0]) { case 0: task->data[8] = IndexOfSpritePaletteTag(ANIM_TAG_LEAF) * 16 + 256; task->data[12] = IndexOfSpritePaletteTag(ANIM_TAG_RAZOR_LEAF) * 16 + 256; task->data[0]++; break; case 1: if (++task->data[9] >= 0) { task->data[9] = 0; BlendPalette(task->data[8], 16, task->data[10], gMagicalLeafBlendColors[task->data[11]]); BlendPalette(task->data[12], 16, task->data[10], gMagicalLeafBlendColors[task->data[11]]); if (++task->data[10] == 17) { task->data[10] = 0; if (++task->data[11] == 7) task->data[11] = 0; } } break; } if (gBattleAnimArgs[ARG_RET_ID] == -1) DestroyAnimVisualTask(taskId); } void AnimNeedleArmSpike(struct Sprite* sprite) { u8 a; u8 b; u16 c; u16 x; u16 y; if (gBattleAnimArgs[4] == 0) { DestroyAnimSprite(sprite); } else { if (gBattleAnimArgs[0] == 0) { a = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); b = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); } else { a = GetBattlerSpriteCoord(gBattleAnimTarget, 2); b = GetBattlerSpriteCoord(gBattleAnimTarget, 3); } sprite->data[0] = gBattleAnimArgs[4]; if (gBattleAnimArgs[1] == 0) { sprite->pos1.x = gBattleAnimArgs[2] + a; sprite->pos1.y = gBattleAnimArgs[3] + b; sprite->data[5] = a; sprite->data[6] = b; } else { sprite->pos1.x = a; sprite->pos1.y = b; sprite->data[5] = gBattleAnimArgs[2] + a; sprite->data[6] = gBattleAnimArgs[3] + b; } x = sprite->pos1.x; sprite->data[1] = x * 16; y = sprite->pos1.y; sprite->data[2] = y * 16; sprite->data[3] = (sprite->data[5] - sprite->pos1.x) * 16 / gBattleAnimArgs[4]; sprite->data[4] = (sprite->data[6] - sprite->pos1.y) * 16 / gBattleAnimArgs[4]; c = ArcTan2Neg(sprite->data[5] - x, sprite->data[6] - y); if (IsContest()) c -= 0x8000; TrySetSpriteRotScale(sprite, 0, 0x100, 0x100, c); sprite->callback = AnimNeedleArmSpikeStep; } } static void AnimNeedleArmSpikeStep(struct Sprite* sprite) { if (sprite->data[0]) { sprite->data[1] += sprite->data[3]; sprite->data[2] += sprite->data[4]; sprite->pos1.x = sprite->data[1] >> 4 ; sprite->pos1.y = sprite->data[2] >> 4 ; sprite->data[0]--; } else { DestroySpriteAndMatrix(sprite); } } static void sub_81009DC(struct Sprite* sprite) { if (sprite->animEnded) DestroyAnimSprite(sprite); } void sub_81009F8(struct Sprite* sprite) { if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) { sprite->pos1.x -= gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; } else { sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; } sprite->callback = RunStoredCallbackWhenAnimEnds; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } void AnimWhipHit(struct Sprite* sprite) { if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) StartSpriteAnim(sprite, 1); sprite->callback = sub_81009DC; SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); sprite->pos1.y += gBattleAnimArgs[1]; } void sub_8100A94(struct Sprite* sprite) { sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = gBattleAnimArgs[3]; sprite->data[3] = gBattleAnimArgs[4]; sprite->data[5] = gBattleAnimArgs[5]; StartSpriteAffineAnim(sprite, gBattleAnimArgs[6]); StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); sprite->callback = TranslateSpriteLinearAndFlicker; } // Moves the sprite in a diagonally slashing motion across the target mon. // Used by moves such as MOVE_CUT and MOVE_AERIAL_ACE. // arg 0: initial x pixel offset // arg 1: initial y pixel offset // arg 2: slice direction; 0 = right-to-left, 1 = left-to-right void AnimCuttingSlice(struct Sprite* sprite) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0); sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) sprite->pos1.y += 8; sprite->callback = AnimSliceStep; if (gBattleAnimArgs[2] == 0) { sprite->pos1.x += gBattleAnimArgs[0]; } else { sprite->pos1.x -= gBattleAnimArgs[0]; sprite->hFlip = 1; } sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[1] -= 0x400; sprite->data[2] += 0x400; sprite->data[5] = gBattleAnimArgs[2]; if (sprite->data[5] == 1) sprite->data[1] = -sprite->data[1]; } void AnimAirCutterSlice(struct Sprite* sprite) { u8 a; u8 b; switch (gBattleAnimArgs[3]) { case 1: a = GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), 0); b = GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), 1); break; case 2: a = GetBattlerSpriteCoord(gBattleAnimTarget, 0); b = GetBattlerSpriteCoord(gBattleAnimTarget, 1); if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) { a = (GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), 0) + a) / 2; b = (GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), 1) + b) / 2; } break; case 0: default: a = GetBattlerSpriteCoord(gBattleAnimTarget, 0); b = GetBattlerSpriteCoord(gBattleAnimTarget, 1); break; } sprite->pos1.x = a; sprite->pos1.y = b; if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) sprite->pos1.y += 8; sprite->callback = AnimSliceStep; if (gBattleAnimArgs[2] == 0) { sprite->pos1.x += gBattleAnimArgs[0]; } else { sprite->pos1.x -= gBattleAnimArgs[0]; sprite->hFlip = 1; } sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[1] -= 0x400; sprite->data[2] += 0x400; sprite->data[5] = gBattleAnimArgs[2]; if (sprite->data[5] == 1) sprite->data[1] = -sprite->data[1]; } static void AnimSliceStep(struct Sprite* sprite) { sprite->data[3] += sprite->data[1]; sprite->data[4] += sprite->data[2]; if (sprite->data[5] == 0) sprite->data[1] += 0x18; else sprite->data[1] -= 0x18; sprite->data[2] -= 0x18; sprite->pos2.x = sprite->data[3] >> 8; sprite->pos2.y = sprite->data[4] >> 8; sprite->data[0]++; if (sprite->data[0] == 20) { StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); sprite->data[0] = 3; sprite->callback = WaitAnimForDuration; } } void unref_sub_8100D38(struct Sprite* sprite) { if (sprite->data[2] > 1) { if (sprite->data[3] & 1) { sprite->invisible = 0; gSprites[sprite->data[0]].invisible = 0; gSprites[sprite->data[1]].invisible = 0; } else { sprite->invisible = 1; gSprites[sprite->data[0]].invisible = 1; gSprites[sprite->data[1]].invisible = 1; } sprite->data[2] = 0; sprite->data[3]++; } else { sprite->data[2]++; } if (sprite->data[3] == 10) { DestroySprite(&gSprites[sprite->data[0]]); DestroySprite(&gSprites[sprite->data[1]]); DestroyAnimSprite(sprite); } } void sub_8100E1C(struct Sprite* sprite) { sprite->data[0] = gBattleAnimArgs[2]; if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) sprite->pos1.x -= gBattleAnimArgs[0]; else sprite->pos1.x += gBattleAnimArgs[0]; StartSpriteAnim(sprite, gBattleAnimArgs[5]); sprite->data[1] = -gBattleAnimArgs[3]; sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[3] = gBattleAnimArgs[4]; sprite->callback = sub_8100E80; sprite->callback(sprite); } static void sub_8100E80(struct Sprite* sprite) { sprite->pos2.x = Cos(sprite->data[0], 100); sprite->pos2.y = Sin(sprite->data[0], 20); if (sprite->data[0] < 128) sprite->subpriority = 0; else sprite->subpriority = 14; sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF; sprite->data[5] += 0x82; sprite->pos2.y += sprite->data[5] >> 8; sprite->data[2]++; if (sprite->data[2] == sprite->data[3]) DestroyAnimSprite(sprite); } void AnimProtect(struct Sprite* sprite) { if (IsContest()) gBattleAnimArgs[1] += 8; sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimAttacker, 0) + gBattleAnimArgs[0]; sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimAttacker, 1) + gBattleAnimArgs[1]; if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER || IsContest()) sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker) + 1; else sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); sprite->data[0] = gBattleAnimArgs[2]; sprite->data[2] = (IndexOfSpritePaletteTag(ANIM_TAG_PROTECT) << 4) + 0x100; sprite->data[7] = 16; SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[7], sprite->data[7])); sprite->callback = AnimProtectStep; } static void AnimProtectStep(struct Sprite *sprite) { int a; int i; sprite->data[5] += 96; sprite->pos2.x = -(sprite->data[5] >> 8); if (++sprite->data[1] > 1) { sprite->data[1] = 0; a = gPlttBufferFaded[sprite->data[2] + 1]; i = 0; do { gPlttBufferFaded[sprite->data[2] + ++i] = gPlttBufferFaded[sprite->data[2] + i + 1]; } while (i < 6); gPlttBufferFaded[sprite->data[2] + 7] = a; } if (sprite->data[7] > 6 && sprite->data[0] >0 && ++sprite->data[6] > 1) { sprite->data[6] = 0; sprite->data[7] -= 1; SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[7], sprite->data[7])); } if (sprite->data[0] > 0) { sprite->data[0] -= 1; } else if (++sprite->data[6] > 1) { sprite->data[6] = 0; sprite->data[7]++; SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[7], sprite->data[7])); if (sprite->data[7] == 16) { sprite->invisible = 1; sprite->callback = DestroyAnimSpriteAndDisableBlend; } } } void AnimMilkBottle(struct Sprite* sprite) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + 0xFFE8; sprite->data[0] = 0; sprite->data[1] = 0; sprite->data[2] = 0; sprite->data[3] = 0; sprite->data[4] = 0; sprite->data[6] = 0; sprite->data[7] = 16; SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7])); sprite->callback = AnimMilkBottleStep1; } static void AnimMilkBottleStep1(struct Sprite* sprite) { switch (sprite->data[0]) { case 0: if (++sprite->data[2] > 0) { sprite->data[2] = 0; if (((++sprite->data[1]) & 1) != 0) { if (sprite->data[6] <= 15) sprite->data[6]++; } else if (sprite->data[7] > 0) sprite->data[7]--; SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7])); if (sprite->data[6] == 16 && sprite->data[7] == 0) { sprite->data[1] = 0; sprite->data[0]++; } } break; case 1: if (++sprite->data[1] > 8) { sprite->data[1] = 0; StartSpriteAffineAnim(sprite, 1); sprite->data[0]++; } break; case 2: AnimMilkBottleStep2(sprite, 16, 4); if (++sprite->data[1] > 2) { sprite->data[1] = 0; sprite->pos1.y++; } if (++sprite->data[2] <= 29) break; if (sprite->data[2] & 1) { if (sprite->data[6] > 0) sprite->data[6]--; } else if (sprite->data[7] <= 15) { sprite->data[7]++; } SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7])); if (sprite->data[6] == 0 && sprite->data[7] == 16) { sprite->data[1] = 0; sprite->data[2] = 0; sprite->data[0]++; } break; case 3: sprite->invisible = 1; sprite->data[0]++; break; case 4: SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0)); DestroyAnimSprite(sprite); break; } } static void AnimMilkBottleStep2(struct Sprite* sprite, int unk1, int unk2) { if (sprite->data[3] <= 11) sprite->data[4] += 2; if ((u16)(sprite->data[3] - 0x12) <= 0x17) sprite->data[4] -= 2; if ((sprite->data[3]) > 0x2F) sprite->data[4] += 2; sprite->pos2.x = sprite->data[4] / 9; sprite->pos2.y = sprite->data[4] / 14; if (sprite->pos2.y < 0) sprite->pos2.y *= -1; sprite->data[3]++; if (sprite->data[3] > 0x3B) sprite->data[3] = 0; } void AnimGrantingStars(struct Sprite* sprite) { if (!gBattleAnimArgs[2]) SetSpriteCoordsToAnimAttackerCoords(sprite); SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[0] = gBattleAnimArgs[5]; sprite->data[1] = gBattleAnimArgs[3]; sprite->data[2] = gBattleAnimArgs[4]; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); sprite->callback = TranslateSpriteLinearFixedPoint; } void AnimSparkingStars(struct Sprite* sprite) { u8 battler; if (!gBattleAnimArgs[2]) battler = gBattleAnimAttacker; else battler = gBattleAnimTarget; if (IsDoubleBattle() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler))) { SetAverageBattlerPositions(battler, gBattleAnimArgs[6], &sprite->pos1.x, &sprite->pos1.y); SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); sprite->pos1.y += gBattleAnimArgs[1]; } else { if (!gBattleAnimArgs[6]) { sprite->pos1.x = GetBattlerSpriteCoord(battler, 0); sprite->pos1.y = GetBattlerSpriteCoord(battler, 1) + gBattleAnimArgs[1]; } else { sprite->pos1.x = GetBattlerSpriteCoord(battler, 2); sprite->pos1.y = GetBattlerSpriteCoord(battler, 3) + gBattleAnimArgs[1]; } SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); } sprite->data[0] = gBattleAnimArgs[5]; sprite->data[1] = gBattleAnimArgs[3]; sprite->data[2] = gBattleAnimArgs[4]; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); sprite->callback = TranslateSpriteLinearFixedPoint; } void sub_8101440(struct Sprite* sprite) { SetSpriteCoordsToAnimAttackerCoords(sprite); if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) { sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; } else { sprite->pos1.x -= gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; StartSpriteAnim(sprite, 1); } sprite->callback = sub_81014A0; } static void sub_81014A0(struct Sprite* sprite) { if (++sprite->data[0] > 30) { sprite->pos2.y = (30 - sprite->data[0]) / 3; sprite->pos2.x = Sin(sprite->data[1] * 4, 3); sprite->data[1]++; } if (sprite->animEnded) DestroyAnimSprite(sprite); } void AnimSleepLetterZ(struct Sprite* sprite) { SetSpriteCoordsToAnimAttackerCoords(sprite); if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) { sprite->pos1.x += gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[3] = 1; } else { sprite->pos1.x -= gBattleAnimArgs[0]; sprite->pos1.y += gBattleAnimArgs[1]; sprite->data[3] = 0xFFFF; StartSpriteAffineAnim(sprite, 1); } sprite->callback = AnimSleepLetterZStep; } static void AnimSleepLetterZStep(struct Sprite* sprite) { sprite->pos2.y = -(sprite->data[0] / 0x28); sprite->pos2.x = sprite->data[4] / 10; sprite->data[4] += sprite->data[3] * 2; sprite->data[0] += sprite->data[1]; if (++sprite->data[1] > 60) DestroySpriteAndMatrix(sprite); } void AnimLockOnTarget(struct Sprite* sprite) { sprite->pos1.x -= 32; sprite->pos1.y -= 32; sprite->data[0] = 20; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData6(sprite, AnimLockOnTargetStep1); } static void AnimLockOnTargetStep1(struct Sprite* sprite) { switch (sprite->data[5] & 1) { case 0: sprite->data[0] = 1; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData6(sprite, AnimLockOnTargetStep1); break; case 1: sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.y = 0; sprite->pos2.x = 0; sprite->data[0] = 8; sprite->data[2] = sprite->pos1.x + gInclineMonCoordTable[sprite->data[5] >> 8][0]; sprite->data[4] = sprite->pos1.y + gInclineMonCoordTable[sprite->data[5] >> 8][1]; sprite->callback = StartAnimLinearTranslation; StoreSpriteCallbackInData6(sprite, AnimLockOnTargetStep2); sprite->data[5] += 0x100; PlaySE12WithPanning(SE_W199, BattleAnimAdjustPanning(63)); break; } sprite->data[5] ^= 1; } static void AnimLockOnTargetStep2(struct Sprite* sprite) { if ((sprite->data[5] >> 8) == 4) { sprite->data[0] = 10; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData6(sprite, AnimLockOnTargetStep3); } else { sprite->callback = AnimLockOnTargetStep1; } } static void AnimLockOnTargetStep3(struct Sprite* sprite) { s16 a; s16 b; if (sprite->oam.affineParam == 0) { sprite->data[0] = 3; sprite->data[1] = 0; sprite->data[2] = 0; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData6(sprite, AnimLockOnTargetStep4); } else { switch (sprite->oam.affineParam) { case 1: a = -8; b = -8; break; case 2: a = -8; b = 8; break; case 3: a = 8; b = -8; break; default: a = 8; b = 8; break; } sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; sprite->pos2.y = 0; sprite->pos2.x = 0; sprite->data[0] = 6; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + a; sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + b; sprite->callback = StartAnimLinearTranslation; StoreSpriteCallbackInData6(sprite, AnimLockOnTargetStep5); } } static void AnimLockOnTargetStep4(struct Sprite* sprite) { if (sprite->data[2] == 0) { if ((sprite->data[1] += 3) > 16) sprite->data[1] = 16; } else if ((sprite->data[1] -= 3) < 0) { sprite->data[1] = 0; } BlendPalettes(sub_80A75AC(1, 1, 1, 1, 1, 0, 0), sprite->data[1], RGB(31, 31, 31)); if (sprite->data[1] == 16) { int pal; sprite->data[2]++; pal = sprite->oam.paletteNum; LoadPalette(&gPlttBufferUnfaded[0x108 + pal * 16], pal * 16 | 0x101, 4); PlaySE12WithPanning(SE_W043, BattleAnimAdjustPanning(63)); } else if (sprite->data[1] == 0) { sprite->callback = AnimLockOnTargetStep5; } } static void AnimLockOnTargetStep5(struct Sprite* sprite) { if ((u16)gBattleAnimArgs[ARG_RET_ID] == 0xFFFF) { sprite->data[1] = 0; sprite->data[0] = 0; sprite->callback = AnimLockOnTargetStep6; } } static void AnimLockOnTargetStep6(struct Sprite* sprite) { if (sprite->data[0] % 3 == 0) { sprite->data[1]++; sprite->invisible ^= 1; } sprite->data[0]++; if (sprite->data[1] == 8) DestroyAnimSprite(sprite); } void AnimLockOnMoveTarget(struct Sprite* sprite) { sprite->oam.affineParam = gBattleAnimArgs[0]; if ((s16)sprite->oam.affineParam == 1) { sprite->pos1.x -= 0x18; sprite->pos1.y -= 0x18; } else if ((s16)sprite->oam.affineParam == 2) { sprite->pos1.x -= 0x18; sprite->pos1.y += 0x18; sprite->oam.matrixNum = ST_OAM_VFLIP; } else if ((s16)sprite->oam.affineParam == 3) { sprite->pos1.x += 0x18; sprite->pos1.y -= 0x18; sprite->oam.matrixNum = ST_OAM_HFLIP; } else { sprite->pos1.x += 0x18; sprite->pos1.y += 0x18; sprite->oam.matrixNum = ST_OAM_HFLIP | ST_OAM_VFLIP; } sprite->oam.tileNum = (sprite->oam.tileNum + 16); sprite->callback = AnimLockOnTarget; sprite->callback(sprite); } void AnimBowMon(struct Sprite* sprite) { sprite->invisible = 1; sprite->data[0] = 0; switch (gBattleAnimArgs[0]) { case 0: sprite->callback = AnimBowMonStep1; break; case 1: sprite->callback = AnimBowMonStep2; break; case 2: sprite->callback = AnimBowMonStep3; break; default: sprite->callback = AnimBowMonStep4; break; } } static void AnimBowMonStep1(struct Sprite* sprite) { sprite->data[0] = 6; sprite->data[1] = (GetBattlerSide(gBattleAnimAttacker)) ? 2 : -2; sprite->data[2] = 0; sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker]; StoreSpriteCallbackInData6(sprite, AnimBowMonStep1_Callback); sprite->callback = TranslateMonSpriteLinear; } static void AnimBowMonStep1_Callback(struct Sprite* sprite) { if (sprite->data[0] == 0) { sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker]; PrepareBattlerSpriteForRotScale(sprite->data[3], ST_OAM_OBJ_NORMAL); sprite->data[4] = (sprite->data[6] = GetBattlerSide(gBattleAnimAttacker)) ? 0x300 : 0xFFFFFD00; sprite->data[5] = 0; } sprite->data[5] += sprite->data[4]; SetSpriteRotScale(sprite->data[3], 0x100, 0x100, sprite->data[5]); SetBattlerSpriteYOffsetFromRotation(sprite->data[3]); if (++sprite->data[0] > 3) { sprite->data[0] = 0; sprite->callback = AnimBowMonStep4; } } static void AnimBowMonStep2(struct Sprite* sprite) { sprite->data[0] = 4; sprite->data[1] = (GetBattlerSide(gBattleAnimAttacker)) ? -3 : 3; sprite->data[2] = 0; sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker]; StoreSpriteCallbackInData6(sprite, AnimBowMonStep4); sprite->callback = TranslateMonSpriteLinear; } static void AnimBowMonStep3(struct Sprite* sprite) { if (++sprite->data[0] > 8) { sprite->data[0] = 0; sprite->callback = AnimBowMonStep3_Callback; } } static void AnimBowMonStep3_Callback(struct Sprite* sprite) { if (sprite->data[0] == 0) { sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker]; sprite->data[6] = GetBattlerSide(gBattleAnimAttacker); if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) { sprite->data[4] = 0xFC00; sprite->data[5] = 0xC00; } else { sprite->data[4] = 0x400; sprite->data[5] = 0xF400; } } sprite->data[5] += sprite->data[4]; SetSpriteRotScale(sprite->data[3], 0x100, 0x100, sprite->data[5]); SetBattlerSpriteYOffsetFromRotation(sprite->data[3]); if (++sprite->data[0] > 2) { ResetSpriteRotScale(sprite->data[3]); sprite->callback = AnimBowMonStep4; } } static void AnimBowMonStep4(struct Sprite* sprite) { DestroyAnimSprite(sprite); } void sub_8101B90(struct Sprite *sprite) { sprite->data[0] = 0; sprite->callback = sub_8101BA0; } static void sub_8101BA0(struct Sprite *sprite) { switch (sprite->data[0]) { case 0: sprite->data[1] = 0; sprite->data[2] = gBattlerSpriteIds[gBattleAnimAttacker]; sprite->data[3] = GetBattlerSide(gBattleAnimAttacker); sprite->data[4] = (sprite->data[3] != B_SIDE_PLAYER) ? 0x200 : -0x200; sprite->data[5] = 0; PrepareBattlerSpriteForRotScale(sprite->data[2], ST_OAM_OBJ_NORMAL); sprite->data[0]++; // fall through case 1: sprite->data[5] += sprite->data[4]; SetSpriteRotScale(sprite->data[2], 0x100, 0x100, sprite->data[5]); SetBattlerSpriteYOffsetFromRotation(sprite->data[2]); if (++sprite->data[1] > 3) { sprite->data[1] = 0; sprite->data[4] *= -1; sprite->data[0]++; } break; case 2: sprite->data[5] += sprite->data[4]; SetSpriteRotScale(sprite->data[2], 0x100, 0x100, sprite->data[5]); SetBattlerSpriteYOffsetFromRotation(sprite->data[2]); if (++sprite->data[1] > 3) { ResetSpriteRotScale(sprite->data[2]); DestroyAnimSprite(sprite); } break; } } void AnimTask_SkullBashPosition(u8 taskId) { u8 a; gTasks[taskId].data[0] = gBattlerSpriteIds[gBattleAnimAttacker]; a = GetBattlerSide(gBattleAnimAttacker); gTasks[taskId].data[1] = a; gTasks[taskId].data[2] = 0; switch (gBattleAnimArgs[0]) { default: DestroyAnimVisualTask(taskId); break; case 0: gTasks[taskId].data[2] = 0; gTasks[taskId].data[3] = 8; gTasks[taskId].data[4] = 0; gTasks[taskId].data[5] = 3; if (a == 0) gTasks[taskId].data[5] *= -1; gTasks[taskId].func = AnimTask_SkullBashPositionSet; break; case 1: gTasks[taskId].data[3] = 8; gTasks[taskId].data[4] = 0x600; gTasks[taskId].data[5] = 0xC0; if (a == 0) { gTasks[taskId].data[4] = -gTasks[taskId].data[4]; gTasks[taskId].data[5] = -gTasks[taskId].data[5]; } gTasks[taskId].func = AnimTask_SkullBashPositionReset; break; } } static void AnimTask_SkullBashPositionSet(u8 taskId) { struct Task *task = &gTasks[taskId]; switch (task->data[2]) { case 0: if (task->data[3]) { task->data[4] += task->data[5]; gSprites[task->data[0]].pos2.x = task->data[4]; task->data[3]--; } else { task->data[3] = 8; task->data[4] = 0; task->data[5] = (task->data[1] == 0) ? -0xC0 : 0xC0; PrepareBattlerSpriteForRotScale(task->data[0], ST_OAM_OBJ_NORMAL); task->data[2]++; } break; case 1: if (task->data[3]) { task->data[4] += task->data[5]; SetSpriteRotScale(task->data[0], 0x100, 0x100, task->data[4]); SetBattlerSpriteYOffsetFromRotation(task->data[0]); task->data[3]--; } else { task->data[3] = 8; task->data[4] = gSprites[task->data[0]].pos2.x; task->data[5] = (task->data[1] == 0) ? 0x2 : -0x2; task->data[6] = 1; task->data[2]++; } break; case 2: if (task->data[3]) { if (task->data[6]) { task->data[6]--; } else { if (task->data[3] & 1) gSprites[task->data[0]].pos2.x = task->data[4] + task->data[5]; else gSprites[task->data[0]].pos2.x = task->data[4] - task->data[5]; task->data[6] = 1; task->data[3]--; } } else { gSprites[task->data[0]].pos2.x = task->data[4]; task->data[3] = 12; task->data[2]++; } break; case 3: if (task->data[3]) { task->data[3]--; } else { task->data[3] = 3; task->data[4] = gSprites[task->data[0]].pos2.x; task->data[5] = (task->data[1] == 0) ? 8 : -8; task->data[2]++; } break; case 4: if (task->data[3]) { task->data[4] += task->data[5]; gSprites[task->data[0]].pos2.x = task->data[4]; task->data[3]--; } else { DestroyAnimVisualTask(taskId); } break; } } static void AnimTask_SkullBashPositionReset(u8 taskId) { struct Task* task = &gTasks[taskId]; if (task->data[3]) { task->data[4] -= task->data[5]; SetSpriteRotScale(task->data[0], 0x100, 0x100, task->data[4]); SetBattlerSpriteYOffsetFromRotation(task->data[0]); task->data[3]--; } else { ResetSpriteRotScale(task->data[0]); DestroyAnimVisualTask(taskId); } } void AnimSlashSlice(struct Sprite* sprite) { if (gBattleAnimArgs[0] == 0) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[1]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2]; } else { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[1]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[2]; } sprite->data[0] = 0; sprite->data[1] = 0; StoreSpriteCallbackInData6(sprite, AnimFalseSwipeSliceStep3); sprite->callback = RunStoredCallbackWhenAnimEnds; } void AnimFalseSwipeSlice(struct Sprite* sprite) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + 0xFFD0; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); StoreSpriteCallbackInData6(sprite, AnimFalseSwipeSliceStep1); sprite->callback = RunStoredCallbackWhenAnimEnds; } void AnimFalseSwipePositionedSlice(struct Sprite* sprite) { sprite->pos1.x = sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + 0xFFD0 + gBattleAnimArgs[0]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); StartSpriteAnim(sprite, 1); sprite->data[0] = 0; sprite->data[1] = 0; sprite->callback = AnimFalseSwipeSliceStep3; } static void AnimFalseSwipeSliceStep1(struct Sprite* sprite) { if (++sprite->data[0] > 8) { sprite->data[0] = 12; sprite->data[1] = 8; sprite->data[2] = 0; StoreSpriteCallbackInData6(sprite, AnimFalseSwipeSliceStep2); sprite->callback = TranslateSpriteLinear; } } static void AnimFalseSwipeSliceStep2(struct Sprite* sprite) { sprite->data[0] = 0; sprite->data[1] = 0; sprite->callback = AnimFalseSwipeSliceStep3; } static void AnimFalseSwipeSliceStep3(struct Sprite* sprite) { if (++sprite->data[0] > 1) { sprite->data[0] = 0; sprite->invisible = !sprite->invisible; if (++sprite->data[1] > 8) DestroyAnimSprite(sprite); } } void AnimEndureEnergy(struct Sprite* sprite) { if (gBattleAnimArgs[0] == 0) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[1]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + gBattleAnimArgs[2]; } else { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0) + gBattleAnimArgs[1]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + gBattleAnimArgs[2]; } sprite->data[0] = 0; sprite->data[1] = gBattleAnimArgs[3]; sprite->callback = AnimEndureEnergyStep; } static void AnimEndureEnergyStep(struct Sprite* sprite) { if (++sprite->data[0] > sprite->data[1]) { sprite->data[0] = 0; sprite->pos1.y--; } sprite->pos1.y -= sprite->data[0]; if (sprite->animEnded) DestroyAnimSprite(sprite); } void AnimSharpenSphere(struct Sprite* sprite) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) - 12; sprite->data[0] = 0; sprite->data[1] = 2; sprite->data[2] = 0; sprite->data[3] = 0; sprite->data[4] = 0; sprite->data[5] = BattleAnimAdjustPanning(-64); sprite->callback = AnimSharpenSphereStep; } static void AnimSharpenSphereStep(struct Sprite* sprite) { if (++sprite->data[0] >= sprite->data[1]) { sprite->invisible = !sprite->invisible; if (!sprite->invisible) { sprite->data[4]++; if (!(sprite->data[4] & 1)) PlaySE12WithPanning(SE_W207B, sprite->data[5]); } sprite->data[0] = 0; if (++sprite->data[2] > 1) { sprite->data[2] = 0; sprite->data[1]++; } } if (sprite->animEnded && sprite->data[1] > 16 && sprite->invisible) DestroyAnimSprite(sprite); } void AnimConversion(struct Sprite* sprite) { if (sprite->data[0] == 0) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[0]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + gBattleAnimArgs[1]; if (IsContest()) sprite->pos1.y += 10; sprite->data[0]++; } if ((u16)gBattleAnimArgs[ARG_RET_ID] == 0xFFFF) DestroyAnimSprite(sprite); } void AnimTask_ConversionAlphaBlend(u8 taskId) { if (gTasks[taskId].data[2] == 1) { gBattleAnimArgs[ARG_RET_ID] = 0xFFFF; gTasks[taskId].data[2]++; } else if (gTasks[taskId].data[2] == 2) { DestroyAnimVisualTask(taskId); } else { if (++gTasks[taskId].data[0] == 4) { gTasks[taskId].data[0] = 0; gTasks[taskId].data[1]++; SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - gTasks[taskId].data[1], gTasks[taskId].data[1])); if (gTasks[taskId].data[1] == 16) gTasks[taskId].data[2]++; } } } void AnimConversion2(struct Sprite* sprite) { InitSpritePosToAnimTarget(sprite, FALSE); sprite->animPaused = 1; sprite->data[0] = gBattleAnimArgs[2]; sprite->callback = AnimConversion2Step; } static void AnimConversion2Step(struct Sprite* sprite) { if (sprite->data[0]) { sprite->data[0]--; } else { sprite->animPaused = 0; sprite->data[0] = 30; sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); sprite->callback = StartAnimLinearTranslation; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } } void AnimTask_Conversion2AlphaBlend(u8 taskId) { if (++gTasks[taskId].data[0] == 4) { gTasks[taskId].data[0] = 0; gTasks[taskId].data[1]++; SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1])); if (gTasks[taskId].data[1] == 16) DestroyAnimVisualTask(taskId); } } void unref_sub_8102434(u8 taskId) { u8 i; for (i = 0; i < gBattlersCount; i++) { if (gBattleAnimArgs[0] == 1 && GetBattlerSide(i) == B_SIDE_PLAYER) SetHealthboxSpriteInvisible(gHealthboxSpriteIds[i]); if (gBattleAnimArgs[1] == 1 && GetBattlerSide(i) == B_SIDE_OPPONENT) SetHealthboxSpriteInvisible(gHealthboxSpriteIds[i]); } DestroyAnimVisualTask(taskId); } void unref_sub_81024A8(u8 taskId) { u8 i; for (i = 0; i < gBattlersCount; i++) SetHealthboxSpriteVisible(gHealthboxSpriteIds[i]); DestroyAnimVisualTask(taskId); } void AnimMoon(struct Sprite* sprite) { if (IsContest()) { sprite->pos1.x = 48; sprite->pos1.y = 40; } else { sprite->pos1.x = gBattleAnimArgs[0]; sprite->pos1.y = gBattleAnimArgs[1]; } sprite->oam.shape = SPRITE_SHAPE(64x64); sprite->oam.size = SPRITE_SIZE(64x64); sprite->data[0] = 0; sprite->callback = AnimMoonStep; } static void AnimMoonStep(struct Sprite* sprite) { if (sprite->data[0]) DestroyAnimSprite(sprite); } void AnimMoonlightSparkle(struct Sprite* sprite) { sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[0]; sprite->pos1.y = gBattleAnimArgs[1]; sprite->data[0] = 0; sprite->data[1] = 0; sprite->data[2] = 0; sprite->data[3] = 0; sprite->data[4] = 1; sprite->callback = AnimMoonlightSparkleStep; } static void AnimMoonlightSparkleStep(struct Sprite* sprite) { if (++sprite->data[1] > 1) { sprite->data[1] = 0; if (sprite->data[2] < 120) { sprite->pos1.y++; sprite->data[2]++; } } if (sprite->data[0]) DestroyAnimSprite(sprite); } void AnimTask_FadeScreenBlueStep(u8); void AnimTask_FadeScreenBlue(u8 taskId) { int a = sub_80A75AC(1, 0, 0, 0, 0, 0, 0) & 0xFFFF; int b; int c; int d; gTasks[taskId].data[0] = 0; gTasks[taskId].data[1] = 0; gTasks[taskId].data[2] = 0; gTasks[taskId].data[3] = a; gTasks[taskId].data[4] = 0; gTasks[taskId].data[5] = 0; gTasks[taskId].data[6] = 0; gTasks[taskId].data[7] = 13; gTasks[taskId].data[8] = 14; gTasks[taskId].data[9] = 15; b = sub_80A76C4(1, 1, 1, 1); c = a | b; StorePointerInVars(&gTasks[taskId].data[14], &gTasks[taskId].data[15], (void*)c); b = b | (0x10000 << IndexOfSpritePaletteTag(ANIM_TAG_MOON)); d = IndexOfSpritePaletteTag(ANIM_TAG_GREEN_SPARKLE); BeginNormalPaletteFade((0x10000 << d) | b, 0, 0, 16, RGB(27, 29, 31)); gTasks[taskId].func = AnimTask_FadeScreenBlueStep; gTasks[taskId].func(taskId); } void AnimTask_FadeScreenBlueStep(u8 taskId) { struct Task* task = &gTasks[taskId]; switch (task->data[0]) { case 0: if (++task->data[1] > 0) { u16 color; u16 bitmask; u16 r3; u16 i; u16 j; task->data[1] = 0; if (++task->data[2] <= 15) { u16 red; u16 green; u16 blue; task->data[4] += task->data[7]; task->data[5] += task->data[8]; task->data[6] += task->data[9]; red = task->data[4] >> 3; green = task->data[5] >> 3; blue = task->data[6] >> 3; color = RGB(red, green, blue); } else { color = RGB(27, 29, 31); task->data[0]++; } bitmask = 1; r3 = 0; for (i = 0; i <= 15; i++) { if (task->data[3] & bitmask) { for (j = 1; j <= 15; j++) { gPlttBufferFaded[r3 + j] = color; } } bitmask <<= 1; r3 += 16; } } break; case 1: if (!gPaletteFade.active) { u8 spriteId; for (spriteId = 0; spriteId < MAX_SPRITES; spriteId++) { if (gSprites[spriteId].template == &gMoonSpriteTemplate || gSprites[spriteId].template == &gMoonlightSparkleSpriteTemplate) gSprites[spriteId].data[0] = 1; } task->data[1] = 0; task->data[0]++; } break; case 2: if (++task->data[1] > 30) { BeginNormalPaletteFade((u32)LoadPointerFromVars(task->data[14], task->data[15]), 0, 16, 0, RGB(27, 29, 31)); task->data[0]++; } break; case 3: if (!gPaletteFade.active) DestroyAnimVisualTask(taskId); break; } } void AnimHornHit(struct Sprite* sprite) { if (gBattleAnimArgs[2] < 2) gBattleAnimArgs[2] = 2; if (gBattleAnimArgs[2] > 0x7F) gBattleAnimArgs[2] = 0x7F; sprite->data[0] = 0; sprite->data[1] = gBattleAnimArgs[2]; sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[0]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[1]; sprite->data[6] = sprite->pos1.x; sprite->data[7] = sprite->pos1.y; if (IsContest()) { sprite->oam.matrixNum = ST_OAM_HFLIP; sprite->pos1.x += 40; sprite->pos1.y += 20; sprite->data[2] = sprite->pos1.x << 7; sprite->data[3] = -0x1400 / sprite->data[1]; sprite->data[4] = sprite->pos1.y << 7; sprite->data[5] = -0xA00 / sprite->data[1]; } else if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) { sprite->pos1.x -= 40; sprite->pos1.y += 20; sprite->data[2] = sprite->pos1.x << 7; sprite->data[3] = 0x1400 / sprite->data[1]; sprite->data[4] = sprite->pos1.y << 7; sprite->data[5] = -0xA00 / sprite->data[1]; } else { sprite->pos1.x += 40; sprite->pos1.y -= 20; sprite->data[2] = sprite->pos1.x << 7; sprite->data[3] = -0x1400 / sprite->data[1]; sprite->data[4] = sprite->pos1.y << 7; sprite->data[5] = 0xA00 / sprite->data[1]; sprite->oam.matrixNum = (ST_OAM_HFLIP | ST_OAM_VFLIP); } sprite->callback = AnimHornHitStep; } static void AnimHornHitStep(struct Sprite* sprite) { sprite->data[2] += sprite->data[3]; sprite->data[4] += sprite->data[5]; sprite->pos1.x = sprite->data[2] >> 7; sprite->pos1.y = sprite->data[4] >> 7; if (--sprite->data[1] == 1) { sprite->pos1.x = sprite->data[6]; sprite->pos1.y = sprite->data[7]; } if (sprite->data[1] == 0) DestroyAnimSprite(sprite); } void AnimTask_DoubleTeam(u8 taskId) { u16 i; int obj; u16 r3; u16 r4; struct Task* task = &gTasks[taskId]; task->data[0] = GetAnimBattlerSpriteId(ANIM_ATTACKER); task->data[1] = AllocSpritePalette(ANIM_TAG_BENT_SPOON); r3 = (task->data[1] * 16) + 0x100; r4 = (gSprites[task->data[0]].oam.paletteNum + 16) << 4; for (i = 1; i < 16; i++) gPlttBufferUnfaded[r3 + i] = gPlttBufferUnfaded[r4 + i]; BlendPalette(r3, 16, 11, RGB(0, 0, 0)); task->data[3] = 0; i = 0; while (i < 2 && (obj = CloneBattlerSpriteWithBlend(0)) >= 0) { gSprites[obj].oam.paletteNum = task->data[1]; gSprites[obj].data[0] = 0; gSprites[obj].data[1] = i << 7; gSprites[obj].data[2] = taskId; gSprites[obj].callback = AnimTask_DoubleTeamCallback; task->data[3]++; i++; } task->func = AnimTask_DoubleTeamStep; if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON); else ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); } static void AnimTask_DoubleTeamStep(u8 taskId) { struct Task* task = &gTasks[taskId]; if (!task->data[3]) { if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON); else SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON); FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON); DestroyAnimVisualTask(taskId); } } static void AnimTask_DoubleTeamCallback(struct Sprite* sprite) { if (++sprite->data[3] > 1) { sprite->data[3] = 0; sprite->data[0]++; } if (sprite->data[0] > 64) { gTasks[sprite->data[2]].data[3]--; obj_delete_but_dont_free_vram(sprite); } else { sprite->data[4] = gSineTable[sprite->data[0]] / 6; sprite->data[5] = gSineTable[sprite->data[0]] / 13; sprite->data[1] = (sprite->data[1] + sprite->data[5]) & 0xFF; sprite->pos2.x = Sin(sprite->data[1], sprite->data[4]); } } void AnimSuperFang(struct Sprite* sprite) { StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); sprite->callback = RunStoredCallbackWhenAnimEnds; } void AnimTask_MusicNotesRainbowBlend(u8 taskId) { u16 i; u16 j; u16 index; index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[0][0]); if (index != 0xFF) { index = (index << 4) + 0x100; for (i = 1; i < ARRAY_COUNT(gParticlesColorBlendTable[0]); i++) gPlttBufferFaded[index + i] = gParticlesColorBlendTable[0][i]; } for (j = 1; j < ARRAY_COUNT(gParticlesColorBlendTable); j++) { index = AllocSpritePalette(gParticlesColorBlendTable[j][0]); if (index != 0xFF) { index = (index << 4) + 0x100; for (i = 1; i < ARRAY_COUNT(gParticlesColorBlendTable[0]); i++) gPlttBufferFaded[index + i] = gParticlesColorBlendTable[j][i]; } } DestroyAnimVisualTask(taskId); } // clears the rainbow effect for musical notes. void AnimTask_MusicNotesClearRainbowBlend(u8 taskId) { u16 i; for (i = 1; i < ARRAY_COUNT(gParticlesColorBlendTable); i++) FreeSpritePaletteByTag(gParticlesColorBlendTable[i][0]); DestroyAnimVisualTask(taskId); } void AnimWavyMusicNotes(struct Sprite* sprite) { u8 index; u8 a; u8 b; SetSpriteCoordsToAnimAttackerCoords(sprite); StartSpriteAnim(sprite, gBattleAnimArgs[0]); if ((index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[gBattleAnimArgs[1]][0])) != 0xFF) sprite->oam.paletteNum = index; sprite->data[1] = gBattleAnimArgs[1]; sprite->data[2] = 0; sprite->data[3] = gBattleAnimArgs[2]; if (IsContest()) { a = 48; b = 40; } else { a = GetBattlerSpriteCoord(gBattleAnimTarget, 2); b = GetBattlerSpriteCoord(gBattleAnimTarget, 3); } sprite->data[4] = sprite->pos1.x << 4; sprite->data[5] = sprite->pos1.y << 4; AnimWavyMusicNotesGetNextPos(a - sprite->pos1.x, b - sprite->pos1.y, &sprite->data[6], &sprite->data[7], 40); sprite->callback = AnimWavyMusicNotesStep; } static void AnimWavyMusicNotesGetNextPos(s16 a, s16 b, s16* c, s16* d, s8 e) { int f; int g; if (a < 0) e = -e; f = a << 8; g = f / e; if (g == 0) g = 1; *c = f / g; *d = (b << 8) / g; } static void AnimWavyMusicNotesStep(struct Sprite* sprite) { s16 y, yDelta; u8 index; sprite->data[0]++; yDelta = sprite->data[0] * 5 - ((sprite->data[0] * 5 / 256) << 8); sprite->data[4] += sprite->data[6]; sprite->data[5] += sprite->data[7]; sprite->pos1.x = sprite->data[4] >> 4; sprite->pos1.y = sprite->data[5] >> 4; sprite->pos2.y = Sin(yDelta, 15); y = sprite->pos1.y; if (sprite->pos1.x < -16 || sprite->pos1.x > 256 || y < -16 || y > 128) { DestroySpriteAndMatrix(sprite); } else { if (sprite->data[3] && ++sprite->data[2] > sprite->data[3]) { sprite->data[2] = 0; if (++sprite->data[1] > 3) sprite->data[1] = 0; index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[sprite->data[1]][0]); if (index != 0xFF) sprite->oam.paletteNum = index; } } } void AnimFlyingMusicNotes(struct Sprite* sprite) { if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) gBattleAnimArgs[1] *= -1; sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[1]; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2]; StartSpriteAnim(sprite, gBattleAnimArgs[0]); sprite->data[2] = 0; sprite->data[3] = 0; sprite->data[4] = sprite->pos1.x << 4; sprite->data[5] = sprite->pos1.y << 4; sprite->data[6] = (gBattleAnimArgs[1] << 4) / 5; sprite->data[7] = (gBattleAnimArgs[2] << 7) / 5; sprite->callback = AnimFlyingMusicNotesStep; } static void AnimFlyingMusicNotesStep(struct Sprite* sprite) { sprite->data[4] += sprite->data[6]; sprite->data[5] += sprite->data[7]; sprite->pos1.x = sprite->data[4] >> 4; sprite->pos1.y = sprite->data[5] >> 4; if (sprite->data[0] > 5 && sprite->data[3] == 0) { sprite->data[2] = (sprite->data[2] + 16) & 0xFF; sprite->pos2.x = Cos(sprite->data[2], 18); sprite->pos2.y = Sin(sprite->data[2], 18); if (sprite->data[2] == 0) sprite->data[3] = 1; } if (++sprite->data[0] == 48) DestroySpriteAndMatrix(sprite); } void AnimBellyDrumHand(struct Sprite* sprite) { s16 a; if (gBattleAnimArgs[0] == 1) { sprite->oam.matrixNum = ST_OAM_HFLIP; a = 16; } else { a = -16; } sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + a; sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + 8; sprite->data[0] = 8; sprite->callback = WaitAnimForDuration; StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } void AnimSlowFlyingMusicNotes(struct Sprite* sprite) { s16 xDiff; u8 index; SetSpriteCoordsToAnimAttackerCoords(sprite); sprite->pos1.y += 8; StartSpriteAnim(sprite, gBattleAnimArgs[1]); index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[gBattleAnimArgs[2]][0]); if (index != 0xFF) sprite->oam.paletteNum = index; xDiff = (gBattleAnimArgs[0] == 0) ? -32 : 32; sprite->data[0] = 40; sprite->data[1] = sprite->pos1.x; sprite->data[2] = xDiff + sprite->data[1]; sprite->data[3] = sprite->pos1.y; sprite->data[4] = sprite->data[3] - 40; InitAnimLinearTranslation(sprite); sprite->data[5] = gBattleAnimArgs[3]; sprite->callback = AnimSlowFlyingMusicNotesStep; } static void AnimSlowFlyingMusicNotesStep(struct Sprite* sprite) { if (AnimTranslateLinear(sprite) == 0) { s16 xDiff; xDiff = Sin(sprite->data[5], 8); if (sprite->pos2.x < 0) xDiff = -xDiff; sprite->pos2.x += xDiff; sprite->pos2.y += Sin(sprite->data[5], 4); sprite->data[5] = (sprite->data[5] + 8) & 0xFF; } else { DestroyAnimSprite(sprite); } } void SetSpriteNextToMonHead(u8 battler, struct Sprite* sprite) { if (GetBattlerSide(battler) == B_SIDE_PLAYER) sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) + 8; else sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) - 8; sprite->pos1.y = GetBattlerSpriteCoord(battler, 3) - (s16)GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_HEIGHT) / 4; } void AnimThoughtBubble(struct Sprite* sprite) { u8 a; u8 battler; if (gBattleAnimArgs[0] == 0) battler = gBattleAnimAttacker; else battler = gBattleAnimTarget; SetSpriteNextToMonHead(battler, sprite); a = (GetBattlerSide(battler) == B_SIDE_PLAYER) ? 0 : 1; sprite->data[0] = gBattleAnimArgs[1]; sprite->data[1] = a + 2; StartSpriteAnim(sprite, a); StoreSpriteCallbackInData6(sprite, AnimThoughtBubbleStep); sprite->callback = RunStoredCallbackWhenAnimEnds; } static void AnimThoughtBubbleStep(struct Sprite* sprite) { if (--sprite->data[0] == 0) { StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); StartSpriteAnim(sprite, sprite->data[1]); sprite->callback = RunStoredCallbackWhenAnimEnds; } } void AnimMetronomeFinger(struct Sprite* sprite) { u8 battler; if (gBattleAnimArgs[0] == 0) battler = gBattleAnimAttacker; else battler = gBattleAnimTarget; SetSpriteNextToMonHead(battler, sprite); sprite->data[0] = 0; StoreSpriteCallbackInData6(sprite, AnimMetronomeFingerStep); sprite->callback = RunStoredCallbackWhenAffineAnimEnds; } static void AnimMetronomeFingerStep(struct Sprite* sprite) { if (++sprite->data[0] > 16) { StartSpriteAffineAnim(sprite, 1); StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); sprite->callback = RunStoredCallbackWhenAffineAnimEnds; } } void AnimFollowMeFinger(struct Sprite* sprite) { u8 battler; if (gBattleAnimArgs[0] == 0) battler = gBattleAnimAttacker; else battler = gBattleAnimTarget; sprite->pos1.x = GetBattlerSpriteCoord(battler, 0); sprite->pos1.y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP); if (sprite->pos1.y <= 9) sprite->pos1.y = 10; sprite->data[0] = 1; sprite->data[1] = 0; sprite->data[2] = sprite->subpriority; sprite->data[3] = sprite->subpriority + 4; sprite->data[4] = 0; StoreSpriteCallbackInData6(sprite, AnimFollowMeFingerStep1); sprite->callback = RunStoredCallbackWhenAffineAnimEnds; } static void AnimFollowMeFingerStep1(struct Sprite* sprite) { if (++sprite->data[4] > 12) sprite->callback = AnimFollowMeFingerStep2; } static void AnimFollowMeFingerStep2(struct Sprite* sprite) { s16 x1, x2; sprite->data[1] += 4; if (sprite->data[1] > 254) { if (--sprite->data[0] == 0) { sprite->pos2.x = 0; sprite->callback = AnimMetronomeFingerStep; return; } else { sprite->data[1] &= 0xFF; } } if (sprite->data[1] > 0x4F) sprite->subpriority = sprite->data[3]; if (sprite->data[1] > 0x9F) sprite->subpriority = sprite->data[2]; x1 = gSineTable[sprite->data[1]]; x2 = x1 >> 3; sprite->pos2.x = (x1 >> 3) + (x2 >> 1); } void AnimTauntFinger(struct Sprite* sprite) { u8 battler; if (gBattleAnimArgs[0] == 0) battler = gBattleAnimAttacker; else battler = gBattleAnimTarget; SetSpriteNextToMonHead(battler, sprite); if (GetBattlerSide(battler) == B_SIDE_PLAYER) { StartSpriteAnim(sprite, 0); sprite->data[0] = 2; } else { StartSpriteAnim(sprite, 1); sprite->data[0] = 3; } sprite->callback = AnimTauntFingerStep1; } static void AnimTauntFingerStep1(struct Sprite* sprite) { if (++sprite->data[1] > 10) { sprite->data[1] = 0; StartSpriteAnim(sprite, sprite->data[0]); StoreSpriteCallbackInData6(sprite, AnimTauntFingerStep2); sprite->callback = RunStoredCallbackWhenAnimEnds; } } static void AnimTauntFingerStep2(struct Sprite* sprite) { if (++sprite->data[1] > 5) DestroyAnimSprite(sprite); }