Go Back   The PokéCommunity Forums > ROM Hacking > Tools, Tutorials & Resources
Reload this Page [Tutorial] Pokéball hacking guide

Notices
For all updates, view the main page.

Tools, Tutorials & Resources Various tools to help you develop your hacks can be found here.
New threads in this forum are to be approved by a moderator before they are displayed.



Reply
 
Thread Tools
  #1    
Old May 13th, 2014 (07:08 AM). Edited February 2nd, 2015 by daniilS.
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 15
Gender: Male
Posts: 357
Pokéball Hacking Guide


Introduction
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!


Requirements
  • A hex editor (I use Hex Workshop)
  • A way to find free space in your rom; FSF recommended
  • Images for your balls
  • A way to insert those images (I use nse 2.1)
  • Basic hex editing/assembly knowledge. I do assume you know how to assemble a routine and place an inverted pointer +1 to it.


Step 1: Dealing with the pokemon data limiters
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
Spoiler:
IMPORTANT: If your hack is already released, this will screw up pokemon already in pokeballs: they will all get the ball*2, f.e. a poke in a pokeball will become a poke in a friend ball. This may look like a minor bug at first, but if the ball index is high, the doubled index may not exist, resulting in a crash upon throwing the ball. So, if your hack is already released, you can do three things:
  • Force the players to restart the save or not to use pokemon caught in balls with high indexes previously
  • Only add up to three balls
  • Expand the data like mentioned, and then double all existing ball indexes. Then inflate the catch rate table at part 3 and the conversion table at step four part 1. So instead of [original entry 1][original entry 2]...[entry 12][custom entry 1][custom entry 2]..., they will become [custom/empty entry 1][original entry 1][custom/empty entry 2][original entry 2][custom/empty entry 3][original entry 3]. That should fix the problem.

And you're done! Move on to step 2.


Step 2: Inserting the catch rate routine
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:
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

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:
  • 0802D500
  • 0802D544
  • 0802D6A0
  • 0802D71C
  • 0802D7B8
  • 080EF4B4
  • 080EF4DC
  • 080EF674
  • 080EF9AC
  • 080F0368
You probably don't know what the pokeball index is. Well, it's an unused value in the item structure, and afaik you can only change it with the tool "Item manager". Sadly, it doesn't have ini support, so if you repointed the items, do this:
Take the index number of the item, multiply it by 0x2C, then add to it the offset of the item data and finally, add to that 0x1B, and you have the pokeball index field. Using either method, you need to put there the pokeball number. For regular balls, it is equal to the index number; for custom balls, just continue counting up. Also, set your balls' field usage to 0, battle usage to 2, and code to 80A1E1D. (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.


Step 3: Making the balls do something
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 0802D52C to FF. Then, look at the table at 0802D54C. It has a pointer to a routine for every pokeball starting from 6. At 0802D548 you can see a pointer to the table; repoint it somewhere else. Now, to give a ball a certain catch rate, you must write a routine to load it into r4, and exit to 0802D7A2. Then place a pointer to that routine in the table.
Some example routines:
Quick ball:
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, #30
ender:
	ldr r0, catchratecalcfunction
	mov pc, r0
	
.align 2
	battleturncounter:	.word 0x03004fa3
	catchratecalcfunction:	.word 0x0802d62a

Dusk ball:
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global catchratebyareaortimeofday

main:
	ldr r0, time
	ldrb r0, [r0, #0x0]
	cmp r0, #0x6
	blt night
	cmp r0, #0x15
	bge night
day:
	mov r4, #10
	ldr r0, maptype
	ldrb r0, [r0]
	cmp r0, #0x4
	bne ender
night:
	mov r4, #35
ender:
	ldr r0, catchratecalcfunction
	mov pc, r0

.align 2
	time:			.word 0x03005542
	maptype:		.word 0x02036e13
	catchratecalcfunction:	.word 0x0802d62a

Park ball; this one uses a modified safari ball routine, and will get another piece of code later:
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

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 (add 0x28 to the item offset and change the word you find there). 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

After inserting the routines, take your ball index, substract six of it, multiply by four, and add to the new offset of the table. Place the offset where you inserted your routine there.
Here comes the part JPAN didn't document: animations. And be prepared, it's a long part.


Step four: Expanding the throwing graphics part 1
The conversion table
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:
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

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:
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)
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
Code:
FF 04 03 01 00 02 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
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.


