summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgolem galvanize <golemgalvanize@github.com>2018-12-20 16:20:34 -0500
committergolem galvanize <golemgalvanize@github.com>2018-12-20 16:20:34 -0500
commit64832ff67e1027ed14909039a000904a460515b2 (patch)
tree488fb1f0a3e76e7c4c3d6c050ea65602fd40838c /src
parent6ef96717181dfa1cda548cbe405410aba065e41c (diff)
start ice
Diffstat (limited to 'src')
-rw-r--r--src/ice.c801
1 files changed, 801 insertions, 0 deletions
diff --git a/src/ice.c b/src/ice.c
index ebd0d3cf6..be8255231 100644
--- a/src/ice.c
+++ b/src/ice.c
@@ -1,21 +1,39 @@
#include "global.h"
#include "battle_anim.h"
+#include "bg.h"
+#include "field_weather.h"
+#include "gpu_regs.h"
+#include "graphics.h"
+#include "palette.h"
+#include "sprite.h"
+#include "task.h"
+#include "trig.h"
+#include "constants/battle_anim.h"
#include "constants/rgb.h"
+extern void sub_810B684(struct Sprite *);
extern void sub_810B6C4(struct Sprite *);
+extern void sub_810B848(struct Sprite *);
extern void sub_810B8AC(struct Sprite *);
extern void sub_810B8EC(struct Sprite *);
extern void sub_810B974(struct Sprite *);
+extern void sub_810B9E8(struct Sprite *);
extern void sub_810BA24(struct Sprite *);
+extern void sub_810BB60(struct Sprite *);
+extern void sub_810BBC8(struct Sprite *);
+extern void sub_810BC4C(struct Sprite *);
extern void sub_810BC94(struct Sprite *);
+extern void sub_810BDD8(struct Sprite *);
extern void sub_810BE48(struct Sprite *);
extern void sub_810BED0(struct Sprite *);
+extern void sub_810C008(struct Sprite *);
extern void sub_810C2F0(struct Sprite *);
extern void sub_810C560(struct Sprite *);
extern void sub_810CB58(struct Sprite *);
extern void sub_80A8EE4(struct Sprite *);
extern void unc_080B06FC(struct Sprite *);
extern void sub_810CD4C(struct Sprite *);
+void sub_810C164(u8);
const union AnimCmd gUnknown_08595A48[] =
{
@@ -489,3 +507,786 @@ const struct SpriteTemplate gUnknown_08595DFC =
.affineAnims = gDummySpriteAffineAnimTable,
.callback = sub_810CD4C,
};
+
+extern const struct SpriteTemplate gUnknown_085956C0;
+
+bool8 sub_810B614(struct Task *task, u8 taskId)
+{
+ u8 spriteId = CreateSprite(&gUnknown_085956C0, task->data[13], task->data[14], task->data[12]);
+
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].callback = sub_810B684;
+ gSprites[spriteId].data[6] = taskId;
+ gSprites[spriteId].data[7] = 10;
+ task->data[10]++;
+ }
+ if (task->data[14] >= task->data[15])
+ return TRUE;
+ task->data[14] += 32;
+ return FALSE;
+}
+
+void sub_810B684(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ gTasks[sprite->data[6]].data[sprite->data[7]]--;
+ DestroySprite(sprite);
+ }
+}
+
+// unused
+#ifdef NONMATCHING
+void sub_810B6C4(struct Sprite *sprite)
+{
+ s16 targetX, targetY, attackerX, attackerY;
+ s16 i;
+
+ sprite->oam.tileNum += 7;
+ targetX = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ targetY = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = gBattleAnimArgs[0] + attackerX;
+ sprite->data[2] = gBattleAnimArgs[2] + targetX;
+ sprite->data[3] = gBattleAnimArgs[1] + attackerY;
+ sprite->data[4] = gBattleAnimArgs[3] + targetY;
+ sub_80A64EC(sprite);
+ while ((targetX >= -32 && targetX <= 272) && (targetY >= -32 && targetY <= 192))
+ {
+ targetX += sprite->data[1];
+ targetY += sprite->data[2];
+ }
+ sprite->data[1] = -sprite->data[1];
+ sprite->data[2] = -sprite->data[2];
+ while ((attackerX >= -32 && attackerX <= 272) && (attackerY >= -32 && attackerY <= 192))
+ {
+ attackerX += sprite->data[1];
+ attackerY += sprite->data[2];
+ }
+ sprite->pos1.x = attackerX;
+ sprite->pos1.y = attackerY;
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = attackerX;
+ sprite->data[2] = targetX;
+ sprite->data[3] = attackerY;
+ sprite->data[4] = targetY;
+ sub_80A64EC(sprite);
+ sprite->data[3] = gBattleAnimArgs[5];
+ sprite->data[4] = gBattleAnimArgs[6];
+ sprite->callback = sub_810B848;
+}
+#else
+NAKED
+void sub_810B6C4(struct Sprite *sprite)
+{
+ asm_unified("push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x4\n\
+ adds r5, r0, 0\n\
+ ldrh r2, [r5, 0x4]\n\
+ lsls r1, r2, 22\n\
+ lsrs r1, 22\n\
+ adds r1, 0x7\n\
+ ldr r3, =0x000003ff\n\
+ adds r0, r3, 0\n\
+ ands r1, r0\n\
+ ldr r0, =0xfffffc00\n\
+ ands r0, r2\n\
+ orrs r0, r1\n\
+ strh r0, [r5, 0x4]\n\
+ ldr r4, =gBattleAnimTarget\n\
+ ldrb r0, [r4]\n\
+ movs r1, 0x2\n\
+ bl GetBattlerSpriteCoord\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r9, r0\n\
+ ldrb r0, [r4]\n\
+ movs r1, 0x3\n\
+ bl GetBattlerSpriteCoord\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+ ldr r4, =gBattleAnimAttacker\n\
+ ldrb r0, [r4]\n\
+ movs r1, 0x2\n\
+ bl GetBattlerSpriteCoord\n\
+ lsls r0, 24\n\
+ lsrs r3, r0, 24\n\
+ ldrb r0, [r4]\n\
+ movs r1, 0x3\n\
+ str r3, [sp]\n\
+ bl GetBattlerSpriteCoord\n\
+ lsls r0, 24\n\
+ lsrs r6, r0, 24\n\
+ ldr r1, =gBattleAnimArgs\n\
+ ldrh r0, [r1, 0x8]\n\
+ strh r0, [r5, 0x2E]\n\
+ ldrh r0, [r1]\n\
+ ldr r3, [sp]\n\
+ adds r0, r3\n\
+ strh r0, [r5, 0x30]\n\
+ ldrh r0, [r1, 0x4]\n\
+ mov r4, r9\n\
+ adds r0, r4, r0\n\
+ strh r0, [r5, 0x32]\n\
+ ldrh r0, [r1, 0x2]\n\
+ adds r0, r6\n\
+ strh r0, [r5, 0x34]\n\
+ ldrh r0, [r1, 0x6]\n\
+ mov r7, r8\n\
+ adds r0, r7, r0\n\
+ strh r0, [r5, 0x36]\n\
+ adds r0, r5, 0\n\
+ bl sub_80A64EC\n\
+ adds r4, 0x20\n\
+ movs r0, 0x98\n\
+ lsls r0, 1\n\
+ mov r12, r0\n\
+ ldr r3, [sp]\n\
+ cmp r4, r12\n\
+ bhi _0810B79E\n\
+ adds r0, r7, 0\n\
+ adds r0, 0x20\n\
+ ldrh r1, [r5, 0x30]\n\
+ ldrh r2, [r5, 0x32]\n\
+ cmp r0, 0xE0\n\
+ bhi _0810B79E\n\
+ adds r4, r1, 0\n\
+ mov r10, r12\n\
+_0810B76A:\n\
+ mov r7, r9\n\
+ lsls r1, r7, 16\n\
+ asrs r1, 16\n\
+ adds r1, r4\n\
+ lsls r1, 16\n\
+ mov r7, r8\n\
+ lsls r0, r7, 16\n\
+ asrs r0, 16\n\
+ adds r0, r2\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r8, r0\n\
+ lsrs r0, r1, 16\n\
+ mov r9, r0\n\
+ movs r7, 0x80\n\
+ lsls r7, 14\n\
+ adds r1, r7\n\
+ lsrs r1, 16\n\
+ cmp r1, r10\n\
+ bhi _0810B79E\n\
+ mov r1, r8\n\
+ lsls r0, r1, 16\n\
+ adds r0, r7\n\
+ lsrs r0, 16\n\
+ cmp r0, 0xE0\n\
+ bls _0810B76A\n\
+_0810B79E:\n\
+ ldrh r0, [r5, 0x30]\n\
+ negs r7, r0\n\
+ strh r7, [r5, 0x30]\n\
+ ldrh r0, [r5, 0x32]\n\
+ negs r4, r0\n\
+ strh r4, [r5, 0x32]\n\
+ lsls r0, r3, 16\n\
+ movs r1, 0x80\n\
+ lsls r1, 14\n\
+ adds r0, r1\n\
+ lsrs r0, 16\n\
+ movs r2, 0x98\n\
+ lsls r2, 1\n\
+ mov r12, r2\n\
+ ldr r1, =gBattleAnimArgs\n\
+ mov r10, r1\n\
+ cmp r0, r12\n\
+ bhi _0810B80A\n\
+ lsls r1, r6, 16\n\
+ movs r2, 0x80\n\
+ lsls r2, 14\n\
+ adds r0, r1, r2\n\
+ b _0810B802\n\
+ .pool\n\
+_0810B7E0:\n\
+ lsls r1, r3, 16\n\
+ asrs r1, 16\n\
+ adds r1, r7\n\
+ lsls r1, 16\n\
+ asrs r0, r2, 16\n\
+ adds r0, r4\n\
+ lsls r0, 16\n\
+ lsrs r6, r0, 16\n\
+ lsrs r3, r1, 16\n\
+ movs r0, 0x80\n\
+ lsls r0, 14\n\
+ adds r1, r0\n\
+ lsrs r1, 16\n\
+ cmp r1, r12\n\
+ bhi _0810B80A\n\
+ lsls r1, r6, 16\n\
+ adds r0, r1, r0\n\
+_0810B802:\n\
+ lsrs r0, 16\n\
+ adds r2, r1, 0\n\
+ cmp r0, 0xE0\n\
+ bls _0810B7E0\n\
+_0810B80A:\n\
+ strh r3, [r5, 0x20]\n\
+ strh r6, [r5, 0x22]\n\
+ mov r1, r10\n\
+ ldrh r0, [r1, 0x8]\n\
+ strh r0, [r5, 0x2E]\n\
+ strh r3, [r5, 0x30]\n\
+ mov r2, r9\n\
+ strh r2, [r5, 0x32]\n\
+ strh r6, [r5, 0x34]\n\
+ mov r3, r8\n\
+ strh r3, [r5, 0x36]\n\
+ adds r0, r5, 0\n\
+ bl sub_80A64EC\n\
+ mov r7, r10\n\
+ ldrh r0, [r7, 0xA]\n\
+ strh r0, [r5, 0x34]\n\
+ ldrh r0, [r7, 0xC]\n\
+ strh r0, [r5, 0x36]\n\
+ ldr r0, =sub_810B848\n\
+ str r0, [r5, 0x1C]\n\
+ add sp, 0x4\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n");
+}
+#endif
+
+void sub_810B848(struct Sprite *sprite)
+{
+ if (sprite->data[0] != 0)
+ {
+ sprite->data[5] += sprite->data[1];
+ sprite->data[6] += sprite->data[2];
+ sprite->pos2.x = sprite->data[5];
+ sprite->pos2.y = sprite->data[6];
+ sprite->pos2.x += Sin(sprite->data[7], sprite->data[3]);
+ sprite->pos2.y += Sin(sprite->data[7], sprite->data[3]);
+ sprite->data[7] = (sprite->data[7] + sprite->data[4]) & 0xFF;
+ sprite->data[0]--;
+ }
+ else
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Animates the swirling ice crystals in Ice Punch.
+// arg 0: initial position angle around circle (0-256)
+void sub_810B8AC(struct Sprite *sprite)
+{
+ sprite->data[0] = gBattleAnimArgs[0];
+ sprite->data[1] = 60;
+ sprite->data[2] = 9;
+ sprite->data[3] = 30;
+ sprite->data[4] = -512;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = TranslateSpriteInGrowingCircleOverDuration;
+ sprite->callback(sprite);
+}
+
+// Animates the ice particles in Ice Beam.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: duration
+void sub_810B8EC(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->data[2] -= gBattleAnimArgs[2];
+ else
+ sprite->data[2] += gBattleAnimArgs[2];
+
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3];
+ sprite->data[0] = gBattleAnimArgs[4];
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = StartAnimLinearTranslation;
+}
+
+// Animates the ice crystals at the end of Ice Punch, Ice Beam, Tri Attack,
+// Weather Ball (Hail), Blizzard, and Powder Snow.
+// arg 0: target x offset
+// arg 1: target y offset
+// arg 2: ??? unknown boolean
+void sub_810B974(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[2] == 0)
+ {
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+
+ StoreSpriteCallbackInData6(sprite, sub_810B9E8);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+}
+
+void sub_810B9E8(struct Sprite *sprite)
+{
+ sprite->invisible ^= 1;
+ sprite->data[0] += 1;
+ if (sprite->data[0] == 20)
+ DestroySpriteAndMatrix(sprite);
+}
+
+// Animates the small snowballs that swirl around the target in Blizzard and Icy Wind.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: particle speed
+// arg 5: multiple targets? (boolean)
+void sub_810BA24(struct Sprite *sprite)
+{
+ int i;
+ s16 tempDataHolder[8];
+
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+
+ if (!gBattleAnimArgs[5])
+ {
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3];
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]);
+ }
+
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->data[2] -= gBattleAnimArgs[2];
+ else
+ sprite->data[2] += gBattleAnimArgs[2];
+
+ for (i = 0; i < 8; i++)
+ tempDataHolder[i] = sprite->data[i];
+
+ InitAnimFastLinearTranslationWithSpeed(sprite);
+ sprite->data[1] ^= 1;
+ sprite->data[2] ^= 1;
+
+ while (1)
+ {
+ sprite->data[0] = 1;
+ AnimFastTranslateLinear(sprite);
+
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 160
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ break;
+ }
+
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+
+ for (i = 0; i < 8; i++)
+ sprite->data[i] = tempDataHolder[i];
+
+ sprite->callback = sub_80A718C;
+ StoreSpriteCallbackInData6(sprite, sub_810BB60);
+}
+
+void sub_810BB60(struct Sprite *sprite)
+{
+ s16 tempVar;
+
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+ sprite->data[0] = 128;
+
+ tempVar = GetBattlerSide(gBattleAnimAttacker) != 0 ? 20 : -20;
+
+ sprite->data[3] = Sin(sprite->data[0], tempVar);
+ sprite->data[4] = Cos(sprite->data[0], 0xF);
+ sprite->data[5] = 0;
+ sprite->callback = sub_810BBC8;
+ sprite->callback(sprite);
+}
+
+void sub_810BBC8(struct Sprite *sprite)
+{
+ s16 tempVar;
+ tempVar = GetBattlerSide(gBattleAnimAttacker) != 0 ? 20 : -20;
+
+ if (sprite->data[5] <= 31)
+ {
+ sprite->pos2.x = Sin(sprite->data[0], tempVar) - sprite->data[3];
+ sprite->pos2.y = Cos(sprite->data[0], 15) - sprite->data[4];
+ sprite->data[0] = (sprite->data[0] + 16) & 0xFF;
+ sprite->data[5] += 1;
+ }
+ else
+ {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+ sprite->data[4] = 0;
+ sprite->data[3] = 0;
+ sprite->callback = sub_810BC4C;
+ }
+}
+
+void sub_810BC4C(struct Sprite *sprite)
+{
+ sprite->data[0] = 1;
+ AnimFastTranslateLinear(sprite);
+
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 256
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ DestroyAnimSprite(sprite);
+}
+
+// Moves particles towards the target mon and off the screen. Used to animate
+// the large snowballs in Blizzard and the small snowballs in Powder Snow.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: speed
+// arg 5: wave amplitude
+// arg 6: wave frequency
+// arg 7: multiple targets? (boolean)
+void sub_810BC94(struct Sprite *sprite)
+{
+ int i;
+ s16 tempDataHolder[8];
+
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+
+ if (!gBattleAnimArgs[7])
+ {
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]);
+ }
+
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->data[2] -= gBattleAnimArgs[2];
+ else
+ sprite->data[2] += gBattleAnimArgs[2];
+
+ sprite->data[4] += gBattleAnimArgs[3];
+ InitAnimFastLinearTranslationWithSpeed(sprite);
+ for (i = 0; i < 8; i++)
+ tempDataHolder[i] = sprite->data[i];
+
+ sprite->data[1] ^= 1;
+ sprite->data[2] ^= 1;
+
+ while (1)
+ {
+ sprite->data[0] = 1;
+ AnimFastTranslateLinear(sprite);
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 160
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ break;
+ }
+
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+
+ for (i = 0; i < 8; i++)
+ sprite->data[i] = tempDataHolder[i];
+
+ sprite->data[5] = gBattleAnimArgs[5];
+ sprite->data[6] = gBattleAnimArgs[6];
+ sprite->callback = sub_810BDD8;
+}
+
+// Moves particles in a sine wave towards the target.
+void sub_810BDD8(struct Sprite *sprite)
+{
+ AnimFastTranslateLinear(sprite);
+ if (sprite->data[0] == 0)
+ sprite->data[0] = 1;
+
+ sprite->pos2.y += Sin(sprite->data[7], sprite->data[5]);
+ sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
+ if (sprite->data[0] == 1)
+ {
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 160
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Animates the ice pilar wave used by Icy Wind.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: ??? unknown boolean
+void sub_810BE48(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ if (gBattleAnimArgs[2] == 0)
+ {
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
+
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+
+ sprite->data[0]++;
+ }
+ else
+ {
+ if (sprite->animEnded)
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Animates the fog that swirls around the mon in Mist and Smog.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: change in y pixels per rotation
+// arg 3: duration
+// arg 4: animate on opponent? (boolean)
+// arg 5: ??? unknown boolean
+void sub_810BED0(struct Sprite *sprite)
+{
+ s16 tempVar;
+ u8 battler;
+
+ if (gBattleAnimArgs[4] == 0)
+ {
+ if (gBattleAnimArgs[5] == 0)
+ {
+ InitSpritePosToAnimAttacker(sprite, FALSE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimAttacker, 0, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+
+ battler = gBattleAnimAttacker;
+ }
+ else
+ {
+ if (gBattleAnimArgs[5] == 0)
+ {
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER)
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+
+ battler = gBattleAnimTarget;
+ }
+
+ sprite->data[7] = battler;
+ if (gBattleAnimArgs[5] == 0 || !IsDoubleBattle())
+ tempVar = 0x20;
+ else
+ tempVar = 0x40;
+
+ sprite->data[6] = tempVar;
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
+ sprite->pos1.y += 8;
+
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[2];
+
+ InitAnimLinearTranslation(sprite);
+
+ sprite->data[5] = 64;
+ sprite->callback = sub_810C008;
+ sprite->callback(sprite);
+}
+
+// Animates swirling fog initialized by InitSwirlingFogAnim.
+void sub_810C008(struct Sprite *sprite)
+{
+ if (!AnimTranslateLinear(sprite))
+ {
+ sprite->pos2.x += Sin(sprite->data[5], sprite->data[6]);
+ sprite->pos2.y += Cos(sprite->data[5], -6);
+
+ if ((u16)(sprite->data[5] - 64) <= 0x7F)
+ sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]);
+ else
+ sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]) + 1;
+
+ sprite->data[5] = (sprite->data[5] + 3) & 0xFF;
+ }
+ else
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Fades mons to black and places foggy overlay in Haze.
+void sub_810C0A0(u8 taskId)
+{
+ struct UnknownAnimStruct2 subStruct;
+
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 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_80A6B30(&subStruct);
+ LoadBgTiles(subStruct.bgId, gWeatherFog1Tiles, 0x800, subStruct.tilesOffset);
+ sub_80A6D60(&subStruct, gBattleAnimFogTilemap, 0);
+ LoadPalette(&gUnknown_083970E8, subStruct.unk8 * 16, 32);
+
+ gTasks[taskId].func = sub_810C164;
+}
+
+void sub_810C164(u8 taskId)
+{
+ struct UnknownAnimStruct2 subStruct;
+
+ gBattle_BG1_X += -1;
+ gBattle_BG1_Y += 0;
+
+ switch (gTasks[taskId].data[12])
+ {
+ case 0:
+ if (++gTasks[taskId].data[10] == 4)
+ {
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[9]++;
+ gTasks[taskId].data[11] = gUnknown_08595C5C[gTasks[taskId].data[9]];
+
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 9)
+ {
+ gTasks[taskId].data[12]++;
+ gTasks[taskId].data[11] = 0;
+ }
+ }
+ break;
+ case 1:
+ if (++gTasks[taskId].data[11] == 0x51)
+ {
+ gTasks[taskId].data[11] = 9;
+ 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_80A6B30(&subStruct);
+ sub_80A6C68(1);
+ sub_80A6C68(2);
+
+ gTasks[taskId].data[12]++;
+
+ // fall through
+ case 4:
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
+
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+// Throws the ball in Mist Ball.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: targey x offset
+// arg 3: target y offset
+// arg 4: duration
+// arg 5: ??? unknown (seems to vibrate target mon somehow)
+void sub_810C2F0(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ sprite->callback = TranslateAnimSpriteToTargetMonLocation;
+}