Gamer2020

Accept no Imitations!

Male
Distant Land
Seen 2 Weeks Ago
Posted January 6th, 2019
942 posts
11.5 Years
A week or so ago, someone (A-bird?) on the irc mentioned to me that the move relearner would not work properly if the Pokemon could not learn any moves. I tried to reproduce the problem and sure enough this happens:



I made a mental note to look into it at some point. While working on PGE I noticed that there were 6 pointers to the level up attacks but remembered that Jambo51 only posted 3 routines. I took a look and there are 3 more routines that need to be edited.

One of these routines is called when the move relearner is run. This routine, located at 08043E2C, seems to return the number of attacks the Pokemon can relearn. I rewrote the routine and here it is:

This is for Fire Red. I will port it eventually.
.text
.align 2
.thumb
.thumb_func
.global newmovesetstyle4

/*at 8043E2C 004B1847xxxxxxxx */

/*08043E2C*/
main:
    PUSH    {R4-R7,LR}
    MOV     R7, R10
    MOV     R6, R9
    MOV     R5, R8
    PUSH    {R5-R7}
    sub sp, sp, #0x3C
    add r6, r0, #0x0
    mov r0, #0x0
    mov r10, r0
    add r0, r6, #0x0
    mov r1, #0x41
    mov r2, #0x0
    ldr r3, .READ_Poke_DATA /*Get Species*/
    bl bx_r3
    lsl r0, r0, #0x10
    lsr r4, r0, #0x10
    add r0, r6, #0x0
    mov r1, #0x38
    mov r2, #0x0
    ldr r3, .READ_Poke_DATA /*Get Level*/
    bl bx_r3
    lsl r0, r0, #0x18 /*Drops leading 000000??*/
    lsr r0, r0, #0x18
    str r0, [sp, #0x30]
    mov r0, #0xce /*Check if slot 412*/
    lsl r0, r0, #0x01
    cmp r4, r0
    bne     loc_8043E68
    mov r0, #0x0
    b       exit

loc_8043E68:
    mov r5, #0x0
    lsl r4, r4, #0x02 /*Species x 4*/
    str r4, [sp, #0x38] /*Stores value for later */
    mov r4, sp

loc_8043E70:
    mov r1, r5
    add r1, #0xd
    mov r0, r6
    mov r2, #0x0
    ldr r3, .READ_Poke_DATA /*Get attacks*/
    bl bx_r3
    strh r0, [r4]
    add r4, #0x2
    add r5, #0x1 /*Loops through 4 attacks on Poke*/
    cmp r5, #0x3
    ble loc_8043E70
    mov r5, #0x0
    ldr     r3, .learned_moves_ptr
    ldr r2, [sp, #0x38]
    add r1, r2, r3
    ldr     r0,[r1]
ldrb r0, [r0, #0x2]
CMP     R0, #0xFF
    BEQ     loc_8043F70
    mov     r9,r1
    mov     r4,r13
    add     r4,#0x8
    str     r4,[sp,#0x34]        

loc_8043EA0:
    mov     r1,r9
    ldr     r0,[r1]
mov r2,#0x03
mul r2, r2, r5 /*mult 3*/
    add     r0,r2,r0
ldrb r0, [r0, #0x2] /*Puts level in r0.*/
    ldr     r4,[sp, #0x30] /*Loads mon level*/
mov     r1,r4
    mov     r7,r2
    add     r5, #0x1 /*Incremeants place*/
    mov     r12,r5
    cmp     r0,r1  /*Level Check*/
    bgt     loc_8043F5A
    mov     r4, #0x0
mov     r0,r9
ldr     r0,[r0]
 ldrb r1, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r0, r1 /*Puts attack in r0.*/
     mov     r1,r13
    ldrh    r1,[r1]
    cmp     r1,r0
    beq     loc_8043EF2
    ldr     r0,[sp, #0x38]
    ldr     r1, .learned_moves_ptr
    add     r6,r0,r1
    mov     r3,r13
    mov     r5,r7

loc_8043EDA:
    add     r3, #0x2
    add     r4, #0x1
    cmp     r4, #0x3
    bgt     loc_8043EF2
    ldr     r0,[r6]
    add     r0,r5,r0
 ldrb r1, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r0, r1 /*Loads bytes Gets attack put into r0*/
    ldrh    r2,[r3]
    cmp     r2,r0
    bne     loc_8043EDA

loc_8043EF2:
    cmp     r4, #0x4
    bne     loc_8043F5A
    mov     r4, #0x0
    cmp     r4,r10
    bge     loc_8043F38
    mov     r1,r9
    ldr     r0,[r1]
    add     r0,r7,r0
 ldrb r1, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r1, r0 /*Loads bytes Gets attack put into r1*/
    ldr     r0,[sp,#0x34]
    ldrh    r2,[r0]
mov     r0,r1 /*Gets attack put into r0*/
    add     r1,sp,#0x8
    cmp     r2,r0
    beq     loc_8043F38
    ldr     r2,[sp,#0x38]
    ldr     r0, .learned_moves_ptr
    add     r6,r2,r0
    mov     r3,r1
    mov     r5,r7

loc_8043F20:
    add     r3, #0x2
    add     r4, #0x1
    cmp     r4,r10
    bge     loc_8043F38
    ldr     r0,[r6]
    add     r0,r5,r0 /*Attack*/
 ldrb r1, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r0, r1 /*Loads bytes Gets attack put into r0*/
    ldrh    r2,[r3]
    cmp     r2,r0
    bne     loc_8043F20

loc_8043F38:
    cmp     r4,r10
    bne     loc_8043F5A
    mov     r0,r10
    add     r0, #0x1
    lsl     r0,r0, #0x18
    lsr     r0,r0, #0x18
    mov     r10,r0
    lsl     r2,r4, #0x1 /*mult 2?*/
    ldr     r4,[sp,#0x34]
    add     r2,r4,r2
    mov     r1,r9
    ldr     r0,[r1]
    add     r0,r7,r0
 ldrb r1, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r0, r1 /*Loads bytes Gets attack put into r0*/
    strh    r0,[r2] 

loc_8043F5A:
    mov     r5,r12
    cmp     r5, #0x13 /*Some kind of limit to attacks?*/
    bgt     loc_8043F70
    mov     r2,r9
    ldr     r0,[r2]
mov r1,#0x03
mul r1, r1, r5
    add     r1,r1,r0
ldrb r0, [r1, #0x2]
cmp     r0, #0xFF /*Term Check*/
    bne     loc_8043EA0

loc_8043F70:
    mov     r0,r10 /*Return Value*/

exit:
    add     sp, #0x3C
    pop     {r3-r5}
    mov     r8,r3
    mov     r9,r4
    mov     r10,r5
    pop     {r4-r7}
    pop     {r1}
    bx      r1 

bx_r3:
    bx r3
    
.align 2
.READ_Poke_DATA:
    .word 0x0803FBE9
.learned_moves_ptr:
    .word 0x0825D7B4
This routine takes care of the pointer at 08043F84. I tested this routine and it seemed to work fine but it could always be optimized a bit more. This seems to fix most of the problems but I think that Jambo51's third routine may need some tweaking. There are two more pointers at 0803EB10 and 08043E20 but I currently have no time to look into the routines that use them.