-
Notifications
You must be signed in to change notification settings - Fork 1k
Attack animation tiles
## Introduction The aim of this tutorial is to use additional tiles for the attack animations in battle. There are 2 ways to do that: moving black tiles from both attack tilesets to the font tileset, and/or add a new tileset. The 1st method lets you add up to 22 tiles, the 2nd method lets you add 32 tiles more or less but it puts some limitations. You can use both methods to have a total of 54 new tiles. Before starting the tutorial, I strongly recommend to know how animations work in pokered. You need to know at least what are frameblocks and subanimations, especially for the first method.
## A/ Method 1: Moving black tiles and replacing them This is the best way if you only need few tiles. # 1) Move your tiles First you need to know that the font tileset (in gfx/font/font.png) is used in battle just like the 2 attack animation tilesets. If you look at this font tileset, you will notice a white empty space (enough for 32 tiles) right after the 64 characters, BUT this space can't be used for the tiles that use 4 colors. The font tileset is coded in 1 bit per pixel (1bpp), which means that it only uses black (and white for the transparency of course). No gray. Now the interesting thing is that many tiles in the attack tilesets (22 in total) only use black. So, as you probably want to add 4-color tiles, you can just move the black tiles from the attack tilesets to the unused space in the font tileset, and then replace these black tiles by your custom tiles.
# 2) Change the tile IDs in frameblocks From this point, it's a bit complicated to explain but I will do my best and show an example. So, after moving your tiles, change the tile IDs in the frameblocks so that the animations find the new location of the moved tiles. Otherwise, the attacks using these tiles will not find them (they would use the new replaced tiles and that's not what we want). Just change data/battle_anims/frame_blocks.asm. You need to do a little bit of investigation for that, I mean you need to find which specific frameblock(s) use the tile. Make sure the tile ID in the frameblock matches the place of the tile in the tileset, and make sure that the animation using the frameblock uses the good tileset too. Then set the tile ID in the frameblock to the new ID (in the font tileset). Important to know: the font tileset can be used along with attack_anim_1 or attack_anim_2 (and even attack_anim_3 if you add a 3rd tileset). The tile IDs in the free slots of the font tileset go from 0x90 to 0xAF.
# 3) An example with the question mark tiles Let's make all this clear with an example. The question mark tiles in attack_anim_1 are fully black, then you can move them to the font tileset. Now, put your new custom tiles where the question mark is in attack_anim_1. Now you need to change the ID of the question mark tiles in the frameblocks. Start with the first tile. Go to frame_blocks.asm and look for the frameblock(s) that use the 1st tile of the question mark. The ID of this tile is 0x2a, we know it because we can see that it's the 42nd in the tileset (counting from 0!). Do ctrl+F and search for $2a. You will find the frameblocks 35 and 52. Be careful here, this doesn't mean these two frameblocks use the tile, because they might use the tile 0x2a of the other tileset (attack_anim_2). To figure this out, you have to investigate a bit. In subanimations.asm, search for the subanimations that use frameblocks 35 and 52, you will see that 35 is used by subanim 15, and 52 is used by subanims 25 and 26. Now, what animation(s) does use these subanims? Search in data/moves/animations.asm, you'll find Roar, Sonicboom, Amnesia, ConfusedPlayerAnim and ConfusedEnemyAnim. From here you can guess that only Amnesia and confusion animations use the question mark tile, or you can check in-game, or just by checking the tileset ID (in animations.asm. 0 is attack_anim_1 and 1 is attack_anim_2). Now, you know which frameblock you have to change: 52. Because Amnesia and confusion animations use the subanims 25 and 26, which use the frameblock 52. Set the tile IDs to something from 0x90 to 0xAF. That's it, you just replaced the question mark tiles without messing with Amnesia's animation. You can use your new tiles now.
## B/ Method 2: Adding a new tileset You will be able to add only one tileset of 32 tiles, choose a size of 128*16 preferently but any size should be fine, and of course the tileset must be indexed in 4 colors (black, white, light grey and dark grey). A few limits to this method: *You might be restricted to 16 tiles if you add many attack animations (subanimations, frameblocks...). Indeed the tilesets and files using them must be in the same bank, which puts some limits in terms of rom space. If you manage to keep a bank with few data in it, you can think of adding more tiles but you really need to know exactly what you do and what you move from the bank. Anyway, 32 tiles is the recommended quantity for this tutorial. *Another limit of adding a tileset is that you will have to remove 5 special effect animations. 3 are unused by the game though, only 2 need to be removed, you'll understand why later.
This method can be improved, you are welcome to share anything useful.
# 1) Adding the gfx pointer to the engine routine
In engine/battle/animations.asm, add these lines under the AnimationTileset2 pointer:
AnimationTileset3:
INCBIN "gfx/battle/attack_anim_3.2bpp" ; the path must match the name of your directory and tileset of course
Then add this under the 3 anim_tileset lines: anim_tileset x, AnimationTileset3
Replace the "x" by the number of tiles you have in your tileset (32 if you stick to this number).
## 2) Restructure the banks
Adding a tileset will probably make the bank space overflow. This bank should be bank1E normally. You need to move some data in this bank to another bank. For this, create a new bank and a new section for it in layout.link (the file name may change depending on the updates of the pokered repository). Type in something like:
ROMX d
"bank2D" ; you can put these lines under ROMX C for example
Then you can move the data from bank1E in main.asm to your new bank, but make sure to keep these includes in the same bank: engine/battle/animations.asm, data/moves/animations.asm, data/battle_anims/subanimations.asm, data/battle_anims/frame_blocks.asm, engine/overworld/cut2.asm and engine/overworld/dust_smoke.asm. These files need each other in some way, don't put them in separate banks.
# 3) Affect the tileset to an animation In data/moves/animations.asm, set the 3rd parameter of the animation you want to 3. This tells the compiler that the animation uses the tileset 3. We do count tilesets from 0 but 0, 1 and 2 are for tilesets 1 and 2, and 3 is for tileset 3.
# 4) Change the FIRST_SE_ID constant In constants/move_animation_constants.asm, set this constant to 0xC5 (replace $C0 by $C5). Then remove 5 constants among the special effect animations (the ones beginning by "SE"). 3 animations are already unused: SE_FLASH_ENEMY_MON_PIC, SE_SHAKE_ENEMY_HUD_2 et SE_SHOOT_MANY_BALLS_UPWARD. See the difference between special effects and normal animations (subanims) in data/moves/animations.asm. By "remove" I mean delete the whole line of the constant. There are 2 anims left to delete, you can choose SE_BOUNCE_UP_AND_DOWN for example because it's exclusive to Splash which can be replaced, and it's not essential in my opinion. For the last one, you can choose one that is exclusive to one animation, like the one for Whirlwind, Minimize... I'm not sure how you can replace them though, the attack might become unusable, I didn't work much on this point. You can try to make a generic animation to gather 2 into one (in engine/battle/animations.asm) but that sounds pretty hard. I hope this tutorial will be updated with more information.
After that, remove the references to the deleted constants in data/moves/animations.asm. You can either remove the full line containing the constant or modify the whole animation by using subanimations for example. The point is to delete any reference to the constants. Same thing in data/battle_anims/special_effect_pointers.asm, you have to remove the whole lines here.
Now you can use your new tileset.
# 5) Why setting FIRST_SE_ID to 0xC5? This part is not necessary for the tutorial but it's meant to explain what happens in the code. When you set the tileset ID of an animation to 3, this causes a bug as soon as you use your new tileset (if FIRST_SE_ID is left to 0xC0). The bug comes from the PlayAnimation routine in engine/battle/animations.asm.
The value pointed by the animation pointer is 0xC4 when the animation uses the tileset 3, this pointer is at AttackAnimationPointers + (AnimationID*2) if I'm not wrong. 0xC4 is loaded into register a, then a is compared with FIRST_SE_ID (which has 0xC0). As a is greater than FIRST_SE_ID, the routine doesn't jump to .playSubanimation. The routine "thinks" the animation contains a special effect whereas it contains subanimation(s) instead. It loops in searchSpecialEffectTableLoop and it obviously doesn't find any matching special effect. This is the cause of the bug and the reason why we set FIRST_SE_ID to 0xC5, we make it greater than 0xC4 to force the jump.
I hope that I was clear in the explanations, I did my best to make this tutorial enjoyable to read but I might improve it in the future. I made many tests and didn't find any bug with both methods, you can be quiet. I didn't make a full playthrough however, you're welcome to report any bug or detail that I should mention on this page. By the way I thank 33dannye for providing me some information about the source code in pokered.