diff options
Diffstat (limited to 'src/ice.c')
-rw-r--r-- | src/ice.c | 820 |
1 files changed, 748 insertions, 72 deletions
@@ -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); +} |