New and polished battle animations (#7074)

This commit is contained in:
Linathan 2025-07-11 13:14:19 -04:00 committed by GitHub
parent 7d5a949b71
commit 9228826ae1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 2904 additions and 249 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

View File

@ -93,6 +93,7 @@ void AnimWeatherBallUp(struct Sprite *sprite);
void AnimWeatherBallDown(struct Sprite *sprite);
void AnimSpinningSparkle(struct Sprite *sprite);
void SetAverageBattlerPositions(u8 battler, bool8 respectMonPicOffsets, s16 *x, s16 *y);
void SetToPartnerPositions(u8 battler, bool8 respectMonPicOffsets, s16 *x, s16 *y);
void DestroySpriteAndMatrix(struct Sprite *sprite);
void TranslateSpriteLinearFixedPoint(struct Sprite *sprite);
void InitSpritePosToAnimAttacker(struct Sprite *sprite, bool8 respectMonPicOffsets);
@ -230,6 +231,8 @@ void AnimMudSportDirt(struct Sprite *sprite);
void AnimDirtScatter(struct Sprite *sprite);
void AnimMudSportDirtRising(struct Sprite *sprite);
void AnimDirtPlumeParticle(struct Sprite *);
void AnimBoneHitProjectile(struct Sprite *sprite);
extern const union AnimCmd *const sAnims_MudSlapMud[];
extern const union AffineAnimCmd *const gAffineAnims_SpinningBone[];
// battle_anim_throw.c
@ -268,6 +271,7 @@ void AnimTranslateLinearSingleSineWave(struct Sprite *sprite);
void AnimTeraStarstormStars(struct Sprite *sprite);
void AnimGrantingStars(struct Sprite *sprite);
void AnimFollowMeFinger(struct Sprite *sprite);
void AnimPoisonJabProjectile(struct Sprite *sprite);
extern const union AnimCmd *const gRazorLeafParticleAnimTable[];
extern const union AnimCmd *const gPowerAbsorptionOrbAnimTable[];
extern const union AffineAnimCmd *const gPowerAbsorptionOrbAffineAnimTable[];
@ -466,6 +470,7 @@ void AnimElectricity(struct Sprite *);
void AnimTask_VoltSwitch(struct Sprite* sprite);
extern const union AffineAnimCmd *const gAffineAnims_GrowingElectricOrb[];
extern const union AffineAnimCmd *const gAffineAnims_FlashingSpark[];
extern const union AnimCmd *const sAnims_CirclingElectricShock[];
extern const union AnimCmd *const gAnims_ThunderboltOrb[];
extern const union AnimCmd *const gAnims_ElectricPuff[];
extern const union AnimCmd *const gAnims_ElectricChargingParticles[];
@ -490,6 +495,8 @@ extern const union AnimCmd *const gAnims_FlyingRock[];
extern const union AffineAnimCmd *const gAffineAnims_Whirlpool[];
extern const union AffineAnimCmd *const gAffineAnims_BasicRock[];
extern const union AnimCmd *const gAnims_FlyingRock[];
extern const union AnimCmd *const sAnims_BasicRock[];
void AnimRockTomb(struct Sprite *sprite);
void AnimParticleInVortex(struct Sprite *sprite);
void AnimFallingRock(struct Sprite *sprite);
void AnimRaiseSprite(struct Sprite *sprite);
@ -557,6 +564,9 @@ void InitSpritePosToAnimTargetsCentre(struct Sprite *sprite, bool32 respectMonPi
extern const union AffineAnimCmd *const gSpriteAffineAnimTable_PrimalSymbol[];
extern const union AffineAnimCmd *const gSpriteAffineAnimTable_MegaSymbol[];
// battle_anim_ice.c
void AnimIceBeamParticle(struct Sprite *sprite);
// battle_anim_bug.c
void AnimTranslateStinger(struct Sprite *sprite);

View File

@ -419,6 +419,10 @@
#define ANIM_TAG_PINKVIO_ORB (ANIM_SPRITES_START + 405)
#define ANIM_TAG_STARSTORM (ANIM_SPRITES_START + 406)
#define ANIM_TAG_SALT_PARTICLE (ANIM_SPRITES_START + 407)
#define ANIM_TAG_TERA_SYMBOL (ANIM_SPRITES_START + 408)
#define ANIM_TAG_TATSUGIRI_CURLY (ANIM_SPRITES_START + 409)
#define ANIM_TAG_TATSUGIRI_DROOPY (ANIM_SPRITES_START + 410)
#define ANIM_TAG_TATSUGIRI_STRETCHY (ANIM_SPRITES_START + 411)
// battlers
#define ANIM_ATTACKER 0
@ -657,6 +661,12 @@
#define ANIM_SURF_PAL_MUDDY_WATER 1
#define ANIM_SURF_PAL_SLUDGE_WAVE 2
// Order Up palettes for Commander
#define ANIM_ORDER_UP_NONE 0
#define ANIM_ORDER_UP_CURLY 1
#define ANIM_ORDER_UP_DROOPY 2
#define ANIM_ORDER_UP_STRETCHY 3
// Flags given to various functions to indicate which palettes to consider.
// Handled by UnpackSelectedBattlePalettes
#define F_PAL_BG (1 << 0)

View File

@ -2700,6 +2700,8 @@ extern const u32 gBattleAnimSpriteGfx_MegaParticles[];
extern const u16 gBattleAnimSpritePal_MegaParticles[];
extern const u32 gBattleAnimSpriteGfx_MegaSymbol[];
extern const u16 gBattleAnimSpritePal_MegaSymbol[];
extern const u32 gBattleAnimSpriteGfx_TeraSymbol[];
extern const u16 gBattleAnimSpritePal_TeraSymbol[];
extern const u32 gBattleAnimSpriteGfx_FlashCannonBall[];
extern const u16 gBattleAnimSpritePal_FlashCannonBall[];
extern const u32 gBattleAnimSpriteGfx_WaterGun[];
@ -2712,6 +2714,12 @@ extern const u32 gBattleAnimSpriteGfx_TeraCrystal[];
extern const u16 gBattleAnimSpritePal_TeraCrystal[];
extern const u32 gBattleAnimSpriteGfx_TeraShatter[];
extern const u16 gBattleAnimSpritePal_TeraShatter[];
extern const u32 gBattleAnimSpriteGfx_TatsugiriCurly[];
extern const u16 gBattleAnimSpritePal_TatsugiriCurly[];
extern const u32 gBattleAnimSpriteGfx_TatsugiriDroopy[];
extern const u16 gBattleAnimSpritePal_TatsugiriDroopy[];
extern const u32 gBattleAnimSpriteGfx_TatsugiriStretchy[];
extern const u16 gBattleAnimSpritePal_TatsugiriStretchy[];
// New Battle Anim Particles
extern const u32 gBattleAnimSpriteGfx_AlphaStone[];

View File

@ -257,6 +257,21 @@ const struct SpriteTemplate gPunishmentImpactSpriteTemplate =
.callback = AnimPunishment,
};
// See AnimShadowBall in battle_anim_ghost.c for more specifics
// arg 0: duration step 1 (attacker -> center)
// arg 1: duration step 2 (spin center)
// arg 2: duration step 3 (center -> target)
const struct SpriteTemplate gDarkPulseSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_RING,
.paletteTag = ANIM_TAG_PURPLE_RING,
.oam = &gOamData_AffineDouble_ObjNormal_16x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_SpinningBone,
.callback = AnimShadowBall,
};
// arg 0: x pixel offset
// arg 1: y pixel offset
// arg 2: Something

