Pokéball Hacking Guide
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/9/93/Bag_Pok%C3%A9_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/9/93/Bag_Pok%C3%A9_Ball_Sprite.png)
All credits for the original thread go to danills. It's thanks to him any of this is even possible. The following introduction is from him.
Some months ago, when I was still attempting my first hack, I was wondering whether it was possible to create a custom pokeball. The only thing I found was this post by JPAN. It wasn't complete, and I hadn't seen anyone using it, so I forgot about it.
Now, I am working full-time on Platinum Red&Blue with GoGoJJTech, and had to implement gen IV pokeballs into the hack. I have altered JPAN's asm code a bit, and included documentation on the throwing graphics for everybody to use. Enjoy!
Some months ago, when I was still attempting my first hack, I was wondering whether it was possible to create a custom pokeball. The only thing I found was this post by JPAN. It wasn't complete, and I hadn't seen anyone using it, so I forgot about it.
Now, I am working full-time on Platinum Red&Blue with GoGoJJTech, and had to implement gen IV pokeballs into the hack. I have altered JPAN's asm code a bit, and included documentation on the throwing graphics for everybody to use. Enjoy!
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/c/ca/Bag_Great_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/c/ca/Bag_Great_Ball_Sprite.png)
- A hex editor (I use HxD)
- A way to find free space in your rom; FSF recommended
- Images for your balls
- A way to insert those images (I use unLZ-GBA)
- Gen 3 Tools
- Basic hex editing/assembly knowledge. I do assume you know how to assemble a routine and place an inverted pointer +1 to it.
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/0/03/Bag_Ultra_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/0/03/Bag_Ultra_Ball_Sprite.png)
WARNING: This step will break any saves in progress!
This is the easiest part. As you can see here, the balls only get four bits of data, and 0 is unused, meaning you can add up to three balls. Since I don't think there are many people who have transferred pokemon from Colosseum or XD to a hack, it's safe to sacrifice the most significant bit used to determine the game of origin, leaving us space for 19 extra balls. If you need more, you will need a different workaround.You've got to change six bytes:
- At 080400B6, place 80
- At 080400B8, place 44
- At 080400BE, place 0B
- At 08040855, place FC
- At 0804085A, place 1F
- At 0804085E, place 89
- At 08040862, place 7C
And you're done! Move on to step 2.
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/e/eb/Bag_Safari_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/e/eb/Bag_Safari_Ball_Sprite.png)
JPAN has written a neat routine that replaces the regular check for pokeballs (see the link posted above). However, it requires you to perform a cmp for every ball index, and that's not very efficient and forces you to modify the routine every time you add a ball. Thus, I have modified it, so that it checks what pocket the selected item is in. Now, you only have to give the item the right pocket value and it becomes a ball. The routine:
Now, in the code you see "somevar". There you must place an address (or use this one I saw in JPAN's original routine) that will keep track of the current pokeball index. Other than in the routine, there are a few places you need to place a pointer to it:
(more information here)
Now you've done all that, it's time to assemble the routine. Insert in anywhere, and place a pointer to it at 08016494. Then at 08016460, type 00 00 00 00 0B 4A 97 46. Done! Move on to the next step to make your ball actually do something.
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global ballchecker
ballcompare:
mov r0, #0x2C
mul r0, r1
mov r10, r1
ldr r1, itemdata
add r1, r0, r1
add r1, #0x1A
ldrb r0, [r1]
cmp r0, #0x3
beq isball
otherstuffcompare:
mov r1, r10
cmp r1, #0x50
beq dolly
cmp r1, #0x51
beq dolly
mov r0, #0xaf
lsl r0, r0, #0x1
cmp r1, r0
beq flute
ldr r0, return_addr
bx r0
isball:
ldr r0, somevar
add r1, #0x1
ldrb r1, [r1]
strb r1, [r0]
ldr r0, ball_script
cmp r1, #0x11 /*If you want to have a second safari ball like the park ball, place its pokeball index here*/
beq safari /*Otherwise, remove these two lines*/
cmp r1, #0x5
bne preender
safari:
add r0, #0x28
preender:
b script_ender
dolly:
ldr r0, doll_script
b script_ender
flute:
ldr r0, flute_script
script_ender:
ldr r1, script_ptr
str r0, [r1]
ldr r1, be3_addr
mov r10, r1
ldr r0, end_addr
bx r0
.align 2
ball_script: .word 0x081D9A14
doll_script: .word 0x081D9B7C
flute_script: .word 0x081D9B86
script_ptr: .word 0x02023d74
be3_addr: .word 0x02023be3
return_addr: .word 0x080164e9
end_addr: .word 0x0801671f
itemdata: .word 0x083DB028
somevar: .word 0x0203fe00
- 0802D500
- 0802D544
- 0802D6A0
- 0802D71C
- 0802D7B8
- 080EF4B4
- 080EF4DC
- 080EF674
- 080EF9AC
- 080F0368
(more information here)
Now you've done all that, it's time to assemble the routine. Insert in anywhere, and place a pointer to it at 08016494. Then at 08016460, type 00 00 00 00 0B 4A 97 46. Done! Move on to the next step to make your ball actually do something.
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/6/6d/Bag_Master_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/6/6d/Bag_Master_Ball_Sprite.png)
The balls with a pokeball index (previously index number) higher than 5 each have their own catch rate calculation subroutine. We need to extend that. To do this, first change the byte at 0x802D52C to FF. Then, look at the table at 0x802D54C. It has a pointer to a routine for every pokeball starting from 6. At 0x802D548 you can see a pointer to the table; repoint it somewhere else (the table is 0x1C bytes long). Now, to give a ball a certain catch rate, you must write a routine to load it into r4, and exit to 0x802D7A2. Then place a pointer to that routine in the table.
Some example routines:
Quick ball:
Dusk ball:
Park ball; this one uses a modified safari ball routine, and will get another piece of code later:
Heal ball/Cherish ball (the heal ball will get another piece of code later)
These are special. They load the catch rate from the "Extra value" of the item (labeled as "Extra" in Gen3Tools). In the case of these balls it's 10, but you can easily change it without altering the code:
Moon Ball:
Sport Ball:
Dream Ball:
This is a hook from the Master Ball routine. This code DOES NOT go at the end of the catch routine table. Where a routine in the table would have gone for the Dream Ball, place 00 00 00 00. Despite it not having its own routine, the Dream Ball still receives a unique index like every other ball.
Beast Ball:
Here comes the part JPAN didn't document: animations. And be prepared, it's a long part.
Some example routines:
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/4/41/Bag_Quick_Ball_Sprite.png)
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global catchratebyturn
main:
mov r4, #10
ldr r0, battleturncounter
ldrb r0, [r0]
cmp r0, #0x0
bne ender
firstturn:
add r4, #40 [B]@Change to 30 for Gen IV effect[/B]
ender:
ldr r0, catchratecalcfunction
mov pc, r0
.align 2
battleturncounter: .word 0x03004fa3
catchratecalcfunction: .word 0x0802d62a
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/0/06/Bag_Dusk_Ball_Sprite.png)
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global catchratebyareaortimeofday
main:
ldr r0, time
ldrb r0, [r0]
cmp r0, #0x6 [B]@6 AM - Change if you want![/B]
blt night
cmp r0, #0x15 [B]@9 PM - Change if you want![/B]
bge night
day:
mov r4, #10
ldr r0, maptype
ldrb r0, [r0]
cmp r0, #0x4
bne ender
night:
mov r4, #35 [B]@Change to 30 for Sun/Moon effect[/B]
ender:
ldr r0, catchratecalcfunction
mov pc, r0
.align 2
time: .word 0x03005542
maptype: .word 0x02036e13
catchratecalcfunction: .word 0x0802d62a
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/b/b2/Bag_Park_Ball_Sprite.png)
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global safaricatchmax
main:
LDR R0, dword_2023FE8
LDR R0, [R0]
ADD R0, #0x7C
LDR R0, [R0]
LSL R1, R0, #2
ADD R1, R1, R0
LSL R0, R1, #8
SUB R0, R0, R1
MOV R1, #0x64
BL __divsi3
LSL R0, R0, #0x18
LSR R5, R0, #0x18
park:
mov r4, #0xff
ldr r0, catchratecalcfunction
mov pc, r0
.align 2
catchratecalcfunction: .word 0x0802D62A
dword_2023FE8: .word 0x02023FE8
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/1/17/Bag_Heal_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/f/ff/Bag_Cherish_Ball_Sprite.png)
These are special. They load the catch rate from the "Extra value" of the item (labeled as "Extra" in Gen3Tools). In the case of these balls it's 10, but you can easily change it without altering the code:
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global staticcatchrate
main:
ldr r4, itembuffer
ldrh r4, [r4]
mov r0, #44
mul r4, r0
ldr r0, itemdata
add r0, r4
add r0, #40
ldr r4, [r0]
ldr r0, catchratecalcfunction
mov pc, r0
.align 2
catchratecalcfunction: .word 0x0802d62a
itemdata: .word 0x083DB028
itembuffer: .word 0x02023d68
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/f/f9/Bag_Moon_Ball_Sprite.png)
Spoiler:
Code:
.thumb
.global MoonBall
Main:
ldr r0, .BattleData
ldr r1, .TargetBank
ldrb r1, [r1]
mov r2, #0x58
mul r1, r2
ldrh r1, [r0, r1] @r1 has wild pokemon species
ldr r0, .MoonTable
ldrh r3, =0xFFFF
mov r4, #10 @catch rate of normal Pokemon
Loop:
ldrh r2, [r0] @r2 has first Pokemon in table
cmp r1, r2
beq Moon
cmp r2, r3
beq End
add r0, #0x2
b loop
Moon:
mov r4, #40 @catch rate of Moon Stone family
End:
ldr r0, .CatchRateCalcFunction
mov pc, r0
.align 2
.BattleData: .word 0x2023BE4
.TargetBank: .word 0x2023D6C
.CatchRateCalcFunction: .word 0x802D62A
[B]@The moon table is a table of halfwords (2 bytes each) with each moon stone based pokemon species index number (this is not Pokedex number). It must be terminated with FF FF. It should start with [1D 00 1E 00…] [\B]
. MoonTable: .word [B]0x8MMMMMM @Replace with your offset of your Moon Ball table[\B]
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/3/3e/Bag_Sport_Ball_Sprite.png)
Spoiler:
Code:
@Credits to [URL="https://www.pokecommunity.com/members/581824"]Ghoulslash[/URL]
.thumb
.global SportBall
Main:
mov r4, #15 @1.5x catch rate
Endfunc:
ldr r0, =(0x0802D62A)
mov pc, r0
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/4/4a/Bag_Dream_Ball_Sprite.png)
This is a hook from the Master Ball routine. This code DOES NOT go at the end of the catch routine table. Where a routine in the table would have gone for the Dream Ball, place 00 00 00 00. Despite it not having its own routine, the Dream Ball still receives a unique index like every other ball.
Spoiler:
Code:
@Credits to [URL="https://www.pokecommunity.com/members/581824"]Ghoulslash[/URL]
.thumb
.global DreamBall
@00 48 00 47 (xx+1) xx xx 08 at 0x802D508
Main:
ldr r1, =(0x02023d68)
ldrb r0, [r1]
cmp r0, #0xXX @dream ball tag
beq CatchGuarantee
CheckMaster:
cmp r0, #0x1 @master ball
bne OtherBall
CatchGuarantee:
ldr r0, =(0x03004F90)
ldr r1, =(0x0802D688 +1)
bx r1
OtherBall:
ldr r3, .BaseStats
ldr r2, .BattleStruct
ldrb r1, [r6]
mov r0, #0x58
ldr r5, =(0x0802d510 +1)
bx r5
.align 2
.BaseStats: .word 0x08254784
.BattleStruct: .word 0x02023BE4
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/f/f2/Bag_Beast_Ball_Sprite.png)
Spoiler:
Code:
.thumb
.global BeastBall
Main:
ldr r0, .BattleData
ldr r1, .TargetBank
ldrb r1, [r1]
mov r2, #0x58
mul r1, r2
ldrh r1, [r0, r1] @r1 has wild pokemon species
ldr r0, .UBTable
ldrh r3, =0xFFFF
mov r4, #0x1 @catch rate of normal Pokemon
Loop:
ldrh r2, [r0] @r2 has first Pokemon in table
cmp r1, r2
beq Beast
cmp r2, r3
beq End
add r0, #0x2
b loop
Beast:
mov r4, #50 @catch rate of UB
End:
ldr r0, .CatchRateCalcFunction
mov pc, r0
.align 2
.BattleData: .word 0x2023BE4
.TargetBank: .word 0x2023D6C
.CatchRateCalcFunction: .word 0x802D62A
[B]@The UB table is a table of halfwords (2 bytes each) with each Ultra Beast species index number (this is not Pokedex number). It must be terminated with FF FF.[/B]
.UBTable: .word [B]0x8UUUUUU @Replace with your offset of your UB table[/B]
Step four: Expanding the Throwing Graphics - Part 1
The conversion table
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/d/df/Bag_Level_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/d/df/Bag_Level_Ball_Sprite.png)
Now, if you've ever looked at the pokeballs in an item viewer and at the throwing graphics of them in an image viewer, you might have noticed they're in a different order. So, there is a routine somewhere that converts the index to the throwing graphics table (or tgt in short because I'm lazy) entry. That routine is located at 080EF52C. Due to the way it's written, there's enough space to replace it by a new routine and a table. First the routine:
Assemble this routine and insert it at 080ef52C. Now, the conversion from index to tgt entry will be done through throwtablepositionstable. By this, we freed up more than enough space at the specified offset, so I recommend you to put the table there. Now for the table, it will look like this:
It is the easiest if you insert the throwing graphics in the same order as your pokeballs, so just count up. For the five gen 4 balls, it would be
But be careful: while the pokeball index was one-indexed, the tgt is zero-indexed, which means that in the entry for ball x you will have to type x-1.
After inserting this, remove a limiter by typing 00 00 at 080EF972 and at 080F02D6, and continue to the next step.
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global ballchecker
main:
push {lr}
ldr r1, throwtablepositionstable
add r0, r0, r1
ldrb r0, [r0]
pop {pc}
.align 2
throwtablepositionstable: .word 0x080EF53C
Code:
(unused zeroth entry) FF 04 03 01 00 02 05 06 07 08 09 0A 0B (insert ongoing numbers for each of your balls here)
Code:
FF 04 03 01 00 02 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
After inserting this, remove a limiter by typing 00 00 at 080EF972 and at 080F02D6, and continue to the next step.
Step four: Expanding the Throwing Graphics - Part 2
The image and palette tables
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/2/25/Bag_Lure_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/4/4e/Bag_Lure_Ball_IV_Sprite.png)
Prepare your ball images. Example with gen 4 balls:
Made by Bela. Isn't he awesome? :D
Anyways, you must repoint and extend two tables in this step. First, the one for the images, located at 0826056C. 12 entries, each eight bytes: one word and two halfwords. Repoint it somewhere. Then, append your own balls as follows:
The second table is a lot like this one: it's for the palettes. Located at 082605CC, again 12*8 bytes long. Repoint somewhere, and extend this way:
We just started repointing, and we still have a long way to go.
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://dl.dropboxusercontent.com/s/6nopc4oo4kx7ok4/DzLLV9G.png)
Made by Bela. Isn't he awesome? :D
Anyways, you must repoint and extend two tables in this step. First, the one for the images, located at 0826056C. 12 entries, each eight bytes: one word and two halfwords. Repoint it somewhere. Then, append your own balls as follows:
Code:
word pointer to image
halfword decompressed size (180)
halfword tag of ball(I'm not sure which tags are free exactly, but I started with tag 0xFF00 for the first entry and counted up for the following balls/particles and it worked fine.)
Code:
word pointer to palette
halfword tag of ball
halfword filler (0000)
Step four: Expanding the Throwing Graphics - Part 3
Repointing generic tables
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/f/f9/Bag_Moon_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/f/f9/Bag_Moon_Ball_Sprite.png)
Here comes a list of the tables:
After you have done this, you can finally assign particles and animations to your balls.
Spoiler:
Code:
082606F4 ball object template table
one entry is 24 bytes:
halfword tag of ball
halfword tag of ball
word 0826062C
word 08260674
word 00000000
word 082606E0
word 0804ABD5
Code:
0840BF48 unknown particle table
one entry is 8 bytes:
word 08D1A608
halfword 0100
halfword tag of particle
Code:
0840BFA8 unknown particle table 2
one entry is 8 bytes:
word 08D1A6DC
halfword tag of particle
halfword 0000
Code:
0840C0A4 particle object template table
one entry is 24 bytes:
halfword tag of particle
halfword tag of particle
word 083AC9C8
word 0840C050
word 00000000
word 08231CFC
word 0800760D
Step four: Expanding the Throwing Graphics - Part 4
The particle and animation tables
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/1/17/Bag_Friend_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/1/17/Bag_Friend_Ball_Sprite.png)
As for now, I will only document the tables and their meanings, and how to assign existing animations/particles to new balls. Another part on custom animations may follow later.
The first table you need to repoint and extend is located at 0840C068. For every ball it tells which particle to use. 0=sticks, 1=stars, 2=bubbles, 3=hearts, 4=big green crosses, 5=small green crosses (last two strongly affected by the second table).
The second table is located at 0840C074. Each entry is a pointer to a routine+1 that describes how the particles should act. I can't really describe the effects, so just look at them.
And that's it! Congratulations, you've succesfully expanded the pokeballs! The next parts will describe how to apply some special effects.
The first table you need to repoint and extend is located at 0840C068. For every ball it tells which particle to use. 0=sticks, 1=stars, 2=bubbles, 3=hearts, 4=big green crosses, 5=small green crosses (last two strongly affected by the second table).
The second table is located at 0840C074. Each entry is a pointer to a routine+1 that describes how the particles should act. I can't really describe the effects, so just look at them.
And that's it! Congratulations, you've succesfully expanded the pokeballs! The next parts will describe how to apply some special effects.
Step Five: Expanding the Throwing Graphics - Part 5
Ball Opening Colour Table
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/8/87/Bag_Luxury_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/8/87/Bag_Luxury_Ball_Sprite.png)
There is one last table at 0x40C1C4:
Each half-word (2 bytes) in this table corresponds to the palette the Pokemon is faded when it comes out of that certain Poke Ball. For instance, the first entry, 0x7ADF (DF 7A reversed) is the pink colour a Pokemon fades from when it leaves a Poke Ball. To repoint this table, copy 0x18 bytes to another location, replace the pointers to C4 C1 40 08, and add new colours on to the end of your table in the same order as your Poke Balls. APE's colour picker can be used to calculate the hex codes of new colours in reversed format, ready to be added to the table.
Code:
DF 7A F0 7A D7 53 FF 3F 97 72 F5 67 2C 7B 7E 2B 1F 43 DD 7B 3F 2A 3F 29
Step Six: Additional effects part 1
Healing pokemon after capture
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/4/42/Bag_Love_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/4/42/Bag_Love_Ball_Sprite.png)
This effect was written by danills for the Heal Ball:
In this code you must change the values at the ball index and somevar. Then assemble it and insert it anywhere. To activate it, place 00 4B 9F 46 XX XX XX XX at 08040B08, where XXXXXXXX is an inverted pointer to this routine.
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global afterpoketranscalc
main:
push {lr}
recycle:
ldr r3, memcpy
bl bxr3
calc:
cmp r7, #0x64
bne ender
ldr r3, somevar
ldrb r3, [r3]
cmp r3, #14 /*ball index of heal ball here*/
bne ender
healstuff:
ldr r3, poke_quantity
ldrb r1, [r3]
mov r10, r1
mov r1, #1
strb r1, [r3]
heal_recycle:
mov r3, pc
add r3, #0x1d
push {r3}
push {r4-r7}
mov r7, r10
mov r6, r9
mov r5, r8
push {r5-r7}
sub sp, sp, #4
mov r1, #0
mov r8, r1
mov r1, r0
mov r10, r1
mov r6, sp
ldr r3, healpoke
b bxr3
heal_finish:
ldr r3, poke_quantity
mov r1, r10
strb r1, [r3]
ender:
pop {r3}
bxr3:
bx r3
.align 2
memcpy: .word 0x081e5e78+1
somevar: .word 0x0203fe00
partyadr: .word 0x02024284
poke_quantity: .word 0x02024029
healpoke: .word 0x080a0076+1
Step Six: Additional effects part 2
Retaining pokeballs
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/7/74/Bag_Heavy_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/7/74/Bag_Heavy_Ball_Sprite.png)
This effect was written by me for the Park Ball, and will work if the caught poke already has a pokeball, like with the Pal Park:
In this code you must only change the the ball index. Then assemble it and insert it anywhere. To activate it, place 40 4B 9F 46 12 F0 EB FD 13 F0 49 FA at 0802D6EE, and 70 BD XX XX XX XX at 0802D7EE where XXXXXXXX is an inverted pointer to this routine.
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global keepballcheck
main:
mov r5, r3
ldr r3, returnadr
cmp r5, #17
bne bxr3
add r3, #4
bxr3:
bx r3
.align 2
returnadr: .word 0x0802D7A2+1
Step Six: Additional effects part 3
The givepokemon hack
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/7/70/Bag_Fast_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/7/70/Bag_Fast_Ball_Sprite.png)
One of the gen 4 balls is the Cherish Ball, which has no effects other than being the standard ball for event pokes. To copy this effect, I wrote a piece of code to change the givepokemon command. Know how it has three unused parameters? Well, the last one, a byte, is now the pokeball the received pokemon will be in. If it's 0, it will be in a regular pokeball.
Anyways, the hack:
Congratulations! You are finished! If you write more ball effects, I'm sure everybody will gladly take a look at them!
Anyways, the hack:
Code:
Type A1 68 0A 79 00 2A 00 D1 04 22 05 31 at 0806c014. Activate the hack by typing 29 98 at 0803DC52.
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/3/3e/Bag_Sport_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/3/3e/Bag_Sport_Ball_Sprite.png)
- Implement custom particles
- Discover how to write custom animations
- Come up with a solution for the Heavy Ball
- Think of a way to create a ball that catches trainer's pokemon
- Finish the givepokemon hack to include the moveset
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/5/55/Bag_Premier_Ball_Sprite.png)
![[PokeCommunity.com] Pokéball hacking guide [PokeCommunity.com] Pokéball hacking guide](https://archives.bulbagarden.net/media/upload/5/55/Bag_Premier_Ball_Sprite.png)
- JPAN, for the original research and his tutorial that actually got me into asm
- knizz, for his disassembly (if you haven't heard about it yet, it's a must-have for any asm hacker: link) and infinite amount of help, with finding tables, answering all my dumb questions, and even answering most of my advanced questions
- Danills for the original code
- GoGo, for pushing me to finish this
- Bela, for drawing the balls
- Jambo51, for the idea of the givepokemon hack
- Mat (bond697), for trying to help danills fix a major issue with this. Although the reason for the crash turned out to be something else, He appreciated his help and he learned something
- Kearnseyboy6, for code
- Ghoulslash, for code
Last edited: