The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > 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!
Research & Development programs in this forum are subject to moderator approval before they are displayed.

Reply
Click here to go to the first staff post in this thread.  
Thread Tools
  #26    
Old August 7th, 2010, 06:08 PM
JPAN
pokemon rom researcher
 
Join Date: Dec 2008
The disobedience check is part of the BattleScript commands, namely command 0, that checks what the pokemon will do. The actual obedience check is at 0801D438, covering all types of disobedience. The code checks for the obedience flag first, then proceeds to check for badges and levels. I'll post here the relevant piece of code for this matter:
Spoiler:
Code:
ROM:0801D460                 BL      Disobey_byte_check     ;decompiled below, the code that was talked about earlier
ROM:0801D464                 CMP     R0, #0
ROM:0801D466                 BEQ     loc_801D4BE
ROM:0801D468                 LDR     R2, =0x2023BE4
ROM:0801D46A                 LDRB    R1, [R4]
ROM:0801D46C                 MOVS    R0, #0x58
ROM:0801D46E                 MULS    R1, R0
ROM:0801D470                 MOVS    R0, R2
ROM:0801D472                 ADDS    R0, #0x54
ROM:0801D474                 ADDS    R0, R1, R0
ROM:0801D476                 LDR     R0, [R0]
ROM:0801D478                 ADDS    R2, #0x3C
ROM:0801D47A                 ADDS    R1, R1, R2
 
ROM:0801D47C                 BL      Compare_trainer_values ;compares your trainer IDS with the pokemon trainer IDS
ROM:0801D480                 LSLS    R0, R0, #0x18
ROM:0801D482                 CMP     R0, #0
ROM:0801D484                 BEQ     loc_801D4F4 ;the same, is obedient
;from here on it's the badge checks. R6 is the maximum level the pokemon may have
ROM:0801D486                 LDR     R0, =0x827
ROM:0801D488                 BL      Check_active_flag
ROM:0801D48C                 LSLS    R0, R0, #0x18
ROM:0801D48E                 CMP     R0, #0
ROM:0801D490                 BNE     loc_801D4F4 ;earthbadge on = obedience
 
ROM:0801D492                 MOVS    R6, #0xA
ROM:0801D494                 LDR     R0, =0x821
ROM:0801D496                 BL      Check_active_flag
ROM:0801D49A                 LSLS    R0, R0, #0x18
ROM:0801D49C                 CMP     R0, #0
ROM:0801D49E                 BEQ     loc_801D4A2 
 
ROM:0801D4A0                 MOVS    R6, #0x1E
ROM:0801D4A2
ROM:0801D4A2 loc_801D4A2                             ; CODE XREF: Disobedience_check+66j
ROM:0801D4A2                 LDR     R0, =0x823
ROM:0801D4A4                 BL      Check_active_flag
ROM:0801D4A8                 LSLS    R0, R0, #0x18
ROM:0801D4AA                 CMP     R0, #0
ROM:0801D4AC                 BEQ     loc_801D4B0
 
ROM:0801D4AE                 MOVS    R6, #0x32
ROM:0801D4B0
ROM:0801D4B0 loc_801D4B0                             ; CODE XREF: Disobedience_check+74j
ROM:0801D4B0                 LDR     R0, =0x825
ROM:0801D4B2                 BL      Check_active_flag
ROM:0801D4B6                 LSLS    R0, R0, #0x18
ROM:0801D4B8                 CMP     R0, #0
ROM:0801D4BA                 BEQ     loc_801D4BE
 
ROM:0801D4BC                 MOVS    R6, #0x46
ROM:0801D4BE
ROM:0801D4BE loc_801D4BE                             ; CODE XREF: Disobedience_check+2Ej
ROM:0801D4BE                                         ; Disobedience_check+82j
ROM:0801D4BE                 LDR     R5, =0x2023BE4
ROM:0801D4C0                 LDR     R0, =0x2023D6B
ROM:0801D4C2                 MOV     R8, R0
ROM:0801D4C4                 LDRB    R0, [R0]
ROM:0801D4C6                 MOVS    R7, #0x58
ROM:0801D4C8                 MULS    R0, R7
ROM:0801D4CA                 ADDS    R0, R0, R5
ROM:0801D4CC                 ADDS    R0, #0x2A
ROM:0801D4CE                 LDRB    R0, [R0] ;gets pokemon current level
ROM:0801D4D0                 CMP     R0, R6 
ROM:0801D4D2                 BLS     loc_801D4F4 ;if current level <= max level, is obedient
 
