Avara

She/Her
Seen 36 Minutes Ago
Posted 1 Day Ago
1,275 posts
9.1 Years
Battle Transitions




Instead of creating a massive post, I've broken this up into smaller sections so you can find which subject you're looking for more easily. I'll be covering how to configure, replace and add new ones.

Avara

She/Her
Seen 36 Minutes Ago
Posted 1 Day Ago
1,275 posts
9.1 Years
Editing Existing Battle Transitions

To give the existing battle transitions a complete makeover, you'll need the latest version of esperance's Tilemap Creator and GraphicsGale, or another program capable of working with indexed images.


We're going to be editing the "Big Pokéball" transition (as seen above). I've got a simple pre-made indexed tileset from one of my own projects that's ready to use (please don't steal; I spent a long time making sure it was perfect) so what I've done is deleted the original and replaced it with my own, renaming my .png file to match the original. Open the tileset for the transition you want to edit (in this case, "big_pokeball.png") with TMC and its corresponding tilemap ("big_pokeball_map.bin") with the size specifications set to 30x20 (some transitions have size specs of 32x32, either of those is fine).


Don't panic if you're using a custom tileset like I have and the tilemap looks like an absolute mess as below - that's perfectly normal, it's just because the tilemap is still using its default tile arrangements from the original tileset it was created for. Draw your tilemap using the 8x8 blocks from the tileset on the left. Once you're happy with it, highlight the "Tilemap" drop-down and hit "Save". (Do not save your tileset, as it may result in an invalid .png signature error when you try to build.) Let's compile and see how it looks in-game...

Avara

She/Her
Seen 36 Minutes Ago
Posted 1 Day Ago
1,275 posts
9.1 Years
Adding New Battle Transitions

This demonstration won't show you how to create a whole new custom fancy transition animation - I'm not smart enough for that - but it should hopefully be helpful to you in some way if you've never looked at this stuff before, even if just to show how they're set up and structured. Think of this post as an easy beginner's guide as opposed to a complete compendium.

We're simply going to add a new transition that has the same animation style as Team Aqua/Magma - basically creating another version of it as though it was a battle transition for another trainer class. Maybe you want five evil teams instead of two or want a special transition for a particular character, etc!
Please note that Pokéemerald labels are always subject to change; I'll do my best to keep this post up to date (I wrote this ages ago and forgot to post it until now, oops). I've colour coded some labels to help show how sections are related to one another, so try to pay attention to those. As well as trying to describe where to put things I've also mentioned which line number I'm adding code to, but remember that due to Pokéemerald being updated so often, it might be slightly different for you.

-----------------------------------------------------------------------------------------------------------------------------------------------------

Alright, first things first: you will need a tilemap (.bin), palette (.pal) and tileset (.png) for your new transition. I've named all of mine “example_transition”. These files go in the “pokeemerald\graphics\battle_transitions” folder.


Once you've got your files in the correct location, open “pokeemerald\include\battle_transition.h” and add an entry for your new transition beforeB_TRANSITION_COUNT”. (line 70)

...
#define B_TRANSITION_41                     41
#define B_TRANSITION_EXAMPLE                42
#define B_TRANSITION_COUNT                  43

#endif // GUARD_BATTLE_TRANSITION_H
The bottom of the file should then look something like the above. Remember to fix the numbers appropriately! Obviously since this is just a demonstration, I've named mine “B_TRANSITION_EXAMPLE”.
You're finished with “battle_transition.h” now, so you can close it if you want.

-----------------------------------------------------------------------------------------------------------------------------------------------------

Next, open “pokeemerald\src\battle_transition.c”. It's a pretty big file, but don't worry, there are a lot of annotations - look for //const rom data and add a few lines to the end of this section. (starting at line 317)
static const u32 sExampleTransition_Palette[] = INCBIN_U32("graphics/battle_transitions/example_transition.gbapal");
static const u32 sExampleTransition_Tileset[] = INCBIN_U32("graphics/battle_transitions/example_transition.4bpp.lz");
static const u32 sExampleTransition_Tilemap[] = INCBIN_U32("graphics/battle_transitions/example_transition.bin.lz");
On the left side of the "=" we have our label and on the right we have the file's location. Simple enough, right?
You'll want to follow the above example using your own labels and file names.

-----------------------------------------------------------------------------------------------------------------------------------------------------

