diff options
author | Evan <eroelke@gmail.com> | 2019-12-02 12:32:56 -0700 |
---|---|---|
committer | Evan <eroelke@gmail.com> | 2019-12-02 12:32:56 -0700 |
commit | 4454ef35e861cf18ce6e43033f551538366bfb51 (patch) | |
tree | 47fb087feaba7d2019512b57f8099a42f8ee0210 /src | |
parent | 86e62e24c1fe9d7fe39f6ece5412ef24a7c2c9e5 (diff) |
b_anim_eff_3
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_anim_effects_1.c | 463 | ||||
-rw-r--r-- | src/battle_anim_effects_2.c | 3818 | ||||
-rw-r--r-- | src/battle_anim_effects_3.c | 5495 |
3 files changed, 9560 insertions, 216 deletions
diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index a02125d6d..9d820b628 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -16,8 +16,10 @@ #include "constants/rgb.h" #include "constants/songs.h" -EWRAM_DATA s16 gUnknown_0203A0F8[4] = {0}; +// RAM +EWRAM_DATA s16 gUnknown_203999C[4] = {0}; +// Function Declarations void AnimMovePowderParticle(struct Sprite *); void AnimPowerAbsorptionOrb(struct Sprite *); void AnimSolarbeamBigOrb(struct Sprite *); @@ -150,6 +152,8 @@ static void AnimFollowMeFingerStep2(struct Sprite *); static void AnimTauntFingerStep1(struct Sprite *); static void AnimTauntFingerStep2(struct Sprite *); +static const u8 gUnknown_83E2964[] = {0x02, 0x04, 0x01, 0x03}; + const union AnimCmd gPowderParticlesAnimCmds[] = //gUnknown_83E2968 { ANIMCMD_FRAME(0, 5), @@ -406,25 +410,25 @@ const struct SpriteTemplate gLeechSeedSpriteTemplate = //gUnknown_83E2B34 .callback = AnimLeechSeed, }; -const union AnimCmd gSporeParticleAnimCmds1[] = +const union AnimCmd gSporeParticleAnimCmds1[] = //gUnknown_83E2B4C { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; -const union AnimCmd gSporeParticleAnimCmds2[] = +const union AnimCmd gSporeParticleAnimCmds2[] = //gUnknown_83E2B54 { ANIMCMD_FRAME(4, 7), ANIMCMD_END, }; -const union AnimCmd *const gSporeParticleAnimTable[] = +const union AnimCmd *const gSporeParticleAnimTable[] = //gUnknown_83E2B5C { gSporeParticleAnimCmds1, gSporeParticleAnimCmds2, }; -const struct SpriteTemplate gSporeParticleSpriteTemplate = +const struct SpriteTemplate gSporeParticleSpriteTemplate = //gUnknown_83E2B64 { .tileTag = ANIM_TAG_SPORE, .paletteTag = ANIM_TAG_SPORE, @@ -435,29 +439,29 @@ const struct SpriteTemplate gSporeParticleSpriteTemplate = .callback = AnimSporeParticle, }; -const union AnimCmd gPetalDanceBigFlowerAnimCmds[] = +const union AnimCmd gPetalDanceBigFlowerAnimCmds[] = //gUnknown_83E2B7C { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; -const union AnimCmd gPetalDanceSmallFlowerAnimCmds[] = +const union AnimCmd gPetalDanceSmallFlowerAnimCmds[] = //gUnknown_83E2B84 { ANIMCMD_FRAME(4, 1), ANIMCMD_END, }; -const union AnimCmd *const gPetalDanceBigFlowerAnimTable[] = +const union AnimCmd *const gPetalDanceBigFlowerAnimTable[] = //gUnknown_83E2B8C { gPetalDanceBigFlowerAnimCmds, }; -const union AnimCmd *const gPetalDanceSmallFlowerAnimTable[] = +const union AnimCmd *const gPetalDanceSmallFlowerAnimTable[] = //gUnknown_83E2B90 { gPetalDanceSmallFlowerAnimCmds, }; -const struct SpriteTemplate gPetalDanceBigFlowerSpriteTemplate = +const struct SpriteTemplate gPetalDanceBigFlowerSpriteTemplate = //gUnknown_83E2B94 { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, @@ -468,7 +472,7 @@ const struct SpriteTemplate gPetalDanceBigFlowerSpriteTemplate = .callback = AnimPetalDanceBigFlower, }; -const struct SpriteTemplate gPetalDanceSmallFlowerSpriteTemplate = +const struct SpriteTemplate gPetalDanceSmallFlowerSpriteTemplate = //gUnknown_83E2BAC { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, @@ -479,7 +483,7 @@ const struct SpriteTemplate gPetalDanceSmallFlowerSpriteTemplate = .callback = AnimPetalDanceSmallFlower, }; -const union AnimCmd gRazorLeafParticleAnimCmds1[] = +const union AnimCmd gRazorLeafParticleAnimCmds1[] = //gUnknown_83E2BC4 { ANIMCMD_FRAME(0, 5), ANIMCMD_FRAME(4, 5), @@ -494,7 +498,7 @@ const union AnimCmd gRazorLeafParticleAnimCmds1[] = ANIMCMD_JUMP(0), }; -const union AnimCmd gRazorLeafParticleAnimCmds2[] = +const union AnimCmd gRazorLeafParticleAnimCmds2[] = //gUnknown_83E2BF0 { ANIMCMD_FRAME(24, 5), ANIMCMD_FRAME(28, 5), @@ -502,13 +506,13 @@ const union AnimCmd gRazorLeafParticleAnimCmds2[] = ANIMCMD_END, }; -const union AnimCmd *const gRazorLeafParticleAnimTable[] = +const union AnimCmd *const gRazorLeafParticleAnimTable[] = //gUnknown_83E2C00 { gRazorLeafParticleAnimCmds1, gRazorLeafParticleAnimCmds2, }; -const struct SpriteTemplate gRazorLeafParticleSpriteTemplate = +const struct SpriteTemplate gRazorLeafParticleSpriteTemplate = //gUnknown_83E2C08 { .tileTag = ANIM_TAG_LEAF, .paletteTag = ANIM_TAG_LEAF, @@ -519,7 +523,7 @@ const struct SpriteTemplate gRazorLeafParticleSpriteTemplate = .callback = AnimRazorLeafParticle, }; -const struct SpriteTemplate gTwisterLeafParticleSpriteTemplate = +const struct SpriteTemplate gTwisterLeafParticleSpriteTemplate = //gUnknown_83E2C20 { .tileTag = ANIM_TAG_LEAF, .paletteTag = ANIM_TAG_LEAF, @@ -530,7 +534,7 @@ const struct SpriteTemplate gTwisterLeafParticleSpriteTemplate = .callback = AnimMoveTwisterParticle, }; -const union AnimCmd gRazorLeafCutterAnimCmds[] = +const union AnimCmd gRazorLeafCutterAnimCmds[] = //gUnknown_83E2C38 { ANIMCMD_FRAME(0, 3), ANIMCMD_FRAME(0, 3, .hFlip = TRUE), @@ -539,12 +543,12 @@ const union AnimCmd gRazorLeafCutterAnimCmds[] = ANIMCMD_JUMP(0), }; -const union AnimCmd *const gRazorLeafCutterAnimTable[] = +const union AnimCmd *const gRazorLeafCutterAnimTable[] = //gUnknown_83E2C4C { gRazorLeafCutterAnimCmds, }; -const struct SpriteTemplate gRazorLeafCutterSpriteTemplate = +const struct SpriteTemplate gRazorLeafCutterSpriteTemplate = //gUnknown_83E2C50 { .tileTag = ANIM_TAG_RAZOR_LEAF, .paletteTag = ANIM_TAG_RAZOR_LEAF, @@ -555,16 +559,18 @@ const struct SpriteTemplate gRazorLeafCutterSpriteTemplate = .callback = AnimTranslateLinearSingleSineWave, }; -const union AffineAnimCmd gSwiftStarAffineAnimCmds[] = { +const union AffineAnimCmd gSwiftStarAffineAnimCmds[] = //gUnknown_83E2C68 +{ AFFINEANIMCMD_FRAME(0, 0, 0, 1), AFFINEANIMCMD_JUMP(0), }; -const union AffineAnimCmd *const gSwiftStarAffineAnimTable[] = { +const union AffineAnimCmd *const gSwiftStarAffineAnimTable[] = //gUnknown_83E2C78 +{ gSwiftStarAffineAnimCmds, }; -const struct SpriteTemplate gSwiftStarSpriteTemplate = +const struct SpriteTemplate gSwiftStarSpriteTemplate = //gUnknown_83E2C7C { .tileTag = ANIM_TAG_YELLOW_STAR, .paletteTag = ANIM_TAG_YELLOW_STAR, @@ -575,7 +581,7 @@ const struct SpriteTemplate gSwiftStarSpriteTemplate = .callback = AnimTranslateLinearSingleSineWave, }; -const union AnimCmd gConstrictBindingAnimCmds1[] = +const union AnimCmd gConstrictBindingAnimCmds1[] = //gUnknown_83E2C94 { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(32, 4), @@ -584,7 +590,7 @@ const union AnimCmd gConstrictBindingAnimCmds1[] = ANIMCMD_END, }; -const union AnimCmd gConstrictBindingAnimCmds2[] = +const union AnimCmd gConstrictBindingAnimCmds2[] = //gUnknown_83E2CA8 { ANIMCMD_FRAME(0, 4, .hFlip = TRUE), ANIMCMD_FRAME(32, 4, .hFlip = TRUE), @@ -593,32 +599,35 @@ const union AnimCmd gConstrictBindingAnimCmds2[] = ANIMCMD_END, }; -const union AnimCmd *const gConstrictBindingAnimTable[] = +const union AnimCmd *const gConstrictBindingAnimTable[] = //gUnknown_83E2CBC { gConstrictBindingAnimCmds1, gConstrictBindingAnimCmds2, }; -const union AffineAnimCmd gConstrictBindingAffineAnimCmds1[] = { +const union AffineAnimCmd gConstrictBindingAffineAnimCmds1[] = //gUnknown_83E2CC4 +{ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_FRAME(-11, 0, 0, 6), AFFINEANIMCMD_FRAME(11, 0, 0, 6), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gConstrictBindingAffineAnimCmds2[] = { +const union AffineAnimCmd gConstrictBindingAffineAnimCmds2[] = //gUnknown_83E2CE4 +{ 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[] = { +const union AffineAnimCmd *const gConstrictBindingAffineAnimTable[] = //gUnknown_83E2D04 +{ gConstrictBindingAffineAnimCmds1, gConstrictBindingAffineAnimCmds2, }; -const struct SpriteTemplate gConstrictBindingSpriteTemplate = +const struct SpriteTemplate gConstrictBindingSpriteTemplate = //gUnknown_83E2D0C { .tileTag = ANIM_TAG_TENDRILS, .paletteTag = ANIM_TAG_TENDRILS, @@ -629,23 +638,26 @@ const struct SpriteTemplate gConstrictBindingSpriteTemplate = .callback = AnimConstrictBinding, }; -const union AffineAnimCmd gMimicOrbAffineAnimCmds1[] = { +const union AffineAnimCmd gMimicOrbAffineAnimCmds1[] = //gUnknown_83E2D24 +{ AFFINEANIMCMD_FRAME(0, 0, 0, 0), AFFINEANIMCMD_FRAME(48, 48, 0, 14), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gMimicOrbAffineAnimCmds2[] = { +const union AffineAnimCmd gMimicOrbAffineAnimCmds2[] = //gUnknown_83E2D3C +{ AFFINEANIMCMD_FRAME(-16, -16, 0, 1), AFFINEANIMCMD_JUMP(0), }; -const union AffineAnimCmd *const gMimicOrbAffineAnimTable[] = { +const union AffineAnimCmd *const gMimicOrbAffineAnimTable[] = //gUnknown_83E2D4C +{ gMimicOrbAffineAnimCmds1, gMimicOrbAffineAnimCmds2, }; -const struct SpriteTemplate gMimicOrbSpriteTemplate = +const struct SpriteTemplate gMimicOrbSpriteTemplate = //gUnknown_83E2D54 { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, @@ -656,7 +668,7 @@ const struct SpriteTemplate gMimicOrbSpriteTemplate = .callback = AnimMimicOrb, }; -const union AnimCmd gIngrainRootAnimCmds1[] = +const union AnimCmd gIngrainRootAnimCmds1[] = //gUnknown_83E2D6C { ANIMCMD_FRAME(0, 7), ANIMCMD_FRAME(16, 7), @@ -665,7 +677,7 @@ const union AnimCmd gIngrainRootAnimCmds1[] = ANIMCMD_END, }; -const union AnimCmd gIngrainRootAnimCmds2[] = +const union AnimCmd gIngrainRootAnimCmds2[] = //gUnknown_83E2D80 { ANIMCMD_FRAME(0, 7, .hFlip = TRUE), ANIMCMD_FRAME(16, 7, .hFlip = TRUE), @@ -674,7 +686,7 @@ const union AnimCmd gIngrainRootAnimCmds2[] = ANIMCMD_END, }; -const union AnimCmd gIngrainRootAnimCmds3[] = +const union AnimCmd gIngrainRootAnimCmds3[] = //gUnknown_83E2D94 { ANIMCMD_FRAME(0, 7), ANIMCMD_FRAME(16, 7), @@ -682,7 +694,7 @@ const union AnimCmd gIngrainRootAnimCmds3[] = ANIMCMD_END, }; -const union AnimCmd gIngrainRootAnimCmds4[] = +const union AnimCmd gIngrainRootAnimCmds4[] = //gUnknown_83E2DA4 { ANIMCMD_FRAME(0, 7, .hFlip = TRUE), ANIMCMD_FRAME(16, 7, .hFlip = TRUE), @@ -690,7 +702,7 @@ const union AnimCmd gIngrainRootAnimCmds4[] = ANIMCMD_END, }; -const union AnimCmd *const gIngrainRootAnimTable[] = +const union AnimCmd *const gIngrainRootAnimTable[] = //gUnknown_83E2DB4 { gIngrainRootAnimCmds1, gIngrainRootAnimCmds2, @@ -698,7 +710,7 @@ const union AnimCmd *const gIngrainRootAnimTable[] = gIngrainRootAnimCmds4, }; -const struct SpriteTemplate gIngrainRootSpriteTemplate = +const struct SpriteTemplate gIngrainRootSpriteTemplate = //gUnknown_83E2DC4 { .tileTag = ANIM_TAG_ROOTS, .paletteTag = ANIM_TAG_ROOTS, @@ -709,7 +721,7 @@ const struct SpriteTemplate gIngrainRootSpriteTemplate = .callback = AnimIngrainRoot, }; -const struct SpriteTemplate gFrenzyPlantRootSpriteTemplate = +const struct SpriteTemplate gFrenzyPlantRootSpriteTemplate = //gUnknown_83E2DDC { .tileTag = ANIM_TAG_ROOTS, .paletteTag = ANIM_TAG_ROOTS, @@ -720,19 +732,19 @@ const struct SpriteTemplate gFrenzyPlantRootSpriteTemplate = .callback = AnimFrenzyPlantRoot, }; -const union AnimCmd gIngrainOrbAnimCmds[] = +const union AnimCmd gIngrainOrbAnimCmds[] = //gUnknown_83E2DF4 { ANIMCMD_FRAME(3, 3), ANIMCMD_FRAME(0, 5), ANIMCMD_JUMP(0), }; -const union AnimCmd *const gIngrainOrbAnimTable[] = +const union AnimCmd *const gIngrainOrbAnimTable[] = //gUnknown_83E2E00 { gIngrainOrbAnimCmds, }; -const struct SpriteTemplate gIngrainOrbSpriteTemplate = +const struct SpriteTemplate gIngrainOrbSpriteTemplate = //gUnknown_83E2E04 { .tileTag = ANIM_TAG_ORBS, .paletteTag = ANIM_TAG_ORBS, @@ -743,25 +755,27 @@ const struct SpriteTemplate gIngrainOrbSpriteTemplate = .callback = AnimIngrainOrb, }; -const union AnimCmd gFallingBagAnimCmds[] = +const union AnimCmd gFallingBagAnimCmds[] = //gUnknown_83E2E1C { ANIMCMD_FRAME(0, 30), ANIMCMD_END, }; -const union AnimCmd *const gFallingBagAnimTable[] = +const union AnimCmd *const gFallingBagAnimTable[] = //gUnknown_83E2E24 { gFallingBagAnimCmds, }; -const union AffineAnimCmd gFallingBagAffineAnimCmds1[] = { +const union AffineAnimCmd gFallingBagAffineAnimCmds1[] = //gUnknown_83E2E28 +{ AFFINEANIMCMD_FRAME(0, 0, -4, 10), AFFINEANIMCMD_FRAME(0, 0, 4, 20), AFFINEANIMCMD_FRAME(0, 0, -4, 10), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gFallingBagAffineAnimCmds2[] = { +const union AffineAnimCmd gFallingBagAffineAnimCmds2[] = //gUnknown_83E2E48 +{ AFFINEANIMCMD_FRAME(0, 0, -1, 2), AFFINEANIMCMD_FRAME(0, 0, 1, 4), AFFINEANIMCMD_FRAME(0, 0, -1, 4), @@ -771,12 +785,13 @@ const union AffineAnimCmd gFallingBagAffineAnimCmds2[] = { AFFINEANIMCMD_END, }; -const union AffineAnimCmd *const gFallingBagAffineAnimTable[] = { +const union AffineAnimCmd *const gFallingBagAffineAnimTable[] = //gUnknown_83E2E80 +{ gFallingBagAffineAnimCmds1, gFallingBagAffineAnimCmds2, }; -const struct SpriteTemplate gPresentSpriteTemplate = +const struct SpriteTemplate gPresentSpriteTemplate = //gUnknown_83E2E88 { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, @@ -787,7 +802,7 @@ const struct SpriteTemplate gPresentSpriteTemplate = .callback = AnimPresent, }; -const struct SpriteTemplate gKnockOffItemSpriteTemplate = +const struct SpriteTemplate gKnockOffItemSpriteTemplate = //gUnknown_83E2EA0 { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, @@ -798,7 +813,7 @@ const struct SpriteTemplate gKnockOffItemSpriteTemplate = .callback = AnimKnockOffItem, }; -const union AnimCmd gPresentHealParticleAnimCmds[] = +const union AnimCmd gPresentHealParticleAnimCmds[] = //gUnknown_83E2EB8 { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(4, 4), @@ -807,12 +822,12 @@ const union AnimCmd gPresentHealParticleAnimCmds[] = ANIMCMD_END, }; -const union AnimCmd *const gPresentHealParticleAnimTable[] = +const union AnimCmd *const gPresentHealParticleAnimTable[] = //gUnknown_83E2ECC { gPresentHealParticleAnimCmds, }; -const struct SpriteTemplate gPresentHealParticleSpriteTemplate = +const struct SpriteTemplate gPresentHealParticleSpriteTemplate = //gUnknown_83E2ED0 { .tileTag = ANIM_TAG_GREEN_SPARKLE, .paletteTag = ANIM_TAG_GREEN_SPARKLE, @@ -823,7 +838,7 @@ const struct SpriteTemplate gPresentHealParticleSpriteTemplate = .callback = AnimPresentHealParticle, }; -const struct SpriteTemplate gItemStealSpriteTemplate = +const struct SpriteTemplate gItemStealSpriteTemplate = //gUnknown_83E2EE8 { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, @@ -834,12 +849,14 @@ const struct SpriteTemplate gItemStealSpriteTemplate = .callback = AnimItemSteal, }; -const union AffineAnimCmd gTrickBagAffineAnimCmds1[] = { +const union AffineAnimCmd gTrickBagAffineAnimCmds1[] = //gUnknown_83E2F00 +{ AFFINEANIMCMD_FRAME(0, 0, 0, 3), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gTrickBagAffineAnimCmds2[] = { +const union AffineAnimCmd gTrickBagAffineAnimCmds2[] = //gUnknown_83E2F10 +{ AFFINEANIMCMD_FRAME(0, -10, 0, 3), AFFINEANIMCMD_FRAME(0, -6, 0, 3), AFFINEANIMCMD_FRAME(0, -2, 0, 3), @@ -850,14 +867,15 @@ const union AffineAnimCmd gTrickBagAffineAnimCmds2[] = { AFFINEANIMCMD_END, }; -const union AffineAnimCmd *const gTrickBagAffineAnimTable[] = { +const union AffineAnimCmd *const gTrickBagAffineAnimTable[] = //gUnknown_83E2F50 +{ gTrickBagAffineAnimCmds1, gTrickBagAffineAnimCmds2, gFallingBagAffineAnimCmds1, gFallingBagAffineAnimCmds2, }; -const struct SpriteTemplate gTrickBagSpriteTemplate = +const struct SpriteTemplate gTrickBagSpriteTemplate = //gUnknown_83E2F60 { .tileTag = ANIM_TAG_ITEM_BAG, .paletteTag = ANIM_TAG_ITEM_BAG, @@ -868,7 +886,7 @@ const struct SpriteTemplate gTrickBagSpriteTemplate = .callback = AnimTrickBag, }; -const s8 gTrickBagCoordinates[][3] = +const s8 gTrickBagCoordinates[][3] = //gUnknown_83E2F78 { {5, 24, 1}, {0, 4, 0}, @@ -883,49 +901,49 @@ const s8 gTrickBagCoordinates[][3] = {0, 0, 127}, }; -const union AnimCmd gLeafBladeAnimCmds1[] = +const union AnimCmd gLeafBladeAnimCmds1[] = //gUnknown_83E2F9C { ANIMCMD_FRAME(28, 1), ANIMCMD_END, }; -const union AnimCmd gLeafBladeAnimCmds2[] = +const union AnimCmd gLeafBladeAnimCmds2[] = //gUnknown_83E2FA4 { ANIMCMD_FRAME(32, 1), ANIMCMD_END, }; -const union AnimCmd gLeafBladeAnimCmds3[] = +const union AnimCmd gLeafBladeAnimCmds3[] = //gUnknown_83E2FAC { ANIMCMD_FRAME(20, 1), ANIMCMD_END, }; -const union AnimCmd gLeafBladeAnimCmds4[] = +const union AnimCmd gLeafBladeAnimCmds4[] = //gUnknown_83E2FB4 { ANIMCMD_FRAME(28, 1, .hFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd gLeafBladeAnimCmds5[] = +const union AnimCmd gLeafBladeAnimCmds5[] = //gUnknown_83E2FBC { ANIMCMD_FRAME(16, 1), ANIMCMD_END, }; -const union AnimCmd gLeafBladeAnimCmds6[] = +const union AnimCmd gLeafBladeAnimCmds6[] = //gUnknown_83E2FC4 { ANIMCMD_FRAME(16, 1, .hFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd gLeafBladeAnimCmds7[] = +const union AnimCmd gLeafBladeAnimCmds7[] = //gUnknown_83E2FCC { ANIMCMD_FRAME(28, 1), ANIMCMD_END, }; -const union AnimCmd *const gLeafBladeAnimTable[] = +const union AnimCmd *const gLeafBladeAnimTable[] = //gUnknown_83E2FD4 { gLeafBladeAnimCmds1, gLeafBladeAnimCmds2, @@ -936,7 +954,7 @@ const union AnimCmd *const gLeafBladeAnimTable[] = gLeafBladeAnimCmds7, }; -const struct SpriteTemplate gLeafBladeSpriteTemplate = +const struct SpriteTemplate gLeafBladeSpriteTemplate = //gUnknown_83E2FF0 { .tileTag = ANIM_TAG_LEAF, .paletteTag = ANIM_TAG_LEAF, @@ -947,17 +965,19 @@ const struct SpriteTemplate gLeafBladeSpriteTemplate = .callback = SpriteCallbackDummy, }; -const union AffineAnimCmd gAromatherapyBigFlowerAffineAnimCmds[] = { +const union AffineAnimCmd gAromatherapyBigFlowerAffineAnimCmds[] = //gUnknown_83E3008 +{ AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_FRAME(0, 0, 4, 1), AFFINEANIMCMD_JUMP(1), }; -const union AffineAnimCmd *const gAromatherapyBigFlowerAffineAnimTable[] = { +const union AffineAnimCmd *const gAromatherapyBigFlowerAffineAnimTable[] = //gUnknown_83E3020 +{ gAromatherapyBigFlowerAffineAnimCmds, }; -const struct SpriteTemplate gAromatherapySmallFlowerSpriteTemplate = +const struct SpriteTemplate gAromatherapySmallFlowerSpriteTemplate = //gUnknown_83E3024 { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, @@ -968,7 +988,7 @@ const struct SpriteTemplate gAromatherapySmallFlowerSpriteTemplate = .callback = AnimFlyingParticle, }; -const struct SpriteTemplate gAromatherapyBigFlowerSpriteTemplate = +const struct SpriteTemplate gAromatherapyBigFlowerSpriteTemplate = //gUnknown_83E303C { .tileTag = ANIM_TAG_FLOWER, .paletteTag = ANIM_TAG_FLOWER, @@ -979,37 +999,43 @@ const struct SpriteTemplate gAromatherapyBigFlowerSpriteTemplate = .callback = AnimFlyingParticle, }; -const union AffineAnimCmd gSilverWindBigSparkAffineAnimCmds[] = { +const union AffineAnimCmd gSilverWindBigSparkAffineAnimCmds[] = //gUnknown_83E3054 +{ AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_FRAME(0, 0, -10, 1), AFFINEANIMCMD_JUMP(1), }; -const union AffineAnimCmd gSilverWindMediumSparkAffineAnimCmds[] = { +const union AffineAnimCmd gSilverWindMediumSparkAffineAnimCmds[] = //gUnknown_83E306C +{ AFFINEANIMCMD_FRAME(192, 192, 0, 0), AFFINEANIMCMD_FRAME(0, 0, -12, 1), AFFINEANIMCMD_JUMP(1), }; -const union AffineAnimCmd gSilverWindSmallSparkAffineAnimCmds[] = { +const union AffineAnimCmd gSilverWindSmallSparkAffineAnimCmds[] = //gUnknown_83E3084 +{ AFFINEANIMCMD_FRAME(143, 143, 0, 0), AFFINEANIMCMD_FRAME(0, 0, -15, 1), AFFINEANIMCMD_JUMP(1), }; -const union AffineAnimCmd *const gSilverWindBigSparkAffineAnimTable[] = { +const union AffineAnimCmd *const gSilverWindBigSparkAffineAnimTable[] = //gUnknown_83E309C +{ gSilverWindBigSparkAffineAnimCmds, }; -const union AffineAnimCmd *const gSilverWindMediumSparkAffineAnimTable[] = { +const union AffineAnimCmd *const gSilverWindMediumSparkAffineAnimTable[] = //gUnknown_83E30A0 +{ gSilverWindMediumSparkAffineAnimCmds, }; -const union AffineAnimCmd *const gSilverWindSmallSparkAffineAnimTable[] = { +const union AffineAnimCmd *const gSilverWindSmallSparkAffineAnimTable[] = //gUnknown_83E30A4 +{ gSilverWindSmallSparkAffineAnimCmds, }; -const struct SpriteTemplate gSilverWindBigSparkSpriteTemplate = +const struct SpriteTemplate gSilverWindBigSparkSpriteTemplate = //gUnknown_83E30A8 { .tileTag = ANIM_TAG_SPARKLE_6, .paletteTag = ANIM_TAG_SPARKLE_6, @@ -1020,7 +1046,7 @@ const struct SpriteTemplate gSilverWindBigSparkSpriteTemplate = .callback = AnimFlyingParticle, }; -const struct SpriteTemplate gSilverWindMediumSparkSpriteTemplate = +const struct SpriteTemplate gSilverWindMediumSparkSpriteTemplate = //gUnknown_83E30C0 { .tileTag = ANIM_TAG_SPARKLE_6, .paletteTag = ANIM_TAG_SPARKLE_6, @@ -1031,7 +1057,7 @@ const struct SpriteTemplate gSilverWindMediumSparkSpriteTemplate = .callback = AnimFlyingParticle, }; -const struct SpriteTemplate gSilverWindSmallSparkSpriteTemplate = +const struct SpriteTemplate gSilverWindSmallSparkSpriteTemplate = //gUnknown_83E30D8 { .tileTag = ANIM_TAG_SPARKLE_6, .paletteTag = ANIM_TAG_SPARKLE_6, @@ -1042,7 +1068,7 @@ const struct SpriteTemplate gSilverWindSmallSparkSpriteTemplate = .callback = AnimFlyingParticle, }; -const u16 gMagicalLeafBlendColors[] = +const u16 gMagicalLeafBlendColors[] = //gUnknown_83E30F0 { RGB(31, 0, 0), RGB(31, 19, 0), @@ -1053,7 +1079,7 @@ const u16 gMagicalLeafBlendColors[] = RGB(22, 21, 31), }; -const struct SpriteTemplate gNeedleArmSpikeSpriteTemplate = +const struct SpriteTemplate gNeedleArmSpikeSpriteTemplate = //gUnknown_83E3100 { .tileTag = ANIM_TAG_GREEN_SPIKE, .paletteTag = ANIM_TAG_GREEN_SPIKE, @@ -1064,7 +1090,7 @@ const struct SpriteTemplate gNeedleArmSpikeSpriteTemplate = .callback = AnimNeedleArmSpike, }; -const union AnimCmd gWhipAnimCmds1[] = +const union AnimCmd gWhipAnimCmds1[] = //gUnknown_83E3118 { ANIMCMD_FRAME(64, 3), ANIMCMD_FRAME(80, 3), @@ -1073,7 +1099,7 @@ const union AnimCmd gWhipAnimCmds1[] = ANIMCMD_END, }; -const union AnimCmd gWhipAnimCmds2[] = +const union AnimCmd gWhipAnimCmds2[] = //gUnknown_83E312C { ANIMCMD_FRAME(64, 3, .hFlip = TRUE), ANIMCMD_FRAME(80, 3, .hFlip = TRUE), @@ -1082,13 +1108,13 @@ const union AnimCmd gWhipAnimCmds2[] = ANIMCMD_END, }; -const union AnimCmd *const gWhipAnimTable[] = +const union AnimCmd *const gWhipAnimTable[] = //gUnknown_83E3140 { gWhipAnimCmds1, gWhipAnimCmds2, }; -const struct SpriteTemplate gSlamHitSpriteTemplate = +const struct SpriteTemplate gSlamHitSpriteTemplate = //gUnknown_83E3148 { .tileTag = ANIM_TAG_SLAM_HIT, .paletteTag = ANIM_TAG_SLAM_HIT, @@ -1099,7 +1125,7 @@ const struct SpriteTemplate gSlamHitSpriteTemplate = .callback = AnimWhipHit, }; -const struct SpriteTemplate gVineWhipSpriteTemplate = +const struct SpriteTemplate gVineWhipSpriteTemplate = //gUnknown_83E3160 { .tileTag = ANIM_TAG_WHIP_HIT, .paletteTag = ANIM_TAG_WHIP_HIT, @@ -1110,7 +1136,7 @@ const struct SpriteTemplate gVineWhipSpriteTemplate = .callback = AnimWhipHit, }; -const union AnimCmd gUnknown_08592900[] = +const union AnimCmd gUnknown_83E3178[] = { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), @@ -1120,99 +1146,105 @@ const union AnimCmd gUnknown_08592900[] = ANIMCMD_END, }; -const union AnimCmd *const gUnknown_08592918[] = +const union AnimCmd *const gUnknown_83E3190[] = { - gUnknown_08592900, + gUnknown_83E3178, }; -// Unused -const struct SpriteTemplate gUnknown_0859291C = +const struct SpriteTemplate gUnknown_83E3194 = // Unused { .tileTag = ANIM_TAG_HIT, .paletteTag = ANIM_TAG_HIT, .oam = &gOamData_AffineOff_ObjNormal_32x32, - .anims = gUnknown_08592918, + .anims = gUnknown_83E3190, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_80A43F8, }; -// Unused -const struct SpriteTemplate gUnknown_08592934 = +const struct SpriteTemplate gUnknown_83E31AC = // Unused { .tileTag = ANIM_TAG_HIT_2, .paletteTag = ANIM_TAG_HIT_2, .oam = &gOamData_AffineOff_ObjNormal_32x32, - .anims = gUnknown_08592918, + .anims = gUnknown_83E3190, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_80A43F8, }; -const union AffineAnimCmd gUnknown_0859294C[] = { +const union AffineAnimCmd gUnknown_83E31C4[] = +{ AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gUnknown_0859295C[] = { +const union AffineAnimCmd gUnknown_83E31D4[] = +{ AFFINEANIMCMD_FRAME(256, 256, 32, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gUnknown_0859296C[] = { +const union AffineAnimCmd gUnknown_83E31E4[] = +{ AFFINEANIMCMD_FRAME(256, 256, 64, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gUnknown_0859297C[] = { +const union AffineAnimCmd gUnknown_83E31F4[] = +{ AFFINEANIMCMD_FRAME(256, 256, 96, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gUnknown_0859298C[] = { +const union AffineAnimCmd gUnknown_83E3204[] = +{ AFFINEANIMCMD_FRAME(256, 256, -128, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gUnknown_0859299C[] = { +const union AffineAnimCmd gUnknown_83E3214[] = +{ AFFINEANIMCMD_FRAME(256, 256, -96, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gUnknown_085929AC[] = { +const union AffineAnimCmd gUnknown_83E3224[] = +{ AFFINEANIMCMD_FRAME(256, 256, -64, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gUnknown_085929BC[] = { +const union AffineAnimCmd gUnknown_83E3234[] = +{ 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, +const union AffineAnimCmd *const gUnknown_83E3244[] = +{ + gUnknown_83E31C4, + gUnknown_83E31D4, + gUnknown_83E31E4, + gUnknown_83E31F4, + gUnknown_83E3204, + gUnknown_83E3214, + gUnknown_83E3224, + gUnknown_83E3234, }; -// Unused -const struct SpriteTemplate gUnknown_085929EC = +const struct SpriteTemplate gUnknown_83E3264 = // Unused { .tileTag = ANIM_TAG_HANDS_AND_FEET, .paletteTag = ANIM_TAG_HANDS_AND_FEET, .oam = &gOamData_AffineNormal_ObjNormal_32x32, .anims = gDummySpriteAnimTable, .images = NULL, - .affineAnims = gUnknown_085929CC, + .affineAnims = gUnknown_83E3244, .callback = sub_80A4494, }; -const union AnimCmd gCuttingSliceAnimCmds[] = +const union AnimCmd gCuttingSliceAnimCmds[] = //gUnknown_83E327C { ANIMCMD_FRAME(0, 5), ANIMCMD_FRAME(16, 5), @@ -1221,12 +1253,12 @@ const union AnimCmd gCuttingSliceAnimCmds[] = ANIMCMD_END, }; -const union AnimCmd *const gCuttingSliceAnimTable[] = +const union AnimCmd *const gCuttingSliceAnimTable[] = //gUnknown_83E3290 { gCuttingSliceAnimCmds, }; -const struct SpriteTemplate gCuttingSliceSpriteTemplate = +const struct SpriteTemplate gCuttingSliceSpriteTemplate = //gUnknown_83E3294 { .tileTag = ANIM_TAG_CUT, .paletteTag = ANIM_TAG_CUT, @@ -1237,7 +1269,7 @@ const struct SpriteTemplate gCuttingSliceSpriteTemplate = .callback = AnimCuttingSlice, }; -const struct SpriteTemplate gAirCutterSliceSpriteTemplate = +const struct SpriteTemplate gAirCutterSliceSpriteTemplate = //gUnknown_83E32AC { .tileTag = ANIM_TAG_CUT, .paletteTag = ANIM_TAG_CUT, @@ -1248,93 +1280,92 @@ const struct SpriteTemplate gAirCutterSliceSpriteTemplate = .callback = AnimAirCutterSlice, }; -const union AnimCmd gUnknown_08592A4C[] = +const union AnimCmd gUnknown_83E32C4[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A54[] = +const union AnimCmd gUnknown_83E32CC[] = { ANIMCMD_FRAME(4, 1), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A5C[] = +const union AnimCmd gUnknown_83E32D4[] = { ANIMCMD_FRAME(8, 1), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A64[] = +const union AnimCmd gUnknown_83E32DC[] = { ANIMCMD_FRAME(12, 1), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A6C[] = +const union AnimCmd gUnknown_83E32E4[] = { ANIMCMD_FRAME(16, 1), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A74[] = +const union AnimCmd gUnknown_83E32EC[] = { ANIMCMD_FRAME(20, 1), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A7C[] = +const union AnimCmd gUnknown_83E32F4[] = { ANIMCMD_FRAME(0, 1, .vFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A84[] = +const union AnimCmd gUnknown_83E32FC[] = { ANIMCMD_FRAME(4, 1, .vFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A8C[] = +const union AnimCmd gUnknown_83E3304[] = { ANIMCMD_FRAME(8, 1, .vFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd gUnknown_08592A94[] = +const union AnimCmd gUnknown_83E330C[] = { ANIMCMD_FRAME(12, 1, .vFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd *const gUnknown_08592A9C[] = +const union AnimCmd *const gUnknown_83E3314[] = { - gUnknown_08592A4C, - gUnknown_08592A54, - gUnknown_08592A5C, - gUnknown_08592A64, - gUnknown_08592A6C, - gUnknown_08592A74, - gUnknown_08592A7C, - gUnknown_08592A84, - gUnknown_08592A8C, - gUnknown_08592A94, + gUnknown_83E32C4, + gUnknown_83E32CC, + gUnknown_83E32D4, + gUnknown_83E32DC, + gUnknown_83E32E4, + gUnknown_83E32EC, + gUnknown_83E32F4, + gUnknown_83E32FC, + gUnknown_83E3304, + gUnknown_83E330C, }; -// Unused -const struct SpriteTemplate gUnknown_08592AC4 = +const struct SpriteTemplate gUnknown_83E333C = // Unused { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, .oam = &gOamData_AffineOff_ObjNormal_16x16, - .anims = gUnknown_08592A9C, + .anims = gUnknown_83E3314, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_80A481C, }; -const struct SpriteTemplate gUnknown_08592ADC = +const struct SpriteTemplate gProtectWallSpriteTemplate = //gUnknown_83E3354 { .tileTag = ANIM_TAG_PROTECT, .paletteTag = ANIM_TAG_PROTECT, @@ -1345,13 +1376,13 @@ const struct SpriteTemplate gUnknown_08592ADC = .callback = AnimProtect, }; -const union AffineAnimCmd gMilkBottleAffineAnimCmds1[] = +const union AffineAnimCmd gMilkBottleAffineAnimCmds1[] = //gUnknown_83E336C { AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_END, }; -const union AffineAnimCmd gMilkBottleAffineAnimCmds2[] = +const union AffineAnimCmd gMilkBottleAffineAnimCmds2[] =//gUnknown_83E337C { AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 12), AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6), @@ -1361,13 +1392,13 @@ const union AffineAnimCmd gMilkBottleAffineAnimCmds2[] = AFFINEANIMCMD_JUMP(0), }; -const union AffineAnimCmd *const gMilkBottleAffineAnimTable[] = +const union AffineAnimCmd *const gMilkBottleAffineAnimTable[] =//gUnknown_83E33AC { gMilkBottleAffineAnimCmds1, gMilkBottleAffineAnimCmds2, }; -const struct SpriteTemplate gMilkBottleSpriteTemplate = +const struct SpriteTemplate gMilkBottleSpriteTemplate =//gUnknown_83E33B4 { .tileTag = ANIM_TAG_MILK_BOTTLE, .paletteTag = ANIM_TAG_MILK_BOTTLE, @@ -1378,7 +1409,7 @@ const struct SpriteTemplate gMilkBottleSpriteTemplate = .callback = AnimMilkBottle, }; -const union AnimCmd gGrantingStarsAnimCmds[] = +const union AnimCmd gGrantingStarsAnimCmds[] =//gUnknown_83E33CC { ANIMCMD_FRAME(0, 7), ANIMCMD_FRAME(16, 7), @@ -1391,12 +1422,12 @@ const union AnimCmd gGrantingStarsAnimCmds[] = ANIMCMD_JUMP(0), }; -const union AnimCmd *const gGrantingStarsAnimTable[] = +const union AnimCmd *const gGrantingStarsAnimTable[] =//gUnknown_83E33F0 { gGrantingStarsAnimCmds, }; -const struct SpriteTemplate gGrantingStarsSpriteTemplate = +const struct SpriteTemplate gGrantingStarsSpriteTemplate = //gUnknown_83E33F4 { .tileTag = ANIM_TAG_SPARKLE_2, .paletteTag = ANIM_TAG_SPARKLE_2, @@ -1407,7 +1438,7 @@ const struct SpriteTemplate gGrantingStarsSpriteTemplate = .callback = AnimGrantingStars, }; -const struct SpriteTemplate gSparklingStarsSpriteTemplate = +const struct SpriteTemplate gSparklingStarsSpriteTemplate = //gUnknown_83E340C { .tileTag = ANIM_TAG_SPARKLE_2, .paletteTag = ANIM_TAG_SPARKLE_2, @@ -1418,7 +1449,7 @@ const struct SpriteTemplate gSparklingStarsSpriteTemplate = .callback = AnimSparkingStars, }; -const union AnimCmd gUnknown_08592BAC[] = +const union AnimCmd gUnknown_83E3424[] = { ANIMCMD_FRAME(0, 10), ANIMCMD_FRAME(4, 10), @@ -1431,7 +1462,7 @@ const union AnimCmd gUnknown_08592BAC[] = ANIMCMD_END, }; -const union AnimCmd gUnknown_08592BD0[] = +const union AnimCmd gUnknown_83E3448[] = { ANIMCMD_FRAME(0, 10, .hFlip = TRUE), ANIMCMD_FRAME(4, 10, .hFlip = TRUE), @@ -1444,31 +1475,30 @@ const union AnimCmd gUnknown_08592BD0[] = ANIMCMD_END, }; -const union AnimCmd *const gUnknown_08592BF4[] = +const union AnimCmd *const gUnknown_83E346C[] = { - gUnknown_08592BAC, - gUnknown_08592BD0, + gUnknown_83E3424, + gUnknown_83E3448, }; -// Unused -const struct SpriteTemplate gUnknown_08592BFC = +const struct SpriteTemplate gUnknown_83E3474 = // Unused { .tileTag = ANIM_TAG_BUBBLE_BURST, .paletteTag = ANIM_TAG_BUBBLE_BURST, .oam = &gOamData_AffineOff_ObjNormal_16x16, - .anims = gUnknown_08592BF4, + .anims = gUnknown_83E346C, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = sub_80A4E40, }; -const union AnimCmd gSleepLetterZAnimCmds[] = +const union AnimCmd gSleepLetterZAnimCmds[] =//gUnknown_83E348C { ANIMCMD_FRAME(0, 40), ANIMCMD_END, }; -const union AnimCmd *const gSleepLetterZAnimTable[] = +const union AnimCmd *const gSleepLetterZAnimTable[] =//gUnknown_83E3494 { gSleepLetterZAnimCmds, }; @@ -1501,13 +1531,13 @@ const union AffineAnimCmd gSleepLetterZAffineAnimCmds2_2[] = AFFINEANIMCMD_LOOP(10), }; -const union AffineAnimCmd *const gSleepLetterZAffineAnimTable[] = +const union AffineAnimCmd *const gSleepLetterZAffineAnimTable[] =//gUnknown_83E34F8 { gSleepLetterZAffineAnimCmds1, gSleepLetterZAffineAnimCmds2, }; -const struct SpriteTemplate gSleepLetterZSpriteTemplate = +const struct SpriteTemplate gSleepLetterZSpriteTemplate = //gUnknown_83E3500 { .tileTag = ANIM_TAG_LETTER_Z, .paletteTag = ANIM_TAG_LETTER_Z, @@ -1518,7 +1548,7 @@ const struct SpriteTemplate gSleepLetterZSpriteTemplate = .callback = AnimSleepLetterZ, }; -const struct SpriteTemplate gLockOnTargetSpriteTemplate = +const struct SpriteTemplate gLockOnTargetSpriteTemplate = //gUnknown_83E3518 { .tileTag = ANIM_TAG_LOCK_ON, .paletteTag = ANIM_TAG_LOCK_ON, @@ -1529,7 +1559,7 @@ const struct SpriteTemplate gLockOnTargetSpriteTemplate = .callback = AnimLockOnTarget, }; -const struct SpriteTemplate gLockOnMoveTargetSpriteTemplate = +const struct SpriteTemplate gLockOnMoveTargetSpriteTemplate = //gUnknown_83E3530 { .tileTag = ANIM_TAG_LOCK_ON, .paletteTag = ANIM_TAG_LOCK_ON, @@ -1548,7 +1578,7 @@ const s8 gInclineMonCoordTable[][2] = { 32, -32}, }; -const struct SpriteTemplate gBowMonSpriteTemplate = +const struct SpriteTemplate gBowMonSpriteTemplate = //gUnknown_83E3550 { .tileTag = 0, .paletteTag = 0, @@ -1559,8 +1589,7 @@ const struct SpriteTemplate gBowMonSpriteTemplate = .callback = AnimBowMon, }; -// Unused -const struct SpriteTemplate gUnknown_08592CF0 = +const struct SpriteTemplate gUnknown_83E3568 = // Unused { .tileTag = 0, .paletteTag = 0, @@ -1571,7 +1600,7 @@ const struct SpriteTemplate gUnknown_08592CF0 = .callback = sub_80A5590, }; -const union AnimCmd gSlashSliceAnimCmds1[] = +const union AnimCmd gSlashSliceAnimCmds1[] = //gUnknown_83E3580 { ANIMCMD_FRAME(0, 4), ANIMCMD_FRAME(16, 4), @@ -1592,7 +1621,7 @@ const union AnimCmd *const gSlashSliceAnimTable[] = gSlashSliceAnimCmds2, }; -const struct SpriteTemplate gSlashSliceSpriteTemplate = +const struct SpriteTemplate gSlashSliceSpriteTemplate = //gUnknown_83E35A4 { .tileTag = ANIM_TAG_SLASH, .paletteTag = ANIM_TAG_SLASH, @@ -1603,7 +1632,7 @@ const struct SpriteTemplate gSlashSliceSpriteTemplate = .callback = AnimSlashSlice, }; -const struct SpriteTemplate gFalseSwipeSliceSpriteTemplate = +const struct SpriteTemplate gFalseSwipeSliceSpriteTemplate = //gUnknown_83E35BC { .tileTag = ANIM_TAG_SLASH_2, .paletteTag = ANIM_TAG_SLASH_2, @@ -1614,7 +1643,7 @@ const struct SpriteTemplate gFalseSwipeSliceSpriteTemplate = .callback = AnimFalseSwipeSlice, }; -const struct SpriteTemplate gFalseSwipePositionedSliceSpriteTemplate = +const struct SpriteTemplate gFalseSwipePositionedSliceSpriteTemplate = //gUnknown_83E35D4 { .tileTag = ANIM_TAG_SLASH_2, .paletteTag = ANIM_TAG_SLASH_2, @@ -1639,7 +1668,7 @@ const union AnimCmd *const gEndureEnergyAnimTable[] = gEndureEnergyAnimCmds, }; -const struct SpriteTemplate gEndureEnergySpriteTemplate = +const struct SpriteTemplate gEndureEnergySpriteTemplate = //gUnknown_83E3604 { .tileTag = ANIM_TAG_FOCUS_ENERGY, .paletteTag = ANIM_TAG_FOCUS_ENERGY, @@ -1674,7 +1703,7 @@ const union AnimCmd *const gSharpenSphereAnimTable[] = gSharpenSphereAnimCmds, }; -const struct SpriteTemplate gSharpenSphereSpriteTemplate = +const struct SpriteTemplate gSharpenSphereSpriteTemplate = //gUnknown_83E365C { .tileTag = ANIM_TAG_SPHERE_TO_CUBE, .paletteTag = ANIM_TAG_SPHERE_TO_CUBE, @@ -1685,7 +1714,7 @@ const struct SpriteTemplate gSharpenSphereSpriteTemplate = .callback = AnimSharpenSphere, }; -const struct SpriteTemplate gOctazookaBallSpriteTemplate = +const struct SpriteTemplate gOctazookaBallSpriteTemplate = //gUnknown_83E3674 { .tileTag = ANIM_TAG_BLACK_BALL, .paletteTag = ANIM_TAG_BLACK_BALL, @@ -1711,7 +1740,7 @@ const union AnimCmd *const gOctazookaAnimTable[] = gOctazookaAnimCmds, }; -const struct SpriteTemplate gOctazookaSmokeSpriteTemplate = +const struct SpriteTemplate gOctazookaSmokeSpriteTemplate = //gUnknown_83E36A8 { .tileTag = ANIM_TAG_GRAY_SMOKE, .paletteTag = ANIM_TAG_GRAY_SMOKE, @@ -1747,7 +1776,7 @@ const union AffineAnimCmd *const gConversionAffineAnimTable[] = gConversionAffineAnimCmds, }; -const struct SpriteTemplate gConversionSpriteTemplate = +const struct SpriteTemplate gConversionSpriteTemplate = //gUnknown_83E36EC { .tileTag = ANIM_TAG_CONVERSION, .paletteTag = ANIM_TAG_CONVERSION, @@ -1772,7 +1801,7 @@ const union AnimCmd *const gConversion2AnimTable[] = gConversion2AnimCmds, }; -const struct SpriteTemplate gConversion2SpriteTemplate = +const struct SpriteTemplate gConversion2SpriteTemplate = //gUnknown_83E371C { .tileTag = ANIM_TAG_CONVERSION, .paletteTag = ANIM_TAG_CONVERSION, @@ -1783,7 +1812,7 @@ const struct SpriteTemplate gConversion2SpriteTemplate = .callback = AnimConversion2, }; -const struct SpriteTemplate gMoonSpriteTemplate = +const struct SpriteTemplate gMoonSpriteTemplate = //gUnknown_83E3734 { .tileTag = ANIM_TAG_MOON, .paletteTag = ANIM_TAG_MOON, @@ -1808,7 +1837,7 @@ const union AnimCmd *const gMoonlightSparkleAnimTable[] = gMoonlightSparkleAnimCmds, }; -const struct SpriteTemplate gMoonlightSparkleSpriteTemplate = +const struct SpriteTemplate gMoonlightSparkleSpriteTemplate = //gUnknown_83E3764 { .tileTag = ANIM_TAG_GREEN_SPARKLE, .paletteTag = ANIM_TAG_GREEN_SPARKLE, @@ -1837,7 +1866,7 @@ const union AnimCmd *const gHealingBlueStarAnimTable[] = gHealingBlueStarAnimCmds, }; -const struct SpriteTemplate gHealingBlueStarSpriteTemplate = +const struct SpriteTemplate gHealingBlueStarSpriteTemplate = //gUnknown_83E37A4 { .tileTag = ANIM_TAG_BLUE_STAR, .paletteTag = ANIM_TAG_BLUE_STAR, @@ -1848,7 +1877,7 @@ const struct SpriteTemplate gHealingBlueStarSpriteTemplate = .callback = AnimSpriteOnMonPos, }; -const struct SpriteTemplate gHornHitSpriteTemplate = +const struct SpriteTemplate gHornHitSpriteTemplate = //gUnknown_83E37BC { .tileTag = ANIM_TAG_HORN_HIT, .paletteTag = ANIM_TAG_HORN_HIT, @@ -1873,7 +1902,7 @@ const union AnimCmd *const gSuperFangAnimTable[] = gSuperFangAnimCmds, }; -const struct SpriteTemplate gSuperFangSpriteTemplate = +const struct SpriteTemplate gSuperFangSpriteTemplate = //gUnknown_83E37EC { .tileTag = ANIM_TAG_FANG_ATTACK, .paletteTag = ANIM_TAG_FANG_ATTACK, @@ -1932,7 +1961,7 @@ const union AnimCmd gWavyMusicNotesAnimCmds8[] = ANIMCMD_END, }; -const union AnimCmd *const gMusicNotesAnimTable[] = +const union AnimCmd *const gMusicNotesAnimTable[] = //gUnknown_83E3844 { gWavyMusicNotesAnimCmds1, gWavyMusicNotesAnimCmds2, @@ -1944,19 +1973,19 @@ const union AnimCmd *const gMusicNotesAnimTable[] = gWavyMusicNotesAnimCmds8, }; -const union AffineAnimCmd gWavyMusicNotesAffineAnimCmds[] = +const union AffineAnimCmd gWavyMusicNotesAffineAnimCmds[] = //gUnknown_83E3864 { AFFINEANIMCMD_FRAME(0xC, 0xC, 0, 16), AFFINEANIMCMD_FRAME(0xFFF4, 0xFFF4, 0, 16), AFFINEANIMCMD_JUMP(0), }; -const union AffineAnimCmd *const gMusicNotesAffineAnimTable[] = +const union AffineAnimCmd *const gMusicNotesAffineAnimTable[] = //gUnknown_83E387C { gWavyMusicNotesAffineAnimCmds, }; -const struct SpriteTemplate gWavyMusicNotesSpriteTemplate = +const struct SpriteTemplate gWavyMusicNotesSpriteTemplate = //gUnknown_83E3880 { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, @@ -1967,7 +1996,7 @@ const struct SpriteTemplate gWavyMusicNotesSpriteTemplate = .callback = AnimWavyMusicNotes, }; -const u16 gParticlesColorBlendTable[][6] = +const u16 gParticlesColorBlendTable[][6] = //gUnknown_83E3898 { {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)}, @@ -1975,7 +2004,7 @@ const u16 gParticlesColorBlendTable[][6] = {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 = +const struct SpriteTemplate gFastFlyingMusicNotesSpriteTemplate = //gUnknown_83E38C8 { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, @@ -1986,7 +2015,7 @@ const struct SpriteTemplate gFastFlyingMusicNotesSpriteTemplate = .callback = AnimFlyingMusicNotes, }; -const struct SpriteTemplate gBellyDrumHandSpriteTemplate = +const struct SpriteTemplate gBellyDrumHandSpriteTemplate = // gUnknown_83E38E0 { .tileTag = ANIM_TAG_PURPLE_HAND_OUTLINE, .paletteTag = ANIM_TAG_PURPLE_HAND_OUTLINE, @@ -2009,7 +2038,7 @@ const union AffineAnimCmd *const gSlowFlyingMusicNotesAffineAnimTable[] = gSlowFlyingMusicNotesAffineAnimCmds, }; -const struct SpriteTemplate gSlowFlyingMusicNotesSpriteTemplate = +const struct SpriteTemplate gSlowFlyingMusicNotesSpriteTemplate = //gUnknown_83E3914 { .tileTag = ANIM_TAG_MUSIC_NOTES, .paletteTag = ANIM_TAG_MUSIC_NOTES, @@ -2064,7 +2093,7 @@ const union AnimCmd *const gMetronomeThroughtBubbleAnimTable[] = gMetronomeThroughtBubbleAnimCmds4, }; -const struct SpriteTemplate gThoughtBubbleSpriteTemplate = +const struct SpriteTemplate gThoughtBubbleSpriteTemplate = //gUnknown_83E398C { .tileTag = ANIM_TAG_THOUGHT_BUBBLE, .paletteTag = ANIM_TAG_THOUGHT_BUBBLE, @@ -2110,7 +2139,7 @@ const union AffineAnimCmd *const gMetronomeFingerAffineAnimTable[] = gMetronomeFingerAffineAnimCmds2, }; -const struct SpriteTemplate gMetronomeFingerSpriteTemplate = +const struct SpriteTemplate gMetronomeFingerSpriteTemplate = //gUnknown_83E3A34 { .tileTag = ANIM_TAG_FINGER, .paletteTag = ANIM_TAG_FINGER, @@ -2121,7 +2150,7 @@ const struct SpriteTemplate gMetronomeFingerSpriteTemplate = .callback = AnimMetronomeFinger, }; -const struct SpriteTemplate gFollowMeFingerSpriteTemplate = +const struct SpriteTemplate gFollowMeFingerSpriteTemplate = //gUnknown_83E3A4C { .tileTag = ANIM_TAG_FINGER, .paletteTag = ANIM_TAG_FINGER, @@ -2176,7 +2205,7 @@ const union AnimCmd *const gTauntFingerAnimTable[] = gTauntFingerAnimCmds4, }; -const struct SpriteTemplate gTauntFingerSpriteTemplate = +const struct SpriteTemplate gTauntFingerSpriteTemplate = //gUnknown_83E3AC4 { .tileTag = ANIM_TAG_FINGER_2, .paletteTag = ANIM_TAG_FINGER_2, @@ -2797,7 +2826,8 @@ static void AnimConstrictBindingStep2(struct Sprite* sprite) } } -void sub_80FF458(u8 taskId) +// Unused +void sub_80A2F0C(u8 taskId) { u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); if (gSprites[spriteId].invisible) @@ -2927,6 +2957,7 @@ void AnimIngrainRoot(struct Sprite* sprite) // arg 3: sprite subpriority offset // arg 4: sprite anum num // arg 5: duration +//sub_80A31EC void AnimFrenzyPlantRoot(struct Sprite *sprite) { s16 attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); @@ -2944,10 +2975,10 @@ void AnimFrenzyPlantRoot(struct Sprite *sprite) 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; + gUnknown_203999C[0] = sprite->pos1.x; + gUnknown_203999C[1] = sprite->pos1.y; + gUnknown_203999C[2] = targetX; + gUnknown_203999C[3] = targetY; } static void AnimRootFlickerOut(struct Sprite* sprite) @@ -2983,7 +3014,7 @@ void AnimIngrainOrb(struct Sprite* sprite) DestroyAnimSprite(sprite); } -static void sub_80FF9B8(struct Sprite* sprite, s16 c) +static void sub_80A33B8(struct Sprite* sprite, s16 c) { int a = (sprite->pos1.x << 8) | sprite->pos1.y; int b = (sprite->data[6] << 8) | sprite->data[7]; @@ -2993,7 +3024,7 @@ static void sub_80FF9B8(struct Sprite* sprite, s16 c) sprite->data[7] = c; } -bool8 moveAlongLinearPath(struct Sprite* sprite) +bool8 MoveAlongLinearPath(struct Sprite* sprite) { u16 xStartPos = (u8)(sprite->data[5] >> 8); u16 yStartPos = (u8)sprite->data[5]; @@ -3044,7 +3075,7 @@ static void AnimItemStealStep1(struct Sprite* sprite) } sprite->pos2.y = Sin(sprite->data[0] + 128, 30 - sprite->data[1] * 8); - if (moveAlongLinearPath(sprite)) + if (MoveAlongLinearPath(sprite)) { sprite->pos2.y = 0; sprite->data[0] = 0; @@ -3063,14 +3094,14 @@ void AnimPresent(struct Sprite* sprite) { sprite->data[6] = targetX; sprite->data[7] = targetY + 10; - sub_80FF9B8(sprite, 60); + sub_80A33B8(sprite, 60); sprite->data[3] = 1; } else { sprite->data[6] = targetX; sprite->data[7] = targetY + 10; - sub_80FF9B8(sprite, 60); + sub_80A33B8(sprite, 60); sprite->data[3] = 3; } @@ -3078,7 +3109,7 @@ void AnimPresent(struct Sprite* sprite) sprite->callback = AnimItemStealStep1; } -static void sub_80FFB90(struct Sprite* sprite) +static void sub_80A3590(struct Sprite* sprite) { int zero; sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]); @@ -3090,7 +3121,7 @@ static void sub_80FFB90(struct Sprite* sprite) } sprite->pos2.y = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8); - if (moveAlongLinearPath(sprite)) + if (MoveAlongLinearPath(sprite)) { sprite->pos2.y = zero; sprite->data[0] = zero; @@ -3105,7 +3136,7 @@ void AnimKnockOffItem(struct Sprite* sprite) { sprite->data[6] = 0; sprite->data[7] = targetY + 10; - sub_80FF9B8(sprite, 40); + sub_80A33B8(sprite, 40); sprite->data[3] = 3; sprite->data[4] = 60; sprite->callback = AnimItemStealStep1; @@ -3117,10 +3148,10 @@ void AnimKnockOffItem(struct Sprite* sprite) if (IsContest()) sprite->data[6] = 0; - sub_80FF9B8(sprite, 40); + sub_80A33B8(sprite, 40); sprite->data[3] = 3; sprite->data[4] = 60; - sprite->callback = sub_80FFB90; + sprite->callback = sub_80A3590; } } @@ -3154,14 +3185,14 @@ void AnimItemSteal(struct Sprite* sprite) { sprite->data[6] = attackerX; sprite->data[7] = attackerY + 10; - sub_80FF9B8(sprite, 60); + sub_80A33B8(sprite, 60); sprite->data[3] = 1; } else { sprite->data[6] = attackerX; sprite->data[7] = attackerY + 10; - sub_80FF9B8(sprite, 60); + sub_80A33B8(sprite, 60); sprite->data[3] = 3; } @@ -3184,7 +3215,7 @@ static void AnimItemStealStep3(struct Sprite* sprite) if (sprite->pos2.y == 0) PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(63)); - if (moveAlongLinearPath(sprite)) + if (MoveAlongLinearPath(sprite)) { sprite->pos2.y = 0; sprite->data[0] = 0; diff --git a/src/battle_anim_effects_2.c b/src/battle_anim_effects_2.c new file mode 100644 index 000000000..32ed2fba9 --- /dev/null +++ b/src/battle_anim_effects_2.c @@ -0,0 +1,3818 @@ +#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" + +void sub_80A6E48(struct Sprite *); +void sub_80A6E98(struct Sprite *); +void sub_80A6F8C(struct Sprite *); +void sub_80A7020(struct Sprite *); +void Anim_KinesisZapEnergy(struct Sprite *); +void Anim_SwordsDanceBlade(struct Sprite *); +void AnimSonicBoomProjectile(struct Sprite *); +void AnimAirWaveProjectile(struct Sprite *); +void sub_80A79E8(struct Sprite *); +void AnimCoinThrow(struct Sprite *); +void AnimFallingCoin(struct Sprite *); +void AnimBulletSeed(struct Sprite *); +void AnimRazorWindTornado(struct Sprite *); +void AnimViceGripPincer(struct Sprite *); +void AnimGuillotinePincer(struct Sprite *); +void AnimBreathPuff(struct Sprite *); +void AnimAngerMark(struct Sprite *); +void AnimPencil(struct Sprite *); +void AnimBlendThinRing(struct Sprite *); +void AnimHyperVoiceRing(struct Sprite *); +void AnimUproarRing(struct Sprite *); +void AnimSoftBoiledEgg(struct Sprite *); +void AnimSpeedDust(struct Sprite *); +void AnimHealBellMusicNote(struct Sprite *); +void AnimMagentaHeart(struct Sprite *); +void AnimRedHeartProjectile(struct Sprite *); +void AnimParticuleBurst(struct Sprite *); +void AnimRedHeartRising(struct Sprite *); +void AnimOrbitFast(struct Sprite *); +void AnimOrbitScatter(struct Sprite *); +void AnimSpitUpOrb(struct Sprite *); +void AnimEyeSparkle(struct Sprite *); +void AnimAngel(struct Sprite *); +void AnimPinkHeart(struct Sprite *); +void AnimDevil(struct Sprite *); +void AnimFurySwipes(struct Sprite *); +void AnimMovmentWaves(struct Sprite *); +void AnimJaggedMusicNote(struct Sprite *); +void AnimPerishSongMusicNote2(struct Sprite *); +void AnimPerishSongMusicNote(struct Sprite *); +void AnimGuardRing(struct Sprite *); +static void sub_80A6ED8(struct Sprite *); +static void sub_80A7058(struct Sprite *); +static void sub_80A7080(struct Sprite *); +static void AnimTask_WithdrawStep(u8); +static void AnimSwordsDanceBladeStep(struct Sprite *); +static void sub_80A7A18(struct Sprite *); +static void AnimFallingCoin_Step(struct Sprite *); +static void AnimBulletSeed_Step1(struct Sprite *); +static void AnimBulletSeed_Step2(struct Sprite *); +static void AnimViceGripPincerStep(struct Sprite *); +static void AnimGuillotinePincerStep1(struct Sprite *); +static void AnimGuillotinePincerStep2(struct Sprite *); +static void AnimGuillotinePincerStep3(struct Sprite *); +static void AnimTask_GrowAndGreyscaleStep(u8); +static void AnimTask_MinimizeStep1(u8); +static void CreateMinimizeSprite(struct Task *, u8); +static void ClonedMinizeSprite_Step(struct Sprite *); +static void AnimTask_SplashStep(u8); +static void AnimTask_GrowAndShrinkStep(u8); +static void ThrashMoveMonStep(u8); +static void ThrashMoveMon(u8); +static void AnimTask_SketchDrawMon(u8); +static void AnimPencil_Step(struct Sprite *); +static void AnimSoftBoiledEgg_Step1(struct Sprite *); +static void AnimSoftBoiledEgg_Step2(struct Sprite *); +static void AnimSoftBoiledEgg_Step3(struct Sprite *); +static void AnimSoftBoiledEgg_Step3_Callback1(struct Sprite *); +static void AnimSoftBoiledEgg_Step3_Callback2(struct Sprite *); +static void AnimSoftBoiledEgg_Step4(struct Sprite *); +static void AnimSoftBoiledEgg_Step4_Callback(struct Sprite *); +static void StretchAttacker_Step(u8); +static void ExtremeSpeedImpact_Step(u8); +static void ExtremeSpeedMonReappear_Step(u8); +static void SpeedDust_Step1(u8); +static void FakeOutStep1(u8); +static void FakeOutStep2(u8); +static void AnimRedHeartProjectile_Step(struct Sprite *); +static void AnimRedHeartRising_Step(struct Sprite *); +static void HeartsBackground_Step(u8); +static void ScaryFace_Step(u8); +static void AnimOrbitFastStep(struct Sprite *); +static void AnimOrbitScatterStep(struct Sprite *); +static void AnimMovmentWaves_Step(struct Sprite *); +static void UproarDistortion_Step(u8); +static void AnimJaggedMusicNote_Step(struct Sprite *); +static void AnimPerishSongMusicNote_Step1(struct Sprite *); +static void AnimPerishSongMusicNote_Step2(struct Sprite *); + +// Data +const struct SpriteTemplate gUnknown_83E3ADC = // Unused +{ + .tileTag = ANIM_TAG_FINGER, + .paletteTag = ANIM_TAG_FINGER, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80A6E48, +}; + +const union AnimCmd gUnknown_83E3AF4[] = +{ + ANIMCMD_FRAME(4, 1), + ANIMCMD_END, +}; + +const union AnimCmd *const gUnknown_83E3AFC[] = +{ + gUnknown_83E3AF4, +}; + +const struct SpriteTemplate gUnknown_83E3B00 = // Unused +{ + .tileTag = ANIM_TAG_MUSIC_NOTES, + .paletteTag = ANIM_TAG_MUSIC_NOTES, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80A6E98, +}; + +const struct SpriteTemplate gUnknown_83E3B18 = // Unused +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80A6F8C, +}; + +extern const union AffineAnimCmd *const gUnknown_83E7910[]; +const struct SpriteTemplate gUnknown_83E3B30 = // Unused +{ + .tileTag = ANIM_TAG_CLAMP, + .paletteTag = ANIM_TAG_CLAMP, + .oam = &gOamData_AffineNormal_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gUnknown_83E7910, + .callback = sub_80A7020, +}; + +const union AnimCmd gUnknown_83E3B48[] = +{ + ANIMCMD_FRAME(0, 9), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_END, +}; + +const union AnimCmd *const gUnknown_83E3B5C[] = +{ + gUnknown_83E3B48, +}; + +const union AffineAnimCmd gUnknown_83E3B60[] = +{ + AFFINEANIMCMD_FRAME(0x50, 0x50, 0, 0), + AFFINEANIMCMD_FRAME(0x9, 0x9, 0, 18), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gUnknown_83E3B78[] = +{ + gUnknown_83E3B60, +}; + +const struct SpriteTemplate gUnknown_83E3B7C = // Unused +{ + .tileTag = ANIM_TAG_EXPLOSION_6, + .paletteTag = ANIM_TAG_EXPLOSION_6, + .oam = &gOamData_AffineNormal_ObjNormal_32x32, + .anims = gUnknown_83E3B5C, + .images = NULL, + .affineAnims = gUnknown_83E3B78, + .callback = AnimSpriteOnMonPos, +}; + +const union AnimCmd gKinesisZapEnergyAnimCmds[] = +{ + ANIMCMD_FRAME(0, 3, .hFlip = TRUE), + ANIMCMD_FRAME(8, 3, .hFlip = TRUE), + ANIMCMD_FRAME(16, 3, .hFlip = TRUE), + ANIMCMD_FRAME(24, 3, .hFlip = TRUE), + ANIMCMD_FRAME(32, 3, .hFlip = TRUE), + ANIMCMD_FRAME(40, 3, .hFlip = TRUE), + ANIMCMD_FRAME(48, 3, .hFlip = TRUE), + ANIMCMD_LOOP(1), + ANIMCMD_END, +}; + +const union AnimCmd *const gKinesisZapEnergyAnimTable[] = +{ + gKinesisZapEnergyAnimCmds, +}; + +const struct SpriteTemplate gKinesisZapEnergySpriteTemplate = //gUnknown_83E3BBC +{ + .tileTag = ANIM_TAG_ALERT, + .paletteTag = ANIM_TAG_ALERT, + .oam = &gOamData_AffineOff_ObjNormal_32x16, + .anims = gKinesisZapEnergyAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = Anim_KinesisZapEnergy, +}; + +const union AffineAnimCmd gSwordsDanceBladeAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x14, 0x0, 0, 12), + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 32), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSwordsDanceBladeAffineAnimTable[] = +{ + gSwordsDanceBladeAffineAnimCmds, +}; + +const struct SpriteTemplate gSwordsDanceBladeSpriteTemplate = //gUnknown_83E3BF8 +{ + .tileTag = ANIM_TAG_SWORD, + .paletteTag = ANIM_TAG_SWORD, + .oam = &gOamData_AffineNormal_ObjBlend_32x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSwordsDanceBladeAffineAnimTable, + .callback = Anim_SwordsDanceBlade, +}; + +const struct SpriteTemplate gSonicBoomSpriteTemplate = //gUnknown_83E3C10 +{ + .tileTag = ANIM_TAG_AIR_WAVE, + .paletteTag = ANIM_TAG_AIR_WAVE, + .oam = &gOamData_AffineDouble_ObjBlend_32x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSonicBoomProjectile, +}; + +const struct SpriteTemplate gAirWaveProjectileSpriteTemplate = //gUnknown_83E3C28 +{ + .tileTag = ANIM_TAG_AIR_WAVE, + .paletteTag = ANIM_TAG_AIR_WAVE, + .oam = &gOamData_AffineOff_ObjBlend_32x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimAirWaveProjectile, +}; + +const union AffineAnimCmd gGrowingRingAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0), + AFFINEANIMCMD_FRAME(0x7, 0x7, 0, -56), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gWaterPulseRingAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 10), + AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 10), + AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10), + AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 10), + AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10), + AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 10), + AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gGrowingRingAffineAnimTable[] = +{ + gGrowingRingAffineAnimCmds, +}; + +const union AffineAnimCmd *const gWaterPulseRingAffineAnimTable[] = +{ + gWaterPulseRingAffineAnimCmds, +}; + +const struct SpriteTemplate gSupersonicWaveSpriteTemplate = //gUnknown_83E3CA0 +{ + .tileTag = ANIM_TAG_GOLD_RING, + .paletteTag = ANIM_TAG_GOLD_RING, + .oam = &gOamData_AffineDouble_ObjNormal_16x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gGrowingRingAffineAnimTable, + .callback = TranslateAnimSpriteToTargetMonLocation, +}; + +const struct SpriteTemplate gScreechWaveSpriteTemplate = //gUnknown_83E3CB8 +{ + .tileTag = ANIM_TAG_PURPLE_RING, + .paletteTag = ANIM_TAG_PURPLE_RING, + .oam = &gOamData_AffineDouble_ObjNormal_16x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gGrowingRingAffineAnimTable, + .callback = TranslateAnimSpriteToTargetMonLocation, +}; + +const struct SpriteTemplate gMetalSoundSpriteTemplate = //gUnknown_83E3CD0 +{ + .tileTag = ANIM_TAG_METAL_SOUND_WAVES, + .paletteTag = ANIM_TAG_METAL_SOUND_WAVES, + .oam = &gOamData_AffineDouble_ObjNormal_32x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gGrowingRingAffineAnimTable, + .callback = TranslateAnimSpriteToTargetMonLocation, +}; + +const struct SpriteTemplate gWaterPulseRingSpriteTemplate = //gUnknown_83E3CE8 +{ + .tileTag = ANIM_TAG_BLUE_RING_2, + .paletteTag = ANIM_TAG_BLUE_RING_2, + .oam = &gOamData_AffineDouble_ObjNormal_16x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gWaterPulseRingAffineAnimTable, + .callback = AnimWaterPulseRing, +}; + +const struct SpriteTemplate gEggThrowSpriteTemplate = //gUnknown_83E3D00 +{ + .tileTag = ANIM_TAG_LARGE_FRESH_EGG, + .paletteTag = ANIM_TAG_LARGE_FRESH_EGG, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimThrowProjectile, +}; + +const struct SpriteTemplate gUnknown_83E3D18 = +{ + .tileTag = ANIM_TAG_VOID_LINES, + .paletteTag = ANIM_TAG_VOID_LINES, + .oam = &gOamData_AffineOff_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80A79E8, +}; + +const union AnimCmd gCoinAnimCmds[] = +{ + ANIMCMD_FRAME(8, 1), + ANIMCMD_END, +}; + +const union AnimCmd *const gCoinAnimTable[] = +{ + gCoinAnimCmds, +}; + +const union AffineAnimCmd gFallingCoinAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gFallingCoinAffineAnimTable[] = +{ + gFallingCoinAffineAnimCmds, +}; + +const struct SpriteTemplate gCoinThrowSpriteTemplate = //gUnknown_83E3D50 +{ + .tileTag = ANIM_TAG_COIN, + .paletteTag = ANIM_TAG_COIN, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gCoinAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimCoinThrow, +}; + +const struct SpriteTemplate gFallingCoinSpriteTemplate = //gUnknown_83E3D68 +{ + .tileTag = ANIM_TAG_COIN, + .paletteTag = ANIM_TAG_COIN, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gCoinAnimTable, + .images = NULL, + .affineAnims = gFallingCoinAffineAnimTable, + .callback = AnimFallingCoin, +}; + +const union AffineAnimCmd gBulletSeedAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 1), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gBulletSeedAffineAnimTable[] = +{ + gBulletSeedAffineAnimCmds, +}; + +const struct SpriteTemplate gBulletSeedSpriteTemplate = //gUnknown_83E3D94 +{ + .tileTag = ANIM_TAG_SEED, + .paletteTag = ANIM_TAG_SEED, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gBulletSeedAffineAnimTable, + .callback = AnimBulletSeed, +}; + +const union AffineAnimCmd gRazorWindTornadoAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x4, 0x0, 0, 40), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gRazorWindTornadoAffineAnimTable[] = +{ + gRazorWindTornadoAffineAnimCmds, +}; + +const struct SpriteTemplate gRazorWindTornadoSpriteTemplate = //gUnknown_83E3DC8 +{ + .tileTag = ANIM_TAG_GUST, + .paletteTag = ANIM_TAG_GUST, + .oam = &gOamData_AffineNormal_ObjNormal_32x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gRazorWindTornadoAffineAnimTable, + .callback = AnimRazorWindTornado, +}; + +const union AnimCmd gViceGripAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 20), + ANIMCMD_END, +}; + +const union AnimCmd gViceGripAnimCmds2[] = +{ + ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(16, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(32, 20, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_END, +}; + +const union AnimCmd *const gViceGripAnimTable[] = +{ + gViceGripAnimCmds1, + gViceGripAnimCmds2, +}; + +const struct SpriteTemplate gViceGripSpriteTemplate = //gUnknown_83E3E08 +{ + .tileTag = ANIM_TAG_CUT, + .paletteTag = ANIM_TAG_CUT, + .oam = &gOamData_AffineOff_ObjBlend_32x32, + .anims = gViceGripAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimViceGripPincer, +}; + +const union AnimCmd gGuillotineAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 2), + ANIMCMD_FRAME(16, 2), + ANIMCMD_FRAME(32, 1), + ANIMCMD_END, +}; + +const union AnimCmd gGuillotineAnimCmds2[] = +{ + ANIMCMD_FRAME(0, 2, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(16, 2, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(32, 1, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_END, +}; + +const union AnimCmd *const gGuillotineAnimTable[] = +{ + gGuillotineAnimCmds1, + gGuillotineAnimCmds2, +}; + +const struct SpriteTemplate gGuillotineSpriteTemplate = //gUnknown_83E3E48 +{ + .tileTag = ANIM_TAG_CUT, + .paletteTag = ANIM_TAG_CUT, + .oam = &gOamData_AffineOff_ObjBlend_32x32, + .anims = gGuillotineAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimGuillotinePincer, +}; + +const union AffineAnimCmd gSplashEffectAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(-6, 4, 0, 8), + AFFINEANIMCMD_FRAME(10, -10, 0, 8), + AFFINEANIMCMD_FRAME(-4, 6, 0, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gGrowAndShrinkAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(-4, -5, 0, 12), + AFFINEANIMCMD_FRAME(0, 0, 0, 24), + AFFINEANIMCMD_FRAME(4, 5, 0, 12), + AFFINEANIMCMD_END, +}; + +const union AnimCmd gBreathPuffAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 4, .hFlip = TRUE), + ANIMCMD_FRAME(4, 40, .hFlip = TRUE), + ANIMCMD_FRAME(8, 4, .hFlip = TRUE), + ANIMCMD_FRAME(12, 4, .hFlip = TRUE), + ANIMCMD_END, +}; + +const union AnimCmd gBreathPuffAnimCmds2[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(4, 40), + ANIMCMD_FRAME(8, 4), + ANIMCMD_FRAME(12, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gBreathPuffAnimTable[] = +{ + gBreathPuffAnimCmds1, + gBreathPuffAnimCmds2, +}; + +const struct SpriteTemplate gBreathPuffSpriteTemplate = //gUnknown_83E3ED0 +{ + .tileTag = ANIM_TAG_BREATH, + .paletteTag = ANIM_TAG_BREATH, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gBreathPuffAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimBreathPuff, +}; + +const union AffineAnimCmd gAngerMarkAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0xB, 0xB, 0, 8), + AFFINEANIMCMD_FRAME(0xFFF5, 0xFFF5, 0, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gAngerMarkAffineAnimTable[] = +{ + gAngerMarkAffineAnimCmds, +}; + +const struct SpriteTemplate gAngerMarkSpriteTemplate = //gUnknown_83E3F04 +{ + .tileTag = ANIM_TAG_ANGER, + .paletteTag = ANIM_TAG_ANGER, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gAngerMarkAffineAnimTable, + .callback = AnimAngerMark, +}; + +const union AffineAnimCmd gThrashMoveMonAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(-10, 9, 0, 7), + AFFINEANIMCMD_FRAME(20, -20, 0, 7), + AFFINEANIMCMD_FRAME(-20, 20, 0, 7), + AFFINEANIMCMD_FRAME(10, -9, 0, 7), + AFFINEANIMCMD_LOOP(2), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gPencilSpriteTemplate = //gUnknown_83E3F4C +{ + .tileTag = ANIM_TAG_PENCIL, + .paletteTag = ANIM_TAG_PENCIL, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimPencil, +}; + +const struct SpriteTemplate gSnoreZSpriteTemplate = //gUnknown_83E3F64 +{ + .tileTag = ANIM_TAG_SNORE_Z, + .paletteTag = ANIM_TAG_SNORE_Z, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSnoreZ, +}; + +const union AnimCmd gExplosionAnimCmds[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(16, 5), + ANIMCMD_FRAME(32, 5), + ANIMCMD_FRAME(48, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gExplosionAnimTable[] = +{ + gExplosionAnimCmds, +}; + +const struct SpriteTemplate gExplosionSpriteTemplate = //gUnknown_83E3F94 +{ + .tileTag = ANIM_TAG_EXPLOSION, + .paletteTag = ANIM_TAG_EXPLOSION, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gExplosionAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const union AffineAnimCmd gSoftBoiledEggAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 2), + AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 4), + AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 2), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSoftBoiledEggAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gSoftBoiledEggAffineAnimCmds3[] = +{ + AFFINEANIMCMD_FRAME(0xFFF8, 0x4, 0, 8), + AFFINEANIMCMD_LOOP(0), + AFFINEANIMCMD_FRAME(0x10, 0xFFF8, 0, 8), + AFFINEANIMCMD_FRAME(0xFFF0, 0x8, 0, 8), + AFFINEANIMCMD_LOOP(1), + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 15), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSoftBoiledEggAffineAnimTable[] = +{ + gSoftBoiledEggAffineAnimCmds1, + gSoftBoiledEggAffineAnimCmds2, + gSoftBoiledEggAffineAnimCmds3, +}; + +const struct SpriteTemplate gSoftBoiledEggSpriteTemplate = //gUnknown_83E4028 +{ + .tileTag = ANIM_TAG_BREAKING_EGG, + .paletteTag = ANIM_TAG_BREAKING_EGG, + .oam = &gOamData_AffineDouble_ObjBlend_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSoftBoiledEggAffineAnimTable, + .callback = AnimSoftBoiledEgg, +}; + +const union AffineAnimCmd gThinRingExpandingAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0), + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 30), + AFFINEANIMCMD_END_ALT(1), +}; + +const union AffineAnimCmd gThinRingExpandingAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0), + AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 15), + AFFINEANIMCMD_END_ALT(1), +}; + +const union AffineAnimCmd gHyperVoiceRingAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0), + AFFINEANIMCMD_FRAME(0xB, 0xB, 0, 45), + AFFINEANIMCMD_END_ALT(1), +}; + +const union AffineAnimCmd *const gThinRingExpandingAffineAnimTable[] = +{ + gThinRingExpandingAffineAnimCmds1, + gThinRingExpandingAffineAnimCmds2, +}; + +const union AffineAnimCmd *const gHyperVoiceRingAffineAnimTable[] = +{ + gHyperVoiceRingAffineAnimCmds, +}; + +const struct SpriteTemplate gThinRingExpandingSpriteTemplate = //gUnknown_83E4094 +{ + .tileTag = ANIM_TAG_THIN_RING, + .paletteTag = ANIM_TAG_THIN_RING, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gThinRingExpandingAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const union AffineAnimCmd gThinRingShrinkingAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), + AFFINEANIMCMD_FRAME(0xFFF0, 0xFFF0, 0, 30), + AFFINEANIMCMD_END_ALT(1), +}; + +const union AffineAnimCmd *const gThinRingShrinkingAffineAnimTable[] = +{ + gThinRingShrinkingAffineAnimCmds, +}; + +const struct SpriteTemplate gThinRingShrinkingSpriteTemplate = //gUnknown_83E40C8 +{ + .tileTag = ANIM_TAG_THIN_RING, + .paletteTag = ANIM_TAG_THIN_RING, + .oam = &gOamData_AffineDouble_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gThinRingShrinkingAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const struct SpriteTemplate gBlendThinRingExpandingSpriteTemplate = //gUnknown_83E40E0 +{ + .tileTag = ANIM_TAG_THIN_RING, + .paletteTag = ANIM_TAG_THIN_RING, + .oam = &gOamData_AffineDouble_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gThinRingExpandingAffineAnimTable, + .callback = AnimBlendThinRing, +}; + +const struct SpriteTemplate gHyperVoiceRingSpriteTemplate = //gUnknown_83E40F8 +{ + .tileTag = ANIM_TAG_THIN_RING, + .paletteTag = ANIM_TAG_THIN_RING, + .oam = &gOamData_AffineDouble_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gHyperVoiceRingAffineAnimTable, + .callback = AnimHyperVoiceRing, +}; + +const struct SpriteTemplate gUproarRingSpriteTemplate = //gUnknown_83E4110 +{ + .tileTag = ANIM_TAG_THIN_RING, + .paletteTag = ANIM_TAG_THIN_RING, + .oam = &gOamData_AffineDouble_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gThinRingExpandingAffineAnimTable, + .callback = AnimUproarRing, +}; + +const union AffineAnimCmd gStretchAttackerAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(96, -13, 0, 8), + AFFINEANIMCMD_END, +}; + +const union AnimCmd gSpeedDustAnimCmds[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(4, 3), + ANIMCMD_FRAME(8, 3), + ANIMCMD_FRAME(4, 3), + ANIMCMD_FRAME(0, 3), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpeedDustAnimTable[] = +{ + gSpeedDustAnimCmds, +}; + +const struct SpriteTemplate gSpeedDustSpriteTemplate = //gUnknown_83E4154 +{ + .tileTag = ANIM_TAG_SPEED_DUST, + .paletteTag = ANIM_TAG_SPEED_DUST, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gSpeedDustAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpeedDust, +}; + +const s8 gSpeedDustPosTable[][2] = +{ + {30, 28}, + {-20, 24}, + {16, 26}, + {-10, 28}, +}; + +const union AnimCmd gBellAnimCmds[] = +{ + ANIMCMD_FRAME(0, 6), + ANIMCMD_FRAME(16, 6), + ANIMCMD_FRAME(32, 15), + ANIMCMD_FRAME(16, 6), + ANIMCMD_FRAME(0, 6), + ANIMCMD_FRAME(16, 6, .hFlip = TRUE), + ANIMCMD_FRAME(32, 15, .hFlip = TRUE), + ANIMCMD_FRAME(16, 6, .hFlip = TRUE), + ANIMCMD_FRAME(0, 6), + ANIMCMD_FRAME(16, 6), + ANIMCMD_FRAME(32, 15), + ANIMCMD_FRAME(16, 6), + ANIMCMD_FRAME(0, 6), + ANIMCMD_END, +}; + +const union AnimCmd *const gBellAnimTable[] = +{ + gBellAnimCmds, +}; + +const struct SpriteTemplate gBellSpriteTemplate = //gUnknown_83E41B0 +{ + .tileTag = ANIM_TAG_BELL, + .paletteTag = ANIM_TAG_BELL, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gBellAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const u16 gMusicNotePaletteTagsTable[] = +{ + ANIM_TAG_MUSIC_NOTES_2, + ANIM_SPRITES_START - 1, + ANIM_SPRITES_START - 2, +}; + +const struct SpriteTemplate gHealBellMusicNoteSpriteTemplate = //gUnknown_83E41D0 +{ + .tileTag = ANIM_TAG_MUSIC_NOTES_2, + .paletteTag = ANIM_TAG_MUSIC_NOTES_2, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimHealBellMusicNote, +}; + +const struct SpriteTemplate gMagentaHeartSpriteTemplate = //gUnknown_83E41E8 +{ + .tileTag = ANIM_TAG_MAGENTA_HEART, + .paletteTag = ANIM_TAG_MAGENTA_HEART, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMagentaHeart, +}; + +const union AffineAnimCmd gUnknown_83E4200[] = +{ + AFFINEANIMCMD_FRAME(0x000A, 0xFFF3, 0x00, 0x0A), + AFFINEANIMCMD_FRAME(0xFFF6, 0x000D, 0x00, 0x0A), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gRedHeartProjectileSpriteTemplate = //gUnknown_83E4218 +{ + .tileTag = ANIM_TAG_RED_HEART, + .paletteTag = ANIM_TAG_RED_HEART, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimRedHeartProjectile, +}; + +const struct SpriteTemplate gRedHeartBurstSpriteTemplate = //gUnknown_83E4230 +{ + .tileTag = ANIM_TAG_RED_HEART, + .paletteTag = ANIM_TAG_RED_HEART, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimParticuleBurst, +}; + +const struct SpriteTemplate gRedHeartRisingSpriteTemplate = //gUnknown_83E4248 +{ + .tileTag = ANIM_TAG_RED_HEART, + .paletteTag = ANIM_TAG_RED_HEART, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimRedHeartRising, +}; + +const union AffineAnimCmd gHiddenPowerOrbAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 1), + AFFINEANIMCMD_JUMP(1), +}; + +const union AffineAnimCmd *const gHiddenPowerOrbAffineAnimTable[] = +{ + gHiddenPowerOrbAffineAnimCmds, +}; + +const struct SpriteTemplate gHiddenPowerOrbSpriteTemplate = //gUnknown_83E427C +{ + .tileTag = ANIM_TAG_RED_ORB, + .paletteTag = ANIM_TAG_RED_ORB, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gHiddenPowerOrbAffineAnimTable, + .callback = AnimOrbitFast, +}; + +const struct SpriteTemplate gHiddenPowerOrbScatterSpriteTemplate = //gUnknown_83E4294 +{ + .tileTag = ANIM_TAG_RED_ORB, + .paletteTag = ANIM_TAG_RED_ORB, + .oam = &gOamData_AffineDouble_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gHiddenPowerOrbAffineAnimTable, + .callback = AnimOrbitScatter, +}; + +const union AffineAnimCmd gSpitUpOrbAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 1), + AFFINEANIMCMD_JUMP(1), +}; + +const union AffineAnimCmd *const gSpitUpOrbAffineAnimTable[] = +{ + gSpitUpOrbAffineAnimCmds, +}; + +const struct SpriteTemplate gSpitUpOrbSpriteTemplate = //gUnknown_83E42C8 +{ + .tileTag = ANIM_TAG_RED_ORB_2, + .paletteTag = ANIM_TAG_RED_ORB_2, + .oam = &gOamData_AffineDouble_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpitUpOrbAffineAnimTable, + .callback = AnimSpitUpOrb, +}; + +const union AnimCmd gEyeSparkleAnimCmds[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(4, 4), + ANIMCMD_FRAME(8, 4), + ANIMCMD_FRAME(4, 4), + ANIMCMD_FRAME(0, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gEyeSparkleAnimTable[] = +{ + gEyeSparkleAnimCmds, +}; + +const struct SpriteTemplate gEyeSparkleSpriteTemplate = //gUnknown_83E42FC +{ + .tileTag = ANIM_TAG_EYE_SPARKLE, + .paletteTag = ANIM_TAG_EYE_SPARKLE, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gEyeSparkleAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimEyeSparkle, +}; + +const union AnimCmd gAngelSpriteAnimCmds[] = +{ + ANIMCMD_FRAME(0, 24), + ANIMCMD_END, +}; + +const union AnimCmd *const gAngelSpriteAnimTable[] = +{ + gAngelSpriteAnimCmds, +}; + +const struct SpriteTemplate gAngelSpriteTemplate = //gUnknown_83E4320 +{ + .tileTag = ANIM_TAG_ANGEL, + .paletteTag = ANIM_TAG_ANGEL, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gAngelSpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimAngel, +}; + +const struct SpriteTemplate gPinkHeartSpriteTemplate = //gUnknown_83E4338 +{ + .tileTag = ANIM_TAG_PINK_HEART, + .paletteTag = ANIM_TAG_PINK_HEART, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimPinkHeart, +}; + +const union AnimCmd gDevilAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gDevilAnimCmds2[] = +{ + ANIMCMD_FRAME(16, 3), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd *const gDevilAnimTable[] = +{ + gDevilAnimCmds1, + gDevilAnimCmds2, +}; + +const struct SpriteTemplate gDevilSpriteTemplate = //gUnknown_83E4368 +{ + .tileTag = ANIM_TAG_DEVIL, + .paletteTag = ANIM_TAG_DEVIL, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDevilAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimDevil, +}; + +const union AnimCmd gUnknown_08593B08[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(16, 4), + ANIMCMD_FRAME(32, 4), + ANIMCMD_FRAME(48, 4), + ANIMCMD_END, +}; + +const union AnimCmd gUnknown_08593B1C[] = +{ + ANIMCMD_FRAME(0, 4, .hFlip = TRUE), + ANIMCMD_FRAME(16, 4, .hFlip = TRUE), + ANIMCMD_FRAME(32, 4, .hFlip = TRUE), + ANIMCMD_FRAME(48, 4, .hFlip = TRUE), + ANIMCMD_END, +}; + +const union AnimCmd *const gFurySwipesAnimTable[] = +{ + gUnknown_08593B08, + gUnknown_08593B1C, +}; + +const struct SpriteTemplate gFurySwipesSpriteTemplate = //gUnknown_83E43B0 +{ + .tileTag = ANIM_TAG_SWIPE, + .paletteTag = ANIM_TAG_SWIPE, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gFurySwipesAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimFurySwipes, +}; + +const union AnimCmd gMovementWavesAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(16, 8), + ANIMCMD_FRAME(32, 8), + ANIMCMD_FRAME(16, 8), + ANIMCMD_END, +}; + +const union AnimCmd gMovementWavesAnimCmds2[] = +{ + ANIMCMD_FRAME(16, 8, .hFlip = TRUE), + ANIMCMD_FRAME(32, 8, .hFlip = TRUE), + ANIMCMD_FRAME(16, 8, .hFlip = TRUE), + ANIMCMD_FRAME(0, 8, .hFlip = TRUE), + ANIMCMD_END, +}; + +const union AnimCmd *const gMovementWavesAnimTable[] = +{ + gMovementWavesAnimCmds1, + gMovementWavesAnimCmds2, +}; + +const struct SpriteTemplate gMovementWavesSpriteTemplate = //gUnknown_83E43F8 +{ + .tileTag = ANIM_TAG_MOVEMENT_WAVES, + .paletteTag = ANIM_TAG_MOVEMENT_WAVES, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gMovementWavesAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMovmentWaves, +}; + +const union AffineAnimCmd gUnknown_08593B98[] = +{ + AFFINEANIMCMD_FRAME(-12, 8, 0, 4), + AFFINEANIMCMD_FRAME(20, -20, 0, 4), + AFFINEANIMCMD_FRAME(-8, 12, 0, 4), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gJaggedMusicNoteSpriteTemplate = //gUnknown_83E4430 +{ + .tileTag = ANIM_TAG_JAGGED_MUSIC_NOTE, + .paletteTag = ANIM_TAG_JAGGED_MUSIC_NOTE, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimJaggedMusicNote, +}; + +const union AffineAnimCmd gPerishSongMusicNoteAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 5), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gPerishSongMusicNoteAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 16), + AFFINEANIMCMD_END_ALT(1), +}; + +const union AffineAnimCmd gPerishSongMusicNoteAffineAnimCmds3[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 16), + AFFINEANIMCMD_END_ALT(1), +}; + +const union AffineAnimCmd *const gPerishSongMusicNoteAffineAnimTable[] = +{ + gPerishSongMusicNoteAffineAnimCmds1, + gPerishSongMusicNoteAffineAnimCmds2, + gPerishSongMusicNoteAffineAnimCmds3, +}; + +extern const union AnimCmd *const gMusicNotesAnimTable[]; +const struct SpriteTemplate gPerishSongMusicNoteSpriteTemplate = //gUnknown_83E4484 +{ + .tileTag = ANIM_TAG_MUSIC_NOTES_2, + .paletteTag = ANIM_TAG_MUSIC_NOTES_2, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gMusicNotesAnimTable, + .images = NULL, + .affineAnims = gPerishSongMusicNoteAffineAnimTable, + .callback = AnimPerishSongMusicNote, +}; + +const struct SpriteTemplate gPerishSongMusicNote2SpriteTemplate = //gUnknown_83E449C +{ + .tileTag = ANIM_TAG_MUSIC_NOTES_2, + .paletteTag = ANIM_TAG_MUSIC_NOTES_2, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gMusicNotesAnimTable, + .images = NULL, + .affineAnims = gPerishSongMusicNoteAffineAnimTable, + .callback = AnimPerishSongMusicNote2, +}; + +const union AffineAnimCmd gGuardRingAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gGuardRingAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x200, 0x100, 0, 0), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gGuardRingAffineAnimTable[] = +{ + gGuardRingAffineAnimCmds1, + gGuardRingAffineAnimCmds2, +}; + +const struct SpriteTemplate gGuardRingSpriteTemplate = //gUnknown_83E44DC +{ + .tileTag = ANIM_TAG_GUARD_RING, + .paletteTag = ANIM_TAG_GUARD_RING, + .oam = &gOamData_AffineDouble_ObjBlend_64x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gGuardRingAffineAnimTable, + .callback = AnimGuardRing, +}; + +// Functions +void sub_80A6E48(struct Sprite *sprite) +{ + SetSpriteCoordsToAnimAttackerCoords(sprite); + SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[1] = gBattleAnimArgs[2]; + sprite->data[2] = gBattleAnimArgs[4]; + sprite->data[3] = gBattleAnimArgs[5]; + sprite->data[4] = gBattleAnimArgs[3]; + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = TranslateSpriteInEllipseOverDuration; + sprite->callback(sprite); +} + +void sub_80A6E98(struct Sprite *sprite) +{ + u8 battler; + if (gBattleAnimArgs[0] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + SetSpriteNextToMonHead(battler, sprite); + sprite->data[0] = 0; + sprite->data[1] = 0; + sprite->callback = sub_80A6ED8; +} + +static void sub_80A6ED8(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos2.y -= 3; + if (++sprite->data[1] == 6) + sprite->data[0]++; + break; + case 1: + sprite->pos2.y += 3; + if (--sprite->data[1] == 0) + sprite->data[0]++; + break; + case 2: + if (++sprite->data[1] == 64) + DestroyAnimSprite(sprite); + break; + } +} + +static void sub_80A6F3C(struct Sprite *sprite) +{ + s16 temp; + gSprites[sprite->data[2]].pos2.x += sprite->data[1]; + temp = sprite->data[1]; + sprite->data[1] = -temp; + if (sprite->data[0] == 0) + { + gSprites[sprite->data[2]].pos2.x = 0; + DestroySpriteAndMatrix(sprite); + } + + sprite->data[0]--; +} + +void sub_80A6F8C(struct Sprite *sprite) +{ + u8 spriteId; + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + spriteId = gBattlerSpriteIds[gBattleAnimTarget]; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos1.x -= gBattleAnimArgs[0]; + else + sprite->pos1.x += gBattleAnimArgs[0]; + + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[2] = spriteId; + sprite->callback = sub_80A6F3C; + sprite->invisible = 1; +} + +void sub_80A7020(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, TRUE); + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[5] = gBattleAnimArgs[4]; + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData6(sprite, sub_80A7058); +} + +static void sub_80A7058(struct Sprite *sprite) +{ + sprite->data[0] = sprite->data[1]; + sprite->data[2] = sprite->pos1.x; + sprite->data[4] = sprite->pos1.y + 15; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, sub_80A7080); +} + +static void sub_80A7080(struct Sprite *sprite) +{ + if (sprite->data[5] == 0) + DestroyAnimSprite(sprite); + else + sprite->data[5]--; +} + +// Rotates the attacking mon sprite downwards and then back upwards to its original position. +// No args. +void AnimTask_Withdraw(u8 taskId) +{ + PrepareBattlerSpriteForRotScale(gBattlerSpriteIds[gBattleAnimAttacker], ST_OAM_OBJ_NORMAL); + gTasks[taskId].func = AnimTask_WithdrawStep; +} + +static void AnimTask_WithdrawStep(u8 taskId) +{ + u8 spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + s16 rotation; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + rotation = -gTasks[taskId].data[0]; + else + rotation = gTasks[taskId].data[0]; + + SetSpriteRotScale(spriteId, 0x100, 0x100, rotation); + if (gTasks[taskId].data[1] == 0) + { + gTasks[taskId].data[0] += 0xB0; + // this y position update gets overwritten by SetBattlerSpriteYOffsetFromRotation() + gSprites[spriteId].pos2.y++; + } + else if (gTasks[taskId].data[1] == 1) + { + if (++gTasks[taskId].data[3] == 30) + gTasks[taskId].data[1] = 2; + + return; + } + else + { + gTasks[taskId].data[0] -= 0xB0; + // this y position update gets overwritten by SetBattlerSpriteYOffsetFromRotation() + gSprites[spriteId].pos2.y--; + } + + SetBattlerSpriteYOffsetFromRotation(spriteId); + if (gTasks[taskId].data[0] == 0xF20 || gTasks[taskId].data[0] == 0) + { + if (gTasks[taskId].data[1] == 2) + { + ResetSpriteRotScale(spriteId); + DestroyAnimVisualTask(taskId); + } + else + { + gTasks[taskId].data[1]++; + } + } +} + +// Animates a "zap of energy" used in KINESIS. +// arg 0: x pixel offset +// arg 1: y pixel offset +// arg 2: vertical flip +void Anim_KinesisZapEnergy(struct Sprite *sprite) +{ + SetSpriteCoordsToAnimAttackerCoords(sprite); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos1.x -= gBattleAnimArgs[0]; + else + sprite->pos1.x += gBattleAnimArgs[0]; + + sprite->pos1.y += gBattleAnimArgs[1]; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->hFlip = 1; + if (gBattleAnimArgs[2]) + sprite->vFlip = 1; + } + else + { + if (gBattleAnimArgs[2]) + sprite->vFlip = 1; + } + + sprite->callback = RunStoredCallbackWhenAnimEnds; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Animates a sword that rises into the air after a brief pause. +// arg 0: x pixel offset +// arg 1: y pixel offset +void Anim_SwordsDanceBlade(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, FALSE); + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; + StoreSpriteCallbackInData6(sprite, AnimSwordsDanceBladeStep); +} + +static void AnimSwordsDanceBladeStep(struct Sprite *sprite) +{ + sprite->data[0] = 6; + sprite->data[2] = sprite->pos1.x; + sprite->data[4] = sprite->pos1.y - 32; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Moves a projectile towards the target mon. The sprite is rotated to be pointing +// in the same direction it's moving. +// 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 +void AnimSonicBoomProjectile(struct Sprite *sprite) +{ + s16 targetXPos; + s16 targetYPos; + u16 rotation; + + if (IsContest()) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + else if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + } + + InitSpritePosToAnimAttacker(sprite, TRUE); + targetXPos = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2]; + targetYPos = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3]; + rotation = ArcTan2Neg(targetXPos - sprite->pos1.x, targetYPos - sprite->pos1.y); + rotation += 0xF000; + if (IsContest()) + rotation -= 0x6000; + + TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rotation); + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = targetXPos; + sprite->data[4] = targetYPos; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +static void AnimAirWaveProjectile_Step2(struct Sprite *sprite) +{ + if (sprite->data[0]-- <= 0) + { + gTasks[sprite->data[7]].data[1]--; + DestroySprite(sprite); + } +} + +static void AnimAirWaveProjectile_Step1(struct Sprite *sprite) +{ + struct Task* task = &gTasks[sprite->data[7]]; + if (sprite->data[0] > task->data[5]) + { + sprite->data[5] += sprite->data[3]; + sprite->data[6] += sprite->data[4]; + } + else + { + sprite->data[5] -= sprite->data[3]; + sprite->data[6] -= sprite->data[4]; + } + + sprite->data[1] += sprite->data[5]; + sprite->data[2] += sprite->data[6]; + if (1 & task->data[7]) + sprite->pos2.x = ((u16)sprite->data[1] >> 8) * -1; + else + sprite->pos2.x = (u16)sprite->data[1] >> 8; + + if (1 & task->data[8]) + sprite->pos2.y = ((u16)sprite->data[2] / 256u) * -1; + else + sprite->pos2.y = (u16)sprite->data[2] / 256u; + + if (sprite->data[0]-- <= 0) + { + sprite->data[0] = 30; + sprite->callback = AnimAirWaveProjectile_Step2; + } +} + +void AnimAirWaveProjectile(struct Sprite *sprite) +{ + s16 a; + s16 b; + s16 c; + + struct Task* task = &gTasks[sprite->data[7]]; + sprite->data[1] += (-2 & task->data[7]); + sprite->data[2] += (-2 & task->data[8]); + if (1 & task->data[7]) + sprite->pos2.x = ((u16)sprite->data[1] >> 8) * -1; + else + sprite->pos2.x = (u16)sprite->data[1] >> 8; + + if (1 & task->data[8]) + sprite->pos2.y = ((u16)sprite->data[2] / 256u) * -1; + else + sprite->pos2.y = (u16)sprite->data[2] / 256u; + + if (sprite->data[0]-- <= 0) + { + sprite->data[0] = 8; + task->data[5] = 4; + a = sub_80D8B90(0x1000); + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + if (task->data[11] >= sprite->pos1.x) + b = (task->data[11] - sprite->pos1.x) << 8; + else + b = (sprite->pos1.x - task->data[11]) << 8; + + if (task->data[12] >= sprite->pos1.y) + c = (task->data[12] - sprite->pos1.y) << 8; + else + c = (sprite->pos1.y - task->data[12]) << 8; + + sprite->data[2] = 0; + sprite->data[1] = 0; + sprite->data[6] = 0; + sprite->data[5] = 0; + sprite->data[3] = sub_80D8AA0(sub_80D8AA0(b, a), sub_80D8B90(0x1C0)); + sprite->data[4] = sub_80D8AA0(sub_80D8AA0(c, a), sub_80D8B90(0x1C0)); + sprite->callback = AnimAirWaveProjectile_Step1; + } +} + +static void AirCutterProjectileStep2(u8 taskId) +{ + if (gTasks[taskId].data[1] == 0) + DestroyAnimVisualTask(taskId); +} + +static void AirCutterProjectileStep1(u8 taskId) +{ + if (gTasks[taskId].data[0]-- <= 0) + { + u8 spriteId; + struct Sprite *sprite; + spriteId = CreateSprite(&gAirWaveProjectileSpriteTemplate, gTasks[taskId].data[9], gTasks[taskId].data[10], gTasks[taskId].data[2] - gTasks[taskId].data[1]); + sprite = &gSprites[spriteId]; + switch (gTasks[taskId].data[4]) + { + case 1: + sprite->oam.matrixNum |= (ST_OAM_HFLIP | ST_OAM_VFLIP); + break; + case 2: + sprite->oam.matrixNum = ST_OAM_HFLIP; + break; + } + + sprite->data[0] = gTasks[taskId].data[5] - gTasks[taskId].data[6]; + sprite->data[7] = taskId; + gTasks[taskId].data[gTasks[taskId].data[1] + 13] = spriteId; + gTasks[taskId].data[0] = gTasks[taskId].data[3]; + gTasks[taskId].data[1]++; + PlaySE12WithPanning(SE_W059B, BattleAnimAdjustPanning(-63)); + if (gTasks[taskId].data[1] > 2) + gTasks[taskId].func = AirCutterProjectileStep2; + } +} + +void AnimTask_AirCutterProjectile(u8 taskId) +{ + s16 attackerY = 0; + s16 attackerX = 0; + s16 targetX = 0; + s16 targetY = 0; + s16 xDiff, yDiff; + + if (IsContest()) + { + gTasks[taskId].data[4] = 2; + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + if (gBattleAnimArgs[2] & 1) + gBattleAnimArgs[2] &= ~1; + else + gBattleAnimArgs[2] |= 1; + } + else + { + if ((gBattlerPositions[gBattleAnimTarget] & BIT_SIDE) == B_SIDE_PLAYER) + { + gTasks[taskId].data[4] = 1; + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[2] & 1) + gBattleAnimArgs[2] &= ~1; + else + gBattleAnimArgs[2] |= 1; + } + } + + attackerX = gTasks[taskId].data[9] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); + attackerY = gTasks[taskId].data[10] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y); + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) + { + SetAverageBattlerPositions(gBattleAnimTarget, 0, &targetX, &targetY); + } + else + { + targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y); + } + + targetX = gTasks[taskId].data[11] = targetX + gBattleAnimArgs[0]; + targetY = gTasks[taskId].data[12] = targetY + gBattleAnimArgs[1]; + if (targetX >= attackerX) + xDiff = targetX - attackerX; + else + xDiff = attackerX - targetX; + + gTasks[taskId].data[5] = sub_80D8AA0(xDiff, sub_80D8B90(gBattleAnimArgs[2] & ~1)); + gTasks[taskId].data[6] = sub_80D8AA0(gTasks[taskId].data[5], 0x80); + gTasks[taskId].data[7] = gBattleAnimArgs[2]; + if (targetY >= attackerY) + { + yDiff = targetY - attackerY; + gTasks[taskId].data[8] = sub_80D8AA0(yDiff, sub_80D8B90(gTasks[taskId].data[5])) & ~1; + } + else + { + yDiff = attackerY - targetY; + gTasks[taskId].data[8] = sub_80D8AA0(yDiff, sub_80D8B90(gTasks[taskId].data[5])) | 1; + } + + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + if (gBattleAnimArgs[4] & 0x80) + { + gBattleAnimArgs[4] ^= 0x80; + if (gBattleAnimArgs[4] >= 64) + { + u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) + (gBattleAnimArgs[4] - 64); + gTasks[taskId].data[2] = var; + } + else + { + u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) - gBattleAnimArgs[4]; + gTasks[taskId].data[2] = var; + } + } + else + { + if (gBattleAnimArgs[4] >= 64) + { + u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) + (gBattleAnimArgs[4] - 64); + gTasks[taskId].data[2] = var; + } + else + { + u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) - gBattleAnimArgs[4]; + gTasks[taskId].data[2] = var; + } + } + + if (gTasks[taskId].data[2] < 3) + gTasks[taskId].data[2] = 3; + + gTasks[taskId].func = AirCutterProjectileStep1; +} + +void sub_80A79E8(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, FALSE); + sprite->data[0] = 0x100 + (IndexOfSpritePaletteTag(gUnknown_83E3D18.paletteTag) << 4); + sprite->callback = sub_80A7A18; +} + +static void sub_80A7A18(struct Sprite *sprite) +{ + u16 id, val; + int i; + + if (++sprite->data[1] == 2) + { + sprite->data[1] = 0; + id = sprite->data[0]; + val = gPlttBufferFaded[8 + id]; + for (i = 8; i < 16; i++) + gPlttBufferFaded[i + id] = gPlttBufferFaded[i + id + 1]; + + gPlttBufferFaded[id + 15] = val; + + if (++sprite->data[2] == 24) + DestroyAnimSprite(sprite); + } +} + +void AnimCoinThrow(struct Sprite *sprite) +{ + s16 r6; + s16 r7; + u16 var; + + InitSpritePosToAnimAttacker(sprite, TRUE); + r6 = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + r7 = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3]; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + + r6 += gBattleAnimArgs[2]; + var = ArcTan2Neg(r6 - sprite->pos1.x, r7 - sprite->pos1.y); + var += 0xC000; + TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, var); + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = r6; + sprite->data[4] = r7; + sprite->callback = sub_80756A4; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void AnimFallingCoin(struct Sprite *sprite) +{ + sprite->data[2] = -16; + sprite->pos1.y += 8; + sprite->callback = AnimFallingCoin_Step; +} + +static void AnimFallingCoin_Step(struct Sprite *sprite) +{ + sprite->data[0] += 0x80; + sprite->pos2.x = sprite->data[0] >> 8; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + sprite->pos2.x = -sprite->pos2.x; + + sprite->pos2.y = Sin(sprite->data[1], sprite->data[2]); + sprite->data[1] += 5; + if (sprite->data[1] > 126) + { + sprite->data[1] = 0; + sprite->data[2] /= 2; + if (++sprite->data[3] == 2) + DestroyAnimSprite(sprite); + } +} + +void AnimBulletSeed(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, TRUE); + sprite->data[0] = 20; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); + sprite->callback = StartAnimLinearTranslation; + sprite->affineAnimPaused = 1; + StoreSpriteCallbackInData6(sprite, AnimBulletSeed_Step1); +} + +static void AnimBulletSeed_Step1(struct Sprite *sprite) +{ + int i; + u16 rand; + s16* ptr; + PlaySE12WithPanning(SE_W030, BattleAnimAdjustPanning(63)); + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + ptr = &sprite->data[7]; + for (i = 0; i < 8; i++) + ptr[i - 7] = 0; + + rand = Random2(); + sprite->data[6] = 0xFFF4 - (rand & 7); + rand = Random2(); + sprite->data[7] = (rand % 0xA0) + 0xA0; + sprite->callback = AnimBulletSeed_Step2; + sprite->affineAnimPaused = 0; +} + +static void AnimBulletSeed_Step2(struct Sprite *sprite) +{ + sprite->data[0] += sprite->data[7]; + sprite->pos2.x = sprite->data[0] >> 8; + if (sprite->data[7] & 1) + sprite->pos2.x = -sprite->pos2.x; + + sprite->pos2.y = Sin(sprite->data[1], sprite->data[6]); + sprite->data[1] += 8; + if (sprite->data[1] > 126) + { + sprite->data[1] = 0; + sprite->data[2] /= 2; + if (++sprite->data[3] == 1) + DestroyAnimSprite(sprite); + } +} + +// Moves a tornado in a circlular motion. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: wave amplitude +// arg 3: unused +// arg 4: initial wave offset +// arg 5: wave period (higher means faster wave) +// arg 6: duration +void AnimRazorWindTornado(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, FALSE); + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + sprite->pos1.y += 16; + + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = gBattleAnimArgs[2]; + sprite->data[2] = gBattleAnimArgs[5]; + sprite->data[3] = gBattleAnimArgs[6]; + sprite->data[4] = gBattleAnimArgs[3]; + sprite->callback = TranslateSpriteInCircleOverDuration; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->callback(sprite); +} + +// Animates a single pincer line that extends towards the center of the target mon. +// arg 0: invert +void AnimViceGripPincer(struct Sprite *sprite) +{ + s16 startXOffset = 32; + s16 startYOffset = -32; + s16 endXOffset = 16; + s16 endYOffset = -16; + if (gBattleAnimArgs[0]) + { + startXOffset = -32; + startYOffset = 32; + endXOffset = -16; + endYOffset = 16; + StartSpriteAnim(sprite, 1); + } + + sprite->pos1.x += startXOffset; + sprite->pos1.y += startYOffset; + sprite->data[0] = 6; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + endXOffset; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + endYOffset; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, AnimViceGripPincerStep); +} + +static void AnimViceGripPincerStep(struct Sprite *sprite) +{ + if (sprite->animEnded) + DestroyAnimSprite(sprite); +} + +// Animates a single pincer line that extends towards the center of the target mon, and then back out. +// arg 0: animation id +void AnimGuillotinePincer(struct Sprite *sprite) +{ + s16 startXOffset = 32; + s16 startYOffset = -32; + s16 endXOffset = 16; + s16 endYOffset = -16; + if (gBattleAnimArgs[0]) + { + startXOffset = -32; + startYOffset = 32; + endXOffset = -16; + endYOffset = 16; + StartSpriteAnim(sprite, gBattleAnimArgs[0]); + } + + sprite->pos1.x += startXOffset; + sprite->pos1.y += startYOffset; + sprite->data[0] = 6; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + endXOffset; + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + endYOffset; + InitAnimLinearTranslation(sprite); + sprite->data[5] = gBattleAnimArgs[0]; + sprite->data[6] = sprite->data[0]; + sprite->callback = AnimGuillotinePincerStep1; +} + +static void AnimGuillotinePincerStep1(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite) && sprite->animEnded) + { + SeekSpriteAnim(sprite, 0); + sprite->animPaused = 1; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 2; + sprite->pos2.y = -2; + sprite->data[0] = sprite->data[6]; + sprite->data[1] ^= 1; + sprite->data[2] ^= 1; + sprite->data[4] = 0; + sprite->data[3] = 0; + sprite->callback = AnimGuillotinePincerStep2; + } +} + +static void AnimGuillotinePincerStep2(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = -sprite->pos2.x; + sprite->pos2.y = -sprite->pos2.y; + } + + sprite->data[3] ^= 1; + if (++sprite->data[4] == 51) + { + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[4] = 0; + sprite->data[3] = 0; + sprite->animPaused = 0; + StartSpriteAnim(sprite, sprite->data[5] ^ 1); + sprite->callback = AnimGuillotinePincerStep3; + } +} + +static void AnimGuillotinePincerStep3(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite)) + DestroyAnimSprite(sprite); +} + +// Scales up the target mon sprite, and sets the palette to greyscale. +// Used in MOVE_DISABLE. +// No args. +void AnimTask_GrowAndGreyscale(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND); + SetSpriteRotScale(spriteId, 0xD0, 0xD0, 0); + SetGreyscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, FALSE); + gTasks[taskId].data[0] = 80; + gTasks[taskId].func = AnimTask_GrowAndGreyscaleStep; +} + +static void AnimTask_GrowAndGreyscaleStep(u8 taskId) +{ + if (--gTasks[taskId].data[0] == -1) + { + u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); + ResetSpriteRotScale(spriteId); + SetGreyscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, TRUE); + DestroyAnimVisualTask(taskId); + } +} + +// Shrinks and grows the attacking mon several times. Also creates transparent versions of the +// mon's sprite while it is shrinking. +// No args. +void AnimTask_Minimize(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->data[0] = spriteId; + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + task->data[4] = 0x100; + task->data[5] = 0; + task->data[6] = 0; + task->data[7] = GetBattlerSpriteSubpriority(gBattleAnimAttacker); + task->func = AnimTask_MinimizeStep1; +} + +static void AnimTask_MinimizeStep1(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + switch (task->data[1]) + { + case 0: + if (task->data[2] == 0 || task->data[2] == 3 || task->data[2] == 6) + CreateMinimizeSprite(task, taskId); + task->data[2]++; + task->data[4] += 0x28; + SetSpriteRotScale(task->data[0], task->data[4], task->data[4], 0); + SetBattlerSpriteYOffsetFromYScale(task->data[0]); + if (task->data[2] == 32) + { + task->data[5]++; + task->data[1]++; + } + break; + case 1: + if (task->data[6] == 0) + { + if (task->data[5] == 3) + { + task->data[2] = 0; + task->data[1] = 3; + } + else + { + task->data[2] = 0; + task->data[3] = 0; + task->data[4] = 0x100; + SetSpriteRotScale(task->data[0], task->data[4], task->data[4], 0); + SetBattlerSpriteYOffsetFromYScale(task->data[0]); + task->data[1] = 2; + } + } + break; + case 2: + task->data[1] = 0; + break; + case 3: + if (++task->data[2] > 32) + { + task->data[2] = 0; + task->data[1]++; + } + break; + case 4: + task->data[2] += 2; + task->data[4] -= 0x50; + SetSpriteRotScale(task->data[0], task->data[4], task->data[4], 0); + SetBattlerSpriteYOffsetFromYScale(task->data[0]); + if (task->data[2] == 32) + { + task->data[2] = 0; + task->data[1]++; + } + break; + case 5: + ResetSpriteRotScale(task->data[0]); + gSprites[task->data[15]].pos2.y = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +static void CreateMinimizeSprite(struct Task* task, u8 taskId) +{ + u16 matrixNum; + s16 spriteId = CloneBattlerSpriteWithBlend(ANIM_ATTACKER); + if (spriteId >= 0) + { + if ((matrixNum = AllocOamMatrix()) == 0xFF) + { + obj_delete_but_dont_free_vram(&gSprites[spriteId]); + } + else + { + gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND; + gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + gSprites[spriteId].affineAnimPaused = TRUE; + gSprites[spriteId].oam.matrixNum = matrixNum; + gSprites[spriteId].subpriority = task->data[7] - task->data[3]; + task->data[3]++; + task->data[6]++; + gSprites[spriteId].data[0] = 16; + gSprites[spriteId].data[1] = taskId; + gSprites[spriteId].data[2] = 6; + gSprites[spriteId].callback = ClonedMinizeSprite_Step; + SetSpriteRotScale(spriteId, task->data[4], task->data[4], 0); + gSprites[spriteId].oam.affineMode = 1; + CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode); + } + } +} + +static void ClonedMinizeSprite_Step(struct Sprite *sprite) +{ + if (--sprite->data[0] == 0) + { + gTasks[sprite->data[1]].data[sprite->data[2]]--; + FreeOamMatrix(sprite->oam.matrixNum); + obj_delete_but_dont_free_vram(sprite); + } +} + +// Task to facilitate expanding and hopping effect seen in Splash. +// arg 0: anim battler +// arg 1: num hops +void AnimTask_Splash(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + if (gBattleAnimArgs[1] == 0) + { + DestroyAnimVisualTask(taskId); + } + else + { + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + task->data[0] = spriteId; + task->data[1] = 0; + task->data[2] = gBattleAnimArgs[1]; + task->data[3] = 0; + task->data[4] = 0; + PrepareAffineAnimInTaskData(task, spriteId, gSplashEffectAffineAnimCmds); + task->func = AnimTask_SplashStep; + } +} + +static void AnimTask_SplashStep(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + switch (task->data[1]) + { + case 0: + RunAffineAnimFromTaskData(task); + task->data[4] += 3; + gSprites[task->data[0]].pos2.y += task->data[4]; + if (++task->data[3] > 7) + { + task->data[3] = 0; + task->data[1]++; + } + break; + case 1: + RunAffineAnimFromTaskData(task); + gSprites[task->data[0]].pos2.y += task->data[4]; + if (++task->data[3] > 7) + { + task->data[3] = 0; + task->data[1]++; + } + break; + case 2: + if (task->data[4] != 0) + { + gSprites[task->data[0]].pos2.y -= 2; + task->data[4] -= 2; + } + else + task->data[1]++; + break; + case 3: + if (!RunAffineAnimFromTaskData(task)) + { + if (--task->data[2] == 0) + { + gSprites[task->data[0]].pos2.y = 0; + DestroyAnimVisualTask(taskId); + } + else + { + PrepareAffineAnimInTaskData(task, task->data[0], gSplashEffectAffineAnimCmds); + task->data[1] = 0; + } + } + break; + } +} + +// Grows, pauses, then shrinks the attacking mon. +// Used by MOVE_SWAGGER and MOVE_BULK_UP +// No args. +void AnimTask_GrowAndShrink(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + PrepareAffineAnimInTaskData(task, spriteId, gGrowAndShrinkAffineAnimCmds); + task->func = AnimTask_GrowAndShrinkStep; +} + +static void AnimTask_GrowAndShrinkStep(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + if (!RunAffineAnimFromTaskData(task)) + DestroyAnimVisualTask(taskId); +} + +// Animates a little puff of the mon's breath. +// Used by MOVE_SWAGGER and MOVE_BULK_UP +// No args. +void AnimBreathPuff(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + StartSpriteAnim(sprite, 0); + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + 32; + sprite->data[1] = 64; + } + else + { + StartSpriteAnim(sprite, 1); + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) - 32; + sprite->data[1] = -64; + } + + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + sprite->data[0] = 52; + sprite->data[2] = 0; + sprite->data[3] = 0; + sprite->data[4] = 0; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->callback = TranslateSpriteLinearFixedPoint; +} + +// Animates an "angry" mark above a mon's head. +// arg 0: target mon (0 = attacker, 1 = target) +// arg 1: x pixel offset +// arg 2: y pixel offset +void AnimAngerMark(struct Sprite *sprite) +{ + u8 battler; + if (!gBattleAnimArgs[0]) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + if (GetBattlerSide(battler) == B_SIDE_OPPONENT) + gBattleAnimArgs[1] *= -1; + + sprite->pos1.x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2]; + if (sprite->pos1.y < 8) + sprite->pos1.y = 8; + + StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); + sprite->callback = RunStoredCallbackWhenAffineAnimEnds; +} + +// left/right movements +void AnimTask_ThrashMoveMonHorizontal(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->data[0] = spriteId; + task->data[1] = 0; + PrepareAffineAnimInTaskData(task, spriteId, gThrashMoveMonAffineAnimCmds); + task->func = ThrashMoveMonStep; +} + +static void ThrashMoveMonStep(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + if (!RunAffineAnimFromTaskData(task)) + DestroyAnimVisualTask(taskId); +} + +// up/down movements +void AnimTask_ThrashMoveMonVertical(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + task->data[0] = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->data[1] = 0; + task->data[2] = 4; + task->data[3] = 7; + task->data[4] = 3; + task->data[5] = gSprites[task->data[0]].pos1.x; + task->data[6] = gSprites[task->data[0]].pos1.y; + task->data[7] = 0; + task->data[8] = 0; + task->data[9] = 2; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + task->data[2] *= -1; + + task->func = ThrashMoveMon; +} + +static void ThrashMoveMon(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + if (++task->data[7] > 2) + { + task->data[7] = 0; + task->data[8]++; + if (task->data[8] & 1) + gSprites[task->data[0]].pos1.y += task->data[9]; + else + gSprites[task->data[0]].pos1.y -= task->data[9]; + } + switch (task->data[1]) + { + case 0: + gSprites[task->data[0]].pos1.x += task->data[2]; + if (--task->data[3] == 0) + { + task->data[3] = 14; + task->data[1] = 1; + } + break; + case 1: + gSprites[task->data[0]].pos1.x -= task->data[2]; + if (--task->data[3] == 0) + { + task->data[3] = 7; + task->data[1] = 2; + } + break; + case 2: + gSprites[task->data[0]].pos1.x += task->data[2]; + if (--task->data[3] == 0) + { + if (--task->data[4] != 0) + { + task->data[3] = 7; + task->data[1] = 0; + } + else + { + if ((task->data[8] & 1) != 0) + gSprites[task->data[0]].pos1.y -= task->data[9]; + + DestroyAnimVisualTask(taskId); + } + } + break; + } +} + +void sub_80A8874(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + struct ScanlineEffectParams params; + + s16 i; + task->data[0] = GetBattlerYCoordWithElevation(gBattleAnimTarget) + 32; + task->data[1] = 4; + task->data[2] = 0; + task->data[3] = 0; + task->data[4] = 0; + task->data[5] = 0; + task->data[15] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT); + + if (GetBattlerSpriteBGPriorityRank(gBattleAnimTarget) == 1) + { + task->data[6] = gBattle_BG1_X; + params.dmaDest = (u16 *)REG_ADDR_BG1HOFS; + } + else + { + task->data[6] = gBattle_BG2_X; + params.dmaDest = (u16 *)REG_ADDR_BG2HOFS; + } + + for (i = task->data[0] - 0x40; i <= task->data[0]; i++) + { + if (i >= 0) + { + gScanlineEffectRegBuffers[0][i] = task->data[6] + 0xF0; + gScanlineEffectRegBuffers[1][i] = task->data[6] + 0xF0; + } + } + + params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + params.initState = 1; + params.unused9 = 0; + ScanlineEffect_SetParams(params); + task->func = AnimTask_SketchDrawMon; +} + +static void AnimTask_SketchDrawMon(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + + switch (task->data[4]) + { + case 0: + if (++task->data[5] > 20) + task->data[4]++; + break; + case 1: + if (++task->data[1] > 3) + { + task->data[1] = 0; + task->data[2] = task->data[3] & 3; + task->data[5] = task->data[0] - task->data[3]; + switch (task->data[2]) + { + case 0: + break; + case 1: + task->data[5] -= 2; + break; + case 2: + task->data[5] += 1; + break; + case 3: + task->data[5] += 1; + break; + } + + if (task->data[5] >= 0) + { + gScanlineEffectRegBuffers[0][task->data[5]] = task->data[6]; + gScanlineEffectRegBuffers[1][task->data[5]] = task->data[6]; + } + + if (++task->data[3] >= task->data[15]) + { + gScanlineEffect.state = 3; + DestroyAnimVisualTask(taskId); + } + } + break; + } +} + +void AnimPencil(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0) - 16; + sprite->pos1.y = GetBattlerYCoordWithElevation(gBattleAnimTarget) + 16; + sprite->data[0] = 0; + sprite->data[1] = 0; + sprite->data[2] = 0; + sprite->data[3] = 16; + sprite->data[4] = 0; + sprite->data[5] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT) + 2; + sprite->data[6] = BattleAnimAdjustPanning(63); + sprite->callback = AnimPencil_Step; +} + +static void AnimPencil_Step(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + if (++sprite->data[2] > 1) + { + sprite->data[2] = 0; + sprite->invisible = !sprite->invisible; + } + if (++sprite->data[1] > 16) + { + sprite->invisible = 0; + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[1] > 3 && sprite->data[2] < sprite->data[5]) + { + sprite->data[1] = 0; + sprite->pos1.y -= 1; + sprite->data[2]++; + if (sprite->data[2] % 10 == 0) + PlaySE12WithPanning(SE_W166, sprite->data[6]); + } + sprite->data[4] += sprite->data[3]; + if (sprite->data[4] > 31) + { + sprite->data[4] = 0x40 - sprite->data[4]; + sprite->data[3] *= -1; + } + else if (sprite->data[4] <= -32) + { + sprite->data[4] = -0x40 - sprite->data[4]; + sprite->data[3] *= -1; + } + sprite->pos2.x = sprite->data[4]; + if (sprite->data[5] == sprite->data[2]) + { + sprite->data[1] = 0; + sprite->data[2] = 0; + sprite->data[0]++; + } + break; + case 2: + if (++sprite->data[2] > 1) + { + sprite->data[2] = 0; + sprite->invisible = !sprite->invisible; + } + if (++sprite->data[1] > 16) + { + sprite->invisible = 0; + DestroyAnimSprite(sprite); + } + break; + } +} + +void AnimBlendThinRing(struct Sprite *sprite) +{ + u8 battler = 0; + u16 sp0 = 0; + u16 sp1 = 0; + u8 r4; + + if (gBattleAnimArgs[2] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + r4 = gBattleAnimArgs[3] ^ 1; + if (IsDoubleBattle() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler))) + { + SetAverageBattlerPositions(battler, r4, &sp0, &sp1); + if (r4 == 0) + r4 = GetBattlerSpriteCoord(battler, 0); + else + r4 = GetBattlerSpriteCoord(battler, 2); + + if (GetBattlerSide(battler) != B_SIDE_PLAYER) + gBattleAnimArgs[0] -= (sp0 - r4) - gBattleAnimArgs[0]; // This is weird. + else + gBattleAnimArgs[0] = sp0 - r4; + } + + sprite->callback = AnimSpriteOnMonPos; + sprite->callback(sprite); +} + +void sub_80A8C84(struct Sprite *sprite) +{ + if (AnimTranslateLinear(sprite)) + { + FreeSpriteOamMatrix(sprite); + DestroyAnimSprite(sprite); + } +} + +void AnimHyperVoiceRing(struct Sprite *sprite) +{ + u16 r9 = 0; + u16 r6 = 0; + s16 sp0 = 0; + s16 sp1 = 0; + u8 sp4; + u8 battler1; + u8 battler2; + u8 r10; + + if (gBattleAnimArgs[5] == 0) + { + battler1 = gBattleAnimAttacker; + battler2 = gBattleAnimTarget; + } + else + { + battler1 = gBattleAnimTarget; + battler2 = gBattleAnimAttacker; + } + + if (!gBattleAnimArgs[6]) + { + r10 = 0; + sp4 = 1; + } + else + { + r10 = 2; + sp4 = 3; + } + + if (GetBattlerSide(battler1) != B_SIDE_PLAYER) + { + r9 = GetBattlerSpriteCoord(battler1, r10) + gBattleAnimArgs[0]; + if (IsBattlerSpriteVisible(BATTLE_PARTNER(battler2))) + sprite->subpriority = gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler2)]].subpriority - 1; + else + sprite->subpriority = gSprites[gBattlerSpriteIds[battler2]].subpriority - 1; + } + else + { + r9 = GetBattlerSpriteCoord(battler1, r10) - gBattleAnimArgs[0]; + if (!IsContest() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler1))) + { + if (gSprites[gBattlerSpriteIds[battler1]].pos1.x < gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler1)]].pos1.x) + sprite->subpriority = gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler1)]].subpriority + 1; + else + sprite->subpriority = gSprites[gBattlerSpriteIds[battler1]].subpriority - 1; + } + else + { + sprite->subpriority = gSprites[gBattlerSpriteIds[battler1]].subpriority - 1; + } + + } + + r6 = GetBattlerSpriteCoord(battler1, sp4) + gBattleAnimArgs[1]; + if (!IsContest() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler2))) + { + SetAverageBattlerPositions(battler2, gBattleAnimArgs[6], &sp0, &sp1); + } + else + { + sp0 = GetBattlerSpriteCoord(battler2, r10); + sp1 = GetBattlerSpriteCoord(battler2, sp4); + } + + if (GetBattlerSide(battler2)) + sp0 += gBattleAnimArgs[3]; + else + sp0 -= gBattleAnimArgs[3]; + + sp1 += gBattleAnimArgs[4]; + sprite->pos1.x = sprite->data[1] = r9; + sprite->pos1.y = sprite->data[3] = r6; + sprite->data[2] = sp0; + sprite->data[4] = sp1; + sprite->data[0] = gBattleAnimArgs[0]; + InitAnimLinearTranslation(sprite); + sprite->callback = sub_80A8C84; + sprite->callback(sprite); +} + +void AnimUproarRing(struct Sprite *sprite) +{ + u8 index = IndexOfSpritePaletteTag(ANIM_TAG_THIN_RING); + if (index != 0xFF) + { + BlendPalette(((index << 20) + 0x1010000) >> 16, 15, gBattleAnimArgs[5], gBattleAnimArgs[4]); + } + + StartSpriteAffineAnim(sprite, 1); + sprite->callback = AnimSpriteOnMonPos; + sprite->callback(sprite); +} + +void AnimSoftBoiledEgg(struct Sprite *sprite) +{ + s16 r1; + InitSpritePosToAnimAttacker(sprite, FALSE); + r1 = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? -160 : 160; + sprite->data[0] = 0x380; + sprite->data[1] = r1; + sprite->data[7] = gBattleAnimArgs[2]; + sprite->callback = AnimSoftBoiledEgg_Step1; +} + +static void AnimSoftBoiledEgg_Step1(struct Sprite *sprite) +{ + s16 add; + sprite->pos2.y -= (sprite->data[0] >> 8); + sprite->pos2.x = sprite->data[1] >> 8; + sprite->data[0] -= 32; + add = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? -160 : 160; + sprite->data[1] += add; + if (sprite->pos2.y > 0) + { + sprite->pos1.y += sprite->pos2.y; + sprite->pos1.x += sprite->pos2.x; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[0] = 0; + StartSpriteAffineAnim(sprite, 1); + sprite->callback = AnimSoftBoiledEgg_Step2; + } +} + +static void AnimSoftBoiledEgg_Step2(struct Sprite *sprite) +{ + if (sprite->data[0]++ > 19) + { + StartSpriteAffineAnim(sprite, 2); + sprite->callback = AnimSoftBoiledEgg_Step3; + } +} + +static void AnimSoftBoiledEgg_Step3(struct Sprite *sprite) +{ + if (sprite->affineAnimEnded) + { + StartSpriteAffineAnim(sprite, 1); + sprite->data[0] = 0; + if (sprite->data[7] == 0) + { + sprite->oam.tileNum += 16; + sprite->callback = AnimSoftBoiledEgg_Step3_Callback1; + } + else + { + sprite->oam.tileNum += 32; + sprite->callback = AnimSoftBoiledEgg_Step4; + } + } +} + +static void AnimSoftBoiledEgg_Step3_Callback1(struct Sprite *sprite) +{ + sprite->pos2.y -= 2; + if (++sprite->data[0] == 9) + { + sprite->data[0] = 16; + sprite->data[1] = 0; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND((u16)sprite->data[0], 0)); + sprite->callback = AnimSoftBoiledEgg_Step3_Callback2; + } +} + +static void AnimSoftBoiledEgg_Step3_Callback2(struct Sprite *sprite) +{ + if (sprite->data[1]++ % 3 == 0) + { + sprite->data[0]--; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0])); + if (sprite->data[0] == 0) + sprite->callback = AnimSoftBoiledEgg_Step4; + } +} + +static void AnimSoftBoiledEgg_Step4(struct Sprite *sprite) +{ + if ((u16)gBattleAnimArgs[7] == 0xFFFF) + { + sprite->invisible = 1; + if (sprite->data[7] == 0) + sprite->callback = AnimSoftBoiledEgg_Step4_Callback; + else + sprite->callback = DestroyAnimSprite; + } +} + +static void AnimSoftBoiledEgg_Step4_Callback(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); +} + +void AnimTask_StretchAttacker(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->data[0] = spriteId; + PrepareAffineAnimInTaskData(task, spriteId, gStretchAttackerAffineAnimCmds); + task->func = StretchAttacker_Step; +} + +static void StretchAttacker_Step(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + if (!RunAffineAnimFromTaskData(task)) + { + gSprites[task->data[0]].pos2.y = 0; + gSprites[task->data[0]].invisible = 1; + DestroyAnimVisualTask(taskId); + } +} + +void AnimTask_ExtremeSpeedImpact(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + task->data[12] = 3; + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + task->data[13] = 0xFFFF; + task->data[14] = 8; + } + else + { + task->data[13] = 1; + task->data[14] = -8; + } + + task->data[15] = GetAnimBattlerSpriteId(ANIM_TARGET); + task->func = ExtremeSpeedImpact_Step; +} + +static void ExtremeSpeedImpact_Step(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + gSprites[task->data[15]].pos2.x += task->data[14]; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + task->data[0]++; + break; + case 1: + if (++task->data[1] > 1) + { + task->data[1] = 0; + task->data[2]++; + if (task->data[2] & 1) + gSprites[task->data[15]].pos2.x += 6; + else + gSprites[task->data[15]].pos2.x -= 6; + + if (++task->data[3] > 4) + { + if (task->data[2] & 1) + gSprites[task->data[15]].pos2.x -= 6; + + task->data[0]++; + } + } + break; + case 2: + if (--task->data[12] != 0) + task->data[0] = 0; + else + task->data[0]++; + break; + case 3: + gSprites[task->data[15]].pos2.x += task->data[13]; + if (gSprites[task->data[15]].pos2.x == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimTask_ExtremeSpeedMonReappear(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + task->data[4] = 1; + task->data[13] = 14; + task->data[14] = 2; + task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->func = ExtremeSpeedMonReappear_Step; +} + +static void ExtremeSpeedMonReappear_Step(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + if (task->data[0] == 0 && ++task->data[1] > task->data[4]) + { + task->data[1] = 0; + if (++task->data[2] & 1) + gSprites[task->data[15]].invisible = 0; + else + gSprites[task->data[15]].invisible = 1; + + if (++task->data[3] >= task->data[13]) + { + if (++task->data[4] < task->data[14]) + { + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + } + else + { + gSprites[task->data[15]].invisible = 0; + DestroyAnimVisualTask(taskId); + } + } + } +} + +void AnimTask_SpeedDust(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + task->data[0] = 0; + task->data[1] = 4; + task->data[2] = 0; + task->data[3] = 0; + task->data[4] = 0; + task->data[5] = 0; + task->data[6] = 0; + task->data[7] = 0; + task->data[8] = 0; + task->data[13] = 0; + task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, ANIM_ATTACKER); + task->data[15] = GetBattlerSpriteCoord(gBattleAnimAttacker, ANIM_TARGET); + task->func = SpeedDust_Step1; +} + +static void SpeedDust_Step1(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + switch (task->data[8]) + { + case 0: + if (++task->data[4] > 1) + { + task->data[4] = 0; + task->data[5] = (task->data[5] + 1) & 1; + if (++task->data[6] > 20) + { + if (task->data[7] == 0) + { + task->data[6] = 0; + task->data[8] = 1; + } + else + task->data[8] = 2; + } + } + break; + case 1: + task->data[5] = 0; + if (++task->data[4] > 20) + { + task->data[7] = 1; + task->data[8] = 0; + } + break; + case 2: + task->data[5] = 1; + break; + } + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 4) + { + u8 spriteId; + task->data[1] = 0; + spriteId = CreateSprite(&gSpeedDustSpriteTemplate, task->data[14], task->data[15], 0); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].data[0] = taskId; + gSprites[spriteId].data[1] = 13; + gSprites[spriteId].pos2.x = gSpeedDustPosTable[task->data[2]][0]; + gSprites[spriteId].pos2.y = gSpeedDustPosTable[task->data[2]][1]; + task->data[13]++; + if (++task->data[2] > 3) + { + task->data[2] = 0; + if (++task->data[3] > 5) + task->data[0]++; + } + } + } + break; + case 1: + if (task->data[13] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimSpeedDust(struct Sprite *sprite) +{ + sprite->invisible = gTasks[sprite->data[0]].data[5]; + if (sprite->animEnded) + { + gTasks[sprite->data[0]].data[sprite->data[1]]--; + DestroySprite(sprite); + } +} + +void sub_80A96B4(u8 taskId) +{ + int i; + u8 paletteNums[3]; + + paletteNums[0] = IndexOfSpritePaletteTag(ANIM_TAG_MUSIC_NOTES_2); + for (i = 1; i < 3; i++) + paletteNums[i] = AllocSpritePalette(ANIM_SPRITES_START - i); + + gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000); + LZDecompressWram(gBattleAnimSpritePal_MusicNotes2, gMonSpritesGfxPtr->field_17C); + for (i = 0; i < 3; i++) + LoadPalette(&gMonSpritesGfxPtr->field_17C[i * 32], (u16)((paletteNums[i] << 4) + 0x100), 32); + + FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C); + DestroyAnimVisualTask(taskId); +} + +void sub_80A9760(u8 taskId) +{ + int i; + for (i = 0; i < 3; i++) + FreeSpritePaletteByTag(gMusicNotePaletteTagsTable[i]); + + DestroyAnimVisualTask(taskId); +} + +static void SetMusicNotePalette(struct Sprite *sprite, u8 a, u8 b) +{ + u8 tile; + tile = (b & 1); + tile = ((-tile | tile) >> 31) & 32; + sprite->oam.tileNum += tile + (a << 2); + sprite->oam.paletteNum = IndexOfSpritePaletteTag(gMusicNotePaletteTagsTable[b >> 1]); +} + +void AnimHealBellMusicNote(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, FALSE); + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + gBattleAnimArgs[3]; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + SetMusicNotePalette(sprite, gBattleAnimArgs[5], gBattleAnimArgs[6]); +} + +void AnimMagentaHeart(struct Sprite *sprite) +{ + if (++sprite->data[0] == 1) + InitSpritePosToAnimAttacker(sprite, FALSE); + + sprite->pos2.x = Sin(sprite->data[1], 8); + sprite->pos2.y = sprite->data[2] >> 8; + sprite->data[1] = (sprite->data[1] + 7) & 0xFF; + sprite->data[2] -= 0x80; + if (sprite->data[0] == 60) + DestroyAnimSprite(sprite); +} + +void AnimTask_FakeOut(u8 taskId) +{ + u16 win0h = IsContest() ? 0x98 : 0xF0; + u16 win0v = 0; + + gBattle_WIN0H = win0h; + gBattle_WIN0V = 0xA0; + SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H); + SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V); + SetGpuReg(REG_OFFSET_WININ, 0x3F1F); + SetGpuReg(REG_OFFSET_WINOUT, 0x3F3F); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_DARKEN); + SetGpuReg(REG_OFFSET_BLDY, 0x10); + gTasks[taskId].data[0] = win0v; + gTasks[taskId].data[1] = win0h; + gTasks[taskId].func = FakeOutStep1; +} + +static void FakeOutStep1(u8 taskId) +{ + gTasks[taskId].data[0] += 13; + gTasks[taskId].data[1] -= 13; + if (gTasks[taskId].data[0] >= gTasks[taskId].data[1]) + { + gBattle_WIN0H = 0; + gTasks[taskId].func = FakeOutStep2; + } + else + { + gBattle_WIN0H = gTasks[taskId].data[1] | (gTasks[taskId].data[0] << 8); + } +} + +static void FakeOutStep2(u8 taskId) +{ + if (++gTasks[taskId].data[10] == 5) + { + gTasks[taskId].data[11] = 0x88; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_LIGHTEN); + BlendPalettes(sub_80A75AC(1, 0, 0, 0, 0, 0, 0), 16, RGB(31, 31, 31)); + } + else if (gTasks[taskId].data[10] > 4) + { + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + DestroyAnimVisualTask(taskId); + } +} + +void sub_80A9A20(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); + if (++gTasks[taskId].data[0] == 1) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(1), gUnknown_83E4200); + gSprites[spriteId].pos2.x = 4; + } + else + { + gSprites[spriteId].pos2.x = -gSprites[spriteId].pos2.x; + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + { + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + } + } +} + +void sub_80A9AB0(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + if (++gTasks[taskId].data[0] == 1) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), gUnknown_83E4200); + gSprites[spriteId].pos2.x = 4; + } + else + { + gSprites[spriteId].pos2.x = -gSprites[spriteId].pos2.x; + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + { + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + } + } +} + +void AnimRedHeartProjectile(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, TRUE); + sprite->data[0] = 95; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + InitAnimLinearTranslation(sprite); + sprite->callback = AnimRedHeartProjectile_Step; +} + +static void AnimRedHeartProjectile_Step(struct Sprite *sprite) +{ + if (!AnimTranslateLinear(sprite)) + { + sprite->pos2.y += Sin(sprite->data[5], 14); + sprite->data[5] = (sprite->data[5] + 4) & 0xFF; + } + else + { + DestroyAnimSprite(sprite); + } +} + +void AnimParticuleBurst(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + sprite->data[1] = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[0]++; + } + else + { + sprite->data[4] += sprite->data[1]; + sprite->pos2.x = sprite->data[4] >> 8; + sprite->pos2.y = Sin(sprite->data[3], sprite->data[2]); + sprite->data[3] = (sprite->data[3] + 3) & 0xFF; + if (sprite->data[3] > 100) + sprite->invisible = sprite->data[3] % 2; + + if (sprite->data[3] > 120) + DestroyAnimSprite(sprite); + } +} + +void AnimRedHeartRising(struct Sprite *sprite) +{ + sprite->pos1.x = gBattleAnimArgs[0]; + sprite->pos1.y = 160; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData6(sprite, AnimRedHeartRising_Step); +} + +static void AnimRedHeartRising_Step(struct Sprite *sprite) +{ + s16 y; + sprite->data[2] += sprite->data[1]; + sprite->pos2.y = -((u16)sprite->data[2] >> 8); + sprite->pos2.x = Sin(sprite->data[3], 4); + sprite->data[3] = (sprite->data[3] + 3) & 0xFF; + y = sprite->pos1.y + sprite->pos2.y; + if (y <= 72) + { + sprite->invisible = sprite->data[3] % 2; + if (y <= 64) + DestroyAnimSprite(sprite); + } +} + +void AnimTask_HeartsBackground(u8 taskId) +{ + struct BattleAnimBgData animBg; + + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 3); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X); + SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y); + sub_80752A0(&animBg); + AnimLoadCompressedBgGfx(animBg.bgId, &gUnknown_08C232E0, animBg.tilesOffset); + sub_80A6D60(&animBg, &gUnknown_08C23D78, 0); + LoadCompressedPalette(&gUnknown_08C23D50, animBg.paletteId * 16, 32); + gTasks[taskId].func = HeartsBackground_Step; +} + +static void HeartsBackground_Step(u8 taskId) +{ + struct BattleAnimBgData animBg; + + switch (gTasks[taskId].data[12]) + { + case 0: + if (++gTasks[taskId].data[10] == 4) + { + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[11]++; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11])); + if (gTasks[taskId].data[11] == 16) + { + gTasks[taskId].data[12]++; + gTasks[taskId].data[11] = 0; + } + } + break; + case 1: + if (++gTasks[taskId].data[11] == 141) + { + gTasks[taskId].data[11] = 16; + gTasks[taskId].data[12]++; + } + break; + case 2: + if (++gTasks[taskId].data[10] == 4) + { + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[11]--; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11])); + if (gTasks[taskId].data[11] == 0) + { + gTasks[taskId].data[12]++; + gTasks[taskId].data[11] = 0; + } + } + break; + case 3: + sub_80752A0(&animBg); + sub_8075358(animBg.bgId); + gTasks[taskId].data[12]++; + break; + case 4: + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimTask_ScaryFace(u8 taskId) +{ + struct BattleAnimBgData animBg; + + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X); + SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y); + sub_80752A0(&animBg); + if (IsContest()) + sub_80A6D60(&animBg, &gBattleAnimBgTilemap_ScaryFaceContest, 0); + else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) + sub_80A6D60(&animBg, &gBattleAnimBgTilemap_ScaryFacePlayer, 0); + else + sub_80A6D60(&animBg, &gBattleAnimBgTilemap_ScaryFaceOpponent, 0); + + AnimLoadCompressedBgGfx(animBg.bgId, gUnknown_08C249F8, animBg.tilesOffset); + LoadCompressedPalette(gUnknown_08C249D0, animBg.paletteId * 16, 32); + gTasks[taskId].func = ScaryFace_Step; +} + +static void ScaryFace_Step(u8 taskId) +{ + struct BattleAnimBgData animBg; + + switch (gTasks[taskId].data[12]) + { + case 0: + if (++gTasks[taskId].data[10] == 2) + { + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[11]++; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11])); + if (gTasks[taskId].data[11] == 14) + { + gTasks[taskId].data[12]++; + gTasks[taskId].data[11] = 0; + } + } + break; + case 1: + if (++gTasks[taskId].data[11] == 21) + { + gTasks[taskId].data[11] = 14; + gTasks[taskId].data[12]++; + } + break; + case 2: + if (++gTasks[taskId].data[10] == 2) + { + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[11]--; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11])); + if (gTasks[taskId].data[11] == 0) + { + gTasks[taskId].data[12]++; + gTasks[taskId].data[11] = 0; + } + } + break; + case 3: + sub_80752A0(&animBg); + sub_8075358(1); + sub_8075358(2); + gTasks[taskId].data[12]++; + // fall through + case 4: + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + DestroyAnimVisualTask(taskId); + break; + } +} + +// Orbits a sphere in an ellipse around the mon. +// Used by MOVE_HIDDEN_POWER +// arg 0: duration +// arg 1: initial wave offset +void AnimOrbitFast(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->affineAnimPaused = 1; + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->data[7] = GetBattlerSpriteSubpriority(gBattleAnimAttacker); + sprite->callback = AnimOrbitFastStep; + sprite->callback(sprite); +} + +static void AnimOrbitFastStep(struct Sprite *sprite) +{ + if (sprite->data[1] >= 64 && sprite->data[1] <= 191) + sprite->subpriority = sprite->data[7] + 1; + else + sprite->subpriority = sprite->data[7] - 1; + + sprite->pos2.x = Sin(sprite->data[1], sprite->data[2] >> 8); + sprite->pos2.y = Cos(sprite->data[1], sprite->data[3] >> 8); + sprite->data[1] = (sprite->data[1] + 9) & 0xFF; + switch (sprite->data[5]) + { + case 1: + sprite->data[2] -= 0x400; + sprite->data[3] -= 0x100; + if (++sprite->data[4] == sprite->data[0]) + { + sprite->data[5] = 2; + return; + } + break; + case 0: + sprite->data[2] += 0x400; + sprite->data[3] += 0x100; + if (++sprite->data[4] == sprite->data[0]) + { + sprite->data[4] = 0; + sprite->data[5] = 1; + } + break; + } + + if ((u16)gBattleAnimArgs[7] == 0xFFFF) + DestroyAnimSprite(sprite); +} + +// Moves orbs away from the mon, based on where they are in their orbit. +// Used in MOVE_HIDDEN_POWER. +// arg 0: initial wave offset +void AnimOrbitScatter(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[0] = Sin(gBattleAnimArgs[0], 10); + sprite->data[1] = Cos(gBattleAnimArgs[0], 7); + sprite->callback = AnimOrbitScatterStep; +} + +static void AnimOrbitScatterStep(struct Sprite *sprite) +{ + sprite->pos2.x += sprite->data[0]; + sprite->pos2.y += sprite->data[1]; + if (sprite->pos1.x + sprite->pos2.x + 16 > 272u || sprite->pos1.y + sprite->pos2.y > 160 || sprite->pos1.y + sprite->pos2.y < -16) + DestroyAnimSprite(sprite); +} + +static void AnimSpitUpOrb_Step(struct Sprite *sprite) +{ + sprite->pos2.x += sprite->data[0]; + sprite->pos2.y += sprite->data[1]; + if (sprite->data[3]++ >= sprite->data[2]) + DestroyAnimSprite(sprite); +} + +void AnimSpitUpOrb(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[0] = Sin(gBattleAnimArgs[0], 10); + sprite->data[1] = Cos(gBattleAnimArgs[0], 7); + sprite->data[2] = gBattleAnimArgs[1]; + sprite->callback = AnimSpitUpOrb_Step; +} + +static void sub_80AA3D4(struct Sprite *sprite) +{ + if (sprite->animEnded) + DestroyAnimSprite(sprite); +} + +void AnimEyeSparkle(struct Sprite *sprite) +{ + InitSpritePosToAnimAttacker(sprite, TRUE); + sprite->callback = sub_80AA3D4; +} + +void AnimAngel(struct Sprite *sprite) +{ + s16 var0; + if (!sprite->data[0]) + { + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + } + + sprite->data[0]++; + var0 = (sprite->data[0] * 10) & 0xFF; + sprite->pos2.x = Sin(var0, 80) >> 8; + if (sprite->data[0] < 80) + sprite->pos2.y = (sprite->data[0] / 2) + (Cos(var0, 80) >> 8); + + if (sprite->data[0] > 90) + { + sprite->data[2]++; + sprite->pos2.x -= sprite->data[2] / 2; + } + + if (sprite->data[0] > 100) + DestroyAnimSprite(sprite); +} + +static void sub_80AA49C(struct Sprite *sprite) +{ + sprite->data[5]++; + sprite->pos2.x = Sin(sprite->data[3], 5); + sprite->pos2.y = sprite->data[5] / 2; + sprite->data[3] = (sprite->data[3] + 3) & 0xFF; + if (sprite->data[5] > 20) + sprite->invisible = sprite->data[5] % 2; + + if (sprite->data[5] > 30) + DestroyAnimSprite(sprite); +} + +void AnimPinkHeart(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + sprite->data[1] = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[0]++; + } + else + { + sprite->data[4] += sprite->data[1]; + sprite->pos2.x = sprite->data[4] >> 8; + sprite->pos2.y = Sin(sprite->data[3], sprite->data[2]); + sprite->data[3] = (sprite->data[3] + 3) & 0xFF; + if (sprite->data[3] > 70) + { + sprite->callback = sub_80AA49C; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data[3] = Random2() % 180; + } + } +} + +void AnimDevil(struct Sprite *sprite) +{ + if (sprite->data[3] == 0) + { + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + StartSpriteAnim(sprite, 0); + sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 1; + sprite->data[2] = 1; + } + sprite->data[0] += sprite->data[2]; + sprite->data[1] = (sprite->data[0] * 4) % 256; + if (sprite->data[1] < 0) + sprite->data[1] = 0; + sprite->pos2.x = Cos(sprite->data[1], 30 - sprite->data[0] / 4); + sprite->pos2.y = Sin(sprite->data[1], 10 - sprite->data[0] / 8); + if (sprite->data[1] > 128 && sprite->data[2] > 0) + sprite->data[2] = -1; + if (sprite->data[1] == 0 && sprite->data[2] < 0) + sprite->data[2] = 1; + sprite->data[3]++; + if (sprite->data[3] < 10 || sprite->data[3] > 80) + sprite->invisible = sprite->data[0] % 2; + else + sprite->invisible = FALSE; + if (sprite->data[3] > 90) + DestroyAnimSprite(sprite); +} + +void AnimFurySwipes(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + StartSpriteAnim(sprite, gBattleAnimArgs[2]); + sprite->data[0]++; + } + else if (sprite->animEnded) + { + DestroyAnimSprite(sprite); + } +} + +void AnimMovmentWaves(struct Sprite *sprite) +{ + if (!gBattleAnimArgs[2]) + { + DestroyAnimSprite(sprite); + } + else + { + if (!gBattleAnimArgs[0]) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + } + + if (!gBattleAnimArgs[1]) + sprite->pos1.x += 32; + else + sprite->pos1.x -= 32; + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[1]; + StartSpriteAnim(sprite, sprite->data[1]); + sprite->callback = AnimMovmentWaves_Step; + } +} + +static void AnimMovmentWaves_Step(struct Sprite *sprite) +{ + if (sprite->animEnded) + { + if (--sprite->data[0]) + StartSpriteAnim(sprite, sprite->data[1]); + else + DestroyAnimSprite(sprite); + } +} + +void AnimTask_UproarDistortion(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + + PrepareAffineAnimInTaskData(&gTasks[taskId], spriteId, gUnknown_08593B98); + gTasks[taskId].func = UproarDistortion_Step; +} + +static void UproarDistortion_Step(u8 taskId) +{ + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); +} + +void AnimJaggedMusicNote(struct Sprite *sprite) +{ + int var1; + u8 battler = !gBattleAnimArgs[0] ? gBattleAnimAttacker : gBattleAnimTarget; + + if (GetBattlerSide(battler) == B_SIDE_OPPONENT) + gBattleAnimArgs[1] *= -1; + + sprite->pos1.x = GetBattlerSpriteCoord(battler, 2) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(battler, 3) + gBattleAnimArgs[2]; + sprite->data[0] = 0; + sprite->data[1] = (u16)sprite->pos1.x << 3; + sprite->data[2] = (u16)sprite->pos1.y << 3; + + var1 = gBattleAnimArgs[1] << 3; + if (var1 < 0) + var1 += 7; + sprite->data[3] = var1 >> 3; + + var1 = gBattleAnimArgs[2] << 3; + if (var1 < 0) + var1 += 7; + sprite->data[4] = var1 >> 3; + + sprite->oam.tileNum += gBattleAnimArgs[3] * 16; + sprite->callback = AnimJaggedMusicNote_Step; +} + +static void AnimJaggedMusicNote_Step(struct Sprite *sprite) +{ + sprite->data[1] += sprite->data[3]; + sprite->data[2] += sprite->data[4]; + sprite->pos1.x = sprite->data[1] >> 3; + sprite->pos1.y = sprite->data[2] >> 3; + if (++sprite->data[0] > 16) + DestroyAnimSprite(sprite); +} + +void AnimPerishSongMusicNote2(struct Sprite *sprite) +{ + if (!sprite->data[0]) + { + sprite->data[1] = 120 - gBattleAnimArgs[0]; + sprite->invisible = 1; + } + + if (++sprite->data[0] == sprite->data[1]) + SetGreyscaleOrOriginalPalette(sprite->oam.paletteNum + 16, 0); + + if (sprite->data[0] == sprite->data[1] + 80) + DestroyAnimSprite(sprite); +} + +void AnimPerishSongMusicNote(struct Sprite *sprite) +{ + int index; + int var2; + + if (!sprite->data[0]) + { + sprite->pos1.x = 120; + sprite->pos1.y = (gBattleAnimArgs[0] + (((u16)gBattleAnimArgs[0]) >> 31)) / 2 - 15; + + StartSpriteAnim(sprite, gBattleAnimArgs[1]); + + sprite->data[5] = 120; + sprite->data[3] = gBattleAnimArgs[2]; + } + + sprite->data[0]++; + + sprite->data[1] = (sprite->data[0] + ((u16)sprite->data[0] >> 31)) / 2; + index = ((sprite->data[0] * 3) + (u16)sprite->data[3]); + var2 = 0xFF; + sprite->data[6] = (sprite->data[6] + 10) & 0xFF; + + index &= var2; + sprite->pos2.x = Cos(index, 100); + + sprite->pos2.y = sprite->data[1] + Sin(index, 10) + Cos(sprite->data[6], 4); + + if (sprite->data[0] > sprite->data[5]) + { + sprite->callback = AnimPerishSongMusicNote_Step1; + + sprite->data[0] = 0; + SetSpritePrimaryCoordsFromSecondaryCoords(sprite); + sprite->data[2] = 5; + sprite->data[4] = 0; + sprite->data[3] = 0; + + StartSpriteAffineAnim(sprite, 1); + } +} + +static void AnimPerishSongMusicNote_Step1(struct Sprite *sprite) +{ + if (++sprite->data[0] > 10) + { + sprite->data[0] = 0; + sprite->callback = AnimPerishSongMusicNote_Step2; + } +} + +static void AnimPerishSongMusicNote_Step2(struct Sprite *sprite) +{ + sprite->data[3] += sprite->data[2]; + sprite->pos2.y = sprite->data[3]; + + sprite->data[2]++; + + if (sprite->data[3] > 48 && sprite->data[2] > 0) + { + sprite->data[2] = sprite->data[4] - 5; + sprite->data[4]++; + } + + if (sprite->data[4] > 3) + { + int var1 = sprite->data[2]; + sprite->invisible = var1 - (((s32)(var1 + ((u32)var1 >> 31)) >> 1) << 1); + DestroyAnimSprite(sprite); + } + + if (sprite->data[4] == 4) + { + DestroyAnimSprite(sprite); + } +} + +void AnimGuardRing(struct Sprite *sprite) +{ + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + { + SetAverageBattlerPositions(gBattleAnimAttacker, 0, &sprite->pos1.x, &sprite->pos1.y); + sprite->pos1.y += 40; + + StartSpriteAffineAnim(sprite, 1); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 40; + } + + sprite->data[0] = 13; + sprite->data[2] = sprite->pos1.x; + sprite->data[4] = sprite->pos1.y - 72; + + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void AnimTask_IsFuryCutterHitRight(u8 taskId) +{ + gBattleAnimArgs[7] = gAnimDisableStructPtr->furyCutterCounter & 1; + DestroyAnimVisualTask(taskId); +} + +void AnimTask_GetFuryCutterHitCount(u8 taskId) +{ + gBattleAnimArgs[7] = gAnimDisableStructPtr->furyCutterCounter; + DestroyAnimVisualTask(taskId); +} diff --git a/src/battle_anim_effects_3.c b/src/battle_anim_effects_3.c new file mode 100644 index 000000000..89f66139f --- /dev/null +++ b/src/battle_anim_effects_3.c @@ -0,0 +1,5495 @@ +#include "global.h" +#include "malloc.h" +#include "battle.h" +#include "battle_anim.h" +#include "bg.h" +#include "contest.h" +#include "data.h" +#include "decompress.h" +#include "dma3.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "palette.h" +#include "pokemon_icon.h" +#include "random.h" +#include "scanline_effect.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "util.h" +#include "constants/battle_anim.h" +#include "constants/rgb.h" +#include "constants/songs.h" +#include "constants/species.h" +#include "constants/weather.h" + +extern const struct SpriteTemplate gThoughtBubbleSpriteTemplate; + +void AnimBlackSmoke(struct Sprite *); +void AnimWhiteHalo(struct Sprite *); +void AnimTealAlert(struct Sprite *); +void AnimMeanLookEye(struct Sprite *); +void AnimSpikes(struct Sprite *); +void AnimLeer(struct Sprite *); +void AnimLetterZ(struct Sprite *); +void AnimFang(struct Sprite *); +void AnimSpotlight(struct Sprite *); +void AnimClappingHand(struct Sprite *); +void AnimClappingHand2(struct Sprite *); +void AnimRapidSpin(struct Sprite *); +void AnimTriAttackTriangle(struct Sprite *); +void AnimBatonPassPokeball(struct Sprite *); +void AnimWishStar(struct Sprite *); +void AnimMiniTwinklingStar(struct Sprite *); +void AnimSwallowBlueOrb(struct Sprite *); +void AnimGreenStar(struct Sprite *); +void AnimWeakFrustrationAngerMark(struct Sprite *); +void AnimSweetScentPetal(struct Sprite *); +void AnimPainSplitProjectile(struct Sprite *); +void AnimFlatterConfetti(struct Sprite *); +void AnimFlatterSpotlight(struct Sprite *); +void AnimReversalOrb(struct Sprite *); +void AnimYawnCloud(struct Sprite *); +void AnimSmokeBallEscapeCloud(struct Sprite *); +void AnimFacadeSweatDrop(struct Sprite *); +void AnimRoarNoiseLine(struct Sprite *); +void AnimGlareEyeDot(struct Sprite *); +void AnimAssistPawprint(struct Sprite *); +void AnimSmellingSaltsHand(struct Sprite *); +void AnimSmellingSaltExclamation(struct Sprite *); +void AnimHelpingHandClap(struct Sprite *); +void AnimForesightMagnifyingGlass(struct Sprite *); +void AnimMeteorMashStar(struct Sprite *); +void AnimBlockX(struct Sprite *); +void sub_80E3E84(struct Sprite *); +void AnimParticuleBurst(struct Sprite *); +void AnimKnockOffStrike(struct Sprite *); +void AnimRecycle(struct Sprite *); +static void AnimBlackSmokeStep(struct Sprite *); +static void AnimWhiteHalo_Step1(struct Sprite *); +static void AnimWhiteHalo_Step2(struct Sprite *); +static void AnimMeanLookEye_Step1(struct Sprite *); +static void AnimMeanLookEye_Step2(struct Sprite *); +static void AnimMeanLookEye_Step3(struct Sprite *); +static void AnimMeanLookEye_Step4(struct Sprite *); +static void SetPsychicBackground_Step(u8); +static void FadeScreenToWhite_Step(u8); +static void AnimSpikes_Step1(struct Sprite *); +static void AnimSpikes_Step2(struct Sprite *); +static void AnimSpotlight_Step1(struct Sprite *); +static void AnimSpotlight_Step2(struct Sprite *); +static void AnimClappingHand_Step(struct Sprite *); +static void AnimRapidSpin_Step(struct Sprite *); +static void RapinSpinMonElevation_Step(u8); +static void TormentAttacker_Step(u8); +static void TormentAttacker_Callback(struct Sprite *); +static void AnimWishStar_Step(struct Sprite *); +static void AnimMiniTwinklingStar_Step(struct Sprite *); +static void AnimGreenStar_Step1(struct Sprite *); +static void AnimGreenStar_Step2(struct Sprite *); +static void AnimGreenStar_Callback(struct Sprite *); +static void AnimTask_RockMonBackAndForthStep(u8); +static void AnimSweetScentPetalStep(struct Sprite *); +static void AnimTask_FlailMovementStep(u8); +static void AnimFlatterConfettiStep(struct Sprite *); +static void AnimFlatterSpotlightStep(struct Sprite *); +static void AnimReversalOrbStep(struct Sprite *); +static void AnimTask_RolePlaySilhouetteStep1(u8); +static void AnimTask_RolePlaySilhouetteStep2(u8); +static void AnimTask_AcidArmorStep(u8); +static void AnimTask_DeepInhaleStep(u8); +static void AnimYawnCloudStep(struct Sprite *); +static void AnimTask_SquishAndSweatDropletsStep(u8); +static void CreateSweatDroplets(u8, bool8); +static void AnimTask_FacadeColorBlendStep(u8); +static void AnimRoarNoiseLineStep(struct Sprite *); +static void AnimTask_GlareEyeDotsStep(u8); +static void GetGlareEyeDotCoords(s16, s16, s16, s16, u8, u8, s16 *, s16 *); +static void AnimTask_BarrageBallStep(u8); +static void AnimSmellingSaltsHand_Step(struct Sprite *); +static void AnimTask_SmellingSaltsSquishStep(u8); +static void AnimSmellingSaltExclamationStep(struct Sprite *); +static void AnimHelpingHandClapStep(struct Sprite *); +static void AnimTask_HelpingHandAttackerMovementStep(u8); +static void AnimForesightMagnifyingGlassStep(struct Sprite *); +static void AnimTask_MonToSubstituteDoll(u8); +static void AnimBlockXStep(struct Sprite *); +static void AnimTask_OdorSleuthMovementWaitFinish(u8); +static void MoveOdorSleuthClone(struct Sprite *); +static void AnimTask_TeeterDanceMovementStep(u8); +static void AnimRecycleStep(struct Sprite *); +static void AnimTask_SlackOffSquishStep(u8); +const union AnimCmd gScratchAnimCmds[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(16, 4), + ANIMCMD_FRAME(32, 4), + ANIMCMD_FRAME(48, 4), + ANIMCMD_FRAME(64, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gScratchAnimTable[] = +{ + gScratchAnimCmds, +}; + +const struct SpriteTemplate gScratchSpriteTemplate = +{ + .tileTag = ANIM_TAG_SCRATCH, + .paletteTag = ANIM_TAG_SCRATCH, + .oam = &gOamData_AffineOff_ObjBlend_32x32, + .anims = gScratchAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const struct SpriteTemplate gBlackSmokeSpriteTemplate = +{ + .tileTag = ANIM_TAG_BLACK_SMOKE, + .paletteTag = ANIM_TAG_BLACK_SMOKE, + .oam = &gOamData_AffineOff_ObjNormal_32x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimBlackSmoke, +}; + +const struct SpriteTemplate gBlackBallSpriteTemplate = +{ + .tileTag = ANIM_TAG_BLACK_BALL, + .paletteTag = ANIM_TAG_BLACK_BALL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimThrowProjectile, +}; + +const union AnimCmd gOpeningEyeAnimCmds[] = +{ + ANIMCMD_FRAME(0, 40), + ANIMCMD_FRAME(16, 8), + ANIMCMD_FRAME(32, 40), + ANIMCMD_END, +}; + +const union AnimCmd *const gOpeningEyeAnimTable[] = +{ + gOpeningEyeAnimCmds, +}; + +const struct SpriteTemplate gOpeningEyeSpriteTemplate = +{ + .tileTag = ANIM_TAG_OPENING_EYE, + .paletteTag = ANIM_TAG_OPENING_EYE, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gOpeningEyeAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const struct SpriteTemplate gWhiteHaloSpriteTemplate = +{ + .tileTag = ANIM_TAG_ROUND_WHITE_HALO, + .paletteTag = ANIM_TAG_ROUND_WHITE_HALO, + .oam = &gOamData_AffineOff_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimWhiteHalo, +}; + +const struct SpriteTemplate gTealAlertSpriteTemplate = +{ + .tileTag = ANIM_TAG_TEAL_ALERT, + .paletteTag = ANIM_TAG_TEAL_ALERT, + .oam = &gOamData_AffineNormal_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimTealAlert, +}; + +const union AffineAnimCmd gMeanLookEyeAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x180, 0x180, 0, 0), + AFFINEANIMCMD_FRAME(-0x20, 0x18, 0, 5), + AFFINEANIMCMD_FRAME(0x18, -0x20, 0, 5), + AFFINEANIMCMD_JUMP(1), +}; + +const union AffineAnimCmd gMeanLookEyeAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x30, 0x30, 0, 0), + AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 6), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gMeanLookEyeAffineAnimTable[] = +{ + gMeanLookEyeAffineAnimCmds1, + gMeanLookEyeAffineAnimCmds2, +}; + +const struct SpriteTemplate gMeanLookEyeSpriteTemplate = +{ + .tileTag = ANIM_TAG_EYE, + .paletteTag = ANIM_TAG_EYE, + .oam = &gOamData_AffineDouble_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gMeanLookEyeAffineAnimTable, + .callback = AnimMeanLookEye, +}; + +const struct SpriteTemplate gSpikesSpriteTemplate = +{ + .tileTag = ANIM_TAG_SPIKES, + .paletteTag = ANIM_TAG_SPIKES, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpikes, +}; + +const union AnimCmd gLeerAnimCmds[] = +{ + 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 gLeerAnimTable[] = +{ + gLeerAnimCmds, +}; + +const struct SpriteTemplate gLeerSpriteTemplate = +{ + .tileTag = ANIM_TAG_LEER, + .paletteTag = ANIM_TAG_LEER, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gLeerAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimLeer, +}; + +const union AnimCmd gLetterZAnimCmds[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_END, +}; + +const union AnimCmd *const gLetterZAnimTable[] = +{ + gLetterZAnimCmds, +}; + +const union AffineAnimCmd gLetterZAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(-7, -7, -3, 16), + AFFINEANIMCMD_FRAME(7, 7, 3, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gLetterZAffineAnimTable[] = +{ + gLetterZAffineAnimCmds, +}; + +const struct SpriteTemplate gLetterZSpriteTemplate = +{ + .tileTag = ANIM_TAG_LETTER_Z, + .paletteTag = ANIM_TAG_LETTER_Z, + .oam = &gOamData_AffineNormal_ObjNormal_32x32, + .anims = gLetterZAnimTable, + .images = NULL, + .affineAnims = gLetterZAffineAnimTable, + .callback = AnimLetterZ, +}; + +const union AnimCmd gFangAnimCmds[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(16, 16), + ANIMCMD_FRAME(32, 4), + ANIMCMD_FRAME(48, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gFangAnimTable[] = +{ + gFangAnimCmds, +}; + +const union AffineAnimCmd gFangAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), + AFFINEANIMCMD_FRAME(-0x20, -0x20, 0, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gFangAffineAnimTable[] = +{ + gFangAffineAnimCmds, +}; + +const struct SpriteTemplate gFangSpriteTemplate = +{ + .tileTag = ANIM_TAG_FANG_ATTACK, + .paletteTag = ANIM_TAG_FANG_ATTACK, + .oam = &gOamData_AffineDouble_ObjNormal_32x32, + .anims = gFangAnimTable, + .images = NULL, + .affineAnims = gFangAffineAnimTable, + .callback = AnimFang, +}; + +const union AffineAnimCmd gSpotlightAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x180, 0, 0), + AFFINEANIMCMD_FRAME(0x10, 0x0, 0, 20), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gSpotlightAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x140, 0x180, 0, 0), + AFFINEANIMCMD_FRAME(-0x10, 0x0, 0, 19), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSpotlightAffineAnimTable[] = +{ + gSpotlightAffineAnimCmds1, + gSpotlightAffineAnimCmds2, +}; + +const struct SpriteTemplate gSpotlightSpriteTemplate = +{ + .tileTag = ANIM_TAG_SPOTLIGHT, + .paletteTag = ANIM_TAG_SPOTLIGHT, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpotlightAffineAnimTable, + .callback = AnimSpotlight, +}; + +const struct SpriteTemplate gClappingHandSpriteTemplate = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimClappingHand, +}; + +const struct SpriteTemplate gClappingHand2SpriteTemplate = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimClappingHand2, +}; + +const union AnimCmd gRapidSpinAnimCmds[] = +{ + ANIMCMD_FRAME(0, 2), + ANIMCMD_FRAME(8, 2), + ANIMCMD_FRAME(16, 2), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd *const gRapidSpinAnimTable[] = +{ + gRapidSpinAnimCmds, +}; + +const struct SpriteTemplate gRapidSpinSpriteTemplate = +{ + .tileTag = ANIM_TAG_RAPID_SPIN, + .paletteTag = ANIM_TAG_RAPID_SPIN, + .oam = &gOamData_AffineOff_ObjNormal_32x16, + .anims = gRapidSpinAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimRapidSpin, +}; + +const union AffineAnimCmd gUnknown_085CE2A0[] = +{ + AFFINEANIMCMD_FRAME(-12, 8, 0, 4), + AFFINEANIMCMD_FRAME(20, -20, 0, 4), + AFFINEANIMCMD_FRAME(-8, 12, 0, 4), + AFFINEANIMCMD_END, +}; + +const union AnimCmd gTriAttackTriangleAnimCmds[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_END, +}; + +const union AnimCmd *const gTriAttackTriangleAnimTable[] = +{ + gTriAttackTriangleAnimCmds, +}; + +const union AffineAnimCmd gTriAttackTriangleAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, 0, 5, 40), + AFFINEANIMCMD_FRAME(0, 0, 10, 10), + AFFINEANIMCMD_FRAME(0, 0, 15, 10), + AFFINEANIMCMD_FRAME(0, 0, 20, 40), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gTriAttackTriangleAffineAnimTable[] = +{ + gTriAttackTriangleAffineAnimCmds, +}; + +const struct SpriteTemplate gTriAttackTriangleSpriteTemplate = +{ + .tileTag = ANIM_TAG_TRI_ATTACK_TRIANGLE, + .paletteTag = ANIM_TAG_TRI_ATTACK_TRIANGLE, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gTriAttackTriangleAnimTable, + .images = NULL, + .affineAnims = gTriAttackTriangleAffineAnimTable, + .callback = AnimTriAttackTriangle, +}; + +const union AnimCmd gEclipsingOrbAnimCmds[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_FRAME(32, 3, .hFlip = TRUE), + ANIMCMD_FRAME(16, 3, .hFlip = TRUE), + ANIMCMD_FRAME(0, 3, .hFlip = TRUE), + ANIMCMD_LOOP(1), + ANIMCMD_END, +}; + +const union AnimCmd *const gEclipsingOrbAnimTable[] = +{ + gEclipsingOrbAnimCmds, +}; + +const struct SpriteTemplate gEclipsingOrbSpriteTemplate = +{ + .tileTag = ANIM_TAG_ECLIPSING_ORB, + .paletteTag = ANIM_TAG_ECLIPSING_ORB, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gEclipsingOrbAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const union AffineAnimCmd DefenseCurlDeformMonAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(-12, 20, 0, 8), + AFFINEANIMCMD_FRAME(12, -20, 0, 8), + AFFINEANIMCMD_LOOP(2), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gBatonPassPokeballSpriteTemplate = +{ + .tileTag = ANIM_TAG_POKEBALL, + .paletteTag = ANIM_TAG_POKEBALL, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimBatonPassPokeball, +}; + +const struct SpriteTemplate gWishStarSpriteTemplate = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimWishStar, +}; + +const struct SpriteTemplate gMiniTwinklingStarSpriteTemplate = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMiniTwinklingStar, +}; + +const union AffineAnimCmd gStockpileDeformMonAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(8, -8, 0, 12), + AFFINEANIMCMD_FRAME(-16, 16, 0, 12), + AFFINEANIMCMD_FRAME(8, -8, 0, 12), + AFFINEANIMCMD_LOOP(1), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gSpitUpDeformMonAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, 6, 0, 20), + AFFINEANIMCMD_FRAME(0, 0, 0, 20), + AFFINEANIMCMD_FRAME(0, -18, 0, 6), + AFFINEANIMCMD_FRAME(-18, -18, 0, 3), + AFFINEANIMCMD_FRAME(0, 0, 0, 15), + AFFINEANIMCMD_FRAME(4, 4, 0, 13), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gSwallowBlueOrbSpriteTemplate = +{ + .tileTag = ANIM_TAG_BLUE_ORB, + .paletteTag = ANIM_TAG_BLUE_ORB, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSwallowBlueOrb, +}; + +const union AffineAnimCmd gSwallowDeformMonAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, 6, 0, 20), + AFFINEANIMCMD_FRAME(0, 0, 0, 20), + AFFINEANIMCMD_FRAME(7, -30, 0, 6), + AFFINEANIMCMD_FRAME(0, 0, 0, 20), + AFFINEANIMCMD_FRAME(-2, 3, 0, 20), + AFFINEANIMCMD_END, +}; + +const s8 gMorningSunLightBeamCoordsTable[] = +{ + 0xE8, + 0x18, + 0xFC, + 0x00, +}; + +const union AnimCmd gGreenStarAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 6), + ANIMCMD_FRAME(4, 6), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gGreenStarAnimCmds2[] = +{ + ANIMCMD_FRAME(8, 6), + ANIMCMD_END, +}; + +const union AnimCmd gGreenStarAnimCmds3[] = +{ + ANIMCMD_FRAME(12, 6), + ANIMCMD_END, +}; + +const union AnimCmd *const gGreenStarAnimTable[] = +{ + gGreenStarAnimCmds1, + gGreenStarAnimCmds2, + gGreenStarAnimCmds3, +}; + +const struct SpriteTemplate gGreenStarSpriteTemplate = +{ + .tileTag = ANIM_TAG_GREEN_STAR, + .paletteTag = ANIM_TAG_GREEN_STAR, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gGreenStarAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimGreenStar, +}; + +const s8 gDoomDesireLightBeamCoordTable[] = +{ + 0x78, + 0x50, + 0x28, + 0x00, +}; + +const u8 gDoomDesireLightBeamDelayTable[] = +{ + 0, + 0, + 0, + 0, + 50, +}; + +const union AffineAnimCmd gStrongFrustrationAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, -15, 0, 7), + AFFINEANIMCMD_FRAME(0, 15, 0, 7), + AFFINEANIMCMD_LOOP(2), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gWeakFrustrationAngerMarkSpriteTemplate = +{ + .tileTag = ANIM_TAG_ANGER, + .paletteTag = ANIM_TAG_ANGER, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimWeakFrustrationAngerMark, +}; + +const union AnimCmd gSweetScentPetalAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(1, 8), + ANIMCMD_FRAME(2, 8), + ANIMCMD_FRAME(3, 8), + ANIMCMD_FRAME(3, 8, .vFlip = TRUE), + ANIMCMD_FRAME(2, 8, .vFlip = TRUE), + ANIMCMD_FRAME(0, 8, .vFlip = TRUE), + ANIMCMD_FRAME(1, 8, .vFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSweetScentPetalAnimCmds2[] = +{ + ANIMCMD_FRAME(0, 8, .hFlip = TRUE), + ANIMCMD_FRAME(1, 8, .hFlip = TRUE), + ANIMCMD_FRAME(2, 8, .hFlip = TRUE), + ANIMCMD_FRAME(3, 8, .hFlip = TRUE), + ANIMCMD_FRAME(3, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(2, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(0, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(1, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSweetScentPetalAnimCmds3[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_END, +}; + +const union AnimCmd *const gSweetScentPetalAnimCmdTable[] = +{ + gSweetScentPetalAnimCmds1, + gSweetScentPetalAnimCmds2, + gSweetScentPetalAnimCmds3, +}; + +const struct SpriteTemplate gSweetScentPetalSpriteTemplate = +{ + .tileTag = ANIM_TAG_PINK_PETAL, + .paletteTag = ANIM_TAG_PINK_PETAL, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gSweetScentPetalAnimCmdTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSweetScentPetal, +}; + +const u16 gUnknown_085CE55C[] = INCBIN_U16("graphics/unknown/unknown_85CE55C.gbapal"); + +const union AnimCmd gPainSplitAnimCmds[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(4, 9), + ANIMCMD_FRAME(8, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gPainSplitAnimCmdTable[] = +{ + gPainSplitAnimCmds, +}; + +const struct SpriteTemplate gPainSplitProjectileSpriteTemplate = +{ + .tileTag = ANIM_TAG_PAIN_SPLIT, + .paletteTag = ANIM_TAG_PAIN_SPLIT, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gPainSplitAnimCmdTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimPainSplitProjectile, +}; + +const struct SpriteTemplate gFlatterConfettiSpriteTemplate = +{ + .tileTag = ANIM_TAG_CONFETTI, + .paletteTag = ANIM_TAG_CONFETTI, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimFlatterConfetti, +}; + +const struct SpriteTemplate gFlatterSpotlightSpriteTemplate = +{ + .tileTag = ANIM_TAG_SPOTLIGHT, + .paletteTag = ANIM_TAG_SPOTLIGHT, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpotlightAffineAnimTable, + .callback = AnimFlatterSpotlight, +}; + +const struct SpriteTemplate gReversalOrbSpriteTemplate = +{ + .tileTag = ANIM_TAG_BLUE_ORB, + .paletteTag = ANIM_TAG_BLUE_ORB, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimReversalOrb, +}; + +const union AffineAnimCmd gDeepInhaleAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(16, 0, 0, 4), + AFFINEANIMCMD_FRAME(0, -3, 0, 16), + AFFINEANIMCMD_FRAME(4, 0, 0, 4), + AFFINEANIMCMD_FRAME(0, 0, 0, 24), + AFFINEANIMCMD_FRAME(-5, 3, 0, 16), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gYawnCloudAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(-8, -8, 0, 8), + AFFINEANIMCMD_FRAME(8, 8, 0, 8), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gYawnCloudAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0), + AFFINEANIMCMD_FRAME(8, 8, 0, 8), + AFFINEANIMCMD_FRAME(-8, -8, 0, 8), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gYawnCloudAffineAnimCmds3[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(8, 8, 0, 8), + AFFINEANIMCMD_FRAME(-8, -8, 0, 8), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gYawnCloudAffineAnimTable[] = +{ + gYawnCloudAffineAnimCmds1, + gYawnCloudAffineAnimCmds2, + gYawnCloudAffineAnimCmds3, +}; + +const struct SpriteTemplate gYawnCloudSpriteTemplate = +{ + .tileTag = ANIM_TAG_PINK_CLOUD, + .paletteTag = ANIM_TAG_PINK_CLOUD, + .oam = &gOamData_AffineNormal_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gYawnCloudAffineAnimTable, + .callback = AnimYawnCloud, +}; + +const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(-4, -6, 0, 16), + AFFINEANIMCMD_FRAME(4, 6, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0), + AFFINEANIMCMD_FRAME(4, 6, 0, 16), + AFFINEANIMCMD_FRAME(-4, -6, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds3[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(4, 6, 0, 16), + AFFINEANIMCMD_FRAME(-4, -6, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds4[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(8, 10, 0, 30), + AFFINEANIMCMD_FRAME(-8, -10, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gSmokeBallEscapeCloudAffineAnimTable[] = +{ + gSmokeBallEscapeCloudAffineAnimCmds1, + gSmokeBallEscapeCloudAffineAnimCmds2, + gSmokeBallEscapeCloudAffineAnimCmds3, + gSmokeBallEscapeCloudAffineAnimCmds4, +}; + +const struct SpriteTemplate gSmokeBallEscapeCloudSpriteTemplate = +{ + .tileTag = ANIM_TAG_PINK_CLOUD, + .paletteTag = ANIM_TAG_PINK_CLOUD, + .oam = &gOamData_AffineDouble_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSmokeBallEscapeCloudAffineAnimTable, + .callback = AnimSmokeBallEscapeCloud, +}; + +const union AffineAnimCmd gFacadeSquishAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(-16, 16, 0, 6), + AFFINEANIMCMD_FRAME(16, -16, 0, 12), + AFFINEANIMCMD_FRAME(-16, 16, 0, 6), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gFacadeSweatDropSpriteTemplate = +{ + .tileTag = ANIM_TAG_SWEAT_DROP, + .paletteTag = ANIM_TAG_SWEAT_DROP, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimFacadeSweatDrop, +}; + +const u16 gFacadeBlendColors[] = { + RGB(28, 25, 1), + RGB(28, 21, 5), + RGB(27, 18, 8), + RGB(27, 14, 11), + RGB(26, 10, 15), + RGB(26, 7, 18), + RGB(25, 3, 21), + RGB(25, 0, 25), + RGB(25, 0, 23), + RGB(25, 0, 20), + RGB(25, 0, 16), + RGB(25, 0, 13), + RGB(26, 0, 10), + RGB(26, 0, 6), + RGB(26, 0, 3), + RGB(27, 0, 0), + RGB(27, 1, 0), + RGB(27, 5, 0), + RGB(27, 9, 0), + RGB(27, 12, 0), + RGB(28, 16, 0), + RGB(28, 19, 0), + RGB(28, 23, 0), + RGB(29, 27, 0), +}; + +const union AnimCmd gRoarNoiseLineAnimCmds1[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gRoarNoiseLineAnimCmds2[] = +{ + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd *const gRoarNoiseLineAnimTable[] = +{ + gRoarNoiseLineAnimCmds1, + gRoarNoiseLineAnimCmds2, +}; + +const struct SpriteTemplate gRoarNoiseLineSpriteTemplate = +{ + .tileTag = ANIM_TAG_NOISE_LINE, + .paletteTag = ANIM_TAG_NOISE_LINE, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gRoarNoiseLineAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimRoarNoiseLine, +}; + +const struct SpriteTemplate gGlareEyeDotSpriteTemplate = +{ + .tileTag = ANIM_TAG_SMALL_RED_EYE, + .paletteTag = ANIM_TAG_SMALL_RED_EYE, + .oam = &gOamData_AffineOff_ObjNormal_8x8, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimGlareEyeDot, +}; + +const struct SpriteTemplate gAssistPawprintSpriteTemplate = +{ + .tileTag = ANIM_TAG_PAW_PRINT, + .paletteTag = ANIM_TAG_PAW_PRINT, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimAssistPawprint, +}; + +const union AffineAnimCmd gBarrageBallAffineAnimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0, 0, -4, 24), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gBarrageBallAffineAnimCmds2[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0), + AFFINEANIMCMD_FRAME(0, 0, 4, 24), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gBarrageBallAffineAnimTable[] = +{ + gBarrageBallAffineAnimCmds1, + gBarrageBallAffineAnimCmds2, +}; + +const struct SpriteTemplate gBarrageBallSpriteTemplate = +{ + .tileTag = ANIM_TAG_RED_BALL, + .paletteTag = ANIM_TAG_RED_BALL, + .oam = &gOamData_AffineNormal_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gBarrageBallAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +const struct SpriteTemplate gSmellingSaltsHandSpriteTemplate = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSmellingSaltsHand, +}; + +const union AffineAnimCmd gSmellingSaltsSquishAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, -16, 0, 6), + AFFINEANIMCMD_FRAME(0, 16, 0, 6), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gSmellingSaltExclamationSpriteTemplate = +{ + .tileTag = ANIM_TAG_SMELLINGSALT_EFFECT, + .paletteTag = ANIM_TAG_SMELLINGSALT_EFFECT, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSmellingSaltExclamation, +}; + +const struct SpriteTemplate gHelpingHandClapSpriteTemplate = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimHelpingHandClap, +}; + +const struct SpriteTemplate gForesightMagnifyingGlassSpriteTemplate = +{ + .tileTag = ANIM_TAG_MAGNIFYING_GLASS, + .paletteTag = ANIM_TAG_MAGNIFYING_GLASS, + .oam = &gOamData_AffineOff_ObjBlend_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimForesightMagnifyingGlass, +}; + +const struct SpriteTemplate gMeteorMashStarSpriteTemplate = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMeteorMashStar, +}; + +const struct SpriteTemplate gUnknown_085CE8F4 = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimParticuleBurst, +}; + +const struct SpriteTemplate gBlockXSpriteTemplate = +{ + .tileTag = ANIM_TAG_X_SIGN, + .paletteTag = ANIM_TAG_X_SIGN, + .oam = &gOamData_AffineOff_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimBlockX, +}; + +const struct SpriteTemplate gUnknown_085CE924 = +{ + .tileTag = ANIM_TAG_ITEM_BAG, + .paletteTag = ANIM_TAG_ITEM_BAG, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_815FE80, +}; + +const union AnimCmd gKnockOffStrikeAnimCmds[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(64, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gKnockOffStrikeAnimTable[] = +{ + gKnockOffStrikeAnimCmds, +}; + +const union AffineAnimCmd gKnockOffStrikeAffineanimCmds1[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0, 0, -4, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gKnockOffStrikeAffineanimCmds2[] = +{ + AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0, 0, 4, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gKnockOffStrikeAffineAnimTable[] = +{ + gKnockOffStrikeAffineanimCmds1, + gKnockOffStrikeAffineanimCmds2, +}; + +const struct SpriteTemplate gKnockOffStrikeSpriteTemplate = +{ + .tileTag = ANIM_TAG_SLAM_HIT_2, + .paletteTag = ANIM_TAG_SLAM_HIT_2, + .oam = &gOamData_AffineNormal_ObjNormal_64x64, + .anims = gKnockOffStrikeAnimTable, + .images = NULL, + .affineAnims = gKnockOffStrikeAffineAnimTable, + .callback = AnimKnockOffStrike, +}; + +const union AffineAnimCmd gRecycleSpriteAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, 0, -4, 64), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gRecycleSpriteAffineAnimTable[] = +{ + gRecycleSpriteAffineAnimCmds, +}; + +const struct SpriteTemplate gRecycleSpriteTemplate = +{ + .tileTag = ANIM_TAG_RECYCLE, + .paletteTag = ANIM_TAG_RECYCLE, + .oam = &gOamData_AffineNormal_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gRecycleSpriteAffineAnimTable, + .callback = AnimRecycle, +}; + +const union AffineAnimCmd gSlackOffSquishAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, 16, 0, 4), + AFFINEANIMCMD_FRAME(-2, 0, 0, 8), + AFFINEANIMCMD_FRAME(0, 4, 0, 4), + AFFINEANIMCMD_FRAME(0, 0, 0, 24), + AFFINEANIMCMD_FRAME(1, -5, 0, 16), + AFFINEANIMCMD_END, +}; + +// Functions +void AnimBlackSmoke(struct Sprite *sprite) +{ + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + + if (!gBattleAnimArgs[3]) + sprite->data[0] = gBattleAnimArgs[2]; + else + sprite->data[0] = -gBattleAnimArgs[2]; + + sprite->data[1] = gBattleAnimArgs[4]; + sprite->callback = AnimBlackSmokeStep; +} + +static void AnimBlackSmokeStep(struct Sprite *sprite) +{ + if (sprite->data[1] > 0) + { + sprite->pos2.x = sprite->data[2] >> 8; + sprite->data[2] += sprite->data[0]; + sprite->invisible ^= 1; + sprite->data[1]--; + } + else + { + DestroyAnimSprite(sprite); + } +} + +void AnimTask_SmokescreenImpact(u8 taskId) +{ + SmokescreenImpact( + GetBattlerSpriteCoord(gBattleAnimTarget, 2) + 8, + GetBattlerSpriteCoord(gBattleAnimTarget, 3) + 8, + 0); + DestroyAnimVisualTask(taskId); +} + +void AnimWhiteHalo(struct Sprite *sprite) +{ + sprite->data[0] = 90; + sprite->callback = WaitAnimForDuration; + sprite->data[1] = 7; + StoreSpriteCallbackInData6(sprite, AnimWhiteHalo_Step1); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1])); +} + +static void AnimWhiteHalo_Step1(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1])); + if (--sprite->data[1] < 0) + { + sprite->invisible = 1; + sprite->callback = AnimWhiteHalo_Step2; + } +} + +static void AnimWhiteHalo_Step2(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); +} + +void AnimTealAlert(struct Sprite *sprite) +{ + u16 rotation; + u8 x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + u8 y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + + InitSpritePosToAnimTarget(sprite, TRUE); + + rotation = ArcTan2Neg(sprite->pos1.x - x, sprite->pos1.y - y); + rotation += 0x6000; + if (IsContest()) + rotation += 0x4000; + + TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rotation); + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[2] = x; + sprite->data[4] = y; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void AnimMeanLookEye(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + sprite->data[0] = 4; + sprite->callback = AnimMeanLookEye_Step1; +} + +static void AnimMeanLookEye_Step1(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0])); + + if (sprite->data[1]) + sprite->data[0]--; + else + sprite->data[0]++; + + if (sprite->data[0] == 15 || sprite->data[0] == 4) + sprite->data[1] ^= 1; + + if (sprite->data[2]++ > 70) + { + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + StartSpriteAffineAnim(sprite, 1); + sprite->data[2] = 0; + sprite->invisible = 1; + sprite->affineAnimPaused = 1; + sprite->callback = AnimMeanLookEye_Step2; + } +} + +static void AnimMeanLookEye_Step2(struct Sprite *sprite) +{ + if (sprite->data[2]++ > 9) + { + sprite->invisible = 0; + sprite->affineAnimPaused = 0; + if (sprite->affineAnimEnded) + sprite->callback = AnimMeanLookEye_Step3; + } +} + +static void AnimMeanLookEye_Step3(struct Sprite *sprite) +{ + switch (sprite->data[3]) + { + case 0: + case 1: + sprite->pos2.x = 1; + sprite->pos2.y = 0; + break; + case 2: + case 3: + sprite->pos2.x = -1; + sprite->pos2.y = 0; + break; + case 4: + case 5: + sprite->pos2.x = 0; + sprite->pos2.y = 1; + break; + case 6: + default: + sprite->pos2.x = 0; + sprite->pos2.y = -1; + break; + } + + if (++sprite->data[3] > 7) + sprite->data[3] = 0; + + if (sprite->data[4]++ > 15) + { + sprite->data[0] = 16; + sprite->data[1] = 0; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 0)); + sprite->callback = AnimMeanLookEye_Step4; + } +} + +static void AnimMeanLookEye_Step4(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0])); + + if (sprite->data[1]++ > 1) + { + sprite->data[0]--; + sprite->data[1] = 0; + } + + if (sprite->data[0] == 0) + sprite->invisible = 1; + + if (sprite->data[0] < 0) + { + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); + } +} + +void AnimTask_SetPsychicBackground(u8 taskId) +{ + gTasks[taskId].func = SetPsychicBackground_Step; + gAnimVisualTaskCount--; +} + +static void SetPsychicBackground_Step(u8 taskId) +{ + int i; + u16 lastColor; + u8 paletteIndex = GetBattleBgPaletteNum(); + + if (++gTasks[taskId].data[5] == 4) + { + lastColor = gPlttBufferFaded[paletteIndex * 16 + 11]; + for (i = 10; i > 0; i--) + gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i]; + + gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor; + gTasks[taskId].data[5] = 0; + } + + if ((u16)gBattleAnimArgs[7] == 0xFFFF) + DestroyTask(taskId); +} + +void AnimTask_FadeScreenToWhite(u8 taskId) +{ + gTasks[taskId].func = FadeScreenToWhite_Step; + gAnimVisualTaskCount--; +} + +static void FadeScreenToWhite_Step(u8 taskId) +{ + int i; + u16 lastColor; + u8 paletteIndex = GetBattleBgPaletteNum(); + + if (++gTasks[taskId].data[5] == 4) + { + lastColor = gPlttBufferFaded[paletteIndex * 16 + 11]; + for (i = 10; i > 0; i--) + gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i]; + gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor; + + lastColor = gPlttBufferUnfaded[paletteIndex * 16 + 11]; + for (i = 10; i > 0; i--) + gPlttBufferUnfaded[paletteIndex * 16 + i + 1] = gPlttBufferUnfaded[paletteIndex * 16 + i]; + gPlttBufferUnfaded[paletteIndex * 16 + 1] = lastColor; + + gTasks[taskId].data[5] = 0; + } + + if ((u16)gBattleAnimArgs[7] == 0xFFFF) + DestroyTask(taskId); +} + +void AnimSpikes(struct Sprite *sprite) +{ + u16 x; + u16 y; + + InitSpritePosToAnimAttacker(sprite, TRUE); + SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &x, &y); + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = x + gBattleAnimArgs[2]; + sprite->data[4] = y + gBattleAnimArgs[3]; + sprite->data[5] = -50; + + InitAnimArcTranslation(sprite); + sprite->callback = AnimSpikes_Step1; +} + +static void AnimSpikes_Step1(struct Sprite *sprite) +{ + if (TranslateAnimHorizontalArc(sprite)) + { + sprite->data[0] = 30; + sprite->data[1] = 0; + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData6(sprite, AnimSpikes_Step2); + } +} + +static void AnimSpikes_Step2(struct Sprite *sprite) +{ + if (sprite->data[1] & 1) + sprite->invisible ^= 1; + + if (++sprite->data[1] == 16) + DestroyAnimSprite(sprite); +} + +void AnimLeer(struct Sprite *sprite) +{ + SetSpriteCoordsToAnimAttackerCoords(sprite); + SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->callback = RunStoredCallbackWhenAnimEnds; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void AnimLetterZ(struct Sprite *sprite) +{ + int var0; + if (sprite->data[0] == 0) + { + SetSpriteCoordsToAnimAttackerCoords(sprite); + SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); + if (!IsContest()) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->data[1] = gBattleAnimArgs[2]; + sprite->data[2] = gBattleAnimArgs[3]; + } + else + { + sprite->data[1] = -1 * gBattleAnimArgs[2]; + sprite->data[2] = -1 * gBattleAnimArgs[3]; + } + } + else + { + sprite->data[1] = -1 * gBattleAnimArgs[2]; + sprite->data[2] = gBattleAnimArgs[3]; + } + } + + sprite->data[0]++; + var0 = (sprite->data[0] * 20) & 0xFF; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = sprite->data[3] / 2; + sprite->pos2.y = Sin(var0 & 0xFF, 5) + (sprite->data[4] / 2); + + if ((u16)(sprite->pos1.x + sprite->pos2.x) > 240) + DestroyAnimSprite(sprite); +} + +void AnimFang(struct Sprite *sprite) +{ + if (sprite->animEnded) + DestroyAnimSprite(sprite); +} + +void AnimTask_IsTargetPlayerSide(u8 taskId) +{ + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) + gBattleAnimArgs[7] = 0; + else + gBattleAnimArgs[7] = 1; + + DestroyAnimVisualTask(taskId); +} + +void AnimTask_IsHealingMove(u8 taskId) +{ + if (gAnimMoveDmg > 0) + gBattleAnimArgs[7] = 0; + else + gBattleAnimArgs[7] = 1; + + DestroyAnimVisualTask(taskId); +} + +void AnimSpotlight(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H); + SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V); + + InitSpritePosToAnimTarget(sprite, FALSE); + + sprite->oam.objMode = ST_OAM_OBJ_WINDOW; + sprite->invisible = 1; + sprite->callback = AnimSpotlight_Step1; +} + +static void AnimSpotlight_Step1(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->invisible = 0; + if (sprite->affineAnimEnded) + sprite->data[0]++; + break; + case 1: + case 3: + sprite->data[1] += 117; + sprite->pos2.x = sprite->data[1] >> 8; + if (++sprite->data[2] == 21) + { + sprite->data[2] = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->data[1] -= 117; + sprite->pos2.x = sprite->data[1] >> 8; + if (++sprite->data[2] == 41) + { + sprite->data[2] = 0; + sprite->data[0]++; + } + break; + case 4: + ChangeSpriteAffineAnim(sprite, 1); + sprite->data[0]++; + break; + case 5: + if (sprite->affineAnimEnded) + { + sprite->invisible = 1; + sprite->callback = AnimSpotlight_Step2; + } + break; + } +} + +static void AnimSpotlight_Step2(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); + DestroyAnimSprite(sprite); +} + +void AnimClappingHand(struct Sprite *sprite) +{ + if (gBattleAnimArgs[3] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + } + + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->oam.tileNum += 16; + + if (gBattleAnimArgs[2] == 0) + { + sprite->oam.matrixNum = ST_OAM_HFLIP; + sprite->pos2.x = -12; + sprite->data[1] = 2; + } + else + { + sprite->pos2.x = 12; + sprite->data[1] = -2; + } + + sprite->data[0] = gBattleAnimArgs[4]; + + if (sprite->data[3] != 255) + sprite->data[3] = gBattleAnimArgs[2]; + + sprite->callback = AnimClappingHand_Step; +} + +static void AnimClappingHand_Step(struct Sprite *sprite) +{ + if (sprite->data[2] == 0) + { + sprite->pos2.x += sprite->data[1]; + if (sprite->pos2.x == 0) + { + sprite->data[2]++; + if (sprite->data[3] == 0) + { + PlaySE1WithPanning(SE_W227, BattleAnimAdjustPanning(-64)); + } + } + } + else + { + sprite->pos2.x -= sprite->data[1]; + if (abs(sprite->pos2.x) == 12) + { + sprite->data[0]--; + sprite->data[2]--; + } + + } + + if (sprite->data[0] == 0) + DestroyAnimSprite(sprite); +} + +void AnimClappingHand2(struct Sprite *sprite) +{ + sprite->oam.objMode = ST_OAM_OBJ_WINDOW; + sprite->data[3] = 255; + AnimClappingHand(sprite); +} + +void AnimTask_CreateSpotlight(u8 taskId) +{ + if (IsContest()) + { + SetGpuReg(REG_OFFSET_WININ, 0x1F3F); + gBattle_WIN1H = 0x98F0; + gBattle_WIN1V = 0x00A0; + SetGpuReg(REG_OFFSET_WIN1H, gBattle_WIN0H); + SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN0V); + } + else + { + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ); + gBattle_WIN1H = 0x00F0; + gBattle_WIN1V = 0x78A0; + SetGpuReg(REG_OFFSET_WIN1H, 0x00F0); + SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN1V); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN1_ON); + } + + DestroyAnimVisualTask(taskId); +} + +void AnimTask_RemoveSpotlight(u8 taskId) +{ + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + gBattle_WIN1H = 0; + gBattle_WIN1V = 0; + if (!IsContest()) + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN1_ON); + + DestroyAnimVisualTask(taskId); +} + +void AnimRapidSpin(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); + } + + sprite->pos2.y = gBattleAnimArgs[2]; + + sprite->data[0] = (sprite->pos2.y > gBattleAnimArgs[3]); + sprite->data[1] = 0; + sprite->data[2] = gBattleAnimArgs[4]; + sprite->data[3] = gBattleAnimArgs[5]; + sprite->data[4] = gBattleAnimArgs[3]; + sprite->callback = AnimRapidSpin_Step; +} + +static void AnimRapidSpin_Step(struct Sprite *sprite) +{ + sprite->data[1] = (sprite->data[1] + sprite->data[2]) & 0xFF; + sprite->pos2.x = gSineTable[sprite->data[1]] >> 4; + sprite->pos2.y += sprite->data[3]; + + if (sprite->data[0]) + { + if (sprite->pos2.y < sprite->data[4]) + DestroyAnimSprite(sprite); + } + else + { + if (sprite->pos2.y > sprite->data[4]) + DestroyAnimSprite(sprite); + } +} + +void AnimTask_RapinSpinMonElevation(u8 taskId) +{ + s16 var0; + u8 toBG2; + s16 var2; + int var3; + int var4; + s16 i; + struct ScanlineEffectParams scanlineParams; + struct Task *task = &gTasks[taskId]; + + if (!gBattleAnimArgs[0]) + { + var0 = GetBattlerYCoordWithElevation(gBattleAnimAttacker); + toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker); + } + else + { + var0 = GetBattlerYCoordWithElevation(gBattleAnimTarget); + toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget); + } + + task->data[0] = var0 + 36; + task->data[1] = task->data[0]; + task->data[2] = var0 - 33; + if (task->data[2] < 0) + task->data[2] = 0; + + task->data[3] = task->data[0]; + task->data[4] = 8; + task->data[5] = gBattleAnimArgs[1]; + task->data[6] = 0; + task->data[7] = 0; + + if (toBG2 == 1) + { + var3 = gBattle_BG1_X; + task->data[8] = var3; + var4 = var3 + 240; + } + else + { + var3 = gBattle_BG2_X; + task->data[8] = var3; + var4 = var3 + 240; + } + + task->data[9] = var4; + task->data[10] = gBattleAnimArgs[2]; + + if (!gBattleAnimArgs[2]) + { + task->data[11] = var4; + var2 = task->data[8]; + } + else + { + task->data[11] = var3; + var2 = task->data[9]; + } + + task->data[15] = 0; + + i = task->data[2]; + while (i <= task->data[3]) + { + gScanlineEffectRegBuffers[0][i] = var2; + gScanlineEffectRegBuffers[1][i] = var2; + i++; + } + + if (toBG2 == 1) + scanlineParams.dmaDest = ®_BG1HOFS; + else + scanlineParams.dmaDest = ®_BG2HOFS; + + scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + ScanlineEffect_SetParams(scanlineParams); + + task->func = RapinSpinMonElevation_Step; +} + +static void RapinSpinMonElevation_Step(u8 taskId) +{ + s16 i; + struct Task *task = &gTasks[taskId]; + + task->data[0] -= task->data[5]; + if (task->data[0] < task->data[2]) + task->data[0] = task->data[2]; + + if (task->data[4] == 0) + { + task->data[1] -= task->data[5]; + if (task->data[1] < task->data[2]) + { + task->data[1] = task->data[2]; + task->data[15] = 1; + } + } + else + { + task->data[4]--; + } + + if (++task->data[6] > 1) + { + task->data[6] = 0; + task->data[7] = task->data[7] == 0 ? 1 : 0; + + if (task->data[7]) + task->data[12] = task->data[8]; + else + task->data[12] = task->data[9]; + } + + i = task->data[0]; + while (i < task->data[1]) + { + gScanlineEffectRegBuffers[0][i] = task->data[12]; + gScanlineEffectRegBuffers[1][i] = task->data[12]; + i++; + } + + i = task->data[1]; + while (i <= task->data[3]) + { + gScanlineEffectRegBuffers[0][i] = task->data[11]; + gScanlineEffectRegBuffers[1][i] = task->data[11]; + i++; + } + + if (task->data[15]) + { + if (task->data[10]) + gScanlineEffect.state = 3; + + DestroyAnimVisualTask(taskId); + } +} + +void AnimTask_TormentAttacker(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + task->data[3] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + task->data[4] = 32; + task->data[5] = -20; + task->data[6] = 0; + task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->func = TormentAttacker_Step; +} + +static void TormentAttacker_Step(u8 taskId) +{ + int var0, var1; + s16 x, y; + u16 i, j; + u8 spriteId; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + var0 = task->data[2]; + if (task->data[1] & 1) + { + var1 = task->data[4]; + x = var0 - var1; + } + else + { + var1 = task->data[4]; + x = var0 + var1; + } + + y = task->data[3] + task->data[5]; + spriteId = CreateSprite(&gThoughtBubbleSpriteTemplate, x, y, 6 - task->data[1]); + PlaySE12WithPanning(SE_W118, BattleAnimAdjustPanning(-64)); + + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].hFlip = task->data[1] & 1; + gSprites[spriteId].callback = SpriteCallbackDummy; + } + + if (task->data[1] & 1) + { + task->data[4] -= 6; + task->data[5] -= 6; + } + + PrepareAffineAnimInTaskData(task, task->data[15], gUnknown_085CE2A0); + task->data[1]++; + task->data[0] = 1; + break; + case 1: + if (!RunAffineAnimFromTaskData(task)) + { + if (task->data[1] == 6) + { + task->data[6] = 8; + task->data[0] = 3; + } + else + { + if (task->data[1] <= 2) + task->data[6] = 10; + else + task->data[6] = 0; + + task->data[0] = 2; + } + } + break; + case 2: + if (task->data[6] != 0) + task->data[6]--; + else + task->data[0] = 0; + break; + case 3: + if (task->data[6] != 0) + task->data[6]--; + else + task->data[0] = 4; + break; + case 4: + for (i = 0, j = 0; i < MAX_SPRITES; i++) + { + if (gSprites[i].template == &gThoughtBubbleSpriteTemplate) + { + gSprites[i].data[0] = taskId; + gSprites[i].data[1] = 6; + StartSpriteAnim(&gSprites[i], 2); + gSprites[i].callback = TormentAttacker_Callback; + + if (++j == 6) + break; + } + } + + task->data[6] = j; + task->data[0] = 5; + break; + case 5: + if (task->data[6] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void TormentAttacker_Callback(struct Sprite *sprite) +{ + if (sprite->animEnded) + { + gTasks[sprite->data[0]].data[sprite->data[1]]--; + DestroySprite(sprite); + } +} + +void AnimTriAttackTriangle(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + InitSpritePosToAnimAttacker(sprite, FALSE); + + if (++sprite->data[0] < 40) + { + u16 var = sprite->data[0]; + if ((var & 1) == 0) + sprite->invisible = 1; + else + sprite->invisible = 0; + } + + if (sprite->data[0] > 30) + sprite->invisible = 0; + + if (sprite->data[0] == 61) + { + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data[0] = 20; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->callback = StartAnimLinearTranslation; + } +} + +void AnimTask_DefenseCurlDeformMon(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gUnknown_085CE350); + gTasks[taskId].data[0]++; + break; + case 1: + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimBatonPassPokeball(struct Sprite *sprite) +{ + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + + switch (sprite->data[0]) + { + case 0: + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); + sprite->data[1] = 256; + sprite->data[2] = 256; + sprite->data[0]++; + break; + case 1: + sprite->data[1] += 96; + sprite->data[2] -= 26; + SetSpriteRotScale(spriteId, sprite->data[1], sprite->data[2], 0); + + if (++sprite->data[3] == 5) + sprite->data[0]++; + // fall through + case 2: + sprite->data[1] += 96; + sprite->data[2] += 48; + SetSpriteRotScale(spriteId, sprite->data[1], sprite->data[2], 0); + + if (++sprite->data[3] == 9) + { + sprite->data[3] = 0; + gSprites[spriteId].invisible = 1; + ResetSpriteRotScale(spriteId); + sprite->data[0]++; + } + break; + case 3: + sprite->pos2.y -= 6; + if (sprite->pos1.y + sprite->pos2.y < -32) + DestroyAnimSprite(sprite); + break; + } +} + +void AnimWishStar(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos1.x = -16; + else + sprite->pos1.x = 256; + + sprite->pos1.y = 0; + sprite->callback = AnimWishStar_Step; +} + +static void AnimWishStar_Step(struct Sprite *sprite) +{ + u32 newX; + + sprite->data[0] += 72; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos2.x = sprite->data[0] >> 4; + else + sprite->pos2.x = -(sprite->data[0] >> 4); + + sprite->data[1] += 16; + sprite->pos2.y += sprite->data[1] >> 8; + + if (++sprite->data[2] % 3 == 0) + { + CreateSpriteAndAnimate( + &gMiniTwinklingStarSpriteTemplate, + sprite->pos1.x + sprite->pos2.x, + sprite->pos1.y + sprite->pos2.y, + sprite->subpriority + 1); + } + + newX = sprite->pos1.x + sprite->pos2.x + 32; + if (newX > 304) + DestroyAnimSprite(sprite); +} + +void AnimMiniTwinklingStar(struct Sprite *sprite) +{ + u8 rand; + s8 y; + + rand = Random2() & 3; + if (rand == 0) + sprite->oam.tileNum += 4; + else + sprite->oam.tileNum += 5; + + y = Random2() & 7; + if (y > 3) + y = -y; + + sprite->pos2.y = y; + sprite->callback = AnimMiniTwinklingStar_Step; +} + +static void AnimMiniTwinklingStar_Step(struct Sprite *sprite) +{ + if (++sprite->data[0] < 30) + { + if (++sprite->data[1] == 2) + { + sprite->invisible ^= 1; + sprite->data[1] = 0; + } + } + else + { + if (sprite->data[1] == 2) + sprite->invisible = 0; + + if (sprite->data[1] == 3) + { + sprite->invisible = 1; + sprite->data[1] = -1; + } + + sprite->data[1]++; + } + + if (sprite->data[0] > 60) + DestroySprite(sprite); +} + +void AnimTask_StockpileDeformMon(u8 taskId) +{ + if (!gTasks[taskId].data[0]) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gUnknown_085CE3B8); + gTasks[taskId].data[0]++; + } + else + { + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); + } +} + +void AnimTask_SpitUpDeformMon(u8 taskId) +{ + if (!gTasks[taskId].data[0]) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gUnknown_085CE3E0); + gTasks[taskId].data[0]++; + } + else + { + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); + } +} + +void AnimSwallowBlueOrb(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + InitSpritePosToAnimAttacker(sprite, FALSE); + sprite->data[1] = 0x900; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[0]++; + break; + case 1: + sprite->pos2.y -= sprite->data[1] >> 8; + sprite->data[1] -= 96; + if (sprite->pos1.y + sprite->pos2.y > sprite->data[2]) + DestroyAnimSprite(sprite); + break; + } +} + +void AnimTask_SwallowDeformMon(u8 taskId) +{ + if (!gTasks[taskId].data[0]) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gUnknown_085CE430); + gTasks[taskId].data[0]++; + } + else + { + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); + } +} + +void AnimTask_TransformMon(u8 taskId) +{ + int i, j; + u8 position; + struct BattleAnimBgData animBg; + u8 *dest; + u8 *src; + u16 *bgTilemap; + u16 stretch; + + switch (gTasks[taskId].data[0]) + { + case 0: + SetGpuReg(REG_OFFSET_MOSAIC, 0); + if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) + SetAnimBgAttribute(1, BG_ANIM_MOSAIC, 1); + else + SetAnimBgAttribute(2, BG_ANIM_MOSAIC, 1); + + gTasks[taskId].data[10] = gBattleAnimArgs[0]; + gTasks[taskId].data[0]++; + break; + case 1: + if (gTasks[taskId].data[2]++ > 1) + { + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[1]++; + stretch = gTasks[taskId].data[1]; + SetGpuReg(REG_OFFSET_MOSAIC, (stretch << 4) | stretch); + if (stretch == 15) + gTasks[taskId].data[0]++; + } + break; + case 2: + HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10]); + sub_80A6BFC(&animBg, gBattleAnimAttacker); + + if (IsContest()) + position = 0; + else + position = GetBattlerPosition(gBattleAnimAttacker); + + src = gMonSpritesGfxPtr->sprites[position] + (gBattleMonForms[gBattleAnimAttacker] << 11); + dest = animBg.bgTiles; + CpuCopy32(src, dest, 0x800); + LoadBgTiles(1, animBg.bgTiles, 0x800, animBg.tilesOffset); + if (IsContest()) + { + if (IsSpeciesNotUnown(gContestResources->field_18->species) != IsSpeciesNotUnown(gContestResources->field_18->unk2)) + { + bgTilemap = (u16 *)animBg.bgTilemap; + for (i = 0; i < 8; i++) + { + for (j = 0; j < 4; j++) + { + u16 temp = bgTilemap[j + i * 0x20]; + bgTilemap[j + i * 0x20] = bgTilemap[(7 - j) + i * 0x20]; + bgTilemap[(7 - j) + i * 0x20] = temp; + } + } + + for (i = 0; i < 8; i++) + { + for (j = 0; j < 8; j++) + { + bgTilemap[j + i * 0x20] ^= 0x400; + } + } + } + + if (IsSpeciesNotUnown(gContestResources->field_18->unk2)) + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].affineAnims = gUnknown_082FF6C0; + else + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].affineAnims = gUnknown_082FF694; + + StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimAttacker]], 0); + } + + gTasks[taskId].data[0]++; + break; + case 3: + if (gTasks[taskId].data[2]++ > 1) + { + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[1]--; + stretch = gTasks[taskId].data[1]; + SetGpuReg(REG_OFFSET_MOSAIC, (stretch << 4) | stretch); + + if (stretch == 0) + gTasks[taskId].data[0]++; + } + break; + case 4: + SetGpuReg(REG_OFFSET_MOSAIC, 0); + if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1) + SetAnimBgAttribute(1, BG_ANIM_MOSAIC, 0); + else + SetAnimBgAttribute(2, BG_ANIM_MOSAIC, 0); + + if (!IsContest()) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + { + if (gTasks[taskId].data[10] == 0) + SetBattlerShadowSpriteCallback(gBattleAnimAttacker, gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies); + } + } + + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimTask_IsMonInvisible(u8 taskId) +{ + gBattleAnimArgs[7] = gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible; + DestroyAnimVisualTask(taskId); +} + +void AnimTask_CastformGfxChange(u8 taskId) +{ + HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, TRUE); + DestroyAnimVisualTask(taskId); +} + +void AnimTask_MorningSunLightBeam(u8 taskId) +{ + struct BattleAnimBgData animBg; + + switch (gTasks[taskId].data[0]) + { + case 0: + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + + sub_80752A0 + sub_807543C + sub_80753B4 //AnimLoadCompressedBgGfx(animBg.bgId, gUnknown_08C2A634, animBg.tilesOffset); + LoadCompressedPalette(gUnknown_8D2A8A8, animBg.paletteId * 16, 32); + if (IsContest()) + { + sub_80730C0(animBg.paletteId, [sp+4 ???], 0, 0); + gBattle_BG1_X = -56; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattle_BG1_X = -135; + else + gBattle_BG1_X = -10; + } + + gBattle_BG1_Y = 0; + + /* + sub_80752A0(&animBg); + sub_80A6D60(&animBg, &gUnknown_08C2A6EC, 0); + + if (IsContest()) + { + gBattle_BG1_X = -56; + gBattle_BG1_Y = 0; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattle_BG1_X = -135; + else + gBattle_BG1_X = -10; + + gBattle_BG1_Y = 0; + } + */ + + + + + gTasks[taskId].data[10] = gBattle_BG1_X; + gTasks[taskId].data[11] = gBattle_BG1_Y; + + gTasks[taskId].data[0]++; + PlaySE12WithPanning(SE_W234, BattleAnimAdjustPanning(-64)); + break; + case 1: + if (gTasks[taskId].data[4]++ > 0) + { + gTasks[taskId].data[4] = 0; + if (++gTasks[taskId].data[1] > 12) + gTasks[taskId].data[1] = 12; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1])); + + if (gTasks[taskId].data[1] == 12) + gTasks[taskId].data[0]++; + } + break; + case 2: + if (--gTasks[taskId].data[1] < 0) + gTasks[taskId].data[1] = 0; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1])); + + if (!gTasks[taskId].data[1]) + { + gBattle_BG1_X = gUnknown_085CE460[gTasks[taskId].data[2]] + gTasks[taskId].data[10]; + if (++gTasks[taskId].data[2] == 4) + gTasks[taskId].data[0] = 4; + else + gTasks[taskId].data[0] = 3; + } + break; + case 3: + if (++gTasks[taskId].data[3] == 4) + { + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[0] = 1; + PlaySE12WithPanning(SE_W234, BattleAnimAdjustPanning(-64)); + } + break; + case 4: + sub_80752A0(&animBg); + sub_8075358(animBg.bgId); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + break; + } +} + +void AnimGreenStar(struct Sprite *sprite) +{ + s16 xOffset; + u8 spriteId1; + u8 spriteId2; + + xOffset = Random2(); + xOffset &= 0x3F; + if (xOffset > 31) + xOffset = 32 - xOffset; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + xOffset; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 32; + sprite->data[1] = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + + spriteId1 = CreateSprite(&gUnknown_085CE48C, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1); + spriteId2 = CreateSprite(&gUnknown_085CE48C, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1); + StartSpriteAnim(&gSprites[spriteId1], 1); + StartSpriteAnim(&gSprites[spriteId2], 2); + + gSprites[spriteId1].data[1] = gBattleAnimArgs[0]; + gSprites[spriteId1].data[2] = gBattleAnimArgs[1]; + gSprites[spriteId2].data[1] = gBattleAnimArgs[0]; + gSprites[spriteId2].data[2] = gBattleAnimArgs[1]; + gSprites[spriteId1].data[7] = -1; + gSprites[spriteId2].data[7] = -1; + gSprites[spriteId1].invisible = 1; + gSprites[spriteId2].invisible = 1; + gSprites[spriteId1].callback = AnimGreenStar_Callback; + gSprites[spriteId2].callback = AnimGreenStar_Callback; + + sprite->data[6] = spriteId1; + sprite->data[7] = spriteId2; + sprite->callback = AnimGreenStar_Step1; +} + +static void AnimGreenStar_Step1(struct Sprite *sprite) +{ + s16 delta = sprite->data[3] + sprite->data[2]; + sprite->pos2.y -= delta >> 8; + sprite->data[3] += sprite->data[2]; + sprite->data[3] &= 0xFF; + if (sprite->data[4] == 0 && sprite->pos2.y < -8) + { + gSprites[sprite->data[6]].invisible = 0; + sprite->data[4]++; + } + + if (sprite->data[4] == 1 && sprite->pos2.y < -16) + { + gSprites[sprite->data[7]].invisible = 0; + sprite->data[4]++; + } + + if (--sprite->data[1] == -1) + { + sprite->invisible = 1; + sprite->callback = AnimGreenStar_Step2; + } +} + +static void AnimGreenStar_Step2(struct Sprite *sprite) +{ + if (gSprites[sprite->data[6]].callback == SpriteCallbackDummy + && gSprites[sprite->data[7]].callback == SpriteCallbackDummy) + { + DestroySprite(&gSprites[sprite->data[6]]); + DestroySprite(&gSprites[sprite->data[7]]); + DestroyAnimSprite(sprite); + } +} + +static void AnimGreenStar_Callback(struct Sprite *sprite) +{ + if (!sprite->invisible) + { + s16 delta = sprite->data[3] + sprite->data[2]; + sprite->pos2.y -= delta >> 8; + sprite->data[3] += sprite->data[2]; + sprite->data[3] &= 0xFF; + if (--sprite->data[1] == -1) + { + sprite->invisible = 1; + sprite->callback = SpriteCallbackDummy; + } + } +} + +void AnimTask_DoomDesireLightBeam(u8 taskId) +{ + struct BattleAnimBgData animBg; + + switch (gTasks[taskId].data[0]) + { + case 0: + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(3, 13)); + SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0); + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1); + + /* + sub_80752A0(&animBg); + sub_80A6D60(&animBg, &gUnknown_08C2A6EC, 0); + */ + + sub_80752A0 + sub_807543C + sub_80753B4 + LoadCompressedPalette + //... + + if (IsContest()) + { + gBattle_BG1_X = -56; + gBattle_BG1_Y = 0; + } + else + { + u8 position = GetBattlerPosition(gBattleAnimTarget); + if (IsDoubleBattle() == TRUE) + { + if (position == B_POSITION_OPPONENT_LEFT) + gBattle_BG1_X = -155; + if (position == B_POSITION_OPPONENT_RIGHT) + gBattle_BG1_X = -115; + if (position == B_POSITION_PLAYER_LEFT) + gBattle_BG1_X = 14; + if (position == B_POSITION_PLAYER_RIGHT) + gBattle_BG1_X = -20; + } + else + { + if (position == B_POSITION_OPPONENT_LEFT) + gBattle_BG1_X = -135; + if (position == B_POSITION_PLAYER_LEFT) + gBattle_BG1_X = -10; + } + + gBattle_BG1_Y = 0; + } + + AnimLoadCompressedBgGfx(animBg.bgId, gUnknown_08C2A634, animBg.tilesOffset); + LoadCompressedPalette(gUnknown_08C2A6D4, animBg.paletteId * 16, 32); + gTasks[taskId].data[10] = gBattle_BG1_X; + gTasks[taskId].data[11] = gBattle_BG1_Y; + gTasks[taskId].data[0]++; + break; + case 1: + gTasks[taskId].data[3] = 0; + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) + gBattle_BG1_X = gTasks[taskId].data[10] + gUnknown_085CE4A4[gTasks[taskId].data[2]]; + else + gBattle_BG1_X = gTasks[taskId].data[10] - gUnknown_085CE4A4[gTasks[taskId].data[2]]; + + if (++gTasks[taskId].data[2] == 5) + gTasks[taskId].data[0] = 5; + else + gTasks[taskId].data[0]++; + break; + case 2: + if (--gTasks[taskId].data[1] <= 4) + gTasks[taskId].data[1] = 5; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(3, gTasks[taskId].data[1])); + if (gTasks[taskId].data[1] == 5) + gTasks[taskId].data[0]++; + break; + case 3: + if (++gTasks[taskId].data[3] > gUnknown_085CE4A8[gTasks[taskId].data[2]]) + gTasks[taskId].data[0]++; + break; + case 4: + if (++gTasks[taskId].data[1] > 13) + gTasks[taskId].data[1] = 13; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(3, gTasks[taskId].data[1])); + if (gTasks[taskId].data[1] == 13) + gTasks[taskId].data[0] = 1; + break; + case 5: + sub_80752A0(&animBg); + sub_8075358(animBg.bgId); + if (!IsContest()) + SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0); + + SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1); + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + break; + } +} + +// Briefly vertically grows and shrinks the attacking mon's sprite. +// No args. +void AnimTask_StrongFrustrationGrowAndShrink(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gStrongFrustrationAffineAnimCmds); + gTasks[taskId].data[0]++; + } + else + { + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); + } +} + +// Animates an anger mark near the mon's head. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +void AnimWeakFrustrationAngerMark(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + InitSpritePosToAnimAttacker(sprite, 0); + sprite->data[0]++; + } + else if (sprite->data[0]++ > 20) + { + sprite->data[1] += 160; + sprite->data[2] += 128; + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos2.x = -(sprite->data[1] >> 8); + else + sprite->pos2.x = sprite->data[1] >> 8; + + sprite->pos2.y += sprite->data[2] >> 8; + if (sprite->pos2.y > 64) + DestroyAnimSprite(sprite); + } +} + +// Rocks the mon back and forth. This is done on a pivot so it is done via rotation. +// arg 0: which battler +// arg 1: number of rocks +// arg 2: rotation speed increase +void AnimTask_RockMonBackAndForth(u8 taskId) +{ + u8 side; + struct Task *task = &gTasks[taskId]; + + if (!gBattleAnimArgs[1]) + { + DestroyAnimVisualTask(taskId); + return; + } + + if (gBattleAnimArgs[2] < 0) + gBattleAnimArgs[2] = 0; + if (gBattleAnimArgs[2] > 2) + gBattleAnimArgs[2] = 2; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 8 - (2 * gBattleAnimArgs[2]); + task->data[4] = 0x100 + (gBattleAnimArgs[2] * 128); + task->data[5] = gBattleAnimArgs[2] + 2; + task->data[6] = gBattleAnimArgs[1] - 1; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + side = GetBattlerSide(gBattleAnimAttacker); + else + side = GetBattlerSide(gBattleAnimTarget); + + if (side == B_SIDE_OPPONENT) + { + task->data[4] *= -1; + task->data[5] *= -1; + } + + PrepareBattlerSpriteForRotScale(task->data[15], ST_OAM_OBJ_NORMAL); + task->func = AnimTask_RockMonBackAndForthStep; +} + +static void AnimTask_RockMonBackAndForthStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + gSprites[task->data[15]].pos2.x += task->data[5]; + task->data[2] -= task->data[4]; + SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]); + SetBattlerSpriteYOffsetFromRotation(task->data[15]); + if (++task->data[1] >= task->data[3]) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 1: + gSprites[task->data[15]].pos2.x -= task->data[5]; + task->data[2] += task->data[4]; + SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]); + SetBattlerSpriteYOffsetFromRotation(task->data[15]); + if (++task->data[1] >= task->data[3] * 2) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 2: + gSprites[task->data[15]].pos2.x += task->data[5]; + task->data[2] -= task->data[4]; + SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]); + SetBattlerSpriteYOffsetFromRotation(task->data[15]); + if (++task->data[1] >= task->data[3]) + { + if (task->data[6]) + { + task->data[6]--; + task->data[1] = 0; + task->data[0] = 0; + } + else + { + task->data[0]++; + } + } + break; + case 3: + ResetSpriteRotScale(task->data[15]); + DestroyAnimVisualTask(taskId); + break; + } +} + +// Floats a petal across the screen towards the target mon's side. +// arg 0: initial y pixel offset +// arg 1: sprite anim num +// arg 2: unused +void AnimSweetScentPetal(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->pos1.x = 0; + sprite->pos1.y = gBattleAnimArgs[0]; + } + else + { + sprite->pos1.x = 240; + sprite->pos1.y = gBattleAnimArgs[0] - 30; + } + + sprite->data[2] = gBattleAnimArgs[2]; + StartSpriteAnim(sprite, gBattleAnimArgs[1]); + sprite->callback = AnimSweetScentPetalStep; +} + +static void AnimSweetScentPetalStep(struct Sprite *sprite) +{ + sprite->data[0] += 3; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->pos1.x += 5; + sprite->pos1.y -= 1; + + if (sprite->pos1.x > 240) + DestroyAnimSprite(sprite); + + sprite->pos2.y = Sin(sprite->data[0] & 0xFF, 16); + } + else + { + sprite->pos1.x -= 5; + sprite->pos1.y += 1; + + if (sprite->pos1.x < 0) + DestroyAnimSprite(sprite); + + sprite->pos2.y = Cos(sprite->data[0] & 0xFF, 16); + } +} + +// Moves the mon sprite in a flailing back-and-forth motion. +// arg 0: which battler +void AnimTask_FlailMovement(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + task->data[12] = 0x20; + task->data[13] = 0x40; + task->data[14] = 0x800; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + + PrepareBattlerSpriteForRotScale(task->data[15], ST_OAM_OBJ_NORMAL); + task->func = AnimTask_FlailMovementStep; +} + +static void AnimTask_FlailMovementStep(u8 taskId) +{ + int temp; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[2] += 0x200; + if (task->data[2] >= task->data[14]) + { + s16 diff = task->data[14] - task->data[2]; + s16 div = diff / (task->data[14] * 2); + s16 mod = diff % (task->data[14] * 2); + + if ((div & 1) == 0) + { + task->data[2] = task->data[14] - mod; + task->data[0] = 1; + } + else + { + task->data[2] = mod - task->data[14]; + } + } + break; + case 1: + task->data[2] -= 0x200; + if (task->data[2] <= -task->data[14]) + { + s16 diff = task->data[14] - task->data[2]; + s16 div = diff / (task->data[14] * 2); + s16 mod = diff % (task->data[14] * 2); + + if ((1 & div) == 0) + { + task->data[2] = mod - task->data[14]; + task->data[0] = 0; + } + else + { + task->data[2] = task->data[14] - mod; + } + } + break; + case 2: + ResetSpriteRotScale(task->data[15]); + DestroyAnimVisualTask(taskId); + return; + } + + SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]); + SetBattlerSpriteYOffsetFromRotation(task->data[15]); + gSprites[task->data[15]].pos2.x = -(((temp = task->data[2]) >= 0 ? task->data[2] : temp + 63) >> 6); + + if (++task->data[1] > 8) + { + if (task->data[12]) + { + task->data[12]--; + task->data[14] -= task->data[13]; + if (task->data[14] < 16) + task->data[14] = 16; + } + else + { + task->data[0] = 2; + } + } +} + +// Makes a spark-like projectile fall on top of the mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: which battler +void AnimPainSplitProjectile(struct Sprite *sprite) +{ + if (!sprite->data[0]) + { + if (gBattleAnimArgs[2] == ANIM_ATTACKER) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + } + + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[1] = 0x80; + sprite->data[2] = 0x300; + sprite->data[3] = gBattleAnimArgs[1]; + sprite->data[0]++; + } + else + { + sprite->pos2.x = sprite->data[1] >> 8; + sprite->pos2.y += sprite->data[2] >> 8; + if (sprite->data[4] == 0 && sprite->pos2.y > -sprite->data[3]) + { + sprite->data[4] = 1; + sprite->data[2] = (-sprite->data[2] / 3) * 2; + } + + sprite->data[1] += 192; + sprite->data[2] += 128; + if (sprite->animEnded) + DestroyAnimSprite(sprite); + } +} + +// Performs one of several affine transformations on the mon sprite. +// arg 0: which battler +// arg 1: which transformation +void AnimTask_PainSplitMovement(u8 taskId) +{ + u8 spriteId; + + if (gTasks[taskId].data[0] == 0) + { + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + gTasks[taskId].data[11] = gBattleAnimAttacker; + else + gTasks[taskId].data[11] = gBattleAnimTarget; + + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + gTasks[taskId].data[10] = spriteId; + PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL); + + switch (gBattleAnimArgs[1]) + { + case 0: + SetSpriteRotScale(spriteId, 0xE0, 0x140, 0); + SetBattlerSpriteYOffsetFromYScale(spriteId); + break; + case 1: + SetSpriteRotScale(spriteId, 0xD0, 0x130, 0xF00); + SetBattlerSpriteYOffsetFromYScale(spriteId); + if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.y += 16; + break; + case 2: + SetSpriteRotScale(spriteId, 0xD0, 0x130, 0xF100); + SetBattlerSpriteYOffsetFromYScale(spriteId); + if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.y += 16; + break; + } + + gSprites[spriteId].pos2.x = 2; + gTasks[taskId].data[0]++; + } + else + { + spriteId = gTasks[taskId].data[10]; + if (++gTasks[taskId].data[2] == 3) + { + gTasks[taskId].data[2] = 0; + gSprites[spriteId].pos2.x = -gSprites[spriteId].pos2.x; + } + + if (++gTasks[taskId].data[1] == 13) + { + ResetSpriteRotScale(spriteId); + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + } + } +} + +// Move a piece of confetti in a slightly-random speed across the screen. +// arg 0: which battler the confetti starts from +void AnimFlatterConfetti(struct Sprite *sprite) +{ + u8 tileOffset; + int rand1; + int rand2; + + tileOffset = Random2() % 12; + sprite->oam.tileNum += tileOffset; + rand1 = Random2() & 0x1FF; + rand2 = Random2() & 0xFF; + + if (rand1 & 1) + sprite->data[0] = 0x5E0 + rand1; + else + sprite->data[0] = 0x5E0 - rand1; + + if (rand2 & 1) + sprite->data[1] = 0x480 + rand2; + else + sprite->data[1] = 0x480 - rand2; + + sprite->data[2] = gBattleAnimArgs[0]; + if (sprite->data[2] == ANIM_ATTACKER) + sprite->pos1.x = -8; + else + sprite->pos1.x = 248; + + sprite->pos1.y = 104; + sprite->callback = AnimFlatterConfettiStep; +} + +static void AnimFlatterConfettiStep(struct Sprite *sprite) +{ + if (sprite->data[2] == 0) + { + sprite->pos2.x += sprite->data[0] >> 8; + sprite->pos2.y -= sprite->data[1] >> 8; + } + else + { + sprite->pos2.x -= sprite->data[0] >> 8; + sprite->pos2.y -= sprite->data[1] >> 8; + } + + sprite->data[0] -= 22; + sprite->data[1] -= 48; + if (sprite->data[0] < 0) + sprite->data[0] = 0; + + if (++sprite->data[3] == 31) + DestroyAnimSprite(sprite); +} + +// Uses a spotlight sprite as a light mask to illuminate the target mon. The spotlight grows and shrinks. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: duration of fully-opened spotlight +void AnimFlatterSpotlight(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H); + SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V); + + sprite->data[0] = gBattleAnimArgs[2]; + InitSpritePosToAnimTarget(sprite, FALSE); + sprite->oam.objMode = ST_OAM_OBJ_WINDOW; + sprite->invisible = 1; + sprite->callback = AnimFlatterSpotlightStep; +} + +static void AnimFlatterSpotlightStep(struct Sprite *sprite) +{ + switch (sprite->data[1]) + { + case 0: + sprite->invisible = 0; + if (sprite->affineAnimEnded) + sprite->data[1]++; + break; + case 1: + if (--sprite->data[0] == 0) + { + ChangeSpriteAffineAnim(sprite, 1); + sprite->data[1]++; + } + break; + case 2: + if (sprite->affineAnimEnded) + { + sprite->invisible = 1; + sprite->data[1]++; + } + break; + case 3: + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON); + DestroyAnimSprite(sprite); + break; + } +} + +// Spins an orb around the attacking mon, while its path radius grows and shrinks. +// arg 0: duration +// arg 1: initial wave offset +void AnimReversalOrb(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->callback = AnimReversalOrbStep; + sprite->callback(sprite); +} + +static void AnimReversalOrbStep(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[1], sprite->data[2] >> 8); + sprite->pos2.y = Cos(sprite->data[1], sprite->data[3] >> 8); + sprite->data[1] = (sprite->data[1] + 9) & 0xFF; + + if ((u16)sprite->data[1] < 64 || sprite->data[1] > 195) + sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 1; + else + sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) + 1; + + if (!sprite->data[5]) + { + sprite->data[2] += 0x400; + sprite->data[3] += 0x100; + sprite->data[4]++; + if (sprite->data[4] == sprite->data[0]) + { + sprite->data[4] = 0; + sprite->data[5] = 1; + } + } + else if (sprite->data[5] == 1) + { + sprite->data[2] -= 0x400; + sprite->data[3] -= 0x100; + sprite->data[4]++; + if (sprite->data[4] == sprite->data[0]) + DestroyAnimSprite(sprite); + } +} + +// Copies the target mon's sprite, and makes a white silhouette that shrinks away. +void AnimTask_RolePlaySilhouette(u8 taskId) +{ + u8 isBackPic; + u32 personality; + u32 otId; + u16 species; + s16 xOffset; + u32 priority; + u8 spriteId; + s16 coord1, coord2; + + GetAnimBattlerSpriteId(ANIM_ATTACKER); + if (IsContest()) + { + isBackPic = 1; + personality = gContestResources->field_18->unk10; + otId = gContestResources->field_18->unkC; + species = gContestResources->field_18->unk2; + xOffset = 20; + priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + isBackPic = 0; + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); + otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); + if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE) + { + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + else + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + } + else + { + species = gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies; + } + + xOffset = 20; + priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); + } + else + { + isBackPic = 1; + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); + otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); + if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE) + { + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + else + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + } + else + { + species = gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies; + } + + xOffset = -20; + priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); + } + } + + coord1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + coord2 = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + spriteId = sub_80A8394(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, otId, gBattleAnimTarget, 1); + + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND; + FillPalette(RGB_WHITE, (gSprites[spriteId].oam.paletteNum << 4) + 0x100, 32); + gSprites[spriteId].oam.priority = priority; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1])); + + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].func = AnimTask_RolePlaySilhouetteStep1; +} + +static void AnimTask_RolePlaySilhouetteStep1(u8 taskId) +{ + if (gTasks[taskId].data[10]++ > 1) + { + gTasks[taskId].data[10] = 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] == 10) + { + gTasks[taskId].data[10] = 256; + gTasks[taskId].data[11] = 256; + gTasks[taskId].func = AnimTask_RolePlaySilhouetteStep2; + } + } +} + +static void AnimTask_RolePlaySilhouetteStep2(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[0]; + gTasks[taskId].data[10] -= 16; + gTasks[taskId].data[11] += 128; + gSprites[spriteId].oam.affineMode |= ST_OAM_AFFINE_DOUBLE_MASK; + TrySetSpriteRotScale(&gSprites[spriteId], TRUE, gTasks[taskId].data[10], gTasks[taskId].data[11], 0); + if (++gTasks[taskId].data[12] == 9) + { + sub_80A749C(&gSprites[spriteId]); + DestroySpriteAndFreeResources_(&gSprites[spriteId]); + gTasks[taskId].func = DestroyAnimVisualTaskAndDisableBlend; + } +} + +// Performs a wavy transformation on the mon's sprite, and fades out. +// arg 0: which battler +void AnimTask_AcidArmor(u8 taskId) +{ + u8 battler; + u16 bgX, bgY; + s16 y, i; + struct ScanlineEffectParams scanlineParams; + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 16; + task->data[4] = 0; + task->data[5] = battler; + task->data[6] = 32; + task->data[7] = 0; + task->data[8] = 24; + + if (GetBattlerSide(battler) == B_SIDE_OPPONENT) + task->data[8] *= -1; + + task->data[13] = GetBattlerYCoordWithElevation(battler) - 34; + if (task->data[13] < 0) + task->data[13] = 0; + + task->data[14] = task->data[13] + 66; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (GetBattlerSpriteBGPriorityRank(battler) == 1) + { + scanlineParams.dmaDest = ®_BG1HOFS; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1); + bgX = gBattle_BG1_X; + bgY = gBattle_BG1_Y; + } + else + { + scanlineParams.dmaDest = ®_BG2HOFS; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2); + bgX = gBattle_BG2_X; + bgY = gBattle_BG2_Y; + } + + for (y = 0, i = 0; y < 160; y++, i += 2) + { + gScanlineEffectRegBuffers[0][i] = bgX; + gScanlineEffectRegBuffers[1][i] = bgX; + gScanlineEffectRegBuffers[0][i + 1] = bgY; + gScanlineEffectRegBuffers[1][i + 1] = bgY; + } + + scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_32BIT; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + ScanlineEffect_SetParams(scanlineParams); + task->func = AnimTask_AcidArmorStep; +} + +static void AnimTask_AcidArmorStep(u8 taskId) +{ + struct Task *task; + s16 var1; + s16 var2; + s16 bgX, bgY; + s16 offset; + s16 var0; + s16 i; + s16 sineIndex; + s16 var3; + + task = &gTasks[taskId]; + if (GetBattlerSpriteBGPriorityRank(task->data[5]) == 1) + { + bgX = gBattle_BG1_X; + bgY = gBattle_BG1_Y; + } + else + { + bgX = gBattle_BG2_X; + bgY = gBattle_BG2_Y; + } + + switch (task->data[0]) + { + case 0: + offset = task->data[14] * 2; + var1 = 0; + var2 = 0; + i = 0; + task->data[1] = (task->data[1] + 2) & 0xFF; + sineIndex = task->data[1]; + task->data[9] = 0x7E0 / task->data[6]; + task->data[10] = -((task->data[7] * 2) / task->data[9]); + task->data[11] = task->data[7]; + var3 = task->data[11] >> 5; + task->data[12] = var3; + var0 = task->data[14]; + while (var0 > task->data[13]) + { + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset + 1] = (i - var2) + bgY; + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset] = bgX + var3 + (gSineTable[sineIndex] >> 5); + sineIndex = (sineIndex + 10) & 0xFF; + task->data[11] += task->data[10]; + var3 = task->data[11] >> 5; + task->data[12] = var3; + + i++; + offset -= 2; + var1 += task->data[6]; + var2 = var1 >> 5; + var0--; + } + + var0 *= 2; + while (var0 >= 0) + { + gScanlineEffectRegBuffers[0][var0] = bgX + 240; + gScanlineEffectRegBuffers[1][var0] = bgX + 240; + var0 -= 2; + } + + if (++task->data[6] > 63) + { + task->data[6] = 64; + task->data[2]++; + if (task->data[2] & 1) + task->data[3]--; + else + task->data[4]++; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4])); + if (task->data[3] == 0 && task->data[4] == 16) + { + task->data[2] = 0; + task->data[3] = 0; + task->data[0]++; + } + } + else + { + task->data[7] += task->data[8]; + } + break; + case 1: + if (++task->data[2] > 12) + { + gScanlineEffect.state = 3; + task->data[2] = 0; + task->data[0]++; + } + break; + case 2: + task->data[2]++; + if (task->data[2] & 1) + task->data[3]++; + else + task->data[4]--; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4])); + if (task->data[3] == 16 && task->data[4] == 0) + { + task->data[2] = 0; + task->data[3] = 0; + task->data[0]++; + } + break; + case 3: + DestroyAnimVisualTask(taskId); + break; + } +} + +// Runs an affine animation that makes it look like the mon is inhaling deeply. +// arg 0: which battler +void AnimTask_DeepInhale(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + task->data[0] = 0; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(&gTasks[taskId], task->data[15], gDeepInhaleAffineAnimCmds); + task->func = AnimTask_DeepInhaleStep; +} + +static void AnimTask_DeepInhaleStep(u8 taskId) +{ + u16 var0; + + struct Task *task = &gTasks[taskId]; + var0 = task->data[0]; + task->data[0]++; + var0 -= 20; + if (var0 < 23) + { + if (++task->data[1] > 1) + { + task->data[1] = 0; + task->data[2]++; + if (task->data[2] & 1) + gSprites[task->data[15]].pos2.x = 1; + else + gSprites[task->data[15]].pos2.x = -1; + } + } + else + { + gSprites[task->data[15]].pos2.x = 0; + } + + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); +} + +static void InitYawnCloudPosition(struct Sprite *sprite, s16 startX, s16 startY, s16 destX, s16 destY, u16 duration) +{ + sprite->pos1.x = startX; + sprite->pos1.y = startY; + sprite->data[4] = startX << 4; + sprite->data[5] = startY << 4; + sprite->data[6] = ((destX - startX) << 4) / duration; + sprite->data[7] = ((destY - startY) << 4) / duration; +} + +static void UpdateYawnCloudPosition(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; +} + +// Drifts a cloud in a wavy path towards the target mon. +// arg 0: which affine anim +void AnimYawnCloud(struct Sprite *sprite) +{ + s16 destX = sprite->pos1.x; + s16 destY = sprite->pos1.y; + + SetSpriteCoordsToAnimAttackerCoords(sprite); + StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]); + InitYawnCloudPosition(sprite, sprite->pos1.x, sprite->pos1.y, destX, destY, 64); + sprite->data[0] = 0; + sprite->callback = AnimYawnCloudStep; +} + +static void AnimYawnCloudStep(struct Sprite *sprite) +{ + int index; + + sprite->data[0]++; + index = (sprite->data[0] * 8) & 0xFF; + UpdateYawnCloudPosition(sprite); + sprite->pos2.y = Sin(index, 8); + if (sprite->data[0] > 58) + { + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + sprite->data[2]++; + sprite->invisible = sprite->data[2] & 1; + if (sprite->data[2] > 3) + DestroySpriteAndMatrix(sprite); + } + } +} + +// Animates a cloud coming from the smoke ball. +// arg 0: ? +// arg 1: initial x pixel offset +// arg 2: initial y pixel offset +// arg 3: ? +void AnimSmokeBallEscapeCloud(struct Sprite *sprite) +{ + sprite->data[0] = gBattleAnimArgs[3]; + StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]); + if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER) + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2]; + sprite->callback = sub_80B1D3C; +} + +static void sub_80E1990(u8 taskId) +{ + u16 var0 = 0; + u16 var1 = 0; + + gTasks[taskId].data[0]--; + if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1)) + { + if (gTasks[taskId].data[9] == 0) + { + gTasks[taskId].data[9] = gTasks[taskId].data[4]; + gTasks[taskId].data[4] = -gTasks[taskId].data[4]; + } + else + { + gTasks[taskId].data[9] = 0; + } + + if (gTasks[taskId].data[10] == 0) + { + gTasks[taskId].data[10] = gTasks[taskId].data[5]; + gTasks[taskId].data[5] = -gTasks[taskId].data[5]; + } + else + { + gTasks[taskId].data[10] = 0; + } + + gTasks[taskId].data[1] = gTasks[taskId].data[13]; + } + + var0 = gTasks[taskId].data[7]; + var1 = gTasks[taskId].data[8]; + if (gTasks[taskId].data[2] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] - (var0 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] + (var0 >> 8); + + if (gTasks[taskId].data[3] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] - (var1 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] + (var1 >> 8); + + if (gTasks[taskId].data[0] < 1) + { + DestroyTask(taskId); + gAnimVisualTaskCount--; + } +} + +static void sub_80E1AD8(u8 taskId) +{ + u16 var0 = 0; + u16 var1 = 0; + + gTasks[taskId].data[0]--; + if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1)) + { + if (gTasks[taskId].data[9] == 0) + { + gTasks[taskId].data[9] = gTasks[taskId].data[4]; + gTasks[taskId].data[4] = -gTasks[taskId].data[4]; + } + else + { + gTasks[taskId].data[9] = var0; + } + + if (gTasks[taskId].data[10] == 0) + { + gTasks[taskId].data[10] = gTasks[taskId].data[5]; + gTasks[taskId].data[5] = -gTasks[taskId].data[5]; + } + else + { + gTasks[taskId].data[10] = 0; + } + + gTasks[taskId].data[1] = gTasks[taskId].data[13]; + } + + var0 = (gTasks[taskId].data[2] & 0x7FFF) + gTasks[taskId].data[7]; + var1 = (gTasks[taskId].data[3] & 0x7FFF) + gTasks[taskId].data[8]; + if (gTasks[taskId].data[2] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] - (var0 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] + (var0 >> 8); + + if (gTasks[taskId].data[3] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] - (var1 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] + (var1 >> 8); + + gTasks[taskId].data[7] = var0; + gTasks[taskId].data[8] = var1; + if (gTasks[taskId].data[0] < 1) + { + gTasks[taskId].data[0] = 30; + gTasks[taskId].data[13] = 0; + gTasks[taskId].func = sub_80E1990; + } +} + +void sub_80E1C48(u8 taskId) +{ + gTasks[taskId].data[15] = gBattlerSpriteIds[gBattleAnimAttacker]; + gTasks[taskId].data[14] = gBattleAnimArgs[0]; + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[13] = gBattleAnimArgs[6]; + if (gBattleAnimArgs[3]) + gTasks[taskId].data[6] = gTasks[taskId].data[6] | -0x8000; + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + gTasks[taskId].data[2] = gBattleAnimArgs[1]; + gTasks[taskId].data[3] = gBattleAnimArgs[2]; + } + else + { + if (gBattleAnimArgs[1] & 0x8000) + gTasks[taskId].data[2] = gBattleAnimArgs[1] & 0x7FFF; + else + gTasks[taskId].data[2] = gBattleAnimArgs[1] | -0x8000; + + if (gBattleAnimArgs[2] & 0x8000) + gTasks[taskId].data[3] = gBattleAnimArgs[2] & 0x7FFF; + else + gTasks[taskId].data[3] = gBattleAnimArgs[2] | -0x8000; + } + + gTasks[taskId].data[8] = 0; + gTasks[taskId].data[7] = 0; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = gBattleAnimArgs[5]; + gTasks[taskId].func = sub_80E1AD8; +} + +// Squishes the mon vertically and emits sweat droplets a few times. +// arg 0: battler +// arg 1: num squishes +void AnimTask_SquishAndSweatDroplets(u8 taskId) +{ + u8 battler; + struct Task *task = &gTasks[taskId]; + + if (!gBattleAnimArgs[1]) + DestroyAnimVisualTask(taskId); + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = gBattleAnimArgs[1]; + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + task->data[4] = GetBattlerSpriteCoord(battler, BATTLER_COORD_X); + task->data[5] = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y); + task->data[6] = GetBattlerSpriteSubpriority(battler); + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(task, task->data[15], gFacadeSquishAffineAnimCmds); + task->func = AnimTask_SquishAndSweatDropletsStep; +} + +static void AnimTask_SquishAndSweatDropletsStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[1]++; + if (task->data[1] == 6) + CreateSweatDroplets(taskId, TRUE); + + if (task->data[1] == 18) + CreateSweatDroplets(taskId, FALSE); + + if (!RunAffineAnimFromTaskData(task)) + { + if (--task->data[3] == 0) + { + task->data[0]++; + } + else + { + task->data[1] = 0; + PrepareAffineAnimInTaskData(task, task->data[15], gFacadeSquishAffineAnimCmds); + } + } + break; + case 1: + if (task->data[2] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void CreateSweatDroplets(u8 taskId, bool8 arg1) +{ + u8 i; + s8 xOffset, yOffset; + struct Task *task; + s16 xCoords[4]; + s16 yCoords[2]; + + task = &gTasks[taskId]; + if (!arg1) + { + xOffset = 18; + yOffset = -20; + } + else + { + xOffset = 30; + yOffset = 20; + } + + xCoords[0] = task->data[4] - xOffset; + xCoords[1] = task->data[4] - xOffset - 4; + xCoords[2] = task->data[4] + xOffset; + xCoords[3] = task->data[4] + xOffset + 4; + yCoords[0] = task->data[5] + yOffset; + yCoords[1] = task->data[5] + yOffset + 6; + + for (i = 0; i < 4; i++) + { + u8 spriteId = CreateSprite(&gFacadeSweatDrop, xCoords[i], yCoords[i & 1], task->data[6] - 5); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].data[0] = 0; + gSprites[spriteId].data[1] = i < 2 ? -2 : 2; + gSprites[spriteId].data[2] = -1; + gSprites[spriteId].data[3] = taskId; + gSprites[spriteId].data[4] = 2; + task->data[2]++; + } + } +} + +void AnimFacadeSweatDrop(struct Sprite *sprite) +{ + sprite->pos1.x += sprite->data[1]; + sprite->pos1.y += sprite->data[2]; + if (++sprite->data[0] > 6) + { + gTasks[sprite->data[3]].data[sprite->data[4]]--; + DestroySprite(sprite); + } +} + +// Blends the mon sprite's color with a rotating set of colors. +// arg 0: battler +// arg 1: duration +void AnimTask_FacadeColorBlend(u8 taskId) +{ + u8 spriteId; + + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + gTasks[taskId].data[2] = 0x100 + gSprites[spriteId].oam.paletteNum * 16; + gTasks[taskId].func = AnimTask_FacadeColorBlendStep; +} + +static void AnimTask_FacadeColorBlendStep(u8 taskId) +{ + if (gTasks[taskId].data[1]) + { + BlendPalette(gTasks[taskId].data[2], 16, 8, gFacadeBlendColors[gTasks[taskId].data[0]]); + if (++gTasks[taskId].data[0] > 23) + gTasks[taskId].data[0] = 0; + + gTasks[taskId].data[1]--; + } + else + { + BlendPalette(gTasks[taskId].data[2], 16, 0, RGB(0, 0, 0)); + DestroyAnimVisualTask(taskId); + } +} + +void sub_80E2084(u8 taskId) +{ + sub_80BBA20(taskId, + 0, + 0x1A0, + gBattleAnimAttacker, + gBattleAnimArgs[0], + 10, + 2, + 30, + gCureBubblesGfx, + gCureBubblesTilemap, + gCureBubblesPal); +} + +// Moves a noise line from the mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: which direction (0 = upward, 1 = downward, 2 = horizontal) +void AnimRoarNoiseLine(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[0]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1]; + if (gBattleAnimArgs[2] == 0) + { + sprite->data[0] = 0x280; + sprite->data[1] = -0x280; + } + else if (gBattleAnimArgs[2] == 1) + { + sprite->vFlip = 1; + sprite->data[0] = 0x280; + sprite->data[1] = 0x280; + } + else + { + StartSpriteAnim(sprite, 1); + sprite->data[0] = 0x280; + } + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->data[0] = -sprite->data[0]; + sprite->hFlip = 1; + } + + sprite->callback = AnimRoarNoiseLineStep; +} + +static void AnimRoarNoiseLineStep(struct Sprite *sprite) +{ + sprite->data[6] += sprite->data[0]; + sprite->data[7] += sprite->data[1]; + sprite->pos2.x = sprite->data[6] >> 8; + sprite->pos2.y = sprite->data[7] >> 8; + if (++sprite->data[5] == 14) + DestroyAnimSprite(sprite); +} + +// Makes a series of dots in a trail from the attacker to the target. +// arg 0: unused +void AnimTask_GlareEyeDots(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (IsContest()) + { + task->data[5] = 8; + task->data[6] = 3; + task->data[7] = 1; + } + else + { + task->data[5] = 12; + task->data[6] = 3; + task->data[7] = 0; + } + + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 4; + else + task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 4; + + task->data[12] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 4; + task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); + task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); + task->func = AnimTask_GlareEyeDotsStep; +} + +static void AnimTask_GlareEyeDotsStep(u8 taskId) +{ + u8 i; + s16 x, y; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 3) + { + task->data[1] = 0; + GetGlareEyeDotCoords( + task->data[11], + task->data[12], + task->data[13], + task->data[14], + task->data[5], + task->data[2], + &x, + &y); + + for (i = 0; i < 2; i++) + { + u8 spriteId = CreateSprite(&gGlareEyeDotSpriteTemplate, x, y, 35); + if (spriteId != MAX_SPRITES) + { + if (task->data[7] == 0) + { + if (i == 0) + gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = -task->data[6]; + else + gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = task->data[6]; + } + else + { + if (i == 0) + { + gSprites[spriteId].pos2.x = -task->data[6]; + gSprites[spriteId].pos2.y = task->data[6]; + } + else + { + gSprites[spriteId].pos2.x = task->data[6]; + gSprites[spriteId].pos2.y = -task->data[6]; + } + } + + gSprites[spriteId].data[0] = 0; + gSprites[spriteId].data[1] = taskId; + gSprites[spriteId].data[2] = 10; + task->data[10]++; + } + } + + if (task->data[2] == task->data[5]) + task->data[0]++; + + task->data[2]++; + } + break; + case 1: + if (task->data[10] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void GetGlareEyeDotCoords(s16 arg0, s16 arg1, s16 arg2, s16 arg3, u8 arg4, u8 arg5, s16 *x, s16 *y) +{ + int x2; + int y2; + + if (arg5 == 0) + { + *x = arg0; + *y = arg1; + return; + } + + if (arg5 >= arg4) + { + *x = arg2; + *y = arg3; + return; + } + + arg4--; + x2 = (arg0 << 8) + arg5 * (((arg2 - arg0) << 8) / arg4); + y2 = (arg1 << 8) + arg5 * (((arg3 - arg1) << 8) / arg4); + *x = x2 >> 8; + *y = y2 >> 8; +} + +void AnimGlareEyeDot(struct Sprite *sprite) +{ + if (++sprite->data[0] > 36) + { + gTasks[sprite->data[1]].data[sprite->data[2]]--; + DestroySprite(sprite); + } +} + +// Moves a pawprint in a straight line. +// arg 0: initial x position +// arg 1: initial y position +// arg 2: destination x position +// arg 3: destination y position +// arg 4: duration +void AnimAssistPawprint(struct Sprite *sprite) +{ + sprite->pos1.x = gBattleAnimArgs[0]; + sprite->pos1.y = gBattleAnimArgs[1]; + sprite->data[2] = gBattleAnimArgs[2]; + sprite->data[4] = gBattleAnimArgs[3]; + sprite->data[0] = gBattleAnimArgs[4]; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->callback = InitAndRunAnimFastLinearTranslation; +} + +// Moves a ball in an arc twoards the target, and rotates the ball while arcing. +// No args. +void AnimTask_BarrageBall(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + task->data[12] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET); + task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); + task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT) / 4; + task->data[15] = CreateSprite(&gBarrageBallSpriteTemplate, task->data[11], task->data[12], GetBattlerSpriteSubpriority(gBattleAnimTarget) - 5); + if (task->data[15] != MAX_SPRITES) + { + gSprites[task->data[15]].data[0] = 16; + gSprites[task->data[15]].data[2] = task->data[13]; + gSprites[task->data[15]].data[4] = task->data[14]; + gSprites[task->data[15]].data[5] = -32; + InitAnimArcTranslation(&gSprites[task->data[15]]); + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + StartSpriteAffineAnim(&gSprites[task->data[15]], 1); + + task->func = AnimTask_BarrageBallStep; + } + else + { + DestroyAnimVisualTask(taskId); + } +} + +static void AnimTask_BarrageBallStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 1) + { + task->data[1] = 0; + TranslateAnimHorizontalArc(&gSprites[task->data[15]]); + if (++task->data[2] > 7) + task->data[0]++; + } + break; + case 1: + if (TranslateAnimHorizontalArc(&gSprites[task->data[15]])) + { + task->data[1] = 0; + task->data[2] = 0; + task->data[0]++; + } + break; + case 2: + if (++task->data[1] > 1) + { + task->data[1] = 0; + task->data[2]++; + gSprites[task->data[15]].invisible = task->data[2] & 1; + if (task->data[2] == 16) + { + FreeOamMatrix(gSprites[task->data[15]].oam.matrixNum); + DestroySprite(&gSprites[task->data[15]]); + task->data[0]++; + } + } + break; + case 3: + DestroyAnimVisualTask(taskId); + break; + } +} + +// Moves a hand back and forth in a squishing motion. +// arg 0: which battler +// arg 1: horizontal flip +// arg 2: num squishes +void AnimSmellingSaltsHand(struct Sprite *sprite) +{ + u8 battler; + + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + sprite->oam.tileNum += 16; + sprite->data[6] = gBattleAnimArgs[2]; + sprite->data[7] = gBattleAnimArgs[1] == 0 ? -1 : 1; + sprite->pos1.y = GetBattlerSpriteCoord(battler, 3); + if (gBattleAnimArgs[1] == 0) + { + sprite->oam.matrixNum |= ST_OAM_HFLIP; + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) - 8; + } + else + { + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) + 8; + } + + sprite->callback = AnimSmellingSaltsHand_Step; +} + +static void AnimSmellingSaltsHand_Step(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + sprite->pos2.x += sprite->data[7]; + if (++sprite->data[2] == 12) + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[1] == 8) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->pos2.x -= sprite->data[7] * 4; + if (++sprite->data[1] == 6) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 3: + sprite->pos2.x += sprite->data[7] * 3; + if (++sprite->data[1] == 8) + { + if (--sprite->data[6]) + { + sprite->data[1] = 0; + sprite->data[0]--; + } + else + { + DestroyAnimSprite(sprite); + } + } + break; + } +} + +// Squishes the mon horizontally a few times. +// arg 0: which mon +// arg 1: number of squishes +void AnimTask_SmellingSaltsSquish(u8 taskId) +{ + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + { + DestroyAnimVisualTask(taskId); + } + else + { + gTasks[taskId].data[0] = gBattleAnimArgs[1]; + gTasks[taskId].data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], gSmellingSaltsSquishAffineAnimCmds); + gTasks[taskId].func = AnimTask_SmellingSaltsSquishStep; + } +} + +static void AnimTask_SmellingSaltsSquishStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (++task->data[1] > 1) + { + task->data[1] = 0; + if (!(task->data[2] & 1)) + gSprites[task->data[15]].pos2.x = 2; + else + gSprites[task->data[15]].pos2.x = -2; + } + + if (!RunAffineAnimFromTaskData(task)) + { + gSprites[task->data[15]].pos2.x = 0; + if (--task->data[0]) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], gSmellingSaltsSquishAffineAnimCmds); + task->data[1] = 0; + task->data[2] = 0; + } + else + { + DestroyAnimVisualTask(taskId); + } + } +} + +// Blinks an exclamation image over the mon a few times. +// arg 0: which mon +// arg 1: blink delay +// arg 2: number of blinks +void AnimSmellingSaltExclamation(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP); + } + + if (sprite->pos1.y < 8) + sprite->pos1.y = 8; + + sprite->data[0] = 0; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->data[2] = 0; + sprite->data[3] = gBattleAnimArgs[2]; + sprite->callback = AnimSmellingSaltExclamationStep; +} + +static void AnimSmellingSaltExclamationStep(struct Sprite *sprite) +{ + if (++sprite->data[0] >= sprite->data[1]) + { + sprite->data[0] = 0; + sprite->data[2] = (sprite->data[2] + 1) & 1; + sprite->invisible = sprite->data[2]; + if (sprite->data[2] && --sprite->data[3] == 0) + DestroyAnimSprite(sprite); + } +} + +// Claps a hand several times. +// arg 0: which hand +// arg 1: +void AnimHelpingHandClap(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->oam.matrixNum |= ST_OAM_HFLIP; + sprite->pos1.x = 100; + sprite->data[7] = 1; + } + else + { + sprite->pos1.x = 140; + sprite->data[7] = -1; + } + + sprite->pos1.y = 56; + sprite->callback = AnimHelpingHandClapStep; +} + +static void AnimHelpingHandClapStep(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos1.y -= sprite->data[7] * 2; + if (sprite->data[1] & 1) + sprite->pos1.x -= sprite->data[7] * 2; + + if (++sprite->data[1] == 9) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[1] == 4) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->data[1]++; + sprite->pos1.y += sprite->data[7] * 3; + sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); + if (sprite->data[1] == 12) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 3: + if (++sprite->data[1] == 2) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 4: + sprite->data[1]++; + sprite->pos1.y -= sprite->data[7] * 3; + sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); + if (sprite->data[1] == 12) + sprite->data[0]++; + break; + case 5: + sprite->data[1]++; + sprite->pos1.y += sprite->data[7] * 3; + sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); + if (sprite->data[1] == 15) + sprite->oam.tileNum += 16; + + if (sprite->data[1] == 18) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 6: + sprite->pos1.x += sprite->data[7] * 6; + if (++sprite->data[1] == 9) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 7: + sprite->pos1.x += sprite->data[7] * 2; + if (++sprite->data[1] == 1) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 8: + sprite->pos1.x -= sprite->data[7] * 3; + if (++sprite->data[1] == 5) + DestroyAnimSprite(sprite); + break; + } +} + +// Repeatedly moves the attacking mon in a horizontal lunging motion. +// No args. +void AnimTask_HelpingHandAttackerMovement(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER); + if (!IsContest()) + { + if (IsDoubleBattle() == TRUE) + { + int x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + int y = GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimAttacker), 0); + if (x > y) + task->data[14] = 1; + else + task->data[14] = -1; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + task->data[14] = -1; + else + task->data[14] = 1; + } + } + else + { + task->data[14] = 1; + } + + task->func = AnimTask_HelpingHandAttackerMovementStep; +} + +static void AnimTask_HelpingHandAttackerMovementStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] == 13) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 1: + gSprites[task->data[15]].pos2.x -= task->data[14] * 3; + if (++task->data[1] == 6) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 2: + gSprites[task->data[15]].pos2.x += task->data[14] * 3; + if (++task->data[1] == 6) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 3: + if (++task->data[1] == 2) + { + task->data[1] = 0; + if (task->data[2] == 0) + { + task->data[2]++; + task->data[0] = 1; + } + else + { + task->data[0]++; + } + } + break; + case 4: + gSprites[task->data[15]].pos2.x += task->data[14]; + if (++task->data[1] == 3) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 5: + if (++task->data[1] == 6) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 6: + gSprites[task->data[15]].pos2.x -= task->data[14] * 4; + if (++task->data[1] == 5) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 7: + gSprites[task->data[15]].pos2.x += task->data[14] * 4; + if (++task->data[1] == 5) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 8: + gSprites[task->data[15]].pos2.x = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +// Moves a magnifying glass around in straight lines. +// arg 0: magnifying glass target mon +void AnimForesightMagnifyingGlass(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == ANIM_ATTACKER) + { + InitSpritePosToAnimAttacker(sprite, TRUE); + sprite->data[7] = gBattleAnimAttacker; + } + else + { + sprite->data[7] = gBattleAnimTarget; + } + + if (GetBattlerSide(sprite->data[7]) == B_SIDE_OPPONENT) + sprite->oam.matrixNum = ST_OAM_HFLIP; + + sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]); + sprite->oam.objMode = ST_OAM_OBJ_BLEND; + sprite->callback = AnimForesightMagnifyingGlassStep; +} + +static void AnimForesightMagnifyingGlassStep(struct Sprite *sprite) +{ + u16 x, y; + + switch (sprite->data[5]) + { + case 0: + switch (sprite->data[6]) + { + default: + sprite->data[6] = 0; + case 0: + case 4: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 5) - 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 3) - 4; + break; + case 1: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 5) - 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 2) + 4; + break; + case 2: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 4) + 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 3) - 4; + break; + case 3: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 4) + 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 2) - 4; + break; + case 5: + x = GetBattlerSpriteCoord(sprite->data[7], 2); + y = GetBattlerSpriteCoord(sprite->data[7], 3); + break; + } + + if (sprite->data[6] == 4) + sprite->data[0] = 24; + else if (sprite->data[6] == 5) + sprite->data[0] = 6; + else + sprite->data[0] = 12; + + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = x; + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = y; + InitAnimLinearTranslation(sprite); + sprite->data[5]++; + break; + case 1: + if (AnimTranslateLinear(sprite)) + { + switch (sprite->data[6]) + { + default: + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[0] = 0; + sprite->data[5]++; + sprite->data[6]++; + break; + case 4: + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[5] = 0; + sprite->data[6]++; + break; + case 5: + sprite->data[0] = 0; + sprite->data[1] = 16; + sprite->data[2] = 0; + sprite->data[5] = 3; + break; + } + } + break; + case 2: + if (++sprite->data[0] == 4) + sprite->data[5] = 0; + break; + case 3: + if (!(sprite->data[0] & 1)) + sprite->data[1]--; + else + sprite->data[2]++; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], sprite->data[2])); + if (++sprite->data[0] == 32) + { + sprite->invisible = 1; + sprite->data[5]++; + } + break; + case 4: + DestroyAnimSprite(sprite); + break; + } +} + +static void AnimMeteorMashStarStep(struct Sprite *sprite) +{ + sprite->pos2.x = ((sprite->data[2] - sprite->data[0]) * sprite->data[5]) / sprite->data[4]; + sprite->pos2.y = ((sprite->data[3] - sprite->data[1]) * sprite->data[5]) / sprite->data[4]; + if (!(sprite->data[5] & 1)) + { + CreateSprite( + &gMiniTwinklingStarSpriteTemplate, + sprite->pos1.x + sprite->pos2.x, + sprite->pos1.y + sprite->pos2.y, 5); + } + + if (sprite->data[5] == sprite->data[4]) + DestroyAnimSprite(sprite); + + sprite->data[5]++; +} + +// Moves a shooting star across the screen that leaves little twinkling stars behind its path. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +// arg 2: destination x pixel offset +// arg 3: destination y pixel offset +// arg 4: duration +void AnimMeteorMashStar(struct Sprite *sprite) +{ + s16 y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); // unused local variable + s16 x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); // unused local variable + + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER || IsContest()) + { + sprite->data[0] = sprite->pos1.x - gBattleAnimArgs[0]; + sprite->data[2] = sprite->pos1.x - gBattleAnimArgs[2]; + } + else + { + sprite->data[0] = sprite->pos1.x + gBattleAnimArgs[0]; + sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; + } + + sprite->data[1] = sprite->pos1.y + gBattleAnimArgs[1]; + sprite->data[3] = sprite->pos1.y + gBattleAnimArgs[3]; + sprite->data[4] = gBattleAnimArgs[4]; + sprite->pos1.x = sprite->data[0]; + sprite->pos1.y = sprite->data[1]; + sprite->callback = AnimMeteorMashStarStep; +} + +void AnimTask_MonToSubstitute(u8 taskId) +{ + int i; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + + if (gTasks[taskId].data[0] == 0) + { + PrepareBattlerSpriteForRotScale(spriteId, FALSE); + gTasks[taskId].data[1] = 0x100; + gTasks[taskId].data[2] = 0x100; + gTasks[taskId].data[0]++; + } + else if (gTasks[taskId].data[0] == 1) + { + gTasks[taskId].data[1] += 0x60; + gTasks[taskId].data[2] -= 0xD; + SetSpriteRotScale(spriteId, gTasks[taskId].data[1], gTasks[taskId].data[2], 0); + if (++gTasks[taskId].data[3] == 9) + { + gTasks[taskId].data[3] = 0; + ResetSpriteRotScale(spriteId); + gSprites[spriteId].invisible = 1; + gTasks[taskId].data[0]++; + } + } + else + { + LoadBattleMonGfxAndAnimate(gBattleAnimAttacker, 0, spriteId); + for (i = 0; i < 16; i++) + gTasks[taskId].data[i] = 0; + + gTasks[taskId].func = AnimTask_MonToSubstituteDoll; + } +} + +static void AnimTask_MonToSubstituteDoll(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + + switch (gTasks[taskId].data[0]) + { + case 0: + gSprites[spriteId].pos2.y = -200; + gSprites[spriteId].pos2.x = 200; + gSprites[spriteId].invisible = 0; + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[0]++; + break; + case 1: + gTasks[taskId].data[10] += 112; + gSprites[spriteId].pos2.y += gTasks[taskId].data[10] >> 8; + if (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y >= -32) + gSprites[spriteId].pos2.x = 0; + + if (gSprites[spriteId].pos2.y > 0) + gSprites[spriteId].pos2.y = 0; + + if (gSprites[spriteId].pos2.y == 0) + { + PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(-64)); + gTasks[taskId].data[10] -= 0x800; + gTasks[taskId].data[0]++; + } + break; + case 2: + gTasks[taskId].data[10] -= 112; + if (gTasks[taskId].data[10] < 0) + gTasks[taskId].data[10] = 0; + + gSprites[spriteId].pos2.y -= gTasks[taskId].data[10] >> 8; + if (gTasks[taskId].data[10] == 0) + gTasks[taskId].data[0]++; + break; + case 3: + gTasks[taskId].data[10] += 112; + gSprites[spriteId].pos2.y += gTasks[taskId].data[10] >> 8; + if (gSprites[spriteId].pos2.y > 0) + gSprites[spriteId].pos2.y = 0; + + if (gSprites[spriteId].pos2.y == 0) + { + PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(-64)); + DestroyAnimVisualTask(taskId); + } + break; + } +} + +// Moves down an X that flickers and disappears. +// No args. +void AnimBlockX(struct Sprite *sprite) +{ + s16 y; + + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 2; + y = -144; + } + else + { + sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + 2; + y = -96; + } + + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->pos2.y = y; + sprite->callback = AnimBlockXStep; +} + +static void AnimBlockXStep(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos2.y += 10; + if (sprite->pos2.y >= 0) + { + PlaySE12WithPanning(SE_W166, BattleAnimAdjustPanning(63)); + sprite->pos2.y = 0; + sprite->data[0]++; + } + break; + case 1: + sprite->data[1] += 4; + sprite->pos2.y = -(gSineTable[sprite->data[1]] >> 3); + if (sprite->data[1] > 0x7F) + { + PlaySE12WithPanning(SE_W166, BattleAnimAdjustPanning(63)); + sprite->data[1] = 0; + sprite->pos2.y = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->data[1] += 6; + sprite->pos2.y = -(gSineTable[sprite->data[1]] >> 4); + if (sprite->data[1] > 0x7F) + { + sprite->data[1] = 0; + sprite->pos2.y = 0; + sprite->data[0]++; + } + break; + case 3: + if (++sprite->data[1] > 8) + { + PlaySE12WithPanning(SE_W043, BattleAnimAdjustPanning(63)); + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 4: + if (++sprite->data[1] > 8) + { + sprite->data[1] = 0; + sprite->data[2]++; + sprite->invisible = sprite->data[2] & 1; + if (sprite->data[2] == 7) + DestroyAnimSprite(sprite); + } + break; + } +} + +// Quickly moves two clones of the target mon back and forth. +// No args. +void AnimTask_OdorSleuthMovement(u8 taskId) +{ + s16 spriteId1, spriteId2; + + if (IsContest()) + { + DestroyAnimVisualTask(taskId); + return; + } + + spriteId1 = CloneBattlerSpriteWithBlend(ANIM_TARGET); + if (spriteId1 < 0) + { + DestroyAnimVisualTask(taskId); + return; + } + + spriteId2 = CloneBattlerSpriteWithBlend(ANIM_TARGET); + if (spriteId2 < 0) + { + obj_delete_but_dont_free_vram(&gSprites[spriteId1]); + DestroyAnimVisualTask(taskId); + return; + } + + gSprites[spriteId2].pos2.x += 24; + gSprites[spriteId1].pos2.x -= 24; + gSprites[spriteId2].data[0] = 0; + gSprites[spriteId1].data[0] = 0; + gSprites[spriteId2].data[1] = 0; + gSprites[spriteId1].data[1] = 0; + gSprites[spriteId2].data[2] = 0; + gSprites[spriteId1].data[2] = 0; + gSprites[spriteId2].data[3] = 16; + gSprites[spriteId1].data[3] = -16; + gSprites[spriteId2].data[4] = 0; + gSprites[spriteId1].data[4] = 128; + gSprites[spriteId2].data[5] = 24; + gSprites[spriteId1].data[5] = 24; + gSprites[spriteId2].data[6] = taskId; + gSprites[spriteId1].data[6] = taskId; + gSprites[spriteId2].data[7] = 0; + gSprites[spriteId1].data[7] = 0; + gTasks[taskId].data[0] = 2; + + if (!gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].invisible) + { + gSprites[spriteId2].invisible = 0; + gSprites[spriteId1].invisible = 1; + } + else + { + gSprites[spriteId2].invisible = 1; + gSprites[spriteId1].invisible = 1; + } + + gSprites[spriteId2].oam.objMode = ST_OAM_OBJ_NORMAL; + gSprites[spriteId1].oam.objMode = ST_OAM_OBJ_NORMAL; + gSprites[spriteId2].callback = MoveOdorSleuthClone; + gSprites[spriteId1].callback = MoveOdorSleuthClone; + gTasks[taskId].func = AnimTask_OdorSleuthMovementWaitFinish; +} + +static void AnimTask_OdorSleuthMovementWaitFinish(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + DestroyAnimVisualTask(taskId); +} + +static void MoveOdorSleuthClone(struct Sprite *sprite) +{ + int zero = 0; + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + if (!gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].invisible) + sprite->invisible ^= 1; + } + + sprite->data[4] = sprite->data[4] + sprite->data[3]; + sprite->data[4] &= 0xFF; + sprite->pos2.x = Cos(sprite->data[4], sprite->data[5]); + switch (sprite->data[0]) + { + case 0: + if (++sprite->data[2] == 60) + { + sprite->data[2] = 0; + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[2] > 0) + { + sprite->data[2] = 0; + sprite->data[5] -= 2; + if (sprite->data[5] < 0) + { + gTasks[sprite->data[6]].data[sprite->data[7]]--; + obj_delete_but_dont_free_vram(sprite); + } + } + break; + } +} + +void AnimTask_GetReturnPowerLevel(u8 taskId) +{ + gBattleAnimArgs[7] = 0; + if (gAnimFriendship < 60) + gBattleAnimArgs[7] = 0; + if (gAnimFriendship > 60 && gAnimFriendship < 92) + gBattleAnimArgs[7] = 1; + if (gAnimFriendship > 91 && gAnimFriendship < 201) + gBattleAnimArgs[7] = 2; + if (gAnimFriendship > 200) + gBattleAnimArgs[7] = 3; + + DestroyAnimVisualTask(taskId); +} + +// Makes the mon run out of screen, run past the opposing mon, and return to its original position. +// No args. +void AnimTask_SnatchOpposingMonMove(u8 taskId) +{ + u8 spriteId, spriteId2; + int personality; + int otId; + u16 species; + u8 subpriority; + u8 isBackPic; + s16 x; + + switch (gTasks[taskId].data[0]) + { + case 0: + spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + gTasks[taskId].data[1] += 0x800; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.x += (gTasks[taskId].data[1] >> 8); + else + gSprites[spriteId].pos2.x -= (gTasks[taskId].data[1] >> 8); + + gTasks[taskId].data[1] &= 0xFF; + x = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + if ((u16)(x + 32) > 304) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 1: + if (IsContest()) + { + personality = gContestResources->field_18->unk8; + otId = gContestResources->field_18->unkC; + species = gContestResources->field_18->species; + subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker); + isBackPic = 0; + x = -32; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); + otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); + if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + else + species = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies; + + subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority + 1; + isBackPic = 0; + x = 272; + } + else + { + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); + otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); + if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + else + species = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies; + + subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority - 1; + isBackPic = 1; + x = -32; + } + } + + spriteId2 = sub_80A8394(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, otId, gBattleAnimAttacker, 0); + if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies != SPECIES_NONE) + BlendPalette((gSprites[spriteId2].oam.paletteNum * 16) | 0x100, 16, 6, RGB_WHITE); + + gTasks[taskId].data[15] = spriteId2; + gTasks[taskId].data[0]++; + break; + case 2: + spriteId2 = gTasks[taskId].data[15]; + gTasks[taskId].data[1] += 0x800; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + gSprites[spriteId2].pos2.x -= (gTasks[taskId].data[1] >> 8); + else + gSprites[spriteId2].pos2.x += (gTasks[taskId].data[1] >> 8); + + gTasks[taskId].data[1] &= 0xFF; + x = gSprites[spriteId2].pos1.x + gSprites[spriteId2].pos2.x; + if (gTasks[taskId].data[14] == 0) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + if (x < GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X)) + { + gTasks[taskId].data[14]++; + gBattleAnimArgs[7] = 0xFFFF; + } + } + else + { + if (x > GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X)) + { + gTasks[taskId].data[14]++; + gBattleAnimArgs[7] = 0xFFFF; + } + } + } + + if ((u16)(x + 32) > 304) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 3: + spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + spriteId2 = gTasks[taskId].data[15]; + DestroySpriteAndFreeResources_(&gSprites[spriteId2]); + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.x = -gSprites[spriteId].pos1.x - 32; + else + gSprites[spriteId].pos2.x = 272 - gSprites[spriteId].pos1.x; + + gTasks[taskId].data[0]++; + break; + case 4: + spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER); + gTasks[taskId].data[1] += 0x800; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + gSprites[spriteId].pos2.x += (gTasks[taskId].data[1] >> 8); + if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x >= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X)) + gSprites[spriteId].pos2.x = 0; + } + else + { + gSprites[spriteId].pos2.x -= (gTasks[taskId].data[1] >> 8); + if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x <= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X)) + gSprites[spriteId].pos2.x = 0; + } + + gTasks[taskId].data[1] = (u8)gTasks[taskId].data[1]; + if (gSprites[spriteId].pos2.x == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_80E3E84(struct Sprite *sprite) +{ + switch (sprite->data[7]) + { + case 0: + if (gBattleAnimArgs[7] == -1) + { + PlaySE12WithPanning(SE_W233, BattleAnimAdjustPanning(63)); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 16; + sprite->data[0] = -32; + sprite->data[7]++; + sprite->invisible = 0; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT && !IsContest()) + sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority - 1; + } + else + { + sprite->invisible = 1; + } + break; + case 1: + sprite->pos2.y = Sin(sprite->data[1], sprite->data[0]); + sprite->data[1] += 5; + if (sprite->data[1] > 0x7F) + { + sprite->data[0] = sprite->data[0] / 2; + sprite->data[3]++; + sprite->data[1] -= 0x7F; + } + + sprite->data[2] += 0x100; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + sprite->pos2.x -= (sprite->data[2] >> 8); + else + sprite->pos2.x += (sprite->data[2] >> 8); + + sprite->data[2] &= 0xFF; + if (sprite->data[3] == 2) + DestroyAnimSprite(sprite); + break; + } +} + +// Quickly moves the mon towards its partner and back. +// No args. +void AnimTask_SnatchPartnerMove(u8 taskId) +{ + s16 attackerX, targetX; + u8 spriteId; + + switch (gTasks[taskId].data[15]) + { + case 0: + attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); + targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + gTasks[taskId].data[0] = 6; + if (attackerX > targetX) + gTasks[taskId].data[0] *= -1; + + gTasks[taskId].data[1] = attackerX; + gTasks[taskId].data[2] = targetX; + gTasks[taskId].data[15]++; + break; + case 1: + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + gSprites[spriteId].pos2.x += gTasks[taskId].data[0]; + if (gTasks[taskId].data[0] > 0) + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x >= gTasks[taskId].data[2]) + gTasks[taskId].data[15]++; + } + else + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x <= gTasks[taskId].data[2]) + gTasks[taskId].data[15]++; + } + break; + case 2: + gTasks[taskId].data[0] *= -1; + gTasks[taskId].data[15]++; + break; + case 3: + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + gSprites[spriteId].pos2.x += gTasks[taskId].data[0]; + if (gTasks[taskId].data[0] < 0) + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x <= gTasks[taskId].data[1]) + gTasks[taskId].data[15]++; + } + else + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x >= gTasks[taskId].data[1]) + gTasks[taskId].data[15]++; + } + break; + case 4: + default: + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + gSprites[spriteId].pos2.x = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +// Moves the mon's sprite back and forth in an unpredictable swaying motion. +// No args. +void AnimTask_TeeterDanceMovement(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + task->data[3] = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->data[4] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1; + task->data[6] = gSprites[task->data[3]].pos1.y; + task->data[5] = gSprites[task->data[3]].pos1.x; + task->data[9] = 0; + task->data[11] = 0; + task->data[10] = 1; + task->data[12] = 0; + task->func = AnimTask_TeeterDanceMovementStep; +} + +static void AnimTask_TeeterDanceMovementStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + switch (task->data[0]) + { + case 0: + task->data[11] += 8; + task->data[11] &= 0xFF; + gSprites[task->data[3]].pos2.x = gSineTable[task->data[11]] >> 5; + task->data[9] += 2; + task->data[9] &= 0xFF; + gSprites[task->data[3]].pos1.x = (gSineTable[task->data[9]] >> 3) * task->data[4] + task->data[5]; + if (task->data[9] == 0) + { + gSprites[task->data[3]].pos1.x = task->data[5]; + task->data[0]++; + } + break; + case 1: + task->data[11] += 8; + task->data[11] &= 0xFF; + gSprites[task->data[3]].pos2.x = gSineTable[task->data[11]] >> 5; + if (task->data[11] == 0) + { + gSprites[task->data[3]].pos2.x = 0; + task->data[0]++; + } + break; + case 2: + DestroyAnimVisualTask(taskId); + break; + } +} + +static void AnimKnockOffStrikeStep(struct Sprite *sprite) +{ + // These two cases are identical. + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + sprite->data[1] += sprite->data[0]; + sprite->data[1] &= 0xFF; + } + else + { + sprite->data[1] += sprite->data[0]; + sprite->data[1] &= 0xFF; + } + + sprite->pos2.x = Cos(sprite->data[1], 20); + sprite->pos2.y = Sin(sprite->data[1], 20); + if (sprite->animEnded) + DestroyAnimSprite(sprite); + + sprite->data[2]++; +} + +// Animates a strike that swipes downard at the target mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +void AnimKnockOffStrike(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + sprite->pos1.x -= gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = -11; + sprite->data[1] = 192; + StartSpriteAffineAnim(sprite, 1); + } + else + { + sprite->data[0] = 11; + sprite->data[1] = 192; + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + } + + sprite->callback = AnimKnockOffStrikeStep; +} + +// Gradually fades a rotating recyle arrow sprite in and back out. +// No args. +void AnimRecycle(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP); + if (sprite->pos1.y < 16) + sprite->pos1.y = 16; + + sprite->data[6] = 0; + sprite->data[7] = 16; + sprite->callback = AnimRecycleStep; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7])); +} + +static void AnimRecycleStep(struct Sprite *sprite) +{ + switch (sprite->data[2]) + { + case 0: + if (++sprite->data[0] > 1) + { + sprite->data[0] = 0; + if (!(sprite->data[1] & 1)) + { + if (sprite->data[6] < 16) + sprite->data[6]++; + } + else + { + if (sprite->data[7] != 0) + sprite->data[7]--; + } + + sprite->data[1]++; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7])); + if (sprite->data[7] == 0) + sprite->data[2]++; + } + break; + case 1: + if (++sprite->data[0] == 10) + { + sprite->data[0] = 0; + sprite->data[1] = 0; + sprite->data[2]++; + } + break; + case 2: + if (++sprite->data[0] > 1) + { + sprite->data[0] = 0; + if (!(sprite->data[1] & 1)) + { + if (sprite->data[6] != 0) + sprite->data[6]--; + } + else + { + if (sprite->data[7] < 16) + sprite->data[7]++; + } + + sprite->data[1]++; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7])); + if (sprite->data[7] == 16) + sprite->data[2]++; + } + break; + case 3: + DestroySpriteAndMatrix(sprite); + break; + } +} + +void AnimTask_GetWeather(u8 taskId) +{ + gBattleAnimArgs[7] = ANIM_WEATHER_NONE; + if (gWeatherMoveAnim & WEATHER_SUN_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_SUN; + else if (gWeatherMoveAnim & WEATHER_RAIN_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_RAIN; + else if (gWeatherMoveAnim & WEATHER_SANDSTORM_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_SANDSTORM; + else if (gWeatherMoveAnim & WEATHER_HAIL_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_HAIL; + + DestroyAnimVisualTask(taskId); +} + +// Squishes the mon sprite vertically, and shakes it back and forth. +// arg 0: which battler +void AnimTask_SlackOffSquish(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + task->data[0] = 0; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(task, task->data[15], gSlackOffSquishAffineAnimCmds); + task->func = AnimTask_SlackOffSquishStep; +} + +static void AnimTask_SlackOffSquishStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + gTasks[taskId].data[0]++; + if (gTasks[taskId].data[0] > 16 && gTasks[taskId].data[0] < 40) + { + if (++task->data[1] > 2) + { + task->data[1] = 0; + task->data[2]++; + if (!(task->data[2] & 1)) + gSprites[task->data[15]].pos2.x = -1; + else + gSprites[task->data[15]].pos2.x = 1; + } + } + else + { + gSprites[task->data[15]].pos2.x = 0; + } + + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); +} |