View File

@ -154,7 +154,6 @@ static void AnimDoubleTeam(struct Sprite *);
static void AnimNightSlash(struct Sprite *);
static void AnimRockPolishStreak(struct Sprite *);
static void AnimRockPolishSparkle(struct Sprite *);
static void AnimPoisonJabProjectile(struct Sprite *);
static void AnimNightSlash(struct Sprite *);
static void AnimPluck(struct Sprite *);
static void AnimAcrobaticsSlashes(struct Sprite *);
@ -5190,7 +5189,7 @@ void AnimNeedleArmSpike(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
if (IsDoubleBattle())
if (gMovesInfo[gAnimMoveIndex].target == MOVE_TARGET_BOTH)
{
SetAverageBattlerPositions(gBattleAnimAttacker, TRUE, &a, &b);
}
@ -5202,7 +5201,7 @@ void AnimNeedleArmSpike(struct Sprite *sprite)
}
else
{
if (IsDoubleBattle())
if (gMovesInfo[gAnimMoveIndex].target == MOVE_TARGET_BOTH)
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &a, &b);
}
@ -7450,7 +7449,7 @@ static void AnimRockPolishSparkle(struct Sprite *sprite)
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration
static void AnimPoisonJabProjectile(struct Sprite *sprite)
void AnimPoisonJabProjectile(struct Sprite *sprite)
{
s16 targetXPos;
s16 targetYPos;

View File

@ -1325,6 +1325,41 @@ const struct SpriteTemplate gTeraCrystalSpreadSpriteTemplate =
.callback = AnimTask_TeraCrystalShatter,
};
// See AnimSpriteOnMonPos in battle_anim_mons.c for more specifics
// Reuses the Mega Symbol affine animation seen in Mega Evolution
// gBattleAnimArgs 0-3 used
// 0, 1 used for position
// 2, 3 as some control variables
const struct SpriteTemplate gTeraSymbolSpriteTemplate =
{
.tileTag = ANIM_TAG_TERA_SYMBOL,
.paletteTag = ANIM_TAG_TERA_SYMBOL,
.oam = &gOamData_AffineDouble_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSpriteAffineAnimTable_MegaSymbol,
.callback = AnimSpriteOnMonPos,
};
// Swirls particle in vortex. Used for moves like Fire Spin or Sand Tomb
// args[0] - initial x offset
// args[1] - initial y offset
// args[2] - y increment
// args[3] - duration
// args[4] - increments some sin parameter
// args[5] - fixed sin parameter
// args[6] - attacker or target
const struct SpriteTemplate gTeraSmokeSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_6,
.paletteTag = ANIM_TAG_SPARKLE_6,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimParticleInVortex,
};
const struct SpriteTemplate gPinkPetalVortexTemplate =
{
.tileTag = ANIM_TAG_PINK_PETAL,

View File

@ -10,7 +10,7 @@ static void AnimLightning(struct Sprite *);
static void AnimLightning_Step(struct Sprite *);
static void AnimUnusedSpinningFist(struct Sprite *);
static void AnimUnusedSpinningFist_Step(struct Sprite *);
static void AnimUnusedCirclingShock(struct Sprite *);
static void AnimCirclingElectricShock(struct Sprite *);
static void AnimZapCannonSpark_Step(struct Sprite *);
static void AnimThunderboltOrb(struct Sprite *);
static void AnimThunderboltOrb_Step(struct Sprite *);
@ -83,7 +83,9 @@ static const struct SpriteTemplate sUnusedSpinningFistSpriteTemplate =
.callback = AnimUnusedSpinningFist,
};
static const union AnimCmd sAnim_UnusedCirclingShock[] =
// Previously an unused function named sAnim_CirclingElectricShock
// Now used for Tera Blast Electric
static const union AnimCmd sAnim_CirclingElectricShock[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
@ -94,21 +96,24 @@ static const union AnimCmd sAnim_UnusedCirclingShock[] =
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_UnusedCirclingShock[] =
// Previously an unused function named sAnims_UnusedCirclingShock
// Now used for Tera Blast Electric
const union AnimCmd *const sAnims_CirclingElectricShock[] =
{
sAnim_UnusedCirclingShock,
sAnim_CirclingElectricShock,
};
// Unused
static const struct SpriteTemplate sUnusedCirclingShockSpriteTemplate =
// Previously named sUnusedCirclingShockSpriteTemplate
// Still unused, but renamed for consistency
static const struct SpriteTemplate sCirclingElectricShockSpriteTemplate =
{
.tileTag = ANIM_TAG_SHOCK,
.paletteTag = ANIM_TAG_SHOCK,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_UnusedCirclingShock,
.anims = sAnims_CirclingElectricShock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedCirclingShock,
.callback = AnimCirclingElectricShock,
};
const struct SpriteTemplate gSparkElectricitySpriteTemplate =
@ -675,7 +680,7 @@ static void AnimUnusedSpinningFist_Step(struct Sprite *sprite)
DestroySpriteAndMatrix(sprite);
}
static void AnimUnusedCirclingShock(struct Sprite *sprite)
static void AnimCirclingElectricShock(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);