Now that you're done with that, we're going to define our functions. Look for //this file's functions (or just Ctrl+F if you get lost scrolling). You will want to add lines to the end of that list. (starting at line 262)
static void Phase2Task_ExampleTransition(u8 taskId);
static bool8 Phase2_ExampleTransition_Func1(struct Task *task);
static bool8 Phase2_ExampleTransition_Func2(struct Task *task);
The lines you add should look like this but with your own labels, of course. If you search for "TaskFunc sPhase2_Tasks" you should come across a list with commented corresponding numbers. Scroll to the bottom of this list and add an entry for the orange label shown above. (line 371)

...
Phase2Task_40,                          // 40
Phase2Task_41,                          // 41
Phase2Task_ExampleTransition,           // 42
	
};
This happens to have the same corresponding number as it does in “battle_transition.h”. Searching for "Phase2Task_BigPokeball" will bring you to a bunch of functions that look similar to what we've got below - simply copy it and replace the label with your own. (line 1268)
static void Phase2Task_ExampleTransition(u8 taskId)
{
   while (sPhase2_ExampleTransition_Funcs[gTasks[taskId].tState](&gTasks[taskId]));
}
You'll notice that we have a new label here - “sPhase2_ExampleTransition_Funcs”.

-----------------------------------------------------------------------------------------------------------------------------------------------------

Search "TransitionStateFunc sPhase2_Magma_Funcs" to find this snippet here:
static const TransitionStateFunc sPhase2_Magma_Funcs[] =
{
    Phase2_Magma_Func1,
    Phase2_Magma_Func2,
    Phase2_BigPokeball_Func3,
    Phase2_BigPokeball_Func4,
    Phase2_BigPokeball_Func5,
    Phase2_FramesCountdown,
    Phase2_BigPokeball_Func6
};
If you've looked at the code you'll notice that the battle transitions for Team Magma and Aqua use almost exactly the same functions as the big Pokéball transition aside from the first two. As this demo is for making a simple trainer class style transition, just copy & paste that and replace the first two labels with your own. (line 424) For instance, I now have:
static const TransitionStateFunc sPhase2_ExampleTransition_Funcs[] =
{
    Phase2_ExampleTransition_Func1,
    Phase2_ExampleTransition_Func2,
    Phase2_BigPokeball_Func3,
    Phase2_BigPokeball_Func4,
    Phase2_BigPokeball_Func5,
    Phase2_FramesCountdown,
    Phase2_BigPokeball_Func6
};
We're nearly done. Ctrl+F "Phase2_Magma_Func1" & "Phase2_Magma_Func2" and copypaste those as well, making the following changes:
static bool8 Phase2_ExampleTransition_Func1(struct Task *task)
{
    u16 *dst1, *dst2;

    task->tFrames = 60;
    sub_814669C(task);
    sub_8149F58(&dst1, &dst2);
    CpuFill16(0, dst1, 0x800);
    LZ77UnCompVram(sExampleTransition_Tileset, dst2);
    LoadPalette(sExampleTransition_Palette, 0xF0, 0x20);

    task->tState++;
    return FALSE;
}
The pink labels are for our tileset and tilemap - remember we added these back at the start?

static bool8 Phase2_ExampleTransition_Func2(struct Task *task)
{
    u16 *dst1, *dst2;

    sub_8149F58(&dst1, &dst2);
    LZ77UnCompVram(sExampleTransition_Tilemap, dst1);
    sub_8149F98(gScanlineEffectRegBuffers[0], 0, task->tData4, 132, task->tData5, 160);

    task->tState++;
    return FALSE;
}
Again, the pink text is the tilemap's label. What's next? Save all that and now you are finished! You can assign your new battle transition to a trainer class in “src\battle_setup.c”. Just to demonstrate, I gave mine to the standard wild Pokémon battle. All that's left to do is test in-game and see how it looks.

Avara

She/Her
Seen 36 Minutes Ago
Posted 1 Day Ago
1,275 posts
9.1 Years
Configuring Battle Transitions

This is the easiest bit which people should find the most straight forward, but writing this anyway in case it isn't so obvious to newbies at first glance.
Have “src\battle_setup.c” open. As mentioned earlier on in the guide, you'll find the transitions list in "include\battle_transition.h”.

