diff options
Diffstat (limited to 'src/battle/anim/leaf.c')
-rw-r--r-- | src/battle/anim/leaf.c | 240 |
1 files changed, 237 insertions, 3 deletions
diff --git a/src/battle/anim/leaf.c b/src/battle/anim/leaf.c index ca2af257d..d31e4dbd6 100644 --- a/src/battle/anim/leaf.c +++ b/src/battle/anim/leaf.c @@ -1,18 +1,120 @@ #include "global.h" +#include "battle.h" +#include "battle_anim.h" #include "rom_8077ABC.h" #include "trig.h" -#include "battle_anim.h" extern s16 gBattleAnimArgs[]; extern u8 gAnimBankAttacker; extern u8 gAnimBankTarget; +void sub_80CAED8(struct Sprite* sprite); +void AnimMoveTwisterParticle(struct Sprite* sprite); +void AnimTranslateLinearSingleSineWave(struct Sprite* sprite); static void sub_80CAF20(struct Sprite* sprite); static void sub_80CAF6C(struct Sprite* sprite); +static void AnimTranslateLinearSingleSineWaveStep(struct Sprite* sprite); +static void AnimMoveTwisterParticleStep(struct Sprite* sprite); // leaf // Used by Razor Leaf and Twister. +const union AnimCmd gSpriteAnim_83D6458[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(4, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_FRAME(12, 5), + ANIMCMD_FRAME(16, 5), + ANIMCMD_FRAME(20, 5), + ANIMCMD_FRAME(16, 5), + ANIMCMD_FRAME(12, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_FRAME(4, 5), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSpriteAnim_83D6484[] = +{ + ANIMCMD_FRAME(24, 5), + ANIMCMD_FRAME(28, 5), + ANIMCMD_FRAME(32, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_83D6494[] = +{ + gSpriteAnim_83D6458, + gSpriteAnim_83D6484, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_83D649C = +{ + .tileTag = 10063, + .paletteTag = 10063, + .oam = &gOamData_837DF2C, + .anims = gSpriteAnimTable_83D6494, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80CAED8, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_83D64B4 = +{ + .tileTag = 10063, + .paletteTag = 10063, + .oam = &gOamData_837DF2C, + .anims = gSpriteAnimTable_83D6494, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMoveTwisterParticle, +}; + +const union AnimCmd gSpriteAnim_83D64CC[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(0, 3, .hFlip = TRUE), + ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(0, 3, .vFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd *const gSpriteAnimTable_83D64E0[] = +{ + gSpriteAnim_83D64CC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_83D64E4 = +{ + .tileTag = 10160, + .paletteTag = 10160, + .oam = &gOamData_837DF54, + .anims = gSpriteAnimTable_83D64E0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimTranslateLinearSingleSineWave, +}; + +const union AffineAnimCmd gSpriteAffineAnim_83D64FC[] = { + AFFINEANIMCMD_FRAME(0, 0, 0, 1), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_83D650C[] = { + gSpriteAffineAnim_83D64FC, +}; + +const struct SpriteTemplate gSwiftStarSpriteTemplate = +{ + .tileTag = 10174, + .paletteTag = 10174, + .oam = &gOamData_837DF94, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_83D650C, + .callback = AnimTranslateLinearSingleSineWave, +}; + void sub_80CAED8(struct Sprite* sprite) { sprite->pos1.x = GetBattlerSpriteCoord(gAnimBankAttacker, 2); @@ -23,7 +125,7 @@ void sub_80CAED8(struct Sprite* sprite) sprite->callback = sub_80CAF20; } -void sub_80CAF20(struct Sprite* sprite) +static void sub_80CAF20(struct Sprite* sprite) { if (!sprite->data[2]) { @@ -49,7 +151,7 @@ void sub_80CAF20(struct Sprite* sprite) } } -void sub_80CAF6C(struct Sprite* sprite) +static void sub_80CAF6C(struct Sprite* sprite) { if (GetBattlerSide(gAnimBankAttacker)) { @@ -72,3 +174,135 @@ void sub_80CAF6C(struct Sprite* sprite) DestroyAnimSprite(sprite); } } + +// Animates a sprite that moves linearly from one location to another, with a +// single-cycle sine wave added to the y position along the way. +// Used by Razor Leaf and Magical Leaf. +// arg 0: initial x offset +// arg 1: initial y offset +// arg 2: target x offset +// arg 3: target y offset +// arg 4: translation duration +// arg 5: wave amplitude +// arg 6: target between double battle opponents (boolean) +void AnimTranslateLinearSingleSineWave(struct Sprite* sprite) +{ + InitAnimSpritePos(sprite, 1); + if (GetBattlerSide(gAnimBankAttacker) != B_SIDE_PLAYER) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + + sprite->data[0] = gBattleAnimArgs[4]; + if (!gBattleAnimArgs[6]) + { + sprite->data[2] = GetBattlerSpriteCoord(gAnimBankTarget, 2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gAnimBankTarget, 3) + gBattleAnimArgs[3]; + } + else + { + SetAverageBattlerPositions(gAnimBankTarget, 1, &sprite->data[2], &sprite->data[4]); + sprite->data[2] += gBattleAnimArgs[2]; + sprite->data[4] += gBattleAnimArgs[3]; + } + + sprite->data[5] = gBattleAnimArgs[5]; + InitAnimSpriteTranslationOverDuration(sprite); + if (GetBattlerSide(gAnimBankAttacker) == GetBattlerSide(gAnimBankTarget)) + { + sprite->data[0] = 1; + } + else + { + sprite->data[0] = 0; + } + + sprite->callback = AnimTranslateLinearSingleSineWaveStep; +} + +static void AnimTranslateLinearSingleSineWaveStep(struct Sprite* sprite) +{ + bool8 destroy = FALSE; + s16 a = sprite->data[0]; + s16 b = sprite->data[7]; + s16 r0; + + sprite->data[0] = 1; + TranslateAnimSpriteLinearAndSine(sprite); + r0 = sprite->data[7]; + sprite->data[0] = a; + if (b > 0xC8 && r0 <= 0x37 && sprite->oam.affineParam == 0) + sprite->oam.affineParam++; + + if (sprite->oam.affineParam != 0 && sprite->data[0] != 0) + { + sprite->invisible ^= 1; + sprite->oam.affineParam++; + if (sprite->oam.affineParam == 0x1E) + destroy = TRUE; + } + + if (sprite->pos1.x + sprite->pos2.x > 256 + || sprite->pos1.x + sprite->pos2.x < -16 + || sprite->pos1.y + sprite->pos2.y > 160 + || sprite->pos1.y + sprite->pos2.y < -16) + destroy = TRUE; + + if (destroy) + DestroyAnimSprite(sprite); +} + +// Animates particles in the Twister move animation. +// arg 0: duration +// arg 1: total y delta (the particles rise upward) +// arg 2: wave period (higher means faster wave) +// arg 3: wave amplitude +// arg 4: speedup frame (particles move faster at the end of the animation) +void AnimMoveTwisterParticle(struct Sprite* sprite) +{ + if (!IsContest() && IsDoubleBattle() == TRUE) + { + SetAverageBattlerPositions(gAnimBankTarget, 1, &sprite->pos1.x, &sprite->pos1.y); + } + + sprite->pos1.y += 32; + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->data[2] = gBattleAnimArgs[2]; + sprite->data[3] = gBattleAnimArgs[3]; + sprite->data[4] = gBattleAnimArgs[4]; + sprite->callback = AnimMoveTwisterParticleStep; +} + +static void AnimMoveTwisterParticleStep(struct Sprite* sprite) +{ + if (sprite->data[1] == 0xFF) + { + sprite->pos1.y -= 2; + } + else if (sprite->data[1] > 0) + { + sprite->pos1.y -= 2; + sprite->data[1] -= 2; + } + + sprite->data[5] += sprite->data[2]; + if (sprite->data[0] < sprite->data[4]) + sprite->data[5] += sprite->data[2]; + + sprite->data[5] &= 0xFF; + sprite->pos2.x = Cos(sprite->data[5], sprite->data[3]); + sprite->pos2.y = Sin(sprite->data[5], 5); + if (sprite->data[5] <= 0x7F) + { + sprite->oam.priority = sub_8079ED4(gAnimBankTarget) - 1; + } + else + { + sprite->oam.priority = sub_8079ED4(gAnimBankTarget) + 1; + } + + sprite->data[0]--; + if (!sprite->data[0]) + DestroyAnimSprite(sprite); +} |