The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Creative Discussions > Emulation & ROM Hacking > Research & Development
Sign Up Rules/FAQ Live Battle Blogs Mark Forums Read

Notices

Research & Development Got a well-founded knack with ROM hacking? Love reverse-engineering the Pokémon games? Or perhaps you love your assembly language. This is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!
New threads in this forum are to be approved by a moderator before they are displayed. The thread revival limit does not apply here.


Reply
 
Thread Tools
  #26    
Old July 13th, 2011, 09:55 PM
JPAN
pokemon rom researcher
 
Join Date: Dec 2008
I believe I have the answer to this question.

BattleScript 0xef is the pokeball catch routine. It is used whenever a ball is thrown, and depending on several checks, jumps to the script best equiped to handle the situation. Near the beginning, it makes three checks to check for situations where the outcome is always the same.


Starting at at 0802D452, we have:
  • the ghost battle check; continues to the script at 0x081D9Ad1
  • the trainer battle check; contiu 0x081D9AC1
  • the fake battle check; continues to the script at 0x081D9A88
With a small bypass near that area, we can use the ghost script (that has nothing related to the ghost battle in it) to prevent capture of a pokemon when a certain flag, variable or another address in the RAM has the desired value. The code is presented below:
Code:
Catch_me_not:  ldr r0, num_to_check /*can be anything you want, like flags, variables or addresses. Here, we'll use addresses*/
    ldrb r0, [r0]
    cmp r0, #0x1 /*or any other value you want*/
    bne return_to_normal
    ldr r1, battleFlags
    ldr r1, [r1]
    ldr r0, afterGhostAddr
    bx r0
 
return_to_normal: ldr r1, battleFlags
     ldr r1, [r1]
     ldr r0, ghostCheckAddr
     bx r0
 
num_to_check: .word 0x020370c0 /*var 8004 address, in this example*/
battleFlags: .word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr: .word 0x0802d457
In the attachment, you have the compiled version of this code, as well as the source that contains a variable access and a flag access code, commented. For those versions, replace num_to_check with the number of the flag/variable you want.

Note: There was a typo on the commented code, on the Load variable commented function: the address should be 0x0806e569, not 0x0806e568.
Attached Files
File Type: zip Not Catching Pokemon.zip‎ (978 Bytes, 30 views)
__________________
Here are the links for my work


Currently working on:
Battle Script Documentation
Another large project

Last edited by JPAN; July 14th, 2011 at 07:58 AM. Reason: Typo in the code
Reply With Quote
  #27    
Old July 14th, 2011, 07:11 AM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by JPAN View Post
I believe I have the answer to this question.

BattleScript 0xef is the pokeball catch routine. It is used whenever a ball is thrown, and depending on several checks, jumps to the script best equiped to handle the situation. Near the beginning, it makes three checks to check for situations where the outcome is always the same.

Starting at at 0802D452, we have:
  • the ghost battle check; continues to the script at 0x081D9Ad1
  • the trainer battle check; contiu 0x081D9AC1
  • the fake battle check; continues to the script at 0x081D9A88
With a small bypass near that area, we can use the ghost script (that has nothing related to the ghost battle in it) to prevent capture of a pokemon when a certain flag, variable or another address in the RAM has the desired value. The code is presented below:
Code:
Catch_me_not:  ldr r0, num_to_check /*can be anything you want, like flags, variables or addresses. Here, we'll use addresses*/
    ldrb r0, [r0]
    cmp r0, #0x1 /*or any other value you want*/
    bne return_to_normal
    ldr r1, battleFlags
    ldr r1, [r1]
    ldr r0, afterGhostAddr
    bx r0
 
return_to_normal: ldr r1, battleFlags
     ldr r1, [r1]
     ldr r0, ghostCheckAddr
     bx r0
 
num_to_check: .word 0x020370c0 /*var 8004 address, in this examle*/
battleFlags: .word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr: .word 0x0802d457
In the attachment, you have the compiled version of this code, as well as the source that contains a variable access and a flag access code, commented. For those versions, replace num_to_check with the number of the flag/variable you want.
I tried it out, but haven't gotten it to work. Here's the code I'm using:

Code:
.thumb
.align 2