ROM:0801D4D4                 BL      RNG_halfword
ROM:0801D4D8                 MOVS    R1, #0xFF
ROM:0801D4DA                 ANDS    R1, R0
ROM:0801D4DC                 MOV     R2, R8
ROM:0801D4DE                 LDRB    R0, [R2]
ROM:0801D4E0                 MOVS    R2, R0
ROM:0801D4E2                 MULS    R2, R7
ROM:0801D4E4                 ADDS    R0, R2, R5
ROM:0801D4E6                 ADDS    R0, #0x2A
ROM:0801D4E8                 LDRB    R0, [R0]
ROM:0801D4EA                 ADDS    R0, R0, R6
ROM:0801D4EC                 MULS    R0, R1
ROM:0801D4EE                 ASRS    R4, R0, #8
ROM:0801D4F0                 CMP     R4, R6
ROM:0801D4F2                 BGE     loc_801D518
ROM:0801D4F4
ROM:0801D4F4 loc_801D4F4                             ; CODE XREF: Disobedience_check+14j
ROM:0801D4F4                                         ; Disobedience_check+24j ...
ROM:0801D4F4                 MOVS    R0, #0
ROM:0801D4F6                 B       loc_801D738
Code:
Disobey_byte_check                      ; CODE XREF: Disobedience_check+28p
ROM:0801D3C0                 PUSH    {R4-R7,LR}
ROM:0801D3C2                 LSLS    R0, R0, #0x18
ROM:0801D3C4                 LSRS    R4, R0, #0x18
ROM:0801D3C6                 MOVS    R0, R4
ROM:0801D3C8                 BL      sub_80751C4
ROM:0801D3CC                 LSLS    R0, R0, #0x18
ROM:0801D3CE                 LSRS    R0, R0, #0x18
ROM:0801D3D0                 CMP     R0, #1
ROM:0801D3D2                 BEQ     loc_801D406
ROM:0801D3D4                 LDR     R0, =0x2023BCE
ROM:0801D3D6                 LSLS    R4, R4, #1
ROM:0801D3D8                 ADDS    R5, R4, R0
ROM:0801D3DA                 LDRH    R0, [R5]
ROM:0801D3DC                 MOVS    R7, #0x64
ROM:0801D3DE                 MULS    R0, R7
ROM:0801D3E0                 LDR     R6, =0x2024284
ROM:0801D3E2                 ADDS    R0, R0, R6
ROM:0801D3E4                 MOVS    R1, #0xB
ROM:0801D3E6                 MOVS    R2, #0
ROM:0801D3E8                 BL      get_party_status     ;get pokemon species
ROM:0801D3EC                 MOVS    R1, 0x19A            ;compares with deoxys
ROM:0801D3F0                 CMP     R0, R1
ROM:0801D3F2                 BEQ     loc_801D414         ; if so, check obedience flag
 
ROM:0801D3F4                 LDRH    R0, [R5]
ROM:0801D3F6                 MULS    R0, R7
ROM:0801D3F8                 ADDS    R0, R0, R6
ROM:0801D3FA                 MOVS    R1, #0xB
ROM:0801D3FC                 MOVS    R2, #0
ROM:0801D3FE                 BL      get_party_status      ; redundant, checks your pokemon again for its species
ROM:0801D402                 CMP     R0, #0x97
ROM:0801D404                 BEQ     loc_801D414           ;if mew, check for obedience
ROM:0801D406
ROM:0801D406 loc_801D406                             ; CODE XREF: Disobey_byte_check+12j
ROM:0801D406                 MOVS    R0, #1
ROM:0801D408                 B       loc_801D42A     ; is obedient, end
ROM:0801D408 ; ---------------------------------------------------------------------------
ROM:0801D40A                 DCB    0
ROM:0801D40B                 DCB    0
ROM:0801D40C dword_801D40C   DCD 0x2023BCE           ; DATA XREF: Disobey_byte_check+14r
ROM:0801D410 dword_801D410   DCD 0x2024284           ; DATA XREF: Disobey_byte_check+20r
ROM:0801D414 ; ---------------------------------------------------------------------------
ROM:0801D414
ROM:0801D414 loc_801D414                             ; CODE XREF: Disobey_byte_check+32j
ROM:0801D414                                         ; Disobey_byte_check+44j
ROM:0801D414                 LDR     R0, =0x2023BCE
ROM:0801D416                 ADDS    R0, R4, R0
ROM:0801D418                 LDRH    R1, [R0]
ROM:0801D41A                 MOVS    R0, #0x64
ROM:0801D41C                 MULS    R0, R1
ROM:0801D41E                 LDR     R1, =0x2024284
ROM:0801D420                 ADDS    R0, R0, R1
ROM:0801D422                 MOVS    R1, #0x50
ROM:0801D424                 MOVS    R2, #0
ROM:0801D426                 BL      get_party_status     ;checks last ribbon, that is the obedience flag, and returns it
ROM:0801D42A
ROM:0801D42A loc_801D42A                             ; CODE XREF: Disobey_byte_check+48j
ROM:0801D42A                 POP     {R4-R7}
ROM:0801D42C                 POP     {R1}
ROM:0801D42E                 BX      R1
0801D4D4 checks one last time if, by chance, the attack will go trough. If not it will proceed to 0x0801d518, where what will the pokemon actually do\say is calculated.
So, several modifications can be made here to change the level a pokemon will become disobedient and in what conditions will it become disobedient.
The location of the obedience flag is actually in the last part of the Ribbon data in the Misc block, the topmost flag (bit 31 of the Ribbon word), but it's only useful for the species listed on the disobedience byte. And as for why Mew\Deoxys only disobey, it's because the chance of attack is determined by a random number (from 0-ff) to be smaller than the max level (that in the byte case is 0).

Edit: If I understood correctly, the code needed here is one that, if a pokemon doesn't have the flag, the pokemon has some chances of attacking, instead of just laying around all the time. With that in mind, I made a code for the occasion
Spoiler:
Code:
.align 2
.thumb
/*to use this code, place 00 49 08 47 at 0x0801d3f4, and the reversed pointer to  where
you put this code at 0x0801d3f8*/
    cmp r0, #0x5
    beq disobey_or_not
    cmp r0, #0x6 
    beq disobey_or_not    /*add more checks here for other pokemon*/
    ldr r1, mew_check
    bx r1
