From da3d715f3ba5b4b38b90a67bc73c93aa645ada56 Mon Sep 17 00:00:00 2001 From: Abbie Potter <5558819+Pokabbie@users.noreply.github.com> Date: Tue, 7 May 2024 12:59:52 +0100 Subject: [PATCH] Punchier tera animation (#4507) * Punchier tera animation * Removed testing comments * Replaced VARIOUS_APPLY_TERASTALLIZATION with callnative * Remove redundant arg from applyterastallization --- asm/macros/battle_script.inc | 4 ++ data/battle_anim_scripts.s | 48 ++++++++++++++++ data/battle_scripts_1.s | 10 +++- .../battle_anims/sprites/tera_crystal.png | Bin 0 -> 1011 bytes .../battle_anims/sprites/tera_shatter.png | Bin 0 -> 439 bytes include/battle_terastal.h | 1 + include/constants/battle_anim.h | 4 ++ include/graphics.h | 4 ++ src/battle_anim.c | 1 + src/battle_anim_effects_3.c | 53 ++++++++++++++++++ src/battle_script_commands.c | 12 +++- src/battle_terastal.c | 11 +++- src/data/battle_anim.h | 4 ++ src/graphics.c | 6 ++ 14 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 graphics/battle_anims/sprites/tera_crystal.png create mode 100644 graphics/battle_anims/sprites/tera_shatter.png diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 34f29950bd..5e08c7cdb5 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1641,6 +1641,10 @@ .macro removeweather callnative BS_RemoveWeather .endm + + .macro applyterastallization + callnative BS_ApplyTerastallization + .endm @ various command changed to more readable macros .macro cancelmultiturnmoves battler:req diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index d5d81cf709..23697e38ad 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -1033,6 +1033,8 @@ gBattleAnims_General:: .4byte General_MagicRoom @ B_ANIM_MAGIC_ROOM .4byte General_Tailwind @ B_ANIM_TAILLWIND .4byte General_Fog @ B_ANIM_FOG_CONTINUES + .4byte General_TeraCharge @ B_ANIM_TERA_CHARGE + .4byte General_TeraActivate @ B_ANIM_TERA_ACTIVATE .align 2 gBattleAnims_Special:: @@ -28316,6 +28318,52 @@ MegaEvolutionParticles: delay 3 return +General_TeraCharge: + loadspritegfx ANIM_TAG_TERA_CRYSTAL + loadspritegfx ANIM_TAG_TERA_SHATTER + loadspritegfx ANIM_TAG_FOCUS_ENERGY + loadspritegfx ANIM_TAG_WHIP_HIT @green color + loadspritegfx ANIM_TAG_SWEAT_BEAD @blue color + loadspritegfx ANIM_TAG_PAW_PRINT @yellow color + monbg ANIM_ATTACKER + setalpha 12, 8 + playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER + createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 6, 0, 11, RGB_RED + call RainbowEndureEffect + call RainbowEndureEffect + call RainbowEndureEffect + call RainbowEndureEffect + call RainbowEndureEffect + waitforvisualfinish + playsewithpan SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER + createsprite gTeraCrystalSpriteTemplate, ANIM_ATTACKER, 41, 0, 0, 0, 0 + delay 20 + createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA + waitforvisualfinish + call TeraChargeParticles + playsewithpan SE_M_BRICK_BREAK, SOUND_PAN_ATTACKER + clearmonbg ANIM_ATK_PARTNER + blendoff + end + +TeraChargeParticles: + createsprite gTeraCrystalSpreadSpriteTemplate, ANIM_TARGET, 0, 0, -5, 8 + createsprite gTeraCrystalSpreadSpriteTemplate, ANIM_TARGET, 0, 1, 5, 9 + createsprite gTeraCrystalSpreadSpriteTemplate, ANIM_TARGET, 0, 2, 5, -8 + createsprite gTeraCrystalSpreadSpriteTemplate, ANIM_TARGET, 0, 2, -5, -8 + createsprite gTeraCrystalSpreadSpriteTemplate, ANIM_TARGET, 0, 1, -10, 0 + createsprite gTeraCrystalSpreadSpriteTemplate, ANIM_TARGET, 0, 0, 10, 0 + return + +General_TeraActivate: + createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA + createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14 + waitforvisualfinish + createvisualtask SoundTask_PlayNormalCry, 0 + clearmonbg ANIM_ATK_PARTNER + blendoff + end + General_RestoreBg: restorebg waitbgfadein diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 5dd00b2b6a..26beaf139a 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -22,10 +22,14 @@ BattleScript_Terastallization:: @ TODO: no string prints in S/V, but right now this helps with clarity - printstring STRINGID_PKMNTERASTALLIZEDINTO - @ TODO: replace this animation - playanimation BS_ATTACKER, B_ANIM_TOTEM_FLARE + printstring STRINGID_PKMNSTORINGENERGY + playanimation BS_ATTACKER, B_ANIM_TERA_CHARGE waitanimation + applyterastallization + playanimation BS_ATTACKER, B_ANIM_TERA_ACTIVATE + waitanimation + printstring STRINGID_PKMNTERASTALLIZEDINTO + waitmessage B_WAIT_TIME_LONG end3 BattleScript_LowerAtkSpAtk:: diff --git a/graphics/battle_anims/sprites/tera_crystal.png b/graphics/battle_anims/sprites/tera_crystal.png new file mode 100644 index 0000000000000000000000000000000000000000..e1c406a744a3659cd6ae11e23878a90b2bdfc73f GIT binary patch literal 1011 zcmVb0000000000004KqDyaYf00Cl4M@0Xn2lB-L00S3E zL_t(|oW+$*YU3~z$9({uLKKmvJ%%tC<`l*VyUr=R2x^m65uzHhF0GT58A4KJ5lRV7 z>O;+YlE2!LE@$2<_WSAoKIH_#zcy0W^^fj1&iVel|Hva_%&)V+8#id`ti(|{z%0&& zP%gyz7(^Kb1fQG-GNTNSF^4aCK=ts37(6dx_)Qj{2qKJF1oi$1fEMv-6&%!J*sz1* z-0V*)4~TL_bd;I87deEPjwYw_IYeMwmd7v>qA!0Kac}`a;!+uryRD#9B&Gw7 zQZy0(Tw>SmDdY_8ZyQm+r&C7&@F(+r(1^Nekg{A(0g08#pIbkr$q*>*W;&HylSi0< zGsZgLR3c$F)NXBiJ{H&gN}QZu!s}&aZH4j0c-2k<_U*kW7z9_CUYY|vAKt_AJTUyxLD7)zaSf{vkODP|hP^RKW^gxn?&N~9PoIQ@8u+uPz z-%SpO&?Ir=mh$eAmeSo|u65l4M$5)#C8J|`YZ?)Eo$xN0hsOW%Brp?y$rTR`T+>4j z%nB+QrD;bPJs&E}Dmt37m@?@J+?e@5VS{xRxOngYX($bAgdq@yP^O zu~81#y}CwK2%v<#)eYbzUY zMqdQBJM=)s1t=8&tN}>pZ3?fE(pZD790;-C4v2Kp7YTDq<;+?U`?-JEI_=Lx2>jq6 z!2IUzNFCIJ?`S|S5SUooZ05k#RsjIp*R}N#z5@(Oy2hz|%rL@NKR9A`?T!&ZHs1t- hV2~2|@sIQW*k9iVUkceG)`I{5002ovPDHLkV1fdjrxgGI literal 0 HcmV?d00001 diff --git a/graphics/battle_anims/sprites/tera_shatter.png b/graphics/battle_anims/sprites/tera_shatter.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f698b9d47562a8ba48b278e1417219025dba34 GIT binary patch literal 439 zcmeAS@N?(olHy`uVBq!ia0vp^0zhoQ!VDx|6+TY^QtTz3zOL*qSlM`GgpS3Kw8%z%ONJz6V)Y{n#ScNc~ZR#^`q=eDPdV@SoE(g}`SM-+HmZ5x)KICNFUnQ5=v zM27{-HI-Owe8O9s+GnXmrJ3IR@$=%p>+*;4k4a3QyHT(-c;geF_Ad5LqgADgJEmwK z>C#!^r^BlGexKINNnH`03~&B!o?Gxk{Iy+c)V@IPOCk>~!|L`Nnje|qb?sM8u(5Tb z^Q6PV5lgH$ccn=jjo5wH)LZ}VY?U}Bq1Ra*3>L>Hv`QV@8K3{kCe9{Kr2MGeodcUT z{x4kGbk~Sgy8Eh9XJ6zbcHu7;zl=M+_K|UPesw-(-SCs?j%}{( T#IJYiK>qi1^>bP0l+XkK1v9C) literal 0 HcmV?d00001 diff --git a/include/battle_terastal.h b/include/battle_terastal.h index 078bf39079..c5428b6418 100644 --- a/include/battle_terastal.h +++ b/include/battle_terastal.h @@ -2,6 +2,7 @@ #define GUARD_BATTLE_TERASTAL_H void PrepareBattlerForTera(u32 battler); +void ApplyBattlerVisualsForTeraAnim(u32 battler); bool32 CanTerastallize(u32 battler); u32 GetBattlerTeraType(u32 battler); bool32 IsTerastallized(u32 battler); diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 162eb11c99..bde2458508 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -405,6 +405,8 @@ #define ANIM_TAG_SYRUP_SHELL_YELLOW (ANIM_SPRITES_START + 391) #define ANIM_TAG_SYRUP_SPLAT_RED (ANIM_SPRITES_START + 392) #define ANIM_TAG_SYRUP_SPLAT_YELLOW (ANIM_SPRITES_START + 393) +#define ANIM_TAG_TERA_CRYSTAL (ANIM_SPRITES_START + 394) +#define ANIM_TAG_TERA_SHATTER (ANIM_SPRITES_START + 395) // battlers #define ANIM_ATTACKER 0 @@ -568,6 +570,8 @@ #define B_ANIM_MAGIC_ROOM 47 #define B_ANIM_TAILWIND 48 #define B_ANIM_FOG_CONTINUES 49 +#define B_ANIM_TERA_CHARGE 50 +#define B_ANIM_TERA_ACTIVATE 51 // special animations table (gBattleAnims_Special) #define B_ANIM_LVL_UP 0 diff --git a/include/graphics.h b/include/graphics.h index e7e884e194..e8054d08f6 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -2698,6 +2698,10 @@ extern const u32 gBattleAnimSpriteGfx_Punishment[]; extern const u32 gBattleAnimSpritePal_Punishment[]; extern const u32 gBattleAnimSpriteGfx_QuickGuard[]; extern const u32 gBattleAnimSpritePal_QuickGuard[]; +extern const u32 gBattleAnimSpriteGfx_TeraCrystal[]; +extern const u32 gBattleAnimSpritePal_TeraCrystal[]; +extern const u32 gBattleAnimSpriteGfx_TeraShatter[]; +extern const u32 gBattleAnimSpritePal_TeraShatter[]; // New Battle Anim Particles extern const u32 gBattleAnimSpriteGfx_AlphaStone[]; diff --git a/src/battle_anim.c b/src/battle_anim.c index af1a5a262a..deb56db036 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -283,6 +283,7 @@ void LaunchBattleAnimation(u32 animType, u32 animId) case B_ANIM_RAINBOW: case B_ANIM_SEA_OF_FIRE: case B_ANIM_SWAMP: + case B_ANIM_TERA_CHARGE: sAnimHideHpBoxes = TRUE; break; default: diff --git a/src/battle_anim_effects_3.c b/src/battle_anim_effects_3.c index 5dd91b7f49..ed2e7457f6 100644 --- a/src/battle_anim_effects_3.c +++ b/src/battle_anim_effects_3.c @@ -112,6 +112,8 @@ static void AnimTask_OdorSleuthMovementWaitFinish(u8); static void MoveOdorSleuthClone(struct Sprite *); static void AnimTask_TeeterDanceMovement_Step(u8); static void AnimTask_SlackOffSquish_Step(u8); +static void AnimTask_TeraCrystalShatter(struct Sprite *); +static void AnimTask_TeraCrystalShatter_Step(struct Sprite *); const union AnimCmd gScratchAnimCmds[] = { @@ -1257,6 +1259,57 @@ const struct SpriteTemplate gOmegaSymbolSpriteTemplate = .callback = AnimGhostStatusSprite, }; +const struct SpriteTemplate gTeraCrystalSpriteTemplate = +{ + .tileTag = ANIM_TAG_TERA_CRYSTAL, + .paletteTag = ANIM_TAG_TERA_CRYSTAL, + .oam = &gOamData_AffineDouble_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gAffineAnims_LusterPurgeCircle, + .callback = AnimSpriteOnMonPos, +}; + +const struct SpriteTemplate gTeraCrystalSpreadSpriteTemplate = +{ + .tileTag = ANIM_TAG_TERA_SHATTER, + .paletteTag = ANIM_TAG_TERA_SHATTER, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimTask_TeraCrystalShatter, +}; + +// Task data for AnimTask_TeraCrystalShatter +#define tCounter data[0] +#define tDX data[6] +#define tDY data[7] + +static void AnimTask_TeraCrystalShatter(struct Sprite *sprite) +{ + sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y); + sprite->oam.tileNum += gBattleAnimArgs[0] * 4; + + sprite->tCounter = 0; + sprite->tDX = gBattleAnimArgs[1]; + sprite->tDY = gBattleAnimArgs[2]; + + sprite->callback = AnimTask_TeraCrystalShatter_Step; +} + +static void AnimTask_TeraCrystalShatter_Step(struct Sprite *sprite) +{ + sprite->x += sprite->tDX; + sprite->y += sprite->tDY; + + if (++sprite->tCounter > 15) + DestroyAnimSprite(sprite); +} + +#undef tCounter + void AnimBlackSmoke(struct Sprite *sprite) { sprite->x += gBattleAnimArgs[0]; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index f8ea34e912..7d59b8913c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5159,7 +5159,9 @@ static void PlayAnimation(u32 battler, u8 animId, const u16 *argPtr, const u8 *n || animId == B_ANIM_FORM_CHANGE || animId == B_ANIM_SUBSTITUTE_FADE || animId == B_ANIM_PRIMAL_REVERSION - || animId == B_ANIM_ULTRA_BURST) + || animId == B_ANIM_ULTRA_BURST + || animId == B_ANIM_TERA_CHARGE + || animId == B_ANIM_TERA_ACTIVATE) { BtlController_EmitBattleAnimation(battler, BUFFER_A, animId, &gDisableStructs[battler], *argPtr); MarkBattlerForControllerExec(battler); @@ -16955,3 +16957,11 @@ void BS_RemoveWeather(void) RemoveAllWeather(); gBattlescriptCurrInstr = cmd->nextInstr; } + +void BS_ApplyTerastallization(void) +{ + NATIVE_ARGS(); + ApplyBattlerVisualsForTeraAnim(gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; +} + diff --git a/src/battle_terastal.c b/src/battle_terastal.c index ad83779682..62d83efd5a 100644 --- a/src/battle_terastal.c +++ b/src/battle_terastal.c @@ -18,7 +18,6 @@ void PrepareBattlerForTera(u32 battler) { u32 side = GetBattlerSide(battler); - struct Pokemon *party = GetBattlerParty(battler); u32 index = gBattlerPartyIndexes[battler]; // Update TeraData fields. @@ -33,11 +32,21 @@ void PrepareBattlerForTera(u32 battler) { FlagClear(B_FLAG_TERA_ORB_CHARGED); } +} + +// Applies palette blend and enables UI indicator after animation has played +void ApplyBattlerVisualsForTeraAnim(u32 battler) +{ + struct Pokemon *party = GetBattlerParty(battler); + u32 index = gBattlerPartyIndexes[battler]; // Show indicator and do palette blend. UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &party[index], HEALTHBOX_ALL); BlendPalette(OBJ_PLTT_ID(battler), 16, 8, GetTeraTypeRGB(GetBattlerTeraType(battler))); CpuCopy32(gPlttBufferFaded + OBJ_PLTT_ID(battler), gPlttBufferUnfaded + OBJ_PLTT_ID(battler), PLTT_SIZEOF(16)); + + // We apply the animation behind a white screen, so restore the blended color here to avoid a pop + BlendPalette(OBJ_PLTT_ID(battler), 16, 16, RGB_WHITEALPHA); } // Returns whether a battler can Terastallize. diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h index 77b61584ca..6b29a7c9ef 100644 --- a/src/data/battle_anim.h +++ b/src/data/battle_anim.h @@ -1454,6 +1454,8 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] = {gBattleAnimSpriteGfx_SyrupShell, 0x2000, ANIM_TAG_SYRUP_SHELL_YELLOW}, {gBattleAnimSpriteGfx_SyrupSplat, 0x400, ANIM_TAG_SYRUP_SPLAT_RED}, {gBattleAnimSpriteGfx_SyrupSplat, 0x400, ANIM_TAG_SYRUP_SPLAT_YELLOW}, + {gBattleAnimSpriteGfx_TeraCrystal, 0x800, ANIM_TAG_TERA_CRYSTAL}, + {gBattleAnimSpriteGfx_TeraShatter, 0x0180, ANIM_TAG_TERA_SHATTER}, }; const struct CompressedSpritePalette gBattleAnimPaletteTable[] = @@ -1909,6 +1911,8 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] = {gBattleAnimSpritePal_SyrupYellow, ANIM_TAG_SYRUP_SHELL_YELLOW}, {gBattleAnimSpritePal_SyrupRed, ANIM_TAG_SYRUP_SPLAT_RED}, {gBattleAnimSpritePal_SyrupYellow, ANIM_TAG_SYRUP_SPLAT_YELLOW}, + {gBattleAnimSpritePal_TeraCrystal, ANIM_TAG_TERA_CRYSTAL}, + {gBattleAnimSpritePal_TeraShatter, ANIM_TAG_TERA_SHATTER}, }; const struct BattleAnimBackground gBattleAnimBackgroundTable[] = diff --git a/src/graphics.c b/src/graphics.c index c00bb2c767..4f10e0f965 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -57,6 +57,12 @@ const u32 gBattleAnimSpritePal_QuickGuard[] = INCBIN_U32("graphics/battle_anims/ const u32 gBattleAnimSpriteGfx_AlphaStone[] = INCBIN_U32("graphics/battle_anims/sprites/alpha_stone.4bpp.lz"); const u32 gBattleAnimSpritePal_AlphaStone[] = INCBIN_U32("graphics/battle_anims/sprites/alpha_stone.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_TeraCrystal[] = INCBIN_U32("graphics/battle_anims/sprites/tera_crystal.4bpp.lz"); +const u32 gBattleAnimSpritePal_TeraCrystal[] = INCBIN_U32("graphics/battle_anims/sprites/tera_crystal.gbapal.lz"); + +const u32 gBattleAnimSpriteGfx_TeraShatter[] = INCBIN_U32("graphics/battle_anims/sprites/tera_shatter.4bpp.lz"); +const u32 gBattleAnimSpritePal_TeraShatter[] = INCBIN_U32("graphics/battle_anims/sprites/tera_shatter.gbapal.lz"); + const u32 gBattleAnimSpriteGfx_Anchor[] = INCBIN_U32("graphics/battle_anims/sprites/anchor.4bpp.lz"); const u32 gBattleAnimSpriteGfx_Apple[] = INCBIN_U32("graphics/battle_anims/sprites/apple.4bpp.lz");