• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Code: ASM Resource Thread

232
Posts
12
Years
    • Seen Sep 10, 2019
    There is a way to make it work only with wild and breeding and to make the shiny chance 1/2048?

    To make the shiny chance 1/2048 replace these lines
    Code:
         mov r0, #0xA
         lsl r0, r0, #0x7
         add r0, r0, #0x55 @1/1365 chance with shiny charm
    with
    Code:
    mov r0, #0x10
    lsl r0, r0, #0x7
    this is for when using the Shiny charm
     
    352
    Posts
    7
    Years
    • Seen Mar 10, 2022
    To make the shiny chance 1/2048 replace these lines
    Code:
         mov r0, #0xA
         lsl r0, r0, #0x7
         add r0, r0, #0x55 @1/1365 chance with shiny charm
    with
    Code:
    mov r0, #0x10
    lsl r0, r0, #0x7
    this is for when using the Shiny charm

    Thank you so much.
     
    Last edited:

    AtecainCorp.

    Rejishan awake...
    1,377
    Posts
    15
    Years
  • Adding a Probability of Wild Pokemon Dodging Poke Balls (Fire Red)

    This routine edits the pokeball throwing command to have a small chance (5-10%) of having the pokemon dodge your pokeball. The probability of missing is calculated by dividing the base speed of the wild pokemon by 10 and adding it to some initial threshold value. If a random value is less than or equal to this threshold, the ball misses.

    The initial threshold value is 13 (0.05*255 ~= 13), and a high base speed pokemon (~130) will increase the threshold value to 26, so roughly 10% chance of missing. Of course, you can edit this formula as you see fit. I would also recommend editing the "It dodged the Poke Ball! It can't be caught!" text.

    To use, insert this routine at 0xXXYYZZ and then insert 01 48 00 47 00 00 (ZZ+1) YY XX 08 at 0x0802D67A

    Spoiler:

    Wow... This code can be also usable for Emerald and Ruby users for make GHOST pokemon in the game possible. Just set aviod rate to 100% and GHOST was been unable to capture.
     

    Urz

    9
    Posts
    14
    Years
    • Seen Oct 8, 2022
    Adding a Probability of Wild Pokemon Dodging Poke Balls (Fire Red)

    This routine edits the pokeball throwing command to have a small chance (5-10%) of having the pokemon dodge your pokeball. The probability of missing is calculated by dividing the base speed of the wild pokemon by 10 and adding it to some initial threshold value. If a random value is less than or equal to this threshold, the ball misses.

    The initial threshold value is 13 (0.05*255 ~= 13), and a high base speed pokemon (~130) will increase the threshold value to 26, so roughly 10% chance of missing. Of course, you can edit this formula as you see fit. I would also recommend editing the "It dodged the Poke Ball! It can't be caught!" text.

    To use, insert this routine at 0xXXYYZZ and then insert 01 48 00 47 00 00 (ZZ+1) YY XX 08 at 0x0802D67A

    Spoiler:

    I've been testing this out a bit. One bug I've found is if your pok?mon on the field has a status effect like sleep or paralysis, when you use a ball, the game will sometimes hang (presumably when the Pok?mon 'dodges' the ball). Any reason for this you can figure out? If you poison or sleep the opponent, it works fine. It's just status effects to your Pok?mon which are the problem

    Otherwise, it works great :-)
     
    Last edited:
    232
    Posts
    12
    Years
    • Seen Sep 10, 2019
    [FR]: Get IVs of a selected POKEMON in PARTY
    Spoiler:
     
    Last edited:

    Squeetz

    ROM Hacker
    191
    Posts
    10
    Years
  • Here's a short little routine for Firered that recalculates the entire party's stats because I wasn't sure if there was a similiar function.
    Spoiler:
     
    32
    Posts
    10
    Years
    • Seen Sep 1, 2021
    Feature request [EM][FR if you want]

    A hacked giveitem command combined with showpokepic to achieve this:

    3bqhTRs.png


    (I made it with paint.net, it's not something I saw in a hack already)
    PS. if possible the ideal thing would be that in a script you would only use the normal giveitem, so all the already existing scripts would get this feature
     
    5,256
    Posts
    16
    Years
  • [FR] Ability Capsule

    Find 0x1FC bytes of free space at a word-aligned address, and take note of it.
    Create an item of Type 1 ("Out of battle").
    Set the item's Field pointer to the address you noted, plus 1.
    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 0x1FC bytes.
    Copy the bytes and paste them in your ROM, at the same address.

    Code:
    [FONT="Source Code Pro"].thumb
    
    .equ location, 0xXXXXXX
    .equ rom, (0x08000000 + 1)
    
    .equ ability_name_length, 0x0D
    .equ base_stats_length, 0x1C
    .equ pokemon_length,  0x64
    .equ req_species, 0x0B
    .equ req_species2, 0x41
    .equ req_ability, 0x2E
    .equ ability1, 0x16
    .equ ability2, 0x17
    .equ egg_species, 0x19C
    
    .org location, 0xFF
    ability_capsule:
        push {lr}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        ldr r2, item_function_ptr
        ldr r1, =(rom + dp05_abilitycapsule)
        str r1, [r2]
        ldr r3, item_consume_maybe
        bl call_via_r3
        pop {r3}
        bx r3
    
    dp05_abilitycapsule:
        push {r4-r7,lr}
        mov r6, r1
        lsl r0, r0, #0x18
        lsr r5, r0, #0x18
    
    get_selected_pokemon:
        ldr r0, brm
        ldrb r0, [r0, #9]
        mov r1, #pokemon_length
        mul r0, r1
        ldr r1, party_player
        add r4, r0, r1    
    
    get_species:
        mov r0, r4
        mov r1, #req_species2
        ldr r3, get_attr
        bl call_via_r3
    
    egg_check:
        ldrh r1, =egg_species
        cmp r0, r1
        beq fail
    
    compare_abilities:
        ldr r1, base_stats_ptr
        ldr r1, [r1]
        mov r2, #base_stats_length
        mul r0, r2
        add r1, r0
        ldrb r0, [r1, #ability1]
        ldrb r1, [r1, #ability2]
        cmp r0, r1
        beq fail
        cmp r0, #0
        beq fail
        cmp r1, #0
        beq fail
        mov r4, #0
        b continue
    
    fail:
        mov r4, #1
    
    continue:
        mov r0, #5
        ldr r3, audio_play
        bl call_via_r3
        cmp r4, #0
        beq effect
    
    no_effect:
        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
        lsl r0, r5, #2
        add r0, r0, r5
        lsl r0, r0, #3
        add r0, r0, r1
        mov r1, r6
        str r1, [r0]
        b end
    
    effect:
        mov r0, r5
        ldr r3, item_use_animation
        bl call_via_r3
        ldr r1, item_function_ptr
        ldr r0, =(rom + abilitycapsule_use)
        str r0, [r1]
        b end
    
    abilitycapsule_use:
        push {r4-r7,lr}
        lsl r0, r0, #0x18
        lsr r5, r0, #0x18
    
    get_selected_pokemon_again:
        ldr r0, brm
        ldrb r0, [r0, #9]
        mov r1, #pokemon_length
        mul r0, r1
        ldr r1, party_player
        add r4, r0, r1
    
    get_ability_id_again:
        mov r0, r4
        mov r1, #req_ability
        ldr r3, get_attr
        bl call_via_r3
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
    
    invert_ability_id:
        mov r1, #1
        eor r0, r1
        ldr r2, var_800D
        strb r0, [r2]
    
    set_new_ability_id:
        mov r0, r4
        mov r1, #req_ability
        ldr r3, set_attr
        bl call_via_r3
    
    set_item_effectiveness:
        mov r0, #1
        ldr r1, item_effectiveness
        strb r0, [r1]
    
    remove_item:
        ldr r0, var_800E
        ldrh r0, [r0]
        mov r1, #1
        ldr r3, bag_remove_item
        bl call_via_r3
    
    buffer_nickname:
        mov r0, r4
        ldr r1, fcode_buffer2
        ldr r3, buffer_pkmn_nick
        bl call_via_r3
    
    buffer_ability_name:
        mov r0, r4
        ldr r1, fcode_buffer3
        ldr r3, =(rom + buffer_ability)
        bl call_via_r3
    
    construct_string:
        ldr r4, displayed_string
        mov r0, r4
        ldr r1, =(rom + abilitycapsule_str)
        ldr r3, fdecoder
        bl call_via_r3
    
    print_string:
        mov r0, r4
        mov r1, #1
        ldr r3, item_menu_string
        bl call_via_r3
    
    display_box:
        mov r0, #2
        ldr r3, bgid_mark_for_sync
        bl call_via_r3
    
    add_callback_task:
        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]
        b end
    
    buffer_ability:
        push {r4-r7,lr}
        mov r4, r0
        mov r5, r1
    
    get_species_again:
        mov r1, #req_species2
        ldr r3, get_attr
        bl call_via_r3
        lsl r0, r0, #0x10
        lsr r6, r0, #0x10
    
    get_ability_bit:
        mov r0, r4
        mov r1, #req_ability
        ldr r3, get_attr
        bl call_via_r3
        lsl r0, r0, #0x18
        lsr r1, r0, #0x18
    
    get_ability_id:
        mov r0, r6
        mov r2, #base_stats_length
        mul r0, r2
        ldr r2, base_stats_ptr
        ldr r2, [r2]
        add r2, r0
        add r2, #ability1
        ldrb r0, [r2, r1]
    
    get_ability_name_string:
        mov r1, #ability_name_length
        mul r0, r1
        ldr r1, ability_names_ptr
        ldr r1, [r1]
        add r1, r0
        mov r0, r5
        ldr r3, strcpy_xFF_terminated
        bl call_via_r3
        
    end:
        pop {r4-r7}
        pop {r3}
    
    call_via_r3:
        bx r3
    
    abilitycapsule_str:
        .byte 0x00
        .byte 0xFD, 0x02, 0xB4, 0xE7, 0x00, 0xBB, 0xD6, 0xDD, 0xE0, 0xDD, 0xE8, 0xED, 0xFE, 0xD7, 0xDC, 0xD5, 0xE2, 0xDB, 0xD9, 0xD8, 0x00, 0xE8, 0xE3, 0x00, 0xFD, 0x03, 0xAB, 0xFC, 0x09, 0xFF
         @ "[PKMN]'s Ability[NEWLINE]changed to [ABILITY]![WAITKEYPRESS]"
        
    .align 2
        fcode_buffer2:          .word 0x02021CD0
        fcode_buffer3:          .word 0x02021CF0
        displayed_string:       .word 0x02021D18
        party_player:           .word 0x02024284
        var_800D:               .word 0x020370D0
        var_800E:               .word 0x0203AD30
        brm:                    .word 0x0203B0A0
        item_effectiveness:     .word 0x0203B0C0
    
        tasks:                  .word 0x03005090
        item_function_ptr:      .word 0x03005E98
    
        base_stats_ptr:         .word 0x080001BC
        ability_names_ptr:      .word 0x080001C0
        strcpy_xFF_terminated:  .word 0x08008D84|1
        fdecoder:               .word 0x08008FCC|1
        get_attr:               .word 0x0803FBE8|1
        set_attr:               .word 0x0804037C|1
        audio_play:             .word 0x080722CC|1
        bag_remove_item:        .word 0x0809A1D8|1
        item_consume_maybe:     .word 0x080A16D0|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
        no_effect_str:          .word 0x084169DC @ "It won't have any effect."
    
    [/FONT]

    This implementation is not identical to how it is in the official games, as it doesn't have a further prompt asking the player to confirm when a Pokémon is selected.

    It will fail ("It won't have any effect") if used on a Pokémon whose base stats has two identical abilities, or if one of the abilities are ID 0x0.

    EDIT 2019/05/29: There was a bug at line 72 where 0 was being stored at a garbage address. It also now checks the species using req_species2 to prevent the Ability Capsule (potentially) working on Eggs, and adds a relevant check (as it turns out, this is technically redundant as the Use menu will not come up for Eggs to begin with, but it's better to redundant than sorry). If you used this routine before this edit's date, I'd recommend updating the ASM to make sure! Thanks to BreadCrumbs/Squeetz for pointing these issues out!
     
    Last edited:
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    Probability of Dodging Poke Balls [FR]

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

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

    MAJOR EDITS:
    1. Fixed bugs/battle flag checks for trainer battles/old man/poke dude, and ghost battles
    2. Hook insertion changed to be more compatible with other battle routines
    3. It adds in the ability to use a custom messages! So you can keep the original ghost battle string the same.
    4. Added a check that makes the ball automatically miss if the enemy is in the air/underground/underwater (credit to shanem7 for this idea)
    5. Changed it so the base threshold is halved for paralysis instead of an automatic contact
    6. You can use the pokeball deflection animation instead of the pokemon dodging animation with your own custom message! See the comment in the code to see how
    7. dodgeball rate modifiers based on evasion and speed stat changes
    8. substitute causes auto-dodge
    9. Wrap effect reduces dodge rate by 1/4 (added 8/5/17)
    10. (9/28/18): fixed jump address to not overwrite register

    NOTE: Safari Balls are unaffected by this routine. Master Ball is also unaffected but can be with an easy change (see comments)

    Insertion:
    *NOTE: THE HOOK ADDRESS HAS CHANGED TO 0802D508. REMEMBER TO RESTORE PREVIOUS HOOKS
    1. Insert custom 'dodging' message at 0xXXYYZZ (see below)
    2. at 0x08XXXXXX: (Battle Script) Requires Jambo's setword battle command
    waitmessage 0x40
    setword 0x203C020 0x08XXYYZZ @pointer to string 0xXXYYZZ you want to display (eg. "You missed wild [pkmn]!" or "Wild [pkmn] dodged your Poke Ball!")
    printstring 0x184
    waitmessage 0x40
    end
    3. Replace .Message :word 0x8XXXXXX with the offset you compiled this battle script in
    4. Compile and insert the routine in free space (0xLLJJKK)
    5. Insert 00 48 00 47 (KK+1) JJ LL 08 at 0802D508


    The Routine:
    Code:
    Main:
    	ldr r1, .BallThrown    @ remember to update RAM if you have expanded pokeballs!
    	ldrb r0, [r1]
    	cmp r0, #0x1		@master ball - move this check to the front of NoDodge to allow Master Ball to miss.
    	bne OtherBall
    	ldr r0, =(0x03004F90)
    	ldr r1, =(0x0802D688 +1)
    	bx r1
    
    OtherBall:
    	ldr r0, .SpecialStatus
    	ldr r0, [r0]
    	ldr r1, =(0x000400C0)
    	and r0, r1
    	cmp r0, #0x0
    	bne DodgeBall	@auto-dodge if not on screen (fly/dive/dig/bounce)
    	ldr r0, .TargetStatus
    	ldrb r1, [r0, #0x7]
    	mov r2, #0x1
    	and r1, r2
    	cmp r1, #0x1		@substitute on
    	beq DodgeBall
    	ldrb r0, [r0]
    	cmp r0, #0x20
    	beq NoDodge
    	mov r1, #0x7
    	and r0, r0, r1
    	cmp r0, #0x0
    	bne NoDodge
    	
    GetThreshold:
    	ldr r0, .WildPoke
    	mov r1, #0xB
    	ldr r2, .GetAttr
    	bl linker        @ r0 = target species ID
    	mov r1, #0x1C
    	mul r0, r1
    	ldr r1, .BaseStats
    	add r0, r0, r1
    	ldrb r0, [r0, #0x3]  @ base speed
    	mov r1, #0xA	@number to divide base speed by (change if you want)
    	bl div_func
    	mov r1, #0xD	@r1 = 13 (lower limit ~5% - change if you want)
    	add r1, r0, r1
    
    CheckParalysis:
    	ldr r2, .TargetStatus
    	ldrb r0, [r2]
    	cmp r0, #0x40	@paralysis
    	bne CheckWrap
    	lsr r1, r1, #0x1	@if pokemon paralyzed, its dodge rate is halved
    	
    CheckWrap:
    	add r2, r2, #0x4	@target status 2 bank
    	ldrb r0, [r2, #0x1]
    	mov r3, #0xE0
    	and r0, r3
    	cmp r0, #0x0
    	beq CheckEvasion
    @     beq CheckDodge      @use this jump if you don't want the Speed/Evasion stat change code
    	lsr r2, r1, #0x2
    	sub r1, r1, r2	@3/4 dodge rate if trapped by wrap effect
    @ b CheckDodge       @use this jump if you don't want the Speed/Evasion stat change code
    
    /*  evasion and speed modifiers     */
    
    CheckEvasion:
    	ldr r2, .TargetStatChanges
    	ldrb r2, [r2, #0x7]
    	cmp r2, #0x6
    	bgt RaiseBase
    	cmp r2, #0x6
    	blt LowerBase
    	b CheckSpeed
    	
    RaiseBase:
    	sub r2, r2, #0x6
    	lsl r2, r2, #0x2      @ add 4:4:24 for speed (1 through 5) -> lower limit=17(6%) to 37(14%)
    	add r1, r1, r2
    	b CheckSpeed
    
    LowerBase:
    	mov r3, #0x6
    	sub r2, r3, r2
    	lsl r2, r2, #0x1     @ lower limit=11/255(4%) to 1/255(.4%)
    	cmp r1, r2
    	blt NoDodge
    	sub r1, r1, r2
    
    CheckSpeed:
    	ldr r2, .TargetStatChanges
    	ldrb r2, [r2, #0x3]
    	cmp r2, #0x6
    	bgt RaiseBase2
    	cmp r2, #0x6
    	blt LowerBase2
    	b CheckDodge
    	
    RaiseBase2:
    	sub r2, r2, #0x6
    	lsl r2, r2, #0x1      @r2 = 2:2:12
    	add r1, r1, r2
    	b CheckDodge
    	
    LowerBase2:
    	mov r3, #0x6
    	sub r2, r3, r2
    	lsl r2, r2, #0x1
    	cmp r1, r2
    	blt NoDodge
    	sub r1, r1, r2
    
    /*  end of evasion and speed modifiers     */
    	
    CheckDodge:
    	mov r3, r1
    	bl rand_func
    	lsr r0, r0, #0x8
    	cmp r0, r3
    	bls DodgeBall	@if r0 <= threshold, pokemon dodges
    
    NoDodge:
    	ldr r3, .BaseStats      @ remember to change if youve repointed!
    	ldr r2, .BattleStruct
    	ldrb r1, [r6]         @ target bank
    	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 animation
    	ldr r2, =(0x0800E194 +1)
    	bl linker
    	ldrb r0, [r5]
    	ldr r2, =(0x08017248 +1)
    	bl linker
    	ldr r1, =(0x02023D74)
    	ldr r0, .DodgeMessage
    	ldr r2, =(0x0802D7EC +1)
    	bx r2
    	
    linker:
    	bx r2
    
    .align 2
    .BallThrown:	.word 0x02023D68
    .GetAttr:	.word 0x0803FBE9
    .Rand: .word 0x08044EC9
    .WildPoke:	.word 0x0202402C
    .BaseStats: .word 0x08254784
    .Divide:	.word 0x081E4019
    .TargetStatus:	.word 0x02023C88
    .BattleStruct:    .word 0x02023BE4
    .TargetStatChanges:	.word 0x02023C54
    .SpecialStatus:	.word 0x02023E00
    .DodgeMessage:	.word 0x08XXXXXX	@custom 'dodgeball' battle script address. battle script must end in 0xF6

    As always, please let me know if there are any bugs,you have any suggestions for the routine, or you need help inserting it.

    Thanks :)
     
    Last edited:
    352
    Posts
    7
    Years
    • Seen Mar 10, 2022
    Update to this post:

    Probability of Dodging Poke Balls [FR]

    As mentioned in the original post, this routine uses the wild pokemon's base speed stat to calculate a probability that it will dodge a thrown pokeball (~5-10%). However, it would freeze the game if the user had a status condition.

    Credits to Urz for helping substantially locate/solve the bizarre bug!

    The updated routine (below), should remove the bug. I also added in a check that prevents the wild pokemon from dodging if it is asleep, frozen, or paralyzed, as is only logical :)

    To use:
    1. Insert routine at 0xXXYYZZ
    2. Insert 01 48 00 47 00 00 (ZZ+1) YY XX 08 at 0x0802D452

    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    .global dodgeball
    
    main:
    	ldr r1, .BallThrown
    	ldrb r0, [r1]
    	cmp r0, #0x5				@safari ball ID
    	beq SafariBall
    	cmp r0, #0x1				@master ball ID
    	bne OtherBall
    	ldr r0, =(0x03004F90)
    	ldr r1, =(0x0802D688 +1)
    	bx r1
    	
    SafariBall:
    	ldr r0, =(0x0802D6BC +1)
    	bx r0
    
    OtherBall:
    	ldr r0, .TargetStatus
    	ldrb r0, [r0]
    	cmp r0, #0x40		@paralysis
    	beq NoDodge
    	cmp r0, #0x20
    	beq NoDodge			@frozen
    	mov r1, #0x7
    	and r0, r0, r1		@sleep (between 0x1 and 0x5)
    	cmp r0, #0x0
    	bne NoDodge
    	
    CheckThreshold:
    	ldr r0, .WildPoke
    	mov r1, #0xB
    	ldr r2, .GetAttr			@get species ID of wild pokemon
    	bl linker
    	sub r0, r0, #0x1
    	mov r1, #0x1C				@pokedex data is 0x1C=28 bytes each
    	mul r0, r0, r1
    	ldr r1, .BaseStats
    	add r0, r0, r1
    	ldrb r0, [r0, #0x3]			@r0 = wild pokemon base speed
    	mov r1, #0xA
    	bl div_func					@r0 =  base speed / 10 (change if you want)
    	mov r3, #0x0
    	mov r1, #0xD				@r1 = 13, lower limit (change if you want)
    	add r3, r0, r1				@r3 = 13 + base_speed/10 = threshold to compare against random byte (~5-10%)
    	bl rand_func
    	lsr r0, r0, #0x8			@r0 = random byte
    	cmp r0, r3
    	bls DodgeBall				@if r0 <= threshold value, the pokemon dodges the ball
    
    NoDodge:
    	ldr r0, =(0x0802D4B4 +1)	@continue with pokemon throw command
    	bx r0
    	
    div_func:
    	ldr r2, .Divide
    	bx r2
    	
    rand_func:
    	ldr r2, .Rand
    	bx r2
    	
    DodgeBall:
    	ldr r0, .Dodge			@pokemon dodges the pokeball - edit text so it doesn't say it can't be caught
    	bx r0
    	
    linker:
    	bx r2
    
    .align 2
    .BallThrown:	.word 0x02023D68
    .GetAttr:	.word 0x0803FBE9	@get pokemon attribute r1 from address r0, store in r0
    .Dodge:	.word 0x802D461			@routine where pokemon dodges the pokeball (also edit the text itself (0x3FD6C7))
    .Rand: .word 0x08044EC9			@random bytes
    .WildPoke:	.word 0x0202402C    @wild pokemon species ID
    .BaseStats: .word 0x082547A0	@pokemon base stat data start (starts at 1, not 0!)
    .Divide:	.word 0x081E4019 	@divide r0 by r1, store integer result in r0
    .TargetStatus:	.word 0x02023C88	@target status bank

    EDIT: of course, please let me know if there are any more bugs.

    One question, the hook at the old post is at 0x2D67A and this one is at 0x2D452, the system will need the two routines or I can restore the vanilla data in the old post's hook offset? Or you mistakenly used the wrong hook? (The offset in question is for the hook of uncapturable Pok?mon)
     
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    One question, the hook at the old post is at 0x2D67A and this one is at 0x2D452, the system will need the two routines or I can restore the vanilla data in the old post's hook offset? Or you mistakenly used the wrong hook? (The offset in question is for the hook of uncapturable Pok?mon)

    Sorry, I should have specified. You will need to restore the data at 0x0802D67A and instead insert the hook at 0x082D452. And then replace 0x0802D6A8+1 with 0x0802D4B4+1 as in the updated routine.
     
    352
    Posts
    7
    Years
    • Seen Mar 10, 2022
    Sorry, I should have specified. You will need to restore the data at 0x0802D67A and instead insert the hook at 0x082D452. And then replace 0x0802D6A8+1 with 0x0802D4B4+1 as in the updated routine.

    But the old offset cannot be used instead? Because some people like me uses this offset for hooking the Uncapturable Pok?mon system.
     
    22
    Posts
    9
    Years
    • Seen Feb 1, 2020
    IDEA
    I'm trying to add a feature that I'm sure it's possible to do. It consist on showing the real time as a clock do (I inserted RTC system) in the start menu, so in fact, the only thing to do is to display in the start menu a box with text that will be the hour based on the statusbytes located in the specified RAM offset.
     
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    But the old offset cannot be used instead? Because some people like me uses this offset for hooking the Uncapturable Pok?mon system.

    Ah, I see what you mean. Well, I haven't tested it myself, but I imagine even with updating the NoDodge routine to 0x0802D4B4 +1, inserting at the old hook would not get rid of the bug that freezes the game when there's a status condition.

    I would suggest merging the two routines; anytime before the NoDodge snippet (at the beginning of OtherBall is probably best), just add in:
    Code:
    ldr r2, .VAR
    ldrb r2, [r2]
    cmp r2, #0x1
    beq DodgeBall

    And that should make it so if your variable is toggled on, the pokemon automatically dodges the ball.

    EDIT: I edited the post to reflect these changes, as well. Thanks for letting me know about that conflict :)
    EDIT 2: I forgot about the master ball - You should be able to just add those four lines above to the beginning of the routine if you want all Pokeballs to miss.
     
    Last edited:
    352
    Posts
    7
    Years
    • Seen Mar 10, 2022
    Ah, I see what you mean. Well, I haven't tested it myself, but I imagine even with updating the NoDodge routine to 0x0802D4B4 +1, inserting at the old hook would not get rid of the bug that freezes the game when there's a status condition.

    I would suggest merging the two routines; anytime before the NoDodge snippet (at the beginning of OtherBall is probably best), just add in:
    Code:
    ldr r2, .VAR
    ldrb r2, [r2]
    cmp r2, #0x1
    beq DodgeBall

    And that should make it so if your variable is toggled on, the pokemon automatically dodges the ball.

    EDIT: I edited the post to reflect these changes, as well. Thanks for letting me know about that conflict :)
    EDIT 2: I forgot about the master ball - You should be able to just add those four lines above to the beginning of the routine if you want all Pokeballs to miss.

    My version of the Uncapturable Pok?mon routine have a flag instead of variable, but it worked fine. ^^

    EDIT: I don't know if you tested, but your updated routine now makes all wild pkmn always dodge.
     
    Last edited:
    88
    Posts
    7
    Years
    • Seen Jan 16, 2020
    My version of the Uncapturable Pok?mon routine have a flag instead of variable, but it worked fine. ^^

    EDIT: I don't know if you tested, but your updated routine now makes all wild pkmn always dodge.

    I had tested it before adding in the capturability toggle and there were no issues
     

    RuFF

    Hope you're having a RuFF day!
    365
    Posts
    11
    Years
  • Please look at following words if you want the custom moves!!!
    Firstly to use custom moves you need a routine written by FBI and modified by me which was originally posted here:

    Custom 'givepokemon'

    No bugs found in this hack.
    Code:
    .thumb
    /*EWRAM:020370B8 var_8000: species      
    EWRAM:020370BA var_8001: level      
    EWRAM:020370BC var_8002: held item      
    EWRAM:020370BE var_8003: attack 1     
    EWRAM:020370C0 var_8004: attack 2      
    EWRAM:020370C2 var_8005: attack 3      
    EWRAM:020370C4 var_8006: attack 4      
    EWRAM:020370C6 var_8007: HP IV      
    EWRAM:020370C8 var_8008: attack IV     
    EWRAM:020370CA var_8009: defence IV      
    EWRAM:020370CC var_800A: speed IV      
    EWRAM:020370CE var_800B: sp. attack IV      
    EWRAM:020370D0 var_800D: sp. defence IV      
    EWRAM:020370D2 var_800F: shiny?
    EWRAM:020370DE var_8014: ball*/
    
    main_func:
    push {r4-r7, lr}
    sub sp, sp, #0x20
    mov r0, #0x64
    ldr r1, .malloc
    bl jump_r1
    mov r8, r0
    ldr r1, .clear
    bl jump_r1
    mov r0, r8
    ldr r1, .clear2
    bl jump_r1
    ldr r1, .random
    bl jump_r1
    mov r4, r0
    ldr r0, .saveblockptr
    ldr r2, [r0]
    add r2, #0xA @OTID_loc
    add r6, r2, #0
    ldrh r1, [r2]
    ldrh r5, [r2, #2]
    eor r5, r1 @TID xor SID
    ldr r3, .var
    ldrh r3, [r3, #0x1A]
    ldr r1, .random
    bl jump_r1
    bl shinycheck
    /*r0 = PID1, r4 = PID2*/
    lsl r0, r0, #0x10
    ldr r2, .var
    add r2, #0x20
    strh r4, [r2]
    orr r0, r4 @PID
    mov r1, #0
    ldr r2, .var
    add r2, #0x1C
    str r0, [r2]
    mov r0, r8
    ldr r3, .setter1
    bl jump_r3
    mov r0, r8
    ldr r3, .setter1
    mov r1, #1
    add r2, r6, #0
    bl jump_r3
    mov r0, r8
    ldr r1, .checksum
    bl jump_r1
    ldr r2, .var
    add r2, #0x1C
    strh r0, [r2]
    mov r0, r8
    mov r1, #9
    ldr r3, .setter1
    bl jump_r3
    mov r0, r8
    ldr r1, .encrypt
    bl jump_r1
    mov r0, sp
    ldr r1, .var
    ldrh r1, [r1]
    ldr r3, .loadname
    bl jump_r3
    mov r0, r8
    mov r1, #2
    mov r2, sp
    ldr r3, .setter1
    bl jump_r3
    ldr r2, .language
    mov r0, r8
    mov r1, #3
    ldr r3, .setter1
    bl jump_r3
    mov r0, r8
    ldr r5, .saveblockptr
    ldr r2, [r5]
    mov r1, #7
    ldr r3, .setter1
    bl jump_r3
    mov r0, r8
    mov r1, #0xb
    ldr r2, .var
    ldr r3, .setter1
    bl jump_r3
    ldr r4, .stat
    ldr r2, .var
    ldrh r1, [r2]
    lsl r0, r1, #3
    sub r0, r0, r1
    lsl r0, r0, #2
    add r0, r0, r4
    ldrb r1, [r0, #0x13] 
    mov r0, #0xCA
    lsl r0, r0, #1
    add r2, r1, #0
    mul r2, r0
    ldr r0, .var
    ldrb r0, [r0, #2]
    lsl r0, r0, #2
    ldr r1, .exp
    add r0, r0, r1
    add r2, r2, r0
    mov r0, r8
    mov r1, #0x19
    ldr r3, .setter1
    bl jump_r3
    ldr r1, .var
    ldrh r0, [r1]
    lsl r2, r0, #3
    sub r2, r2, r0
    lsl r2, r2, #2
    add r4, #0x12
    add r2, r2, r4
    mov r0, r8
    mov r1, #0x20
    ldr r3, .setter1
    bl jump_r3
    ldr r1, .catchlocation
    bl jump_r1
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    mov r1, #0x23
    ldr r2, .var
    add r2, #0x1C
    str r0, [r2]
    mov r0, r8
    ldr r3, .setter1
    bl jump_r3
    mov r0, r8
    mov r1, #0x24
    ldr r2, .var
    add r2, r2, #2
    ldr r3, .setter1
    bl jump_r3
    mov r0, r8
    ldr r2, .version
    mov r1, #0x25
    ldr r3, .setter1
    bl jump_r3
    ldr r2, .var
    add r2, #0x26
    mov r1, #0x26
    mov r0, r8
    ldr r3, .setter1
    bl jump_r3
    ldr r2, [r5]
    add r2, #8
    mov r0, r8
    mov r1, #0x31
    ldr r3, .setter1
    bl jump_r3
    bl iv_encrypt
    ldr r2, .stat
    ldr r3, .var
    ldrh r1, [r3]
    lsl r0, r1, #3
    sub r0, r0, r1
    lsl r0, r0, #2
    add r0, r0, r2
    ldrb r0, [r0, #0x17]
    cmp r0, #0
    beq end
    ldr r2, .var
    add r2, #0x1C
    ldrh r0, [r2, #4]
    mov r1, #1
    and r0, r1
    str r0, [r2]
    mov r0, r8
    mov r1, #0x2E
    ldr r3, .setter1
    bl jump_r3
    
    end:
    mov r0, r8
    ldr r1, .sub_803E9E0
    bl jump_r1
    mov r0, r8
    mov r1, #0x38
    ldr r2, .var
    add r2, r2, #2
    ldr r3, .setter2
    bl jump_r3
    mov r0, r8
    mov r1, #0x40
    ldr r2, .var
    add r2, #0x1C
    mov r3, #0xFF
    str r3, [r2]
    ldr r3, .setter2
    bl jump_r3
    mov r0, r8
    ldr r1, .recalculation
    bl jump_r1
    mov r0, r8
    mov r1, #0xC
    ldr r2, .var
    add r2, #4
    ldr r3, .setter2
    bl jump_r3
    mov r0, r8
    ldr r1, .catch
    bl jump_r1
    lsl r0, r0, #0x18
    lsr r4, r0, #0x18
    ldr r0, .var
    ldrh r0, [r0]
    ldr r1, .convert
    bl jump_r1
    lsl r0, r0, #0x10
    lsr r5, r0, #0x10
    cmp r4, #1
    bgt back
    cmp r4, #0
    blt back
    add r0, r5, #0
    mov r1, #2
    ldr r3, .dexcheck
    bl jump_r3
    add r0, r5, #0
    mov r1, #3
    ldr r3, .dexcheck
    bl jump_r3
    
    back:
    mov r0, r8
    ldr r1, .free
    bl jump_r1
    add r0, r4, #0
    ldr r4, .var
    strh r0, [r4, #0x18]
    add sp, sp, #0x20
    mov r0, #0
    pop {r4-r7, pc}
    
    shinycheck:
    push {lr}
    cmp r3, #0
    beq jump_pc
    ldr r1, .random
    bl jump_r1
    mov r1, #7
    and r0, r1
    eor r0, r5
    eor r0, r4
    
    jump_pc:
    pop {pc}
    
    iv_encrypt:
    push {lr}
    mov r7, #0
    loop_iv:
    ldr r2, .var
    add r2, #0xE
    mov r0, r8
    ldr r3, .setter1
    add r1, r7, #0
    add r1, #0x27
    lsl r6, r7, #1
    add r2, r2, r6
    bl jump_r3
    add r7, r7, #1
    cmp r7, #6
    bne loop_iv
    pop {pc}
    
    jump_r1:
    bx r1
    
    jump_r3:
    bx r3
    
    .align 2
    .malloc: .word 0x08002BB1
    .clear: .word 0x0803D995
    .clear2: .word 0x0803D97D
    .random: .word 0x8044EC9
    .setter1: .word 0x080404D1
    .saveblockptr: .word 0x300500C
    .var: .word 0x020370B8
    .checksum: .word 0x0803E3E9
    .encrypt: .word 0x0803F8F9
    .loadname: .word 0x08040FD1
    .language: .word 0x081E9F11
    .stat: .word 0x08254784
    .exp: .word 0x08253AE4
    .catchlocation: .word 0x08056261
    .version: .word 0x081E9F10
    .sub_803E9E0: .word 0x0803E9E1
    .setter2: .word 0x0804037D
    .recalculation: .word 0x0803E47D
    .catch: .word 0x08040B15
    .convert: .word 0x08043299
    .dexcheck: .word 0x08088E75
    .free: .word 0x08002BC5

    Usage: (script)
    Code:
    lock
    faceplayer
    setvar 0x40ff 0x1 //custom move trigger
    setvar 0x8000 0x19A //species
    setvar 0x8001 0x28 //level
    setvar 0x8002 0x8F //item
    setvar 0x8003 0x1 //moves
    setvar 0x8004 0x2
    setvar 0x8005 0x3
    setvar 0x8006 0x4
    setvar 0x8007 0x1B //IVs
    setvar 0x8008 0x1C
    setvar 0x8009 0x1D
    setvar 0x800A 0x1E
    setvar 0x800B 0x1F
    setvar 0x800D 0x1F
    setvar 0x800F 0x1 //shiny
    setvar 0x8014 0x4 //pokeball
    callasm 0x8LLLLLL //offset of the function + 1
    setvar 0x40ff 0x0 //make it normal
    release
    end

    Custom 'setwildbattle'

    along with a question
    I've also developed a routine which can customize the wild pokemon for firered.
    Insert this piece of code in free space:
    Code:
    .thumb
    /*EWRAM:020370B8 var_8000: species      
    EWRAM:020370BA var_8001: level      
    EWRAM:020370BC var_8002: held item      
    EWRAM:020370BE var_8003: attack 1     
    EWRAM:020370C0 var_8004: attack 2      
    EWRAM:020370C2 var_8005: attack 3      
    EWRAM:020370C4 var_8006: attack 4      
    EWRAM:020370C6 var_8007: HP IV      
    EWRAM:020370C8 var_8008: attack IV     
    EWRAM:020370CA var_8009: defence IV      
    EWRAM:020370CC var_800A: speed IV      
    EWRAM:020370CE var_800B: sp. attack IV      
    EWRAM:020370D0 var_800D: sp. defence IV      
    EWRAM:020370D2 var_800F: shiny?*/
    
    main_func:
    push {r4-r7, lr}
    sub sp, sp, #0x20
    ldr r1, .clear
    bl jump_r1
    ldr r0, .pkmndata
    ldr r1, .clear2
    bl jump_r1
    ldr r1, .random
    bl jump_r1
    mov r4, r0
    ldr r0, .saveblockptr
    ldr r2, [r0]
    add r2, #0xA @OTID_loc
    add r6, r2, #0
    ldrh r1, [r2]
    ldrh r5, [r2, #2]
    eor r5, r1 @TID xor SID
    ldr r3, .var
    ldrh r3, [r3, #0x1A]
    ldr r1, .random
    bl jump_r1
    bl shinycheck
    /*r0 = PID1, r4 = PID2*/
    lsl r0, r0, #0x10
    ldr r2, .var
    add r2, #0x20
    strh r4, [r2]
    orr r0, r4 @PID
    mov r1, #0
    ldr r2, .var
    add r2, #0x1C
    str r0, [r2]
    ldr r0, .pkmndata
    ldr r3, .setter1
    bl jump_r3
    ldr r0, .pkmndata
    ldr r3, .setter1
    mov r1, #1
    add r2, r6, #0
    bl jump_r3
    ldr r0, .pkmndata
    ldr r1, .checksum
    bl jump_r1
    ldr r2, .var
    add r2, #0x1C
    strh r0, [r2]
    ldr r0, .pkmndata
    mov r1, #9
    ldr r3, .setter1
    bl jump_r3
    ldr r0, .pkmndata
    ldr r1, .encrypt
    bl jump_r1
    mov r0, sp
    ldr r1, .var
    ldrh r1, [r1]
    ldr r3, .loadname
    bl jump_r3
    ldr r0, .pkmndata
    mov r1, #2
    mov r2, sp
    ldr r3, .setter1
    bl jump_r3
    ldr r2, .language
    ldr r0, .pkmndata
    mov r1, #3
    ldr r3, .setter1
    bl jump_r3
    ldr r0, .pkmndata
    ldr r5, .saveblockptr
    ldr r2, [r5]
    mov r1, #7
    ldr r3, .setter1
    bl jump_r3
    ldr r0, .pkmndata
    mov r1, #0xb
    ldr r2, .var
    ldr r3, .setter1
    bl jump_r3
    ldr r4, .stat
    ldr r2, .var
    ldrh r1, [r2]
    lsl r0, r1, #3
    sub r0, r0, r1
    lsl r0, r0, #2
    add r0, r0, r4
    ldrb r1, [r0, #0x13] 
    mov r0, #0xCA
    lsl r0, r0, #1
    add r2, r1, #0
    mul r2, r0
    ldr r0, .var
    ldrb r0, [r0, #2]
    lsl r0, r0, #2
    ldr r1, .exp
    add r0, r0, r1
    add r2, r2, r0
    ldr r0, .pkmndata
    mov r1, #0x19
    ldr r3, .setter1
    bl jump_r3
    ldr r1, .var
    ldrh r0, [r1]
    lsl r2, r0, #3
    sub r2, r2, r0
    lsl r2, r2, #2
    add r4, #0x12
    add r2, r2, r4
    ldr r0, .pkmndata
    mov r1, #0x20
    ldr r3, .setter1
    bl jump_r3
    ldr r1, .catchlocation
    bl jump_r1
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    mov r1, #0x23
    ldr r2, .var
    add r2, #0x1C
    str r0, [r2]
    ldr r0, .pkmndata
    ldr r3, .setter1
    bl jump_r3
    ldr r0, .pkmndata
    mov r1, #0x24
    ldr r2, .var
    add r2, r2, #2
    ldr r3, .setter1
    bl jump_r3
    ldr r0, .pkmndata
    ldr r2, .version
    mov r1, #0x25
    ldr r3, .setter1
    bl jump_r3
    mov r0, #4
    ldr r2, .var
    add r2, #0x1C
    str r0, [r2]
    mov r1, #0x26
    ldr r0, .pkmndata
    ldr r3, .setter1
    bl jump_r3
    ldr r2, [r5]
    add r2, #8
    ldr r0, .pkmndata
    mov r1, #0x31
    ldr r3, .setter1
    bl jump_r3
    bl iv_encrypt
    ldr r2, .stat
    ldr r3, .var
    ldrh r1, [r3]
    lsl r0, r1, #3
    sub r0, r0, r1
    lsl r0, r0, #2
    add r0, r0, r2
    ldrb r0, [r0, #0x17]
    cmp r0, #0
    beq end
    ldr r2, .var
    add r2, #0x1C
    ldrh r0, [r2, #4]
    mov r1, #1
    and r0, r1
    str r0, [r2]
    ldr r0, .pkmndata
    mov r1, #0x2E
    ldr r3, .setter1
    bl jump_r3
    
    end:
    ldr r0, .pkmndata
    ldr r1, .sub_803E9E0
    bl jump_r1
    ldr r0, .pkmndata
    mov r1, #0x38
    ldr r2, .var
    add r2, r2, #2
    ldr r3, .setter2
    bl jump_r3
    ldr r0, .pkmndata
    mov r1, #0x40
    ldr r2, .var
    add r2, #0x1C
    mov r3, #0xFF
    str r3, [r2]
    ldr r3, .setter2
    bl jump_r3
    ldr r0, .pkmndata
    ldr r1, .recalculation
    bl jump_r1
    ldr r0, .pkmndata
    mov r1, #0xC
    ldr r2, .var
    add r2, #4
    ldr r3, .setter2
    bl jump_r3
    add sp, sp, #0x20
    mov r0, #0
    pop {r4-r7, pc}
    
    shinycheck:
    push {lr}
    cmp r3, #0
    beq jump_pc
    ldr r1, .random
    bl jump_r1
    mov r1, #7
    and r0, r1
    eor r0, r5
    eor r0, r4
    
    jump_pc:
    pop {pc}
    
    iv_encrypt:
    push {lr}
    mov r7, #0
    loop_iv:
    ldr r2, .var
    add r2, #0xE
    ldr r0, .pkmndata
    ldr r3, .setter1
    add r1, r7, #0
    add r1, #0x27
    lsl r6, r7, #1
    add r2, r2, r6
    bl jump_r3
    add r7, r7, #1
    cmp r7, #6
    bne loop_iv
    pop {pc}
    
    jump_r1:
    bx r1
    
    jump_r3:
    bx r3
    
    .align 2
    .clear: .word 0x0803DA35
    .pkmndata: .word 0x0202402C
    .clear2: .word 0x0803D97D
    .random: .word 0x8044EC9
    .setter1: .word 0x080404D1
    .saveblockptr: .word 0x300500C
    .var: .word 0x020370B8
    .checksum: .word 0x0803E3E9
    .encrypt: .word 0x0803F8F9
    .loadname: .word 0x08040FD1
    .language: .word 0x081E9F11
    .stat: .word 0x08254784
    .exp: .word 0x08253AE4
    .catchlocation: .word 0x08056261
    .version: .word 0x081E9F10
    .sub_803E9E0: .word 0x0803E9E1
    .setter2: .word 0x0804037D
    .recalculation: .word 0x0803E47D

    How to use:
    Create a script: (The usage of the variables are listed in the comment of the function written by me)
    Code:
    lock
    faceplayer
    setvar 0x40ff 0x1 //custom move trigger
    setvar 0x8000 0x19A //species
    setvar 0x8001 0x28 //level
    setvar 0x8002 0x8F //item (This won't work, so you can't make the pokemon hold an item because another routine clears it. I don't know the reason and I can only wait for fixing. )
    setvar 0x8003 0x1 //moves
    setvar 0x8004 0x2
    setvar 0x8005 0x3
    setvar 0x8006 0x4
    setvar 0x8007 0x1F //max IVs
    setvar 0x8008 0x1F
    setvar 0x8009 0x1F
    setvar 0x800A 0x1F
    setvar 0x800B 0x1F
    setvar 0x800D 0x1F
    setvar 0x800F 0x1 //shiny
    callasm 0x8MMMMMM //offset of the ASM function +1
    dowildbattle
    setvar 0x40ff 0x0 //make it normal
    release
    //Here you can insert other codes. 
    end

    The item will be cleared by another routine (around 0x44446), so I hope that someone can fix the bug to make the routine more perfect. :)


    I encountered a bug on custom give pokemon.

    If the specie number is 5, the level of the pokemon will also be 5 no matter what the value you put in var 0x8001.


    Okay, the real problem here is if your specie number is greater than 411 then the level of the pokemon you get is not correct.

    EDIT: I have extended Pokemon. I'm using pokefreak890's base

    EDITEDIT: I found the fix

    Code:
    .language: .word 0x081E9F11
    .stat: .word 0x08254784    Change this to the location where your Pokemon Data is.
    .exp: .word 0x08253AE4

    I don't know if there are other stuffs that needs to be change. You only need to do this if you have extended the number of Pokemon in you rom.

    EDITEDITEDIT: For some reason there are still problems to some Pokemon.

    Sometimes you get Level 0, sometimes 100, sometimes 58.
    I hope someone can fix this.


     
    Last edited:
    Back
    Top