mew_check:   .word 0x0801D403
disobey_or_not: ldr r1, random_addr 
    ldrb r1, [r1]
    mov r0, #0xb4 /*change here the "perform attack" chance. percentage  is r0 divided by 256 times 100 */
    cmp r1, r0 /*aprox 70% chance of not performing an attack*/
    bgt is_obedient
    ldr r0, disobedient_ret_addr
    bx r0
is_obedient:   mov r0, #0x1
    pop {r4-r7,pc}
.hword 0x0000    
random_addr: .word 0x03005000
disobedient_ret_addr: .word 0x0801d415

The trick in that code is that the pokemon will act as if it was obedient every once in a while thanks to the random number stored at 0x03005000.
__________________
Here are the links for my work


Currently working on:
Battle Script Documentation
Another large project

Last edited by JPAN; August 7th, 2010 at 07:30 PM. Reason: Added a ASM code
Reply With Quote
  #27    
Old August 7th, 2010, 07:49 PM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
^ That's an interesting code, JPAN. I might have to try it out. I think it might be useful to have the disobedient Pokemon attack every once in a while. I'll add it to the main page, too.

Oh, and colcolstyles, I'm so pleased with routine you made that I added you to the credits of my hack. I just want you to know that it's appreciated. Thanks again!

Quote:
Originally Posted by JPAN View Post
The disobedience check is part of the BattleScript commands, namely command 0, that checks what the pokemon will do. The actual obedience check is at 0801D438, covering all types of disobedience. The code checks for the obedience flag first, then proceeds to check for badges and levels. I'll post here the relevant piece of code for this matter:
Spoiler:
Code:
ROM:0801D460                 BL      Disobey_byte_check     ;decompiled below, the code that was talked about earlier
ROM:0801D464                 CMP     R0, #0
ROM:0801D466                 BEQ     loc_801D4BE
ROM:0801D468                 LDR     R2, =0x2023BE4
ROM:0801D46A                 LDRB    R1, [R4]
ROM:0801D46C                 MOVS    R0, #0x58
ROM:0801D46E                 MULS    R1, R0
ROM:0801D470                 MOVS    R0, R2
ROM:0801D472                 ADDS    R0, #0x54
ROM:0801D474                 ADDS    R0, R1, R0
ROM:0801D476                 LDR     R0, [R0]
ROM:0801D478                 ADDS    R2, #0x3C
ROM:0801D47A                 ADDS    R1, R1, R2
 
ROM:0801D47C                 BL      Compare_trainer_values ;compares your trainer IDS with the pokemon trainer IDS
ROM:0801D480                 LSLS    R0, R0, #0x18
ROM:0801D482                 CMP     R0, #0
ROM:0801D484                 BEQ     loc_801D4F4 ;the same, is obedient
;from here on it's the badge checks. R6 is the maximum level the pokemon may have
ROM:0801D486                 LDR     R0, =0x827
ROM:0801D488                 BL      Check_active_flag
ROM:0801D48C                 LSLS    R0, R0, #0x18
ROM:0801D48E                 CMP     R0, #0
ROM:0801D490                 BNE     loc_801D4F4 ;earthbadge on = obedience
 
ROM:0801D492                 MOVS    R6, #0xA
ROM:0801D494                 LDR     R0, =0x821
ROM:0801D496                 BL      Check_active_flag
ROM:0801D49A                 LSLS    R0, R0, #0x18
ROM:0801D49C                 CMP     R0, #0
ROM:0801D49E                 BEQ     loc_801D4A2 
 
ROM:0801D4A0                 MOVS    R6, #0x1E
ROM:0801D4A2
ROM:0801D4A2 loc_801D4A2                             ; CODE XREF: Disobedience_check+66j
ROM:0801D4A2                 LDR     R0, =0x823
ROM:0801D4A4                 BL      Check_active_flag
ROM:0801D4A8                 LSLS    R0, R0, #0x18
ROM:0801D4AA                 CMP     R0, #0
ROM:0801D4AC                 BEQ     loc_801D4B0
 
ROM:0801D4AE                 MOVS    R6, #0x32
ROM:0801D4B0
ROM:0801D4B0 loc_801D4B0                             ; CODE XREF: Disobedience_check+74j
ROM:0801D4B0                 LDR     R0, =0x825
ROM:0801D4B2                 BL      Check_active_flag
ROM:0801D4B6                 LSLS    R0, R0, #0x18
ROM:0801D4B8                 CMP     R0, #0
ROM:0801D4BA                 BEQ     loc_801D4BE
 