Catch_me_not: 	ldr r0, =00007015
				bl	LoadVariable
				cmp r0, #0x01
				bne return_to_normal
				ldrb r0, [r0]
				cmp r0, #0x1
				bne return_to_normal
				ldr r1, battleFlags
				ldr r1, [r1]
				ldr r0, afterGhostAddr
				bx r0
				
return_to_normal:	ldr r1, battleFlags
					ldr r1, [r1]
					ldr r0, ghostCheckAddr
					bx r0

battleFlags:	.word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr:	.word 0x0802d457


LoadVariable:	ldr r1, ld_Var_addr
				bx r1
ld_Var_addr:	.word 0x0806e568
Unfortunately, the game freezes any time I try to use a Poke Ball at all, whether a variable is set or not, freezing on [player] used Poke Ball!

With the code, I'm trying to use variable 0x7015. I placed the code at offset 0x08874120.

At offset 0x0802D484 where the original bytes were:
Code:
4C 2B 02 02
I replaced them with a pointer to the new code:

Code:
21 41 87 08

And at offset 0x0802D454 where the original bytes were:

Code:
01 68
I replaced them with:

Code:
00 47
__________________

Last edited by metapod23; July 14th, 2011 at 09:41 AM.
Reply With Quote
  #28    
Old July 14th, 2011, 08:02 AM
JPAN
pokemon rom researcher
 
Join Date: Dec 2008
Quote:
Originally Posted by metapod23 View Post
I tried it out, but haven't gotten it to work.
Sorry about that, copy-paste function from an early code that was bugged, the line
Code:
ld_Var_addr: .word 0x0806e568
should read
Code:
ld_Var_addr: .word 0x0806e569
That way, it should work.
__________________
Here are the links for my work


Currently working on:
Battle Script Documentation
Another large project
Reply With Quote
  #29    
Old July 14th, 2011, 09:41 AM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by JPAN View Post
Sorry about that, copy-paste function from an early code that was bugged, the line
Code:
ld_Var_addr: .word 0x0806e568
should read
Code:
ld_Var_addr: .word 0x0806e569
That way, it should work.
It doesn't freeze, but the Pokemon isn't dodging the Poke Ball for me either when the variable is set. Not sure if it's something I'm doing wrong.
__________________
Reply With Quote
  #30    
Old July 14th, 2011, 10:38 AM
Masou Shoujo Haruna's Avatar
Masou Shoujo Haruna
Don't touch me, I'm sterile
 
Join Date: Jun 2011
Gender: Female
Nature: Naive
it worked for me, though i used JPAN's already made .out file
Attached Images
File Type: png Pokemon - Fire Red.png‎ (7.7 KB, 79 views)
Reply With Quote
  #31    
Old July 14th, 2011, 10:58 AM
ShadowMrk's Avatar
ShadowMrk
The Ghost
 
Join Date: Jul 2010
Location: In a box...that has internet
Age: 18
Gender: Male
Nature: Gentle
It amazes me how fast JPAN did that. I salute you, JPAN. I have alot to learn... :\
Reply With Quote
  #32    
Old July 14th, 2011, 11:41 AM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by Masou Shoujo Haruna View Post
it worked for me, though i used JPAN's already made .out file
Maybe someone can explain to me what's wrong with my code then ... I suspect now that I have more than I need in there, but it still isn't working.

From how I read it, it seems to compare the variable to the value, and if it's not equal, goes to the return_to_normal instruction.