View File

@ -1296,6 +1296,12 @@ static void AnimWillOWispFire(struct Sprite *sprite)
sprite->data[3] += 0xC0 * 2;
sprite->data[4] += 0xA0;
if (IsDoubleBattle()
&& !IsContest()
&& IsBattlerAlive(BATTLE_PARTNER(gBattleAnimTarget))
&& GetMoveTarget(gAnimMoveIndex) == MOVE_TARGET_BOTH)
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
sprite->x2 = Sin(sprite->data[1], sprite->data[3] >> 8);
sprite->y2 = Cos(sprite->data[1], sprite->data[4] >> 8);

View File

@ -7,7 +7,6 @@
#include "constants/rgb.h"
static void AnimBonemerangProjectile(struct Sprite *);
static void AnimBoneHitProjectile(struct Sprite *);
static void AnimDirtPlumeParticle_Step(struct Sprite *);
static void AnimDigDirtMound(struct Sprite *);
static void AnimBonemerangProjectile_Step(struct Sprite *);
@ -84,7 +83,7 @@ static const union AnimCmd sAnim_MudSlapMud[] =
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_MudSlapMud[] =
const union AnimCmd *const sAnims_MudSlapMud[] =
{
sAnim_MudSlapMud,
};
@ -199,7 +198,7 @@ static void AnimBonemerangProjectile_End(struct Sprite *sprite)
// arg 2: target x pixel offset
// arg 3: target y pixel offset
// arg 4: duration
static void AnimBoneHitProjectile(struct Sprite *sprite)
void AnimBoneHitProjectile(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
if (!IsOnPlayerSide(gBattleAnimAttacker))

View File

@ -28,7 +28,6 @@ struct HailStruct {
static void AnimUnusedIceCrystalThrow(struct Sprite *);
static void AnimUnusedIceCrystalThrow_Step(struct Sprite *);
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 *);
@ -703,7 +702,7 @@ static void AnimIcePunchSwirlingParticle(struct Sprite *sprite)
// arg 2: target x offset
// arg 3: target y offset
// arg 4: duration
static void AnimIceBeamParticle(struct Sprite *sprite)
void AnimIceBeamParticle(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);

View File

@ -777,6 +777,24 @@ void InitSpritePosToAnimAttackerPartner(struct Sprite *sprite, bool8 respectMonP
sprite->y += gBattleAnimArgs[1];
}
void InitSpritePosToAnimBothTargets(struct Sprite *sprite, bool8 respectMonPicOffsets)
{
if (!respectMonPicOffsets)
{
sprite->x = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X) + GetBattlerSpriteCoord2(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y) + GetBattlerSpriteCoord2(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_Y);
}
else
{
sprite->x = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X_2) + GetBattlerSpriteCoord2(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + GetBattlerSpriteCoord2(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_Y_PIC_OFFSET);
}
sprite->x = sprite->x / 2;
sprite->y = sprite->y / 2;
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
}
bool32 InitSpritePosToAnimBattler(u32 animBattlerId, struct Sprite *sprite, bool8 respectMonPicOffsets)
{
u32 battler = GetAnimBattlerId(animBattlerId);
@ -1445,12 +1463,24 @@ void AnimSpriteOnMonPos(struct Sprite *sprite)
else
respectMonPicOffsets = FALSE;
if (gBattleAnimArgs[2] == 0)
InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets);
else if (gBattleAnimArgs[2] == 1)
InitSpritePosToAnimTarget(sprite, respectMonPicOffsets);
else if (gBattleAnimArgs[2] == 2)
InitSpritePosToAnimAttackerPartner(sprite, respectMonPicOffsets);
switch(gBattleAnimArgs[2])
{
case 0:
InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets);
break;
case 1:
InitSpritePosToAnimTarget(sprite, respectMonPicOffsets);
break;
case 2:
InitSpritePosToAnimAttackerPartner(sprite, respectMonPicOffsets);
break;
case 3:
if(IsDoubleBattle())
InitSpritePosToAnimBothTargets(sprite, respectMonPicOffsets);
else
InitSpritePosToAnimTarget(sprite, respectMonPicOffsets);
break;
}
sprite->data[0]++;
@ -2180,6 +2210,37 @@ void SetAverageBattlerPositions(u8 battler, bool8 respectMonPicOffsets, s16 *x,
*y = (battlerY + partnerY) / 2;
}
void SetToPartnerPositions(u8 battler, bool8 respectMonPicOffsets, s16 *x, s16 *y)
{
u8 xCoordType, yCoordType;
s16 returnX, returnY;
if (!respectMonPicOffsets)
{
xCoordType = BATTLER_COORD_X;
yCoordType = BATTLER_COORD_Y;
}
else
{
xCoordType = BATTLER_COORD_X_2;
yCoordType = BATTLER_COORD_Y_PIC_OFFSET;
}
if (IsDoubleBattle() && !IsContest() && IsBattlerAlive(BATTLE_PARTNER(battler)))
{
returnX = GetBattlerSpriteCoord(BATTLE_PARTNER(battler), xCoordType);
returnY = GetBattlerSpriteCoord(BATTLE_PARTNER(battler), yCoordType);
}
else
{
returnX = GetBattlerSpriteCoord(battler, xCoordType);
returnY = GetBattlerSpriteCoord(battler, yCoordType);
}
*x = returnX;
*y = returnY;
}
u8 CreateInvisibleSpriteCopy(int battler, u8 spriteId, int species)
{
u8 newSpriteId = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy);