ROM:0801D4BC                 MOVS    R6, #0x46
ROM:0801D4BE
ROM:0801D4BE loc_801D4BE                             ; CODE XREF: Disobedience_check+2Ej
ROM:0801D4BE                                         ; Disobedience_check+82j
ROM:0801D4BE                 LDR     R5, =0x2023BE4
ROM:0801D4C0                 LDR     R0, =0x2023D6B
ROM:0801D4C2                 MOV     R8, R0
ROM:0801D4C4                 LDRB    R0, [R0]
ROM:0801D4C6                 MOVS    R7, #0x58
ROM:0801D4C8                 MULS    R0, R7
ROM:0801D4CA                 ADDS    R0, R0, R5
ROM:0801D4CC                 ADDS    R0, #0x2A
ROM:0801D4CE                 LDRB    R0, [R0] ;gets pokemon current level
ROM:0801D4D0                 CMP     R0, R6 
ROM:0801D4D2                 BLS     loc_801D4F4 ;if current level <= max level, is obedient
 
ROM:0801D4D4                 BL      RNG_halfword
ROM:0801D4D8                 MOVS    R1, #0xFF
ROM:0801D4DA                 ANDS    R1, R0
ROM:0801D4DC                 MOV     R2, R8
ROM:0801D4DE                 LDRB    R0, [R2]
ROM:0801D4E0                 MOVS    R2, R0
ROM:0801D4E2                 MULS    R2, R7
ROM:0801D4E4                 ADDS    R0, R2, R5
ROM:0801D4E6                 ADDS    R0, #0x2A
ROM:0801D4E8                 LDRB    R0, [R0]
ROM:0801D4EA                 ADDS    R0, R0, R6
ROM:0801D4EC                 MULS    R0, R1
ROM:0801D4EE                 ASRS    R4, R0, #8
ROM:0801D4F0                 CMP     R4, R6
ROM:0801D4F2                 BGE     loc_801D518
ROM:0801D4F4
ROM:0801D4F4 loc_801D4F4                             ; CODE XREF: Disobedience_check+14j
ROM:0801D4F4                                         ; Disobedience_check+24j ...
ROM:0801D4F4                 MOVS    R0, #0
ROM:0801D4F6                 B       loc_801D738
Code:
Disobey_byte_check                      ; CODE XREF: Disobedience_check+28p
ROM:0801D3C0                 PUSH    {R4-R7,LR}
ROM:0801D3C2                 LSLS    R0, R0, #0x18
ROM:0801D3C4                 LSRS    R4, R0, #0x18
ROM:0801D3C6                 MOVS    R0, R4
ROM:0801D3C8                 BL      sub_80751C4
ROM:0801D3CC                 LSLS    R0, R0, #0x18
ROM:0801D3CE                 LSRS    R0, R0, #0x18
ROM:0801D3D0                 CMP     R0, #1
ROM:0801D3D2                 BEQ     loc_801D406
ROM:0801D3D4                 LDR     R0, =0x2023BCE
ROM:0801D3D6                 LSLS    R4, R4, #1
ROM:0801D3D8                 ADDS    R5, R4, R0
ROM:0801D3DA                 LDRH    R0, [R5]
ROM:0801D3DC                 MOVS    R7, #0x64
ROM:0801D3DE                 MULS    R0, R7
ROM:0801D3E0                 LDR     R6, =0x2024284
ROM:0801D3E2                 ADDS    R0, R0, R6
ROM:0801D3E4                 MOVS    R1, #0xB
ROM:0801D3E6                 MOVS    R2, #0
ROM:0801D3E8                 BL      get_party_status     ;get pokemon species
ROM:0801D3EC                 MOVS    R1, 0x19A            ;compares with deoxys
ROM:0801D3F0                 CMP     R0, R1
ROM:0801D3F2                 BEQ     loc_801D414         ; if so, check obedience flag
 
ROM:0801D3F4                 LDRH    R0, [R5]
ROM:0801D3F6                 MULS    R0, R7
ROM:0801D3F8                 ADDS    R0, R0, R6
ROM:0801D3FA                 MOVS    R1, #0xB
ROM:0801D3FC                 MOVS    R2, #0
ROM:0801D3FE                 BL      get_party_status      ; redundant, checks your pokemon again for its species
ROM:0801D402                 CMP     R0, #0x97
ROM:0801D404                 BEQ     loc_801D414           ;if mew, check for obedience
ROM:0801D406
ROM:0801D406 loc_801D406                             ; CODE XREF: Disobey_byte_check+12j
ROM:0801D406                 MOVS    R0, #1
ROM:0801D408                 B       loc_801D42A     ; is obedient, end
ROM:0801D408 ; ---------------------------------------------------------------------------
ROM:0801D40A                 DCB    0
ROM:0801D40B                 DCB    0
ROM:0801D40C dword_801D40C   DCD 0x2023BCE           ; DATA XREF: Disobey_byte_check+14r
ROM:0801D410 dword_801D410   DCD 0x2024284           ; DATA XREF: Disobey_byte_check+20r
ROM:0801D414 ; ---------------------------------------------------------------------------
ROM:0801D414
ROM:0801D414 loc_801D414                             ; CODE XREF: Disobey_byte_check+32j
ROM:0801D414                                         ; Disobey_byte_check+44j
ROM:0801D414                 LDR     R0, =0x2023BCE
ROM:0801D416                 ADDS    R0, R4, R0
ROM:0801D418                 LDRH    R1, [R0]
ROM:0801D41A                 MOVS    R0, #0x64
ROM:0801D41C                 MULS    R0, R1
ROM:0801D41E                 LDR     R1, =0x2024284
ROM:0801D420                 ADDS    R0, R0, R1
ROM:0801D422                 MOVS    R1, #0x50
ROM:0801D424                 MOVS    R2, #0
ROM:0801D426                 BL      get_party_status     ;checks last ribbon, that is the obedience flag, and returns it
ROM:0801D42A
ROM:0801D42A loc_801D42A                             ; CODE XREF: Disobey_byte_check+48j
ROM:0801D42A                 POP     {R4-R7}
ROM:0801D42C                 POP     {R1}
ROM:0801D42E                 BX      R1
0801D4D4 checks one last time if, by chance, the attack will go trough. If not it will proceed to 0x0801d518, where what will the pokemon actually do\say is calculated.
So, several modifications can be made here to change the level a pokemon will become disobedient and in what conditions will it become disobedient.
The location of the obedience flag is actually in the last part of the Ribbon data in the Misc block, the topmost flag (bit 31 of the Ribbon word), but it's only useful for the species listed on the disobedience byte. And as for why Mew\Deoxys only disobey, it's because the chance of attack is determined by a random number (from 0-ff) to be smaller than the max level (that in the byte case is 0).

