pokeemerald/src/battle_anim_ice.c

1653 lines
47 KiB
C
Raw Normal View History

2018-10-25 02:01:40 +02:00
#include "global.h"
#include "battle_anim.h"
2018-12-20 22:20:34 +01:00
#include "bg.h"
#include "field_weather.h"
#include "gpu_regs.h"
#include "graphics.h"
2018-12-21 07:37:59 +01:00
#include "main.h"
2018-12-20 22:20:34 +01:00
#include "palette.h"
2018-12-21 07:37:59 +01:00
#include "random.h"
2018-12-20 22:20:34 +01:00
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "constants/battle_anim.h"
2018-10-25 02:01:40 +02:00
#include "constants/rgb.h"
2018-12-21 07:37:59 +01:00
struct HailStruct {
2020-02-21 18:38:20 +01:00
s32 x:10;
s32 y:10;
s32 bPosition:8;
2018-12-21 07:37:59 +01:00
s32 unk3:4;
};
2021-04-11 19:21:22 +02:00
static void AnimUnusedIceCrystalThrow(struct Sprite *);
static void AnimUnusedIceCrystalThrow_Step(struct Sprite *);
2020-02-20 22:22:33 +01:00
static void AnimIcePunchSwirlingParticle(struct Sprite *);
static void AnimIceBeamParticle(struct Sprite *);
static void AnimFlickerIceEffectParticle(struct Sprite *);
static void AnimSwirlingSnowball(struct Sprite *);
static void AnimSwirlingSnowball_Step2(struct Sprite *);
static void AnimSwirlingSnowball_End(struct Sprite *);
static void AnimWiggleParticleTowardsTarget(struct Sprite *);
static void AnimWaveFromCenterOfTarget(struct Sprite *);
static void InitSwirlingFogAnim(struct Sprite *);
static void AnimSwirlingFogAnim(struct Sprite *);
2020-02-16 23:49:24 +01:00
static void InitPoisonGasCloudAnim(struct Sprite *);
2020-02-20 22:22:33 +01:00
static void MovePoisonGasCloud(struct Sprite *);
static void AnimHailBegin(struct Sprite *);
static void AnimHailContinue(struct Sprite *);
static void InitIceBallAnim(struct Sprite *);
static void AnimThrowIceBall(struct Sprite *);
static void InitIceBallParticle(struct Sprite *);
static void AnimIceBallParticle(struct Sprite *);
2021-02-28 00:41:30 +01:00
static void AnimTask_HazeScrollingFog_Step(u8);
static void AnimTask_LoadMistTiles_Step(u8);
2020-02-20 22:22:33 +01:00
static void AnimTask_Hail2(u8);
static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId, u8 c);
2020-02-29 13:59:41 +01:00
static void AvalancheAnim_Step(struct Sprite *sprite);
static void AvalancheAnim_Step2(struct Sprite *sprite);
2018-10-25 02:01:40 +02:00
2021-04-13 10:04:09 +02:00
static const union AnimCmd sAnim_Unused[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
ANIMCMD_FRAME(1, 5, .hFlip = TRUE),
ANIMCMD_JUMP(0),
};
2021-04-13 10:04:09 +02:00
static const union AnimCmd *const sAnims_Unused[] =
2018-10-25 02:01:40 +02:00
{
2021-04-13 10:04:09 +02:00
sAnim_Unused,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
// Unused
2021-04-11 19:21:22 +02:00
static const struct SpriteTemplate sUnusedIceCrystalThrowSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjNormal_8x8,
2018-10-25 02:01:40 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2021-04-11 19:21:22 +02:00
.callback = AnimUnusedIceCrystalThrow,
2018-10-25 02:01:40 +02:00
};
2021-04-11 19:21:22 +02:00
static const union AnimCmd sAnim_IceCrystalLargeChunk[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_IceCrystalLarge[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_IceCrystalSmall[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(6, 1),
ANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_Snowball[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(7, 1),
ANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_BlizzardIceCrystal[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_SmallBubblePair[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(12, 6),
ANIMCMD_FRAME(13, 6),
ANIMCMD_JUMP(0),
};
2021-04-11 19:21:22 +02:00
// Unused, contains just the top left corner of the large ice crystal
static const union AnimCmd *const sAnims_IceCrystalLargeChunk[] =
2018-10-25 02:01:40 +02:00
{
2021-04-11 19:21:22 +02:00
sAnim_IceCrystalLargeChunk,
2018-10-25 02:01:40 +02:00
};
2020-05-25 08:37:32 +02:00
const union AnimCmd *const gAnims_IceCrystalLarge[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_IceCrystalLarge,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd *const sAnims_IceCrystalSmall[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_IceCrystalSmall,
2018-10-25 02:01:40 +02:00
};
2020-05-25 08:37:32 +02:00
const union AnimCmd *const gAnims_Snowball[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_Snowball,
2018-10-25 02:01:40 +02:00
};
2020-05-25 08:37:32 +02:00
const union AnimCmd *const gAnims_BlizzardIceCrystal[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_BlizzardIceCrystal,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
const union AnimCmd *const gAnims_SmallBubblePair[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_SmallBubblePair,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceCrystalSpiralInwardLarge[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 40, 1),
AFFINEANIMCMD_JUMP(0),
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd *const sAffineAnims_IceCrystalSpiralInwardLarge[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAffineAnim_IceCrystalSpiralInwardLarge,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gIceCrystalSpiralInwardLarge =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineDouble_ObjBlend_8x16,
2020-05-25 08:37:32 +02:00
.anims = gAnims_IceCrystalLarge,
2018-10-25 02:01:40 +02:00
.images = NULL,
2020-02-21 18:38:20 +01:00
.affineAnims = sAffineAnims_IceCrystalSpiralInwardLarge,
2018-12-21 07:37:59 +01:00
.callback = AnimIcePunchSwirlingParticle,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gIceCrystalSpiralInwardSmall =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjBlend_8x8,
2020-02-21 18:38:20 +01:00
.anims = sAnims_IceCrystalSmall,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = AnimIcePunchSwirlingParticle,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceBeamInnerCrystal[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1),
AFFINEANIMCMD_JUMP(0),
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd *const sAffineAnims_IceBeamInnerCrystal[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAffineAnim_IceBeamInnerCrystal,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gIceBeamInnerCrystalSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineNormal_ObjBlend_8x16,
2020-05-25 08:37:32 +02:00
.anims = gAnims_IceCrystalLarge,
2018-10-25 02:01:40 +02:00
.images = NULL,
2020-02-21 18:38:20 +01:00
.affineAnims = sAffineAnims_IceBeamInnerCrystal,
2018-12-21 07:37:59 +01:00
.callback = AnimIceBeamParticle,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gIceBeamOuterCrystalSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjBlend_8x8,
2020-02-21 18:38:20 +01:00
.anims = sAnims_IceCrystalSmall,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = AnimIceBeamParticle,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceCrystalHit[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0xCE, 0xCE, 0, 0),
AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 10),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6),
AFFINEANIMCMD_END,
};
2020-05-25 08:37:32 +02:00
const union AffineAnimCmd *const gAffineAnims_IceCrystalHit[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAffineAnim_IceCrystalHit,
2018-10-25 02:01:40 +02:00
};
2020-02-14 22:05:43 +01:00
const struct SpriteTemplate gIceCrystalHitLargeSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineNormal_ObjBlend_8x16,
2020-05-25 08:37:32 +02:00
.anims = gAnims_IceCrystalLarge,
2018-10-25 02:01:40 +02:00
.images = NULL,
2020-05-25 08:37:32 +02:00
.affineAnims = gAffineAnims_IceCrystalHit,
2018-12-21 07:37:59 +01:00
.callback = AnimIceEffectParticle,
2018-10-25 02:01:40 +02:00
};
2020-02-14 22:05:43 +01:00
const struct SpriteTemplate gIceCrystalHitSmallSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineNormal_ObjBlend_8x8,
2020-02-21 18:38:20 +01:00
.anims = sAnims_IceCrystalSmall,
2018-10-25 02:01:40 +02:00
.images = NULL,
2020-05-25 08:37:32 +02:00
.affineAnims = gAffineAnims_IceCrystalHit,
2018-12-21 07:37:59 +01:00
.callback = AnimIceEffectParticle,
2018-10-25 02:01:40 +02:00
};
2020-02-14 22:05:43 +01:00
const struct SpriteTemplate gSwirlingSnowballSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjNormal_8x8,
2020-05-25 08:37:32 +02:00
.anims = gAnims_Snowball,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-02-20 22:22:33 +01:00
.callback = AnimSwirlingSnowball,
2018-10-25 02:01:40 +02:00
};
2020-02-14 22:05:43 +01:00
const struct SpriteTemplate gBlizzardIceCrystalSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjNormal_16x16,
2020-05-25 08:37:32 +02:00
.anims = gAnims_BlizzardIceCrystal,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = AnimMoveParticleBeyondTarget,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gPowderSnowSnowballSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjNormal_8x8,
2020-05-25 08:37:32 +02:00
.anims = gAnims_Snowball,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = AnimMoveParticleBeyondTarget,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_IceGroundSpike[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(6, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd *const sAnims_IceGroundSpike[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_IceGroundSpike,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
const struct SpriteTemplate gIceGroundSpikeSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_SPIKES,
.paletteTag = ANIM_TAG_ICE_SPIKES,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjBlend_8x16,
2020-02-21 18:38:20 +01:00
.anims = sAnims_IceGroundSpike,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = AnimWaveFromCenterOfTarget,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_Cloud[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(8, 8),
ANIMCMD_JUMP(0),
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd *const sAnims_Cloud[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_Cloud,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gMistCloudSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_MIST_CLOUD,
.paletteTag = ANIM_TAG_MIST_CLOUD,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjBlend_32x16,
2020-02-21 18:38:20 +01:00
.anims = sAnims_Cloud,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = InitSwirlingFogAnim,
2018-10-25 02:01:40 +02:00
};
2020-02-20 02:22:53 +01:00
const struct SpriteTemplate gSmogCloudSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_PURPLE_GAS_CLOUD,
.paletteTag = ANIM_TAG_PURPLE_GAS_CLOUD,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjBlend_32x16,
2020-02-21 18:38:20 +01:00
.anims = sAnims_Cloud,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = InitSwirlingFogAnim,
2018-10-25 02:01:40 +02:00
};
2021-02-28 00:41:30 +01:00
static const u8 sHazeBlendAmounts[] =
2018-10-25 02:01:40 +02:00
{
0, 1, 2, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7, 8, 8, 8, 9,
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gMistBallSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjNormal_16x16,
2018-10-25 02:01:40 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = AnimThrowMistBall,
2018-10-25 02:01:40 +02:00
};
2021-02-28 00:41:30 +01:00
static const u8 wMistBlendAmounts[] =
2018-10-25 02:01:40 +02:00
{
0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gPoisonGasCloudSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_PURPLE_GAS_CLOUD,
.paletteTag = ANIM_TAG_PURPLE_GAS_CLOUD,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjBlend_32x16,
2020-02-21 18:38:20 +01:00
.anims = sAnims_Cloud,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = InitPoisonGasCloudAnim,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const struct HailStruct sHailCoordData[] =
2018-12-21 07:37:59 +01:00
{
2020-02-21 18:38:20 +01:00
{.x = 100, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 2},
{.x = 85, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 0},
{.x = 242, .y = 120, .bPosition = B_POSITION_OPPONENT_LEFT, .unk3 = 1},
{.x = 66, .y = 120, .bPosition = B_POSITION_PLAYER_RIGHT, .unk3 = 1},
{.x = 182, .y = 120, .bPosition = B_POSITION_OPPONENT_RIGHT, .unk3 = 0},
{.x = 60, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 2},
{.x = 214, .y = 120, .bPosition = B_POSITION_OPPONENT_LEFT, .unk3 = 0},
{.x = 113, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 1},
{.x = 210, .y = 120, .bPosition = B_POSITION_OPPONENT_RIGHT, .unk3 = 1},
{.x = 38, .y = 120, .bPosition = B_POSITION_PLAYER_RIGHT, .unk3 = 0},
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_HailParticle_0[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_HailParticle_1[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0xF0, 0xF0, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_HailParticle_2[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_WeatherBallIceDown[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd *const sAffineAnims_HailParticle[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAffineAnim_HailParticle_0,
sAffineAnim_HailParticle_1,
sAffineAnim_HailParticle_2,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd *const sAffineAnims_WeatherBallIceDown[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAffineAnim_WeatherBallIceDown,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
const struct SpriteTemplate gHailParticleSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_HAIL,
.paletteTag = ANIM_TAG_HAIL,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
2018-10-25 02:01:40 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
2020-02-21 18:38:20 +01:00
.affineAnims = sAffineAnims_HailParticle,
2018-12-21 07:37:59 +01:00
.callback = AnimHailBegin,
2018-10-25 02:01:40 +02:00
};
2020-02-20 02:22:53 +01:00
const struct SpriteTemplate gWeatherBallIceDownSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_HAIL,
.paletteTag = ANIM_TAG_HAIL,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
2018-10-25 02:01:40 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
2020-02-21 18:38:20 +01:00
.affineAnims = sAffineAnims_WeatherBallIceDown,
2020-02-20 02:22:53 +01:00
.callback = AnimWeatherBallDown,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_IceBallChunk_0[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AnimCmd sAnim_IceBallChunk_1[] =
2018-10-25 02:01:40 +02:00
{
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_END,
};
2020-05-25 08:37:32 +02:00
const union AnimCmd *const gAnims_IceBallChunk[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAnim_IceBallChunk_0,
sAnim_IceBallChunk_1,
2018-10-25 02:01:40 +02:00
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceBallChunk_0[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceBallChunk_1[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x118, 0x118, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceBallChunk_2[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceBallChunk_3[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x180, 0x180, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd sAffineAnim_IceBallChunk_4[] =
2018-10-25 02:01:40 +02:00
{
AFFINEANIMCMD_FRAME(0x1C0, 0x1C0, 0, 0),
AFFINEANIMCMD_END,
};
2020-02-21 18:38:20 +01:00
static const union AffineAnimCmd *const sAffineAnims_IceBallChunk[] =
2018-10-25 02:01:40 +02:00
{
2020-02-21 18:38:20 +01:00
sAffineAnim_IceBallChunk_0,
sAffineAnim_IceBallChunk_1,
sAffineAnim_IceBallChunk_2,
sAffineAnim_IceBallChunk_3,
sAffineAnim_IceBallChunk_4,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gIceBallChunkSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CHUNK,
.paletteTag = ANIM_TAG_ICE_CHUNK,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
2020-05-25 08:37:32 +02:00
.anims = gAnims_IceBallChunk,
2018-10-25 02:01:40 +02:00
.images = NULL,
2020-02-21 18:38:20 +01:00
.affineAnims = sAffineAnims_IceBallChunk,
2018-12-21 07:37:59 +01:00
.callback = InitIceBallAnim,
2018-10-25 02:01:40 +02:00
};
2020-02-16 23:49:24 +01:00
const struct SpriteTemplate gIceBallImpactShardSpriteTemplate =
2018-10-25 02:01:40 +02:00
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
2019-10-15 01:26:47 +02:00
.oam = &gOamData_AffineOff_ObjNormal_8x8,
2020-02-21 18:38:20 +01:00
.anims = sAnims_IceCrystalSmall,
2018-10-25 02:01:40 +02:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-21 07:37:59 +01:00
.callback = InitIceBallParticle,
2018-10-25 02:01:40 +02:00
};
2018-12-20 22:20:34 +01:00
const union AnimCmd gAvalancheAnimTable_1[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END,
};
const union AnimCmd gAvalancheAnimTable_2[] =
{
ANIMCMD_FRAME(48, 1),
ANIMCMD_END,
};
const union AnimCmd gAvalancheAnimTable_3[] =
{
ANIMCMD_FRAME(64, 1),
ANIMCMD_END,
};
const union AnimCmd *const gAvalancheAnimCmd[] =
{
gAvalancheAnimTable_1,
gAvalancheAnimTable_2,
gAvalancheAnimTable_3,
};
const struct SpriteTemplate gAvalancheSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ICE_CHUNK,
2019-10-19 17:47:55 +02:00
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAvalancheAnimCmd,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AvalancheAnim_Step,
};
2020-05-04 06:09:03 +02:00
const struct SpriteTemplate gChatterSingNotesTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES,
.paletteTag = ANIM_TAG_MUSIC_NOTES,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gMusicNotesAnimTable,
.images = NULL,
2020-05-25 08:37:32 +02:00
.affineAnims = gAffineAnims_IceCrystalHit,
2020-05-04 06:09:03 +02:00
.callback = AnimIceEffectParticle
};
2020-02-29 13:59:41 +01:00
static void AvalancheAnim_Step(struct Sprite *sprite)
{
if (gBattleAnimArgs[3] != 0)
SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->x, &sprite->y);
sprite->x += gBattleAnimArgs[0];
sprite->y += 14;
StartSpriteAnim(sprite, gBattleAnimArgs[1]);
AnimateSprite(sprite);
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2] = 4;
sprite->data[3] = 16;
sprite->data[4] = -70;
sprite->data[5] = gBattleAnimArgs[2];
StoreSpriteCallbackInData6(sprite, AvalancheAnim_Step2);
sprite->callback = TranslateSpriteInEllipse;
sprite->callback(sprite);
}
static void AvalancheAnim_Step2(struct Sprite *sprite)
{
sprite->x += sprite->data[5];
sprite->data[0] = 192;
sprite->data[1] = sprite->data[5];
sprite->data[2] = 4;
sprite->data[3] = 32;
sprite->data[4] = -24;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteInEllipse;
sprite->callback(sprite);
}
2020-02-21 18:38:20 +01:00
// Unused
2021-04-11 19:21:22 +02:00
static void AnimUnusedIceCrystalThrow(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
s16 targetX, targetY, attackerX, attackerY;
2019-02-01 12:26:40 +01:00
2018-12-20 22:20:34 +01:00
sprite->oam.tileNum += 7;
2019-04-11 12:05:56 +02:00
targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
2018-12-20 22:20:34 +01:00
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;
2021-11-01 17:41:21 +01:00
ConvertPosDataToTranslateLinearData(sprite);
2019-04-11 12:05:56 +02:00
2021-04-11 19:21:22 +02:00
for (;(targetX >= -32 && targetX <= DISPLAY_WIDTH + 32) && (targetY >= -32 && targetY <= DISPLAY_HEIGHT + 32);
2019-04-11 12:05:56 +02:00
targetX += sprite->data[1], targetY += sprite->data[2])
;
2018-12-20 22:20:34 +01:00
sprite->data[1] = -sprite->data[1];
sprite->data[2] = -sprite->data[2];
2021-04-11 19:21:22 +02:00
for (;(attackerX >= -32 && attackerX <= DISPLAY_WIDTH + 32) && (attackerY >= -32 && attackerY <= DISPLAY_HEIGHT + 32);
2019-04-11 12:05:56 +02:00
attackerX += sprite->data[1], attackerY += sprite->data[2])
;
2021-07-07 15:11:52 +02:00
sprite->x = attackerX;
sprite->y = attackerY;
2018-12-20 22:20:34 +01:00
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = attackerX;
sprite->data[2] = targetX;
sprite->data[3] = attackerY;
sprite->data[4] = targetY;
2021-11-01 17:41:21 +01:00
ConvertPosDataToTranslateLinearData(sprite);
2018-12-20 22:20:34 +01:00
sprite->data[3] = gBattleAnimArgs[5];
sprite->data[4] = gBattleAnimArgs[6];
2021-04-11 19:21:22 +02:00
sprite->callback = AnimUnusedIceCrystalThrow_Step;
2018-12-20 22:20:34 +01:00
}
2018-12-23 07:25:01 +01:00
2021-04-11 19:21:22 +02:00
static void AnimUnusedIceCrystalThrow_Step(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
if (sprite->data[0] != 0)
{
sprite->data[5] += sprite->data[1];
sprite->data[6] += sprite->data[2];
2021-07-07 15:11:52 +02:00
sprite->x2 = sprite->data[5];
sprite->y2 = sprite->data[6];
sprite->x2 += Sin(sprite->data[7], sprite->data[3]);
sprite->y2 += Sin(sprite->data[7], sprite->data[3]);
2018-12-20 22:20:34 +01:00
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)
2020-02-20 22:22:33 +01:00
static void AnimIcePunchSwirlingParticle(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = 60;
sprite->data[2] = 9;
sprite->data[3] = 30;
sprite->data[4] = -512;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
2021-11-08 19:18:58 +01:00
sprite->callback = TranslateSpriteInGrowingCircle;
2018-12-20 22:20:34 +01:00
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
2020-02-20 22:22:33 +01:00
static void AnimIceBeamParticle(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
InitSpritePosToAnimAttacker(sprite, TRUE);
2019-04-11 12:05:56 +02:00
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
2018-12-20 22:20:34 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->data[2] -= gBattleAnimArgs[2];
else
sprite->data[2] += gBattleAnimArgs[2];
2019-04-11 12:05:56 +02:00
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
2018-12-20 22:20:34 +01:00
sprite->data[0] = gBattleAnimArgs[4];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = StartAnimLinearTranslation;
}
2019-02-01 12:26:40 +01:00
// Animates the ice crystals at the end of Ice Punch, Ice Beam, Tri Attack,
2018-12-20 22:20:34 +01:00
// Weather Ball (Hail), Blizzard, and Powder Snow.
// arg 0: target x offset
// arg 1: target y offset
// arg 2: ??? unknown boolean
2020-05-25 08:37:32 +02:00
void AnimIceEffectParticle(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
if (gBattleAnimArgs[2] == 0)
{
InitSpritePosToAnimTarget(sprite, TRUE);
}
else
{
2021-07-07 15:11:52 +02:00
SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->x, &sprite->y);
2018-12-20 22:20:34 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
2021-07-07 15:11:52 +02:00
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
2018-12-20 22:20:34 +01:00
}
2018-12-21 07:37:59 +01:00
StoreSpriteCallbackInData6(sprite, AnimFlickerIceEffectParticle);
2018-12-20 22:20:34 +01:00
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
2020-02-20 22:22:33 +01:00
static void AnimFlickerIceEffectParticle(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
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)
2020-02-20 22:22:33 +01:00
static void AnimSwirlingSnowball(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
int i;
s16 tempDataHolder[8];
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
2021-07-07 15:11:52 +02:00
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
2018-12-20 22:20:34 +01:00
if (!gBattleAnimArgs[5])
{
2019-04-11 12:05:56 +02:00
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
2018-12-20 22:20:34 +01:00
}
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);
2021-07-07 15:11:52 +02:00
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
2018-12-20 22:20:34 +01:00
break;
}
2021-07-07 15:11:52 +02:00
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
2018-12-20 22:20:34 +01:00
for (i = 0; i < 8; i++)
sprite->data[i] = tempDataHolder[i];
2021-01-23 06:40:46 +01:00
sprite->callback = InitAnimFastLinearTranslationWithSpeedAndPos;
2020-02-20 22:22:33 +01:00
StoreSpriteCallbackInData6(sprite, AnimSwirlingSnowball_Step1);
2018-12-20 22:20:34 +01:00
}
2020-05-25 08:37:32 +02:00
void AnimSwirlingSnowball_Step1(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
s16 tempVar;
2021-07-07 15:11:52 +02:00
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
2018-12-20 22:20:34 +01:00
sprite->data[0] = 128;
2019-02-01 12:26:40 +01:00
tempVar = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 20 : -20;
2018-12-20 22:20:34 +01:00
sprite->data[3] = Sin(sprite->data[0], tempVar);
sprite->data[4] = Cos(sprite->data[0], 0xF);
sprite->data[5] = 0;
2020-02-20 22:22:33 +01:00
sprite->callback = AnimSwirlingSnowball_Step2;
2018-12-20 22:20:34 +01:00
sprite->callback(sprite);
}
2020-02-20 22:22:33 +01:00
static void AnimSwirlingSnowball_Step2(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
s16 tempVar;
tempVar = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 20 : -20;
2018-12-20 22:20:34 +01:00
if (sprite->data[5] <= 31)
{
2021-07-07 15:11:52 +02:00
sprite->x2 = Sin(sprite->data[0], tempVar) - sprite->data[3];
sprite->y2 = Cos(sprite->data[0], 15) - sprite->data[4];
2018-12-20 22:20:34 +01:00
sprite->data[0] = (sprite->data[0] + 16) & 0xFF;
sprite->data[5] += 1;
}
else
{
2021-07-07 15:11:52 +02:00
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
2018-12-20 22:20:34 +01:00
sprite->data[4] = 0;
sprite->data[3] = 0;
2018-12-21 07:37:59 +01:00
sprite->callback = AnimSwirlingSnowball_End;
2018-12-20 22:20:34 +01:00
}
}
2020-02-20 22:22:33 +01:00
static void AnimSwirlingSnowball_End(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
2021-07-07 15:11:52 +02:00
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
|| sprite->y + sprite->y2 > 256
|| sprite->y + sprite->y2 < -16)
2018-12-20 22:20:34 +01:00
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)
2020-05-25 08:37:32 +02:00
void AnimMoveParticleBeyondTarget(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
int i;
s16 tempDataHolder[8];
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
2021-07-07 15:11:52 +02:00
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
2018-12-20 22:20:34 +01:00
if (!gBattleAnimArgs[7])
{
2019-04-11 12:05:56 +02:00
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
2018-12-20 22:20:34 +01:00
}
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);
2021-07-07 15:11:52 +02:00
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
2018-12-20 22:20:34 +01:00
break;
}
2021-07-07 15:11:52 +02:00
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
2018-12-20 22:20:34 +01:00
for (i = 0; i < 8; i++)
sprite->data[i] = tempDataHolder[i];
sprite->data[5] = gBattleAnimArgs[5];
sprite->data[6] = gBattleAnimArgs[6];
2018-12-21 07:37:59 +01:00
sprite->callback = AnimWiggleParticleTowardsTarget;
2018-12-20 22:20:34 +01:00
}
// Moves particles in a sine wave towards the target.
2020-02-20 22:22:33 +01:00
static void AnimWiggleParticleTowardsTarget(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
AnimFastTranslateLinear(sprite);
if (sprite->data[0] == 0)
sprite->data[0] = 1;
2021-07-07 15:11:52 +02:00
sprite->y2 += Sin(sprite->data[7], sprite->data[5]);
2018-12-20 22:20:34 +01:00
sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
if (sprite->data[0] == 1)
{
2021-07-07 15:11:52 +02:00
if ((u32)(sprite->x + sprite->x2 + 16) > DISPLAY_WIDTH + 32
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
2018-12-20 22:20:34 +01:00
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
2020-02-20 22:22:33 +01:00
static void AnimWaveFromCenterOfTarget(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
if (sprite->data[0] == 0)
{
if (gBattleAnimArgs[2] == 0)
{
InitSpritePosToAnimTarget(sprite, FALSE);
}
else
{
2021-07-07 15:11:52 +02:00
SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->x, &sprite->y);
2018-12-20 22:20:34 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
2021-07-07 15:11:52 +02:00
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
2018-12-20 22:20:34 +01:00
}
2019-02-01 12:26:40 +01:00
sprite->data[0]++;
2018-12-20 22:20:34 +01:00
}
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
2020-02-20 22:22:33 +01:00
static void InitSwirlingFogAnim(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
s16 tempVar;
u8 battler;
if (gBattleAnimArgs[4] == 0)
{
if (gBattleAnimArgs[5] == 0)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
}
else
{
2021-07-07 15:11:52 +02:00
SetAverageBattlerPositions(gBattleAnimAttacker, 0, &sprite->x, &sprite->y);
2019-02-01 12:26:40 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
2021-07-07 15:11:52 +02:00
sprite->x -= gBattleAnimArgs[0];
2019-02-01 12:26:40 +01:00
else
2021-07-07 15:11:52 +02:00
sprite->x += gBattleAnimArgs[0];
2018-12-20 22:20:34 +01:00
2021-07-07 15:11:52 +02:00
sprite->y += gBattleAnimArgs[1];
2018-12-20 22:20:34 +01:00
}
battler = gBattleAnimAttacker;
}
2019-02-01 12:26:40 +01:00
else
2018-12-20 22:20:34 +01:00
{
if (gBattleAnimArgs[5] == 0)
{
InitSpritePosToAnimTarget(sprite, FALSE);
}
2019-02-01 12:26:40 +01:00
else
2018-12-20 22:20:34 +01:00
{
2021-07-07 15:11:52 +02:00
SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->x, &sprite->y);
2018-12-20 22:20:34 +01:00
if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER)
2021-07-07 15:11:52 +02:00
sprite->x -= gBattleAnimArgs[0];
2019-02-01 12:26:40 +01:00
else
2021-07-07 15:11:52 +02:00
sprite->x += gBattleAnimArgs[0];
2018-12-20 22:20:34 +01:00
2021-07-07 15:11:52 +02:00
sprite->y += gBattleAnimArgs[1];
2018-12-20 22:20:34 +01:00
}
battler = gBattleAnimTarget;
}
sprite->data[7] = battler;
2019-02-01 12:26:40 +01:00
if (gBattleAnimArgs[5] == 0 || !IsDoubleBattle())
2018-12-20 22:20:34 +01:00
tempVar = 0x20;
else
tempVar = 0x40;
sprite->data[6] = tempVar;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
2021-07-07 15:11:52 +02:00
sprite->y += 8;
2018-12-20 22:20:34 +01:00
sprite->data[0] = gBattleAnimArgs[3];
2021-07-07 15:11:52 +02:00
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x;
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->y + gBattleAnimArgs[2];
2018-12-20 22:20:34 +01:00
InitAnimLinearTranslation(sprite);
sprite->data[5] = 64;
2018-12-21 07:37:59 +01:00
sprite->callback = AnimSwirlingFogAnim;
2018-12-20 22:20:34 +01:00
sprite->callback(sprite);
}
// Animates swirling fog initialized by InitSwirlingFogAnim.
2020-02-20 22:22:33 +01:00
static void AnimSwirlingFogAnim(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
if (!AnimTranslateLinear(sprite))
{
2021-07-07 15:11:52 +02:00
sprite->x2 += Sin(sprite->data[5], sprite->data[6]);
sprite->y2 += Cos(sprite->data[5], -6);
2018-12-20 22:20:34 +01:00
if ((u16)(sprite->data[5] - 64) <= 0x7F)
2019-02-01 12:26:40 +01:00
sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]);
2018-12-20 22:20:34 +01:00
else
sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]) + 1;
sprite->data[5] = (sprite->data[5] + 3) & 0xFF;
}
else
{
DestroyAnimSprite(sprite);
}
}
2020-02-15 00:11:04 +01:00
// Adds moving foggy overlay. Used by Haze.
void AnimTask_HazeScrollingFog(u8 taskId)
2018-12-20 22:20:34 +01:00
{
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2018-12-20 22:20:34 +01:00
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);
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
LoadBgTiles(animBg.bgId, gWeatherFogHorizontalTiles, 0x800, animBg.tilesOffset);
2021-10-04 16:21:03 +02:00
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimFogTilemap, FALSE);
2021-02-28 00:41:30 +01:00
LoadPalette(&gFogPalette, animBg.paletteId * 16, 32);
2019-02-01 12:26:40 +01:00
2021-02-28 00:41:30 +01:00
gTasks[taskId].func = AnimTask_HazeScrollingFog_Step;
2018-12-20 22:20:34 +01:00
}
2021-02-28 00:41:30 +01:00
static void AnimTask_HazeScrollingFog_Step(u8 taskId)
2018-12-20 22:20:34 +01:00
{
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2018-12-20 22:20:34 +01:00
gBattle_BG1_X += -1;
gBattle_BG1_Y += 0;
switch (gTasks[taskId].data[12])
{
2019-02-01 12:26:40 +01:00
case 0:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[9]++;
2021-02-28 00:41:30 +01:00
gTasks[taskId].data[11] = sHazeBlendAmounts[gTasks[taskId].data[9]];
2019-02-01 12:26:40 +01:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 9)
2018-12-20 22:20:34 +01:00
{
gTasks[taskId].data[12]++;
2019-02-01 12:26:40 +01:00
gTasks[taskId].data[11] = 0;
2018-12-20 22:20:34 +01:00
}
2019-02-01 12:26:40 +01:00
}
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)
2018-12-20 22:20:34 +01:00
{
2019-02-01 12:26:40 +01:00
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
2018-12-20 22:20:34 +01:00
}
2019-02-01 12:26:40 +01:00
}
break;
case 3:
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(1);
ClearBattleAnimBg(2);
2019-02-01 12:26:40 +01:00
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);
break;
2018-12-20 22:20:34 +01:00
}
2019-02-01 12:26:40 +01:00
}
2018-12-20 22:20:34 +01:00
// 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)
2020-05-25 08:37:32 +02:00
void AnimThrowMistBall(struct Sprite *sprite)
2018-12-20 22:20:34 +01:00
{
2021-07-07 15:11:52 +02:00
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
2018-12-20 22:20:34 +01:00
sprite->callback = TranslateAnimSpriteToTargetMonLocation;
}
2018-12-21 07:37:59 +01:00
// Displays misty background in Mist Ball.
void AnimTask_LoadMistTiles(u8 taskId)
{
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2018-12-21 07:37:59 +01:00
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);
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
LoadBgTiles(animBg.bgId, gWeatherFogHorizontalTiles, 0x800, animBg.tilesOffset);
2021-10-04 16:21:03 +02:00
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimFogTilemap, FALSE);
2021-02-28 00:41:30 +01:00
LoadPalette(&gFogPalette, animBg.paletteId * 16, 32);
2019-02-01 12:26:40 +01:00
2018-12-21 07:37:59 +01:00
gTasks[taskId].data[15] = -1;
2021-02-28 00:41:30 +01:00
gTasks[taskId].func = AnimTask_LoadMistTiles_Step;
2018-12-21 07:37:59 +01:00
}
2021-02-28 00:41:30 +01:00
static void AnimTask_LoadMistTiles_Step(u8 taskId)
2018-12-21 07:37:59 +01:00
{
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2018-12-21 07:37:59 +01:00
gBattle_BG1_X += gTasks[taskId].data[15];
gBattle_BG1_Y += 0;
switch (gTasks[taskId].data[12])
{
2019-02-01 12:26:40 +01:00
case 0:
gTasks[taskId].data[9] += 1;
2021-02-28 00:41:30 +01:00
gTasks[taskId].data[11] = wMistBlendAmounts[gTasks[taskId].data[9]];
2019-02-01 12:26:40 +01:00
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)
2018-12-21 07:37:59 +01:00
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
2019-02-01 12:26:40 +01:00
}
break;
case 3:
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(1);
ClearBattleAnimBg(2);
2019-02-01 12:26:40 +01:00
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);
break;
2018-12-21 07:37:59 +01:00
}
}
// 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
2020-02-16 23:49:24 +01:00
static void InitPoisonGasCloudAnim(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
sprite->data[0] = gBattleAnimArgs[0];
2019-04-11 12:05:56 +02:00
if (GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) < GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2))
2018-12-21 07:37:59 +01:00
sprite->data[7] = 0x8000;
2019-09-04 23:45:04 +02:00
if ((gBattlerPositions[gBattleAnimTarget] & BIT_SIDE) == B_SIDE_PLAYER)
2018-12-21 07:37:59 +01:00
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
2019-09-04 23:45:04 +02:00
if ((sprite->data[7] & 0x8000) && (gBattlerPositions[gBattleAnimAttacker] & BIT_SIDE) == B_SIDE_PLAYER)
2018-12-21 07:37:59 +01:00
sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority + 1;
2019-02-01 12:26:40 +01:00
sprite->data[6] = 1;
2018-12-21 07:37:59 +01:00
}
2021-07-07 15:11:52 +02:00
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
2018-12-21 07:37:59 +01:00
if (gBattleAnimArgs[7])
{
2021-07-07 15:11:52 +02:00
sprite->data[1] = sprite->x + gBattleAnimArgs[1];
2019-04-11 12:05:56 +02:00
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[3];
2021-07-07 15:11:52 +02:00
sprite->data[3] = sprite->y + gBattleAnimArgs[2];
2019-04-11 12:05:56 +02:00
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[4];
2018-12-21 07:37:59 +01:00
sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
}
else
{
2021-07-07 15:11:52 +02:00
sprite->data[1] = sprite->x + gBattleAnimArgs[1];
2019-04-11 12:05:56 +02:00
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[3];
2021-07-07 15:11:52 +02:00
sprite->data[3] = sprite->y + gBattleAnimArgs[2];
2019-04-11 12:05:56 +02:00
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[4];
2018-12-21 07:37:59 +01:00
sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
2019-02-01 12:26:40 +01:00
}
2018-12-21 07:37:59 +01:00
if (IsContest())
{
sprite->data[6] = 1;
sprite->subpriority = 0x80;
}
InitAnimLinearTranslation(sprite);
sprite->callback = MovePoisonGasCloud;
}
2020-02-20 22:22:33 +01:00
static void MovePoisonGasCloud(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
int value;
switch (sprite->data[7] & 0xFF)
{
case 0:
AnimTranslateLinear(sprite);
value = gSineTable[sprite->data[5]];
2021-07-07 15:11:52 +02:00
sprite->x2 += value >> 4;
2018-12-21 07:37:59 +01:00
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)
{
2019-02-01 12:26:40 +01:00
sprite->data[0] = 80;
2021-07-07 15:11:52 +02:00
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x;
sprite->y += sprite->y2;
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->y + 29;
2018-12-21 07:37:59 +01:00
sprite->data[7]++;
2019-02-01 12:26:40 +01:00
if (IsContest())
sprite->data[5] = 80;
else if (GET_BATTLER_SIDE2(gBattleAnimTarget) != B_SIDE_PLAYER)
2018-12-21 07:37:59 +01:00
sprite->data[5] = 204;
else
2019-02-01 12:26:40 +01:00
sprite->data[5] = 80;
2018-12-21 07:37:59 +01:00
2021-07-07 15:11:52 +02:00
sprite->y2 = 0;
2018-12-21 07:37:59 +01:00
value = gSineTable[sprite->data[5]];
2021-07-07 15:11:52 +02:00
sprite->x2 = value >> 3;
2018-12-21 07:37:59 +01:00
sprite->data[5] = (sprite->data[5] + 2) & 0xFF;
InitAnimLinearTranslation(sprite);
}
break;
case 1:
AnimTranslateLinear(sprite);
value = gSineTable[sprite->data[5]];
2021-07-07 15:11:52 +02:00
sprite->x2 += value >> 3;
sprite->y2 += (gSineTable[sprite->data[5] + 0x40] * -3) >> 8;
2018-12-21 07:37:59 +01:00
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)
{
sprite->data[0] = 0x300;
2021-07-07 15:11:52 +02:00
sprite->data[1] = sprite->x += sprite->x2;
sprite->data[3] = sprite->y += sprite->y2;
sprite->data[4] = sprite->y + 4;
2019-02-01 12:26:40 +01:00
if (IsContest())
sprite->data[2] = -0x10;
else if (GET_BATTLER_SIDE2(gBattleAnimTarget) != B_SIDE_PLAYER)
2018-12-21 07:37:59 +01:00
sprite->data[2] = 0x100;
else
sprite->data[2] = -0x10;
sprite->data[7]++;
2021-07-07 15:11:52 +02:00
sprite->x2 = sprite->y2 = 0;
2021-01-23 06:40:46 +01:00
InitAnimLinearTranslationWithSpeed(sprite);
2018-12-21 07:37:59 +01:00
}
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;
}
}
void AnimTask_Hail(u8 taskId)
2018-12-21 07:37:59 +01:00
{
struct Task *task = &gTasks[taskId];
task->func = AnimTask_Hail2;
}
2020-02-20 22:22:33 +01:00
static void AnimTask_Hail2(u8 taskId)
2018-12-21 07:37:59 +01:00
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
2019-02-01 12:26:40 +01:00
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)
2018-12-21 07:37:59 +01:00
{
2019-02-01 12:26:40 +01:00
if (++task->data[3] == 10)
task->data[0]++;
2018-12-21 07:37:59 +01:00
else
2019-02-01 12:26:40 +01:00
task->data[0]--;
2018-12-21 07:37:59 +01:00
}
else
{
2019-02-01 12:26:40 +01:00
task->data[5] = 1;
2018-12-21 07:37:59 +01:00
}
2019-02-01 12:26:40 +01:00
}
else
{
task->data[5]--;
}
break;
case 2:
if (task->data[1] == 0)
DestroyAnimVisualTask(taskId);
break;
2018-12-21 07:37:59 +01:00
}
}
2020-02-20 22:22:33 +01:00
static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId, u8 c)
2018-12-21 07:37:59 +01:00
{
2019-04-11 12:05:56 +02:00
u8 id;
2018-12-21 07:37:59 +01:00
s16 battlerX, battlerY;
s16 spriteX;
2019-04-11 12:05:56 +02:00
bool8 possibleBool = FALSE;
2020-02-21 18:38:20 +01:00
s8 unk = sHailCoordData[hailStructId].unk3;
2019-02-01 12:26:40 +01:00
2018-12-21 07:37:59 +01:00
if (unk != 2)
{
2020-02-21 18:38:20 +01:00
id = GetBattlerAtPosition(sHailCoordData[hailStructId].bPosition);
2019-04-11 12:05:56 +02:00
if (IsBattlerSpriteVisible(id))
2018-12-21 07:37:59 +01:00
{
possibleBool = TRUE;
2019-04-11 12:05:56 +02:00
battlerX = GetBattlerSpriteCoord(id, BATTLER_COORD_X_2);
battlerY = GetBattlerSpriteCoord(id, BATTLER_COORD_Y_PIC_OFFSET);
2018-12-21 07:37:59 +01:00
switch (unk)
{
2019-04-11 12:05:56 +02:00
case 0:
battlerX -= GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_WIDTH) / 6;
battlerY -= GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_HEIGHT) / 6;
break;
case 1:
battlerX += GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_WIDTH) / 6;
battlerY += GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_HEIGHT) / 6;
break;
2018-12-21 07:37:59 +01:00
}
}
2019-04-11 12:05:56 +02:00
else
{
2020-02-21 18:38:20 +01:00
battlerX = (sHailCoordData[hailStructId].x);
battlerY = (sHailCoordData[hailStructId].y);
2019-04-11 12:05:56 +02:00
}
2018-12-21 07:37:59 +01:00
}
else
{
2020-02-21 18:38:20 +01:00
battlerX = (sHailCoordData[hailStructId].x);
battlerY = (sHailCoordData[hailStructId].y);
2018-12-21 07:37:59 +01:00
}
spriteX = battlerX - ((battlerY + 8) / 2);
2020-02-21 18:38:20 +01:00
id = CreateSprite(&gHailParticleSpriteTemplate, spriteX, -8, 18);
2019-04-11 12:05:56 +02:00
if (id == MAX_SPRITES)
{
2018-12-21 07:37:59 +01:00
return FALSE;
2019-04-11 12:05:56 +02:00
}
else
{
StartSpriteAffineAnim(&gSprites[id], affineAnimNum);
gSprites[id].data[0] = possibleBool;
gSprites[id].data[3] = battlerX;
gSprites[id].data[4] = battlerY;
gSprites[id].data[5] = affineAnimNum;
gSprites[id].data[6] = taskId;
gSprites[id].data[7] = c;
return TRUE;
}
2018-12-21 07:37:59 +01:00
}
2020-02-20 22:22:33 +01:00
static void AnimHailBegin(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
u8 spriteId;
2021-07-07 15:11:52 +02:00
sprite->x += 4;
sprite->y += 8;
2018-12-21 07:37:59 +01:00
2021-07-07 15:11:52 +02:00
if (sprite->x < sprite->data[3] && sprite->y < sprite->data[4])
2018-12-21 07:37:59 +01:00
return;
if (sprite->data[0] == 1 && sprite->data[5] == 0)
{
2020-02-14 22:05:43 +01:00
spriteId = CreateSprite(&gIceCrystalHitLargeSpriteTemplate,
2018-12-21 07:37:59 +01:00
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);
}
}
2020-02-20 22:22:33 +01:00
static void AnimHailContinue(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
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)
2020-02-20 22:22:33 +01:00
static void InitIceBallAnim(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
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];
2019-04-11 12:05:56 +02:00
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
2018-12-21 07:37:59 +01:00
sprite->data[5] = gBattleAnimArgs[5];
InitAnimArcTranslation(sprite);
sprite->callback = AnimThrowIceBall;
}
// Throws the ball of ice in Ice Ball.
2020-02-20 22:22:33 +01:00
static void AnimThrowIceBall(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
2019-02-06 20:17:09 +01:00
if (!TranslateAnimHorizontalArc(sprite))
2018-12-21 07:37:59 +01:00
return;
StartSpriteAnim(sprite, 1);
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Initializes the particles that scatter at the end of the Ice Ball animation.
2020-02-20 22:22:33 +01:00
static void InitIceBallParticle(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
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.
2020-02-20 22:22:33 +01:00
static void AnimIceBallParticle(struct Sprite *sprite)
2018-12-21 07:37:59 +01:00
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
if (sprite->data[1] & 1)
2021-07-07 15:11:52 +02:00
sprite->x2 = -(sprite->data[3] >> 8);
2018-12-21 07:37:59 +01:00
else
2021-07-07 15:11:52 +02:00
sprite->x2 = sprite->data[3] >> 8;
2018-12-21 07:37:59 +01:00
2021-07-07 15:11:52 +02:00
sprite->y2 = sprite->data[4] >> 8;
2018-12-21 07:37:59 +01:00
if (++sprite->data[0] == 21)
DestroyAnimSprite(sprite);
}
2020-02-16 23:49:24 +01:00
void AnimTask_GetIceBallCounter(u8 taskId)
2018-12-21 07:37:59 +01:00
{
u8 arg = gBattleAnimArgs[0];
2019-02-01 12:26:40 +01:00
gBattleAnimArgs[arg] = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer - 1;
2018-12-21 07:37:59 +01:00
DestroyAnimVisualTask(taskId);
}