From 708f64247f8abbe22d5cc6f44ede30b333dd030c Mon Sep 17 00:00:00 2001 From: SonikkuA-DatH <58025603+SonikkuA-DatH@users.noreply.github.com> Date: Wed, 9 Oct 2024 01:43:04 -0700 Subject: [PATCH] Heart Swap Move Animation (#5460) --- data/battle_anim_scripts.s | 38 +++++++ graphics/battle_anims/sprites/pinkvio_orb.png | Bin 0 -> 5019 bytes include/constants/battle_anim.h | 1 + include/graphics.h | 2 + src/battle_anim_effects_2.c | 12 +++ src/battle_anim_psychic.c | 100 +++++++++++++++++- src/data/battle_anim.h | 2 + src/graphics.c | 3 + 8 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 graphics/battle_anims/sprites/pinkvio_orb.png diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 98ac1bfda76d..c16a5c7859b3 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -934,6 +934,44 @@ gBattleAnimMove_ToxicSpikes:: end gBattleAnimMove_HeartSwap:: + loadspritegfx ANIM_TAG_RED_HEART + loadspritegfx ANIM_TAG_PINKVIO_ORB + loadspritegfx ANIM_TAG_SPARKLE_2 + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 0, 8, RGB(31, 24, 26) + createvisualtask AnimTask_HeartSwap, 3, ANIM_TARGET + createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_TARGET, RGB_WHITE, 12, 3, 1 + loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 10, 8 + delay 16 + createvisualtask AnimTask_HeartSwap, 3, ANIM_ATTACKER + createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB_WHITE, 12, 3, 1 + waitforvisualfinish + createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 2, -15, 0, 0, 0, 32, 60 + createsprite gGrantingStarsSpriteTemplate, ANIM_TARGET, 2, -15, 0, 0, 0, 32, 60 + delay 8 + createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 2, 12, -5, 0, 0, 32, 60 + createsprite gGrantingStarsSpriteTemplate, ANIM_TARGET, 2, 12, -5, 0, 0, 32, 60 + delay 4 + playsewithpan SE_SHINY, SOUND_PAN_ATTACKER + createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB(31, 25, 27), 12, 3, 1 + createvisualtask AnimTask_ScaleMonAndRestore, 5, -3, -3, 16, ANIM_ATTACKER, 0 + createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_TARGET, RGB(31, 25, 27), 12, 3, 1 + createvisualtask AnimTask_ScaleMonAndRestore, 5, -3, -3, 16, ANIM_TARGET, 0 + createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 160, -32 + createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, -256, -40 + createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 128, -16 + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 8, 0, RGB(31, 24, 26) + createsprite gRedHeartCharmSpriteTemplate, ANIM_ATTACKER, 3, 0, 20 + playsewithpan SE_M_MORNING_SUN, SOUND_PAN_ATTACKER + delay 15 + createsprite gRedHeartCharmSpriteTemplate, ANIM_ATTACKER, 3, -20, 20 + playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER + delay 15 + createsprite gRedHeartCharmSpriteTemplate, ANIM_ATTACKER, 3, 20, 20 + playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER + waitforvisualfinish + clearmonbg ANIM_ATTACKER + clearmonbg ANIM_TARGET + blendoff end gBattleAnimMove_AquaRing:: diff --git a/graphics/battle_anims/sprites/pinkvio_orb.png b/graphics/battle_anims/sprites/pinkvio_orb.png new file mode 100644 index 0000000000000000000000000000000000000000..d0d7c927549bb8590999f1f5184bc587c67501f8 GIT binary patch literal 5019 zcmeHKdsGu=7M}nT5=3YL6}BxQNCj(>$@^g4#Fq%fJ8K!iL<0tCCDE7V6p z3a;1|aVcUcsIUcE5mZ_gs@7s36j2aV>{=0p^#O&V(n&zYvpsu`=WPEoCzH(F@7~|N z_jm7ilW)5+e5o7Jmk0oWn_MP|z`i|fmy;v*d8fM<6F81+P_3~o}cf2yQWl->OdH%;RBiHuZ*>t z;?K_c{PGTeikWo9U9#X#|5*=1;dDt^%%`P1H-f=Y<16c`o$1HEO!cp?svcWrIjR*N z>N%BZb&va(VC0n>Z-&kkO5X&0>I3C4@Ex77sio=;ddIzOwo5~A-x0FM5U&00@W#l0 zCw$bODL9CxhZlIBeOy5sJA0&U(`%U{7wXzC^^Rr6fAE>VpeAIX=iqQk>l$h88>+E} zij3ey*ZYih(>s=Jx&gHXZ1EZjdPVw5`?ON!2ers9^**TL#~tkUIc^`d9&ytQicucoFg)eh6THBPf+a~gnQ~-7&E@C6^-qjGkJu%y((jy2bcy$}o3p}4ZO?H_4MrV+F$H<%yQ|2uQ z<(B&G@!4hU4P3M*h@f8E?-6oho;rx1e1ZQJwI{%K}!;4;#`EkKVu8LiJ z)v|f(+bcUhKJeGbpMx&4Vjj>XJLu(3C4}9cP2nHrN8FfyNwf6QFZt}##l(}JUhI93 zR+_LqaAkEw%|=zMxZO8#eYyXxB3cWbte15J*7V3uq1R9&soN09n=IlPt!4P zH(vT8pvUX=Zyqh<5{JXNk5zo%ACFgFF4M0*(4IWKaAgg}6`O=#_h4jJ)co%6w$pZ_HS;v(Sw%jP33)xbCI$Zo!OY( z|9V(s^CjYa8VhqoVmy$;XKY?+Ivy8u!TFG|8Eq zxyCDtm#?^#NYNQqF3ViAQ{kCfJkYn~T5DWX=k;F&cPmrV{Ps47ocYZ&V}Z_cF1mB{ z`}48cqYaXW@@!^H?DV#yKP_|&o7=qFA=W|E@gU&dEL__=ULp9f5K^WO_$aTJ_LarQ z%dgof#<>OG7rN2Ebya8|ZNE=Q_roh;_448RuJ-<;-Wg2|nI(yX1Ecu)za@P4y%?YOFZB9IK;{BEb zSvhspGpaX}MsU5iukOD|4tz`t{(Rfrt4I6>2SfusxFuyLRdtE4D%s~`EwGwXKX3RL z8Ng+2Q%lt4|CG@*SNTl?*RJ=+WXGqMjF}$+RX6!h1gGZg2{a1}BUB;tOvzq;n)2@}3SF;tM!YD=)w6YB*G;%|@3f_ zNqV!uDk9r)1=zh!Oe2%*DwaeMd5uCz5*th?iA7~mL5kF>O=XZ55=lZ6q7g($LMI`x zClNWpVlfJ6w6wG|Y8sPjFvZj8d_JEBGH4721=FCI)Abg}O3|AGY!DL|64VTvv_^~8 zpeNZdA+;gJA|jKqb<&ggbVh~ZDZJi1$pXd)%?cT5bSg;G>1b0e%ob@X1~M7YA6l4I z*iRcR0yP^_OfV`kA1@T&) z(Qbv2{hX#nt9eG&bFtZ0?CDGm1T%k%`<(WZ-0jMkmO>$r7~m9Jcyft|Z1XQb46qgv z*l$^Mh{J^tkiu0%bP5aQuqiwcpS>h{NZjQ=sH}vjx(_s0|7Or)n`Am`-OS zEGC`8=c!Q&i$T{=AeNd*f!S;|lf~Dt8QiH5D@2hLy=X(FgH+}O zvaK)zEFFwm$kwSCfZYPiMj$q!ki}q984O7xvMnf*&C=fBB;iC^WLh((k#6hx$*zw? zlP8`gHbIiszC?UN`aKUC3?dh3SgsUP$?6cm3b!B0f9rpnB{dP#Sia zQKXsoU7;Ssf4sAEYdbMpf>E~C3;?d4whIRo z70data[10] = -10; task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8; @@ -1023,6 +1036,55 @@ void AnimTask_SkillSwap(u8 taskId) task->func = AnimTask_SkillSwap_Step; } +// Copy of Skill Swap's function to get position of the user and target +// arg 0: move target +void AnimTask_HeartSwap(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (IsContest()) + { + if (gBattleAnimArgs[0] == ANIM_TARGET) + { + task->data[10] = -10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8; + } + else + { + task->data[10] = 10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8; + } + } + else + { + if (gBattleAnimArgs[0] == ANIM_TARGET) + { + task->data[10] = -10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8; + } + else + { + task->data[10] = 10; + task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8; + task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8; + task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8; + } + } + + task->data[1] = 6; + task->func = AnimTask_HeartSwap_Step; +} + static void AnimTask_SkillSwap_Step(u8 taskId) { u8 spriteId; @@ -1057,6 +1119,42 @@ static void AnimTask_SkillSwap_Step(u8 taskId) } } +// Copy of Skill Swap's function to vault the series of orbs between the user and target +// CreateSprite modified so it uses the pink orbs instead of the blue/green ones +static void AnimTask_HeartSwap_Step(u8 taskId) +{ + u8 spriteId; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 6) + { + task->data[1] = 0; + spriteId = CreateSprite(&gHeartSwapOrbSpriteTemplate, task->data[11], task->data[12], 0); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].data[0] = 16; + gSprites[spriteId].data[2] = task->data[13]; + gSprites[spriteId].data[4] = task->data[14]; + gSprites[spriteId].data[5] = task->data[10]; + + InitAnimArcTranslation(&gSprites[spriteId]); + StartSpriteAffineAnim(&gSprites[spriteId], task->data[2] & 3); + } + + if (++task->data[2] == 12) + task->data[0]++; + } + break; + case 1: + if (++task->data[1] > 17) + DestroyAnimVisualTask(taskId); + break; + } +} + static void AnimSkillSwapOrb(struct Sprite *sprite) { if (TranslateAnimHorizontalArc(sprite)) diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h index 2ab982d2d72c..a09c8d72c8cc 100644 --- a/src/data/battle_anim.h +++ b/src/data/battle_anim.h @@ -1465,6 +1465,7 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] = {gBattleAnimSpriteGfx_RedExplosion, 0x0800, ANIM_TAG_RED_EXPLOSION}, {gBattleAnimSpriteGfx_Beam, 0x0800, ANIM_TAG_BEAM}, {gBattleAnimSpriteGfx_PurpleChain, 0x1000, ANIM_TAG_PURPLE_CHAIN}, + {gBattleAnimSpriteGfx_PinkVioletOrb, 0x0080, ANIM_TAG_PINKVIO_ORB}, }; const struct CompressedSpritePalette gBattleAnimPaletteTable[] = @@ -1931,6 +1932,7 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] = {gBattleAnimSpritePal_RedExplosion, ANIM_TAG_RED_EXPLOSION}, {gBattleAnimSpritePal_Beam, ANIM_TAG_BEAM}, {gBattleAnimSpritePal_PurpleChain, ANIM_TAG_PURPLE_CHAIN}, + {gBattleAnimSpritePal_PinkVioletOrb, ANIM_TAG_PINKVIO_ORB}, }; const struct BattleAnimBackground gBattleAnimBackgroundTable[] = diff --git a/src/graphics.c b/src/graphics.c index 231aec415824..5aafa8ae4591 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1263,6 +1263,9 @@ const u32 gBattleAnimSpriteGfx_XSign[] = INCBIN_U32("graphics/battle_anims/sprit const u32 gBattleAnimSpriteGfx_BluegreenOrb[] = INCBIN_U32("graphics/battle_anims/sprites/bluegreen_orb.4bpp.lz"); const u32 gBattleAnimSpritePal_BluegreenOrb[] = INCBIN_U32("graphics/battle_anims/sprites/bluegreen_orb.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_PinkVioletOrb[] = INCBIN_U32("graphics/battle_anims/sprites/pinkvio_orb.4bpp.lz"); +const u32 gBattleAnimSpritePal_PinkVioletOrb[] = INCBIN_U32("graphics/battle_anims/sprites/pinkvio_orb.gbapal.lz"); + const u32 gBattleAnimSpriteGfx_PawPrint[] = INCBIN_U32("graphics/battle_anims/sprites/paw_print.4bpp.lz"); const u32 gBattleAnimSpritePal_PawPrint[] = INCBIN_U32("graphics/battle_anims/sprites/paw_print.gbapal.lz");