View File

@ -4740,7 +4740,7 @@ static const union AffineAnimCmd* const sSpriteAffineAnimTable_Flutterby[] = {
const struct SpriteTemplate gSpriteTemplate_InfernalParadeFlame = {
.tileTag = ANIM_TAG_PURPLE_FLAME,
.paletteTag = ANIM_TAG_PURPLE_FLAME,
.oam = &gOamData_AffineDouble_ObjBlend_32x16,
.oam = &gOamData_AffineDouble_ObjNormal_16x32,
.anims = gAnims_GrudgeFlame,
.images = NULL,
.affineAnims = sSpriteAffineAnimTable_Flutterby,
@ -5695,7 +5695,7 @@ const struct SpriteTemplate gBlackHoleEclipseBlueRingSpriteTemplate =
const struct SpriteTemplate gBlackHoleEclipseBlackRingSpriteTemplate =
{
.tileTag = ANIM_TAG_THIN_RING,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_SHADOW_BALL,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
@ -7312,6 +7312,287 @@ const struct SpriteTemplate gOmegaGeyserSpriteTemplate =
.callback = SpriteCB_Geyser,
};
// Moves objects (ice crystals) in a wave-like behavior. Seen in Max Flutterby
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: wave amplitude
const struct SpriteTemplate gIceShardSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineDouble_ObjBlend_8x8,
.anims = gAnims_IceCrystalSmall,
.images = NULL,
.affineAnims = sSpriteAffineAnimTable_Flutterby,
.callback = SpriteCB_MaxFlutterby
};
const struct SpriteTemplate gSpinningVineSpriteTemplate =
{
.tileTag = ANIM_TAG_PUNISHMENT_BLADES,
.paletteTag = ANIM_TAG_LEAF,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_SpinningBone,
.callback = AnimBoneHitProjectile,
};
const struct SpriteTemplate gMaxFlutterbyButterflySpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_6,
.paletteTag = ANIM_TAG_SPARKLE_6,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sSpriteAffineAnimTable_Flutterby,
.callback = SpriteCB_MaxFlutterby
};
const struct SpriteTemplate gReallyBigRockBlastRockSpriteTemplate =
{
.tileTag = ANIM_TAG_REALLY_BIG_ROCK,
.paletteTag = ANIM_TAG_REALLY_BIG_ROCK,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockBlastRock,
};
const struct SpriteTemplate gOrderUpTatsugiriCurlySpriteTemplate =
{
.tileTag = ANIM_TAG_TATSUGIRI_CURLY,
.paletteTag = ANIM_TAG_TATSUGIRI_CURLY,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_DreepyMissilePlayer,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockTomb,
};
const struct SpriteTemplate gOrderUpTatsugiriDroopySpriteTemplate =
{
.tileTag = ANIM_TAG_TATSUGIRI_DROOPY,
.paletteTag = ANIM_TAG_TATSUGIRI_DROOPY,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_DreepyMissilePlayer,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockTomb,
};
const struct SpriteTemplate gOrderUpTatsugiriStretchySpriteTemplate =
{
.tileTag = ANIM_TAG_TATSUGIRI_STRETCHY,
.paletteTag = ANIM_TAG_TATSUGIRI_STRETCHY,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_DreepyMissilePlayer,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockTomb,
};
// Start of Tera Blast sprite templates
const struct SpriteTemplate gFireSpreadBlastSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_BasicFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimIceBeamParticle,
};
const struct SpriteTemplate gPurpleFlameSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_FLAME,
.paletteTag = ANIM_TAG_PURPLE_FLAME,
.oam = &gOamData_AffineOff_ObjBlend_16x32,
.anims = gAnims_GrudgeFlame,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate gAirWaveSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_AIR_WAVE_2,
.paletteTag = ANIM_TAG_AIR_WAVE_2,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gAffineAnims_AirWaveCrescent,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate gPinkVioletOrbSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_PINKVIO_ORB,
.paletteTag = ANIM_TAG_PINKVIO_ORB,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate gHydroPumpSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_HYDRO_PUMP,
.paletteTag = ANIM_TAG_HYDRO_PUMP,
.oam = &gOamData_AffineOff_ObjBlend_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate sCirclingShockSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_SHOCK,
.paletteTag = ANIM_TAG_SHOCK,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_CirclingElectricShock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate sIceCrystalSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineDouble_ObjBlend_8x16,
.anims = gAnims_IceCrystalLarge,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate sMudSandSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_MUD_SAND,
.paletteTag = ANIM_TAG_MUD_SAND,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_MudSlapMud,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate sPoisonSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_POISON_BUBBLE,
.paletteTag = ANIM_TAG_POISON_BUBBLE,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = &gAnims_PoisonProjectile[0],
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate sRockSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_FlyingRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate sMetalBallSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_METAL_BALL,
.paletteTag = ANIM_TAG_METAL_BALL,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate sPinkHeartSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_PINK_HEART,
.paletteTag = ANIM_TAG_PINK_HEART,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate gDragonDanceOrbSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_HOLLOW_ORB,
.paletteTag = ANIM_TAG_HOLLOW_ORB,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate gYellowStarSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_YELLOW_STAR,
.paletteTag = ANIM_TAG_YELLOW_STAR,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate gTeraBlastFlyingSpriteTemplate =
{
.tileTag = ANIM_TAG_METAL_SOUND_WAVES,
.paletteTag = ANIM_TAG_METAL_SOUND_WAVES,
.oam = &gOamData_AffineDouble_ObjNormal_32x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_SpinningBone,
.callback = AnimShadowBall,
};
const struct SpriteTemplate gTeraBlastWaterSpriteTemplate =
{
.tileTag = ANIM_TAG_HYDRO_PUMP,
.paletteTag = ANIM_TAG_HYDRO_PUMP,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDracoMeteorRock,
};
const struct SpriteTemplate gTeraBlastRockSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_BasicRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDracoMeteorRock,
};
const struct SpriteTemplate gGhostProjectileSpriteTemplate =
{
.tileTag = ANIM_TAG_GHOSTLY_SPIRIT,
.paletteTag = ANIM_TAG_GHOSTLY_SPIRIT,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimPoisonJabProjectile,
};
// End of Tera Blast sprite templates
const union AnimCmd gSproutAnimCmds[] =
{
ANIMCMD_FRAME(96, 5),
@ -9148,6 +9429,18 @@ static void SpriteCB_DragonEnergyShot(struct Sprite* sprite)
//arg 2: wave amplitude
static void SpriteCB_MaxFlutterby(struct Sprite* sprite)
{
s16 target_x;
s16 target_y;
if (gMovesInfo[gAnimMoveIndex].target == MOVE_TARGET_BOTH)
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &target_x, &target_y);
}
else
{
target_x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
target_y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->data[0] = 0x10; //Speed delay
@ -9163,7 +9456,8 @@ static void SpriteCB_MaxFlutterbyStep1(struct Sprite* sprite)
{
if (!FuncIsActiveTask(AnimTask_DynamaxGrowthStep))
{
if (gAnimMoveIndex != MOVE_INFERNAL_PARADE)
if (gAnimMoveIndex != MOVE_INFERNAL_PARADE
&& gAnimMoveIndex != MOVE_ASTRAL_BARRAGE)
PlaySE(SE_M_SAND_ATTACK);
StartSpriteAffineAnim(sprite, 1);
@ -9381,3 +9675,25 @@ const union AffineAnimCmd* const gSpriteAffineAnimTable_MegaSymbol[] =
{
sSpriteAffineAnim_MegaSymbol,
};
// Used for determining which animation to use for Order Up
void AnimTask_GetCommanderType(u8 taskId)
{
switch (gBattleStruct->commanderActive[gEffectBattler])
{
case SPECIES_TATSUGIRI_CURLY:
gBattleAnimArgs[ARG_RET_ID] = ANIM_ORDER_UP_CURLY;
break;
case SPECIES_TATSUGIRI_DROOPY:
gBattleAnimArgs[ARG_RET_ID] = ANIM_ORDER_UP_DROOPY;
break;
case SPECIES_TATSUGIRI_STRETCHY:
gBattleAnimArgs[ARG_RET_ID] = ANIM_ORDER_UP_STRETCHY;
break;
default:
gBattleAnimArgs[ARG_RET_ID] = ANIM_ORDER_UP_NONE;
break;
}
DestroyAnimVisualTask(taskId);
}

View File

@ -520,12 +520,44 @@ static void AnimSludgeProjectile(struct Sprite *sprite)
{
if (!gBattleAnimArgs[3])
StartSpriteAnim(sprite, 2);
if (gBattleAnimArgs[4] && IsDoubleBattle())
{
u32 targetPartner;
if (IsOnPlayerSide(gBattleAnimTarget))
{
if (gBattleAnimTarget == 0)
targetPartner = 2;
else
targetPartner = 0;
}
else
{
if (gBattleAnimTarget == 1)
targetPartner = 3;
else
targetPartner = 1;
}
if (IsBattlerAlive(gBattleAnimTarget) && !IsBattlerAlive(targetPartner))
{
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
sprite->data[2] = GetBattlerSpriteCoord(targetPartner, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(targetPartner, BATTLER_COORD_Y_PIC_OFFSET);
}
}
else
{
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[5] = -30;
InitAnimArcTranslation(sprite);
@ -600,7 +632,12 @@ static void AnimSludgeBombHitParticle_Step(struct Sprite *sprite)
static void AnimAcidPoisonDroplet(struct Sprite *sprite)
{
if (gBattleAnimArgs[5])
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
{
if (gBattleAnimArgs[5] == 1)
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
if (gBattleAnimArgs[5] == 2)
SetToPartnerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
}
if (!IsOnPlayerSide(gBattleAnimAttacker))
gBattleAnimArgs[0] = -gBattleAnimArgs[0];

View File

@ -11,7 +11,6 @@
static void AnimTask_Rollout_Step(u8 taskId);
static void AnimRolloutParticle(struct Sprite *);
static void AnimRockTomb(struct Sprite *);
static void AnimRockTomb_Step(struct Sprite *sprite);
static void AnimRockScatter(struct Sprite *);
static void AnimRockScatter_Step(struct Sprite *sprite);
@ -174,7 +173,7 @@ static const union AnimCmd sAnim_Rock_Smallest[] =
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_BasicRock[] =
const union AnimCmd *const sAnims_BasicRock[] =
{
sAnim_Rock_Biggest,
sAnim_Rock_Bigger,
@ -935,7 +934,7 @@ static u8 GetRolloutCounter(void)
return retVal;
}
static void AnimRockTomb(struct Sprite *sprite)
void AnimRockTomb(struct Sprite *sprite)
{
StartSpriteAnim(sprite, gBattleAnimArgs[4]);

View File

@ -1468,6 +1468,10 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] =
{gBattleAnimSpriteGfx_PinkVioletOrb, 0x0080, ANIM_TAG_PINKVIO_ORB},
{gBattleAnimSpriteGfx_TeraStarstormBeam, 0x200, ANIM_TAG_STARSTORM},
{gBattleAnimSpriteGfx_SaltParticle, 0x400, ANIM_TAG_SALT_PARTICLE},
{gBattleAnimSpriteGfx_TeraSymbol, 0x0200, ANIM_TAG_TERA_SYMBOL},
{gBattleAnimSpriteGfx_TatsugiriCurly, 0x200, ANIM_TAG_TATSUGIRI_CURLY},
{gBattleAnimSpriteGfx_TatsugiriDroopy, 0x200, ANIM_TAG_TATSUGIRI_DROOPY},
{gBattleAnimSpriteGfx_TatsugiriStretchy, 0x200, ANIM_TAG_TATSUGIRI_STRETCHY},
};
const struct SpritePalette gBattleAnimPaletteTable[] =
@ -1937,6 +1941,10 @@ const struct SpritePalette gBattleAnimPaletteTable[] =
{gBattleAnimSpritePal_PinkVioletOrb, ANIM_TAG_PINKVIO_ORB},
{gBattleAnimSpritePal_TeraStarstormBeam, ANIM_TAG_STARSTORM},
{gBattleAnimSpritePal_SaltParticle, ANIM_TAG_SALT_PARTICLE},
{gBattleAnimSpritePal_TeraSymbol, ANIM_TAG_TERA_SYMBOL},
{gBattleAnimSpritePal_TatsugiriCurly, ANIM_TAG_TATSUGIRI_CURLY},
{gBattleAnimSpritePal_TatsugiriDroopy, ANIM_TAG_TATSUGIRI_DROOPY},
{gBattleAnimSpritePal_TatsugiriStretchy, ANIM_TAG_TATSUGIRI_STRETCHY},
};
const struct BattleAnimBackground gBattleAnimBackgroundTable[] =

View File

@ -43,6 +43,9 @@ const u16 gBattleAnimSpritePal_AlphaSymbol[] = INCBIN_U16("graphics/battle_anims
const u32 gBattleAnimSpriteGfx_OmegaSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/omega_symbol.4bpp.smol");
const u16 gBattleAnimSpritePal_OmegaSymbol[] = INCBIN_U16("graphics/battle_anims/sprites/omega_symbol.gbapal");
const u32 gBattleAnimSpriteGfx_TeraSymbol[] = INCBIN_U32("graphics/battle_anims/sprites/tera_symbol.4bpp.smol");
const u16 gBattleAnimSpritePal_TeraSymbol[] = INCBIN_U16("graphics/battle_anims/sprites/tera_symbol.gbapal");
const u32 gBattleAnimSpriteGfx_FlashCannonBall[] = INCBIN_U32("graphics/battle_anims/sprites/flash_cannon_ball.4bpp.smol");
const u16 gBattleAnimSpritePal_FlashCannonBall[] = INCBIN_U16("graphics/battle_anims/sprites/flash_cannon_ball.gbapal");
@ -782,6 +785,15 @@ const u16 gBattleAnimSpritePal_BlueFlames[] = INCBIN_U16("graphics/battle_anims/
const u32 gBattleAnimSpriteGfx_BlueFlames2[] = INCBIN_U32("graphics/battle_anims/sprites/blue_flames_2.4bpp.smol");
const u32 gBattleAnimSpriteGfx_TatsugiriCurly[] = INCBIN_U32("graphics/battle_anims/sprites/tatsugiri_curly.4bpp.smol");
const u16 gBattleAnimSpritePal_TatsugiriCurly[] = INCBIN_U16("graphics/battle_anims/sprites/tatsugiri_curly.gbapal");
const u32 gBattleAnimSpriteGfx_TatsugiriDroopy[] = INCBIN_U32("graphics/battle_anims/sprites/tatsugiri_droopy.4bpp.smol");
const u16 gBattleAnimSpritePal_TatsugiriDroopy[] = INCBIN_U16("graphics/battle_anims/sprites/tatsugiri_droopy.gbapal");
const u32 gBattleAnimSpriteGfx_TatsugiriStretchy[] = INCBIN_U32("graphics/battle_anims/sprites/tatsugiri_stretchy.4bpp.smol");
const u16 gBattleAnimSpritePal_TatsugiriStretchy[] = INCBIN_U16("graphics/battle_anims/sprites/tatsugiri_stretchy.gbapal");
// Contest
const u32 gJPContestGfx1[] = INCBIN_U32("graphics/contest/japanese/composite_1.4bpp.smol");
const u16 gJPContestPal[] = INCBIN_U16("graphics/contest/japanese/palette.gbapal");

View File

@ -1550,4 +1550,261 @@ DOUBLE_BATTLE_TEST("Z-Moves don't leak when used - Doubles (opponentRight to pla
// Max Moves
// Tera Blast and all type variants
#define TERA_BLAST_PARAMETERS PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_NORMAL; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_FIGHTING; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_FLYING; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_POISON; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_GROUND; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_ROCK; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_BUG; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_GHOST; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_STEEL; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_WATER; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_FIRE; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_GRASS; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_ELECTRIC; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_PSYCHIC; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_ICE; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_DRAGON; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_DARK; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_FAIRY; } \
PARAMETRIZE { species = SPECIES_WOBBUFFET; move = MOVE_TERA_BLAST; type = TYPE_STELLAR; }
SINGLE_BATTLE_TEST("Tera Blast doesn't leak when used - Singles (player to opponent)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(species) { TeraType(type); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_FOCUS_SASH); }
} WHEN {
TURN { MOVE(player, move, gimmick: GIMMICK_TERA); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, player);
ANIMATION(ANIM_TYPE_MOVE, move, player);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
SINGLE_BATTLE_TEST("Tera Blast doesn't leak when used - Singles (opponent to player)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FOCUS_SASH); }
OPPONENT(species) { TeraType(type); }
} WHEN {
TURN { MOVE(opponent, move, gimmick: GIMMICK_TERA); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, opponent);
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerLeft to opponentLeft)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(species) { TeraType(type); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
} WHEN {
TURN { MOVE(playerLeft, move, gimmick: GIMMICK_TERA, target: opponentLeft); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, playerLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, playerLeft);
ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerLeft to opponentRight)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(species) { TeraType(type); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
} WHEN {
TURN { MOVE(playerLeft, move, gimmick: GIMMICK_TERA, target: opponentRight); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, playerLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, playerLeft);
ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerRight to opponentLeft)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(SPECIES_WYNAUT);
PLAYER(species) { TeraType(type); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
} WHEN {
TURN { MOVE(playerRight, move, gimmick: GIMMICK_TERA, target: opponentLeft); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, playerRight);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, playerRight);
ANIMATION(ANIM_TYPE_MOVE, move, playerRight);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (playerRight to opponentRight)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(SPECIES_WYNAUT);
PLAYER(species) { TeraType(type); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
} WHEN {
TURN { MOVE(playerRight, move, gimmick: GIMMICK_TERA, target: opponentRight); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, playerRight);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, playerRight);
ANIMATION(ANIM_TYPE_MOVE, move, playerRight);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentLeft to playerLeft)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(species) { Item(ITEM_FOCUS_SASH); }
PLAYER(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WOBBUFFET) { TeraType(type); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(opponentLeft, move, gimmick: GIMMICK_TERA, target: playerLeft); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, opponentLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, opponentLeft);
ANIMATION(ANIM_TYPE_MOVE, move, opponentLeft);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentLeft to playerRight)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(species) { Item(ITEM_FOCUS_SASH); }
PLAYER(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WOBBUFFET) { TeraType(type); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(opponentLeft, move, gimmick: GIMMICK_TERA, target: playerRight); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, opponentLeft);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, opponentLeft);
ANIMATION(ANIM_TYPE_MOVE, move, opponentLeft);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentRight to playerLeft)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(species) { Item(ITEM_FOCUS_SASH); }
PLAYER(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT) { TeraType(type); }
} WHEN {
TURN { MOVE(opponentRight, move, gimmick: GIMMICK_TERA, target: playerLeft); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, opponentRight);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, opponentRight);
ANIMATION(ANIM_TYPE_MOVE, move, opponentRight);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
DOUBLE_BATTLE_TEST("Tera Blast doesn't leak when used - Doubles (opponentRight to playerRight)")
{
FORCE_MOVE_ANIM(TRUE);
u32 species, move, type;
TERA_BLAST_PARAMETERS;
GIVEN {
PLAYER(species) { Item(ITEM_FOCUS_SASH); }
PLAYER(SPECIES_WYNAUT) { Item(ITEM_FOCUS_SASH); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT) { TeraType(type); }
} WHEN {
TURN { MOVE(opponentRight, move, gimmick: GIMMICK_TERA, target: playerRight); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_CHARGE, opponentRight);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, opponentRight);
ANIMATION(ANIM_TYPE_MOVE, move, opponentRight);
} THEN {
FORCE_MOVE_ANIM(FALSE);
if (gLoadFail)
DebugPrintf("Move failed: %S (%u)", gMovesInfo[move].name, move);
EXPECT_EQ(gLoadFail, FALSE);
}
}
#endif