Thread: Development: Uncatchable Pokemon
View Single Post
  #27    
Old July 14th, 2011 (07:11 AM). Edited July 14th, 2011 by metapod23.
metapod23's Avatar
metapod23 metapod23 is offline
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Posts: 673
Quote originally posted by JPAN:
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
__________________
Reply With Quote