Edit: If I understood correctly, the code needed here is one that, if a pokemon doesn't have the flag, the pokemon has some chances of attacking, instead of just laying around all the time. With that in mind, I made a code for the occasion
Spoiler:
Code:
.align 2
.thumb
/*to use this code, place 00 49 08 47 at 0x0801d3f4, and the reversed pointer to  where
you put this code at 0x0801d3f8*/
    cmp r0, #0x5
    beq disobey_or_not
    cmp r0, #0x6 
    beq disobey_or_not    /*add more checks here for other pokemon*/
    ldr r1, mew_check
    bx r1
mew_check:   .word 0x0801D403
disobey_or_not: ldr r1, random_addr 
    ldrb r1, [r1]
    mov r0, #0xb4 /*change here the "perform attack" chance. percentage  is r0 divided by 256 times 100 */
    cmp r1, r0 /*aprox 70% chance of not performing an attack*/
    bgt is_obedient
    ldr r0, disobedient_ret_addr
    bx r0
is_obedient:   mov r0, #0x1
    pop {r4-r7,pc}
.hword 0x0000    
random_addr: .word 0x03005000
disobedient_ret_addr: .word 0x0801d415

The trick in that code is that the pokemon will act as if it was obedient every once in a while thanks to the random number stored at 0x03005000.
JPAN, I tried to assemble this code I got some error messages: invalid offset, target not word aligned; invalid offset, value too big.

I couldn't get it to assemble.
__________________

Last edited by metapod23; August 8th, 2010 at 04:49 AM. Reason: Your double post has been automatically merged.
Reply With Quote
  #28    
Old August 9th, 2010, 08:21 AM
NarutoActor's Avatar
NarutoActor
The rocks cry out to me
Community Supporter
 
Join Date: Jan 2009
Location: Brooklyn/Marlboro
Age: 21
Gender: Female
Nature: Bashful
Send a message via AIM to NarutoActor Send a message via Windows Live Messenger to NarutoActor
Yup. Also, You can edit the asm routine to compare with a var. For an example if var 0x8000 is 0x1 then it will be a bulbasaur. That would make the asm routine more universal for other hackers. All you need to do is set the var before the asm routine, copy the var value into a registry, and compare.
__________________
~There are those people who understand hex, F the rest
Reply With Quote
  #29    
Old August 9th, 2010, 12:44 PM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by NarutoActor View Post
Yup. Also, You can edit the asm routine to compare with a var. For an example if var 0x8000 is 0x1 then it will be a bulbasaur. That would make the asm routine more universal for other hackers. All you need to do is set the var before the asm routine, copy the var value into a registry, and compare.
So could I create a routine that only has Charmeleon or Charizard obey or disobey if a certain variable (or flag) was set? That would be the best thing, imho. Then I could just set the variable (say, to 0x1) when I want them to obey, and unset it when I want them to disobey.

If that's possible, any chance you can enlighten me on to how that routine might be written?

(And I still can't get JPAN's routine to assemble. )
__________________
Reply With Quote
  #30    
Old January 2nd, 2011, 12:20 PM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by NarutoActor View Post
Yup. Also, You can edit the asm routine to compare with a var. For an example if var 0x8000 is 0x1 then it will be a bulbasaur. That would make the asm routine more universal for other hackers. All you need to do is set the var before the asm routine, copy the var value into a registry, and compare.
So I spent a good part of my day trying to get this to work with this code. I've tried various things, but here's what I tried recently:

Code:
.text
.align 2
.thumb
.thumb_func
.global obedience

main:
	cmp r0, #0x97
	beq disobey
	cmp r0, #0x05
	beq disobey
	cmp r0, #0x06
	beq disobey

	mov r0, #0x01
	ldr r1, .RESUME
	bx r1
	
disobey:
	ldr r1, .VAR
	cmp r1, #0x00
	beq disobey2

	mov r0, #0x01
	ldr r1, .RESUME
	bx r1

disobey2:
	ldr r1, .DISOBEY
	bx r1

resume:
	ldr r1, .RESUME
	bx r1
	
branchlink:
	bx r3

.align 2
.RESUME:
	.word	0x0801D42B
.DISOBEY:
	.word	0x0801D415
.VAR:
	.word 0x020370d2