Step four: Expanding the throwing graphics part 2
The image and palette tables
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:
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.)
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:
Code:
word		pointer to palette
halfword	tag of ball
halfword	filler (0000)
We just started repointing, and we still have a long way to go.


Step four: Expanding the throwing graphics part 3
Repointing generic tables
Here comes a list of the tables:
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
After you have done this, you can finally assign particles and animations to your balls.


Step four: Expanding the throwing graphics part 4
The particle and animation tables
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.


Step five: Additional effects part 1
Healing pokemon after capture
This effect was written by me for the Heal Ball:
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
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.


Step five: Additional effects part 2
Retaining pokeballs
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:
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
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.


Step five: Additional effects part 3
The givepokemon hack
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:
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.
Congratulations! You are finished! If you write more ball effects, I'm sure everybody will gladly take a look at them!


To-do list
  • 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


Credits
  • 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
  • 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 me fix a major issue with this. Although the reason for the crash turned out to be something else, I appreciate his help and I learned something

__________________
Reply With Quote
  #2    
Old May 13th, 2014 (11:45 PM).
~Andrea's Avatar
~Andrea ~Andrea is offline
 
Join Date: Oct 2012
Gender: Male
Posts: 144
For everyone use Ruby (me x'D)

0802B78E catch_rate_calc_function
0202E83F map_tipe (out,in,secret_base,caves)
030042F3 battle_turn_counter
083C5564 item_data
080C52CE heal_poke
__________________
Reply With Quote
  #3    
Old May 14th, 2014 (08:43 PM).
Sniper's Avatar
Sniper Sniper is offline
ふゆかい
 
Join Date: Nov 2013
Location: Philippines
Gender: Male
Nature: Quiet
Posts: 1,401
Great tutorial! Really, really thank you for sharing! This is amazing! (:
__________________
Reply With Quote
  #4    
Old May 14th, 2014 (10:52 PM).
DaisukE's Avatar
DaisukE DaisukE is offline
God is busy...May i help you
 
Join Date: May 2013
Location: India
Gender: Male
Nature: Lonely
Posts: 122
Really good tutorial..... Easy to understand ...
__________________
Búrñiñg Émøtiøn§
Reply With Quote
  #5    
Old May 15th, 2014 (01:51 PM).
Lost Heart's Avatar
Lost Heart Lost Heart is offline
Pirate Empress
Gold Tier
 
Join Date: Mar 2010
Location: Amazon Lily
Age: 18
Gender: Female
Nature: Naughty
Posts: 1,203
This is great!
You do a wonderful job of explaining such a complex task!

EDIT:

To use the givepokemon hack on LeafGreen 1.0, just do everything you would for FireRed 1.0.
The offsets and ASM are unchanged.
__________________
#radreds
Reply With Quote
  #6    
Old May 16th, 2014 (01:57 AM).
kearnseyboy6's Avatar
kearnseyboy6 kearnseyboy6 is offline
Aussie's Toughest Mudder
 
Join Date: Dec 2008
Posts: 280
Quote:
first turn:
add r4, #30
I assume for gen v mechanics, we simply make it #40 for 5x the chance?

Awesome tut btw
__________________
HOLIDAYING CURRENTLY!!
Reply With Quote
  #7    
Old May 16th, 2014 (02:41 AM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 15
Gender: Male
Posts: 357
Thanks for all the positive feedback guys!
Quote originally posted by kearnseyboy6:
I assume for gen v mechanics, we simply make it #40 for 5x the chance?

Awesome tut btw
Yeah, and now I look at it I don't remember why it isn't a simple mov.
__________________
Reply With Quote
  #8    
Old May 16th, 2014 (04:59 AM).
kearnseyboy6's Avatar
kearnseyboy6 kearnseyboy6 is offline
Aussie's Toughest Mudder
 
Join Date: Dec 2008
Posts: 280
Hey,

Can you please guide me if this level ball works?

Spoiler:
.text
.align 2
.thumb
.thumb_func
.global levelball

main:
ldr r0, yourpokelevel
ldrb r0, [r0]
ldr r4, wildpokelevel
ldrb r4, [r4]
cmp r0, r4
bhi timestwo
mov r4, #10
bne ender

timestwo:
lsr r0, r0, #1
cmp r0, r4
bhi timesfour
mov r4, #20
bne ender

timesfour:
lsr r0, r0, #1
cmp r0, r4
bhi timeseight
mov r4, #40
bne ender

timeseight:
mov r4, #80
bne ender

ender:
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
yourpokelevel: .word 0x02024284
Wildpokelevel: .word 0x02024080
catchratecalcfunction: .word 0x0802d62a


I sourced it from http://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9_Ball#Level_Ball

This is my very first branching asm, would like some feedback please ?

It basically checks your level against theirs, if its lower x1
If its higher it branches and halves your level, then checks again. if lower x2 (less than double but higher than wild)
If its higher again it will half, then check again. If lower x4 (more than double but less than quadruple)
If its higher it branches and moves x8. How does that sound?
__________________
HOLIDAYING CURRENTLY!!
Reply With Quote
  #9    
Old May 16th, 2014 (07:17 AM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 15
Gender: Male
Posts: 357
Quote originally posted by kearnseyboy6:
Hey,

Can you please guide me if this level ball works?

Spoiler:
.text
.align 2
.thumb
.thumb_func
.global levelball

main:
ldr r0, yourpokelevel
ldrb r0, [r0]
ldr r4, wildpokelevel
ldrb r4, [r4]
cmp r0, r4
bhi timestwo
mov r4, #10
bne ender

timestwo:
lsr r0, r0, #1
cmp r0, r4
bhi timesfour
mov r4, #20
bne ender

timesfour:
lsr r0, r0, #1
cmp r0, r4
bhi timeseight
mov r4, #40
bne ender

timeseight:
mov r4, #80
bne ender

ender:
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
yourpokelevel: .word 0x02024284
Wildpokelevel: .word 0x02024080
catchratecalcfunction: .word 0x0802d62a


I sourced it from http://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9_Ball#Level_Ball

This is my very first branching asm, would like some feedback please ?

It basically checks your level against theirs, if its lower x1
If its higher it branches and halves your level, then checks again. if lower x2 (less than double but higher than wild)
If its higher again it will half, then check again. If lower x4 (more than double but less than quadruple)
If its higher it branches and moves x8. How does that sound?
Looks nice! However, this may cause some issues. For example, if your pokémon is level 17 (10001b) and the wild pokémon is level 2 (10b), right-shifting 17 three times will give 2 (10b), and that isn't higher than the wildpokelevel. So I would left-shift the wildpokelevel instead.
Also you forgot to add 84 to yourpokelevel, and I don't really get why you're using bne instead of simple b, and the last bne has no real use too, but good job apart from that!
__________________
Reply With Quote
  #10    
Old May 18th, 2014 (02:37 AM).
kearnseyboy6's Avatar
kearnseyboy6 kearnseyboy6 is offline
Aussie's Toughest Mudder
 
Join Date: Dec 2008
Posts: 280
Cool so I'm definitely improving my asm skills.

I made a test code for heavy ball, I haven't applied your tut yet so I haven't tested it but it looks reasonable. The main problem with the heavy ball is this hack let's you set a value in r4 and then C*R4, so R4 is basically the ball bonus. Heavy ball doesn't multiply... it adds eg (C+40). So without modifying the routine we could be stuck.

But I think what if we could always have (C+40) = (C*R4)? We simply have algebra to deal with. So our R4 will always mathematically be:

(C+40)/C right? I think so.

Luckily Knizz has found a division routine that's lets me code this to one decimal place. Any way here it is:

Spoiler:
.text
.align 2
.thumb
.thumb_func
.global levelball

main:
ldr r0, pokeindex
ldrh r0, [r0]
mov r1, #0x24
mul r0,r1
ldr r1, pokedextable
add r1, r0, r1
add r1, r1, #0xE
ldrh r1, [r1] \\r1 now contains the weight in kg-1
ldr r2, stattable
ldr r0, pokeindex
ldrh r0, [r0]
mov r4, #0x1C
mul r0, r4
add r2, r2, r0
ldrb r2, [r2] \\r2 loads the catchrate of the poke
cmp r1, #0x1000
bhi plusforty
cmp r1, #0xBB8
bhi plusthirty
cmp r1, #0x7D0
bhi plustwenty
cmp r2, #20 \\checks to see if catchrate <20 (hence 0 chance)
bhi minustwenty
mov r4, #0
b ender

plusforty:
mov r0, #0x0
add r0, r2, #40
mov r1, r2
b 0x081E4018
mov r3, r0 \\integer stored in r3
mov r0, #0x0
add r0, r2, #40
mov r1, r2
b 0x081E4684 \\remainder stored in r0
b intdivision

plusthirty:
mov r0, #0x0
add r0, r2, #30
mov r1, r2
b 0x081E4018
mov r3, r0
mov r0, #0x0
add r0, r2, #30
mov r1, r2
b 0x081E4684
b intdivision

plustwenty:
mov r0, #0x0
add r0, r2, #20
mov r1, r2
b 0x081E4018
mov r3, r0
mov r0, #0x0
add r0, r2, #20
mov r1, r2
b 0x081E4684
b intdivision

minustwenty:
mov r0, #0x0
sub r0, r2, #20
mov r1, r2
b 0x081E4018
mov r3, r0
mov r0, #0x0
sub r0, r2, #20
mov r1, r2
b 0x081E4684
b intdivision

intdivision
mov r4, #0
mov r1, #10
mul r0, r1
mov r1, r2 \\This load 10x the remainder to give an integer when divided
b 0x081E4018 \\divides 10x remainder by C, always <10 due to math laws
mul r3, r1
add r4, r0, r3 \\adds the remainder and whole together
b ender

ender:
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
pokeindex: .word 0x0202077E
pokedextable: .word 0x08735100
stattable: .word 0x08722600
catchratecalcfunction: .word 0x0802d62a


So this is still my 2nd asm script so I'm 100% sure there are inefficiencies and it's probably wrong, but maybe this could help with the heavy ball solution?
__________________
HOLIDAYING CURRENTLY!!
Reply With Quote
  #11    
Old September 29th, 2014 (10:12 PM).
pokemontutorialTV's Avatar
pokemontutorialTV pokemontutorialTV is offline
 
Join Date: Feb 2014
Location: Germany, K-Town
Gender: Male
Nature: Calm
Posts: 39
Send a message via Skype™ to pokemontutorialTV
The givepokemonhack works, but if I start a battle against a trainer, the game freezes, when the opponent throws the ball.
__________________
Making Youtube Videos about Pokémon.
_______________________________________________
Pokémon Zoisit:

_______________________________________________
My Youtube Channel with over 1000 videos to Pokémon: http://www.youtube.com/user/pokemontutorialTV
Reply With Quote
  #12    
Old September 30th, 2014 (03:18 AM). Edited November 20th, 2014 by GoGoJJTech.
GoGoJJTech's Avatar
GoGoJJTech GoGoJJTech is offline
http://GoGoJJTech.com (WIP!)
Silver Tier
 
Join Date: Nov 2012
Location: Earth
Age: 16
Gender: Female
Nature: Jolly
Posts: 1,977
Quote originally posted by pokemontutorialTV:
The givepokemonhack works, but if I start a battle against a trainer, the game freezes, when the opponent throws the ball.
That means you either inserted incorrectly or corrupted something.

EDIT: daniilS explained what could happen to cause the bug.
__________________
I believe in Jesus Christ my Savior. If you do too, and aren't scared to admit it, then copy and paste this into your signature.
The SoulSilver Music Patch - The Black Music Patch - Mega-Huge Sappy Tutorial
Romhack.me Profile - Pokecommunity Profile - Pokemonhackersonline Profile - Youtube Channel

Join us in the romhacking chat
Pokémon Platinum Red and Blue
Reply With Quote
  #13    
Old September 30th, 2014 (11:06 AM).
pokemontutorialTV's Avatar
pokemontutorialTV pokemontutorialTV is offline
 
Join Date: Feb 2014
Location: Germany, K-Town
Gender: Male
Nature: Calm
Posts: 39
Send a message via Skype™ to pokemontutorialTV
No i dont really think so. The problem i saw is, that in german rom the "byte commands" used at (translated offset 086BF78) are diffrent from the english rom.
I show you the problem (both original files):

German: 20 1C FD F7 C1 FC A1 68 0A 78 01 31 A1 60 0A 4C 00 90 01 92 30 1C 49 46 [...]
English: 20 1C FD F7 7B FC A1 68 0A 78 01 31 A1 60 0A 4C 00 90 01 92 30 1C 49 46 [...]

And im 100% sure, that i have made everything right. But i doesnt know really how to fix the problem... I hope you can help me.
__________________
Making Youtube Videos about Pokémon.
_______________________________________________
Pokémon Zoisit:

_______________________________________________
My Youtube Channel with over 1000 videos to Pokémon: http://www.youtube.com/user/pokemontutorialTV
Reply With Quote
  #14    
Old September 30th, 2014 (06:22 PM).
Syrex's Avatar
Syrex Syrex is offline
... Far From Perfect.
Gold Tier
 
Join Date: Jul 2008
Location: Columbus, Ohio
Age: 24
Gender: Male
Nature: Hasty
Posts: 552
Very nice! I was looking for something like this!
__________________

Reply With Quote
  #15    
Old December 13th, 2014 (02:20 AM).
Turtl3Skulll's Avatar
Turtl3Skulll Turtl3Skulll is offline
Blue Turtl3
 
Join Date: Jun 2013
Location: Utah, U.S.A.
Age: 19
Gender: Male
Nature: Bold
Posts: 48
Is there any way you could also give the routine for a Master Ball & a regular Pokeball??
Reply With Quote
  #16    
Old December 13th, 2014 (03:22 AM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 15
Gender: Male
Posts: 357
Quote originally posted by Turtl3Skulll:
Is there any way you could also give the routine for a Master Ball & a regular Pokeball??
Do you mean a routine with fixed catch rate? There is one at heal/cherish ball. Or did I misunderstand?
__________________
Reply With Quote
  #17    
Old December 13th, 2014 (12:05 PM).
Turtl3Skulll's Avatar
Turtl3Skulll Turtl3Skulll is offline
Blue Turtl3
 
Join Date: Jun 2013
Location: Utah, U.S.A.
Age: 19
Gender: Male
Nature: Bold
Posts: 48
Quote originally posted by daniilS:
Do you mean a routine with fixed catch rate? There is one at heal/cherish ball. Or did I misunderstand?
I didn't realize the cherish ball had s standard fixed catch rate, I assume to make another master ball I'd just have to check bulbapedia for the catch rate info on it, or is it different to make one w/ 100% catch rate??
Reply With Quote
  #18    
Old December 13th, 2014 (12:26 PM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 15
Gender: Male
Posts: 357
The masterball is a special case because it skips catch rate calculation completely, but entering 255 as a value should give you no problems unless a poke has a catch rate below 3.
__________________
Reply With Quote
  #19    
Old December 13th, 2014 (03:22 PM).
Turtl3Skulll's Avatar
Turtl3Skulll Turtl3Skulll is offline
Blue Turtl3
 
Join Date: Jun 2013
Location: Utah, U.S.A.
Age: 19
Gender: Male
Nature: Bold
Posts: 48
Alrighty thanks daniilS! I'll use test it out later today.
I wish I'd known how to work this tutorial when it had come out, I think this is flipping awesome, thanks for answer me too:D
Reply With Quote
  #20    
Old December 17th, 2014 (02:42 PM).
Dark Zeta's Avatar
Dark Zeta Dark Zeta is offline
They call me... "The Rod"
 
Join Date: Dec 2014
Location: Mississippi, U.S.
Age: 20
Gender: Male
Nature: Lax
Posts: 20
Do you plan on releasing routines for the apricorn balls as well?
Reply With Quote
  #21    
Old January 10th, 2015 (11:46 AM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 15
Gender: Male
Posts: 357
I've updated the offset of somevar. If anybody is actually using this, please change it, as the first offset may be unsafe to use in some hacks.
__________________
Reply With Quote
  #22    
Old March 1st, 2015 (09:41 PM).
kearnseyboy6's Avatar
kearnseyboy6 kearnseyboy6 is offline
Aussie's Toughest Mudder
 
Join Date: Dec 2008
Posts: 280
For some reason, my extended balls don't have particles assigned in game even when I assign them. I changed all balls to sticks, and it works until I get to new balls.

Any clue?
__________________
HOLIDAYING CURRENTLY!!
Reply With Quote
  #23    
Old March 2nd, 2015 (12:31 AM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 15
Gender: Male
Posts: 357
Quote originally posted by kearnseyboy6:
For some reason, my extended balls don't have particles assigned in game even when I assign them. I changed all balls to sticks, and it works until I get to new balls.

Any clue?
I'd double check step four part three. If that's done correctly, then I can't tell what's wrong without having a look at your rom.
__________________
Reply With Quote
  #24    
Old March 2nd, 2015 (03:57 AM). Edited March 4th, 2015 by kearnseyboy6.
kearnseyboy6's Avatar
kearnseyboy6 kearnseyboy6 is offline
Aussie's Toughest Mudder
 
Join Date: Dec 2008
Posts: 280
Coolio! Got it working, I had particle tags and ball tags using the same tag number which is a big NONO! Thanks Daniils.

Note using Bela's balls in the tutorial you will notice that the balls don't occupy 15 colours. But they all need to be non-black otherwise the particles will be black.

EDIT:
Spoiler:
Here is what I mean for everyone extending:

Fill those black palettes with colours to rid of that horrible black particle!


EDIT 2: That is wrong, they are all tied to the Pal7 ut I have no idea why the extended balls don't work.
__________________
HOLIDAYING CURRENTLY!!
Reply With Quote
  #25    
Old March 9th, 2015 (01:08 AM).
kearnseyboy6's Avatar
kearnseyboy6 kearnseyboy6 is offline
Aussie's Toughest Mudder
 
Join Date: Dec 2008
Posts: 280
Here is a list of Gen II pokeballs and their respective ASM routines:

NOTE: Please change the basestats and pokedex locations in your ROM, they will be different!!

Fast Ball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global fastball

main:
mov r4, #10
bl decrypt
ldr r2, pokemondata
mov r4, #0x1C
mul r0, r4
add r0, r2, r0
ldrb r1, [r0, #0x3]
cmp r0, #0x64
bge correct
pop {r0-r7}
b ender
correct:
pop {r0-r7}
mov r4, #40
ender:
ldr r0, catchratecalcfunction
mov pc, r0

decrypt:
push {r0-r7}
ldr r0, wildpoke
mov r1, #0xB
ldr r2, decryptpoke
bx r2

.align 2
catchratecalcfunction: .word 0x0802D62A
decryptpoke: .word 0x0803FBE9
wildpoke: .word 0x0202402C
pokemondata: .word 0x08722600


Friendball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global friendball

main:
mov r4, #10
bl decrypt
pop {r0-r7}
b ender
ender:
ldr r0, catchratecalcfunction
mov pc, r0

decrypt:
push {r0-r7}
ldr r0, wildpoke
mov r1, #0x20
ldrb r2, ramoff
ldr r3, decryptpoke
bx r3

.align 2
catchratecalcfunction: .word 0x0802D62A
decryptpoke: .word 0x0804037D
ramoff: .word 0x02024098
wildpoke: .word 0x0202402C


Heavyball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global heavyball

main:
ldr r0, pokeindex
ldrh r0, [r0]
mov r1, #0x24
mul r0, r1
ldr r1, pokedextable
add r1, r0, r1
add r1, r1, #0xE
ldrh r1, [r1]
mov r2, #0xC8
lsl r2, #0x1
cmp r1, r2
bhi plusforty
sub r2, r2, #0x64
cmp r1, r2
bhi plusthirty
sub r2, r2, #0x64
cmp r1, r2
bhi plustwenty
b minustwenty

plusforty:
add r5, r5, #40
b ender

plusthirty:
add r5, r5, #30
b ender

plustwenty:
add r5, r5, #20
b ender

minustwenty:
sub r5, r5, #20

ender:
mov r4, #10
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
pokeindex: .word 0x0202077E
pokedextable: .word 0x08735100
stattable: .word 0x08722600
catchratecalcfunction: .word 0x0802d62a


Levelball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global levelball

main:
ldr r0, yourpokelevel
ldrb r0, [r0]
ldr r4, wildpokelevel
ldrb r4, [r4]
cmp r0, r4
bhi timestwo
mov r4, #10
bne ender

timestwo:
lsl r4, r4, #1
cmp r0, r4
bhi timesfour
mov r4, #20
bne ender

timesfour:
lsl r4, r4, #1
cmp r0, r4
bhi timeseight
mov r4, #40
bne ender

timeseight:
mov r4, #80

ender:
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
yourpokelevel: .word 0x020242D8
wildpokelevel: .word 0x02024080
catchratecalcfunction: .word 0x0802d62a


Loveball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global moonball

main:
mov r4, #10
bl decrypt
cmp r0, r4
beq yes
pop {r0-r7}
b ender

yes:
pop {r0-r7}
mov r4, #80
b ender

decrypt:
push {r0-r7}
ldr r0, wildpokelevel
mov r1, #0xB
ldr r2, decryptpoke
bx r2
mov r4, r0
ldr r0, yourpokelevel
ldr r2, decryptpoke
bx r2


ender:
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
wildpokelevel: .word 0x0202402C
catchratecalcfunction: .word 0x0802d62a
decryptpoke: .word 0x0803FBE9
yourpokelevel: .word 0x02024284


Lureball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global fishingball

main:
ldr r0, fishingbyte
ldrb r0, [r0]
cmp r0, #1
beq fishing
mov r4, #10
b ender

fishing:
mov r4, #30

ender:
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
fishingbyte: .word 0x02036E38
catchratecalcfunction: .word 0x0802d62a


Moonball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global moonball

main:
mov r4, #10
bl decrypt
cmp r2, #0x1D
beq yes
cmp r2, #0x1E
beq yes
cmp r2, #0x1F
beq yes
cmp r2, #0x20
beq yes
cmp r2, #0x21
beq yes
cmp r2, #0x22
beq yes
cmp r2, #0x23
beq yes
cmp r2, #0x24
beq yes
cmp r2, #0x28
beq yes
cmp r2, #0x29
beq yes
mov r1, #0x13
lsl r1, #0x4
add r1, #0xB
cmp r2, r1
beq yes
add r1, #0x1
cmp r2, r1
beq yes
mov r1, #0x23
lsl r1, #0x4
add r1, #0xA
cmp r2, r1
beq yes
add r1, #0x1
cmp r2, r1
beq yes
beq yes
pop {r0-r7}
b ender

yes:
pop {r0-r7}
mov r4, #40
b ender

decrypt:
push {r0-r7}
ldr r0, wildpokelevel
mov r1, #0xB
ldr r2, decryptpoke
bx r2


ender:
ldr r0, catchratecalcfunction
mov pc, r0

.align 2
wildpokelevel: .word 0x0202402C
catchratecalcfunction: .word 0x0802d62a
decryptpoke: .word 0x0803FBE9
__________________
HOLIDAYING CURRENTLY!!
Reply With Quote
Reply
Quick Reply

Sponsored Links
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are UTC -8. The time now is 09:31 PM.