Thread: Development: Uncatchable Pokemon
View Single Post
  #27    
Old July 14th, 2011 (7: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 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
    __________________
    Reply With Quote