But the instruction following that (if it doesn't take you to return_to_normal) appears to be exactly the same, so I guess I don't understand where the direction is to take you to the uncatchable code if they are equal. It may be that I'm writing it wrong or understanding what I'm supposed to do wrong.
__________________
Reply With Quote
  #33    
Old July 14th, 2011, 12:19 PM
JPAN
pokemon rom researcher
 
Join Date: Dec 2008
Quote:
Originally Posted by metapod23 View Post
I tried it out, but haven't gotten it to work. Here's the code I'm using:
Code:
.thumb
.align 2
 
Catch_me_not:     ldr r0, =00007015
                bl    LoadVariable
                cmp r0, #0x01
                bne return_to_normal
                ldrb r0, [r0]
                cmp r0, #0x1
                bne return_to_normal
                ldr r1, battleFlags
                ldr r1, [r1]
                ldr r0, afterGhostAddr
                bx r0
 
return_to_normal:    ldr r1, battleFlags
                    ldr r1, [r1]
                    ldr r0, ghostCheckAddr
                    bx r0
 
battleFlags:    .word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr:    .word 0x0802d457
 
 
LoadVariable:    ldr r1, ld_Var_addr
                bx r1
ld_Var_addr:    .word 0x0806e569
All the underlined code is what's throwing the code off. The value returned by the variable loader is the value to compare right after. After that, loading from R0 would be loading from address 1, a BIOS address. That address value (if even loaded) will most likely not be 1, so the second check fails.
That second check is used only on the "address reading" version of the code. Clean it off, and it should work.
__________________
Here are the links for my work


Currently working on:
Battle Script Documentation
Another large project
Reply With Quote
  #34    
Old July 14th, 2011, 12:23 PM
Mr.Pkmn
Someone making a pokemon hack
 
Join Date: May 2008
Quote:
Originally Posted by JPAN View Post
With a small bypass near that area, we can use the ghost script (that has nothing related to the ghost battle in it) to prevent capture of a pokemon when a certain flag, variable or another address in the RAM has the desired value.
Hey JPAN, can you do the same with the trainerbattle command? Making a check to activate the battle tower bit that starts an item forbidden trainer/wild pokemon battle. It's not the same as an uncatchable pokemon, but that would also allow "special", multiplayer-like trainer battles...
Reply With Quote
  #35    
Old July 14th, 2011, 03:33 PM
JPAN
pokemon rom researcher
 
Join Date: Dec 2008
Quote:
Originally Posted by Mr.Pkmn View Post
Hey JPAN, can you do the same with the trainerbattle command? Making a check to activate the battle tower bit that starts an item forbidden trainer/wild pokemon battle. It's not the same as an uncatchable pokemon, but that would also allow "special", multiplayer-like trainer battles...
Not sure if it's this, but in the same way we disable the capture, we can disable the item usage. Before the bag is open, a rather large function that deals with input from the Fight-Bag-Party-run box eventually reaches a check for the item-denying battles. At 080143D4, that check starts, and when successful, continues to 0x080143E0, that loads the script to execute. Placing a bypass there, we get a code amost identical to the one for the capture prevention. The code and compiled address version are included in the attachment. Right now, it's loading from 0x020370c0 (var 8004 address), so change it and compile it as you need it.
Attached Files
File Type: zip Prevent Items.zip‎ (906 Bytes, 28 views)
__________________
Here are the links for my work


Currently working on:
Battle Script Documentation
Another large project
Reply With Quote
  #36    
Old July 14th, 2011, 05:40 PM
war rock exe's Avatar
war rock exe
Pokemon Colosseum Remaker!!
 
Join Date: Dec 2009
Location: wouldn't you like to know?
Age: 16
Gender: Male
Nature: Hardy
So does this create it possible 2 catch trainers pokemon?
__________________
POKÈMON COLOSSEUM TRILOGY FOR RMXP!! COMING THIS SUMMER!
STATUS; BETA 1 70%
Reply With Quote
  #37    
Old July 14th, 2011, 11:27 PM
Deokishisu's Avatar
Deokishisu
Mr. Magius
 
Join Date: Feb 2006
Location: If I'm online, it's a safe bet I'm at a computer.
Gender: Male
Nature: Relaxed
^Just what I was about to ask.

Since we have the code for what prevents a capture, can we enable a capture during a trainer battle?

I can already foresee a problem with this though. I'm pretty sure capturing an enemy trainer's Pokemon immediately ends the battle, not to mention the fact that it'd be difficult to make only a certain Pokemon from an enemy trainer's roster catchable.

So I guess the question is not can an opponent's Pokemon be captured, but can it be implemented well?
Reply With Quote
  #38    
Old July 15th, 2011, 04:04 AM
Mr.Pkmn
Someone making a pokemon hack
 
Join Date: May 2008
Quote:
Originally Posted by JPAN View Post
Not sure if it's this, but in the same way we disable the capture, we can disable the item usage. Before the bag is open, a rather large function that deals with input from the Fight-Bag-Party-run box eventually reaches a check for the item-denying battles. At 080143D4, that check starts, and when successful, continues to 0x080143E0, that loads the script to execute. Placing a bypass there, we get a code amost identical to the one for the capture prevention. The code and compiled address version are included in the attachment. Right now, it's loading from 0x020370c0 (var 8004 address), so change it and compile it as you need it.
Crashes when the bag is selected. It works if i put 0x080143d9 as the pointer (but obviously this is permanent).

Also, while it's useful to have only items disabled (eg: wild battle) the other things (no experience gained, no switch prompt after ko) are activated if 0x02022B4D is 0x1, so you could integrate these other routines if the variable has an another value.
Reply With Quote
  #39    
Old July 15th, 2011, 09:01 AM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by JPAN View Post
All the underlined code is what's throwing the code off. The value returned by the variable loader is the value to compare right after. After that, loading from R0 would be loading from address 1, a BIOS address. That address value (if even loaded) will most likely not be 1, so the second check fails.
That second check is used only on the "address reading" version of the code. Clean it off, and it should work.
I think I finally got it to work! Thanks JPAN! I'll credit you for the code in my hack's thread.

One last thing: Isn't there any way to include the poke ball thrown animation and the dodge animation as well? This does the trick, but shouldn't you be able to load the address that plays those animations as well?
__________________
Reply With Quote
  #40    
Old July 15th, 2011, 09:36 AM
Mr.Pkmn
Someone making a pokemon hack
 
Join Date: May 2008
Quote:
Originally Posted by Mr.Pkmn View Post
Crashes when the bag is selected. It works if i put 0x080143d9 as the pointer (but obviously this is permanent).
Uh I've fixed this, now the routine is working using writebytetooffset with a custom ram address to turn off items. Still would like to see a "complete" battle tower-like routine
Reply With Quote
  #41    
Old December 24th, 2011, 10:19 AM
dʒɹʌmpfʼt̚'s Avatar
dʒɹʌmpfʼt̚
alors on danse
Community Supporter Tier 5
 
Join Date: Sep 2011
Location: bar'jách
Age: 17
Gender: Male
Nature: Impish
Quote:
Originally Posted by metapod23 View Post
I think I finally got it to work! Thanks JPAN! I'll credit you for the code in my hack's thread.

One last thing: Isn't there any way to include the poke ball thrown animation and the dodge animation as well? This does the trick, but shouldn't you be able to load the address that plays those animations as well?
Sorry to revive this thread, but I think that I *may* have "found" something.

I was screwing around one afternoon, and I was looking at the Clock Routine (Special 0x9D in Emerald, I believe), one that has actual pictures and animations and stuff, and I had found the address.

Then I looked at the actual code (in PKSV, because it's not like I was serious), and it was suspiciously short (only about ten or fifteen instructions), and most of them were the branch-with-link instructions or whatever you call them, to some addresses in the ROM straight into the six-digit adresses (around 0x700000) from the five-digits (around 0xB0000) where the specials are. I was also using the actual machine-code-to-assembly .pdf I found on the internets, and so I'm pretty sure it's branch to God knows where.

Just a thought.
__________________

could you ····ing not
·
Reply With Quote
  #42    
Old March 4th, 2012, 06:50 AM
Cosmic Power
Treehugger
 
Join Date: Mar 2012
Location: Salem, MA
Gender: Female
Nature: Careful
Send a message via Skype™ to Cosmic Power
an uncatchable pokemon is actually a pretty good research.. we'll check up on it later on ScriptEd.
__________________
"上に来て、さあ!あなたが行っているどこで狂った祭りの人々が見ていない場合、私はあなたのすべてを微しなければならないつもりだ!"
"-Jō ni kite, sā! Anata ga okonatte iru doko de kurutta matsuri no hitobito ga mite inai baai, watashi wa anata no subete o bi shinakereba naranai tsumorida! "
"Come on, come on! If you crazy festival people don't watch where you're going, I'm gonna have to fine ALL of you!" -Barry
----
FC: 1893-5923-7026
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
Minimum Characters Per Post: 25



All times are UTC -8. The time now is 10:29 PM.


Style by Nymphadora, artwork by Sa-Dui.
Like our Facebook Page Follow us on Twitter © 2002 - 2014 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2014 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.