I bolded what I was attempting to do, which is to set a variable to a register, compare it to a number (in this case, 0) and if it's set to 0, have the Poké disobey; if not, have it obey.

I want to use variable 6187, just because I haven't used that one yet, but I'm just trying to experiment with 0x800d to see if I can get it to work. So far with my attempts, Charizard has either obeyed the entire time, whether 0x800d was set to 0x0 or 0x1, or has disobeyed in either event.

Any input would be appreciated.
__________________
Reply With Quote
  #31    
Old January 2nd, 2011, 04:16 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
You need a 'ldrh r1, [r1]' instruction after 'ldr r1, .VAR'.

Also, you can get rid of the "branchlink" section. That must have been left in from a previous project. It's unnecessary here.
__________________

Brother of Vrai
Reply With Quote
  #32    
Old January 3rd, 2011, 08:53 AM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by colcolstyles View Post
You need a 'ldrh r1, [r1]' instruction after 'ldr r1, .VAR'.

Also, you can get rid of the "branchlink" section. That must have been left in from a previous project. It's unnecessary here.
It worked! Thanks!

Now I'm just trying to find the right register for variable 0x6200. I tried debugging with VBA-SLD-H, but when I try to use the breakpoint command for the script I'm testing, it kind of freezes, and I haven't had any luck comparing registers when I hit F11 right after I activate the script and after/before I activate a different script. At least none of the ones I have tried have worked.

Anybody have any advice?
__________________
Reply With Quote
  #33    
Old January 3rd, 2011, 02:27 PM
colcolstyles's Avatar
colcolstyles
Yours truly
 
Join Date: May 2008
Location: The Bay Area
Gender: Male
Nature: Lonely
I'm not really sure what you're asking but if you want to retrieve the value of a non-0x8000 variable, you should call the THUMB routine at '0x0806E454' and pass the variable number as a parameter through r0.
__________________

Brother of Vrai
Reply With Quote
  #34    
Old January 3rd, 2011, 07:18 PM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by colcolstyles View Post
I'm not really sure what you're asking but if you want to retrieve the value of a non-0x8000 variable, you should call the THUMB routine at '0x0806E454' and pass the variable number as a parameter through r0.
Unfortunately, I have no idea how to do that. :\

I'll keep searching the forums/google to see if I can scrounge up something. None of the tutorials or topics I've found have made it very clear to me.
__________________
Reply With Quote
  #35    
Old January 4th, 2011, 02:13 AM
TheDarkShark
Metal Headed Hacker
 
Join Date: May 2010
Location: Germany
Gender: Male
Nature: Calm
My ASM isn't very good, but I think the code would be something like this:

ldrh r0, <whatever variable you want to use>
bal 0x0806E454

EDIT: Here's the full code. I'm not shure if this will work, but here it is (changes in bold) :
.text
.align 2
.thumb
.thumb_func
.global obedience

main:
cmp r0, #0x97
beq disobey
cmp r0, #0x05
beq disobey
cmp r0, #0x06
beq disobey

mov r0, #0x01
ldr r1, .RESUME
bx r1

disobey:
ldrh r0, 0x6187 @The number of the variable is stored
bal 0x0806E454 @The Routine is called
cmp r0, #0x00 @Maybe, you have to compare another Register, as I don't know, where the value of the variable is stored
beq disobey2[/B]

mov r0, #0x01
ldr r1, .RESUME
bx r1

disobey2:
ldr r1, .DISOBEY
bx r1

resume:
ldr r1, .RESUME
bx r1

branchlink:
bx r3

.align 2
.RESUME:
.word 0x0801D42B
.DISOBEY:
.word 0x0801D415

Last edited by TheDarkShark; January 4th, 2011 at 02:24 AM.
Reply With Quote
  #36    
Old January 4th, 2011, 07:18 AM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by TheDarkShark View Post
My ASM isn't very good, but I think the code would be something like this:

ldrh r0, <whatever variable you want to use>
bal 0x0806E454

.........
Thanks for responding. It didn't work, but it got me trying some different things. Taking word for word what colcol instructed, I tried this:

Code:
.text
.align 2
.thumb
.thumb_func
.global obedience

main:
	cmp r0, #0x97
	beq disobey
	cmp r0, #0x05
	beq disobey
	cmp r0, #0x06
	beq disobey

	mov r0, #0x01
	ldr r1, .RESUME
	bx r1
	
disobey:
	bl =0x0806E454
	ldr r0, =0x00006200
	ldrh r0, [r0]
	cmp r0, #0x00
	beq disobey2

	mov r0, #0x01
	ldr r1, .RESUME
	bx r1

disobey2:
	ldr r1, .DISOBEY
	bx r1

resume:
	ldr r1, .RESUME
	bx r1

.align 2
.RESUME:
	.word	0x0801D42B
.DISOBEY:
	.word	0x0801D415
It doesn't work, though, so obviously I'm doing something wrong. I was trying to use this tut - http://pkmnhackersonline.com/zodiacd...SM/Lesson3.htm - as reference.

It doesn't crash/freeze the game like some of my attempts (like using labels for the variable/routine), but the Pokemon obeys no matter what the variable is set to.

Maybe someone could help me figure out my mistakes?
__________________
Reply With Quote
  #37    