Standard Battles
Spoiler:
So, in “src\battle_setup.c” you'll find this close to the beginning of the file:
static const u8 sBattleTransitionTable_Wild[][2] =
{
    {B_TRANSITION_SLICE,               B_TRANSITION_WHITEFADE},     // Normal
    {B_TRANSITION_CLOCKWISE_BLACKFADE, B_TRANSITION_GRID_SQUARES},  // Cave
    {B_TRANSITION_BLUR,                B_TRANSITION_GRID_SQUARES},  // Cave with flash used
    {B_TRANSITION_WAVE,                B_TRANSITION_RIPPLE},        // Water
};

static const u8 sBattleTransitionTable_Trainer[][2] =
{
    {B_TRANSITION_POKEBALLS_TRAIL, B_TRANSITION_SHARDS},        // Normal
    {B_TRANSITION_SHUFFLE,         B_TRANSITION_BIG_POKEBALL},  // Cave
    {B_TRANSITION_BLUR,            B_TRANSITION_GRID_SQUARES},  // Cave with flash used
    {B_TRANSITION_SWIRL,           B_TRANSITION_RIPPLE},        // Water
};
Completely self explanatory - as per the comments, the transition type on the left is used if the opponent is lower level than the player. Otherwise, the transition on the right is used.

Trainer Classes
Spoiler:
To assign battle transitions to trainer classes, keep going through the file and you'll stumble across this section:
if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION)
        return B_TRANSITION_CHAMPION;

if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_TEAM_MAGMA
        || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_MAGMA_LEADER
        || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_MAGMA_ADMIN)
        return B_TRANSITION_MAGMA;

if (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_TEAM_AQUA
        || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_AQUA_LEADER
        || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_AQUA_ADMIN)
        return B_TRANSITION_AQUA;
Again, fairly straight forward, you can add or edit the code here to your liking.

Specific Pokémon
Spoiler:
Look for the following section:
switch (GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL))
    {
    default:
    case SPECIES_GROUDON:
        gBattleTypeFlags |= BATTLE_TYPE_GROUDON;
        CreateBattleStartTask(B_TRANSITION_GROUDON, MUS_BATTLE34);
        break;
    case SPECIES_KYOGRE:
        gBattleTypeFlags |= BATTLE_TYPE_KYOGRE;
        CreateBattleStartTask(B_TRANSITION_KYOGRE, MUS_BATTLE34);
        break;
    case SPECIES_RAYQUAZA:
        gBattleTypeFlags |= BATTLE_TYPE_RAYQUAZA;
        CreateBattleStartTask(B_TRANSITION_RAYQUAZA, MUS_VS_REKKU);
        break;
    case SPECIES_DEOXYS:
        CreateBattleStartTask(B_TRANSITION_BLUR, MUS_RG_VS_DEO);
        break;
    case SPECIES_LUGIA:
    case SPECIES_HO_OH:
        CreateBattleStartTask(B_TRANSITION_BLUR, MUS_RG_VS_DEN);
        break;
    case SPECIES_MEW:
        CreateBattleStartTask(B_TRANSITION_GRID_SQUARES, MUS_VS_MEW);
        break;
    }
Once again, this shouldn't need very much explanation. Not only can you add and edit the battle transitions for special Pokémon, you can also pick their battle music.
Seen 1 Day Ago
Posted October 28th, 2020
7 posts
142 Days
So I've followed this guide to add some new transitions, and they all seem to be working except for their palettes. I created the tilesets in Graphics Gale as 4bpp (16 colors), saved each palette, then loaded those tilesets into Tilemap Studio to create the tilemap. But none of my tilemaps seem to be using their individual palettes.

I've double-checked the code and I'm pretty sure that's all good. My feeling is it's something to do with creating the tileset and tilemaps, as that's what I'm least knowledgeable with, and the guide itself isn't very clear about creating a tileset .png and palette so I may have missed something during that process.

Any ideas?
Seen 2 Weeks Ago
Posted 2 Weeks Ago
1,334 posts
6.8 Years
I figured it out this morning, there's a palette tab in Tilemap Studio and I just had mark each tile as 'F'. Not sure what that means, or what values 1-E do, but that did the trick.
It's which palette to use. There are 16 of them, and I guess battle transition palettes must be loaded as the 16th (i.e. F, from 0–F)