summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ice.c820
1 files changed, 748 insertions, 72 deletions
diff --git a/src/ice.c b/src/ice.c
index be8255231..329cd0b9a 100644
--- a/src/ice.c
+++ b/src/ice.c
@@ -4,36 +4,52 @@
#include "field_weather.h"
#include "gpu_regs.h"
#include "graphics.h"
+#include "main.h"
#include "palette.h"
+#include "random.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "constants/battle_anim.h"
#include "constants/rgb.h"
+struct HailStruct {
+ s32 unk0:10;
+ s32 unk1:10;
+ s32 unk2:8;
+ s32 unk3:4;
+};
+
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 AnimIcePunchSwirlingParticle(struct Sprite *);
+extern void AnimIceBeamParticle(struct Sprite *);
+extern void AnimIceEffectParticle(struct Sprite *);
+extern void AnimFlickerIceEffectParticle(struct Sprite *);
+extern void AnimSwirlingSnowball_Step1(struct Sprite *);
+extern void AnimSwirlingSnowball_Step2(struct Sprite *);
+extern void AnimSwirlingSnowball_Step3(struct Sprite *);
+extern void AnimSwirlingSnowball_End(struct Sprite *);
+extern void AnimMoveParticleBeyondTarget(struct Sprite *);
+extern void AnimWiggleParticleTowardsTarget(struct Sprite *);
+extern void AnimWaveFromCenterOfTarget(struct Sprite *);
+extern void InitSwirlingFogAnim(struct Sprite *);
+extern void AnimSwirlingFogAnim(struct Sprite *);
+extern void AnimThrowMistBall(struct Sprite *);
+extern void InitPoisonGasCloudAnim(struct Sprite *);
+extern void MovePoisonGasCloud(struct Sprite *);
+extern void AnimHailBegin(struct Sprite *);
+extern void AnimHailContinue(struct Sprite *);
extern void sub_80A8EE4(struct Sprite *);
-extern void unc_080B06FC(struct Sprite *);
-extern void sub_810CD4C(struct Sprite *);
-void sub_810C164(u8);
+extern void InitIceBallAnim(struct Sprite *);
+extern void AnimThrowIceBall(struct Sprite *);
+extern void InitIceBallParticle(struct Sprite *);
+extern void AnimIceBallParticle(struct Sprite *);
+void AnimTask_Haze2(u8);
+void AnimTask_OverlayFogTiles(u8);
+void AnimTask_Hail2(u8);
+bool8 GenerateHailParticle(u8, u8, u8, u8);
const union AnimCmd gUnknown_08595A48[] =
{
@@ -145,7 +161,7 @@ const struct SpriteTemplate gUnknown_08595AD0 =
.anims = gUnknown_08595AA8,
.images = NULL,
.affineAnims = gUnknown_08595ACC,
- .callback = sub_810B8AC,
+ .callback = AnimIcePunchSwirlingParticle,
};
const struct SpriteTemplate gUnknown_08595AE8 =
@@ -156,7 +172,7 @@ const struct SpriteTemplate gUnknown_08595AE8 =
.anims = gUnknown_08595AAC,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810B8AC,
+ .callback = AnimIcePunchSwirlingParticle,
};
const union AffineAnimCmd gUnknown_08595B00[] =
@@ -178,7 +194,7 @@ const struct SpriteTemplate gUnknown_08595B14 =
.anims = gUnknown_08595AA8,
.images = NULL,
.affineAnims = gUnknown_08595B10,
- .callback = sub_810B8EC,
+ .callback = AnimIceBeamParticle,
};
const struct SpriteTemplate gUnknown_08595B2C =
@@ -189,7 +205,7 @@ const struct SpriteTemplate gUnknown_08595B2C =
.anims = gUnknown_08595AAC,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810B8EC,
+ .callback = AnimIceBeamParticle,
};
const union AffineAnimCmd gUnknown_08595B44[] =
@@ -213,7 +229,7 @@ const struct SpriteTemplate gUnknown_08595B68 =
.anims = gUnknown_08595AA8,
.images = NULL,
.affineAnims = gUnknown_08595B64,
- .callback = sub_810B974,
+ .callback = AnimIceEffectParticle,
};
const struct SpriteTemplate gUnknown_08595B80 =
@@ -224,7 +240,7 @@ const struct SpriteTemplate gUnknown_08595B80 =
.anims = gUnknown_08595AAC,
.images = NULL,
.affineAnims = gUnknown_08595B64,
- .callback = sub_810B974,
+ .callback = AnimIceEffectParticle,
};
const struct SpriteTemplate gUnknown_08595B98 =
@@ -235,7 +251,7 @@ const struct SpriteTemplate gUnknown_08595B98 =
.anims = gUnknown_08595AB0,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810BA24,
+ .callback = AnimSwirlingSnowball_Step1,
};
const struct SpriteTemplate gUnknown_08595BB0 =
@@ -246,7 +262,7 @@ const struct SpriteTemplate gUnknown_08595BB0 =
.anims = gUnknown_08595AB4,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810BC94,
+ .callback = AnimMoveParticleBeyondTarget,
};
const struct SpriteTemplate gUnknown_08595BC8 =
@@ -257,7 +273,7 @@ const struct SpriteTemplate gUnknown_08595BC8 =
.anims = gUnknown_08595AB0,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810BC94,
+ .callback = AnimMoveParticleBeyondTarget,
};
const union AnimCmd gUnknown_08595BE0[] =
@@ -285,7 +301,7 @@ const struct SpriteTemplate gUnknown_08595C04 =
.anims = gUnknown_08595C00,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810BE48,
+ .callback = AnimWaveFromCenterOfTarget,
};
const union AnimCmd gUnknown_08595C1C[] =
@@ -308,7 +324,7 @@ const struct SpriteTemplate gUnknown_08595C2C =
.anims = gUnknown_08595C28,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810BED0,
+ .callback = InitSwirlingFogAnim,
};
const struct SpriteTemplate gUnknown_08595C44 =
@@ -319,7 +335,7 @@ const struct SpriteTemplate gUnknown_08595C44 =
.anims = gUnknown_08595C28,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810BED0,
+ .callback = InitSwirlingFogAnim,
};
const u8 gUnknown_08595C5C[] =
@@ -335,7 +351,7 @@ const struct SpriteTemplate gUnknown_08595C70 =
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810C2F0,
+ .callback = AnimThrowMistBall,
};
const u8 gUnknown_08595C88[] =
@@ -351,21 +367,21 @@ const struct SpriteTemplate gUnknown_08595C9C =
.anims = gUnknown_08595C28,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810C560,
+ .callback = InitPoisonGasCloudAnim,
};
-const u8 gUnknown_08595CB4[][4] =
-{
- {0x64, 0xE0, 0x01, 0x20},
- {0x55, 0xE0, 0x01, 0x00},
- {0xF2, 0xE0, 0x11, 0x10},
- {0x42, 0xE0, 0x21, 0x10},
- {0xB6, 0xE0, 0x31, 0x00},
- {0x3C, 0xE0, 0x01, 0x20},
- {0xD6, 0xE0, 0x11, 0x00},
- {0x71, 0xE0, 0x01, 0x10},
- {0xD2, 0xE0, 0x31, 0x10},
- {0x26, 0xE0, 0x21, 0x00},
+const struct HailStruct gUnknown_08595CB4[] =
+{
+ {100, 120, 0, 2},
+ {85, 120, 0, 0},
+ {242, 120, 1, 1},
+ {66, 120, 2, 1},
+ {182, 120, 3, 0},
+ {60, 120, 0, 2},
+ {214, 120, 1, 0},
+ {113, 120, 0, 1},
+ {210, 120, 3, 1},
+ {38, 120, 2, 0},
};
const union AffineAnimCmd gUnknown_08595CDC[] =
@@ -412,7 +428,7 @@ const struct SpriteTemplate gUnknown_08595D2C =
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gUnknown_08595D1C,
- .callback = sub_810CB58,
+ .callback = AnimHailBegin,
};
const struct SpriteTemplate gUnknown_08595D44 =
@@ -494,7 +510,7 @@ const struct SpriteTemplate gUnknown_08595DE4 =
.anims = gUnknown_08595D78,
.images = NULL,
.affineAnims = gUnknown_08595DD0,
- .callback = unc_080B06FC,
+ .callback = InitIceBallAnim,
};
const struct SpriteTemplate gUnknown_08595DFC =
@@ -505,7 +521,7 @@ const struct SpriteTemplate gUnknown_08595DFC =
.anims = gUnknown_08595AAC,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_810CD4C,
+ .callback = InitIceBallParticle,
};
extern const struct SpriteTemplate gUnknown_085956C0;
@@ -536,7 +552,7 @@ void sub_810B684(struct Sprite *sprite)
}
}
-// unused
+// probably unused
#ifdef NONMATCHING
void sub_810B6C4(struct Sprite *sprite)
{
@@ -789,7 +805,7 @@ void sub_810B848(struct Sprite *sprite)
// Animates the swirling ice crystals in Ice Punch.
// arg 0: initial position angle around circle (0-256)
-void sub_810B8AC(struct Sprite *sprite)
+void AnimIcePunchSwirlingParticle(struct Sprite *sprite)
{
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = 60;
@@ -807,7 +823,7 @@ void sub_810B8AC(struct Sprite *sprite)
// arg 2: target x offset
// arg 3: target y offset
// arg 4: duration
-void sub_810B8EC(struct Sprite *sprite)
+void AnimIceBeamParticle(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
@@ -828,7 +844,7 @@ void sub_810B8EC(struct Sprite *sprite)
// arg 0: target x offset
// arg 1: target y offset
// arg 2: ??? unknown boolean
-void sub_810B974(struct Sprite *sprite)
+void AnimIceEffectParticle(struct Sprite *sprite)
{
if (gBattleAnimArgs[2] == 0)
{
@@ -844,11 +860,11 @@ void sub_810B974(struct Sprite *sprite)
sprite->pos1.y += gBattleAnimArgs[1];
}
- StoreSpriteCallbackInData6(sprite, sub_810B9E8);
+ StoreSpriteCallbackInData6(sprite, AnimFlickerIceEffectParticle);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
-void sub_810B9E8(struct Sprite *sprite)
+void AnimFlickerIceEffectParticle(struct Sprite *sprite)
{
sprite->invisible ^= 1;
sprite->data[0] += 1;
@@ -863,7 +879,7 @@ void sub_810B9E8(struct Sprite *sprite)
// arg 3: target y offset
// arg 4: particle speed
// arg 5: multiple targets? (boolean)
-void sub_810BA24(struct Sprite *sprite)
+void AnimSwirlingSnowball_Step1(struct Sprite *sprite)
{
int i;
s16 tempDataHolder[8];
@@ -916,10 +932,10 @@ void sub_810BA24(struct Sprite *sprite)
sprite->data[i] = tempDataHolder[i];
sprite->callback = sub_80A718C;
- StoreSpriteCallbackInData6(sprite, sub_810BB60);
+ StoreSpriteCallbackInData6(sprite, AnimSwirlingSnowball_Step2);
}
-void sub_810BB60(struct Sprite *sprite)
+void AnimSwirlingSnowball_Step2(struct Sprite *sprite)
{
s16 tempVar;
@@ -934,11 +950,11 @@ void sub_810BB60(struct Sprite *sprite)
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 = AnimSwirlingSnowball_Step3;
sprite->callback(sprite);
}
-void sub_810BBC8(struct Sprite *sprite)
+void AnimSwirlingSnowball_Step3(struct Sprite *sprite)
{
s16 tempVar;
tempVar = GetBattlerSide(gBattleAnimAttacker) != 0 ? 20 : -20;
@@ -958,11 +974,11 @@ void sub_810BBC8(struct Sprite *sprite)
sprite->pos2.x = 0;
sprite->data[4] = 0;
sprite->data[3] = 0;
- sprite->callback = sub_810BC4C;
+ sprite->callback = AnimSwirlingSnowball_End;
}
}
-void sub_810BC4C(struct Sprite *sprite)
+void AnimSwirlingSnowball_End(struct Sprite *sprite)
{
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
@@ -983,7 +999,7 @@ void sub_810BC4C(struct Sprite *sprite)
// arg 5: wave amplitude
// arg 6: wave frequency
// arg 7: multiple targets? (boolean)
-void sub_810BC94(struct Sprite *sprite)
+void AnimMoveParticleBeyondTarget(struct Sprite *sprite)
{
int i;
s16 tempDataHolder[8];
@@ -1037,11 +1053,11 @@ void sub_810BC94(struct Sprite *sprite)
sprite->data[5] = gBattleAnimArgs[5];
sprite->data[6] = gBattleAnimArgs[6];
- sprite->callback = sub_810BDD8;
+ sprite->callback = AnimWiggleParticleTowardsTarget;
}
// Moves particles in a sine wave towards the target.
-void sub_810BDD8(struct Sprite *sprite)
+void AnimWiggleParticleTowardsTarget(struct Sprite *sprite)
{
AnimFastTranslateLinear(sprite);
if (sprite->data[0] == 0)
@@ -1062,7 +1078,7 @@ void sub_810BDD8(struct Sprite *sprite)
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: ??? unknown boolean
-void sub_810BE48(struct Sprite *sprite)
+void AnimWaveFromCenterOfTarget(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
@@ -1097,7 +1113,7 @@ void sub_810BE48(struct Sprite *sprite)
// arg 3: duration
// arg 4: animate on opponent? (boolean)
// arg 5: ??? unknown boolean
-void sub_810BED0(struct Sprite *sprite)
+void InitSwirlingFogAnim(struct Sprite *sprite)
{
s16 tempVar;
u8 battler;
@@ -1160,12 +1176,12 @@ void sub_810BED0(struct Sprite *sprite)
InitAnimLinearTranslation(sprite);
sprite->data[5] = 64;
- sprite->callback = sub_810C008;
+ sprite->callback = AnimSwirlingFogAnim;
sprite->callback(sprite);
}
// Animates swirling fog initialized by InitSwirlingFogAnim.
-void sub_810C008(struct Sprite *sprite)
+void AnimSwirlingFogAnim(struct Sprite *sprite)
{
if (!AnimTranslateLinear(sprite))
{
@@ -1186,7 +1202,7 @@ void sub_810C008(struct Sprite *sprite)
}
// Fades mons to black and places foggy overlay in Haze.
-void sub_810C0A0(u8 taskId)
+void AnimTask_Haze1(u8 taskId)
{
struct UnknownAnimStruct2 subStruct;
@@ -1208,10 +1224,10 @@ void sub_810C0A0(u8 taskId)
sub_80A6D60(&subStruct, gBattleAnimFogTilemap, 0);
LoadPalette(&gUnknown_083970E8, subStruct.unk8 * 16, 32);
- gTasks[taskId].func = sub_810C164;
+ gTasks[taskId].func = AnimTask_Haze2;
}
-void sub_810C164(u8 taskId)
+void AnimTask_Haze2(u8 taskId)
{
struct UnknownAnimStruct2 subStruct;
@@ -1284,9 +1300,669 @@ void sub_810C164(u8 taskId)
// arg 3: target y offset
// arg 4: duration
// arg 5: ??? unknown (seems to vibrate target mon somehow)
-void sub_810C2F0(struct Sprite *sprite)
+void AnimThrowMistBall(struct Sprite *sprite)
{
sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
sprite->callback = TranslateAnimSpriteToTargetMonLocation;
}
+
+// Displays misty background in Mist Ball.
+void AnimTask_LoadMistTiles(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].data[15] = -1;
+ gTasks[taskId].func = AnimTask_OverlayFogTiles;
+}
+
+void AnimTask_OverlayFogTiles(u8 taskId)
+{
+ struct UnknownAnimStruct2 subStruct;
+
+ gBattle_BG1_X += gTasks[taskId].data[15];
+ gBattle_BG1_Y += 0;
+
+ switch (gTasks[taskId].data[12])
+ {
+ case 0:
+ gTasks[taskId].data[9] += 1;
+ gTasks[taskId].data[11] = gUnknown_08595C88[gTasks[taskId].data[9]];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 17 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 5)
+ {
+ gTasks[taskId].data[12]++;
+ gTasks[taskId].data[11] = 0;
+ }
+ break;
+ case 1:
+ if (++gTasks[taskId].data[11] == 0x51)
+ {
+ gTasks[taskId].data[11] = 5;
+ gTasks[taskId].data[12]++;
+ }
+ break;
+ case 2:
+ if (++gTasks[taskId].data[10] == 4)
+ {
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[11] -= 1;
+ 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);
+ }
+}
+
+// Initializes gas clouds in the Poison Gas animation.
+// arg 0: duration
+// arg 1: ? target x offset
+// arg 2: ? target y offset
+// arg 3: ? swirl start x
+// arg 4: ? swirl start y
+// arg 5: ??? unknown
+// arg 6: ??? unknown
+// arg 7: ??? unknown boolean
+void InitPoisonGasCloudAnim(struct Sprite *sprite)
+{
+ sprite->data[0] = gBattleAnimArgs[0];
+
+ if (GetBattlerSpriteCoord(gBattleAnimAttacker, 2) < GetBattlerSpriteCoord(gBattleAnimTarget, 2))
+ sprite->data[7] = 0x8000;
+
+ if (!(gBattlerPositions[gBattleAnimTarget] & 1))
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+
+ if ((sprite->data[7] & 0x8000) && !(gBattlerPositions[gBattleAnimAttacker] & 1))
+ sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority + 1;
+
+ sprite->data[6] = 1;
+ }
+
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ if (gBattleAnimArgs[7])
+ {
+ sprite->data[1] = sprite->pos1.x + gBattleAnimArgs[1];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[3];
+ sprite->data[3] = sprite->pos1.y + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[4];
+ sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
+ }
+ else
+ {
+ sprite->data[1] = sprite->pos1.x + gBattleAnimArgs[1];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 0) + gBattleAnimArgs[3];
+ sprite->data[3] = sprite->pos1.y + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + gBattleAnimArgs[4];
+ sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
+ }
+
+ if (IsContest())
+ {
+ sprite->data[6] = 1;
+ sprite->subpriority = 0x80;
+ }
+
+ InitAnimLinearTranslation(sprite);
+ sprite->callback = MovePoisonGasCloud;
+}
+
+void MovePoisonGasCloud(struct Sprite *sprite)
+{
+ int value;
+ register s16 value2 asm("r5");
+ int unused;
+
+ switch (sprite->data[7] & 0xFF)
+ {
+ case 0:
+ AnimTranslateLinear(sprite);
+ value = gSineTable[sprite->data[5]];
+ sprite->pos2.x += value >> 4;
+ if (sprite->data[6])
+ sprite->data[5] = (sprite->data[5] - 8) & 0xFF;
+ else
+ sprite->data[5] = (sprite->data[5] + 8) & 0xFF;
+
+ if (sprite->data[0] <= 0)
+ {
+ value2 = 80;
+ sprite->data[0] = value2;
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y + 29;
+ sprite->data[7]++;
+ if (!IsContest() && gBattlerPositions[gBattleAnimTarget] & 1)
+ sprite->data[5] = 204;
+ else
+ sprite->data[5] = value2;
+
+ sprite->pos2.y = 0;
+ value = gSineTable[sprite->data[5]];
+ sprite->pos2.x = value >> 3;
+ sprite->data[5] = (sprite->data[5] + 2) & 0xFF;
+ InitAnimLinearTranslation(sprite);
+ }
+ break;
+ case 1:
+ AnimTranslateLinear(sprite);
+ value = gSineTable[sprite->data[5]];
+ sprite->pos2.x += value >> 3;
+ sprite->pos2.y += (gSineTable[sprite->data[5] + 0x40] * -3) >> 8;
+ if (!IsContest())
+ {
+ u16 var0 = sprite->data[5] - 0x40;
+ if (var0 <= 0x7F)
+ sprite->oam.priority = sprite->data[7] >> 8;
+ else
+ sprite->oam.priority = (sprite->data[7] >> 8) + 1;
+
+ sprite->data[5] = (sprite->data[5] + 4) & 0xFF;
+ }
+ else
+ {
+ u16 var0 = sprite->data[5] - 0x40;
+ if (var0 <= 0x7F)
+ sprite->subpriority = 128;
+ else
+ sprite->subpriority = 140;
+
+ sprite->data[5] = (sprite->data[5] - 4) & 0xFF;
+ }
+
+ if (sprite->data[0] <= 0)
+ {
+ asm("mov r5, #0"); // unused local variable?
+ unused = 0;
+ sprite->data[0] = 0x300;
+ sprite->data[1] = sprite->pos1.x += sprite->pos2.x;
+ sprite->data[3] = sprite->pos1.y += sprite->pos2.y;
+ sprite->data[4] = sprite->pos1.y + 4;
+ if (!IsContest() && gBattlerPositions[gBattleAnimTarget] & 1)
+ sprite->data[2] = 0x100;
+ else
+ sprite->data[2] = -0x10;
+
+ sprite->data[7]++;
+ sprite->pos2.x = sprite->pos2.y = 0;
+ sub_80A6FD4(sprite);
+ }
+ break;
+ case 2:
+ if (AnimTranslateLinear(sprite))
+ {
+ if (sprite->oam.affineMode & 1)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
+ }
+
+ DestroySprite(sprite);
+ gAnimVisualTaskCount--;
+ }
+ break;
+ }
+}
+
+// Creates Hail.
+void AnimTask_Hail1(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->func = AnimTask_Hail2;
+}
+
+void AnimTask_Hail2(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[4] > 2)
+ {
+ task->data[4] = 0;
+ task->data[5] = 0;
+ task->data[2] = 0;
+ task->data[0]++;
+ }
+ break;
+ case 1:
+ if (task->data[5] == 0)
+ {
+ if (GenerateHailParticle(task->data[3], task->data[2], taskId, 1))
+ task->data[1]++;
+
+ if (++task->data[2] == 3)
+ {
+ if (++task->data[3] == 10)
+ task->data[0]++;
+ else
+ task->data[0]--;
+ }
+ else
+ {
+ task->data[5] = 1;
+ }
+
+ }
+ else
+ {
+ task->data[5]--;
+ }
+ break;
+ case 2:
+ if (task->data[1] == 0)
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+#ifdef NONMATCHING
+bool8 GenerateHailParticle(u8 a, u8 b, u8 taskId, u8 c)
+{
+ bool8 possibleBool = FALSE;
+ // s8 unk = gUnknown_08595CB4[a].unk3;
+ const struct HailStruct *hailData = &gUnknown_08595CB4[a];
+ s8 unk = hailData->unk3;
+ u8 battler;
+ s16 battlerX, battlerY;
+ u8 spriteId;
+ // struct Sprite *sprite;
+ s16 spriteX;
+
+ if (unk != 2)
+ {
+ battler = GetBattlerAtPosition(hailData->unk2);
+ if (IsBattlerSpriteVisible(battler))
+ {
+ possibleBool = TRUE;
+ battlerX = GetBattlerSpriteCoord(battler, 2);
+ battlerY = GetBattlerSpriteCoord(battler, 3);
+ switch (unk)
+ {
+ case 0:
+ battlerX -= sub_80A861C(battler, 1) / 6;
+ battlerY -= sub_80A861C(battler, 0) / 6;
+ break;
+ case 1:
+ battlerX += sub_80A861C(battler, 1) / 6;
+ battlerY += sub_80A861C(battler, 0) / 6;
+ break;
+ }
+ }
+ }
+ else
+ {
+ battlerX = (hailData->unk0);
+ battlerY = (hailData->unk1);
+ }
+ spriteX = battlerX - ((battlerY + 8) / 2);
+ spriteId = CreateSprite(&gUnknown_08595D2C, spriteX, -8, 18);
+ if (spriteId == MAX_SPRITES)
+ return FALSE;
+ // sprite = &gSprites[spriteId];
+ StartSpriteAffineAnim(&gSprites[spriteId], b);
+ gSprites[spriteId].data[0] = possibleBool;
+ gSprites[spriteId].data[3] = battlerX;
+ gSprites[spriteId].data[4] = battlerY;
+ gSprites[spriteId].data[5] = b;
+ gSprites[spriteId].data[6] = taskId;
+ gSprites[spriteId].data[7] = c;
+ return TRUE;
+}
+#else
+NAKED
+bool8 GenerateHailParticle(u8 a, u8 b, u8 taskId, u8 c)
+{
+ 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, 0x8\n\
+ lsls r0, 24\n\
+ lsls r1, 24\n\
+ lsrs r1, 24\n\
+ mov r9, r1\n\
+ lsls r2, 24\n\
+ lsrs r2, 24\n\
+ str r2, [sp]\n\
+ lsls r3, 24\n\
+ lsrs r3, 24\n\
+ mov r10, r3\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x4]\n\
+ ldr r1, =gUnknown_08595CB4\n\
+ lsrs r0, 22\n\
+ adds r4, r0, r1\n\
+ ldrb r0, [r4, 0x3]\n\
+ lsls r0, 24\n\
+ asrs r0, 28\n\
+ mov r8, r0\n\
+ cmp r0, 0x2\n\
+ beq _0810CAD0\n\
+ ldrh r0, [r4, 0x2]\n\
+ lsls r0, 20\n\
+ lsrs r0, 24\n\
+ bl GetBattlerAtPosition\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ adds r0, r5, 0\n\
+ bl IsBattlerSpriteVisible\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _0810CAD0\n\
+ movs r0, 0x1\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r5, 0\n\
+ movs r1, 0x2\n\
+ bl GetBattlerSpriteCoord\n\
+ lsls r0, 24\n\
+ lsrs r7, r0, 24\n\
+ adds r0, r5, 0\n\
+ movs r1, 0x3\n\
+ bl GetBattlerSpriteCoord\n\
+ lsls r0, 24\n\
+ lsrs r6, r0, 24\n\
+ mov r1, r8\n\
+ cmp r1, 0\n\
+ beq _0810CA60\n\
+ cmp r1, 0x1\n\
+ beq _0810CA96\n\
+ b _0810CAE2\n\
+ .pool\n\
+_0810CA60:\n\
+ adds r0, r5, 0\n\
+ movs r1, 0x1\n\
+ bl sub_80A861C\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ movs r1, 0x6\n\
+ bl __divsi3\n\
+ lsls r1, r7, 16\n\
+ asrs r1, 16\n\
+ subs r1, r0\n\
+ lsls r1, 16\n\
+ lsrs r7, r1, 16\n\
+ adds r0, r5, 0\n\
+ movs r1, 0\n\
+ bl sub_80A861C\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ movs r1, 0x6\n\
+ bl __divsi3\n\
+ lsls r1, r6, 16\n\
+ asrs r1, 16\n\
+ subs r1, r0\n\
+ b _0810CACA\n\
+_0810CA96:\n\
+ adds r0, r5, 0\n\
+ movs r1, 0x1\n\
+ bl sub_80A861C\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ movs r1, 0x6\n\
+ bl __divsi3\n\
+ lsls r1, r7, 16\n\
+ asrs r1, 16\n\
+ adds r1, r0\n\
+ lsls r1, 16\n\
+ lsrs r7, r1, 16\n\
+ adds r0, r5, 0\n\
+ movs r1, 0\n\
+ bl sub_80A861C\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ movs r1, 0x6\n\
+ bl __divsi3\n\
+ lsls r1, r6, 16\n\
+ asrs r1, 16\n\
+ adds r1, r0\n\
+_0810CACA:\n\
+ lsls r1, 16\n\
+ lsrs r6, r1, 16\n\
+ b _0810CAE2\n\
+_0810CAD0:\n\
+ ldrh r0, [r4]\n\
+ lsls r0, 22\n\
+ asrs r0, 6\n\
+ lsrs r7, r0, 16\n\
+ ldr r0, [r4]\n\
+ lsls r0, 12\n\
+ asrs r0, 22\n\
+ lsls r0, 16\n\
+ lsrs r6, r0, 16\n\
+_0810CAE2:\n\
+ lsls r0, r6, 16\n\
+ asrs r0, 16\n\
+ adds r0, 0x8\n\
+ lsrs r1, r0, 31\n\
+ adds r0, r1\n\
+ asrs r0, 1\n\
+ lsls r1, r7, 16\n\
+ asrs r1, 16\n\
+ subs r1, r0\n\
+ ldr r0, =gUnknown_08595D2C\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ movs r2, 0x8\n\
+ negs r2, r2\n\
+ movs r3, 0x12\n\
+ bl CreateSprite\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ cmp r5, 0x40\n\
+ beq _0810CB44\n\
+ lsls r4, r5, 4\n\
+ adds r4, r5\n\
+ lsls r4, 2\n\
+ ldr r0, =gSprites\n\
+ adds r4, r0\n\
+ adds r0, r4, 0\n\
+ mov r1, r9\n\
+ bl StartSpriteAffineAnim\n\
+ mov r0, sp\n\
+ ldrh r0, [r0, 0x4]\n\
+ strh r0, [r4, 0x2E]\n\
+ strh r7, [r4, 0x34]\n\
+ strh r6, [r4, 0x36]\n\
+ mov r1, r9\n\
+ strh r1, [r4, 0x38]\n\
+ mov r0, sp\n\
+ ldrh r0, [r0]\n\
+ strh r0, [r4, 0x3A]\n\
+ mov r1, r10\n\
+ strh r1, [r4, 0x3C]\n\
+ movs r0, 0x1\n\
+ b _0810CB46\n\
+ .pool\n\
+_0810CB44:\n\
+ movs r0, 0\n\
+_0810CB46:\n\
+ add sp, 0x8\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n");
+}
+#endif
+
+void AnimHailBegin(struct Sprite *sprite)
+{
+ u8 spriteId;
+
+ sprite->pos1.x += 4;
+ sprite->pos1.y += 8;
+
+ if (sprite->pos1.x < sprite->data[3] && sprite->pos1.y < sprite->data[4])
+ return;
+
+ if (sprite->data[0] == 1 && sprite->data[5] == 0)
+ {
+ spriteId = CreateSprite(&gUnknown_08595B68,
+ sprite->data[3], sprite->data[4], sprite->subpriority);
+
+ sprite->data[0] = spriteId;
+ if (spriteId != 64)
+ {
+ gSprites[sprite->data[0]].callback = AnimHailContinue;
+ gSprites[sprite->data[0]].data[6] = sprite->data[6];
+ gSprites[sprite->data[0]].data[7] = sprite->data[7];
+ }
+
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+ else
+ {
+ gTasks[sprite->data[6]].data[sprite->data[7]]--;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+}
+
+void AnimHailContinue(struct Sprite *sprite)
+{
+ if (++sprite->data[0] == 20)
+ {
+ gTasks[sprite->data[6]].data[sprite->data[7]]--;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+}
+
+// Initializes the animation for Ice Ball.
+// 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
+// arg 5: arc height (negative)
+void InitIceBallAnim(struct Sprite *sprite)
+{
+ u8 animNum = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer - 1;
+
+ if (animNum > 4)
+ animNum = 4;
+
+ StartSpriteAffineAnim(sprite, animNum);
+ InitSpritePosToAnimAttacker(sprite, 1);
+
+ sprite->data[0] = gBattleAnimArgs[4];
+
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3];
+ sprite->data[5] = gBattleAnimArgs[5];
+
+ InitAnimArcTranslation(sprite);
+
+ sprite->callback = AnimThrowIceBall;
+}
+
+// Throws the ball of ice in Ice Ball.
+void AnimThrowIceBall(struct Sprite *sprite)
+{
+ if (!TranslateAnimArc(sprite))
+ return;
+
+ StartSpriteAnim(sprite, 1);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+// Initializes the particles that scatter at the end of the Ice Ball animation.
+void InitIceBallParticle(struct Sprite *sprite)
+{
+ s16 randA, randB;
+
+ sprite->oam.tileNum += 8;
+ InitSpritePosToAnimTarget(sprite, TRUE);
+
+ randA = (Random2() & 0xFF) + 256;
+ randB = Random2() & 0x1FF;
+
+ if (randB > 0xFF)
+ randB = 256 - randB;
+
+ sprite->data[1] = randA;
+ sprite->data[2] = randB;
+ sprite->callback = AnimIceBallParticle;
+}
+
+// Animates the particles created by InitIceBallParticle.
+void AnimIceBallParticle(struct Sprite *sprite)
+{
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+
+ if (sprite->data[1] & 1)
+ sprite->pos2.x = -(sprite->data[3] >> 8);
+ else
+ sprite->pos2.x = sprite->data[3] >> 8;
+
+ sprite->pos2.y = sprite->data[4] >> 8;
+
+ if (++sprite->data[0] == 21)
+ DestroyAnimSprite(sprite);
+}
+
+// Counter for Ice Ball.
+void AnimTask_GetRolloutCounter(u8 taskId)
+{
+ u8 arg = gBattleAnimArgs[0];
+
+ gBattleAnimArgs[arg] = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer - 1;
+ DestroyAnimVisualTask(taskId);
+}