Old January 4th, 2011, 12:11 PM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Quote:
Originally Posted by metapod23 View Post
...Maybe someone could help me figure out my mistakes?
The Line of code I left in bold is the problem here. The bl thumb command has a VERY short range (0xFFFF bytes I think), so instead of trying to directly link to it, try this instead. Unless you are inserting this code within that range. First of all, what you're doing here, because the code is written the wrong way around, is running the variable decrypting routine, then overwriting the result with "garbage".

Try this instead. Essentially the same, but should work better:

Code:
.text
.align 2
.thumb
.thumb_func
.global obedience
 
main:
    cmp r0, #0x97
    beq disobey
    cmp r0, #0x05
    beq disobey
    cmp r0, #0x06
    beq disobey
 
    mov r0, #0x01
    ldr r1, .RESUME
    bx r1
 
disobey:
    ldr r0, =0x00006200
    push {lr}
  bl vardecrypt
    pop {r1}
    mov lr, r1
    ldrh r0, [r0]
    cmp r0, #0x00
    beq disobey2
 
    mov r0, #0x01
    ldr r1, .RESUME
    bx r1
 
disobey2:
    ldr r1, .DISOBEY
    bx r1
 
resume:
    ldr r1, .RESUME
    bx r1
 
vardecrypt:
    ldr r1, .VARDEC
    bx r1
 
.align 2
.RESUME:
    .word    0x0801D42B
.DISOBEY:
    .word    0x0801D415
.VARDEC:
    .word    0x0806E455
For the record, you should ALWAYS precede a bl command with a push {lr} command and follow it with a combo of pop {whatever}, mov lr, whatever; as you don't know if the calling routine needs the value held in lr for the rest of the routine. Better safe than sorry!

Incidentally, I'd assume that this is the same routine which runs the checks on Mew and Deoxys for disobedience? If so, could we rewrite it to exclude those rather frustrating checks?
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

Last edited by Jambo51; January 4th, 2011 at 12:38 PM.
Reply With Quote
  #38    
Old January 4th, 2011, 01:24 PM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by Jambo51 View Post
The Line of code I left in bold is the problem here. The bl thumb command has a VERY short range (0xFFFF bytes I think), so instead of trying to directly link to it, try this instead. Unless you are inserting this code within that range. First of all, what you're doing here, because the code is written the wrong way around, is running the variable decrypting routine, then overwriting the result with "garbage".

Try this instead. Essentially the same, but should work better:

Code:
.text
.align 2
.thumb
.thumb_func
.global obedience
 
main:
    cmp r0, #0x97
    beq disobey
    cmp r0, #0x05
    beq disobey
    cmp r0, #0x06
    beq disobey
 
    mov r0, #0x01
    ldr r1, .RESUME
    bx r1
 
disobey:
    ldr r0, =0x00006200
    push {lr}
  bl vardecrypt
    pop {r1}
    mov lr, r1
    ldrh r0, [r0]
    cmp r0, #0x00
    beq disobey2
 
    mov r0, #0x01
    ldr r1, .RESUME
    bx r1
 
disobey2:
    ldr r1, .DISOBEY
    bx r1
 
resume:
    ldr r1, .RESUME
    bx r1
 
vardecrypt:
    ldr r1, .VARDEC
    bx r1
 
.align 2
.RESUME:
    .word    0x0801D42B
.DISOBEY:
    .word    0x0801D415
.VARDEC:
    .word    0x0806E455
For the record, you should ALWAYS precede a bl command with a push {lr} command and follow it with a combo of pop {whatever}, mov lr, whatever; as you don't know if the calling routine needs the value held in lr for the rest of the routine. Better safe than sorry!
Thanks for the response, but it's still not working for me.
Charizard obeys whether the variable is set to 0x0 or 0x1 ...

Quote:
Incidentally, I'd assume that this is the same routine which runs the checks on Mew and Deoxys for disobedience? If so, could we rewrite it to exclude those rather frustrating checks?
That's correct, it's the same routine. I would guess that you could just alter the routine at 0x0801D404, which I think was the original location of the routine to check for disobedience? I would guess you could just write a new routine that doesn't really do anything and insert it there?

I'm sure there's a routine before this that goes to the routine at 0x0801D404 if an attack is selected, though, and it would be best to edit that routine to not have it go to the routine at 0x0801D404 at all, but I don't know what the offset of that one would be ...
__________________
Reply With Quote
  #39    
Old January 4th, 2011, 03:17 PM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Quote:
Originally Posted by metapod23 View Post
Thanks for the response, but it's still not working for me.
Charizard obeys whether the variable is set to 0x0 or 0x1 ...



That's correct, it's the same routine. I would guess that you could just alter the routine at 0x0801D404, which I think was the original location of the routine to check for disobedience? I would guess you could just write a new routine that doesn't really do anything and insert it there?

