The PokéCommunity Forums

The PokéCommunity Forums (https://www.pokecommunity.com/index.php)
-   Binary Hack Research & Development (https://www.pokecommunity.com/forumdisplay.php?f=195)
-   -   Code ASM Resource Thread (https://www.pokecommunity.com/showthread.php?t=339153)

Spherical Ice June 17th, 2017 4:38 PM

1 Attachment(s)

[FR] EV-reducing Berries


Find 0x49C bytes of free space at a word-aligned address, and take note of it.
Set the EV-reducing berries' Type to Type 1 ("Out of battle").
Set the items' Field script pointers to the address you noted, plus 1.
Set the items' Battle script pointer to 0xA2239.
Assemble the following routine, changing 0xXXXXXX to the address you noted (not plus 1).
Open the generated .bin file, navigate to the location address, and select 0x49C bytes.
Copy the bytes and paste them in your ROM, at the same address.

Code:

.thumb

@ -- Change these
.equ start_address, 0x29B110
@ --

.equ rom, 0x08000000

.equ pokemon_length, 0x64

.equ req_species,          0x0B
.equ req_held_item,        0x0C
.equ req_hp_ev,            0x1A
.equ req_atk_ev,            0x1B
.equ req_def_ev,            0x1C
.equ req_spe_ev,            0x1D
.equ req_spatk_ev,          0x1E
.equ req_spdef_ev,          0x1F
.equ req_happiness,        0x20
.equ req_catch_location,    0x23
.equ req_pokeball,          0x26

.equ item_luxuryball,  0x0B
.equ item_pomegberry,  0x99
.equ item_kelpsyberry,  0x9A
.equ item_qualotberry,  0x9B
.equ item_hondewberry,  0x9C
.equ item_grepaberry,  0x9D
.equ item_tomatoberry,  0x9E
.equ item_soothebell,  0xB8

.org start_address, 0xFF
ev_berries:
    push {lr}
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    ldr r2, item_function_ptr
    ldr r1, =(rom + dp05_ev_berries + 1)
    str r1, [r2]
    ldr r3, item_consume_maybe
    bl call_via_r3
    pop {r3}

call_via_r3:
    bx r3

.align 2
    item_consume_maybe:    .word 0x080A16D0|1
    .pool

dp05_ev_berries:
    push {r4-r7,lr}
    mov r7, r10
    mov r6, r9
    mov r5, r8
    push {r5-r7}
    sub sp, sp, #0xC
    str r1, [sp, #0]
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    mov r10, r0

get_selected_pokemon:
    ldr r4, brm
    ldrb r1, [r4, #9]
    mov r0, #pokemon_length
    mul r1, r0
    ldr r0, party_player
    add r5, r1, r0

determine_berry:
    ldr r0, var_800E
    ldrh r0, [r0]
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    sub r0, #(item_pomegberry - 1)
    mov r7, r0

get_ev_req:
    mov r0, r5
    mov r1, r7
    ldr r3, =(rom + get_ev_req_from_berry_id + 1)
    bl call_via_r3
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    cmp r0, #0
    beq no_effect
    mov r6, r0

happiness_before:
    mov r0, r5
    mov r1, #req_happiness
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    ldr r1, var_8000
    strh r0, [r1]

ev_value_before:
    mov r0, r5
    mov r1, r6
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    ldr r1, var_8001
    strh r0, [r1]

use_berry:
    mov r0, r5
    mov r1, r6
    ldr r3, =(rom + use_ev_berry + 1)
    bl call_via_r3
    lsl r0, r0, #0x18
    lsr r4, r0, #0x18

ev_after:
    mov r0, r5
    mov r1, r6
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r8, r0

happiness_after:
    mov r0, r5
    mov r1, #req_happiness
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r9, r0

branch_for_effectiveness:
    cmp r4, #0
    bne no_effect
    ldr r0, var_8000
    ldrh r0, [r0]
    cmp r0, r9
    bne effect
    ldr r1, var_8001
    ldrh r1, [r1]
    cmp r1, r8
    bne effect

no_effect:
    ldr r1, item_effectiveness
    mov r0, #0
    strb r0, [r1]
    mov r0, #5
    ldr r3, audio_play
    bl call_via_r3
    ldr r0, no_effect_str
    mov r1, #1
    ldr r3, item_menu_string
    bl call_via_r3
    mov r0, #2
    ldr r3, bgid_mark_for_sync
    bl call_via_r3
    ldr r1, tasks
    mov r2, r10
    lsl r0, r2, #2
    add r0, r10
    lsl r0, r0, #3
    add r0, r0, r1
    ldr r1, [sp]
    str r1, [r0]
    b end

effect:
    mov r0, r10
    ldr r3, item_use_animation
    bl call_via_r3
    ldr r1, item_function_ptr
    ldr r0, =(rom + berry_use + 1)
    str r0, [r1]

end:
    add sp, sp, #0xC
    pop {r3-r5}
    mov r8, r3
    mov r9, r4
    mov r10, r5
    pop {r4-r7}
    pop {r0}
    bx r0

.align 2
    item_function_ptr:      .word 0x03005E98
    .pool

berry_use:
    push {r4-r7,lr}
    lsl r0, r0, #0x18
    lsr r5, r0, #0x18
    ldr r1, item_effectiveness
    mov r0, #1
    strb r0, [r1]

sound_fx:
    mov r0, #1
    ldr r3, audio_play
    bl call_via_r3

remove_item:
    ldr r0, var_800E
    ldrh r0, [r0]
    mov r1, #1
    ldr r3, bag_remove_item
    bl call_via_r3

get_selected_pokemon_again:
    ldr r4, brm
    ldrb r1, [r4, #9]
    mov r0, #pokemon_length
    mul r1, r0
    ldr r0, party_player
    add r4, r1, r0

determine_berry_again:
    ldr r0, var_800E
    ldrh r0, [r0]
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    sub r0, #(item_pomegberry - 1)
    mov r7, r0

get_ev_req_again:
    mov r0, r4
    mov r1, r7
    ldr r3, =(rom + get_ev_req_from_berry_id + 1)
    bl call_via_r3
    lsl r0, r0, #0x18
    lsr r1, r0, #0x18

ev_after_again:
    mov r0, r4
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r8, r0

happiness_after_again:
    mov r0, r4
    mov r1, #req_happiness
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r9, r0

buffer_pkmn_nick_to_buffer2:
    ldr r1, fcode_buffer2
    mov r0, r4
    ldr r3, buffer_pkmn_nick
    bl call_via_r3

buffer_stat_name_to_buffer3:
    ldr r1, fcode_buffer3
    mov r0, r7
    ldr r3, =(rom + buffer_stat_name + 1)
    bl call_via_r3

branch_for_string:
    ldr r0, var_8000
    ldrh r0, [r0]
    cmp r0, r9
    beq happiness_at_max
    ldr r0, var_8001
    ldrh r0, [r0]
    cmp r0, r8
    beq ev_at_0

happiness_not_at_max_ev_above_0:
    ldr r0, displayed_string
    ldr r1, =(rom + happiness_not_at_max_ev_above_0_str)
    ldr r3, fdecoder
    bl call_via_r3
    b load_displayed_string

ev_at_0:
    ldr r0, displayed_string
    ldr r1, =(rom + happiness_up_ev_cant_fall_str)
    ldr r3, fdecoder
    bl call_via_r3
    b load_displayed_string

happiness_at_max:
    ldr r0, displayed_string
    ldr r1, =(rom + adore_ev_down_str)
    ldr r3, fdecoder
    bl call_via_r3

load_displayed_string:
    ldr r0, displayed_string

print_item_message:
    mov r1, #1
    ldr r3, item_menu_string
    bl call_via_r3
    mov r0, #2
    ldr r3, bgid_mark_for_sync
    bl call_via_r3
    ldr r1, tasks
    mov r2, r5
    lsl r0, r2, #2
    add r0, r0, r5
    lsl r0, r0, #3
    add r0, r0, r1
    ldr r1, item_menu_callback
    str r1, [r0]
    pop {r4-r7}
    pop {r0}
    bx r0

.align 2
get_ev_req_from_berry_id:
    push {r4-r7,lr}
    mov r4, r0
    lsl r1, r1, #0x18
    lsr r1, r1, #0x18
    lsl r1, r1, #2
    ldr r0, =(rom + ev_switch_table)
    add r0, r0, r1
    ldr r0, [r0]
    mov pc, r0 @ switch jump

.align 2
ev_switch_table:
    .word (rom + ev_switch_default)
    .word (rom + case_ev_hp)
    .word (rom + case_ev_atk)
    .word (rom + case_ev_def)
    .word (rom + case_ev_spatk)
    .word (rom + case_ev_spdef)
    .word (rom + case_ev_spe)

.align 2
ev_switch_default:
case_ev_hp:
    mov r0, #req_hp_ev
    b return_ev_req

case_ev_atk:
    mov r0, #req_atk_ev
    b return_ev_req

case_ev_def:
    mov r0, #req_def_ev
    b return_ev_req

case_ev_spe:
    mov r0, #req_spe_ev
    b return_ev_req

case_ev_spatk:
    mov r0, #req_spatk_ev
    b return_ev_req

case_ev_spdef:
    mov r0, #req_spdef_ev
    b return_ev_req

ev_return_0:
    mov r0, #0

return_ev_req:
    pop {r4-r7}
    pop {r1}
    bx r1

.align 2
buffer_stat_name:
    push {lr}
    mov r2, r1
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    cmp r0, #6
    bgt return_stat_name
    ldr r1, =(rom + stat_name_switch_table)
    lsl r0, r0, #2
    add r0, r0, r1
    ldr r0, [r0]
    mov pc, r0 @ switch jump

stat_name_switch_table:
    .word (rom + stat_name_default)
    .word (rom + case_hp_name)
    .word (rom + case_atk_name)
    .word (rom + case_def_name)
    .word (rom + case_spatk_name)
    .word (rom + case_spdef_name)
    .word (rom + case_spe_name)

stat_name_default:
case_hp_name:
    ldr r1, hp_name_str
    b break_stat_name_switch

case_atk_name:
    ldr r1, atk_name_str
    b break_stat_name_switch

case_def_name:
    ldr r1, def_name_str
    b break_stat_name_switch

case_spe_name:
    ldr r1, spe_name_str
    b break_stat_name_switch

case_spatk_name:
    ldr r1, spatk_name_str
    b break_stat_name_switch

case_spdef_name:
    ldr r1, spdef_name_str

break_stat_name_switch:
    mov r0, r2
    ldr r3, strcpy_xFF_terminated
    bl call_via_r3

return_stat_name:
    pop {r0}
    bx r0

.align 2
use_ev_berry:
    push {r4-r7,lr}
    mov r7, r10
    mov r6, r9
    mov r5, r8
    push {r5-r7}
    lsl r1, r1, #0x18
    lsr r1, r1, #0x18
    mov r8, r0
    mov r7, r1

get_relevant_ev_value:
    mov r0, r8
    mov r1, r7
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10

check_ev:
    cmp r0, #0
    ble set_ev_unchanged_flag

subtract_ev:
    mov r1, r0
    sub r0, #10
    cmp r0, r1
    blo set_ev
    mov r0, #0

set_ev:
    mov r2, sp
    strh r0, [r2]
    mov r0, r8
    mov r1, r7
    ldr r3, set_attr
    bl call_via_r3

recalc_stats:
    mov r0, r8
    ldr r3, recalculate_stats
    bl call_via_r3
    b get_happiness_value

set_ev_unchanged_flag:
    mov r6, #1

get_happiness_value:
    mov r0, r8
    mov r1, #req_happiness
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3

check_happiness:
    cmp r0, #255
    beq check_if_should_return_1
    cmp r0, #199
    bgt add_two_happiness
    cmp r0, #99
    bgt add_five_happiness

add_ten_happiness:
    mov r6, #10
    b remember_new_happiness

add_five_happiness:
    mov r6, #5
    b remember_new_happiness

add_two_happiness:
    mov r6, #2

remember_new_happiness:
    add r5, r6, r0

luxuryball_check:
    mov r0, r8
    mov r1, #req_pokeball
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    cmp r0, #item_luxuryball
    bne metlocation_check

luxuryball_bonus:
    add r5, #1
    add r6, #1

metlocation_check:
    mov r0, r8
    mov r1, #req_catch_location
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    mov r4, r0
    ldr r3, sav1_map_get_name
    bl call_via_r3
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    cmp r4, r0
    bne soothebell_check

metlocation_bonus:
    add r5, #1
    add r6, #1

soothebell_check:
    mov r0, r8
    mov r1, #req_held_item
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r1, #item_soothebell
    cmp r0, r1
    bne add_happiness

soothebell_bonus:
    lsr r0, r6, #1
    add r5, r0

add_happiness:
    mov r0, r5
    cmp r0, #255
    ble set_happiness
    mov r0, #255

set_happiness:
    mov r2, sp
    strh r0, [r2]
    mov r0, r8
    mov r1, #req_happiness
    ldr r3, set_attr
    bl call_via_r3

return_0:
    mov r0, #0
    b finish_using_ev_berry

check_if_should_return_1:
    cmp r5, #1
    bne return_0

return_1:
    mov r0, #1

finish_using_ev_berry:
    pop {r3-r5}
    mov r8, r3
    mov r9, r4
    mov r10, r5
    pop {r4-r7}
    pop {r1}
    bx r1

happiness_not_at_max_ev_above_0_str:
    .byte 0xFD, 0x02, 0x00, 0xE8, 0xE9, 0xE6, 0xE2, 0xD9, 0xD8, 0x00, 0xDA, 0xE6, 0xDD, 0xD9, 0xE2, 0xD8, 0xE0, 0xED, 0xAD, 0xFE, 0xCE, 0xDC, 0xD9, 0x00, 0xD6, 0xD5, 0xE7, 0xD9, 0x00, 0xFD, 0x03, 0x00, 0xDA, 0xD9, 0xE0, 0xE0, 0xAB, 0xFC, 0x09, 0xFF
    @ "[PKMN] turned friendly.[NEWLINE]The base [STAT] fell![WAITKEYPRESS]"

happiness_up_ev_cant_fall_str:
    .byte 0xFD, 0x02, 0x00, 0xE8, 0xE9, 0xE6, 0xE2, 0xD9, 0xD8, 0x00, 0xDA, 0xE6, 0xDD, 0xD9, 0xE2, 0xD8, 0xE0, 0xED, 0xAD, 0xFE, 0xCE, 0xDC, 0xD9, 0x00, 0xD6, 0xD5, 0xE7, 0xD9, 0x00, 0xFD, 0x03, 0x00, 0xD7, 0xD5, 0xE2, 0xB4, 0xE8, 0x00, 0xDA, 0xD5, 0xE0, 0xE0, 0xAB, 0xFC, 0x09, 0xFF
    @ "[PKMN] turned friendly.[NEWLINE]The base [STAT] can't fall![WAITKEYPRESS]"

adore_ev_down_str:
    .byte 0xFD, 0x02, 0x00, 0xD5, 0xD8, 0xE3, 0xE6, 0xD9, 0xE7, 0x00, 0xED, 0xE3, 0xE9, 0xAB, 0xFE, 0xCE, 0xDC, 0xD9, 0x00, 0xD6, 0xD5, 0xE7, 0xD9, 0x00, 0xFD, 0x03, 0x00, 0xDA, 0xD9, 0xE0, 0xE0, 0xAB, 0xFC, 0x09, 0xFF
    @ "[PKMN] adores you![NEWLINE]The base [STAT] fell![WAITKEYPRESS]"

.align 2
    fcode_buffer2:          .word 0x02021CD0
    fcode_buffer3:          .word 0x02021CF0
    displayed_string:      .word 0x02021D18
    party_player:          .word 0x02024284
    var_8000:              .word 0x020370B8
    var_8001:              .word 0x020370BA
    var_800E:              .word 0x0203AD30
    brm:                    .word 0x0203B0A0
    item_effectiveness:    .word 0x0203B0C0

    tasks:                  .word 0x03005090

    strcpy_xFF_terminated:  .word 0x08008D84|1
    fdecoder:              .word 0x08008FCC|1
    recalculate_stats:      .word 0x0803E47C|1
    get_attr:              .word 0x0803FBE8|1
    set_attr:              .word 0x0804037C|1
    sav1_map_get_name:      .word 0x08056260|1
    audio_play:            .word 0x080722CC|1
    bag_remove_item:        .word 0x0809A1D8|1
    bgid_mark_for_sync:    .word 0x080F67A4|1
    buffer_pkmn_nick:      .word 0x081202E0|1
    item_menu_string:      .word 0x081202F8|1
    item_use_animation:    .word 0x08124DC0|1
    item_menu_callback:    .word 0x081255BC|1
    hp_name_str:            .word 0x084169C2 @ "HP"
    spatk_name_str:        .word 0x084169C5 @ "SP. ATK"
    spdef_name_str:        .word 0x084169CD @ "SP. DEF"
    atk_name_str:          .word 0x08417674 @ "ATTACK"
    def_name_str:          .word 0x0841767B @ "DEFENSE"
    spe_name_str:          .word 0x0841768D @ "SPEED"
    no_effect_str:          .word 0x084169DC @ "It won't have any effect."


The Soothe Bell multiplier acts as it does in Generation IV and onwards (meaning it will also multiply bonuses from the met location and Luxury Ball).

This will introduce the Pomeg Glitch; see tkim's post here on how to fix it.

tkim June 17th, 2017 5:08 PM

Quote:

Originally Posted by Spherical Ice (Post 9681830)

[FR] EV-reducing Berries


Can't wait to try this out! Thanks!

I have two questions though. Can I assume that the luxury ball mentioned in the routine affects the happiness the berries give out? Does the routine also check if the player is at the same location as the berry user's met location and if the berry user is holding a soothe bell at the time (unless Emerald's behaves otherwise)? Here's where my questions are based from: https://bulbapedia.bulbagarden.net/wiki/Friendship#Boosting_friendship
Sorry if I'm overwhelming you.

Spherical Ice June 17th, 2017 5:42 PM

Quote:

Originally Posted by tkim (Post 9681840)
Can't wait to try this out! Thanks!

I have two questions though. Can I assume that the luxury ball mentioned in the routine affects the happiness the berries give out? Does the routine also check if the player is at the same location as the berry user's met location and if the berry user is holding a soothe bell at the time (unless Emerald's behaves otherwise)? Here's where my questions are based from: https://bulbapedia.bulbagarden.net/wiki/Friendship#Boosting_friendship
Sorry if I'm overwhelming you.

Ah, I forgot about those bonuses. I've updated the routine to consider both, and used the Gen IV+ method of the Soothe Bell. Thanks for bringing that to my attention!

tkim June 17th, 2017 6:21 PM

Quote:

Originally Posted by Spherical Ice (Post 9681856)
Ah, I forgot about those bonuses. I've updated the routine to consider both, and used the Gen IV+ method of the Soothe Bell. Thanks for bringing that to my attention!

If I wanted to use the Gen III method of the Soothe Bell, can I just rearrange the soothebell check/bonus and change the 'b' conditions to come before the other checks?

edit: here's what I did: is this okay, or do I have to change registers too?
Code:

remember_new_happiness:
    add r5, r5, r0

soothebell_check:
    mov r0, r8
    mov r1, #req_held_item
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r1, #item_soothebell
    cmp r0, r1
    bne luxuryball_check

soothebell_bonus:
    lsr r0, r5, #1
    add r5, r0

luxuryball_check:
    mov r0, r8
    mov r1, #req_pokeball
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    cmp r0, #item_luxuryball
    bne metlocation_check

luxuryball_bonus:
    add r5, #1

metlocation_check:
    mov r0, r8
    mov r1, #req_catch_location
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    mov r4, r0
    ldr r3, sav1_map_get_name
    bl call_via_r3
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    cmp r4, r0
  bne add_happiness

metlocation_bonus:
    add r5, #1

add_happiness:
    mov r0, r5
    cmp r0, #255
    ble set_happiness
    mov r0, #255



Spherical Ice June 17th, 2017 6:34 PM

Quote:

Originally Posted by tkim (Post 9681867)
If I wanted to use the Gen III method of the Soothe Bell, can I just rearrange the soothebell check/bonus and change the 'b' conditions to come before the other checks?

edit: here's what I did: is this okay, or do I have to change registers too?

Yeah, that should work. The registers shouldn't need changing as far as I can tell. Best way to know is to test yourself and have a script that buffers the Pokémon's friendship so you can test; that's what I did.

tkim June 17th, 2017 8:09 PM

Quote:

Originally Posted by Spherical Ice (Post 9681872)
Yeah, that should work. The registers shouldn't need changing as far as I can tell. Best way to know is to test yourself and have a script that buffers the Pokémon's friendship so you can test; that's what I did.

I tested your routine on a pokemon that had 70 base happiness to start with, holding a soothe bell without factoring met location/luxury ball and its happiness grew by 50 (10 from berry and 40 from halving 80), making it 120 base happiness, instead of 85 ( 70 + 10 +5).

You could probably use r6 for the add_ten/five/two_happiness and also 'add r6, #1' for met location bonus/luxury ball bonus.

edit: here's a fix for ease!
Code:

add_ten_happiness:
    mov r6, #10
    b remember_new_happiness

add_five_happiness:
    mov r6, #5
    b remember_new_happiness

add_two_happiness:
    mov r6, #2

remember_new_happiness:
    add r5, r6, r0

luxuryball_check:
    mov r0, r8
    mov r1, #req_pokeball
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    cmp r0, #item_luxuryball
    bne metlocation_check

luxuryball_bonus:
    add r5, #1
    add r6, #1

metlocation_check:
    mov r0, r8
    mov r1, #req_catch_location
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    mov r4, r0
    ldr r3, sav1_map_get_name
    bl call_via_r3
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    cmp r4, r0
    bne soothebell_check

metlocation_bonus:
    add r5, #1
    add r6, #1

soothebell_check:
    mov r0, r8
    mov r1, #req_held_item
    mov r2, #0
    ldr r3, get_attr
    bl call_via_r3
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r1, #item_soothebell
    cmp r0, r1
    bne add_happiness

soothebell_bonus:
    lsr r0, r6, #1
    add r5, r0


If you use this, the new length will be 0x49C bytes

Spherical Ice June 18th, 2017 3:43 AM

Quote:

Originally Posted by tkim (Post 9681906)
I tested your routine on a pokemon that had 70 base happiness to start with, holding a soothe bell without factoring met location/luxury ball and its happiness grew by 50 (10 from berry and 40 from halving 80), making it 120 base happiness, instead of 85 ( 70 + 10 +5).

You could probably use r6 for the add_ten/five/two_happiness and also 'add r6, #1' for met location bonus/luxury ball bonus.

edit: here's a fix for ease!

If you use this, the new length will be 0x49C bytes

Ah, of course. That's what I get for doing ASM at 3am lmao. Fixed the original post, thanks again.

tkim June 18th, 2017 11:03 AM

Spherical Ice' [FR] EV-reducing Berries does in fact bring back the Pomeg Glitch. If you want to fix this, go to offset 0x3E742 and make the following change:

00 29 04 D1 -> 02 29 04 DC

Credits to HackMew: https://www.pokecommunity.com/showthread.php?t=207217
Note: Despite what Wichu said about Pomeg no longer being usable on Shedinja in that thread- I've tested it and it works. I'm also not aware if this change affects anything else during gameplay, so if anybody else could chime in...

Rohink July 4th, 2017 11:14 PM

I wonder if it was possible to make pc accessible from start menu in fire

ghoulslash July 8th, 2017 5:07 PM

Toggle Oak Text in Trainerbattle 0x9 [FR]

Building off of another post in the Quick Research and Development thread about trainerbattle 0x9, turns out that changing the reserved byte from 0x3 to 0x0 in trainerbattle 0x9 removes the text, but also causes you to white out instead of continue with the script if you lose.

This routine hijacks the trainerbattle command to use variable 0x8000 to toggle Oak's text on or off, while keeping the same functionality of continuing the script even if you lose the battle. I mentioned this in my linked post, but 0x1 is also written to variable 0x800D if you lose, allowing you to branch the script based on your battle result.

Here is the code/insertion instructions:
Code:

.text
.align 2
.thumb
.thumb_func

@At 08080478: 00 48 00 47 XX XX XX 08

main:
        ldr r0, =(0x020370B8)                        @variable 0x8000
        ldrb r0, [r0]
        cmp r0, #0x1
        beq NoText
        ldr r0, =(0x080803D8 +1)
        bl linker
        mov r1, #0x3
        and r1, r0
        cmp r1, #0x0
        beq NoText
        ldr r0, =(0x08080484 +1)                @jump back to original routine
        bx r0

NoText:
        ldr r0, =(0x0808048C +1)
        bx r0

linker:
        bx r0

.align 2


To use:
Code:

setvar 0x8000 0x1
trainerbattle 0x9 0x(ID) 0x3 @lose @win


Let me know if there are any bugs.

AkameTheBulbasaur July 11th, 2017 9:55 AM

I fixed the issue of Squeetz's Synchronize routine and FBI's Shiny Generator routine conflicting.

Squeetz's routine works by taking the Synchronize Pokemon's nature and setting that BEFORE the PID is generated. Turns out, FBI's Shiny Generator routine is activated afterwards, and completely redoes the PID generation, essentially making Squeetz's routine never actually come into effect.

To use both, you can use this combination of both their routines in one. I tested it in my game and it works for all four of these scenarios

1. Not Shiny and no Synchronize Pokemon
2. Not Shiny with a Synchronize Pokemon
3. Shiny and no Synchronize Pokemon
4. Shiny with a Synchronize Pokemon

It might not be super efficient, because it loops a lot, but I couldn't find a better way to do it and still get the desired result.

Spoiler:
/*Insert 00 48 00 47 XX XX XX 08 at 0x3DB00*/
/*Also insert 00 00 02 E0 at 0x3DAF6*/
.text
.align 2
.thumb
.thumb_func


Main:
/*Checks if 0x8003 = 1*/
/*If false it goes back to normal*/
ldr r0, .Var8003
ldrb r0, [r0]
cmp r0, #0x1
bne Return

SetBackToZero:
/*Sets 0x8003 back to 0*/
push {r4-r7}
ldr r0, .Var8003
mov r1, #0x0
strb r1, [r0]

SynchronizeCheck:
/*Checks for first Pokemon's ability*/
bl GetAbility
cmp r1, #0x1C
beq Synchronize
b SetPID

Synchronize:
/*Gets first Pokemon's nature*/
ldr r0, .FirstPoke
mov r1, #0x0
mov r2, #0x0
bl Decrypt
bl GetNature
lsl r0, r0, #0x18
lsr r5, r0, #0x18

GenPID:
/*Generates a new bottom half of PID*/
/*Puts it together with stored top half*/
/*Checks to see if it matches nature*/
bl GeneratePID
mov r4, r0
bl GetNature
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, r5
beq GenerateC
b GenPID

SetPID:
/*Generates a PID for the Pokemon*/
bl GeneratePID
mov r4, r0

GenerateC:
/*This generates a random number between 0 and 8*/
/*This number will be used as C*/
bl RNG
lsr r0, r0, #0x8
cmp r0, #0x7
bgt GenerateC
mov r3, r0

FirstXOR:
/*XORs the TID and SID*/
ldr r0, .SaveBlockC
ldr r0, [r0]
mov r1, #0xA
add r1, r1, r0 /*Gets Trainer ID*/
ldrh r1,[r1]
mov r2, #0xC
add r0, r0, r2 /*Gets Secret ID*/
ldrh r0, [r0]
eor r0, r0, r1 /*A = TID xor SID*/
eor r3, r3, r0 /*B = C xor A*/

SecondXOR:
/*This XORs PID1 and PID2*/
/*PID1 = first half of PID*/
lsl r4, r4, #0x10
lsr r4, r4, #0x10 /*r4 = PID2*/
eor r3, r3, r4 /*PID1 = PID2 xor B*/

ConcatenateR4R3:
/*Concatenate means 'to link together'*/
/*This puts PID1 and PID2 together*/
lsl r3, r3, #0x10
orr r3, r3, r4 /*PID for Shiny Pokemon*/
bl GetAbility
cmp r1, #0x1C
beq CheckNatureAgain
b PrepareEnd

CheckNatureAgain:
/*Basically loops through the whole process again*/
/*Until it finds a PID that gives the right nature*/
/*And is Shiny as well*/
mov r6, r3
mov r0, r3
bl GetNature
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, r5
bne GenPID
mov r3, r6

PrepareEnd:
pop {r4-r7}
str r3, [SP, #0x14]
b End

Return:
bl GetAbility
cmp r1, #0x1C
bne NoCrash
ldr r0, .FirstPoke
mov r1, #0x0
mov r2, #0x0
bl Decrypt
bl GetNature
lsl r0, r0, #0x18
lsr r5, r0, #0x18

PIDLoop:
bl GeneratePID
mov r4, r0
bl GetNature
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r5, r0
bne PIDLoop
b Old

NoCrash:
bl GeneratePID
mov r4, r0

Old:
str r4, [sp, #0x14]

End:
ldr r0, =(0x803DB14 +1)
bx r0

RNG:
ldr r6, .RNGRoutine
bx r6

GeneratePID:
push {r4, lr}
bl HalfPID
mov r4, r0
bl HalfPID2
lsl r4, r4, #0x10
lsr r4, r4, #0x10
lsl r0, r0, #0x10
orr r4, r0
mov r0, r4
pop {r4, pc}

GetAbility:
push {r3-r4, lr}
ldr r0, .FirstPoke
mov r1, #0x2E
mov r2, #0x0
bl Decrypt
mov r4, r0
ldr r0, .FirstPoke
mov r1, #0xB
mov r2, #0x0
bl Decrypt
ldr r2, .Stats
ldr r2, [r2]
mov r1, #0x1C
mul r0, r1
add r2, r0, r2
cmp r4, #0x0
beq Ability0
ldrb r1, [r2, #0x17]
pop {r3-r4, pc}

Ability0:
ldrb r1, [r2, #0x16]
pop {r3-r4, pc}

GetNature:
ldr r3, .Nature
bx r3

Decrypt:
ldr r3, .Decrypter
bx r3

HalfPID:
ldr r4, .PID
bx r4

HalfPID2:
ldr r3, .PID
bx r3

Divide:
ldr r7, .Divider
bx r7

.align 2
.Var8003: .word 0x020370BE
.Var8000: .word 0x020370B8
.RNGRoutine: .word 0x0898ADC9 /*Offset of RNG routine +1*/
.SaveBlockC: .word 0x0300500C
.Divider: .word 0x081E4019
.PID: .word 0x08044EC9
.Decrypter: .word 0x0803FBE9
.FirstPoke: .word 0x02024284
.Stats: .word 0x080001BC
.Nature: .word 0x08042EB5


This replaces the Shiny Generator routine, so branch to it at 0x3DB00. You can get rid of the branch at the old Synchronize location since that's not being used.

If you use this, be sure to credit both FBI and Squeetz for their original routines. I don't want to take any credit for their hard work. I just merged the two preexisting codes.

A note, this particular routine makes Synchronize activate 100% of the time. Squeetz's routine had a 50% chance. If you want that still, you can add some sort of RNG/compare thing. There's already an RNG in the routine, so this shouldn't be too hard to do (I hope. I've never tried it).

This also makes Synchronize work with Eggs (I also think, because it did for me, but I hatched the egg immediately after getting it, and I forget when natures are determined.)

Megax Rocker July 14th, 2017 8:51 AM

Quote:

Originally Posted by FBI (Post 8514906)

Inheriting IVs from parents (via Destiny Knot, in the daycare)



How to insert:

Before doing anything, look at the code. There are two comments that say:
@masterball lol. Change to item you want :D
@Parent2 has masterball :D
At those lines, change the line to "cmp r0, #0xDestinyKnotItemID" and
"cmp r3, #0xDestinyKnotItemID" respectively.

Once you're done that, compile and insert into free space.
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r3, r6}
        mov r6, lr
        mov r0, r5
        mov r1, #0xC
        ldr r2, =(0x803FD44 +1)
        bl linker
        mov r3, r0
        mov r0, r5
        add r0, r0, #0x8C
        mov r1, #0xC
        ldr r2, =(0x803FD44 +1)
        bl linker
        cmp r0, #0x1 @masterball lol. Change to item you want :D
        beq inherit
        cmp r3, #0x1 @Parent2 has masterball :D
        beq inherit

end:
        mov lr, r6
        pop {r3, r6}
        mov r0, SP
        mov r1, r5
        ldr r3, = (0x8045AC0 +1)
        bl linkerTwo
        ldr r0, =(0x8046100+1)
        bx r0

inherit:
        mov r3, #0x5
        bl generateRand
        ldrh r3, [r3]
        push {r4, r7}
        mov r4, #0x27
        add r4, r4, r3 @uninherited stat
        mov r7, #0x0

loop:
        cmp r7, #0x6
        beq prepareEnd
        cmp r7, r4
        beq next
        mov r3, #0x1
        bl generateRand @get a random parent's specified IV
        mov r0, r3
        ldrh r0, [r0]
        mov r1, #0x8C
        mul r0, r0, r1
        add r0, r0, r5
        mov r1, #0x27
        add r1, r1, r7
        ldr r2, =(0x803FBE8 +1)
        bl linker
        ldr r2, = (0x20370D0) @set IV to child
        strh r0, [r2]
        mov r1, #0x27
        add r1, r1, r7
        mov r0, SP
        ldr r3, =(0x804037C +1)
        bl linkerTwo
next:
        add r7, r7, #0x1
        b loop

prepareEnd:
        mov r0, SP
        ldr r3, =(0x803E47C +1) @calc stats
        bl linker
        pop {r4, r7}
        b end

generateRand:
        ldr r2, =(0x8044EC8 +1) @get a random between 0 - r3 (r3 = HW)
        bl linker
        lsl r0, r0, #0x10
        lsr r0, r0, #0x10
        mov r1, r3
        ldr r3, =(0x81E4684 +1)
        bl linkerTwo
        ldr r3, = 0x20370D0 @could just move it to r3 I suppose
        strh r0, [r3]
        bx lr

linker:
        bx r2

linkerTwo:
        bx r3

.align 2




Here's a compiled version:
Code:

48 B4 76 46 28 1C 0C 21 26 4A 00 F0 49 F8 03 1C 28 1C 8C 30 0C 21 23 4A 00 F0 42 F8 01 28 0A D0 01 2B 08 D0 B6 46 48 BC 68 46 29 1C 1E 4B 00 F0 38 F8 1E 48 00 47 05 23 00 F0 26 F8 1B 88 90 B4 27 24 E4 18 00 27 06 2F 18 D0 A7 42 14 D0 01 23 00 F0 1A F8 18 1C 00 88 8C 21 48 43 40 19 27 21 C9 19 13 4A 00 F0 1C F8 12 4A 10 80 27 21 C9 19 68 46 11 4B 00 F0 15 F8 01 37 E4 E7 68 46 0F 4B 00 F0 0E F8 90 BC CD E7 0D 4A 00 F0 09 F8 00 04 00 0C 19 1C 0B 4B 00 F0 04 F8 06 4B 18 80 70 47 10 47 18 47 45 FD 03 08 C1 5A 04 08 01 61 04 08 E9 FB 03 08 D0 70 03 02 7D 03 04 08 7D E4 03 08 C9 4E 04 08 85 46 1E 08


Now go to 0x460F8 and insert the following:
Code:

00 48 00 47 XX XX XX 08


Where XX XX XX is the pointer in reverse hex +1 of the routine you just compiled.


How it works:
When the egg is generated, we check both parents to see if their holding an item matching the item we're looking for. If they are, the egg inherits 5/6 IVs from their parents. Each parent has a 50% chance to pass down one of their IVs.

There is no usage section, because the rest is done automagically when you have two compatible Pokemon in the daycare and they make an egg :)

Also, sorry for the double post, I wanted a fresh post for the first page :P

I want to edit this routine so it doesn't check for an item to be held for it to activate, basically I want Pokemon to inherit IV all the time.

What should I do?

Aiolia.leo July 14th, 2017 8:49 PM

Quote:

Originally Posted by tkim (Post 9682364)
Spherical Ice' [FR] EV-reducing Berries does in fact bring back the Pomeg Glitch. If you want to fix this, go to offset 0x3E742 and make the following change:

00 29 04 D1 -> 02 29 04 DC

Credits to HackMew: https://www.pokecommunity.com/showthread.php?t=207217
Note: Despite what Wichu said about Pomeg no longer being usable on Shedinja in that thread- I've tested it and it works. I'm also not aware if this change affects anything else during gameplay, so if anybody else could chime in...

Is this actually accurate? Cuz AFAIK HackMew's fix is for Emerald, not Fire Red roms.

Blah July 14th, 2017 9:01 PM

Quote:

Originally Posted by Megax Rocker (Post 9705064)
I want to edit this routine so it doesn't check for an item to be held for it to activate, basically I want Pokemon to inherit IV all the time.

What should I do?

Code:

        cmp r0, #0x1 @masterball lol. Change to item you want :D
        beq inherit
        cmp r3, #0x1 @Parent2 has masterball :D
        beq inherit


to
Code:

b inherit


disclaimer: I'm not sure if this routine works/how it works anymore.

tkim July 14th, 2017 10:17 PM

Quote:

Originally Posted by Aiolia.leo (Post 9705405)
Is this actually accurate? Cuz AFAIK HackMew's fix is for Emerald, not Fire Red roms.

The offset I posted is for FR and like I mentioned, I have tested it.

chestertagat July 15th, 2017 7:35 AM

I don't know if anyone here has already posted this one,
But i'm sure someone researched this and used it in their hack. (BTW It's Glazed if you don't know)
Credits to: TheCreatorofGlazed for the wonderful Idea, BluRose for the Initialization and Touched Sensei for everything else.

Here it is:

[FR] Text Display Input Routine
Basically what this do is get an input from user via naming_function and stores it somewhere in the ram then compare it to some string you can define.

Note: I'm not GOOD at ASM so don't judge me if i said something wrong or explained something wrong. Please point it out instead . It's just that those ones who I asked to help me are very GOOOOOOOOOOOOD at ASM.
Routine:
Spoiler:
Code:

.text
.align 2

main:
        push {r4, lr}
        sub sp, #8
        mov r0, #0x4              @Type: 0-4 , 4=rival 3=Pokemon
        ldr r1, fcode_buffer
        mov r2, #0
        mov r3, #0
        mov r4, #0
        str r4, [sp]
        adr r4, continue
                add r4, #1
        str r4, [sp, #4]
        ldr r4, display_text
        bl call_via_r4
        add sp, #8
        pop {r4, pc}

.align 2
display_text: .word 0x0809d954|1

continue:
        push {r4, lr}
        ldr r0,fcode_buffer
        ldr r1, real_password
        ldr r1, [r1]
                ldr r4, strcomp
        bl call_via_r4
        cmp r0, #0
        beq matched
        mov r0, #0
        b return

matched:
        mov r0, #1

return:
                ldr r1, var_800D
        strh r0, [r1]
        ldr r4, =0x080568E0|1
        bl call_via_r4
        pop {r4, pc}

call_via_r4:
        bx r4

.align 2
strcomp:      .word 0x08008E28|1
fcode_buffer: .word 0x02021CE0
real_password:.word 0x03000EB0+0x64
var_800D:    .word 0x020370D0



Instruction:
Spoiler:

You can define your password by putting :
loadpointer 0 @password
before the callasm. (note: you can't set your password more than the max Characters in the Input or else it will fail)
#org @password
= yourpass (yes you treat it like a msgstring and also remember the note above)
and what does this do if the input matches your password?
it sets var 0x800D to 1
and if not ViceVersa
and also. instead of defining the password on your script , you can point it out at any address in the rom as long as it's a string that is not more than the max input char.
you can do that by changing the label real_password to the address of your password.

That's it .
and another one , You can also change the "Rival's Name" text or "PKMN name" if you found out how to do that . It'll be really helpful :)
This Routine can be used for many things not just for Password System. You can use it to name People in your game , It's up to you.

and also feel free to ask what is what :D

BluRose July 15th, 2017 12:36 PM

final edit:
if you want to implement this, stay with this post, i babble a lot. good luck

EDIT2: reeeeeee that's hacky af but ok that should work lol. unspoilered post and spoilered previous edit

Spoiler:
EDIT: i was told by discord that he had it complete so i guess i'll just spoiler this post
good job dude~


Quote:

Originally Posted by chestertagat (Post 9705759)
I don't know if anyone here has already posted this one,
But i'm sure someone researched this and used it in their hack. (BTW It's Glazed if you don't know)
Credits to: TheCreatorofGlazed for the wonderful Idea, BluRose for the Initialization and Touched Sensei for everything else.

Here it is:

[FR] Text Display Input Routine
Basically what this do is get an input from user via naming_function and stores it somewhere in the ram then compare it to some string you can define.

Note: I'm not GOOD at ASM so don't judge me if i said something wrong or explained something wrong. Please point it out instead . It's just that those ones who I asked to help me are very GOOOOOOOOOOOOD at ASM.
Routine:
Spoiler:
Code:

.text
.align 2

main:
        push {r4, lr}
        sub sp, #8
        mov r0, #0x4              @set this to 0x1 or 0x2 for Pokemon_nicknaming and 0x4 for rival (if you change it to Rival im not sure if it will require additional args)
        ldr r1, fcode_buffer
        mov r2, #0
        mov r3, #0
        mov r4, #0
        str r4, [sp]
        adr r4, continue
                add r4, #1
        str r4, [sp, #4]
        ldr r4, display_text
        bl call_via_r4
        add sp, #8
        pop {r4, pc}

.align 2
display_text: .word 0x0809d954|1

continue:
        push {r4, lr}
        ldr r0,fcode_buffer
        ldr r1, real_password
        ldr r1, [r1]
                ldr r4, strcomp
        bl call_via_r4
        cmp r0, #0
        beq matched
        mov r0, #0
        b return

matched:
        mov r0, #1

return:
                ldr r1, var_800D
        strh r0, [r1]
        ldr r4, =0x080568E0|1
        bl call_via_r4
        pop {r4, pc}

call_via_r4:
        bx r4

.align 2
strcomp:      .word 0x08008E28|1
fcode_buffer: .word 0x02021CE0
real_password:.word 0x03000EB0+0x64
var_800D:    .word 0x020370D0



Instruction:
Spoiler:

You can define your password by putting :
loadpointer 0 @password
before the callasm. (note: you can't set your password more than the max Characters in the Input or else it will fail)
#org @password
= yourpass (yes you treat it like a msgstring and also remember the note above)
and what does this do if the input matches your password?
it sets var 0x800D to 1
and if not ViceVersa
and also. instead of defining the password on your script , you can point it out at any address in the rom as long as it's a string that is not more than the max input char.
you can do that by changing the label real_password to the address of your password.

That's it .
and another one , You can also change the "Rival's Name" text or "PKMN name" if you found out how to do that . It'll be really helpful :)
This Routine can be used for many things not just for Password System. You can use it to name People in your game , It's up to you.

and also feel free to ask what is what :D

hi
quick correction
Spoiler:
Code:

        mov r0, #0x4              @set this to 0x1 or 0x2 for Pokemon_nicknaming and 0x4 for rival (if you change it to Rival im not sure if it will require additional args)


00 is player
01 is for box naming
02 is for pokémon
03 is literally 02, maybe used for hatching?
04 is the rival


and now, adding on to it

note: i've not actually gotten the following to work satisfactorily, even when just copying a previous entry directly onto the new one, so i'm considering this incomplete but usable

okay so basically we're going to repoint the table at x3E248C which has 5 pointers. there's exactly one pointer to this table, should be at x9DB58

add a new pointer to at least 12 bytes of free space (not hexadecimal). in these bytes, you're going to put some data.
now, the sequence goes like this:
1 byte - ida lists this as "pre-filled," meaning you could fill in things automatically? neat, no idea how that would work, though
1 byte - length of entry. max is 13 (0D)
1 byte - image index
1 byte - gender icon shown - 00 no, 01 yes
1 byte - this one seems to change what it looks like when the naming screen is accessed, but it always looks like this anyways
http://i.imgur.com/5fbftyO.png
3 unknown bytes
4 bytes - pointer to what the text for the prompt should be (i.e. "YOUR NAME?" "RIVAL's NAME?")

* image index can be one of the following values
00 - nothing shows on the shadow thing
01 - player character, probably changes depending on gender
02 - the pc icon, used for renaming boxes (what i use for the password purpose)
03 - pokémon icon (because no pokémon is loaded in r2, we get the question mark)
04 - gary overworld
05 and above reset the game

and so we go for what i put to simulate the password
00 0A 02 00 01 00 00 00 XX XX XX 08
which means it is not pre-filled, the password is ten characters long, the icon used is the one for the pc, there is no gender icon, the "access screen" is 01, and the text for the prompt is located at 08XXXXXX.

and now for the problem which you all may have caught earlier
http://i.imgur.com/5fbftyO.png
there's no text, leaving this large blank white space. the pointer i mentioned earlier doesn't seem to affect anything. i even took the rival's entry and pasted it over exactly, and... well, here's the results:
http://i.imgur.com/5OBNUPh.png
however, editing earlier entries works just finely
http://i.imgur.com/HobldVU.png

so, um, yeah. happy hacking~

EDIT3: when 0xFB (celebi index) is in r2, we get this when image is set to 03
http://i.imgur.com/KFsrZ78.png
can't figure out other two registers though so uh ahaha

HOPEFULLY final edit:

okay! so now we're going to do this rather hackily but it should work (has worked for my testing).

change the bytes at x47614, x9FD1A, xCC038, and xCC112 from 03 to 02. this makes it so that we can use 03 for our purposes. hatching eggs uses 03, but i'm able to nickname hatched pokémon just finely with 02.
so, x3E248C, the table. repoint x3E2498 to some freespace. at this freespace, fill out your entry:
00 for unfilled, length of entry up to 0D, 03 for loading the pokémon icon, 00 for no gender icon, 01 00 00 00, and then a pointer to ANY byte that is JUST FF. my entry looks like this:
Code:

00 0D 03 00 01 00 00 00 D0 00 00 08


and now the weird part. the pokémon names each have a limit of 10 bytes, right? well, yes, but this routine loads until a FF shows up. so, what we can do is use two pokémon names to have our own custom message!
so, i put BF C8 CE BF CC 00 CA BB CD CD D1 C9 CC BE AD FF (ENTER PASSWORD.) at x2469B4, which is the start of the name of the pokémon index 0xFC, or the empty one right after celebi.
and so we edit the beginning of the routine:
Code:

        mov r0, #0x3              @Type: 0-4 , 4=rival 3=Pokemon
        ldr r1, fcode_buffer
        mov r2, #0xFC            @or whichever pokémon you desire that has your custom icon and message, have to edit the routine a bit if over FF
        mov r3, #0
        mov r4, #0


honestly i'm ashamed that i spent so much time on figuring out this horrible method

and now the product:
http://i.imgur.com/tT7q6FD.png
i changed the icon to a blue ralts to show customizability. but there you have it i guess, certainly a subpar solution but it does the job. a better way would probably have been to point the prompt of a vanilla routine to somewhere in the ram, but that doesn't permit the custom icons.

chestertagat July 15th, 2017 3:28 PM

Quote:

Originally Posted by BluRose (Post 9705917)
hi
quick correction
Spoiler:
Code:

        mov r0, #0x4              @set this to 0x1 or 0x2 for Pokemon_nicknaming and 0x4 for rival (if you change it to Rival im not sure if it will require additional args)


00 is player
01 is for box naming
02 is for pokémon
03 is literally 02, maybe used for hatching?
04 is the rival


and now, adding on to it

note: i've not actually gotten the following to work satisfactorily, even when just copying a previous entry directly onto the new one, so i'm considering this incomplete but usable

okay so basically we're going to repoint the table at x3E248C which has 5 pointers. there's exactly one pointer to this table, should be at x9DB58

add a new pointer to at least 12 bytes of free space (not hexadecimal). in these bytes, you're going to put some data.
now, the sequence goes like this:
1 byte - ida lists this as "pre-filled," meaning you could fill in things automatically? neat, no idea how that would work, though
1 byte - length of entry. max is 13 (0D)
1 byte - image index
1 byte - gender icon shown - 00 no, 01 yes
1 byte - this one seems to change what it looks like when the naming screen is accessed, but it always looks like this anyways
http://i.imgur.com/5fbftyO.png
3 unknown bytes
4 bytes - pointer to what the text for the prompt should be (i.e. "YOUR NAME?" "RIVAL's NAME?")

* image index can be one of the following values
00 - nothing shows on the shadow thing
01 - player character, probably changes depending on gender
02 - the pc icon, used for renaming boxes (what i use for the password purpose)
03 - pokémon icon (because no pokémon is loaded, it is the question mark)
04 - gary overworld
05 and above reset the game

and so we go for what i put to simulate the password
00 0A 02 00 01 00 00 00 XX XX XX 08
which means it is not pre-filled, the password is ten characters long, the icon used is the one for the pc, there is no gender icon, the "access screen" is 01, and the text for the prompt is located at 08XXXXXX.

and now for the problem which you all may have caught earlier
http://i.imgur.com/5fbftyO.png
there's no text, leaving this large blank white space. the pointer i mentioned earlier doesn't seem to affect anything. i even took the rival's entry and pasted it over exactly, and... well, here's the results:
http://i.imgur.com/5OBNUPh.png
however, editing earlier entries works just finely
http://i.imgur.com/HobldVU.png

so, um, yeah. happy hacking~

WTH did you just do? now it's complete :D (Not ,yet :P)
Just wanna add something ,if you wan't to modify the icon and change it to something custom.
Actually you can, How? Change the type to 03, (Pokemon encounter)
now rememeber that it Writes there the Species name and Icon? well , you just need to add your Custom icon and put it somewhere (You add new pokemon actually, Let's you change the icon and Title) .
But to be able to choose Pokemon number you need to put a MOV r2, #thePokemonIndexHere.
That means that argument3 actually becomes the Pokemon Specie number.
You can check out the other Arguments to the funcetion here's what i know:
r0 - type ()
r1 - Pointer to the address you want store the inputted string. in the routine.
r2 - the PokemonIndexNumber

Edit: Not yet complete actually, By choosing 0x3 as type (Pokemon) you can customize the Icon but the Title will Show + nickname at the end of the Custom Title (Pokemon Name)

shanem7 July 18th, 2017 11:19 PM

I have a request:

Can someone help me make wild Pokemon jump at the start of a battle just like how they do on the status screen (Fire Red)? Like how when you view a Pokemon on the status screen in Fire Red they shift/jump slightly up and down. Thanks.

Lunos July 20th, 2017 6:05 AM

Quote:

Originally Posted by shanem7 (Post 9708771)
I have a request:

Can someone help me make wild Pokemon jump at the start of a battle just like how they do on the status screen (Fire Red)? Like how when you view a Pokemon on the status screen in Fire Red they shift/jump slightly up and down. Thanks.

altariaking's "Animated Sprites in Ruby and FireRed" might be what you're looking for.

shanem7 July 20th, 2017 11:26 AM

Quote:

Originally Posted by Lunos (Post 9710026)
altariaking's "Animated Sprites in Ruby and FireRed" might be what you're looking for.

Hmm. It's really not. I'm not looking to animate the sprites but merely to make them 'jump' such as when viewing them from Fire Red's status screen. The code's already there it just needs to be adapted or changed for when there's a battle to make it happen like that. It should be easy enough to do, I just don't know enough ARM, so I posted here hoping to get some help since this doesn't seem to have been done, yet. Thank you for trying, though.

12ab July 21st, 2017 3:34 PM

Quote:

Originally Posted by FBI (Post 8522211)
Yeah, I can fix my OP to have the Emerald version of the routines too (if you provide them :P).


1) I don't know why it's reseting, I haven't tried Darthatron's method and I don't have another method :x
2) This is a text edit. Look for the text string in the ROM and change it.

Player Backsprite swapping



So basically, it just sets your backsprite to another backsprite.

How to insert:

Compile into free space the following routine:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r2, lr}
        ldr r0, .Player
        ldr r0, [r0]
        add r0, r0, #0x8
        ldrb r1, [r0]
        ldr r2, .Save
        strb r1, [r2]
        ldr r1, .Var
        ldrb r1, [r1]
        strb r1, [r0]
        pop {r0-r2, pc}

.align 2
.Player:
        .word 0x300500C
.Var:
        .word 0x20370B8 @0x8000
.Save:
        .word 0x203C231 @save location for current value


Here is a compiled version:
Code:

07 B5 05 48 00 68 08 30 01 78 05 4A 11 70 03 49 09 78 01 70 07 BD C0 46 0C 50 00 03 B8 70 03 02 31 C2 03 02




Usage:

In a script insert:
setvar 0x8000 0x[backsprite number]
callasm 0x[routine +1]

Here is a list of possible backsprite numbers:
Code:

0x0 - Male Hero
0x1 - Female Hero
0x2 - Brendon
0x3 - May
0x4 - Teachy TV guy
0x5 - Old man
Greater than 0x5 - game crash :3


Before using this routine there are a few things you should know about it. There is a limit of 6 possible backsprite swaps including: Male Hero, Female Hero, Brendon, May, Teachy TV guy, Old man.
If you need to have more than 6, then figure that out yourself. Otherwise I would just edit over the existing ones rather than inserting new ones.

The second thing you need to know is that this routine works by changing the Player's gender byte. You need to set it back to normal after you're done with the event, or it will reflect in the overworld in the form of a nice buggy player char.

However, you cannot use the checkgender scripting command to figure this out, because we overwrote that byte. So luckily for you, I already thought of that and decided to write the player's backsprite to RAM offset 0x203C231.

So to set it back, use this after the end of your event:
Code:

copybyte 0x20370B8 0x203C231 '@will put the player's old gender byte in 0x8000
callasm 0x[routine +1]


That's it. Here's a nice video:

If this is possible is it also possible for not only the back sprite but the front sprite used for the trainer card and the overworld sprites simultaneously? I was thinking of having the trainer in Emerald be able to change their clothes to the ones from Ruby and Sapphire if the player wanted.

Blah July 21st, 2017 9:55 PM

Quote:

Originally Posted by 12ab (Post 9711131)
If this is possible is it also possible for not only the back sprite but the front sprite used for the trainer card and the overworld sprites simultaneously? I was thinking of having the trainer in Emerald be able to change their clothes to the ones from Ruby and Sapphire if the player wanted.

The algorithm of changing gender to change the backsprite is fundamentally flawed. But I suppose you can write a small hook to change the front sprite too. Anyways this is years old and I have no intention of updating, much less for Emerald.

Foxes July 27th, 2017 6:38 AM

Quote:

Originally Posted by Spherical Ice (Post 9043890)

Nature-affected stats colouring routines [FR]:


CLICK FOR EMERALD

This is probably the least efficient way to do this, but it works.

Attack:
Code:

.thumb
@ 00 49 08 47 XX XX XX XX at x137134

ldr r1, [r2]
ldrb r2,[r1,#4]
add r2,#0x32
lsl r2,r2,#0x18
lsr r2,r2,#0x18
push {r0-r3}
ldr r0, =(0x0203B140)
ldr r0, [r0]
ldr r2, =(0x3290)
add r0, r0, r2
mov r1, #0
bl decryptbranch
bl getnaturebranch
cmp r0, #1 @ Lonely
beq red
cmp r0, #2 @ Brave
beq red
cmp r0, #3 @ Adamant
beq red
cmp r0, #4 @ Naughty
beq red
cmp r0, #5 @ Bold
beq blue
cmp r0, #10 @ Timid
beq blue
cmp r0, #15 @ Modest
beq blue
cmp r0, #20 @ Calm
beq blue

black:
ldr r6, blackfont
b end

red:
ldr r6, redfont
b end

blue:
ldr r6, bluefont

end:
pop {r0-r3}
ldr r1, =(0x0813713c+1)
bx r1

decryptbranch:
ldr r2, =(0x0803FBE8+1)
bx r2

getnaturebranch:
ldr r2, =(0x08042EB4+1)
bx r2

.align 2
blackfont: .word 0x08463FA4 @ In a vanilla FR ROM, this contains: 00 0E 0A 00
redfont: .word 0x08RRRRRR @ ROM location that contains: 00 01 0A 00
bluefont: .word 0x08BBBBBB @ ROM location that contains: 00 07 0A 00


Defense:
Code:

.thumb
@ 00 49 08 47 XX XX XX XX at x137158

ldr r1, [r2]
ldrb r2,[r1,#6]
add r2,#0x32
lsl r2,r2,#0x18
lsr r2,r2,#0x18
push {r0-r3}
ldr r0, =(0x0203B140)
ldr r0, [r0]
ldr r2, =(0x3290)
add r0, r0, r2
mov r1, #0
bl decryptbranch
bl getnaturebranch
cmp r0, #1 @ Lonely
beq blue
cmp r0, #5 @ Nold
beq red
cmp r0, #7 @ Relaxed
beq red
cmp r0, #8 @ Impish
beq red
cmp r0, #9 @ Lax
beq red
cmp r0, #11 @ Hasty
beq blue
cmp r0, #16 @ Mild
beq blue
cmp r0, #21 @ Gentle
beq blue

black:
ldr r6, blackfont
b end

red:
ldr r6, redfont
b end

blue:
ldr r6, bluefont

end:
pop {r0-r3}
ldr r1, =(0x08137162+1)
bx r1

decryptbranch:
ldr r2, =(0x0803FBE8+1)
bx r2

getnaturebranch:
ldr r2, =(0x08042EB4+1)
bx r2

.align 2
blackfont: .word 0x08463FA4 @ In a vanilla FR ROM, this contains: 00 0E 0A 00
redfont: .word 0x08RRRRRR @ ROM location that contains: 00 01 0A 00
bluefont: .word 0x08BBBBBB @ ROM location that contains: 00 07 0A 00


Special Attack:
Code:

.thumb
@ 00 49 08 47 XX XX XX XX at x13717C

mov r2,r8
ldr r1, [r2]
ldrb r2,[r1,#8]
add r2,#0x32
lsl r2,r2,#0x18
lsr r2,r2,#0x18
push {r0-r3}
ldr r0, =(0x0203B140)
ldr r0, [r0]
ldr r2, =(0x3290)
add r0, r0, r2
mov r1, #0
bl decryptbranch
bl getnaturebranch
cmp r0, #3 @ Adamant
beq blue
cmp r0, #8 @ Impish
beq blue
cmp r0, #13 @ Jolly
beq blue
cmp r0, #15 @ Modest
beq red
cmp r0, #16 @ Mild
beq red
cmp r0, #17 @ Quiet
beq red
cmp r0, #19 @ Rash
beq red
cmp r0, #23 @ Careful
beq blue

black:
ldr r6, blackfont
b end

red:
ldr r6, redfont
b end

blue:
ldr r6, bluefont

end:
pop {r0-r3}
ldr r1, =(0x08137188+1)
bx r1

decryptbranch:
ldr r2, =(0x0803FBE8+1)
bx r2

getnaturebranch:
ldr r2, =(0x08042EB4+1)
bx r2

.align 2
blackfont: .word 0x08463FA4 @ In a vanilla FR ROM, this contains: 00 0E 0A 00
redfont: .word 0x08RRRRRR @ ROM location that contains: 00 01 0A 00
bluefont: .word 0x08BBBBBB @ ROM location that contains: 00 07 0A 00


Special Defense:
Code:

.thumb
@ 00 49 08 47 XX XX XX XX at x1371A4

ldr r1, [r2]
ldrb r2,[r1,#0xA]
add r2,#0x32
lsl r2,r2,#0x18
lsr r2,r2,#0x18
push {r0-r3}
ldr r0, =(0x0203B140)
ldr r0, [r0]
ldr r2, =(0x3290)
add r0, r0, r2
mov r1, #0
bl decryptbranch
bl getnaturebranch
cmp r0, #4 @ Naughty
beq blue
cmp r0, #9 @ Lax
beq blue
cmp r0, #14 @ Naive
beq blue
cmp r0, #19 @ Rash
beq blue
cmp r0, #20 @ Calm
beq red
cmp r0, #21 @ Gentle
beq red
cmp r0, #22 @ Sassy
beq red
cmp r0, #23 @ Careful
beq red

black:
ldr r6, blackfont
b end

red:
ldr r6, redfont
b end

blue:
ldr r6, bluefont

end:
pop {r0-r3}
ldr r1, =(0x081371AE+1)
bx r1

decryptbranch:
ldr r2, =(0x0803FBE8+1)
bx r2

getnaturebranch:
ldr r2, =(0x08042EB4+1)
bx r2

.align 2
blackfont: .word 0x08463FA4 @ In a vanilla FR ROM, this contains: 00 0E 0A 00
redfont: .word 0x08RRRRRR @ ROM location that contains: 00 01 0A 00
bluefont: .word 0x08BBBBBB @ ROM location that contains: 00 07 0A 00


Speed:
Code:

.thumb
@ 00 49 08 47 XX XX XX XX at x1371C8

mov r2,r8
ldr r1, [r2]
ldrb r2,[r1,#0xC]
add r2,#0x32
lsl r2,r2,#0x18
lsr r2,r2,#0x18
push {r0-r3}
ldr r0, =(0x0203B140)
ldr r0, [r0]
ldr r2, =(0x3290)
add r0, r0, r2
mov r1, #0
bl decryptbranch
bl getnaturebranch
cmp r0, #2 @ Brave
beq blue
cmp r0, #7 @ Relaxed
beq blue
cmp r0, #10 @ Timid
beq red
cmp r0, #11 @ Hasty
beq red
cmp r0, #13 @ Jolly
beq red
cmp r0, #14 @ Naive
beq red
cmp r0, #17 @ Quiet
beq blue
cmp r0, #22 @ Sassy
beq blue

black:
ldr r6, blackfont
b end

red:
ldr r6, redfont
b end

blue:
ldr r6, bluefont

end:
pop {r0-r3}
ldr r1, =(0x081371d4+1)
bx r1

decryptbranch:
ldr r2, =(0x0803FBE8+1)
bx r2

getnaturebranch:
ldr r2, =(0x08042EB4+1)
bx r2

.align 2
blackfont: .word 0x08463FA4 @ In a vanilla FR ROM, this contains: 00 0E 0A 00
redfont: .word 0x08RRRRRR @ ROM location that contains: 00 01 0A 00
bluefont: .word 0x08BBBBBB @ ROM location that contains: 00 07 0A 00


Reverting the font colour back to black:
Code:

.thumb
@ 00 49 08 47 XX XX XX XX at 081371F0

ldr r1, [r2]
ldrb r2,[r1,#0xE]
add r2,#0xF
lsl r2,r2,#0x18
lsr r2,r2,#0x18
ldr r6, blackfont
ldr r1, =(0x081371FA+1)
bx r1

.align 2
blackfont: .word 0x08463FA4 @ In a vanilla FR ROM, this contains: 00 0E 0A 00


where XX XX XX XX is the location of each routine +1.

This colours the stat increased by the Pokémon's nature red, and the stat that is decreased blue.

http://i.imgur.com/8IfVLeT.pnghttp://i.imgur.com/ltTHc6K.png

Edit: Updated 23/12/2015, the old routines had a few errors that I forgot to update after making changes to my ROM. I've also confirmed what bluefont should be in a vanilla ROM. Enjoy!

Sorry for being dumb, but how do I actually implement this into the game?

Sakib66 July 27th, 2017 6:54 AM

Quote:

Originally Posted by Gameskiller01 (Post 9716626)
Sorry for being dumb, but how do I actually implement this into the game?

use TL's quick enhancer tool

Lunos July 27th, 2017 8:19 AM

Quote:

Originally Posted by Sakib66 (Post 9716640)
use TL's quick enhancer tool

The_Learner removed the DL Link until the next update because its modifications were messing some people's ROMs.

Quote:

Originally Posted by kleenexfeu (Post 8925169)
I know there's several routines like this one, but I didn't found them practical.

Check a specific pokémon with a specific slot through the use of Special 0xA2, for Emerald :
Spoiler:

Code:

.thumb

Start:
    push {r0-r7, lr}
    ldr r6, var8005
    ldr r0, party_amount
    ldrb r4, [r0]
    cmp r4, #0x0
    beq End
    ldrh r3, [r6]
    cmp r3, #0x0
    beq End
Check:
    add r0, #3
    mov r1, #0x64
    ldr r7, var8004
    ldrb r6, [r7]
    mul r1, r6
    add r0, r0, r1
    push {r0-r7}
    mov r1, #0xB
    ldr r2, decrypt_poke
    bl Jump
    mov r9, r0
    pop {r0-r7}
    cmp r9, r3
    bne NoSuccess
    mov r6, #1
    b Success
NoSuccess:
    mov r6, #0
Success:
    ldr r7, var8005
    strh r6, [r7]

End:
    pop {r0-r7, pc}
Jump:
mov pc, r2

.align 2
party_amount:    .word 0x020244E9
var8004:        .word 0x020275D8 + (0x8004*2)
var8005:        .word 0x020275D8 + (0x8005*2)
decrypt_poke:    .word 0x0806A519

/*var 0x8005, species you want to check*/


Basically, when you use special 0xA2, the party screen open and you can select a poke, the slot of the poke is stored in var 0x8004, so the routine check this slot.
If it is the the same species than 0x8005, then 0x8005 is set to 1, otherwise to 0

The routine has apparently some flaws.
They were fixed by @Squeetz in the community's Discord.
I don't know a single thing about ASM, but I thought someone needed to bring this up in case anyone wanted to use it.
Code:

.thumb

Start:
    push {r0-r7, lr}
    ldr r6, var8005
    ldr r0, party_amount
    ldrb r4, [r0]
    cmp r4, #0x0
    beq End
    ldrh r3, [r6]
    cmp r3, #0x0
    beq End
Check:
    ldr r0, party_player
    mov r1, #0x64
    ldr r7, var8004
    ldrb r6, [r7]
    mul r1, r6
    add r0, r0, r1
    push {r0-r7}
    mov r1, #0xB
    ldr r2, decrypt_poke
    bl Jump
    mov r9, r0
    pop {r0-r7}
    cmp r9, r3
    bne NoSuccess
    mov r6, #1
    b Success
NoSuccess:
    mov r6, #0
Success:
    ldr r7, var8005
    strh r6, [r7]

End:
    pop {r0-r7, pc}
Jump:
mov pc, r2

.align 2
party_amount:    .word 0x020244E9
var8004:        .word 0x020275D8 + (0x8004*2)
var8005:        .word 0x020275D8 + (0x8005*2)
decrypt_poke:    .word 0x0806A519
party_player:  .word 0x020244EC

/*var 0x8005, species you want to check*/



ghoulslash July 27th, 2017 8:22 AM

Quote:

Originally Posted by Gameskiller01 (Post 9716626)
Sorry for being dumb, but how do I actually implement this into the game?

I would suggest learning how to compile and insert assembly instead of relying on tools.

1. First, you'll want to download HackMew's thumb compiler, found on this page.

2. Then, save the files you quoted individually as [filename].asm, eg. attack.asm. Using the windows command prompt, type 'thumb [filename].asm [filename].bin' in the same directory as your .asm file and the compiler. Then, open the .bin file with a hex editor, and insert into free space, making sure the offset ends in a 0,4,8, or C. With these particular routines, you'll need to also insert [00 01 0A 00] for red font and [00 07 0A 00] for blue font, somewhere in your rom, and then change the pointer at the bottom of each routine to the location of each 4bytes string. So, if you inserted 00 07 0A 00 at 0x123456, 0x08BBBBBB would become 0x08123456.

3. At the top of each assembly routine you're trying to insert, there is an insertion instruction that has been commented out, eg. @ 00 49 08 47 XX XX XX XX at x137134 in the attack.asm routine. This means, at offset 0x137134 you type the above hex, where XX XX XX XX is a reverse pointer (+1) to the location of the attack.bin hex you inserted into free space from step 2. For example, if you inserted attack.bin at 0x987654, for example, XX XX XX XX will be 55 76 98 08.

Do this for each routine and you should be all set!

I hope this helps. let me know if you have any issues.

Foxes July 29th, 2017 3:01 AM

Quote:

Originally Posted by ghoulslash (Post 9716685)
I would suggest learning how to compile and insert assembly instead of relying on tools.

1. First, you'll want to download HackMew's thumb compiler, found on this page.

2. Then, save the files you quoted individually as [filename].asm, eg. attack.asm. Using the windows command prompt, type 'thumb [filename].asm [filename].bin' in the same directory as your .asm file and the compiler. Then, open the .bin file with a hex editor, and insert into free space, making sure the offset ends in a 0,4,8, or C. With these particular routines, you'll need to also insert [00 01 0A 00] for red font and [00 07 0A 00] for blue font, somewhere in your rom, and then change the pointer at the bottom of each routine to the location of each 4bytes string. So, if you inserted 00 07 0A 00 at 0x123456, 0x08BBBBBB would become 0x08123456.

3. At the top of each assembly routine you're trying to insert, there is an insertion instruction that has been commented out, eg. @ 00 49 08 47 XX XX XX XX at x137134 in the attack.asm routine. This means, at offset 0x137134 you type the above hex, where XX XX XX XX is a reverse pointer (+1) to the location of the attack.bin hex you inserted into free space from step 2. For example, if you inserted attack.bin at 0x987654, for example, XX XX XX XX will be 55 76 98 08.

Do this for each routine and you should be all set!

I hope this helps. let me know if you have any issues.

Thank you! This kind of simple, easy to follow tutorial on how to insert ASM is exactly what I've been looking for! I'll try it now and see if it works.

EDIT: So when I try that, I get this error.
Quote:

attack.asm: Assembler messages:
attack.asm:0: Warning: end of file in comment; newline inserted
attack.asm:60: Error: junk at end of line, first unrecognized character is `R'
EDIT #2: nvm, I figured out that I had to insert the redfont and bluefont and change the .asm file to show where they are.

EDIT #3: So, if I put the hex for attack.bin at 0x71A6B0, XX XX XX XX would be B1 A6 71 08?

EDIT #4: It works! Thanks! Yours is the only tutorial for inserting ASM that I could actually follow and understand.

tkim July 29th, 2017 11:25 AM

Request for FR:

Volt Tackle by breeding with either parent holding a Light Ball.

Foxes July 30th, 2017 5:07 AM

Request for Platinum:

Having coloured stats based on natures. I don't know if this could be done by editing the ASM used to implement this into FireRed and changing the offsets or if they are just too different.

Either way, I think more work needs to be done on hacking 4th gen games, and I'd be happy to help (although I am very dumb). I'm currently looking into editing the hex of the 4th gen games but there doesn't seem to be any documentation on ASM for 4th gen and very little documentation on hex for 4th gen. If someone smarter than me can give me a good starting point as to where I could learn how to find out how to do this (if that makes any sense) I would be more than willing to learn.

Lunos July 30th, 2017 5:40 AM

Quote:

Originally Posted by esperance (Post 8865635)
This thread is for the development of new assembly routines and hacks based off of the requests of users. Feel free to make requests.

With that being said, would a Custom Wildbattle like this one, but that also allows you to choose the Battle Background be possible for FireRed?

ShyGuy25 August 1st, 2017 12:09 AM

Dumb question but what program is used to compile the ASM routines?

Foxes August 1st, 2017 1:46 AM

Quote:

Originally Posted by ShyGuy25 (Post 9719906)
Dumb question but what program is used to compile the ASM routines?

This easy to follow tutorial is what I used to be able to do it (with extremely little prior knowledge on the subject).

Quote:

Originally Posted by ghoulslash (Post 9716685)
I would suggest learning how to compile and insert assembly instead of relying on tools.

1. First, you'll want to download HackMew's thumb compiler, found on this page.

2. Then, save the files you quoted individually as [filename].asm, eg. attack.asm. Using the windows command prompt, type 'thumb [filename].asm [filename].bin' in the same directory as your .asm file and the compiler. Then, open the .bin file with a hex editor, and insert into free space, making sure the offset ends in a 0,4,8, or C. With these particular routines, you'll need to also insert [00 01 0A 00] for red font and [00 07 0A 00] for blue font, somewhere in your rom, and then change the pointer at the bottom of each routine to the location of each 4bytes string. So, if you inserted 00 07 0A 00 at 0x123456, 0x08BBBBBB would become 0x08123456.

3. At the top of each assembly routine you're trying to insert, there is an insertion instruction that has been commented out, eg. @ 00 49 08 47 XX XX XX XX at x137134 in the attack.asm routine. This means, at offset 0x137134 you type the above hex, where XX XX XX XX is a reverse pointer (+1) to the location of the attack.bin hex you inserted into free space from step 2. For example, if you inserted attack.bin at 0x987654, for example, XX XX XX XX will be 55 76 98 08.

Do this for each routine and you should be all set!

I hope this helps. let me know if you have any issues.

If you run into any problems, just look at the edits I made to my response to that message. It's probable that you may come across the same problems as I did.

Quote:

Originally Posted by Gameskiller01 (Post 9718002)
EDIT: So when I try that, I get this error.
Quote:

attack.asm: Assembler messages:
attack.asm:0: Warning: end of file in comment; newline inserted
attack.asm:60: Error: junk at end of line, first unrecognized character is `R'
EDIT #2: nvm, I figured out that I had to insert the redfont and bluefont and change the .asm file to show where they are.

EDIT #3: So, if I put the hex for attack.bin at 0x71A6B0, XX XX XX XX would be B1 A6 71 08?

EDIT #4: It works! Thanks! Yours is the only tutorial for inserting ASM that I could actually follow and understand.


tkim August 3rd, 2017 5:07 PM

1 Attachment(s)
[FR] Volt Tackle port from EM:

If you have free space from 0x270670-0x270741 (0xD2 bytes), use the IPS patch I provide here. ...It's a long story, so I will expand on this when I get the time. Fully working, I promise. You're gonna love it.

edit: A bit of explanation now: I took a look at an Emerald disassembly and found the routine that calls to check if the egg at the Day-Care is a pichu and if either of the parents are holding a Light Ball. I ported that exact routine into FR, but I had to make a copy of the routine at sub_80460D4 as to include the pichu check. Then I had to make special 0xB8 call the new routine instead of sub_80460D4. Since I had made a copy of the routine I also had to make sure the new routine used all the same offsets as before, and therefore I placed the routine at 0x270670, which I happened to have free space. I wanted to place the routine at something like 0x760000 or higher, but the old offsets wouldn't work any more. Down below are the uncompiled stuff:

This routine (located at 0x270670 in my patch) is a copy of the routine at 0x0460D4 but now includes the pichu egg check (in orange):
Code:

sub_80460D4:                @ CODE XREF: sp0B8_daycare+Cp

var_18        = -0x18
var_14        = -0x14

        PUSH    {R4-R6,LR}
        SUB    SP, SP,    #0x6C
        ADD    R5, R0,    #0
        ADD    R6, SP,    #0x7C+var_18
        ADD    R1, R6,    #0
        BL    sub_8046000
        ADD    R4, SP,    #0x7C+var_14
        STRH    R0, [R4]
        ADD    R0, R4,    #0
        ADD    R1, R5,    #0
        BL    incense_effects
        LDRH    R1, [R4]
        MOV    R0, SP
        ADD    R2, R5,    #0
        BL    sub_8046208
        MOV    R0, SP
        ADD    R1, R5,    #0
        BL    sub_8045AC0
        LDRB    R0, [R6,#1]
        MOV    R2, #0x8C @ '?'
        ADD    R1, R0,    #0
        MUL    R1, R2
        ADD    R1, R5,    R1
        LDRB    R0, [R6]
        MUL    R2, R0
        ADD    R2, R5,    R2
        MOV    R0, SP
        BL    daycare_build_child_moveset
        ldrh r0, [r4]
        cmp r0, #0xAC
        bne _08070918
        mov r0, sp
        add r1, r5, #0
        bl sub_82706FC
_08070918:

        MOV    R2, SP
        ADD    R2, #0x6A @ 'j'
        MOV    R0, #1
        STRB    R0, [R2]
        MOV    R0, SP
        MOV    R1, #0x2D @ '-'
        BL    pokemon_setattr
        LDR    R0, off_804614C
        MOV    R1, #0xFA @ '?'
        LSL    R1, R1,    #1
        ADD    R0, R0,    R1
        MOV    R1, SP
        MOV    R2, #0x64 @ 'd'
        BL    memcpy
        BL    party_compaction
        BL    party_count_pokemon
        ADD    R0, R5,    #0
        BL    sub_8045F70
        ADD    SP, SP,    #0x6C
        POP    {R4-R6}
        POP    {R0}
        BX    R0
@ End of function sub_80460D4

@ ---------------------------------------------------------------------------
.align 2
off_804614C:    .long 0x2024284        @ DATA XREF: sub_80460D4+52r


This routine (located at 0x2706FC in my patch) handles the volt tackle inheriting:
Code:

sub_80707A4:
    push {r4-r6,lr}
    add r5, r0, #0
    add r4, r1, #0
    add r0, r4, #0
    mov r1, #0xC
    bl pokemon_getattr_encrypted
    add r6, r0, #0
    add r4, #0x8C
    add r0, r4, #0
    mov r1, #0xC
    bl pokemon_getattr_encrypted
    cmp r6, #0xCA
    beq _080707C6
    cmp r0, #0xCA
    bne _080707E2

_080707C6:
    mov r4, #0xAC
    lsl r4, r4, #0x1
    add r0, r5, #0
    add r1, r4, #0
    bl pokemon_moveset_pad_
    lsl r0, r0, #0x10
    ldr r1, =(0xffff0000)
    cmp r0, r1
    bne _080707E2
    add r0, r5, #0
    add r1, r4, #0
    bl sub_803EB94

_080707E2:
    pop {r4-r6}
    pop {r0}
    bx r0


This last one makes sure the old offsets work correctly from the new offsets:
Code:

.text
.align 2
.thumb
.thumb_func

.org 0x0462B8
bl 0x270670

.org 0x27067A
bl 0x046000

.org 0x270686
bl 0x045FA0

.org 0x270690
bl 0x046208

.org 0x270698
bl 0x045AC0

.org 0x2706AE
bl 0x045CD0

.org 0x2706BC
bl 0x2706FC

.org 0x2706CC
bl 0x04037C

.org 0x2706DC
bl 0x1E5E78

.org 0x2706E0
bl 0x0937DC

.org 0x2706E4
bl 0x040C3C

.org 0x2706EA
bl 0x045F70

.org 0x270706
bl 0x03FD44

.org 0x270712
bl 0x03FD44

.org 0x270726
bl 0x03E89C

.org 0x270736
bl 0x03EB94


If anybody has a better way of porting this, please post it here.
edit2: I could probably just use bx r3?

tkim August 8th, 2017 1:46 PM

Quote:

Originally Posted by DizzyEgg (Post 9171350)
Pokemon Emerald Multichoice Scrolling Box

Spoiler:
So, the mechanic for that is already implemented, we just have to repoint some tables. So let's get down to work.
First, there's a table at 0x085B2CF0. Each entry is a pointer to text to be displayed in the box. One set consist of 16 options. This is important. Anyway, repoint to free space and change pointers to this table. It ends at 0x085B3030.

Now, there's a jumptable at 0x813A156. It ends at 0x0813A19C. It has 12 entries, repoint it to free space. Now for every new set of options you want to add, you have to add a routine like this:
Spoiler:

Code:

.text
.thumb
.thumb_func
.align 2

main:
    mov r0, #5
    strh r0, [r3, #8] @how many are displayed
    mov r0, #8
    strh r0, [r3, #0xA] @how many are in total
    mov r0, #1
    strh r0, [r3, #0xC] @X coordinate
    mov r0, #1
    strh r0, [r3, #0xE] @Y coordinate
    mov r0, #9
    strh r0, [r3, #0x10] @unkown
    mov r0, #0xA
    strh r0, [r3, #0x12] @box height, should be displayed * 2
    mov r0, #0
    strh r0, [r3, #0x14] @unkown
    strh r4, [r3, #0x26] @task id, don't change it
    pop {r4}
    pop {r0}
    bx r0




Note that you can change parameters in those routines. Play with them and see which ones look the best for you. Now, every routine like that above, goes at the end of the repointed jumptable. There are 12-in game sets, so you'll start with 13. Change the byte at 0x813A148 to the amount of all sets.

One more thing, even though the table of pointers to text can only hold 16 pointers, it doesn't mean you're limited to only that many options. You can go to 126 max, because 127 is treated as hitting B. How? Well, in the routine above set how many in total to the amount you want and ignore occupied slots. For example if you want your set to have 50 options, divide it by 16, so you get 3 and some remainder. That means this set occupies 4 places in the jumptable, like this:
XX XX XX 08 00 00 00 00 00 00 00 00 00 00 00 00 NEW SET GOES HERE

Using it in a script is easy, just do this:
setvar 0x8004 slot in the jumptable (starts at 13, since 12 are already occupied in-game)
special 0x1BE
waitstate
Result is stored in the 0x800D. First option chosen is 0, second is 1, and so on. Hitting B be is 0x7F.
compare 0x800D 0x0
if 0x1 goto @first_option
....
compare 0x800D 0x7F
if 0x1 goto @chose_cancel

I hope everything's understandable. :)

I'm having a bit of trouble getting this to work. First of all, isn't the jumptable at 0x813A168 and not 0x813A156? I can repoint 0x813A168, but not your given 0x813A156. Second, I can only get the default choices to work. Anything above 12 (0xC) won't work for me. As soon as special 0x1BE is called ingame with a value of 0xD or more, the game freezes without the list showing up at all.

Here's the steps I did in order:

- repointed the first table located at 0x5B2CF0 to 0xDE43E0 and changed two pointers.
- repointed the jumptable located at 0x13A168 (instead of 0x13A156 as I couldn't find the pointers for it) to 0xDE4760 and changed one pointer.
- compiled your routine and inserted at 0xDE4794 (which is right after the repointed jumptable)
- added new entry (6 pre-existing pointers) to 0xDE4720.
- changed the byte at 0x813A148 from 0xC to 0xD.

Froosty August 9th, 2017 3:37 AM

DIFFERENT PALS FOR THE MALE AND FEMALE BAG [FR]
Thanks to KDS for helping me fix the error. :)
Insert this code:
Spoiler:

/* at 108340 put 00 48 00 47 (insert loc of this routine +1) */

.text
.align 2
.thumb

main:
ldr r0, =(0x0300500C)
ldr r0, [r0]
ldrb r0, [r0, #0x8]
cmp r0, #0x0
bne female
ldr r0, male_pal
b pal_load_maybe

female:
ldr r0, female_pal
b pal_load_maybe

pal_load_maybe:
ldr r1, handling_something
bl call_via_r1
ldr r1, return_loc
bx r1

call_via_r1:
bx r1

.align 2
male_pal: .word 0x08XXXXXX
female_pal: .word 0x08YYYYYY
handling_something: .word 0x0800ec28|1
return_loc: .word 0x08108352|1

Code:

XXXXXX is the pointer to AA AA AA 08 64 00
YYYYYY is the pointer to BB BB BB 08 64 00

where,
AA AA AA 08 is pointer to compressed male bag pallete
BB BB BB 08 is pointer to compressed female bag pallete




example:
Spoiler:
I insreted compressed pals at 900000 and 900030 and the routine at 800000,
so have a look at my rom data.
https://i.imgur.com/pl3ee2A.png
NOTE: you dont need to leave spaces between bytes, I did that just to make it easier to understand

AkameTheBulbasaur August 9th, 2017 9:04 PM

Scaled Experience Formula

In Generation V, a new way of determining the Experience Points gained after Battle was introduced. Previously, the Experience Formula was a flat one, which did not change based on Level Differences between your Pokemon and the other one.

In Black & White, they used a Scaled Experience Formula, which would cause your Pokemon to gain more experience if their opponent was a higher Level, and less if their opponent was a lower one.

Today, I am sharing a way to have this sort of Scaled Experience Points in Fire Red or Emerald. I have included the download link to a folder which contains four items.

Folder: (Download)
  1. The Routine (For Fire Red)
  2. The Routine (For Emerald)
  3. Think0028's Experience All Patch
  4. An Instruction Manual

The Instruction Manual explains how the routine works and any extra information that is necessary to know (particularly if you would like to modify this routine for your specific hack).

Important:
Considering I first uploaded the first version of this routine a long time ago, you may have an older version of it. This version may be preferable to that one, and it is smaller than the previous version is. Therefore, one can simply insert it over the old version and not have to repoint anything.

Extra Information

This routine is compatible with Think0028's Experience All Patch. His original download link is unfortunately broken, hence why I put it in the download folder. If it was still active, I would have linked directly to it.

If you inserted the Disable Experience Gain With Flag routine, originally by FBI, then you may wish to remove it, as this routine implements it. I am not sure if there is a conflict due to this, but at the very least there is a redundant check if you have two routines which both check the same Flag. It is also possible that this routine bypasses that one entirely, in which case you would want to remove it to avoid wasting space.

Thanks and credits to FBI for that original routine, as without it I would likely not have been able to find the correct branching address for this routine.

As I have nowhere else to post this information, I will say here that to remove the 1.5x Experience Boost you get for defeating a Pokemon in a Trainer Battle (like they did in Generation VII), do the following:

Put 07 E0 at 0x21DD8 (FireRed) or 0x4A698 (Emerald)

Put 1C E0 at 0x21E00 (FireRed) or put 28 E0 at 0x4A6C0 (Emerald)

Lunos August 10th, 2017 12:18 PM

The two requests I ever made over here were in vain.. allow me to try another one instead.
How about a port of JPAN's Overworld Hacks to Emerald?
I'm looking for a way to basically change a character's Front sprite, Back sprite and OWs to another one until I revert things back to how it was manually with another command.

Hotice03 August 11th, 2017 7:36 PM

I need help making an eeveelution evolution happen i need it made so when an eevee faints in battle and then you feed it a rare candy while its fainted after battle it evolves into a ghost type eeveelution

AkameTheBulbasaur August 11th, 2017 10:31 PM

Quote:

Originally Posted by Hotice03 (Post 9729572)
I need help making an eeveelution evolution happen i need it made so when an eevee faints in battle and then you feed it a rare candy while its fainted after battle it evolves into a ghost type eeveelution

This is just off the top of my head, so I haven't tested this or anything, but it should give you a head start.

First here's a link to a tutorial on how to add new evolution methods.

https://www.pokecommunity.com/showthread.php?t=329357

Second, you need a way to check if a Pokémon in your party is fainted. You can check the current HP of a Pokémon using the RAM offsets I posted here.

ldr r1, .FirstPoke
mov r1, #0x39
bl Decrypt
cmp r0, #0x0
beq Evolve

.FirstPoke is the first RAM offset in the lists I posted under the "Yours" heading. Basically what this little snippet does is it checks the current HP of the first Pokémon in your party and compares it to zero. If it's zero, the Pokémon is fainted and you can then branch to the next thing. You can change the party slot it checks, but ideally you would want a way for the code to know which Pokemon you selected.

It might help to look through the evolution routines posted in the tutorial and see how they're structured.

That's all I can really do without doing testing first, but that will have to wait until later because it's 2:30 in the morning as I'm posting this. PM me later if you still need help.

Derlo August 22nd, 2017 1:08 PM

Hello, I would like to request a hook routine to be added to the original TM's routine.
The new routine would be activated when the TM's were used and deleted, so a new item would be created in the ITEN bag.
If possible, include checking if the bag is full. If yes, discard new item.
Thanks in advance.

Enn August 24th, 2017 5:38 AM

Quote:

Originally Posted by Derlo (Post 9737411)
Hello, I would like to request a hook routine to be added to the original TM's routine.
The new routine would be activated when the TM's were used and deleted, so a new item would be created in the ITEM bag.
If possible, include checking if the bag is full. If yes, discard new item.
Thanks in advance.

Hello,
I think reuable tms are already done, if thats what you need...

Lunos August 24th, 2017 5:57 AM

Quote:

Originally Posted by Nisarg (Post 9738370)
Hello,
I think reuable tms are already done, if thats what you need...

It looks like he wants an item to be created after a TM is used and naturally deleted.
He didn't mentioned if he wants the exact TM to be created yet again, so I'd say he's not looking for reusable TMs.

Derlo August 24th, 2017 1:16 PM

Quote:

Originally Posted by Nisarg (Post 9738370)
Hello,
I think reuable tms are already done, if thats what you need...

Quote:

Originally Posted by Lunos (Post 9738386)
It looks like he wants an item to be created after a TM is used and naturally deleted.
He didn't mentioned if he wants the exact TM to be created yet again, so I'd say he's not looking for reusable TMs.

In fact what I need is to maintain the original routine that deletes the TM after use and add the creation of an item along with the TM exclusion.
Example: After using any TM, it is deleted from TM CASE and creates a NUGGET in the player bag.
And if possible show the informed message where the new item will be in the bag.

Koople August 25th, 2017 6:24 AM

Fixing some major bugs/oversights with this routine seemed worthy of a new post so anyone who has implemented it can notice the changes:

Adding a Dodge Rate for Catching Wild Pokemon [FR]

This routine uses the wild pokemon's base speed stat to calculate a probability that it will dodge a thrown pokeball (nominally ~5-10%)

(credits to Urz, shanem7, and ghoulslash for bug finding, scripting, and testing!)

Important Routine Notes:
  • This routine does not affect Safari Balls
  • In its current form, the Master Ball skips all dodge rate checks (can be changed easily)
  • The hook address may have changed from previous routine versions. Make sure you are using the correct hook address!

Insertion Instructions:
  1. Insert custom 'dodging' message at 0xXXYYZZ. This is what will be displayed when the Pokemon dodges your thrown Poke Ball
  2. Insert the following custom battle script at 0x08XXXXXX (requires the setword command. Also add #command cmdF6 0xF6 to commands.bsh file)
    Quote:

    waitmessage 0x40
    setword 0x203C020 0x08XXYYZZ
    printstring 0x184
    waitmessage 0x40
    cmdF6
  3. Replace .Message: word 0x8XXXXXX in the assembly routine below with the offset you compiled this battle script in
  4. Compile and insert the routine in free space (0x08TTUUVV)
  5. Insert 00 48 00 47 (VV+1) UU TT 08 at 0802D508

The Routine:
Code:

.text
.align 2
.thumb
.thumb_func

Main:
        ldr r1, .BallThrown
        ldrb r0, [r1]
        cmp r0, #0x1          @master ball
        bne OtherBall
        ldr r0, =(0x03004F90)
        ldr r1, =(0x0802D688 +1)
        bx r1

OtherBall:
        ldr r6, .TargetBank
        ldrb r0, [r6]
        ldr r1, .SpecialStatus
        lsl r0, r0, #0x2
        add r2, r1, r0
        ldr r0, [r2]
        ldr r1, =(0x000400C0)        @fly/dig/bounce/dive status flags
        and r0, r1
        cmp r0, #0x0
        bne DodgeBall    @auto dodge if offscreen
        ldrb r0, [r2, #0x1]
        mov r1, #0x4
        and r0, r1
        cmp r0, #0x0
        bne NoDodge        @ingrain -> cant dodge
        ldrb r0, [r6]
        mov r1, #0x58
        mul r0, r1
        ldr r1, .BattleStruct
        add r5, r1, r0
        mov r0, #0x4C
        add r0, r5, r0
        ldrb r1, [r0, #0x7]
        mov r2, #0x1
        and r1, r2
        cmp r1, #0x0
        bne DodgeBall    @substitute on -> auto dodge
        ldrb r1, [r0, #0x3]
        cmp r1, #0x20
        beq NoDodge        @frozen = can't dodge
        mov r2, #0x7
        and r1, r2
        cmp r1, #0x0
        bne NoDodge        @target is asleep -> cant dodge

GetThreshold:
        ldrh r0, [r5]
        mov r1, #0x1C
        mul r0, r0, r1
        ldr r1, .BaseStats
        add r0, r0, r1
        ldrb r0, [r0, #0x3]                @r0 = wild pokemon base speed
        mov r1, #0xA                @number to divide base speed by (change if you want)
        bl div_func                        @r0 =  base speed / 10
        mov r1, #0xD                @r1 = 13 (lower limit ~5% - change if you want)
        add r1, r0, r1                @r1 = 13 + base_speed/10 = base threshold

CheckParalysis:
        mov r0, r5
        add r0, #0x4F
        ldrb r0, [r0]
        cmp r0, #0x40
        bne CheckWrap
        lsr r1, r1, #0x1        @if pokemon paralyzed, its dodge rate is halved

CheckWrap:
        mov r0, r5
        add r0, #0x51
        ldrb r0, [r0]
        mov r2, #0xE0
        and r0, r2
        cmp r0, #0x0
        beq CheckDodge
        lsr r2, r1, #0x2
        sub r1, r1, r2                @3/4 dodge rate if trapped by wrap effect

CheckDodge:
        mov r3, r1
        bl rand_func
        lsr r0, r0, #0x8
        cmp r0, r3
        bls DodgeBall        @if r0 <= threshold value, the pokemon dodges the ball

NoDodge:
        ldr r3, .BaseStats        @replaced routine from hook
        ldr r2, .BattleStruct
        ldrb r1, [r6]
        mov r0, #0x58
        ldr r5, =(0x0802D510 +1)        @return to original routine
        bx r5

div_func:
        ldr r2, .Divide
        bx r2

rand_func:
        ldr r2, .Rand
        bx r2

DodgeBall:
        mov r0, #0x0
        mov r1, #0x6                @change to mov r1, #0x5 for ball deflection instead of dodging animation
        ldr r2, =(0x0800E194 +1)
        bl linker
        ldr r5, =(0x02023BC4)
        ldrb r0, [r5]
        ldr r2, =(0x08017248 +1)
        bl linker
        ldr r1, =(0x02023D74)
        ldr r0, .DodgeMessage
        ldr r2, =(0x0802D7EC +1)

linker:
        bx r2

.align 2
.BallThrown:        .word 0x02023D68
.Rand: .word 0x08044EC9
.WildPoke:        .word 0x0202402C
.BaseStats: .word 0x08254784
.Divide:        .word 0x081E4019
.UserBank:        .word 0x02023D6B
.TargetBank:        .word 0x02023D6C
.BattleStruct:        .word 0x02023BE4
.SpecialStatus:        .word 0x02023DFC
.DodgeMessage:        .word 0x08XXXXXX        @battle script to display custom message


Current Routine Features:
  1. Target will automatically dodge a thrown ball if it is off-screen (dig, fly, bounce, dive) or has a substitute out
  2. Target will never dodge if it is asleep, frozen, or rooted in the ground (ingrain)
  3. 50% dodge rate for paralysis and 75% dodge rate if trapped by wrap effect
There are lots of other little dodge rate modifiers one could implement, such as speed/evasion stat modifiers, held item, ability, weather, etc. I have implemented some of these, so let me know if you want me to add these in!

Skeli August 31st, 2017 8:47 PM

Expanding the Bag Entirely [FR]

-Big Edit: The routines have been completely rewritten from scratch to work properly now.

This has been done in bits and pieces over the years (I believe it's actually been done completely for Emerald), so I decided to rewrite the bag storage routine for Fire Red.

Pre-Requisites
  • JPAN's Save Block Recycle
    Spoiler:
    Code:

    .thumb
    .global JPAN_Save_Block_Recycle
    .equ rom, 0x8000000
    .equ offset, 0xA00000 @YOUR INSERT OFFSET HERE

    .org 0xD991E, 0xFF
            bx r7

    .org 0xD995C, 0xFF
    .word Recycle_2 + rom + 1

    .org 0xD9EDC, 0xFF
            ldr r0, .Pointer1
            bx r0
    .align 2
    .Pointer1: .word Recycle_1 + rom + 1

    .org 0x3FEC9A, 0xFF
    .byte 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xE0, 0x1F, 0xF0, 0x0F, 0xD0, 0x2F, 0x98, 0xD, 0x0, 0x0, 0xF0, 0x0F, 0xF0, 0xF, 0xF0, 0xF, 0xE0, 0x1F, 0xF0, 0xF, 0xD0, 0x2F, 0xF0, 0xF, 0xC0, 0x3F, 0xF0, 0xF, 0xB0, 0x4F, 0xF0, 0xF, 0xA0, 0x5F, 0xF0, 0xF, 0x90, 0x6F, 0xF0, 0xF, 0x80, 0x7F, 0x50, 0x4

    .org offset, 0xFF
    Recycle_1:
            ldr r1, [r4]
            mov r3, #0xFF
            lsl r3, #0x4
            add r3, r1
            ldrh r0, [r3, #0x4]
            cmp r0, #0x0
            beq Size1
            cmp r0, #0x4
            beq Size2
            cmp r0, #0xD
            beq Size3

    BigLoop:
            cmp r5, #0xD
            ble Return
            mov r0, #0x1
            pop {r3}
            mov r8, r3
            pop {r4-r7,pc}

    Size1:
            mov r1, #0xCC
            ldr r2, .Loc1
            b SmallLoop

    Size2:
            mov r1, #0x96
            lsl r1, #0x2
            ldr r2, .Loc2
            b SmallLoop

    Size3:
            mov r1, #0xBA
            lsl r1, #0x4
            ldr r2, .Loc3

    SmallLoop:
            sub r3, #0x4
            ldr r0, [r3]
            str r0, [r2]
            sub r2, #0x4
            sub r1, #0x4
            cmp r1, #0x0
            bne SmallLoop
            b BigLoop

    .align 2
    .Loc1: .word 0x203C1C8
    .Loc2: .word 0x203C420
    .Loc3: .word 0x203CFC0

    Return:
            ldr r0, .Return
            bx r0

    .align 2
    .Return: .word 0x80D9E71
    .word 0xFFFFFFFF

    Recycle_2:
            mov r7, #0xFF
            lsl r7, #0x4
            add r7, r1, r7
            strh r0, [r7, #0x6]
            ldrh r6, [r7, #0x4]
            cmp r6, #0x0
            beq Size1_2
            cmp r6, #0x4
            beq Size2_2
            cmp r6, #0xD
            beq Size3_2
            lsl r0, #0x0

    Return_2:
            ldr r0, .Return2
            bx r0

    .align 2
    .Return2: .word 0x80D9923

    Size1_2:
            mov r3, #0xCC
            ldr r2, .Loc1_2
            b SmallLoop_2

    Size2_2:
            mov r3, #0x96
            lsl r3, #0x2
            ldr r2, .Loc2_2
            b SmallLoop_2

    Size3_2:
            mov r3, #0xBA
            lsl r3, #0x4
            ldr r2, .Loc3_2

    SmallLoop_2:
            sub r7, #0x4
            ldr r0, [r2]
            str r0, [r7]
            sub r2, #0x4
            sub r3, #0x4
            cmp r3, #0x0
            bne SmallLoop_2
            b Return_2

    .align 2
    .Loc1_2: .word 0x203C1C8
    .Loc2_2: .word 0x203C420
    .Loc3_2: .word 0x203CFC0


    Insertion Instructions:
    1. Change the .equ offset, 0xA00000 to the offset where you plan on inserting the routine.
    2. Compile the asm file.
    3. Open the .bin file and copy all the data from 0xD991E, 0xD995C, 0xD9EDC 0x3FEC9A, and your insert offset (your offset's data will go to the end of the bin file) to those same offsets in your rom.
  • An updated Conversion attack routine:
    Spoiler:

    In the following routine, change the location of your attack data at the top if necessary (if you haven't added new moves to your game it probably isn't). Assemble the routine, copy the data from the .bin file, and then do a paste-write at 0x28604 in your rom.

    Or if you don't understand ASM, copy and paste the compiled version to 0x28604 in your rom:
    Code:

    F0 B5 1B 4F 18 48 19 49 09 78 58 22 51 43 40 18 03 1C 44 7D 85 7D 00 88 12 49 0C 22 50 43 09 18 08 78 A0 42 10 D0 A8 42 0E D0 58 75 98 75 04 1C 10 48 FD 21 01 70 03 21 41 70 84 70 FF 21 C1 70 39 68 05 31 39 60 F0 BD 3A 68 51 78 90 78 00 02 01 43 D0 78 00 04 01 43 10 79 00 06 01 43 39 60 F0 BD C0 46 06 0C 25 08 F0 3B 02 02 6B 3D 02 02 74 3D 02 02 B8 2A 02 02


    (This compiled version assumes you haven't added any new moves)

    Routine:
    Code:

    .thumb
    .global atk90_changetypestoenemyattacktype

    .equ Attack_Data, 0x250C04 @0x900000 for Mr. DS
    .equ rom, 0x8000000

    @Conversion: Insert at 0x28604
    CheckMove:
            push {r4-r7, lr}
            ldr r7, .ScriptLoc
            ldr r0, .BattleData
            ldr r1, .UserBank
            ldrb r1, [r1]
            mov r2, #0x58
            mul r1, r2
            add r0, r1
            mov r3, r0
            ldrb r4, [r0, #0x15] @first type
            ldrb r5, [r0, #0x16] @second type
            ldrh r0, [r0] @First Move

    GetMoveType:
            ldr r1, .MoveData
            mov r2, #0xC
            mul r0, r2
            add r1, r0
            ldrb r0, [r1]

    CheckTypeMatch:
            cmp r0, r4
            beq Failed
            cmp r0, r5
            beq Failed

    Store:
            strb r0, [r3, #0x15]
            strb r0, [r3, #0x16]

    Return:
            mov r4, r0
            ldr r0, =0x2022AB8
            mov r1, #0xFD
            strb r1, [r0]
            mov r1, #0x3
            strb r1, [r0, #0x1]
            strb r4, [r0, #0x2]
            mov r1, #0xFF
            strb r1, [r0, #0x3]
            ldr r1, [r7]
            add r1, #0x5
            str r1, [r7]
            pop {r4-r7, pc}

    Failed:
            ldr r2, [r7]
            ldrb r1, [r2,#1]
            ldrb r0, [r2,#2]
            lsl r0, #8
            orr r1, r0
            ldrb r0, [r2,#3]
            lsl r0, #0x10
            orr r1, R0
            ldrb r0, [r2,#4]
            lsl r0, #0x18
            orr r1, r0
            str r1, [r7]
            pop {r4-r7, pc}

    .align 2
    .MoveData: .word Attack_Data + 0x2  + rom
    .BattleData: .word 0x2023BE4 + 0xC
    .UserBank: .word 0x2023D6B
    .ScriptLoc: .word 0x2023D74




    Why Conversion?
    Spoiler:
    Some of the space from the old Conversion routine is used for the bag expansion. To free up this space, Conversion was rewritten to match its Gen 6+ effect.

The Code
Spoiler:
Code:

.equ Total_Item_Amount, 700 @Change to largest item index number

.equ Regular_Item_Num, 200 @Change to number of items in main bag pocket divided by 2
.equ Key_Item_Num, 30 @Change to number of items in key item pocket divided by 2
.equ Poke_Ball_Num, 14 @Change to number of items in Poke Ball pocket divided by 2
.equ TM_Num, 128 @Change to number of TMs + HMs
.equ Berry_Num, 67 @Change to number of berries

@When changing the following RAM Adresses, make sure no data is being overwritten.
@For example, if you want to change the Poke_Ball_Ram, it needs to be changed to
@a location where there are (Poke_Ball_Num * 2 * 4) bytes of memory free.
.equ TM_Ram, 0x202583C @Change to your TM Case RAM address
.equ Berry_Ram, 0x2025A3C @Change to your Berry Pouch RAM address
.equ Key_Item_Ram, 0x203C7D0 @Change to your Key Item pocket RAM address
.equ Poke_Ball_Ram, 0x203C8C0 @Change to your main Poke Ball Pocket RAM address
.equ Item_Ram, 0x203C930 @Change to your main bag pocket RAM address

.equ Free_Ram, 0x203D900 @Don't change unless you don't like this free ram
.equ offset, 0x8D1980 @Change to Free Space Offset

.equ largest_pocket_size, Regular_Item_Num * 2
.equ largest_pocket_size_plus_one, largest_pocket_size + 1
.equ strings_size, largest_pocket_size_plus_one * 19

.equ rom, 0x8000000

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@HelperRoutine

.org 0x28760, 0xFF
GetItemAmount:
        push {r1,lr}
        ldr r0, .CurrentPocket
        ldrb r0, [r0]
        lsl r0, #0x1
        ldr r1, .ItemStorage
        ldrh r0, [r0, r1]
        pop {r1,pc}

.align 2
.CurrentPocket: .word 0x203AD02
.ItemStorage: .word Free_Ram

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Decryption and DMA Negation
@The first few of these actually decrypt the Pokemon Data because why not?

.org 0x3F906, 0xFF
mov r8, r8
str r0, [r2]
ldr r1, [r3, #0x4]
mov r8, r8

.org 0x3F92A, 0xFF
mov r8, r8
str r0, [r2]
ldr r1, [r3]
mov r8, r8

.org 0x3F94C, 0xFF
mov r0, #0x0
mov r8, r8
mov r8, r8

.org 0x3FDA8, 0xFF
b 0x3FDC2

.org 0x40530, 0xFF
b 0x40550

.org 0x40AE6, 0xFF
mov r8, r8

.org 0x4C062, 0xFF
mov r1, #0x0
mov r1, #0x0

.org 0x4C13C, 0xFF
mov r4, #0x0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

.org 0x6BDEC, 0xFF
        ldr r0, .BerryFix1Ptr
        bx r0
.align 2
.BerryFix1Ptr: .word BerryFix1Ptr + rom + 1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Removal of Item Limiters

.org 0x98998, 0xFF
.word Total_Item_Amount

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Routines Related to Obtaining Items

.org 0x99DFC, 0xFF
ldrh r0, [r0, #0x4]

.org 0x99E1A, 0xFF
ldrh r4, [r4, #0x4]

.org 0x99E44, 0xFF
ldr r1, .BagPocket0

@Regular items
ldr r0, ram_FREE_item
str r0, [r1]
mov r0, #Regular_Item_Num
lsl r0, #0x1 @400 regular items
strh r0, [r1, #0x4]

@Key items
ldr r0, ram_FREE_keyitem
str r0, [r1, #0x8]
mov r0, #(Key_Item_Num * 2) @60 key items
strh r0, [r1, #0xC]

@Poke balls
ldr r0, ball_ram
str r0, [r1, #0x10]
mov r0, #(Poke_Ball_Num * 2) @28 balls
strh r0, [r1, #0x14]

@Tms
ldr r0, tm_ram
str r0, [r1, #0x18]
mov r0, #TM_Num @128 TMs
strh r0, [r1, #0x1C]

@Berries
ldr r0, berry_ram
str r0, [r1, #0x20]
add r1, #0x24
mov r0, #Berry_Num @67 berries
strh r0, [r1]
bx lr

.align 2
.BagPocket0:                .word 0x203988C
tm_ram:                        .word TM_Ram
berry_ram:                .word Berry_Ram
ram_FREE_keyitem:        .word Key_Item_Ram
ball_ram:                .word Poke_Ball_Ram
ram_FREE_item:                .word Item_Ram

.org 0x99ED8, 0xFF
ldrh r1, [r0, #0x4]

.org 0x99EEA, 0xFF
lsl r0, r2, #0x10
lsr r0, r0, #0x10

.org 0x99F16, 0xFF
ldrh r1, [r0, #0x4]

.org 0x99F32, 0xFF
lsl r0, r0, #0x10
lsl r2, r0, #0x10

.org 0x99F6E, 0xFF
ldrh r1, [r0, #0x4]

.org 0x99F9A, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r3, #0x4]

.org 0x99FD4, 0xFF
CheckBerryInBagFix:
        ldr r4, .LastResult
        ldr r0, .CheckBerryBerryRam
        ldrh r0, [r0]
        cmp r0, #0x0
        beq NoBerriesInBag
        mov r0, #0x1
        strh r0, [r4]
        pop {r4,pc}

NoBerriesInBag:
        mov r0, #0x0
        strh r0, [r4]
        pop {r4,pc}

.align 2
.CheckBerryBerryRam: .word Berry_Ram
.LastResult: .word 0x020370D0

.org 0x9A02A, 0xFF
ldrh r1, [r0, #0x4]

.org 0x9A05E, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r3, #0x4]

.org 0x9A06E, 0xFF
lsl r0, r0, #0x10
lsr r0, r0, #0x10

.org 0x9A0B6, 0xFF
ldrh r1, [r0, #0x4]

.org 0x9A0EA, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r5, #0x4]

.org 0x9A110, 0xFF
lsl r0, r0, #0x10
lsr r1, r0, #0x10

.org 0x9A14C, 0xFF
lsl r0, r0, #0x10
lsr r1, r0, #0x10

.org 0x9A186, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10

.org 0x9A204, 0xFF
ldrh r1, [r0, #0x4]

.org 0x9A24E, 0xFF
lsl r0, r0, #0x10
lsr r2, r0, #0x10
ldrh r0, [r6, #0x4]

.org 0x9A2E8, 0xFF
ldrh r1, [r1, #0x4]

.org 0x9A58E, 0xFF @Shifting Items Up
lsl r1, #0x10
lsr r1, #0x10

.org 0x09A8A4, 0xFF
        lsl r0, #0x10
        lsr r0, #0x10
        ldr r1, .ItemLimit
        cmp r1, r0
        bge Return
        mov r0, #0x0
Return:
        bx lr

.align 2
.ItemLimit: .word Total_Item_Amount

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Routines Related to the Pokedex

@The original ram provided above for the berries overrites a copy of the Pokedex data.
@Thus, when the Berry Pouch is sorted upon opening it, garbage data from this dex
@data is loaded. These routines prevent this copy from being read from or written to.

BerryPokedexDataFix:
.org 0x104B34, 0xFF
b 0x104B56

.org 0x104B78, 0xFF
b 0x104BB0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Routines Related to Viewing Items in Bag

Bag_Allocate_Stuff: @Credits to azurile13
.org 0x1083F4, 0xFF
        push {r4,lr}
        ldr r4, .AllocationPointer
        ldr r0, .LargestSize
        lsl r0, #0x3
        bl 0x2B9C @malloc
        str r0, [r4]
        cmp r0, #0x0
        beq No
        ldr r0, .strings_size
        bl 0x2B9C @malloc
        str r0, [r4, #0x4]
        cmp r0, #0x0
        beq No
        mov r0, #0x1
        b End

No:
        mov r0, #0x0

End:
        pop {r4,pc}

.align 2
.LargestSize: .word largest_pocket_size_plus_one
.AllocationPointer: .word 0x0203AD18
.strings_size: .word strings_size

.org 0x108440, 0xFF
bl 0x28760 @GetItemAmount
b 0x10844A

.org 0x10847E, 0xFF @Shop is dis one
bl 0x28760 @GetItemAmount
b 0x108488

.org 0x1084C2, 0xFF
bl 0x28760 @GetItemAmount
b 0x1084CA

.org 0x1085D8, 0xFF
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
cmp r0, r5

.org 0x108698, 0xFF
ldr r5, .Thing
ldrh r1, [r5, #0x6]
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
.hword 0x0
cmp r0, r4

.org 0x10871C, 0xFF
.Thing: .word 0x203ACFC

.org 0x10881E, 0xFF
ldr r1, .Thing2
ldrh r1, [r1, #0x6]
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
.hword 0x0
cmp r2, r0

.org 0x108850, 0xFF
.Thing2: .word 0x203ACFC

.org 0x108894, 0xFF
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
add r1, #0xD

.org 0x108A1C, 0xFF @Up Cursor Bug 1
ldr r1, .OpenBagBugFix1Pointer
bx r1
.align 2
.OpenBagBugFix1Pointer: .word OpenBagBugFix1 + rom + 1

.org 0x108A40, 0xFF @Up Cursor Bug 2
ldr r0, .OpenBagBugFix2Pointer
bx r0
.align 2
.OpenBagBugFix2Pointer: .word OpenBagBugFix2 + rom + 1
.hword 0x0

.org 0x108AC0, 0xFF @Up Cursor Bug 3
ldr r0, .OpenBagBugFix3Pointer
bx r0
.align 2
.OpenBagBugFix3Pointer: .word OpenBagBugFix3 + rom + 1

.org 0x108DC8, 0xFF
ldr r1, .StoreItemPointer
bx r1
.align 2
.StoreItemPointer: .word StoreItem + rom + 1

ldr r0, .Bag_Pocket_0_2
add r4, r1, r0
ldr r0, [r4]
ldrh r1, [r4, #0x4]

.org 0x108DEA, 0xFF
ldrh r0, [r4, #0x4]

.org 0x108E0A, 0xFF
ldrh r0, [r4, #0x4]

.org 0x108E20, 0xFF
ldr r0, .GetSmallestItemAmountPointer
bx r0
.align 2
.GetSmallestItemAmountPointer: .word GetSmallestItemAmount + rom + 1

.org 0x108E3C, 0xFF
.Bag_Pocket_0_2: .word 0x203988C

.org 0x108E4C, 0xFF
pop {r4-r6,pc}

.org 0x108FB6, 0xFF
ldrh r5, [r5, #0x6]
push {r1}
bl 0x28760 @GetItemAmount
pop {r1}
.hword 0x0
cmp r1, r0

.org 0x10904A, 0xFF
        ldrh r1, [r5, #0x6]
        push {r1}
        bl 0x28760 @GetItemAmount
        pop {r1}
        .hword 0x0
        cmp r4, r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Poke Dude Stuff

.org 0x10ADDE, 0xFF
        ldr r0, .PokeDudeBackupRegularBagFixPtr
        bx r0
.align 2
.PokeDudeBackupRegularBagFixPtr: .word PokeDudeBackupRegularBagFix + rom + 1

.org 0x10AE78, 0xFF
        ldr r0, .PokeDudeBackupRegularBagClearPtr
        bx r0
.align 2
.PokeDudeBackupRegularBagClearPtr: .word PokeDudeBackupRegularBagClear + rom + 1

.org 0x10AEDA, 0xFF
        ldr r0, .PokeDudeBackupBagRestorePtr
        bx r0
.align 2
.PokeDudeBackupBagRestorePtr: .word PokeDudeBackupBagRestore + rom + 1

.org 0x132E76, 0xFF
        ldr r1, .PokeDudeBackupTMCasePtr
        bx r1
.align 2
.PokeDudeBackupTMCasePtr: .word PokeDudeBackupTMCase + rom + 1

.org 0x132EB0, 0xFF
        ldr r0, .PokeDudeClearTMCasePtr
        bx r0
.align 2
.PokeDudeClearTMCasePtr: .word PokeDudeClearTMCase + rom + 1

.org 0x13318C, 0xFF
        ldr r0, .PokeDudeRestoreTMCasePtr
        bx r0
.align 2
.PokeDudeRestoreTMCasePtr: .word PokeDudeRestoreTMCase + rom + 1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Remove Help System

.org 0x13B8C2, 0xFF
b 0x13B900

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@More Berry Stuff

.org 0x13D1C4, 0xFF
        mov r0, #Berry_Num + 1
        lsl r0, #0x3

.org 0x13D33C, 0xFF
BerryNumFixesHook:
        ldr r0, .BerryNumFixesPtr
        bx r0
.align 2
.BerryNumFixesPtr: .word BerryNumFixes + rom + 1

BerryFix2Hook:
.org 0x14A490, 0xFF
        ldr r0, .BerryFix2Ptr
        bx r0
.align 2
.BerryFix2Ptr: .word BerryFix2 + rom + 1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@New Routine

.org offset, 0xFF
StoreItem:
        push {r4-r6,lr}
        lsl r0, r0, #0x18
        lsr r5, r0, #0x18
        mov r4, #0x0

GetItemInBagCount:
        mov r6, #0x0
        lsl r0, r4, #0x3
        ldr r1, .Table
        add r0, r1
        ldrh r3, [r0, #0x4]
        lsl r3, #0x1
        ldr r0, [r0]
        mov r1, #0x0

Loop:
        cmp r1, r3
        beq StoreAmount
        ldrh r2, [r0]
        cmp r2, #0x0
        beq CheckNextItemJustInCase
        add r0, #0x4
        add r1, #0x1
        b Loop

CheckNextItemJustInCase:
        ldrh r2, [r0, #0x4]
        cmp r2, #0x0
        beq StoreAmount
        add r0, #0x4
        add r1, #0x1
        mov r6, #0x1
        b Loop       

StoreAmount:
        cmp r6, #0x0
        beq NotShopSkip
        sub r1, #0x1
NotShopSkip:
        ldr r0, .ItemStorage2
        lsl r2, r4, #0x1
        add r0, r2
        strh r1, [r0]
        add r4, #0x1
        cmp r4, #0x3
        beq ReturnToThing
        b GetItemInBagCount

ReturnToThing:
        lsl r1, r5, #0x3
        ldr r0, =0x8108DD1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

GetSmallestItemAmount:
        push {r1}
        ldr r0, .ItemStorage2
        lsl r1, r5, #0x1
        add r0, r1
        pop {r1}
        ldrh r0, [r0]
        ldr r3, =0x8108E29
        bx r3

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

OpenBagBugFix1:
        push {r0}
        lsl r0, r4, #0x1
        ldr r1, .ItemStorage2
        add r1, r0
        ldrh r1, [r1]
        pop {r0}
        add r0, r1, #0x1
        cmp r2, r0
        ldr r0, =0x8108A26 | 1
        bx r0

OpenBagBugFix2:
        lsl r3, r4, #0x1
        ldr r0, .ItemStorage2
        add r0, r3
        ldrh r0, [r0]
        add r3, r0, #0x1
        ldr r4, =0x8108A4C | 1
        bx r4

OpenBagBugFix3:
        lsl r1, r6, #0x1
        ldr r0, .ItemStorage2
        add r0, r1
        ldrh r0, [r0]
        add r0, #0x1
        ldr r1, =0x8108AC8 | 1
        bx r1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

PokeDudeBackupRegularBagFix:
        ldr r5, .PokeDudeItemBackupPtr
        ldr r0, .NewMallocPokeDudeBagSpace
        bl Calloc
        str r0, [r5]
        ldr r1, =Item_Ram
        ldr r2, =Regular_Item_Num * 2 * 4
        mov r4, r2
        bl Memcpy

        ldr r0, [r5]
        add r0, r4
        ldr r1, =Key_Item_Ram
        ldr r2, =Key_Item_Num * 2 * 4
        add r4, r2
        bl Memcpy

        ldr r0, [r5]
        add r0, r4
        ldr r1, =Poke_Ball_Ram
        ldr r2, =Poke_Ball_Num * 2 * 4
        bl Memcpy

        ldr r4, .SaveBlock1
        ldr r0, =0x810AE22 | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x810AE78 with r0
PokeDudeBackupRegularBagClear:
        ldr r0, =Item_Ram
        ldr r1, =Regular_Item_Num * 2
        bl RemoveNItems

        ldr r0, =Key_Item_Ram
        mov r1, #Key_Item_Num * 2
        bl RemoveNItems

        ldr r0, =Poke_Ball_Ram
        mov r1, #Poke_Ball_Num * 2
        bl RemoveNItems

        ldr r4, .SaveBlock1
        ldr r0, =0x810AEA4 | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x10AEDA with r0
PokeDudeBackupBagRestore:
        ldr r0, =Item_Ram
        ldr r1, [r5]
        ldr r2, =Regular_Item_Num * 2 * 4
        mov r4, r2
        bl Memcpy

        ldr r0, =Key_Item_Ram
        ldr r1, [r5]
        add r1, r4
        ldr r2, =Key_Item_Num * 2 * 4
        add r4, r2
        bl Memcpy

        ldr r0, =Poke_Ball_Ram
        ldr r1, [r5]
        add r1, r4
        ldr r2, =Poke_Ball_Num * 2 * 4
        bl Memcpy

        ldr r4, .SaveBlock1
        ldr r0, =0x810AF0C | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x8132E76 with r1
PokeDudeBackupTMCase:
        ldr r1, =TM_Ram
        ldr r2, =TM_Num * 4
        mov r5, r2
        bl Memcpy

        ldr r0, [r4]
        add r0, r5
        ldr r1, =Key_Item_Ram * 2 * 4
        ldr r2, =Key_Item_Num * 2 * 4
        bl Memcpy

        ldr r0, =0x8132E98 | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x132EB0 with r0
PokeDudeClearTMCase:
        ldr r0, =TM_Ram
        mov r1, #TM_Num
        bl RemoveNItems

        ldr r0, =Key_Item_Ram
        mov r1, #Key_Item_Num
        bl RemoveNItems

        ldr r0, =0x8132EC4 | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x813318C with r0
PokeDudeRestoreTMCase:
        ldr r0, =TM_Ram
        ldr r2, =TM_Num * 4
        bl Memcpy

        ldr r0, =Key_Item_Ram
        ldr r1, [r5]
        ldr r2, =Key_Item_Num * 2 * 4
        bl Memcpy

        ldr r0, =0x81331A4 | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

BerryFix1Ptr:
        cmp r6, #0x1
        bls BerryFix1Return
        mov r0, r5
        bl GetItemPocket
        cmp r0, #0x5 @Berry Pouch
        bne BerryFix1Return
        ldr r0, =0x806BDFC | 1
        bx r0

BerryFix1Return:
        ldr r0, =0x806BE22 | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x14A490 with r0
BerryFix2:
        cmp r6, #0x0
        beq BerryFix2Return
        mov r0, r4
        bl GetItemMystery2 @BerryId

BerryFix2Return:
        ldr r0, =0x814A4C2 | 1
        bx r0

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@0x13D33C with r0
BerryNumFixes:
        mov r0, r5
        bl GetItemMystery2
        mov r1, r0
        mov r0, r6
        mov r2, #0x2
        ldr r3, =0x813D344 | 1
        bx r3

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Calloc:
        ldr r1, =0x8002BB0 | 1
        bx r1

Memcpy:
        ldr r3, =0x81E5E78 | 1
        bx r3

RemoveNItems:
        ldr r2, =0x809A274 | 1
        bx r2

GetItemPocket:
        ldr r1, =0x809A9D8 | 1
        bx r1

GetItemMystery2:
        ldr r1, =0x809A9B4 | 1
        bx r1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

.align 2
.ItemStorage2: .word Free_Ram
.Table: .word TABLE + rom
.PokeDudeItemBackupPtr: .word 0x203AD2C
.NewMallocPokeDudeBagSpace: .word (Regular_Item_Num + Key_Item_Num + Poke_Ball_Num) * 2 * 4
.SaveBlock1: .word 0x3005008

.align 2
TABLE:
.word Item_Ram
.hword Regular_Item_Num, 0x0

.word Key_Item_Ram
.hword Key_Item_Num, 0x0

.word Poke_Ball_Ram
.hword Poke_Ball_Num, 0x0

.word 0xFFFFFFFF, 0xFFFFFFFF


The above code is written in such a way that if you were to insert it as is, you would have support for:
  • 400 Regular Items
  • 60 Key Items
  • 28 Poke Balls
  • 128 TMs/HMs
  • 67 Berries
Obviously if you don't need this many items, you're free to change the ram locations and item amounts by modifying the lines at the top of the routine. If you try to expand any of these values, make sure you change the ram locations if necessary.

Important Note About Berries: If you plan on adding new berries to your game, each berry needs to modified in G3T's item editor. Under Mystery1/2, change the value in the second box (Mystery 2) to the berry number for that berry. For instance, the Oran Berry is number 7. All berry numbers can be found on Bulbapedia.
If you don't plan on expanding berries, in the code, change Berry_Num to 43 and remove the bolded section labeled BerryNumFixesHook. Otherwise all your berries will be displayed with a berry number of 0 (or, alternatively, you could assign each berry a number like mentioned above).
If you do expand the berries, they will remain in a sorted order based on their item id. In my upcoming battle engine, a fix will be provided for this (mainly because I didn't want to write a decent sorting algorithm in Assembly).

Insertion Instructions:
  1. Customize to your liking
  2. Assemble the routine
  3. Copy the output bin file (so you should have a file called something like output.bin - Copy and fill this copy with FFs
  4. Create a patch using your blank (filled with FFs) file as the unmodified file, and the output file as the modified file
  5. Patch your rom

This has been confirmed to work with a vanilla Fire Red. However, I can't guarantee it will work with all roms in progress.


Credits

Enn September 5th, 2017 10:52 AM

Alright I'm making a request!
Everyone has probably heard about Bank system...
On which can allow the player to store his money, loans, interest (ofc in support with primes RTC) and other cool banking stuff.
PS this thread has helped me a lot thanks "A free helper" Blah ;) !

BluRose September 5th, 2017 7:59 PM

Quote:

Originally Posted by Nisarg (Post 9746312)
Alright I'm making a request!
Everyone has probably heard about Bank system...
On which can allow the player to store his money, loans, interest (ofc in support with primes RTC) and other cool banking stuff.
PS this thread has helped me a lot thanks "A free helper" Blah ;) !

read the op please &lt;3

Enn September 16th, 2017 6:35 AM

Aight, this request is similar to shinyquagsire's berry selection screen...
I need an asm which can show the party screen and on selecting the pokemon, exits and stores data in a var...
However theres a twist, im not talking about special 0x9f...
The mons need to be read from Ram where PSS stored the mons... So now y'all get it why its so complex...
If that is to be pulled off, it'd be amazing;)

BluRose September 17th, 2017 9:33 AM

Quote:

Originally Posted by Nisarg (Post 9754251)
Aight, this request is similar to shinyquagsire's berry selection screen...
I need an asm which can show the party screen and on selecting the pokemon, exits and stores data in a var...
However theres a twist, im not talking about special 0x9f...
The mons need to be read from Ram where PSS stored the mons... So now y'all get it why its so complex...
If that is to be pulled off, it'd be amazing;)

legit take the routine for special 0x9F
replace the part where it accesses your party with the new ram address. this likely just involves replacing an address from the routine, literally nothing more. callasm the new special and ezpz

Enn September 17th, 2017 11:17 PM

Quote:

Originally Posted by BluRose (Post 9755243)
legit take the routine for special 0x9F
replace the part where it accesses your party with the new ram address. this likely just involves replacing an address from the routine, literally nothing more. callasm the new special and ezpz

Say I located the routine, but how do u decompile the routine in hex to actual asm???

BluRose September 18th, 2017 4:56 AM

Quote:

Originally Posted by Nisarg (Post 9755757)
Say I located the routine, but how do u decompile the routine in hex to actual asm???

two easy ways
look in knizz's idb
disassemble in vba

Wesley FG September 30th, 2017 9:49 PM

Someone can convert it for EM ?

Quote:

Originally Posted by Touched (Post 8852941)
Change the order that badges appear on the trainer card (untested)
Simply makes the loop read from a lookup table before checking for the badge.
Spoiler:

Code:

.align 2
.thumb

@ 00 4B 18 47 XX + 1 XX XX 08 at 0x08AFC8 (0808AFC8 via r3)
hook_name:
    asr r7, r0, #0x10
    add r1, #0x11
    adr r0, order_table
    ldrb r0, [r0, r7]
    add r1, r1, r0
    ldrb r0, [r1]
    ldr r3, return
    bx r3

.align 2
return: .word 0x0808AFD0 + 1

@ Change the badge order using this table (reverse order)
order_table: .byte 7, 6, 5, 4, 3, 2, 1, 0




BluRose October 3rd, 2017 2:32 PM

Quote:

Originally Posted by Wesley FG (Post 9765655)
Someone can convert it for EM ?

Code:

.align 2
.thumb

@ 00 4B 18 47 XX + 1 XX XX 08 at 0x0C4684 (080C4684 via r3)
hook_name:
    asr r7, r0, #0x10
    add r1, #0x11
    adr r0, order_table
    ldrb r0, [r0, r7]
    add r1, r1, r0
    ldrb r0, [r1]
    ldr r3, return
    bx r3

.align 2
return: .word 0x080C468C + 1

@ Change the badge order using this table (reverse order)
order_table: .byte 7, 6, 5, 4, 3, 2, 1, 0


here you go

Megax Rocker October 6th, 2017 12:26 PM

Is it possible to alter the breeding mechanism in FR? Having the egg be only be the mother's species and inherit moves from only the father is limited.

I'm thinking of the egg having a 50% chance to be either species instead, so that male only pokemon would still breed normally, and egg moves would be possible for them as well.

Would probably be much better than the regular one IMO.

Wesley FG October 7th, 2017 12:47 PM

Quote:

Originally Posted by BluRose (Post 9767526)
Code:

.align 2
.thumb

@ 00 4B 18 47 XX + 1 XX XX 08 at 0x0C4684 (080C4684 via r3)
hook_name:
    asr r7, r0, #0x10
    add r1, #0x11
    adr r0, order_table
    ldrb r0, [r0, r7]
    add r1, r1, r0
    ldrb r0, [r1]
    ldr r3, return
    bx r3

.align 2
return: .word 0x080C468C + 1

@ Change the badge order using this table (reverse order)
order_table: .byte 7, 6, 5, 4, 3, 2, 1, 0


here you go


i test and not work

MKCocoon October 17th, 2017 12:22 PM

I have a request:

So FireRed's egg move table only accounts for 8 egg moves. My hack, Pokemon Vega Minus, is obviously derived from the original English translation of Vega by Dr. Akimbo. The problem is, egg moves are busted in both my hack and his because in Vega, Pokemon have anywhere from 15 to 37 egg moves.

So I was able to fix it somewhat by replacing the 0x9 at 0x0456AC with 0x30 (just an arbitrarily large number), and then fixing the limiter at 0x045CC4, but since the amount of RAM allocated to egg moves only can account for ten moves without overflowing, I'm worried this could result in glitches.

In this thread, FBI explains how to fix the crappy way the game checks for egg moves using ASM, except since I know nothing about ASM, it doesn't make any sense to me. Apparently it's simple for people who do understand ASM though, so if anyone could help me out it'd be great. You can go download my patch for reference if needed. I'd also need to know how to implement the ASM into the game.

Thanks in advance.

Lunos October 18th, 2017 5:03 PM

Quote:

Originally Posted by Wesley FG (Post 9770108)
i test and not work

I just tested it, and it does.

1) Copy the routine and paste it in a .txt file, change the order however you want and give the file an easy-to-remember name.

2) Pass it through HackMew's thumb.bat

3) Grab the compiled routine from its .bin file and paste it in an offset that ends in 0, 4, 8 or C and that also has free space in your ROM.

4) Go to the offset 0C4684 and Paste-Write (Ctrl+B) this:
Code:

00 4B 18 47 XX XX XX 08


XX XX XX = Pointer to the offset+1 where you've inserted the routine.
Example: I've put it in E3CF80, then I'd replace XX XX XX with 81 CF E3.

5) Test.

Wesley FG October 19th, 2017 4:05 AM

Quote:

Originally Posted by Lunos (Post 9776847)
I just tested it, and it does.

1) Copy the routine and paste it in a .txt file, change the order however you want and give the file an easy-to-remember name.

2) Pass it through HackMew's thumb.bat

3) Grab the compiled routine from its .bin file and paste it in an offset that ends in 0, 4, 8 or C and that also has free space in your ROM.

4) Go to the offset 0C4684 and Paste-Write (Ctrl+B) this:
Code:

00 4B 18 47 XX XX XX 08


XX XX XX = Pointer to the offset+1 where you've inserted the routine.
Example: I've put it in E3CF80, then I'd replace XX XX XX with 81 CF E3.

5) Test.


i know compile and insert asm routines, and i test it again and not work,
you can post the hex compiled bin generate for you:
for my it:

Quote:

07 14 11 31 03 A0 C0 5D 09 18 08 78 00 4B 18 47
8D 46 0C 08 07 06 03 02 05 04 01 00
and not work, you really check it ?

BluRose October 19th, 2017 4:28 AM

Quote:

Originally Posted by Wesley FG (Post 9777150)
i know compile and insert asm routines, and i test it again and not work,
you can post the hex compiled bin generate for you:
for my it:

and not work, you really check it ?

to be honest i don't understand why this would even be necessary; just replace the graphics if it's really not working for you, although i regrettably inform you that i think lunos is right as i also tested it myself, so... yeah

Wesley FG October 19th, 2017 6:24 AM

Quote:

Originally Posted by BluRose (Post 9777160)
to be honest i don't understand why this would even be necessary; just replace the graphics if it's really not working for you, although i regrettably inform you that i think lunos is right as i also tested it myself, so... yeah

you change some badge of position, for test ?
i change the 5th with 3th (for use surf after 3 gym)
and 6th with 4th (for use fly after 4 gym)
and my changes no have any efecct, the badges apppear in the same order

BluRose October 19th, 2017 6:47 AM

Quote:

Originally Posted by Wesley FG (Post 9777205)
you change some badge of position, for test ?
i change the 5th with 3th (for use surf after 3 gym)
and 6th with 4th (for use fly after 4 gym)
and my changes no have any efecct, the badges apppear in the same order

this has no effect on how the badges are awarded, in what order in the game's story, or which badge awards which move. this solely affects in which order the badges show up on the bottom of the front side of the trainer card

Wesley FG October 19th, 2017 11:17 AM

Quote:

Originally Posted by BluRose (Post 9777213)
this has no effect on how the badges are awarded, in what order in the game's story, or which badge awards which move. this solely affects in which order the badges show up on the bottom of the front side of the trainer card

yes i understand all, i change the order of 3 badge with 5 badge, and no have effect in game.
the badges are same original positions.

Lunos October 19th, 2017 1:45 PM

Quote:

Originally Posted by Wesley FG (Post 9777150)
you can post the hex compiled bin generate for you

07 14 11 31 03 A0 C0 5D 09 18 08 78 00 4B 18 47 8D 46 0C 08 05 04 07 06 01 00 03 02
Order: 5, 4, 7, 6, 1, 0, 3, 2

Also, I'm seeing that you have an empty space after that 00, delete it.
https://i.imgur.com/x6Q1rFm.png

linobigatti October 22nd, 2017 7:31 AM

can i run a ASM routine forever in second plane? how?

ghoulslash October 22nd, 2017 2:05 PM

Here's kind of a silly routine I made for fun.

Custom Vs. Seeker Pedometer [FR]

This will let you change the amount of steps needed to activate the vs. seeker. You can make it step-independent, increase or decrease as the game progresses, or have some random fluctuations, or anything you like.

It requires 2 bytes of free RAM. JPANs save block hack is needed to allow the pedometer to save. The first byte will hold the pedometer value, and the second will hold the 'charged up' limit. When the pedometer reaches this value, the vs. seeker is usable, and then reset upon use.

To change the required steps, just set your second RAM byte to whatever you like. This can easily be done in XSE. Just be sure to set the limit when the player receives the item.

Note: I'm not sure if this is an existing Vs. seeker feature or not, but using it even when there are no trainers are around resets the pedometer. Although from a logical standpoint this makes sense regardless.

Now, for the routines! There are two of them you will need. (insertion instructions in comments of each routine)

First: Change Vs. Seeker Routine to Check our new Pedometer
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func
.global Vs_Seeker_hack
/*
insert 00 48 00 47 (xx+1) xx xx 08 at 0x10c970
*/

Main:
        ldr r0, .Pedometer
        ldrb r1, [r0]                        @pedometer value
        ldrb r0, [r0, #0x1]                @pedometer max
        cmp r1, r0
        beq Usable

Unusable:
        sub r1, r0, r1                @limit - num steps = num steps remaining
        ldr r0, =(0x0810c99c +1)
        bx r0

Usable:
        mov r0, #0x0
        ldr r1, .Pedometer
        strb r0, [r1]                        @reset pedometer to zero
        ldrb r0, =(0x0810c97e +1)
        bx r0

.align 2
.Pedometer:        .word 0x02XXXXXX




Second: Increase pedometer each step (you will have to merge with the hp loss/gain each step routines)
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func
/*
insert 01 4A 10 47 00 00 (xx+1) xx xx 08 at 6D5F6
*/
Main:
        push {r0-r2}
        ldr r2, =(0x02XXXXXX)        @new pedometer loc
        ldrb r0, [r2]
        ldrb r1, [r2, #0x1]                @pedometer limit
        cmp r0, r1
        beq end
        add r0, #0x1        @increase
        strb r0, [r2]

end:
        pop {r0-r2}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq branch
        mov r0, r5
        ldr r1, =(0x806D600 +1)
        bx r1

branch:
        ldr r0, =(0x806D650 +1)
        bx r0



thedarkgod October 29th, 2017 9:19 PM

Hello,

I know this is something which has been requested by others before, but I would like to request a way to store the current hp of pokemon being deposited in the pc storage system.

This would allow us to control any way in which a pokemon can be healed.

Spoiler:

I believe it should be possible to implement by intercepting the script of depositing a pokemon, then store the current hp value in an offset together with a unique id of the pokemon. Then also intercept the script called on withdrawal, and try the id of the pokemon against the id stored at the offset, and if it matches apply the value stored at depositing to current hp.

There would most certainly be bugs, such as not displaying the current hp when inspected, but it would be a way to implement a bare-bone system.


I don't know enough asm to evaluate how hard this would be to implement, but it would be a very good function to have, as it would allow a lot more flexibility with the kind of game-play changes you could implement.

Lunos November 10th, 2017 5:10 AM

Hi, I wanted to make a request. I don't know if it's simple or not but I hope it is.
I'd like an ASM Routine for Fire Red, that checks a Pokémon in your party and returns 0x1 in the var 0x8004, if it's an egg. Would that be possible?

I'm basically thinking in a script that forcefully hatches an egg.
Right now, if someone decided to make such a routine, I imagine that it could be used like this:
Code:

special 0x9F // Pick a Pokémon
waitstate
callasm 0x8XXXXXX|0x8XXXXXX+1 // This would check if the Slot that the Player picked in the special 0x9F is an egg or not, and if it is, it would set to 0x1 the Var 0x8004.
compare 0x8004 0x1
if 0x1 goto @hatch

#org @hatch
special 0xC2 // Hatch the egg



Squeetz November 10th, 2017 5:54 AM

Quote:

Originally Posted by Lunos (Post 9791662)
(...) returns 0x1 in the var 0x8004, if it's an egg. Would that be possible?

There is actually already a special in Firered that checks if what you chose is an egg or not.
Usage:
Code:

(...)
special 0x9f
waitstate
compare 0x8004 0x6
if 0x4 goto @cancelled
special2 0x800d 0x147 - this is the special
compare 0x800d 0x19c - check if egg
if 0x1 goto @itsanegg
(...)



Delta231 November 10th, 2017 10:00 PM

I would like to make request (FR)

An Asm routine which give separate pallets to maps ows (boy and girl)

Megax Rocker November 11th, 2017 3:26 AM

Quote:

Originally Posted by BluRose (Post 9555228)
smh nathan closing tabs like what the hell

EXPANDING THE THING THAT MAKES NIDORAN'S/ILLUMISE'S MALE VARIANTS HATCH FROM EGGS
based on a table

first, the routine:
Spoiler:
Code:

.text
.align 2
.thumb

@ hook via r1 (00 49 08 47 XX+1 XX XX XX) at 46068 (BPRE) / 70858 (BPEE) / 415F6 (AXVE)

main:
        ldr r7, terminate
        mov r3, #0x0
loop:
        ldr r0, table
        lsl r2, r3, #0x1
        add r2, r0, r2
        ldrh r5, [r2, #0x0]
        cmp r5, r7
        beq return
        add r3, #0x1
        cmp r5, r4
        bne loop
        mov r0, #0x8C
        lsl r0, r0, #0x1
        add r0, r8
        ldrh r1, [r0]
        mov r0, #0x80
        lsl r0, r0, #0x8
        and r0, r1
        cmp r0, #0x0
        beq return
        ldrh r4, [r2, #0x2]
return:
        ldr r1, getparents
        bx r1

.align 2

getparents:
        .word 0x0804609B        @ 0x0804609B BPRE; 0x0807088D BPEE; 0x08041F88 AXVE
terminate:
        .word 0x0000FEFE @ end the table below with this
table:                                @change as is necessary
        .word table1 + 0x[place where you plan on inserting this]
table1:
        .hword 0x001D                @ nidoran female
        .hword 0x0020                @ nidoran male
        .hword 0x0183                @ illumise
        .hword 0x0182                @ volbeat
                                @ theoretical new entries
        .word 0x0000FEFE



usage:
- table at the end has a structure:
[hword] - species 1
[hword] - species 2
an egg that is supposed to be species 1 has a 50% chance of turning into species 2 (note at the bottom), and it NEEDS to end with FE FE 00 00 as it does in the example.
- i included addresses for emerald and ruby as well. replace as desired (the hook address and the getparents routine address)
- you need to know where you are going to insert the routine BEFORE compiling it; the table is placed right after the routine and is referenced as such.

proof of concept:
Spoiler:
http://i.imgur.com/7lC2Mkc.pnghttp://i.imgur.com/e10pDfR.pnghttp://i.imgur.com/RT8w4rd.pnghttp://i.imgur.com/bB9lRmL.png
first from female bulba x male venusaur, second from male bulba x ditto, third from illumise and volbeat, last from nidoran(f) x ditto


shoutouts to doesntknowhowtoplay for his research on the subject and to chaotix for initial testing and suggesting the idea of a table instead of some extremely inefficient shtuff that was originally going to happen.

notes:
- species 2 does not ever turn into species 1. so you're breeding your volbeat to get an illumise? you'll only ever get volbeat. just add an entry for volbeat to illumise.
- if you want species 1 to turn into multiple species: i have been testing for literally five hours with the game running consistently at about 300% and have yet to see a phanpy come from my illumise. moral of the story: this code, even with modifications telling it to continue looping after setting the id, doesn't support 1 pokémon to multiple.
i did however manage to get illumise and this after doing like a weird chain thing (illumise -> volbeat -> phanpy), but it negated volbeat, and no we'd not like that:
http://i.imgur.com/Va3fqEl.png
- not tested on bpee or axve but there is no reason it shouldn't work (axve is the same thing while bpee i think interchanges two different registers)
- OH ALSO you have 0x2A bytes of unused space at 46070 for you to use for whatever! knock yourself out with all of that free space

Can make a request?

Is it possible to make the species of the egg have a 50/50 chance of belonging to either of the parents?

For example, ditto and bulbasaur egg would result in a either a ditto or a bulbasaur to hatch, or an egg between a male bulbasaur and female charmander would result in either a bulbasaur egg or a charmander one.

BluRose November 12th, 2017 7:40 PM

Quote:

Originally Posted by Megax Rocker (Post 9792143)
Can make a request?

Is it possible to make the species of the egg have a 50/50 chance of belonging to either of the parents?

For example, ditto and bulbasaur egg would result in a either a ditto or a bulbasaur to hatch, or an egg between a male bulbasaur and female charmander would result in either a bulbasaur egg or a charmander one.

just add a second entry for the other way round to the table:
Code:

table1:
        .hword 0x001D @ nidoranf to
        .hword 0x0020 @ nidoranm
        .hword 0x0020 @ nidoranm to
        .hword 0x001D @ nidoranf
        .hword 0x0183 @ illumise to
        .hword 0x0182 @ volbeat
        .hword 0x0182 @ volbeat to
        .hword 0x0183 @ illumise



Megax Rocker November 19th, 2017 2:47 AM

Quote:

Originally Posted by BluRose (Post 9793133)
just add a second entry for the other way round to the table:
Code:

table1:
        .hword 0x001D @ nidoranf to
        .hword 0x0020 @ nidoranm
        .hword 0x0020 @ nidoranm to
        .hword 0x001D @ nidoranf
        .hword 0x0183 @ illumise to
        .hword 0x0182 @ volbeat
        .hword 0x0182 @ volbeat to
        .hword 0x0183 @ illumise



That's pretty good and it actually helps but it's not what I was talking about, I probably wasn't clear.

What I meant is, is it possible to have the routine check the father's and the mother's species and the resulting eggs would be either of them?

The egg will always be the mother's species, e.g male Bulbasaur and a female Charmander will always produce Charmander eggs.

Your routine would make it possible for Bulbasaur eggs to be produced, but charmander would produce bulbasaur eggs even if it breeds with other species.

What I'm thinking of is a universal chance of having the produced egg be of either species of the parents, this would allow ditto and male only pokemon to hatch eggs of their own species with any pokemon species.

Sorry for not being clear.

Lunos November 27th, 2017 7:17 AM

My last request was solved by normal means. I think that this one won't or might not be as easy though.

I did check JPAN's thread with the Fire Red specials and I found nothing about a command that saves the amount of happiness/friendship that a Pokémon has for the user to use however he wants.
So, can someone make a simple routine for Pokémon Fire Red that checks the amount of Friendship/Happiness that a Pokémon in the var 0x8004 has, and saves the actual amount of points in a different value.. say, 0x8005?

Example:
Spoiler:
(...)
special 0x9F // Pick a Pokémon and saves its Slot in 0x8004
waitstate
bufferpokemon 0x0 0x8004 // Saves the Pokémon in 0x8004 inside the Buffer #1 for msgbox purposes
callasm 0x8XXXXXX/0x8XXXXXX+1 // Would check the happiness of the Pokémon in 0x8004 and save it as a number in 0x8005
buffernumber 0x1 0x8005 // Saves the amount of Happiness in 0x8005 for msgbox purposes
msgbox @1 0x6
(...)

#org @1
= Your [BUFFER1] has [BUFFER2] happiness points.

ghoulslash November 27th, 2017 1:58 PM

Quote:

Originally Posted by Lunos (Post 9800402)
can someone make a simple routine for Pokémon Fire Red that checks the amount of Friendship/Happiness that a Pokémon in the var 0x8004 has, and saves the actual amount of points in a different value.. say, 0x8005?

Here you go! (admittedly I have not tested it)

Code:

.text
.align 2
.thumb
.thumb_func
.global GetHappiness

Main:
        push {r0-r2, lr}
        ldr r0, .var8004
        ldrb r0, [r0]        @slot num
        mov r1, #0x64
        mul r0, r1
        ldr r1, .PartyData
        add r0, r1, r0
        mov r1, #0x20        @happiness
        bl GetAttribute
        ldr r1, .var8004
        strb r0, [r1, #0x2]        @store into var8005
        pop {r0-r2, pc}

GetAttribute:
        ldr r2, =(0x0803FBE8 +1)
        bx r2

.align 2
.PartyData:        .word 0x02024284
.var8004:        .word 0x020370C0



Lunos November 27th, 2017 2:51 PM

Quote:

Originally Posted by ghoulslash (Post 9800529)
Here you go! (admittedly I have not tested it)

Code:

.text
.align 2
.thumb
.thumb_func
.global GetHappiness

Main:
        push {r0-r2, lr}
        ldr r0, .var8004
        ldrb r0, [r0]        @slot num
        mov r1, #0x64
        mul r0, r1
        ldr r1, .PartyData
        add r0, r1, r0
        mov r1, #0x20        @happiness
        bl GetAttribute
        ldr r1, .var8004
        strb r0, [r1, #0x2]        @store into var8005
        pop {r0-r2, pc}

GetAttribute:
        ldr r2, =(0x0803FBE8 +1)
        bx r2

.align 2
.PartyData:        .word 0x02024284
.var8004:        .word 0x020370C0



Welp, it didn't work.
I compiled the routine and dropped it in the offset 71A250, wrote this script and once I checked it In-Game, this was the result.
https://i.imgur.com/yGrrQAK.png
Note: Just for the record, the savefile is right after defeating my Rival for the very first time, so there's no way for my Pokémon to have 76 points.

Dunno if you'll be able to fix it, but in any case thank you very much.

ghoulslash November 27th, 2017 5:18 PM

Quote:

Originally Posted by Lunos (Post 9800566)
Welp, it didn't work.
I compiled the routine and dropped it in the offset 71A250, wrote this script and once I checked it In-Game, this was the result.
https://i.imgur.com/yGrrQAK.png
Note: Just for the record, the savefile is right after defeating my Rival for the very first time, so there's no way for my Pokémon to have 76 points.

Dunno if you'll be able to fix it, but in any case thank you very much.

Hmm. It seems like it might be working, as 76 is close enough to base happiness of 70. +5 pts for leveling up during the rival battle and +1 for running 128 steps is feasible.

You could test it by using the following set happiness (slot in 0x8004, value to set in 0x8005) routine with a pokemon that evolves via happiness. I think the threshold for evolving is 220? (Routine is also untested)

Code:

.text
.align 2
.thumb
.thumb_func
.global SetHappiness

Main:
        push {r0-r3, lr}
        ldr r2, .var8004
        ldrb r0, [r2]        @slot num
        add r2, #0x2        @var 0x8005 address where you stored new happiness
        mov r1, #0x64
        mul r0, r1
        ldr r1, .PartyData
        add r0, r1, r0
        mov r1, #0x20        @happiness
        bl SetAttribute
        pop {r0-r3, pc}

SetAttribute:
        ldr r3, =(0x0804037C +1)
        bx r3

.align 2
.PartyData:        .word 0x02024284
.var8004:        .word 0x020370C0



Lunos November 27th, 2017 5:45 PM

Quote:

Originally Posted by ghoulslash (Post 9800612)
Hmm. It seems like it might be working, as 76 is close enough to base happiness of 70. +5 pts for leveling up during the rival battle and +1 for running 128 steps is feasible.

Oh shoot, you're right! I absolutely forgot the base happiness and the bonus for leveling up!
I thought that the +1 could be because I defeated his Squirtle and that summed one point to my Charmander's happiness, but nope, I tested it by killing a wild Pokémon and it didn't add a point, so I guess the amount of steps must be the answer.

I also fixed my issue with the name by adding the special 0x7C to my script, so yeah, it's over.
https://i.imgur.com/B4kJ2eW.png
Thank you so much for making this routine Ghoul <3

Megax Rocker December 10th, 2017 1:02 PM

Quote:

Originally Posted by NewDenverCity (Post 9416548)
SPEEDING UP FIRERED
All this does is make the turbo button on VBA work faster.
Emerald solution is found here. That's also the source of my implementation of this.
Code:

.thumb

.org 0x890
main:
        push {lr}
        ldr r2, super_bits
        ldrh r3, [r2]
        mov r0, #1
        bic r3, r0
        strh r3, [r2]
loop_label:
        swi #2
        ldrh r3, [r2]
        tst r3, r0
        beq loop_label
        pop {pc}

.align 2
super_bits: .word 0x0300310C



Hello.

Is it possible to make turbo unusable by editing this routine?

Basically to prevent the player from abusing it for grinding and so on.

tkim December 10th, 2017 1:16 PM

Quote:

Originally Posted by Megax Rocker (Post 9807012)
Hello.

Is it possible to make turbo unusable by editing this routine?

Basically to prevent the player from abusing it for grinding and so on.

You mean the turbo function on VBA? If yes, it's impossible.

Quote:

Originally Posted by MWisBest (Post 9611218)
I combined this into 1 routine and cut the total size down a lot. All credit to DizzyEgg of course, this is nothing compared to creating the mod in the first place.

Code:

.text
.thumb
.thumb_func
.align 2

@ 0x1C379E: 02 30 00 4A 10 47 XX+1 XX XX 08
@ 0x1C3864: 00 4A 10 47 XX+1 XX XX 08

main:
        @ at this point... r0 contains our return address (- 8). Convenient!
        push {r5-r7}

        @ save return address for later.
        mov r6, r0
        add r6, #0x8

        @ to determine what function we were called from:
        @ if it was right stats, r9 is 0. if it was left stats, r9 has something in it.
        mov r7, r9 @ can't really use hi registers in thumb, mov it down.
        @ so, to check the function type: cmp r7, #0. eq means right stats.

        sub sp, sp, #0x20
        ldr r0, [r4] @pokemon summary pointer. we're free to use r4 after this.
        add r0, #0xA3 @poke nature
        ldrb r1, [r0]
        ldr r0, nature_stat_table

        mov r2, #5
        mul r2, r1

        mov r1, sp
        mov r5, #0

        add r2, r2, r0 @r2 contains nature info
        cmp r7, #0
        beq right_stats_begin

@@ LEFT STAT COLORING BEGIN @@@

left_stats_begin:
        ldr r3, left_stats_string

handle_hp:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #6
        bne handle_hp
        add r3, #6
        add r1, #6
        mov r5, #0

handle_atk:
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_atk
        cmp r0, #0xFF
        bne copy_atk
        bl blue_font
        b copy_atk

red_font_atk:
        bl red_font

copy_atk:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_atk
        add r3, #3
        add r1, #3
        mov r5, #0

handle_def:
        add r2, #1
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_def
        cmp r0, #0xFF
        beq blue_font_def
        bl default_font
        b copy_def

red_font_def:
        bl red_font
        b copy_def

blue_font_def:
        bl blue_font

copy_def:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_def
        b return

@@@ LEFT STAT COLORING END @@

@@@ RIGHT STAT COLORING BEGIN @@@

right_stats_begin:
        add r2, #3 @r2 contains beg of spatk stat
        ldr r3, right_stats_string

handle_spatk:
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_spatk
        cmp r0, #0xFF
        bne copy_spatk
        bl blue_font
        b copy_spatk

red_font_spatk:
        bl red_font

copy_spatk:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_spatk
        add r3, #3
        add r1, #3
        mov r5, #0

handle_spdef:
        add r2, #1
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_spdef
        cmp r0, #0xFF
        beq blue_font_spdef
        bl default_font
        b copy_spdef

red_font_spdef:
        bl red_font
        b copy_spdef

blue_font_spdef:
        bl blue_font

copy_spdef:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_spdef
        add r3, #3
        add r1, #3
        mov r5, #0

handle_spd:
        sub r2, #2
        ldrb r0, [r2]
        cmp r0, #1
        beq red_font_spd
        cmp r0, #0xFF
        beq blue_font_spd
        bl default_font
        b copy_spd

red_font_spd:
        bl red_font
        b copy_spd

blue_font_spd:
        bl blue_font

copy_spd:
        ldrb r0, [r3, r5]
        strb r0, [r1, r5]
        add r5, #1
        cmp r5, #3
        bne copy_spd
        b return

@@@ RIGHT STAT COLORING END @@@

@@@ FONT FUNCTIONS BEGIN @@@

blue_font: @FC 01 07
        mov r4, #7 @color of the lowered stat
        b font_common

red_font: @FC 01 05
        mov r4, #5 @color of the raised stat
        b font_common

default_font: @FC 01 01
        mov r4, #1 @color of the regular stats
        @ just fall through to font_common (no need to branch)

font_common:
        mov r0, #0xFC
        strb r0, [r1]
        add r1, #1
        mov r0, #1
        strb r0, [r1]
        add r1, #1
        strb r4, [r1]
        add r1, #1
        bx lr

@@@ FONT FUNCTIONS END @@@

return:
        ldr r0, displayed_string
        mov r1, sp
        ldr r2, special_f7_string_fct
        bl x_r2
        cmp r7, #0
        beq skip_mov_r0_r9
        mov r0, r9
skip_mov_r0_r9:
        add sp, sp, #0x20
        mov r2, r6
        pop {r5-r7}
x_r2:
        bx r2

.align 2
nature_stat_table: .word 0x0831E818
left_stats_string: .word 0x0861CE82
right_stats_string: .word 0x0861CE8E
displayed_string: .word 0x02021FC4
special_f7_string_fct: .word 0x081AFC29



Does anybody know how I can edit this in order to make it highlight the stat names instead of values? (ex. 'Attack' instead of '255')

Sensual December 12th, 2017 7:03 AM

Is it possible to add or subtract a value from a var? For example, if I have var x4000 set to 0x3, could I call ASM that dynamically subtracts 1 from it (making it 0x2)?

Pleasure December 12th, 2017 8:28 AM

Quote:

Originally Posted by Sensual (Post 9807808)
Is it possible to add or subtract a value from a var? For example, if I have var x4000 set to 0x3, could I call ASM that dynamically subtracts 1 from it (making it 0x2)?

Addition:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r1, lr}

        ldr r0, =(0x[address of var])

        ldrh r0, [r0]

        add r0, #0x1

        ldr r1, =(0x[address of var])
        strh r0, [r1]

        pop {r0-r1, pc}

.align 2




Subtraction
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r1, lr}

        ldr r0, =(0x[address of var])

        ldrh r0, [r0]

        sub r0, #0x1

        ldr r1, =(0x[address of var])
        strh r0, [r1]

        pop {r0-r1, pc}

.align 2



Skeli December 12th, 2017 8:51 AM

Quote:

Originally Posted by Sensual (Post 9807808)
Is it possible to add or subtract a value from a var? For example, if I have var x4000 set to 0x3, could I call ASM that dynamically subtracts 1 from it (making it 0x2)?

Use the addvar scripting command. Look up in the xse commands how it works.

Blah December 12th, 2017 9:44 AM

Quote:

Originally Posted by Pleasure (Post 9807831)
Addition:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r1, lr}

        ldr r0, =(0x[address of var])

        ldrh r0, [r0]

        add r0, #0x1

        ldr r1, =(0x[address of var])
        strh r0, [r1]

        pop {r0-r1, pc}

.align 2




Subtraction
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r1, lr}

        ldr r0, =(0x[address of var])

        ldrh r0, [r0]

        sub r0, #0x1

        ldr r1, =(0x[address of var])
        strh r0, [r1]

        pop {r0-r1, pc}

.align 2



This would break for every var not in the 0x8000s. Most scripting variables shuffle around with the saveblocks and you need to call the var_access function to get their locations. There is also var_set, var_load and over/underflow to think about. Overall, doing this in scripting is recommended as the callasm setup + execution ends up being slower.

Btw, you don't need to push scratch registers unless you were hooking (do so on a case by case basis). Nor the link register here because you're not calling a function.

Code:

.thumb
.align 2

main:
        ldr r0, =addr
        ldrh r1, [r0]
        sub r1, r1, #0x1
        strh r1, [r0]
        bx lr

.align 2
addr:
        .word 0xsomething


Something like this. But as mentioned before it's unadvisable to do it this way.

Pleasure December 13th, 2017 10:21 AM

Quote:

Originally Posted by FBI (Post 9807855)
This would break for every var not in the 0x8000s. Most scripting variables shuffle around with the saveblocks and you need to call the var_access function to get their locations. There is also var_set, var_load and over/underflow to think about. Overall, doing this in scripting is recommended as the callasm setup + execution ends up being slower.

Btw, you don't need to push scratch registers unless you were hooking (do so on a case by case basis). Nor the link register here because you're not calling a function.

Code:

.thumb
.align 2

main:
        ldr r0, =addr
        ldrh r1, [r0]
        sub r1, r1, #0x1
        strh r1, [r0]
        bx lr

.align 2
addr:
        .word 0xsomething


Something like this. But as mentioned before it's unadvisable to do it this way.

On this note, I want to use something similar to this in the future, but I need the value to stay within a certain range (0x0 - 0x5, for example). Is there a command that checks var values so that the script knows not to add or subtract once the value reaches either end of that range? Or would this require ASM?

Is there a document with all the XSE commands? I can't seem to find one.

Skeli December 13th, 2017 11:20 AM

Quote:

Originally Posted by Pleasure (Post 9808398)
On this note, I want to use something similar to this in the future, but I need the value to stay within a certain range (0x0 - 0x5, for example). Is there a command that checks var values so that the script knows not to add or subtract once the value reaches either end of that range? Or would this require ASM?

Is there a document with all the XSE commands? I can't seem to find one.

Go into XSE and click on the "Help" tab at the top, then "Command Help."

You could do something like:
compare 0x5000 0x5
if >= jump :end
addvar 0x5000 0x1
:end
end

Lunos December 26th, 2017 5:17 AM

Hi. Does anyone over here have an ASM Routine that allows you to hide and show the Trainer Card's access from the Start Menu at will?
https://i.imgur.com/xU5rWLD.png

Thanks in advance for reading.

ghoulslash December 26th, 2017 6:53 AM

Quote:

Originally Posted by Lunos (Post 9814236)
Hi. Does anyone over here have an ASM Routine that allows you to hide and show the Trainer Card's access from the Start Menu at will?
https://i.imgur.com/xU5rWLD.png

Thanks in advance for reading.

You can adjust this routine to do this. The "noMon" header determines the start menu options after pokedex and pokemon, where
Code:

mov r0, #0xX
ldr r1, =(0x806ED94 +1)
bl linker


shows the start menu option 'X'. So in that particular routine, 0x4 is not being added, which is the 'Save' function. So, to remove the trainer card, you would just leave out the 0x3 index of the start menu

Delta231 December 26th, 2017 7:04 AM

I would like someone to make an ASM Routine to have separate palletes for the OWs which appear on the World Map. (Fire Red)

Here are the offsets for the images
Male


Female

ghoulslash December 28th, 2017 7:22 AM

Quote:

Originally Posted by Delta231 (Post 9814271)
I would like someone to make an ASM Routine to have separate palletes for the OWs which appear on the World Map. (Fire Red)

Here are the offsets for the images
Male


Female

You actually probably don't need an assembly routine for this. I would use
Navenatox's dynamic overworld palettes patch
. You can just re-upload the female sprites and it will inherit a different palette number. And combined with JPAN's engine allows you to swap player overworld sprites, all with individual palettes.

Hope this helps :)

Delta231 December 28th, 2017 7:56 AM

Quote:

Originally Posted by ghoulslash (Post 9815323)
You actually probably don't need an assembly routine for this. I would use
Navenatox's dynamic overworld palettes patch
. You can just re-upload the female sprites and it will inherit a different palette number. And combined with JPAN's engine allows you to swap player overworld sprites, all with individual palettes.

Hope this helps :)

Does it really work? I kinda doubt that. :P

ghoulslash December 28th, 2017 10:56 AM

Quote:

Originally Posted by Delta231 (Post 9815343)
Does it really work? I kinda doubt that. :P

It should work fine, as long as you haven't overwritten anything. Try it out!

Lancekoijerwillborough December 30th, 2017 12:26 AM

here is the request of mine:

1. Other Forms
I am looking for a routine that allows 2 or more species to share similar dex number. By that, we can have a feature for Flabébé forms and other Pokémon

Mystelex December 30th, 2017 5:30 PM

Quote:

Originally Posted by Delta231 (Post 9815343)
Does it really work? I kinda doubt that. :P

Delta, they actually use separate palettes.
Boy: 003EF27C
Girl: 003EF29C

:dansad:

Delta231 December 30th, 2017 9:55 PM

Quote:

Originally Posted by Daman (Post 9816672)
Delta, they actually use separate palettes.
Boy: 003EF27C
Girl: 003EF29C

:dansad:

Thanks
^^

Quote:

Originally Posted by ghoulslash (Post 9815428)
It should work fine, as long as you haven't overwritten anything. Try it out!

Sorry, I should have double checked. ;-;

DarkPsychic January 1st, 2018 12:02 AM

XSE Special Command to delete pokemon

Hello,
After taking a tutorial from FBI we where able to come up with this.

Here is how it works:
Var 0x8004 value
0x0 = Players 1st Pokemon
0x1 = Players 2nd Pokemon
0x2 = Players 3rd Pokemon
0x3 = Players 4th Pokemon
0x4 = Players 5th Pokemon
0x5 = Players 6th Pokemon


So you could use Special 0x9F.
Which will let you choose the Pokemon you want deleted.
Then callasm 0x?????? +1(where "??????" is where you placed this routine).

C source:
Code:


#include

void delete_pokemon()
{
    u8 slot = var_8004; // get slot id from variable
    if (slot != 5) {
        memcpy(&party_player[slot], &party_player[slot + 1], 100 * (5 - slot));
    }
    memset(&party_player[5], 0x0, 100);
    return;
}


Pre-Compiled version:
Code:


0C 4B 1B 78 10 B5 05 2B 0C D0 64 24 05 22 59 1C
D2 1A 61 43 63 43 08 48 62 43 09 18 18 18 07 4B
00 F0 12 F8 64 22 00 21 05 48 06 4B 00 F0 0C F8
10 BD C0 46 C0 70 03 02 84 42 02 02 79 5E 1E 08
78 44 02 02 D9 5E 1E 08 18 47 C0 46


Place in free aligned location.

Xse Test Script:
Code:


#dynamic 0x810000

#org @start
lockall
faceplayer
msgbox @question 0x5
compare 0x800D 0x1
if 0x1 goto @yes
msgbox @no 0x6
releaseall
end

#org @yes
msgbox @delete 0x6
special 0x9F
waitstate
callasm 0x??????+1  //make sure to change this to pointer where you put routine
msgbox @done 0x6
release
end

#org @question
= Would you like me to delete a Pokemon?

#org @delete
=Alright then here we go!

#org @done
= There the deed has been done!

#org @no
= Maybe next time then.
Hope this helps and credit to FBI once again.


Hope this helps.

Xencleamas January 7th, 2018 10:37 PM

Quote:

Originally Posted by azurile13 (Post 9169525)
This post motivated me to create an actual regional dex instead of just giving a national dex at the start, so thanks :D I've added some extra routines to do things like display the correct regional dex number in summary screens, displaying dex info on capture, and having the proper regional dex count. New hooks:
Code:

.thumb
.align

.equ number_of_mons_in_regional_dex,        300        //or however long you wanted your regional dex to be
.equ number_of_mons_in_national_dex,        721

data_on_capture_hook:        //0x08106B84 via r1
        bl species_to_regional_dex_number
        cmp r0, #0x0
        bne capture_display_return
        ldr r0, add_task_no_capture_display
        bx r0

capture_display_return:
        ldr r0, add_task_capture_display
        bx r0

habitat_dex_regional_limit_hook:        //0x08106810 via r1
        push {r4, lr}
        mov r4, r0
        bl haz_national_dex_bool
        cmp r0, #0x1
        beq habitat_dex_regional_limit_return        //valid
        mov r0, r4
        bl species_to_regional_dex_number
        cmp r0, #0x0
        beq habitat_dex_regional_limit_return        //not in regional dex, return 0
        mov r0, #0x1

habitat_dex_regional_limit_return:
        pop {r4}
        pop {r1}
        bx r1

dex_seeable_mon_hook:        //0x08043F90 via r1
        push {r4, lr}
        mov r4, r0
        bl haz_national_dex_bool
        cmp r0, #0x0
        beq only_regional_numbered
//national
        mov r0, r4
        bl species_to_national_dex_number_1
        b dex_seeable_mon_check_valid_species

only_regional_numbered:
        mov r0, r4
        bl species_to_regional_dex_number

dex_seeable_mon_check_valid_species:
        cmp r0, #0x0
        bne dex_seeable_mon_return
        ldr r0, full_halfword

dex_seeable_mon_return:
        pop {r4}
        pop {r1}
        bx r1
.align
full_halfword:        .word 0xFFFF

dex_evolution_fix_hook:        //0x080CE91A via r1
        bl species_to_regional_dex_number
        cmp r0, #0x0        //not in regional dex, invalid
        beq dex_evolution_failure
        ldr r0, dex_evolution_success_return
        bx r0

dex_evolution_failure:
        mov r0, #0x11
        strh r0, [r5, #0x8]
        mov r2, #0x1
        ldr r1, dex_evolution_failure_return
        bx r1

dex_display_counts_hook:        //0x08104BBC via r2
        //r0: mode
        push {lr}
        cmp r1, #0x0
        beq call_regional_count
        bl national_pokedex_count
        b dex_display_counts_return

call_regional_count:
        bl dex_regional_count_hook

dex_display_counts_return:
        pop {pc}

dex_regional_count_hook:        //0x08088EDC via r1
        push {r4-r6, lr}
        mov r6, r0        //mode
        mov r4, #0x1        //loop
        mov r5, #0x0        //counter

dex_regional_count_loop:
        lsl r0, r4, #0x1        //loop times 2
        adr r1, regional_dex_order
        ldrh r0, [r1, r0]        //req species
        mov r1, r6        //mode
        mov r2, #0x1        //input is SPECIES
        bl dex_flag_check
        add r5, r5, r0
        add r4, #0x1
        ldr r0, regional_dex_limit
        cmp r4, r0
        blo dex_regional_count_loop
        mov r0, r5
        pop {r4-r6, pc}

dex_display_hook:        //0x0810352C via r1
        ldr r1, regional_dex_limit
        cmp r0, #0x0
        beq store_dex_limit_and_return
        ldr r1, national_dex_limit

store_dex_limit_and_return:
        str r1, [sp, #0x0]
        ldr r0, regional_dex_limit_return
        bx r0

regional_dex_hook:        //0x0810356C via r0
        mov r4, r8
        add r4, #0x1
        lsl r0, r4, #0x1        //index times 2
        adr r1, regional_dex_order
        ldrh r0, [r1, r0]
        bl species_to_national_dex_number_1
        mov r5, r0
        mov r1, #0x0
        ldr r2, regional_dex_hook_return
        bx r2

store_last_dex_seen_hook:        //0x081035B4 via r1
        str r0, [r2]
        mov r10, r4
        mov r4, r3
        ldr r0, def_store_string_dex_number
        bx r0

lazy_regional_dex_end_hook:        //0x081035F4 via r0
        mov r0, r8
        ldr r1, regional_dex_limit
        cmp r0, r1
        blo regional_dex_hook
        ldr r0, end_dex_display_return
        bx r0

display_regional_num_hook:        //0x08104A66 via r1
        mov r5, r0        //save species
        bl haz_national_dex_bool
        cmp r0, #0x0
        beq use_regional_dex_ordering
        ldr r1, dex_malloc_ptr
        ldr r1, [r1]
        add r1, #0x42
        ldrb r1, [r1]
        cmp r1, #0x0        //check if looking at regional dex
        beq use_regional_dex_ordering
        mov r0, r5
        bl species_to_national_dex_number_1
        b display_dex_number_return

use_regional_dex_ordering:
        mov r0, r5
        bl species_to_regional_dex_number       

display_dex_number_return:
        mov r5, r0
        ldr r0, dex_number_display_return
        bx r0

species_to_regional_dex_number:
        adr r3, regional_dex_order
        mov r2, r0        //req species
        mov r0, #0x0        //loop counter
find_regional_number_loop:
        lsl r1, r0, #0x1
        ldrh r1, [r3, r1]
        cmp r1, r2
        beq species_to_regional_dex_return
        add r0, #0x1
        ldr r1, regional_dex_limit
        cmp r0, r1
        bls find_regional_number_loop
        mov r0, #0x0        //not in dex: set number to 0
species_to_regional_dex_return:
        bx lr

species_to_national_dex_number_1:
        ldr r1, f_species_to_nat_dex
        bx r1
.align
f_species_to_nat_dex:        .word 0x08043298 + 1

haz_national_dex_bool:
        ldr r0, f_haz_national_check
        bx r0
.align
f_haz_national_check:        .word 0x0806E25C + 1

dex_flag_check:
        ldr r3, f_dex_flag_check
        bx r3
.align
f_dex_flag_check:        .word 0x08104AB0 + 1

national_pokedex_count:
        ldr r1, f_national_pokedex_count
        bx r1
.align
f_national_pokedex_count:        .word 0x08088E8C + 1

.align
add_task_no_capture_display:        .word 0x08106B90 + 1
add_task_capture_display:        .word 0x08106BA4 + 1
dex_evolution_success_return:        .word 0x080CE948 + 1
dex_evolution_failure_return:        .word 0x080CE924 + 1
regional_dex_limit:        .word number_of_mons_in_regional_dex
national_dex_limit:        .word number_of_mons_in_national_dex
regional_dex_limit_return:        .word 0x0810353a + 1
regional_dex_hook_return:        .word 0x08103578 + 1
def_store_string_dex_number:        .word 0x081035D6 + 1
end_dex_display_return:        .word 0x08103906 + 1
dex_malloc_ptr:                        .word 0x0203ACF0
dex_number_display_return:        .word 0x08104A70 + 1

regional_dex_order:
.short 0x0000
.short CHIKORITA
.short BAYLEEF
.short MEGANIUM
etc


For anyone using Touched's scripts/ASMAGIX:
Code:

data_on_capture_hook                08106B84        1
dex_seeable_mon_hook                08043F90        1
dex_evolution_fix_hook                080CE91A        1
dex_display_counts_hook                08104BBC        2
dex_regional_count_hook                08088EDC        1
dex_display_hook                0810352C        1
regional_dex_hook                0810356C        0
store_last_dex_seen_hook        081035B4        1
lazy_regional_dex_end_hook        081035F4        0
display_regional_num_hook        08104A66        1
habitat_dex_regional_limit_hook        08106810        1



I have modified and enhanced azurile13's (credits and kudos to him) routine to make this supported on the Compiler's THUMB.bat. These are the things I modified:
  • Added routines creating the hooks that are to be copy-pasted on their respective locations. There are 11 hooks.
  • Added the master location of the routine in which the hooks will create locations for those routines. Insert your free space on .equ MyLoc. Format: 0x###### (Hexadecimal Number)
  • Created and added a new index list of Pokémon up to Generation VI including the formes in style of KDS/Chacha Dinosaur from the filenames of MrDollSteak's sprites in his Sugimori and Gen VI threads. I think there is no master index list for Generation VII. If there is, please PM me and I will add those.
  • With the list created as stated above, you will just have to create your own Regional Pokédex by copy-pasting from your Excel and Notepad file to below "regional_dex_order" and .hword 0x0000 should be first in the list. Make sure the names are all CAPS-LOCKED. In case of Nidorans, Farfetch'd, Mr. Mime, Ho-Oh, Mime Jr., Porygon-Z, and Flabébé, their characters are changed so you'll have to look for them in the master list. NOTE: Cofagrigus have been filtered out and changed into asterisks (*). Remember to correct its name before generating the binary file otherwise the .asm file won't work.

Custom Regional Pokédex for FireRed:
Spoiler:
Code:

.thumb
.align

.equ number_of_mons_in_regional_dex, 202 @or however long you wanted your regional dex to be
.equ number_of_mons_in_national_dex, 386
.equ MyLoc, 0x888888 @insert your location here
.equ RomAreaOffset,        0x8000000

@Kanto

.equ UNKNOWN, 0x0
.equ BULBASAUR, 0x1
.equ IVYSAUR, 0x2
.equ VENUSAUR, 0x3
.equ CHARMANDER, 0x4
.equ CHARMELEON, 0x5
.equ CHARIZARD, 0x6
.equ SQUIRTLE, 0x7
.equ WARTORTLE, 0x8
.equ BLASTOISE, 0x9
.equ CATERPIE, 0xA
.equ METAPOD, 0xB
.equ BUTTERFREE, 0xC
.equ WEEDLE, 0xD
.equ KAKUNA, 0xE
.equ BEEDRILL, 0xF
.equ PIDGEY, 0x10
.equ PIDGEOTTO, 0x11
.equ PIDGEOT, 0x12
.equ RATTATA, 0x13
.equ RATICATE, 0x14
.equ SPEAROW, 0x15
.equ FEAROW, 0x16
.equ EKANS, 0x17
.equ ARBOK, 0x18
.equ PIKACHU, 0x19
.equ RAICHU, 0x1A
.equ SANDSHREW, 0x1B
.equ SANDSLASH, 0x1C
.equ NIDORAN_F, 0x1D
.equ NIDORINA, 0x1E
.equ NIDOQUEEN, 0x1F
.equ NIDORAN_M, 0x20
.equ NIDORINO, 0x21
.equ NIDOKING, 0x22
.equ CLEFAIRY, 0x23
.equ CLEFABLE, 0x24
.equ VULPIX, 0x25
.equ NINETALES, 0x26
.equ JIGGLYPUFF, 0x27
.equ WIGGLYTUFF, 0x28
.equ ZUBAT, 0x29
.equ GOLBAT, 0x2A
.equ ODDISH, 0x2B
.equ GLOOM, 0x2C
.equ VILEPLUME, 0x2D
.equ PARAS, 0x2E
.equ PARASECT, 0x2F
.equ VENONAT, 0x30
.equ VENOMOTH, 0x31
.equ DIGLETT, 0x32
.equ DUGTRIO, 0x33
.equ MEOWTH, 0x34
.equ PERSIAN, 0x35
.equ PSYDUCK, 0x36
.equ GOLDUCK, 0x37
.equ MANKEY, 0x38
.equ PRIMEAPE, 0x39
.equ GROWLITHE, 0x3A
.equ ARCANINE, 0x3B
.equ POLIWAG, 0x3C
.equ POLIWHIRL, 0x3D
.equ POLIWRATH, 0x3E
.equ ABRA, 0x3F
.equ KADABRA, 0x40
.equ ALAKAZAM, 0x41
.equ MACHOP, 0x42
.equ MACHOKE, 0x43
.equ MACHAMP, 0x44
.equ BELLSPROUT, 0x45
.equ WEEPINBELL, 0x46
.equ VICTREEBEL, 0x47
.equ TENTACOOL, 0x48
.equ TENTACRUEL, 0x49
.equ GEODUDE, 0x4A
.equ GRAVELER, 0x4B
.equ GOLEM, 0x4C
.equ PONYTA, 0x4D
.equ RAPIDASH, 0x4E
.equ SLOWPOKE, 0x4F
.equ SLOWBRO, 0x50
.equ MAGNEMITE, 0x51
.equ MAGNETON, 0x52
.equ FARFETCH_D, 0x53
.equ DODUO, 0x54
.equ DODRIO, 0x55
.equ SEEL, 0x56
.equ DEWGONG, 0x57
.equ GRIMER, 0x58
.equ MUK, 0x59
.equ SHELLDER, 0x5A
.equ CLOYSTER, 0x5B
.equ GASTLY, 0x5C
.equ HAUNTER, 0x5D
.equ GENGAR, 0x5E
.equ ONIX, 0x5F
.equ DROWZEE, 0x60
.equ HYPNO, 0x61
.equ KRABBY, 0x62
.equ KINGLER, 0x63
.equ VOLTORB, 0x64
.equ ELECTRODE, 0x65
.equ EXEGGCUTE, 0x66
.equ EXEGGUTOR, 0x67
.equ CUBONE, 0x68
.equ MAROWAK, 0x69
.equ HITMONLEE, 0x6A
.equ HITMONCHAN, 0x6B
.equ LICKITUNG, 0x6C
.equ KOFFING, 0x6D
.equ WEEZING, 0x6E
.equ RHYHORN, 0x6F
.equ RHYDON, 0x70
.equ CHANSEY, 0x71
.equ TANGELA, 0x72
.equ KANGASKHAN, 0x73
.equ HORSEA, 0x74
.equ SEADRA, 0x75
.equ GOLDEEN, 0x76
.equ SEAKING, 0x77
.equ STARYU, 0x78
.equ STARMIE, 0x79
.equ MR_MIME, 0x7A
.equ SCYTHER, 0x7B
.equ JYNX, 0x7C
.equ ELECTABUZZ, 0x7D
.equ MAGMAR, 0x7E
.equ PINSIR, 0x7F
.equ TAUROS, 0x80
.equ MAGIKARP, 0x81
.equ GYARADOS, 0x82
.equ LAPRAS, 0x83
.equ DITTO, 0x84
.equ EEVEE, 0x85
.equ VAPOREON, 0x86
.equ JOLTEON, 0x87
.equ FLAREON, 0x88
.equ PORYGON, 0x89
.equ OMANYTE, 0x8A
.equ OMASTAR, 0x8B
.equ KABUTO, 0x8C
.equ KABUTOPS, 0x8D
.equ AERODACTYL, 0x8E
.equ SNORLAX, 0x8F
.equ ARTICUNO, 0x90
.equ ZAPDOS, 0x91
.equ MOLTRES, 0x92
.equ DRATINI, 0x93
.equ DRAGONAIR, 0x94
.equ DRAGONITE, 0x95
.equ MEWTWO, 0x96
.equ MEW, 0x97
.equ CHIKORITA, 0x98
.equ BAYLEEF, 0x99
.equ MEGANIUM, 0x9A
.equ CYNDAQUIL, 0x9B
.equ QUILAVA, 0x9C
.equ TYPHLOSION, 0x9D
.equ TOTODILE, 0x9E
.equ CROCONAW, 0x9F
.equ FERALIGATR, 0xA0
.equ SENTRET, 0xA1
.equ FURRET, 0xA2
.equ HOOTHOOT, 0xA3
.equ NOCTOWL, 0xA4
.equ LEDYBA, 0xA5
.equ LEDIAN, 0xA6
.equ SPINARAK, 0xA7
.equ ARIADOS, 0xA8
.equ CROBAT, 0xA9
.equ CHINCHOU, 0xAA
.equ LANTURN, 0xAB
.equ PICHU, 0xAC
.equ CLEFFA, 0xAD
.equ IGGLYBUFF, 0xAE
.equ TOGEPI, 0xAF
.equ TOGETIC, 0xB0
.equ NATU, 0xB1
.equ XATU, 0xB2
.equ MAREEP, 0xB3
.equ FLAAFFY, 0xB4
.equ AMPHAROS, 0xB5
.equ BELLOSSOM, 0xB6
.equ MARILL, 0xB7
.equ AZUMARILL, 0xB8
.equ SUDOWOODO, 0xB9
.equ POLITOED, 0xBA
.equ HOPPIP, 0xBB
.equ SKIPLOOM, 0xBC
.equ JUMPLUFF, 0xBD
.equ AIPOM, 0xBE
.equ SUNKERN, 0xBF
.equ SUNFLORA, 0xC0
.equ YANMA, 0xC1
.equ WOOPER, 0xC2
.equ QUAGSIRE, 0xC3
.equ ESPEON, 0xC4
.equ UMBREON, 0xC5
.equ MURKROW, 0xC6
.equ SLOWKING, 0xC7
.equ MISDREAVUS, 0xC8
.equ UNOWN, 0xC9
.equ WOBBUFFET, 0xCA
.equ GIRAFARIG, 0xCB
.equ PINECO, 0xCC
.equ FORRETRESS, 0xCD
.equ DUNSPARCE, 0xCE
.equ GLIGAR, 0xCF
.equ STEELIX, 0xD0
.equ SNUBBULL, 0xD1
.equ GRANBULL, 0xD2
.equ QWILFISH, 0xD3
.equ SCIZOR, 0xD4
.equ SHUCKLE, 0xD5
.equ HERACROSS, 0xD6
.equ SNEASEL, 0xD7
.equ TEDDIURSA, 0xD8
.equ URSARING, 0xD9
.equ SLUGMA, 0xDA
.equ MAGCARGO, 0xDB
.equ SWINUB, 0xDC
.equ PILOSWINE, 0xDD
.equ CORSOLA, 0xDE
.equ REMORAID, 0xDF
.equ OCTILLERY, 0xE0
.equ DELIBIRD, 0xE1
.equ MANTINE, 0xE2
.equ SKARMORY, 0xE3
.equ HOUNDOUR, 0xE4
.equ HOUNDOOM, 0xE5
.equ KINGDRA, 0xE6
.equ PHANPY, 0xE7
.equ DONPHAN, 0xE8
.equ PORYGON2, 0xE9
.equ STANTLER, 0xEA
.equ SMEARGLE, 0xEB
.equ TYROGUE, 0xEC
.equ HITMONTOP, 0xED
.equ SMOOCHUM, 0xEE
.equ ELEKID, 0xEF
.equ MAGBY, 0xF0
.equ MILTANK, 0xF1
.equ BLISSEY, 0xF2
.equ RAIKOU, 0xF3
.equ ENTEI, 0xF4
.equ SUICUNE, 0xF5
.equ LARVITAR, 0xF6
.equ PUPITAR, 0xF7
.equ TYRANITAR, 0xF8
.equ LUGIA, 0xF9
.equ HO_OH, 0xFA
.equ CELEBI, 0xFB
.equ NOPE, 0xFC
.equ NOPE, 0xFD
.equ NOPE, 0xFE
.equ NOPE, 0xFF
.equ NOPE, 0x100
.equ NOPE, 0x101
.equ NOPE, 0x102
.equ NOPE, 0x103
.equ NOPE, 0x104
.equ NOPE, 0x105
.equ NOPE, 0x106
.equ NOPE, 0x107
.equ NOPE, 0x108
.equ NOPE, 0x109
.equ NOPE, 0x10A
.equ NOPE, 0x10B
.equ NOPE, 0x10C
.equ NOPE, 0x10D
.equ NOPE, 0x10E
.equ NOPE, 0x10F
.equ NOPE, 0x110
.equ NOPE, 0x111
.equ NOPE, 0x112
.equ NOPE, 0x113
.equ NOPE, 0x114
.equ TREECKO, 0x115
.equ GROVYLE, 0x116
.equ SCEPTILE, 0x117
.equ TORCHIC, 0x118
.equ COMBUSKEN, 0x119
.equ BLAZIKEN, 0x11A
.equ MUDKIP, 0x11B
.equ MARSHTOMP, 0x11C
.equ SWAMPERT, 0x11D
.equ POOCHYENA, 0x11E
.equ MIGHTYENA, 0x11F
.equ ZIGZAGOON, 0x120
.equ LINOONE, 0x121
.equ WURMPLE, 0x122
.equ SILCOON, 0x123
.equ BEAUTIFLY, 0x124
.equ CASCOON, 0x125
.equ DUSTOX, 0x126
.equ LOTAD, 0x127
.equ LOMBRE, 0x128
.equ LUDICOLO, 0x129
.equ SEEDOT, 0x12A
.equ NUZLEAF, 0x12B
.equ SHIFTRY, 0x12C
.equ NINCADA, 0x12D
.equ NINJASK, 0x12E
.equ SHEDINJA, 0x12F
.equ TAILLOW, 0x130
.equ SWELLOW, 0x131
.equ SHROOMISH, 0x132
.equ BRELOOM, 0x133
.equ SPINDA, 0x134
.equ WINGULL, 0x135
.equ PELIPPER, 0x136
.equ SURSKIT, 0x137
.equ MASQUERAIN, 0x138
.equ WAILMER, 0x139
.equ WAILORD, 0x13A
.equ SKITTY, 0x13B
.equ DELCATTY, 0x13C
.equ KECLEON, 0x13D
.equ BALTOY, 0x13E
.equ CLAYDOL, 0x13F
.equ NOSEPASS, 0x140
.equ TORKOAL, 0x141
.equ SABLEYE, 0x142
.equ BARBOACH, 0x143
.equ WHISCASH, 0x144
.equ LUVDISC, 0x145
.equ CORPHISH, 0x146
.equ CRAWDAUNT, 0x147
.equ FEEBAS, 0x148
.equ MILOTIC, 0x149
.equ CARVANHA, 0x14A
.equ SHARPEDO, 0x14B
.equ TRAPINCH, 0x14C
.equ VIBRAVA, 0x14D
.equ FLYGON, 0x14E
.equ MAKUHITA, 0x14F
.equ HARIYAMA, 0x150
.equ ELECTRIKE, 0x151
.equ MANECTRIC, 0x152
.equ NUMEL, 0x153
.equ CAMERUPT, 0x154
.equ SPHEAL, 0x155
.equ SEALEO, 0x156
.equ WALREIN, 0x157
.equ CACNEA, 0x158
.equ CACTURNE, 0x159
.equ SNORUNT, 0x15A
.equ GLALIE, 0x15B
.equ LUNATONE, 0x15C
.equ SOLROCK, 0x15D
.equ AZURILL, 0x15E
.equ SPOINK, 0x15F
.equ GRUMPIG, 0x160
.equ PLUSLE, 0x161
.equ MINUN, 0x162
.equ MAWILE, 0x163
.equ MEDITITE, 0x164
.equ MEDICHAM, 0x165
.equ SWABLU, 0x166
.equ ALTARIA, 0x167
.equ WYNAUT, 0x168
.equ DUSKULL, 0x169
.equ DUSCLOPS, 0x16A
.equ ROSELIA, 0x16B
.equ SLAKOTH, 0x16C
.equ VIGOROTH, 0x16D
.equ SLAKING, 0x16E
.equ GULPIN, 0x16F
.equ SWALOT, 0x170
.equ TROPIUS, 0x171
.equ WHISMUR, 0x172
.equ LOUDRED, 0x173
.equ EXPLOUD, 0x174
.equ CLAMPERL, 0x175
.equ HUNTAIL, 0x176
.equ GOREBYSS, 0x177
.equ ABSOL, 0x178
.equ SHUPPET, 0x179
.equ BANETTE, 0x17A
.equ SEVIPER, 0x17B
.equ ZANGOOSE, 0x17C
.equ RELICANTH, 0x17D
.equ ARON, 0x17E
.equ LAIRON, 0x17F
.equ AGGRON, 0x180
.equ CASTFORM, 0x181
.equ VOLBEAT, 0x182
.equ ILLUMISE, 0x183
.equ LILEEP, 0x184
.equ CRADILY, 0x185
.equ ANORITH, 0x186
.equ ARMALDO, 0x187
.equ RALTS, 0x188
.equ KIRLIA, 0x189
.equ GARDEVOIR, 0x18A
.equ BAGON, 0x18B
.equ SHELGON, 0x18C
.equ SALAMENCE, 0x18D
.equ BELDUM, 0x18E
.equ METANG, 0x18F
.equ METAGROSS, 0x190
.equ REGIROCK, 0x191
.equ REGICE, 0x192
.equ REGISTEEL, 0x193
.equ KYOGRE, 0x194
.equ GROUDON, 0x195
.equ RAYQUAZA, 0x196
.equ LATIAS, 0x197
.equ LATIOS, 0x198
.equ JIRACHI, 0x199
.equ DEOXYS, 0x19A
.equ CHIMECHO, 0x19B
.equ EGG, 0x19C
.equ UNOWN_B, 0x19D
.equ UNOWN_C, 0x19E
.equ UNOWN_D, 0x19F
.equ UNOWN_E, 0x1A0
.equ UNOWN_F, 0x1A1
.equ UNOWN_G, 0x1A2
.equ UNOWN_H, 0x1A3
.equ UNOWN_I, 0x1A4
.equ UNOWN_J, 0x1A5
.equ UNOWN_K, 0x1A6
.equ UNOWN_L, 0x1A7
.equ UNOWN_M, 0x1A8
.equ UNOWN_N, 0x1A9
.equ UNOWN_O, 0x1AA
.equ UNOWN_P, 0x1AB
.equ UNOWN_Q, 0x1AC
.equ UNOWN_R, 0x1AD
.equ UNOWN_S, 0x1AE
.equ UNOWN_T, 0x1AF
.equ UNOWN_U, 0x1B0
.equ UNOWN_V, 0x1B1
.equ UNOWN_W, 0x1B2
.equ UNOWN_X, 0x1B3
.equ UNOWN_Y, 0x1B4
.equ UNOWN_Z, 0x1B5
.equ UNOWN_EXCLAMATION, 0x1B6
.equ UNOWN_QUESTION, 0x1B7
.equ TURTWIG, 0x1B8
.equ GROTLE, 0x1B9
.equ TORTERRA, 0x1BA
.equ CHIMCHAR, 0x1BB
.equ MONFERNO, 0x1BC
.equ INFERNAPE, 0x1BD
.equ PIPLUP, 0x1BE
.equ PRINPLUP, 0x1BF
.equ EMPOLEON, 0x1C0
.equ STARLY, 0x1C1
.equ STARAVIA, 0x1C2
.equ STARAPTOR, 0x1C3
.equ BIDOOF, 0x1C4
.equ BIBAREL, 0x1C5
.equ KRICKETOT, 0x1C6
.equ KRICKETUNE, 0x1C7
.equ SHINX, 0x1C8
.equ LUXIO, 0x1C9
.equ LUXRAY, 0x1CA
.equ BUDEW, 0x1CB
.equ ROSERADE, 0x1CC
.equ CRANIDOS, 0x1CD
.equ RAMPARDOS, 0x1CE
.equ SHIELDON, 0x1CF
.equ BASTIODON, 0x1D0
.equ BURMY, 0x1D1
.equ WORMADAM, 0x1D2
.equ MOTHIM, 0x1D3
.equ COMBEE, 0x1D4
.equ VESPIQUEN, 0x1D5
.equ PACHIRISU, 0x1D6
.equ BUIZEL, 0x1D7
.equ FLOATZEL, 0x1D8
.equ CHERUBI, 0x1D9
.equ CHERRIM, 0x1DA
.equ SHELLOS, 0x1DB
.equ GASTRODON, 0x1DC
.equ AMBIPOM, 0x1DD
.equ DRIFLOON, 0x1DE
.equ DRIFBLIM, 0x1DF
.equ BUNEARY, 0x1E0
.equ LOPUNNY, 0x1E1
.equ MISMAGIUS, 0x1E2
.equ HONCHKROW, 0x1E3
.equ GLAMEOW, 0x1E4
.equ PURUGLY, 0x1E5
.equ CHINGLING, 0x1E6
.equ STUNKY, 0x1E7
.equ SKUNTANK, 0x1E8
.equ BRONZOR, 0x1E9
.equ BRONZONG, 0x1EA
.equ BONSLY, 0x1EB
.equ MIME_JR, 0x1EC
.equ HAPPINY, 0x1ED
.equ CHATOT, 0x1EE
.equ SPIRITOMB, 0x1EF
.equ GIBLE, 0x1F0
.equ GABITE, 0x1F1
.equ GARCHOMP, 0x1F2
.equ MUNCHLAX, 0x1F3
.equ RIOLU, 0x1F4
.equ LUCARIO, 0x1F5
.equ HIPPOPOTAS, 0x1F6
.equ HIPPOWDON, 0x1F7
.equ SKORUPI, 0x1F8
.equ DRAPION, 0x1F9
.equ CROAGUNK, 0x1FA
.equ TOXICROAK, 0x1FB
.equ CARNIVINE, 0x1FC
.equ FINNEON, 0x1FD
.equ LUMINEON, 0x1FE
.equ MANTYKE, 0x1FF
.equ SNOVER, 0x200
.equ ABOMASNOW, 0x201
.equ WEAVILE, 0x202
.equ MAGNEZONE, 0x203
.equ LICKILICKY, 0x204
.equ RHYPERIOR, 0x205
.equ TANGROWTH, 0x206
.equ ELECTIVIRE, 0x207
.equ MAGMORTAR, 0x208
.equ TOGEKISS, 0x209
.equ YANMEGA, 0x20A
.equ LEAFEON, 0x20B
.equ GLACEON, 0x20C
.equ GLISCOR, 0x20D
.equ MAMOSWINE, 0x20E
.equ PORYGON_Z, 0x20F
.equ GALLADE, 0x210
.equ PROBOPASS, 0x211
.equ DUSKNOIR, 0x212
.equ FROSLASS, 0x213
.equ ROTOM, 0x214
.equ UXIE, 0x215
.equ MESPRIT, 0x216
.equ AZELF, 0x217
.equ DIALGA, 0x218
.equ PALKIA, 0x219
.equ HEATRAN, 0x21A
.equ REGIGIGAS, 0x21B
.equ GIRATINA, 0x21C
.equ CRESSELIA, 0x21D
.equ PHIONE, 0x21E
.equ MANAPHY, 0x21F
.equ DARKRAI, 0x220
.equ SHAYMIN, 0x221
.equ ARCEUS, 0x222
.equ BURMY_SAND, 0x223
.equ BURMY_TRASH, 0x224
.equ WORMADAM_SAND, 0x225
.equ WORMADAM_THRASH, 0x226
.equ SHELLOS_EAST, 0x227
.equ GASTRODON_EAST, 0x228
.equ ROTOM_HEAT, 0x229
.equ ROTOM_WASH, 0x22A
.equ ROTOM_FROST, 0x22B
.equ ROTOM_FAN, 0x22C
.equ ROTOM_MOW, 0x22D
.equ GIRATINA_ORIGIN, 0x22E
.equ SHAYMIN_SKY, 0x22F
.equ ARCEUS_FIGHT, 0x230
.equ ARCEUS_FLYING, 0x231
.equ ARCEUS_POISON, 0x232
.equ ARCEUS_GROUND, 0x233
.equ ARCEUS_ROCK, 0x234
.equ ARCEUS_BUG, 0x235
.equ ARCEUS_GHOST, 0x236
.equ ARCEUS_STEEL, 0x237
.equ ARCEUS_UNKNOWN, 0x238
.equ ARCEUS_FIRE, 0x239
.equ ARCEUS_WATER, 0x23A
.equ ARCEUS_GRASS, 0x23B
.equ ARCEUS_ELECTRIC, 0x23C
.equ ARCEUS_PSYCHIC, 0x23D
.equ ARCEUS_ICE, 0x23E
.equ ARCEUS_DRAGON, 0x23F
.equ ARCEUS_DARK, 0x240
.equ ARCEUS_FAIRY, 0x241
.equ VICTINI, 0x242
.equ SNIVY, 0x243
.equ SERVINE, 0x244
.equ SERPERIOR, 0x245
.equ TEPIG, 0x246
.equ PIGNITE, 0x247
.equ EMBOAR, 0x248
.equ OSHAWOTT, 0x249
.equ DEWOTT, 0x24A
.equ SAMUROTT, 0x24B
.equ PATRAT, 0x24C
.equ WATCHOG, 0x24D
.equ LILLIPUP, 0x24E
.equ HERDIER, 0x24F
.equ STOUTLAND, 0x250
.equ PURRLOIN, 0x251
.equ LIEPARD, 0x252
.equ PANSAGE, 0x253
.equ SIMISAGE, 0x254
.equ PANSEAR, 0x255
.equ SIMISEAR, 0x256
.equ PANPOUR, 0x257
.equ SIMIPOUR, 0x258
.equ MUNNA, 0x259
.equ MUSHARNA, 0x25A
.equ PIDOVE, 0x25B
.equ TRANQUILL, 0x25C
.equ UNFEZANT, 0x25D
.equ BLITZLE, 0x25E
.equ ZEBSTRIKA, 0x25F
.equ ROGGENROLA, 0x260
.equ BOLDORE, 0x261
.equ GIGALITH, 0x262
.equ WOOBAT, 0x263
.equ SWOOBAT, 0x264
.equ DRILBUR, 0x265
.equ EXCADRILL, 0x266
.equ AUDINO, 0x267
.equ TIMBURR, 0x268
.equ GURDURR, 0x269
.equ CONKELDURR, 0x26A
.equ TYMPOLE, 0x26B
.equ PALPITOAD, 0x26C
.equ SEISMITOAD, 0x26D
.equ THROH, 0x26E
.equ SAWK, 0x26F
.equ SEWADDLE, 0x270
.equ SWADLOON, 0x271
.equ LEAVANNY, 0x272
.equ VENIPEDE, 0x273
.equ WHIRLIPEDE, 0x274
.equ SCOLIPEDE, 0x275
.equ COTTONEE, 0x276
.equ WHIMSICOTT, 0x277
.equ PETILIL, 0x278
.equ LILLIGANT, 0x279
.equ BASCULIN, 0x27A
.equ SANDILE, 0x27B
.equ KROKOROK, 0x27C
.equ KROOKODILE, 0x27D
.equ DARUMAKA, 0x27E
.equ DARMANITAN, 0x27F
.equ MARACTUS, 0x280
.equ DWEBBLE, 0x281
.equ CRUSTLE, 0x282
.equ SCRAGGY, 0x283
.equ SCRAFTY, 0x284
.equ SIGILYPH, 0x285
.equ YAMASK, 0x286
.equ COFAGRIGUS, 0x287
.equ TIRTOUGA, 0x288
.equ CARRACOSTA, 0x289
.equ ARCHEN, 0x28A
.equ ARCHEOPS, 0x28B
.equ TRUBBISH, 0x28C
.equ GARBODOR, 0x28D
.equ ZORUA, 0x28E
.equ ZOROARK, 0x28F
.equ MINCCINO, 0x290
.equ CINCCINO, 0x291
.equ GOTHITA, 0x292
.equ GOTHORITA, 0x293
.equ GOTHITELLE, 0x294
.equ SOLOSIS, 0x295
.equ DUOSION, 0x296
.equ REUNICLUS, 0x297
.equ DUCKLETT, 0x298
.equ SWANNA, 0x299
.equ VANILLITE, 0x29A
.equ VANILLISH, 0x29B
.equ VANILLUXE, 0x29C
.equ DEERLING, 0x29D
.equ SAWSBUCK, 0x29E
.equ EMOLGA, 0x29F
.equ KARRABLAST, 0x2A0
.equ ESCAVALIER, 0x2A1
.equ FOONGUS, 0x2A2
.equ AMOONGUSS, 0x2A3
.equ FRILLISH, 0x2A4
.equ JELLICENT, 0x2A5
.equ ALOMOMOLA, 0x2A6
.equ JOLTIK, 0x2A7
.equ GALVANTULA, 0x2A8
.equ FERROSEED, 0x2A9
.equ FERROTHORN, 0x2AA
.equ KLINK, 0x2AB
.equ KLANG, 0x2AC
.equ KLINKLANG, 0x2AD
.equ TYNAMO, 0x2AE
.equ EELEKTRIK, 0x2AF
.equ EELEKTROSS, 0x2B0
.equ ELGYEM, 0x2B1
.equ BEHEEYEM, 0x2B2
.equ LITWICK, 0x2B3
.equ LAMPENT, 0x2B4
.equ CHANDELURE, 0x2B5
.equ AXEW, 0x2B6
.equ FRAXURE, 0x2B7
.equ HAXORUS, 0x2B8
.equ CUBCHOO, 0x2B9
.equ BEARTIC, 0x2BA
.equ CRYOGONAL, 0x2BB
.equ SHELMET, 0x2BC
.equ ACCELGOR, 0x2BD
.equ STUNFISK, 0x2BE
.equ MIENFOO, 0x2BF
.equ MIENSHAO, 0x2C0
.equ DRUDDIGON, 0x2C1
.equ GOLETT, 0x2C2
.equ GOLURK, 0x2C3
.equ PAWNIARD, 0x2C4
.equ BISHARP, 0x2C5
.equ BOUFFALANT, 0x2C6
.equ RUFFLET, 0x2C7
.equ BRAVIARY, 0x2C8
.equ VULLABY, 0x2C9
.equ MANDIBUZZ, 0x2CA
.equ HEATMOR, 0x2CB
.equ DURANT, 0x2CC
.equ DEINO, 0x2CD
.equ ZWEILOUS, 0x2CE
.equ HYDREIGON, 0x2CF
.equ LARVESTA, 0x2D0
.equ VOLCARONA, 0x2D1
.equ COBALION, 0x2D2
.equ TERRAKION, 0x2D3
.equ VIRIZION, 0x2D4
.equ TORNADUS, 0x2D5
.equ THUNDURUS, 0x2D6
.equ RESHIRAM, 0x2D7
.equ ZEKROM, 0x2D8
.equ LANDORUS, 0x2D9
.equ KYUREM, 0x2DA
.equ KELDEO, 0x2DB
.equ MELOETTA, 0x2DC
.equ GENESECT, 0x2DD
.equ BASCULIN_BLUE, 0x2DE
.equ DARMANITAN_ZEN, 0x2DF
.equ DEERLING_SUMMER, 0x2E0
.equ DEERLING_AUTUMN, 0x2E1
.equ DEERLING_WINTER, 0x2E2
.equ SAWSBUCK_SUMMER, 0x2E3
.equ SAWSBUCK_AUTUMN, 0x2E4
.equ SAWSBUCK_WINTER, 0x2E5
.equ KYUREM_WHITE, 0x2E6
.equ KYUREM_BLACK, 0x2E7
.equ MELOETTA_PIROUETTE, 0x2E8
.equ GENESECT_SHOCK, 0x2E9
.equ GENESECT_BURN, 0x2EA
.equ GENESECT_CHILL, 0x2EB
.equ GENESECT_DOUSE, 0x2EC
.equ TORNADUS_THERIAN, 0x2ED
.equ THUNDURUS_THERIAN, 0x2EE
.equ LANDORUS_THERIAN, 0x2EF
.equ KELDEO_RESOLUTE, 0x2F0
.equ CHESPIN, 0x2F1
.equ QUILLADIN, 0x2F2
.equ CHESNAUGHT, 0x2F3
.equ FENNEKIN, 0x2F4
.equ BRAIXEN, 0x2F5
.equ DELPHOX, 0x2F6
.equ FROAKIE, 0x2F7
.equ FROGADIER, 0x2F8
.equ GRENINJA, 0x2F9
.equ BUNNELBY, 0x2FA
.equ DIGGERSBY, 0x2FB
.equ FLETCHLING, 0x2FC
.equ FLETCHINDER, 0x2FD
.equ TALONFLAME, 0x2FE
.equ SCATTERBUG, 0x2FF
.equ SPEWPA, 0x300
.equ VIVILLON, 0x301
.equ LITLEO, 0x302
.equ PYROAR, 0x303
.equ FLABEBE, 0x304
.equ FLOETTE, 0x305
.equ FLORGES, 0x306
.equ SKIDDO, 0x307
.equ GOGOAT, 0x308
.equ PANCHAM, 0x309
.equ PANGORO, 0x30A
.equ FURFROU, 0x30B
.equ ESPURR, 0x30C
.equ MEOWSTIC, 0x30D
.equ HONEDGE, 0x30E
.equ DOUBLADE, 0x30F
.equ AEGISLASH, 0x310
.equ SPRITZEE, 0x311
.equ AROMATISSE, 0x312
.equ SWIRLIX, 0x313
.equ SLURPUFF, 0x314
.equ INKAY, 0x315
.equ MALAMAR, 0x316
.equ BINACLE, 0x317
.equ BARBARACLE, 0x318
.equ SKRELP, 0x319
.equ DRAGALGE, 0x31A
.equ CLAUNCHER, 0x31B
.equ CLAWITZER, 0x31C
.equ HELIOPTILE, 0x31D
.equ HELIOLISK, 0x31E
.equ TYRUNT, 0x31F
.equ TYRANTRUM, 0x320
.equ AMAURA, 0x321
.equ AURORUS, 0x322
.equ SYLVEON, 0x323
.equ HAWLUCHA, 0x324
.equ DEDENNE, 0x325
.equ CARBINK, 0x326
.equ GOOMY, 0x327
.equ SLIGGOO, 0x328
.equ GOODRA, 0x329
.equ KLEFKI, 0x32A
.equ PHANTUMP, 0x32B
.equ TREVENANT, 0x32C
.equ PUMPKABOO, 0x32D
.equ GOURGEIST, 0x32E
.equ BERGMITE, 0x32F
.equ AVALUGG, 0x330
.equ NOIBAT, 0x331
.equ NOIVERN, 0x332
.equ XERNEAS, 0x333
.equ YVELTAL, 0x334
.equ ZYGARDE, 0x335
.equ DIANCIE, 0x336
.equ HOOPA, 0x337
.equ VOLCANION, 0x338
.equ PYROAR_FEMALE, 0x339
.equ FLABEBE_WHITE, 0x33A
.equ FLABEBE_YELLOW, 0x33B
.equ FLABEBE_ORANGE, 0x33C
.equ FLABEBE_BLUE, 0x33D
.equ FLOETTE_WHITE, 0x33E
.equ FLOETTE_YELLOW, 0x33F
.equ FLOETTE_ORANGE, 0x340
.equ FLOETTE_BLUE, 0x341
.equ FLORGES_WHITE, 0x342
.equ FLORGES_YELLOW, 0x343
.equ FLORGES_ORANGE, 0x344
.equ FLORGES_BLUE, 0x345
.equ MEOWSTIC_FEMALE, 0x346
.equ AEGISLASH_BLADE, 0x347
.equ PUMPKABOO_2, 0x348
.equ PUMPKABOO_3, 0x349
.equ PUMPKABOO_4, 0x34A
.equ GOURGEIST_2, 0x34B
.equ GOURGEIST_3, 0x34C
.equ GOURGEIST_4, 0x34D
.equ HOOPA_UNBOUND, 0x34E
.equ VENUSAUR_MEGA, 0x34F
.equ CHARIZARD_MEGAX, 0x350
.equ CHARIZARD_MEGAY, 0x351
.equ BLASTOISE_MEGA, 0x352
.equ BEEDRILL_MEGA, 0x353
.equ PIDGEOT_MEGA, 0x354
.equ ALAKAZAM_MEGA, 0x355
.equ SLOWBRO_MEGA, 0x356
.equ GENGAR_MEGA, 0x357
.equ KANGASKHAN_MEGA, 0x358
.equ PINSIR_MEGA, 0x359
.equ GYARADOS_MEGA, 0x35A
.equ AERODACTYL_MEGA, 0x35B
.equ MEWTWO_MEGAX, 0x35C
.equ MEWTWO_MEGAY, 0x35D
.equ AMPHAROS_MEGA, 0x35E
.equ STEELIX_MEGA, 0x35F
.equ SCIZOR_MEGA, 0x360
.equ HERACROSS_MEGA, 0x361
.equ HOUNDOOM_MEGA, 0x362
.equ TYRANITAR_MEGA, 0x363
.equ SCEPTILE_MEGA, 0x364
.equ BLAZIKEN_MEGA, 0x365
.equ SWAMPERT_MEGA, 0x366
.equ GARDEVOIR_MEGA, 0x367
.equ SABLEYE_MEGA, 0x368
.equ MAWILE_MEGA, 0x369
.equ AGGRON_MEGA, 0x36A
.equ MEDICHAM_MEGA, 0x36B
.equ MANECTRIC_MEGA, 0x36C
.equ SHARPEDO_MEGA, 0x36D
.equ CAMERUPT_MEGA, 0x36E
.equ ALTARIA_MEGA, 0x36F
.equ BANETTE_MEGA, 0x370
.equ ABSOL_MEGA, 0x371
.equ GLALIE_MEGA, 0x372
.equ SALAMENCE_MEGA, 0x373
.equ METAGROSS_MEGA, 0x374
.equ NOPE, 0x375 @Dunno why but maybe a new Latias out from the Soul Dew routine
.equ NOPE, 0x376 @Dunno why but maybe a new Latios out from the Soul Dew routine
.equ LATIAS_MEGA, 0x377
.equ LATIOS_MEGA, 0x378
.equ RAYQUAZA_MEGA, 0x379
.equ LOPUNNY_MEGA, 0x37A
.equ GARCHOMP_MEGA, 0x37B
.equ LUCARIO_MEGA, 0x37C
.equ ABOMASNOW_MEGA, 0x37D
.equ GALLADE_MEGA, 0x37E
.equ AUDINO_MEGA, 0x37F
.equ DIANCIE_MEGA, 0x380
.equ DEOXYS_NORMAL, 0x381 @Renewal of Deoxys' index
.equ DEOXYS_ATTACK, 0x382 @Renewal of Deoxys' index
.equ DEOXYS_DEFENSE, 0x383 @Renewal of Deoxys' index
.equ DEXOYS_SPEED, 0x384 @Renewal of Deoxys' index
.equ NOPE, 0x385 @Generation VII Pokemon starts here

.org 0x43F90, 0xFF
ldr r1, Hook3
bx r1
.align 2
Hook3: .word RomAreaOffset+dex_seeable_mon_hook+1

.org 0x88EDC, 0xFF
ldr r1, Hook6
bx r1
.align 2
Hook6: .word RomAreaOffset+dex_regional_count_hook+1

.org 0xCE91A, 0xFF
ldr r1, Hook4
bx r1
.align 2
Hook4: .word RomAreaOffset+dex_evolution_fix_hook+1

.org 0x10352C, 0xFF
ldr r1, Hook7
bx r1
.align 2
Hook7: .word RomAreaOffset+dex_display_hook+1

.org 0x10356C, 0xFF
ldr r0, Hook8
bx r0
.align 2
Hook8: .word RomAreaOffset+regional_dex_hook+1

.org 0x1035B4, 0xFF
ldr r1, Hook9
bx r1
.align 2
Hook9: .word RomAreaOffset+store_last_dex_seen_hook+1

.org 0x1035F4, 0xFF
ldr r0, HookA
bx r0
.align 2
HookA: .word RomAreaOffset+lazy_regional_dex_end_hook+1

.org 0x104A66, 0xFF
ldr r1, HookB
bx r1
.align 2
HookB: .word RomAreaOffset+display_regional_num_hook+1

.org 0x104BBC, 0xFF
ldr r2, Hook5
bx r2
.align 2
Hook5: .word RomAreaOffset+dex_display_counts_hook+1

.org 0x106810, 0xFF
ldr r1, Hook2
bx r1
.align 2
Hook2: .word RomAreaOffset+habitat_dex_regional_limit_hook+1

.org 0x106B84, 0xFF
ldr r1, Hook1
bx r1
.align 2
Hook1: .word RomAreaOffset+data_on_capture_hook+1

.org MyLoc, 0xFF
data_on_capture_hook:        @0x08106B84 via r1
        bl species_to_regional_dex_number
        cmp r0, #0x0
        bne capture_display_return
        ldr r0, add_task_no_capture_display
        bx r0

capture_display_return:
        ldr r0, add_task_capture_display
        bx r0

.align 2
.pool

.align 2

habitat_dex_regional_limit_hook:        @0x08106810 via r1
        push {r4, lr}
        mov r4, r0
        bl haz_national_dex_bool
        cmp r0, #0x1
        beq habitat_dex_regional_limit_return        @valid
        mov r0, r4
        bl species_to_regional_dex_number
        cmp r0, #0x0
        beq habitat_dex_regional_limit_return        @not in regional dex, return 0
        mov r0, #0x1

habitat_dex_regional_limit_return:
        pop {r4}
        pop {r1}
        bx r1

.align 2
.pool

.align 2

dex_seeable_mon_hook:        @0x08043F90 via r1
        push {r4, lr}
        mov r4, r0
        bl haz_national_dex_bool
        cmp r0, #0x0
        beq only_regional_numbered
@national
        mov r0, r4
        bl species_to_national_dex_number_1
        b dex_seeable_mon_check_valid_species

only_regional_numbered:
        mov r0, r4
        bl species_to_regional_dex_number

dex_seeable_mon_check_valid_species:
        cmp r0, #0x0
        bne dex_seeable_mon_return
        ldr r0, full_halfword

dex_seeable_mon_return:
        pop {r4}
        pop {r1}
        bx r1
.align
full_halfword:        .word 0xFFFF

.align 2
.pool

.align 2

dex_evolution_fix_hook:        @0x080CE91A via r1
        bl species_to_regional_dex_number
        cmp r0, #0x0        @not in regional dex, invalid
        beq dex_evolution_failure
        ldr r0, dex_evolution_success_return
        bx r0

dex_evolution_failure:
        mov r0, #0x11
        strh r0, [r5, #0x8]
        mov r2, #0x1
        ldr r1, dex_evolution_failure_return
        bx r1

.align 2
.pool

.align 2

dex_display_counts_hook:        @0x08104BBC via r2
        @r0: mode
        push {lr}
        cmp r1, #0x0
        beq call_regional_count
        bl national_pokedex_count
        b dex_display_counts_return

call_regional_count:
        bl dex_regional_count_hook

dex_display_counts_return:
        pop {pc}

.align 2
.pool

.align 2

dex_regional_count_hook:        @0x08088EDC via r1
        push {r4-r6, lr}
        mov r6, r0        @mode
        mov r4, #0x1        @loop
        mov r5, #0x0        @counter

dex_regional_count_loop:
        lsl r0, r4, #0x1        @loop times 2
        adr r1, regional_dex_order
        ldrh r0, [r1, r0]        @req species
        mov r1, r6        @mode
        mov r2, #0x1        @input is SPECIES
        bl dex_flag_check
        add r5, r5, r0
        add r4, #0x1
        ldr r0, regional_dex_limit
        cmp r4, r0
        blo dex_regional_count_loop
        mov r0, r5
        pop {r4-r6, pc}

.align 2
.pool

.align 2

dex_display_hook:        @0x0810352C via r1
        ldr r1, regional_dex_limit
        cmp r0, #0x0
        beq store_dex_limit_and_return
        ldr r1, national_dex_limit

store_dex_limit_and_return:
        str r1, [sp, #0x0]
        ldr r0, regional_dex_limit_return
        bx r0

.align 2
.pool

.align 2

regional_dex_hook:        @0x0810356C via r0
        mov r4, r8
        add r4, #0x1
        lsl r0, r4, #0x1        @index times 2
        adr r1, regional_dex_order
        ldrh r0, [r1, r0]
        bl species_to_national_dex_number_1
        mov r5, r0
        mov r1, #0x0
        ldr r2, regional_dex_hook_return
        bx r2

.align 2
.pool

.align 2

store_last_dex_seen_hook:        @0x081035B4 via r1
        str r0, [r2]
        mov r10, r4
        mov r4, r3
        ldr r0, def_store_string_dex_number
        bx r0

.align 2
.pool

.align 2

lazy_regional_dex_end_hook:        @0x081035F4 via r0
        mov r0, r8
        ldr r1, regional_dex_limit
        cmp r0, r1
        blo regional_dex_hook
        ldr r0, end_dex_display_return
        bx r0

.align 2
.pool

.align 2

display_regional_num_hook:        @0x08104A66 via r1
        mov r5, r0        @save species
        bl haz_national_dex_bool
        cmp r0, #0x0
        beq use_regional_dex_ordering
        ldr r1, dex_malloc_ptr
        ldr r1, [r1]
        add r1, #0x42
        ldrb r1, [r1]
        cmp r1, #0x0        @check if looking at regional dex
        beq use_regional_dex_ordering
        mov r0, r5
        bl species_to_national_dex_number_1
        b display_dex_number_return

use_regional_dex_ordering:
        mov r0, r5
        bl species_to_regional_dex_number       

display_dex_number_return:
        mov r5, r0
        ldr r0, dex_number_display_return
        bx r0

species_to_regional_dex_number:
        adr r3, regional_dex_order
        mov r2, r0        @req species
        mov r0, #0x0        @loop counter
find_regional_number_loop:
        lsl r1, r0, #0x1
        ldrh r1, [r3, r1]
        cmp r1, r2
        beq species_to_regional_dex_return
        add r0, #0x1
        ldr r1, regional_dex_limit
        cmp r0, r1
        bls find_regional_number_loop
        mov r0, #0x0        @not in dex: set number to 0
species_to_regional_dex_return:
        bx lr

species_to_national_dex_number_1:
        ldr r1, f_species_to_nat_dex
        bx r1
.align
f_species_to_nat_dex:        .word 0x08043298 + 1

haz_national_dex_bool:
        ldr r0, f_haz_national_check
        bx r0
.align
f_haz_national_check:        .word 0x0806E25C + 1

dex_flag_check:
        ldr r3, f_dex_flag_check
        bx r3
.align
f_dex_flag_check:        .word 0x08104AB0 + 1

national_pokedex_count:
        ldr r1, f_national_pokedex_count
        bx r1
.align
f_national_pokedex_count:        .word 0x08088E8C + 1

.align
add_task_no_capture_display:        .word 0x08106B90 + 1
add_task_capture_display:        .word 0x08106BA4 + 1
dex_evolution_success_return:        .word 0x080CE948 + 1
dex_evolution_failure_return:        .word 0x080CE924 + 1
regional_dex_limit:        .word number_of_mons_in_regional_dex
national_dex_limit:        .word number_of_mons_in_national_dex
regional_dex_limit_return:        .word 0x0810353a + 1
regional_dex_hook_return:        .word 0x08103578 + 1
def_store_string_dex_number:        .word 0x081035D6 + 1
end_dex_display_return:        .word 0x08103906 + 1
dex_malloc_ptr:                        .word 0x0203ACF0
dex_number_display_return:        .word 0x08104A70 + 1

regional_dex_order:
.hword        0x0000
.hword        TREECKO
.hword        GROVYLE
.hword        SCEPTILE
.hword        TORCHIC
.hword        COMBUSKEN
.hword        BLAZIKEN
.hword        MUDKIP
.hword        MARSHTOMP
.hword        SWAMPERT
.hword        POOCHYENA
.hword        MIGHTYENA
.hword        ZIGZAGOON
.hword        LINOONE
.hword        WURMPLE
.hword        SILCOON
.hword        BEAUTIFLY
.hword        CASCOON
.hword        DUSTOX
.hword        LOTAD
.hword        LOMBRE
.hword        LUDICOLO
.hword        SEEDOT
.hword        NUZLEAF
.hword        SHIFTRY
.hword        TAILLOW
.hword        SWELLOW
.hword        WINGULL
.hword        PELIPPER
.hword        RALTS
.hword        KIRLIA
.hword        GARDEVOIR
.hword        SURSKIT
.hword        MASQUERAIN
.hword        SHROOMISH
.hword        BRELOOM
.hword        SLAKOTH
.hword        VIGOROTH
.hword        SLAKING
.hword        ABRA
.hword        KADABRA
.hword        ALAKAZAM
.hword        NINCADA
.hword        NINJASK
.hword        SHEDINJA
.hword        WHISMUR
.hword        LOUDRED
.hword        EXPLOUD
.hword        MAKUHITA
.hword        HARIYAMA
.hword        GOLDEEN
.hword        SEAKING
.hword        MAGIKARP
.hword        GYARADOS
.hword        AZURILL
.hword        MARILL
.hword        AZUMARILL
.hword        GEODUDE
.hword        GRAVELER
.hword        GOLEM
.hword        NOSEPASS
.hword        SKITTY
.hword        DELCATTY
.hword        ZUBAT
.hword        GOLBAT
.hword        CROBAT
.hword        TENTACOOL
.hword        TENTACRUEL
.hword        SABLEYE
.hword        MAWILE
.hword        ARON
.hword        LAIRON
.hword        AGGRON
.hword        MACHOP
.hword        MACHOKE
.hword        MACHAMP
.hword        MEDITITE
.hword        MEDICHAM
.hword        ELECTRIKE
.hword        MANECTRIC
.hword        PLUSLE
.hword        MINUN
.hword        MAGNEMITE
.hword        MAGNETON
.hword        VOLTORB
.hword        ELECTRODE
.hword        VOLBEAT
.hword        ILLUMISE
.hword        ODDISH
.hword        GLOOM
.hword        VILEPLUME
.hword        BELLOSSOM
.hword        DODUO
.hword        DODRIO
.hword        ROSELIA
.hword        GULPIN
.hword        SWALOT
.hword        CARVANHA
.hword        SHARPEDO
.hword        WAILMER
.hword        WAILORD
.hword        NUMEL
.hword        CAMERUPT
.hword        SLUGMA
.hword        MAGCARGO
.hword        TORKOAL
.hword        GRIMER
.hword        MUK
.hword        KOFFING
.hword        WEEZING
.hword        SPOINK
.hword        GRUMPIG
.hword        SANDSHREW
.hword        SANDSLASH
.hword        SPINDA
.hword        SKARMORY
.hword        TRAPINCH
.hword        VIBRAVA
.hword        FLYGON
.hword        CACNEA
.hword        CACTURNE
.hword        SWABLU
.hword        ALTARIA
.hword        ZANGOOSE
.hword        SEVIPER
.hword        LUNATONE
.hword        SOLROCK
.hword        BARBOACH
.hword        WHISCASH
.hword        CORPHISH
.hword        CRAWDAUNT
.hword        BALTOY
.hword        CLAYDOL
.hword        LILEEP
.hword        CRADILY
.hword        ANORITH
.hword        ARMALDO
.hword        IGGLYBUFF
.hword        JIGGLYPUFF
.hword        WIGGLYTUFF
.hword        FEEBAS
.hword        MILOTIC
.hword        CASTFORM
.hword        STARYU
.hword        STARMIE
.hword        KECLEON
.hword        SHUPPET
.hword        BANETTE
.hword        DUSKULL
.hword        DUSCLOPS
.hword        TROPIUS
.hword        CHIMECHO
.hword        ABSOL
.hword        VULPIX
.hword        NINETALES
.hword        PICHU
.hword        PIKACHU
.hword        RAICHU
.hword        PSYDUCK
.hword        GOLDUCK
.hword        WYNAUT
.hword        WOBBUFFET
.hword        NATU
.hword        XATU
.hword        GIRAFARIG
.hword        PHANPY
.hword        DONPHAN
.hword        PINSIR
.hword        HERACROSS
.hword        RHYHORN
.hword        RHYDON
.hword        SNORUNT
.hword        GLALIE
.hword        SPHEAL
.hword        SEALEO
.hword        WALREIN
.hword        CLAMPERL
.hword        HUNTAIL
.hword        GOREBYSS
.hword        RELICANTH
.hword        CORSOLA
.hword        CHINCHOU
.hword        LANTURN
.hword        LUVDISC
.hword        HORSEA
.hword        SEADRA
.hword        KINGDRA
.hword        BAGON
.hword        SHELGON
.hword        SALAMENCE
.hword        BELDUM
.hword        METANG
.hword        METAGROSS
.hword        REGIROCK
.hword        REGICE
.hword        REGISTEEL
.hword        LATIAS
.hword        LATIOS
.hword        KYOGRE
.hword        GROUDON
.hword        RAYQUAZA
.hword        JIRACHI
.hword        DEOXYS



Spherical Ice January 14th, 2018 4:50 PM

Deposit entire team but one



Just going to publish this combination of two routines and a script excerpt that you can use to let the player select one Pokémon from their team, and then deposit the rest of their team.

Spoiler: Script
Code:

...
countpokemon
callasm ROUTINE_ONE+1
compare LASTRESULT 0x1
if B_<> goto @snippet1
msgbox @string1 MSG_NORMAL
call @snippet2
callasm ROUTINE_TWO+1
textcolor 0x2 // black
bufferpartypokemon 0x0 0x0
bufferboxname 0x1 0x4035
checkflag 0x834
if 0x1 goto @snippet3
msgbox @string2 MSG_NORMAL
goto @snippet4

//---------------
#org @snippet1
msgbox @string3 MSG_NORMAL
release
end

//---------------
#org @snippet2
special 0x9F
waitstate
special2 LASTRESULT 0x147
compare LASTRESULT 0x19C
if 0x1 goto @egg
compare 0x8004 0x5
if 0x2 goto @exited_out
return

//---------------
#org @snippet3
msgbox @string4 MSG_NORMAL
goto @snippet4

//---------------
#org @snippet4
...

//---------
// Strings
//---------
#org @string1
= You are only allowed to bring one\nPOKéMON.\pPlease select which one you would\nlike to bring.

#org @string2
= [buffer1] will join you.\pThe rest of your team was\ntransferred to SOMEONE's PC.\pThey were placed starting\nin BOX ["][buffer2]."

#org @string3
= You are only allowed to bring one\nPOKéMON.\pNormally, we would offer to deposit\nthe rest of your team into a BOX.\pHowever, it seems like all of your\nBOXES are full.\pPlease make room and return later.

#org @string4
= [buffer1] will join you.\pThe rest of your team was\ntransferred to BILL's PC.\pThey were placed starting\nin BOX ["][buffer2]."




Spoiler: ROUTINE_ONE
Code:

.thumb

@ This routine loops through the player's boxes to make sure there is room in a given box to deposit the entire team

main:
    push {r4-r7, lr}
    ldr r0, =(0x020370D0) @ var_800D
    ldrh r0, [r0]
    sub r0, #2 @ party size - 1
    mov r4, r0
    mov r5, #0

box_loop:
    mov r6, #0 @ box_id
    mov r7, #0 @ pos_in_box

pokemon_in_box_loop:
    mov r0, r6
    mov r1, r7
    ldr r3, =(0x0808BD30+1) @ pokemon_by_box_and_position
    bl call_via_r3
    mov r1, #0xB @ req_species
    ldr r3, =(0x0803FD44+1) @ pokemon_getattr_encrypted
    bl call_via_r3
    cmp r0, #0
    beq empty_space_found

next_loop:
    add r7, #1
    cmp r7, #30
    bls pokemon_in_box_loop

completed_current_box:
    add r6, #1
    cmp r6, #14
    bge not_enough_space
    mov r7, #0
    b pokemon_in_box_loop

empty_space_found:
    add r5, #1
    cmp r5, r4
    bls next_loop

enough_space:
    mov r0, #1
    b end

not_enough_space:
    mov r0, #0

end:
    ldr r1, =(0x020370D0) @ var_800D
    str r0, [r1]
    pop {r4-r7}
    pop {r3}

call_via_r3:
    bx r3

.pool




Spoiler: ROUTINE_TWO
Code:

.thumb

@ This routine loops through the player's party, depositing every slot (slot 0 to 5) except for the slot number in var 8004
@ It then copies the Pokémon in the remaining slot to slot 0, and then erases each Pokémon from slots 1 to 5

main:
    push {r4-r6,lr}
    ldr r4, =(0x020370C0) @ var_8004
    ldrh r4, [r4]
    ldr r5, =(0x02024284) @ party_player
    mov r6, #0

loop:
    cmp r6, #6
    beq continue
    cmp r6, r4
    beq skip
    mov r1, #0x64
    mul r1, r6
    add r0, r1, r5
    ldr r3, =(0x08040B90|1) @ pokemon_add_to_pc
    bl call_via_r3

skip:
    add r6, #1
    b loop

continue:
    mov r1, #0x64
    mul r1, r4
    add r1, r5
    mov r0, r5
    mov r2, #0x64
    ldr r3, =(0x081E5E78|1) @ memcpy
    bl call_via_r3
    ldr r0, =(0x02024284+0x64) @ second Pokémon party address
    ldr r1, =(0x081F42A0) @ just a random 500 (dec) 00 bytes in the ROM
    ldrh r2, =(0x1F4)
    ldr r3, =(0x081E5E78|1) @ memcpy
    bl call_via_r3
    pop {r4-r6}
    pop {r3}

call_via_r3:
    bx r3

.pool



Lunos February 5th, 2018 6:45 AM

Exp. All / Gen. 6 Exp. Share [Emerald]
This routine was created by Samu from Wahack and it was posted right here. All the credits belong to him.

I'm afraid that I'll have to leave the comments in Spanish because I don't know how to properly translate them to English due to my lack of knowledge on the ASM programming language. Sorry :(

ASM Routine:
Code:

.thumb
.align 2

/****** NEW GEN EXP SHARE + EGG EXP FIX *******
************************************************
************************************************
************************************************
Créditos a BluRose & Lunos *********************
************************************************
************************************************/

no_crash:
        ldr r0, [r5]
        mov r1, r0
        add r1, #0x53
        ldrb r0, [r1]

flag_check:                                @Se encarga de comprobar si hemos activado el flag
        push {r0-r2}
        ldr r0, flag_number
        ldr r2, flag_routine
        push {r1-r3}
        bl linker
        pop {r1-r3}
        cmp r0, #0x1                @Compara el flag con 0x1 (activado)
        bne routine_off
        pop {r0-r2}       

main:
        @Comprobar el slot y guardarlo en una variable.
        push {r3-r6}
        ldr r6, slot_var                @Carga en r3 el slot del pokemon
        ldrb r3, [r6]
        ldr r4, is_egg_party
        mov r5, #0x64
        mul r5, r5, r3                        @Calcula las posiciones a avanzar
        ldrb r4, [r4, r5]                @Carga en r4 el byte egg/not
        cmp r4, #0x6
        beq pokemonIsEgg
        mov r2, #0x1
        b update_slot

pokemonIsEgg:
        mov r2, #0x0                        @Establece r2 en 0 (no ganará exp)

update_slot:                                @Actualiza y resetea el valor del slot
        add r3, #0x1
        cmp r3, #0x6
        bne end
        mov r3, #0x0

end:
        strh r3, [r6]
        pop {r3-r6}

return:
        push {r2}
        ldr r2, return_dir
        bx r2

routine_off:                                @Ejecuta las instrucciones "originales"
        pop {r0-r2}
        mov r2, #0x1
        and r2, r0
        b return

linker:
        bx r2

.align 2
flag_number:
        .word 0x00000XXX                                        @Elige el numero del flag
flag_routine:
        .word 0x0809D790 +1                                @Rutina que checkea el flag
slot_var:                                                                @Escoge una variable temporal (no uses la 0x8000,
        .word 0x020275D6 + (0x800Y * 2)        @el juego la utiliza al inicializar combates dobles
is_egg_party:
        .word 0x020244EC + 0x13                                @Byte que comprueba si es un huevo
return_dir:
        .word 0x0804A592 + 1                                @Dirección de retorno a la rutina


Note: In order to use this routine, you must set a flag and a temp var in the Lines 72 and 76 respectively.

After inserting the routine in your ROM, open your Pokémon Emerald ROM in a hex editor and make the following changes:
-04A4BE: 02 21
-04A634: 01 20
-04A58A: C0 46 00 4A 10 47 XX XX XX 08 04 BC
Note: XX XX XX = Pointer to the ASM Routine, +1.
Example: If I were to put it in E3CF80, I'd have to replace XX XX XX with 81 CF E3.


Relevant information:
The flag handles the effect itself. If the flag you gave to the routine is OFF (0x0) the Exp. Share will work just like in Gen. 3. If it's ON (0x1), it'll work like in Gen. 1/6/7.

Result:

I'm sure there's ways to make this better, so if anyone could give that a try, that'd be awesome :)

Skeli February 5th, 2018 9:03 PM

Custom Victory Music [FR]:
Everyone knows of the code that allows you have custom trainer battle music, but as far as I'm aware, no one has ever written code that allows you have custom victory music (that jingle that plays when you win a battle).
This code is very similar to the custom trainer battle music in which it loads the data from a table structured [Byte - Trainer Class] 00 [HWord - Song ID]. The table is ended with a 0xFFFF.
But before you do anything though, you need to decide how many jingles you want. If you don't need more than 7, just compile the code as it is. If you don't modify the code, the table is at 0x15740 (there's enough space there for 7 jingles, just make sure you put the end 0xFFFF). Otherwise change the last line in the code to your table's pointer.
In order to get this working all you need to do is compile the ASM and copy whatever's at the offset 0x156F4 in the bin into your Rom. Due to the way the original code was written, the new code can be completely pasted over.
Enjoy!
Code:

.text
.align 2
.thumb
.thumb_func
.global victorymusic

@TableFormat: [Byte - Trainer Class] 00 [HWord - Song ID]
.org 0x156F4
Main:
        bl 0x35314
        ldr r1, .ScriptLoc
        ldr r0, =0x81D87EF
        str r0, [r1]
        ldr r2, .TrainerSomething
        ldr r0, .TrainerBattleFlagID

GetTrainerType:
        ldrh    r1, [r0]
        lsl            r0, r1, #0x2
        add            r0, r1
        lsl            r0, #0x3
        add            r0, r2
        ldrb    r0, [r0, #1]

CheckTable:
        ldr r1, .Table
        ldrh r3, =0xFFFF

Loop:
        ldrb r2, [r1]
        cmp r0, r2
        beq LoadSpecialSong
        add r1, #0x4
        ldrh r2, [r1]
        cmp r2, r3
        beq 0x1575E @Regular Victory Song
        b Loop

LoadSpecialSong:
        add r1, #0x2
        ldrh r0, [r1]
        b 0x15762

.align 2
.ScriptLoc:                .word 0x2023D74
.TrainerSomething:        .word 0x823EAC8
.TrainerBattleFlagID:        .word 0x20386AE
.Table:                .word 0x8015740




All times are GMT -8. The time now is 8:46 AM.


Like our Facebook Page Follow us on Twitter © 2002 - 2018 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 - 2016 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.

Acknowledgements
Use of PokéCommunity Assets
vB Optimise by DragonByte Technologies Ltd © 2023.