-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Removing the Animation Affines
NOTE: I can't guarantee this method is bug-free ! This is confirmed to work in the summary screen and in battle.
To remove affines, you first need to go into include\pokemon_animation.h
and remove the following code:
#define BACK_ANIM_NONE 0
- #define BACK_ANIM_H_VIBRATE 1
- #define BACK_ANIM_H_SLIDE 2
- #define BACK_ANIM_H_SPRING 3
- #define BACK_ANIM_H_SPRING_REPEATED 4
- #define BACK_ANIM_SHRINK_GROW 5
- #define BACK_ANIM_GROW 6
- #define BACK_ANIM_CIRCLE_COUNTERCLOCKWISE 7
- #define BACK_ANIM_H_SHAKE 8
- #define BACK_ANIM_V_SHAKE 9
- #define BACK_ANIM_V_SHAKE_H_SLIDE 10
- #define BACK_ANIM_V_STRETCH 11
- #define BACK_ANIM_H_STRETCH 12
- #define BACK_ANIM_GROW_STUTTER 13
- #define BACK_ANIM_V_SHAKE_LOW 14
- #define BACK_ANIM_TRIANGLE_DOWN 15
- #define BACK_ANIM_CONCAVE_ARC_LARGE 16
- #define BACK_ANIM_CONVEX_DOUBLE_ARC 17
- #define BACK_ANIM_CONCAVE_ARC_SMALL 18
- #define BACK_ANIM_DIP_RIGHT_SIDE 19
- #define BACK_ANIM_SHRINK_GROW_VIBRATE 20
- #define BACK_ANIM_JOLT_RIGHT 21
- #define BACK_ANIM_SHAKE_FLASH_YELLOW 22
- #define BACK_ANIM_SHAKE_GLOW_RED 23
- #define BACK_ANIM_SHAKE_GLOW_GREEN 24
- #define BACK_ANIM_SHAKE_GLOW_BLUE 25
as well as adjust the code here:
+ #define ANIM_NONE 0
- #define ANIM_V_SQUISH_AND_BOUNCE 0
- #define ANIM_CIRCULAR_STRETCH_TWICE 1
- #define ANIM_H_VIBRATE 2
- #define ANIM_H_SLIDE 3
- #define ANIM_V_SLIDE 4
- #define ANIM_BOUNCE_ROTATE_TO_SIDES 5
- #define ANIM_V_JUMPS_H_JUMPS 6
- #define ANIM_ROTATE_TO_SIDES 7
- #define ANIM_ROTATE_TO_SIDES_TWICE 8
- #define ANIM_GROW_VIBRATE 9
- #define ANIM_ZIGZAG_FAST 10
...
- #define ANIM_SHAKE_GLOW_BLUE_SLOW 150
Essentially, you're going to remove almost everything with a #define_ANIM
or define_BACK_ANIM
, leaving behind BACK_ANIM_NONE
. This will force the game to not load an animation for your back sprites, similarly to Crystal.
You want to include #define ANIM_NONE
in the front animations because this effectively forces the game to only load a static affine for your fronts.
In normal gameplay this is never called, as ANIM_V_SQUISH_AND_BOUNCE
is called when the game can't find valid affine data. As mentioned, a static affine was already included in the backs (though also isn't normally called), so there's not much to worry about there.
Next, we need to clear out everything telling the game to call for a specific affine. This is fairly easy to do.
Head on over to src\pokemon.c
and go the the sMonFrontAnimIdsTable
function. You will be removing everything SPECIES
-related from here.
- [SPECIES_BULBASAUR - 1] = ANIM_V_JUMPS_H_JUMPS,
- [SPECIES_IVYSAUR - 1] = ANIM_V_STRETCH,
- [SPECIES_VENUSAUR - 1] = ANIM_ROTATE_UP_SLAM_DOWN,
- [SPECIES_CHARMANDER - 1] = ANIM_V_JUMPS_SMALL,
- [SPECIES_CHARMELEON - 1] = ANIM_BACK_AND_LUNGE,
- [SPECIES_CHARIZARD - 1] = ANIM_V_SHAKE,
- [SPECIES_SQUIRTLE - 1] = ANIM_SWING_CONCAVE,
- [SPECIES_WARTORTLE - 1] = ANIM_SHRINK_GROW,
- [SPECIES_BLASTOISE - 1] = ANIM_V_SHAKE_TWICE,
- [SPECIES_CATERPIE - 1] = ANIM_SWING_CONCAVE,
- [SPECIES_METAPOD - 1] = ANIM_SWING_CONCAVE,
- [SPECIES_BUTTERFREE - 1] = ANIM_H_SLIDE_WOBBLE,
- [SPECIES_WEEDLE - 1] = ANIM_H_SLIDE_SLOW,
- [SPECIES_KAKUNA - 1] = ANIM_GLOW_ORANGE,
- [SPECIES_BEEDRILL - 1] = ANIM_H_VIBRATE,
- [SPECIES_PIDGEY - 1] = ANIM_V_SLIDE_SLOW,
- [SPECIES_PIDGEOTTO - 1] = ANIM_V_STRETCH,
...
- [SPECIES_CHIMECHO - 1] = ANIM_H_SLIDE_WOBBLE,
This will force the game to always load ANIM_NONE
, which is now our default affine.
Next, we will remove everything from sMonAnimationDelayTable
. This function is used for delaying the affines' animations, which we don't really need anymore:
static const u8 sMonAnimationDelayTable[NUM_SPECIES - 1] =
{
- [SPECIES_BLASTOISE - 1] = 50,
- [SPECIES_WEEDLE - 1]- = 10,
- [SPECIES_KAKUNA - 1]- = 20,
- [SPECIES_BEEDRILL - 1] = 35,
- [SPECIES_PIDGEOTTO - 1] = 25,
- [SPECIES_FEAROW - 1]- = 2,
- [SPECIES_EKANS - 1]- = 30,
...
- [SPECIES_RAYQUAZA - 1] = 60,
};
Finally, we go down to BattleAnimateBackSprite
and edit the following code:
void BattleAnimateBackSprite(struct Sprite *sprite, u16 species)
{
+ sprite->callback = SpriteCallbackDummy;
- if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK)))
- {
- sprite->callback = SpriteCallbackDummy;
- }
- else
- {
- LaunchAnimationTaskForBackSprite(sprite, GetSpeciesBackAnimSet(species));
- sprite->callback = SpriteCallbackDummy_2;
}
}
This also makes sure the game always loads our affine, no matter what situation.
This is the most involved process. Honestly, it's best to just copy the raw file here rather than do the changes manually: This works for the current version of pokeemerald, but there's always a chance that things may change.
Essentially, we blank out all of the back affines first. Then, we go in and delete every instance of an affine being referenced in the code, starting with the static void
lines. We then create a new static void
line for Anim_None
, which just waits for the animation to end.
Hopefully, if everything's gone well, this should build just fine and allow you to do Crystal-style animations from here!
Adding new frames is as easy as extending the target anim_front
file down by 64 pixels and adding the new frame in the pokémon's animation in src\data\pokemon_graphics\front_pic_anims.h
.
Here's a template sheet from the above GIF, edited from the Crystal animation:
The animation in src\data\pokemon_graphics\front_pic_anims.h
will look something like this:
static const union AnimCmd sAnim_Pikachu_1[] =
{
ANIMCMD_FRAME(1, 7),
ANIMCMD_FRAME(2, 7),
ANIMCMD_FRAME(3, 7),
ANIMCMD_FRAME(2, 7),
ANIMCMD_FRAME(3, 7),
ANIMCMD_FRAME(2, 26),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(5, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(5, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_END,
};
That's about all there is to it !