I'm sure there's a routine before this that goes to the routine at 0x0801D404 if an attack is selected, though, and it would be best to edit that routine to not have it go to the routine at 0x0801D404 at all, but I don't know what the offset of that one would be ...
This might sound a bit iffy, but let me insert this routine and i'll see if I can find why it isn't working for you. If you say yes, you'll need to tell me the insertion location so I can do it. Also, 2 seconds after posting this, I found and removed the Mew and Deoxys checks. Hooray! Now we can all catch and actually use Mew. Simply replace the cmp r1, #0x97 line with lsl r0, r0, #0x0 (97 29 with 00 00) and the check won't run.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #40    
Old January 4th, 2011, 04:09 PM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
Quote:
Originally Posted by Jambo51 View Post
This might sound a bit iffy, but let me insert this routine and i'll see if I can find why it isn't working for you. If you say yes, you'll need to tell me the insertion location so I can do it. Also, 2 seconds after posting this, I found and removed the Mew and Deoxys checks. Hooray! Now we can all catch and actually use Mew. Simply replace the cmp r1, #0x97 line with lsl r0, r0, #0x0 (97 29 with 00 00) and the check won't run.
Sure, go ahead. I've been placing the routine at 0x859000.

EDIT

Actually, now I realize that it does work. Thanks!! :D

For some reason variable 0x6200 wasn't already set to 0, even though I hadn't used it in my game yet - I was assuming that it was.

I switched it to 0x6199 and it works perfectly. Thanks again, Jambo51! I really appreciate it.

Also, I put the code in the first post, and I'll add you and others that helped on this code to the credits for my hack.
__________________

Last edited by metapod23; January 5th, 2011 at 07:03 AM.
Reply With Quote
  #41    
Old August 10th, 2011, 01:12 PM
metapod23's Avatar
metapod23
Hardened Trainer
 
Join Date: Mar 2009
Gender: Male
Nature: Timid
I'm just reviving this thread to post that I figured out how to combine JPAN's routine of having a Pokemon obey once in a while and Jambo51's routine of having it only do so when a certain variable is or isn't set. Again, I want to thank colcolstyles, Jambo51, and JPAN for working on this for me! Thanks!

So here's the routine:

First place 00 49 08 47 at 0x0801D3F4, and the reversed pointer to the code below at 0x0801D3F8 (per JPAN's routine).

Code:
.text
.align 2
.thumb
.thumb_func
.global obedience
 
main:
    cmp r0, #0x97    @Mew's number, if you want it to disobey still
    beq disobey
    cmp r0, #0x05    @Pokemon you want to disobey only sometimes 
    beq disobey        (Charmeleon)
    cmp r0, #0x06    @Pokemon you want to disobey only sometimes         
    beq disobey        (Charizard)
    ldr r1, mew_check
    bx r1

mew_check:
   .word 0x0801D403
 
disobey:
    ldr r0, =0x00006199    @Variable you want to use
    push {lr}
    bl vardecrypt
    pop {r1}
    mov lr, r1
    ldrh r0, [r0]
    cmp r0, #0x00    @the value of the variable you want to cause the
    beq disobey2       Pokemon to sometimes disobey
     mov r0, #0x01
    ldr r1, .RESUME
    bx r1

disobey2:
    ldr r1, random_addr 
    ldrb r1, [r1]
    mov r0, #0xcd    the number, divided by 256, that will be the
    cmp r1, r0          percentage of how often the Pokemon disobeys
    bgt is_obedient    (in this case, cd (205)/256 = 80% disobey)
    ldr r0, disobedient_ret_addr
    bx r0
 
resume:
    ldr r1, .RESUME
    bx r1
 
vardecrypt:
    ldr r1, .VARDEC
    bx r1

is_obedient:   mov r0, #0x1
    pop {r4-r7,pc}
.hword 0x0000

.align 2
.RESUME:
    .word    0x0801D42B
.DISOBEY:
    .word    0x0801D415
.VARDEC:
    .word    0x0806E455
random_addr:
	.word 0x03005000

disobedient_ret_addr:
	.word 0x0801d415
__________________
Reply With Quote
  #42    
Old December 30th, 2012, 02:07 PM
Wynchester's Avatar
Wynchester
Legendary Trainer
 
Join Date: Dec 2012
Location: With your sister
Gender: Male
My question is this... Does this then affect every Poke of a species (i.e. all Charmeleon and Charizard) or only one specific pokemon you have? My instinct says all of the Species, but if that's the case, I need help making it so it only affects a very specific Poke.
__________________
To all people who I was trying to help: my computer has encountered a major virus wiping out all of my emulators and related files. My computer and USB drives are in critical condition as far as infection. Please forgive me for any work you were hoping I could do for you, but I don't even have the files for the original games anymore. So for now, I have to resign from work until my computer gets cleaned. I will try to return to hacking as soon as I can, but it may not be for a while.

UPDATE: My computer and devices are cleaned, but atm, I do NOT have access to my hack tools. I can not hack for anyone including myself. My apologies to anyone this inconveniences.
Reply With Quote
  #43    
Old December 31st, 2012, 12:34 AM
tinix's Avatar
tinix
PearlShipper & C Programmer
 
Join Date: Feb 2010
Location: Bratislava, Slovakia
Age: 17
Gender: Male
It affects all of species. I think you could make a specific poke disobey by storing its personality value(it is unique as it is randomly generated) from its data in some variable and then comparing the variable to the personality value of active pokemon. If I am wrong feel free to correct me.
__________________
Pokémon games i own:
Pokémon Diamond
Pokémon Platinum
Pokémon Ranger: Shadows of Almia
Pokémon HeartGold Version

75% of Pokemon gamers use cheats and specially made codes to make their pokemon battle-worthy. If you are one of the 25% percent that level their Pokemon up legally, put this in your signature.
-Started by SkittyLover77


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 03:40 AM.


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.