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)

rojse February 27th, 2017 11:35 AM

Hello. I'm interested in an edit that makes Emerald generate all IVs of all encountered Pokemon at 31. What's the best way to go about this?

linobigatti March 3rd, 2017 9:35 AM

I want to know how it would be to create mysterious gifts

ItsFrickenMe March 11th, 2017 7:58 PM

Quote:

Originally Posted by FBI (Post 8533235)

Roaming Pokemon!


So if I want to use this in Emerald...is it simply a matter of changing offsets? Would the ASM part be the same?

DizzyEgg March 12th, 2017 1:34 AM

Quote:

Originally Posted by ItsFrickenMe (Post 9592046)
So if I want to use this in Emerald...is it simply a matter of changing offsets? Would the ASM part be the same?

No, you can't just port things from one game to another. Also, roaming mechanics already exist in Emerald.

Squeetz March 12th, 2017 6:40 AM

I'm practicing ASM and made a fun little routine for Firered (with some help from Spherical Ice) that counts the amount of Rare Candies the player has used.
If you want to punish your players for cheating by hacking in candies, then this might be of use to you.

Spoiler:
.thumb

main:
ldr r4, variable
mov r0, r4
ldr r2, var_load
bl branch_by_r2
lsl r0, #0x10
lsr r0, #0x10
ldr r1, =(0xFFFF) @if var limit reached, goto end
cmp r0, r1
beq end
mov r1, r0
add r1, #0x1
mov r0, r4
ldr r2, var_set
bl branch_by_r2
end:
ldr r1, tasks
mov r2, r8
lsl r0, r2, #0x2
add r0, r8
lsl r0, #0x3
add r0, r0, r1
ldr r1, sub_81264C8
str r1, [r0]
pop {r3}
mov r8, r3
pop {r4-r7}
pop {r0}
bx r0


branch_by_r2:
bx r2

.align 2
variable: .word 0x4050 @change to variable of choice
var_load: .word 0x0806E568 +1
var_set: .word 0x0806E584 +1
tasks: .word 0x03005090
sub_81264C8: .word 0x081264C8 +1


After inserting this in a word-aligned offset, go to 0x1263F6 and place:
Code:

01 49 08 47 C0 46 XX XX XX 08


Where XX is the pointer to the routine, +1.

This routine will automatically add 1 to the variable you chose each time the player uses a rare candy.
How you handle the variable in a script is all up to you!

ItsFrickenMe March 12th, 2017 7:14 AM

Quote:

Originally Posted by DizzyEgg (Post 9592195)
Also, roaming mechanics already exist in Emerald.

Roaming mechanics already exist in Firered too, so why is this ASM needed at all?

ItsFrickenMe March 14th, 2017 9:39 AM

Quote:

Originally Posted by DizzyEgg (Post 9592195)
No, you can't just port things from one game to another. Also, roaming mechanics already exist in Emerald.

Answer me. Now.

DizzyEgg March 14th, 2017 9:44 AM

Quote:

Originally Posted by ItsFrickenMe (Post 9593626)
Answer me. Now.

Answer what?

ItsFrickenMe March 14th, 2017 9:45 AM

Quote:

Originally Posted by DizzyEgg (Post 9593633)
Answer what?

Why is it relevant that roaming mechanics are already in Emerald, when they're also already in FR?

DizzyEgg March 14th, 2017 9:51 AM

Quote:

Originally Posted by ItsFrickenMe (Post 9593634)
Why is it relevant that roaming mechanics are already in Emerald, when they're also already in FR?

You're right, you could modify or use the already existing system. That's what I would probably do.
I guess FBI made his own to have better control over it and to make it compatible with his swarming system.

mbcn10ww March 16th, 2017 4:55 AM

There is a way to call a script with ASM? I want to make something like this:
If a flag is set do something, if not set show a message.

What's the command I use on a routine to make it work?

BLAx501! March 16th, 2017 12:29 PM

Quote:

Originally Posted by mbcn10ww (Post 9594585)
There is a way to call a script with ASM? I want to make something like this:
If a flag is set do something, if not set show a message.

What's the command I use on a routine to make it work?

Well, you could manage that by simply using scripts, but if you insist on using ASM:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r1, lr}
        ldr r0, .SCRIPT_ADDRESS
        ldr r1, =(0x8069AE4 +1)
        bl linkerTwo
        pop {r0-r1, pc}

linkerTwo:
        bx r1

.align 2

.SCRIPT_ADDRESS:
        .word 0x8[script_location +1]


FBI made this routine as a reply to something I asked some time ago on the ASM Help Thread. You just have to compile it, modifying the code to add your script location, insert the code on an aligned offset (is it said that way? xDD) and then callasm the routine offset + 1 as usual.

Hope this helps :D

mbcn10ww March 16th, 2017 1:40 PM

Quote:

Originally Posted by BLAx501! (Post 9594743)
Well, you could manage that by simply using scripts, but if you insist on using ASM:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r1, lr}
        ldr r0, .SCRIPT_ADDRESS
        ldr r1, =(0x8069AE4 +1)
        bl linkerTwo
        pop {r0-r1, pc}

linkerTwo:
        bx r1

.align 2

.SCRIPT_ADDRESS:
        .word 0x8[script_location +1]


FBI made this routine as a reply to something I asked some time ago on the ASM Help Thread. You just have to compile it, modifying the code to add your script location, insert the code on an aligned offset (is it said that way? xDD) and then callasm the routine offset + 1 as usual.

Hope this helps :D

I know it can be done only with scripts, but it's needed to edit another routine I have, then it looks better than I wanted, thanks for the reply, I will test it soon as possible and I tell if it worked. ^^

EDIT: Haven't worked, I tested running it by another routine, I tested it by running from the START menu, but haven't worked.

tkim March 17th, 2017 10:35 PM

Quote:

Originally Posted by Squeetz (Post 9595301)
Pokémon Ruby and Sapphire introduced a feature where if you bought 10 or more Poké Balls in the Mart, you would get a free Premier Ball.
Sadly, this feature was removed in FRLG, and so I tried to port it the best I could.

First, insert this text somewhere using XSE or something and write down the offset of where you inserted it:
Code:

I'll throw in a Premier Ball, too.


After that, assemble this routine in a word-aligned offset (ends in 0, 4, 8 or C)
(But first, replace the XXXXXX with the offset of where you inserted the Premier Ball message):

Spoiler:

.thumb

main:
push {r4-r7, lr}
lsl r0, r0, #0x18
lsr r5, r0, #0x18
lsl r0, r5, #2
add r0, r0, r5
lsl r0, r0, #3
ldr r1, taskspriv
add r4, r0, r1
mov r0, #4
ldr r7, rboxid_tilemap_update
bl linkr7
ldrh r0, [r4, #0xA] @ItemID
ldrh r1, [r4, #2] @Amount
mov r6, r1
lsl r6, r6, #0x10
add r6, r0
ldr r7, bag_add_item
bl linkr7
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, #1
bne fullbag
ldr r1, hereyouare
ldr r2, sub_809BF0C
mov r0, r5
bl displaymsg
mov r0, r5
mov r0, r6
lsl r0, #0x10
lsr r0, #0x10
cmp r0, #0x4 @Pokeball ID
beq boughtball
next:
ldrh r0, [r4, #0xA]
ldrh r1, [r4, #2]
mov r2, #1
ldr r7, sub_809C09C
bl linkr7
b end

boughtball:
lsr r6, #0x10
mov r1, r6
cmp r1, #0x9 @if player bought over 9 pokeballs, attempt to add premierball
bhi tryadding
b next

tryadding:
mov r0, #0xC @premier ball ID
mov r1, #0x1 @amount of premier balls
ldr r7, bag_add_item
bl linkr7
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, #1
bne next @if no room for premier ball, skip to next
ldr r1, message
ldr r2, sub_809BF0C
mov r0, r5
bl displaymsg
b next

fullbag:
ldr r1, bagisfull
ldr r2, sub_809BF98
mov r0, r5
bl displaymsg
end:
pop {r4-r7}
pop {r0}
bx r0

displaymsg:
ldr r7, displayadress
linkr7:
bx r7

.align 2
taskspriv: .word 0x03005098
rboxid_tilemap_update: .word 0x08003FA0 +1
bag_add_item: .word 0x0809A084 +1
sub_809BF98: .word 0x0809BF98 +1
sub_809BF0C: .word 0x0809BF0C +1
sub_809C09C: .word 0x0809C09C +1
displayadress: .word 0x0813F75C +1
bagisfull: .word 0x08416861
hereyouare: .word 0x084167E7
message: .word 0x08XXXXXX


After inserting the routine, navigate to 0x3DF0B4 and put the pointer to it, +1. (If I inserted the routine at 0x725030 I would put 31 50 72 08)

And that's it!

Hi. The routine works well but The hereyouare message doesn't seem to appear if I do receive the PREMIER BALL. Instead it goes straight to the 'I'll throw in a PREMIER BALL, too.' I would like to see both messages appear, just as it does in R/S/E. Thanks for the routine!

tkim March 18th, 2017 11:40 AM

Quote:

Originally Posted by Squeetz (Post 9595301)
Pokémon Ruby and Sapphire introduced a feature where if you bought 10 or more Poké Balls in the Mart, you would get a free Premier Ball.
Sadly, this feature was removed in FRLG, and so I tried to port it the best I could.

First, insert this text somewhere using XSE or something and write down the offset of where you inserted it:
Code:

Here you are!\nI'll throw in a Premier Ball, too.



Not what I meant but whatever.

Squeetz March 18th, 2017 1:35 PM

Quote:

Originally Posted by tkim (Post 9595892)
Not what I meant but whatever.

Sorry then.
I'm still learning.

tkim March 18th, 2017 3:02 PM

Quote:

Originally Posted by Squeetz (Post 9595968)
Sorry then.
I'm still learning.

What I meant was, I would like to see the 'I'll throw in...' message following the hereyouare message. Instead of combining the text, I would like to see two separate messages. (without using \p from XSE either)

Something like this.... (I have no knowledge of ASM)
Code:

tryadding:
mov r0, #0xC @premier ball ID
mov r1, #0x1 @amount of premier balls
ldr r7, bag_add_item
bl linkr7
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, #1
bne next @if no room for premier ball, skip to next
ldr r1, hereyouare
ldr r2, sub_809BF0C
mov r0, r5
bl displaymsg
ldr r1, message
ldr r2, sub_809BF0C
mov r0, r5
bl displaymsg

b next



linobigatti March 23rd, 2017 9:20 AM

how can i manipulate the mysterious gift system in FR?

MWisBest March 23rd, 2017 6:07 PM

Quote:

Originally Posted by BluRose (Post 9569452)
REUSABLE BALLS IN EMERALD
gracias a familiawerneck
routine with byte changes
Spoiler:
Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX

main:
        bl deleteball
        mov r9, r4
        mov r10, r5                @ added because emerald
        pop {r4-r7}
        pop {r0}
        bx r0

deleteball:
        ldr r0, var_800E        @ last_used_item_maybe
        ldrh r0, [r0]
        mov r1, #1
        ldr r2, =(0x80D6AA5)
        bx r2

.align 2
var_800E: .word 0x0203CE7C



if y'all want to see specific equivalent addresses:
Spoiler:
Code:

[bpre]
2D924                - atkF0 - near end
9A1D8                - bag_remove_item
A1E30                - pokeball + 0x24
0203AD30        - var 800E

[bpee]
56818                - atkF0 - near end
D6AA4                - bag_remove_item
FE3AA                - pokeball + 0x26
0203CE7C        - last_used_item_maybe


have a nice day~

I fixed this so it doesn't delete the fishing rod in the safari zone, among other glitches. It'll now verify that the item is a ball of some kind before it deletes it.

The code looks strange. I'm guessing it could be improved somehow, but it works:
Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX

main:
        bl delete_item_if_pokeball
        b finish

deleteball:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bx r2

delete_item_if_pokeball:
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls deleteball
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq deleteball

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r0}
        bx r0

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1


EDIT: See here for a version that also makes safari balls reusable.

BluRose March 23rd, 2017 6:24 PM

Quote:

Originally Posted by MWisBest (Post 9599642)
I fixed this so it doesn't delete the fishing rod in the safari zone, among other glitches. It'll now verify that the item is a ball of some kind before it deletes it.

The code looks strange. I'm guessing it could be improved somehow, but it works:
Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX

main:
        bl delete_item_if_pokeball
        bl finish

deleteball:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bx r2

delete_item_if_pokeball:
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls deleteball
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq deleteball

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r0}
        bx r0

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1



oh xD
i guess i forgot to edit my post with what i had posted here and here
muchas gracias amigo~
i'll edit my old post and direct to your method as well x3

ghoulslash March 29th, 2017 4:48 AM

I hope this is the right place to ask, but I was wondering if anyone knows how to edit the following routines so that they don't end the script after completion? For example, use callasm 0x8XXXXXX and then continue with a msgbox, etc..

Naming the player from the overworld: callasm 0x809FC91


And Jambo's rival naming script:
Code:

.text
.align 2
.thumb
.thumb_func
.global rivalnamingingame

main:
        push {r0-r4,lr}
        ldr r0, place
        str r0, [sp, #0x4]
        ldr r1, ramlocation
        ldr r1, [r1, #0x0]
        ldr r0, standard
        add r1, r1, r0
        mov r0, #0x4
        mov r2, #0x0
        mov r3, #0x0
        bl place2
        ldr r1, ramlocation
        ldr r1, [r1, #0x0]
        ldr r0, standard
        add r1, r1, r0
        ldrb r0, [r1, #0x0]
        cmp r0, #0xFF
        beq failsafe
        cmp r0, #0x0
        beq failsafe

return:
        pop {r0-r4}
        pop {pc}

place2:
        ldr r4, actualroutine
        bx r4

failsafe:
        ldr r0, rivalname

loop:
        ldrb r2, [r0, #0x0]
        strb r2, [r1, #0x0]
        cmp r2, #0xFF
        beq return
        add r0, #0x1
        add r1, #0x1
        b loop

.align 2
place: .word 0x080568E1
ramlocation: .word 0x03005008
standard: .word 0x00003A4C
actualroutine: .word 0x0809D955
rivalname: .word 0x08FFFFFF                    @default name if left blank



jiangzhengwenjzw March 29th, 2017 6:04 AM

Quote:

Originally Posted by ghoulslash (Post 9604565)
I hope this is the right place to ask, but I was wondering if anyone knows how to edit the following routines so that they don't end the script after completion? For example, use callasm 0x8XXXXXX and then continue with a msgbox, etc..

Naming the player from the overworld: callasm 0x809FC91

Change the A9 at 0x9FCB4 to C5 and then try to callasm 0x809FC91. (i guess you should perform the 'lock' command again after the callasm)

MWisBest March 29th, 2017 12:48 PM

Quote:

Originally Posted by MWisBest (Post 9599642)
I fixed this so it doesn't delete the fishing rod in the safari zone, among other glitches. It'll now verify that the item is a ball of some kind before it deletes it.

The code looks strange. I'm guessing it could be improved somehow, but it works:
Spoiler:
Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX

main:
        bl delete_item_if_pokeball
        b finish

deleteball:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bx r2

delete_item_if_pokeball:
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls deleteball
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq deleteball

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r0}
        bx r0

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1



Made another improvement to the reusable pokeballs: safari balls can now be reused as well!

Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX
@ 3F008 - 02 E0 C0 46 C0 46 C0 46 ! NEW
@ Optional: change initial safari ball count?: FC0E6 - XX 20, XX = initial count

main:
        @ if safari ball counter is not 0, then that's what we need to delete
        ldr r1, .safari_ball_count
        ldrb r0, [r1]
        cmp r0, #0x0
        bne delete_safari_ball

        @ ...otherwise, delete the last used item (if it's a pokeball)
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls delete_ball_in_bag
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq delete_ball_in_bag

        b finish

delete_safari_ball:
        @ r0 already contains current safari ball count, and
        @ r1 already contains safari ball count memory address
        sub r0, #1
        strb r0, [r1]
        b finish

delete_ball_in_bag:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bl x_r2
        b finish

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r2}
x_r2:
        bx r2

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1
.safari_ball_count:
        .word 0x0203A04C



ghoulslash March 30th, 2017 3:59 AM

Quote:

Originally Posted by jiangzhengwenjzw (Post 9604607)
Change the A9 at 0x9FCB4 to C5 and then try to callasm 0x809FC91. (i guess you should perform the 'lock' command again after the callasm)

Thanks! Do you know how that change converts to assembly so I could try and do the same thing with the naming rival function?

jiangzhengwenjzw March 30th, 2017 4:44 AM

Quote:

Originally Posted by ghoulslash (Post 9605305)
Thanks! Do you know how that change converts to assembly so I could try and do the same thing with the naming rival function?

I guess the rival naming func is also built-in.

Change the A9 at 0x9FD54 to C5 and then try to callasm 0x809FD31. (It's from my old note in firered db, so i'm not sure whether it's correct or not...)

ghoulslash March 30th, 2017 8:26 AM

Quote:

Originally Posted by jiangzhengwenjzw (Post 9605326)
I guess the rival naming func is also built-in.

Change the A9 at 0x9FD54 to C5 and then try to callasm 0x809FD31. (It's from my old note in firered db, so i'm not sure whether it's correct or not...)

Yep, that worked, thanks! :)

EDIT: actually it turns out that edits the players name instead of the rival's name

EDIT 2: looks like setting 0xA9 at 0x9FCB4 0xC5 fixed both naming the player and Jambo's routine (or I had made a mistake using it initially). Setting 0xA9 at 0x9FD54 to 0xC5 doesn't appear to change this either, but callasm 0x809FD31 will overwrite the player's name instead of the rival's

Wesley FG March 30th, 2017 9:06 AM

REQUEST for change this ROUTINE for FIRE RED

The user Andrea make this awesome ASM for icon in menu like DPPt,

Quote:

Originally Posted by ~Andrea
Hello everyone, today I would share with you this little patch:
https://image.ibb.co/d2B86F/2hclyd2.png
As you can see from the screen, the patch will add the icons of the DPP next to each menu item.
- ONLY FOR RUBY -
Note:
- If the menu item "Pokenav" should be active, the icons will be loaded out of phase respect to the corresponding menu item.
This is caused by the lack of an icon for Pokenav in DPP.

Technical information:
Offsets routine: 0x720000
Offset Images Icons (uncompressed): 0x7200D0
Offset Palette icons (uncompressed): 0x720610
To change icons you can open the ROM with NSE 2.X, click browse and input offsets earlier in the appropriate fields.

downloads:
http://www.mediafire.com/download/wzs1d0zg2i5e231/DPP_MENU.ips
Credit if you use it!
but it is only for RUBY version

the routine is it:

Spoiler:

.THUMB
.ALIGN 2
@08071174 00490847XXXXXX08
@080711C8 MOVS R0, #0x16 @coordinata x
@08071208 lunghezza cursore
@0807120E posizione X cursore

PUSH {R0-R7}
LDR R1, = 0x06008020
LDR R0, = 0x087200D0
MOV R2, #0x15
LSL R2, #4
SWI 0xC

LSL R2, #2
ADD R0, R2

MOV R3, #1
LSL R3, #10

LDR R1, = 0x0202EC48
MOV R2, #8
SWI 0xC
LDR R4, = 0x0202FEB3
LDRB R4, [R4]
CMP R4, #0x16
BNE ICONE
ADD R1, R1, R3
SWI 0xC

ICONE:
MOV R6, #0

MOV R0, #1
LSL R0, #11
ADD R0, #1
BL CHECKFLAG
CMP R0, #0
BEQ PARTY

ADD R6, #1
MOV R0, #0
MOV R1, #0
BL SPAWN

PARTY:
MOV R0, #1
LSL R0, #11
BL CHECKFLAG
CMP R0, #0
BEQ ALTRO

MOV R0, #1
ADD R6, #1
CMP R6, #2
BEQ CONTROLLO
MOV R0, #0
CONTROLLO:
MOV R1, #1
BL SPAWN

ALTRO:
LDR R5, = 0x0202E8FD
LDRB R5, [R5]

MOV R7, #2
LOOP2:
MOV R0, R6
MOV R1, R7
BL SPAWN
ADD R6, #1
ADD R7, #1
CMP R6, R5
BNE LOOP2

FINE:
POP {R0-R7}
POP {R4-R7,PC}

SPAWN:
LSL R0, #7
LDR R2, = 0x0600F8A8
ADD R0, R2
MOV R3, #6
MUL R1, R3
ADD R1, #1
MOV R2, #0xC0
LSL R2, #8
ADD R1, R2
MOV R2, #0
MOV R3, #0
LOOP:
STRH R1, [R0]
ADD R0, #2
ADD R1, #1
ADD R2, #1
CMP R2, #3
BNE LOOP
ADD R0, #0x3A
MOV R2, #0
ADD R3, #1
CMP R3, #2
BNE LOOP
BX LR

CHECKFLAG:
PUSH {R0}
LDR R0, = 0x08069341
MOV R10, R0
POP {R0}
BX R10



i no have knlowledge for ASM and i really love with some ASM expert convert it for FIRE RED and EMERALD, because it is very beautifull, and make a awesome hack improve.

BUGS:
-No have icon for dex nav- when this flag is active bug it (R, EM)
-when the player enter in map with some wheater the icons bug, probably are using same location memory pal used for it
https://i.imgur.com/OvNCIWa.png

the original thread of andrea ASM;
https://www.pokecommunity.com/showthread.php?p=8880222#post8880222

PLZ port it for FIRE RED and EMERALD

mbcn10ww March 30th, 2017 5:50 PM

Quote:

Originally Posted by MWisBest (Post 9604877)
Made another improvement to the reusable pokeballs: safari balls can now be reused as well!

Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX
@ 3F008 - 02 E0 C0 46 C0 46 C0 46 ! NEW
@ Optional: change initial safari ball count?: FC0E6 - XX 20, XX = initial count

main:
        @ if safari ball counter is not 0, then that's what we need to delete
        ldr r1, .safari_ball_count
        ldrb r0, [r1]
        cmp r0, #0x0
        bne delete_safari_ball

        @ ...otherwise, delete the last used item (if it's a pokeball)
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls delete_ball_in_bag
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq delete_ball_in_bag

        b finish

delete_safari_ball:
        @ r0 already contains current safari ball count, and
        @ r1 already contains safari ball count memory address
        sub r0, #1
        strb r0, [r1]
        b finish

delete_ball_in_bag:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bl x_r2
        b finish

x_r2:
        bx r2

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r0}
        bx r0

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1
.safari_ball_count:
        .word 0x0203A04C



sorry but can you port it to Fire Red?

MWisBest March 30th, 2017 11:09 PM

Change Daycare Cost [EM]

There's 2 versions of this routine.

The first is completely configurable (when you compile it), and the changes you need to make to do so are very simple and explained well in the code:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: 0A 31 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here, *however*: r1 contains
        @ the address this routine was jumped to from, and using
        @ that we can jump back there easier.
        @
        @ the original code we're replacing, for reference:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        @ need to copy r1 to r3 because r1 is clobbered later
        mov r3, r1

        @ adjust the following code like so:
        @ mov r0, #BASE_PER_LEVEL_COST
        @ mov r1, #PER_LEVEL_COST_MULTIPLIER
        @ ...
        mov r0, #100
        mov r1, #2
        mul r0, r1

        @ ...
        @ and adjust this like so:
        @ mov r2, #BASE_MINIMUM_COST
        @ mov r1, #MINIMUM_COST_MULTIPLIER
        mov r2, #100
        mov r1, #2
        mul r2, r1

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r2 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        bx r3

.align 2
.dword_806FEBC:
        .word 0x02021DC4




The second is a little different. Rather than a configurable multiplier, it uses the "XP per step" value as the multiplier, so if you're using this modification to adjust the XP per step amount it will scale the daycare cost accordingly, e.x. 2 XP per step will multiply the normal daycare cost by 2:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: 0A 31 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here, *however*: r1 contains
        @ the address this routine was jumped to from, and using
        @ that we can jump back there easier.
        @
        @ the original code we're replacing, for reference:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        @ need to copy r1 to r3 because r1 is clobbered later
        mov r3, r1

        mov r0, #100
        ldr r1, .xp_per_step
        ldrb r1, [r1]
        mul r0, r1

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r0 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        bx r3

.align 2
.xp_per_step:
        .word 0x08070AE8
.dword_806FEBC:
        .word 0x02021DC4




Quote:

Originally Posted by mbcn10ww (Post 9605799)
sorry but can you port it to Fire Red?

I am planning on porting the stuff I've done for Emerald to Fire Red soon. I just got back into playing the Gen III games a little while ago and decided to start with Emerald for some reason.

EDIT: Made some changes to the original code I posted to make it more compact/efficient. For those that were already using the old version, note that the first 2 bytes of the byte edit required have also been changed.

Compumax March 31st, 2017 5:09 AM

Request!

1) Load 240x160 static images into BG1 or BG2 using (image, palette, RAW) table and allow (if possible) use BG0 to load texts (as in the presentation of Oak, Pokédex, etc.) and objects like pokepic, Mugshots, etc. And their respective routine to remove the image. If it is very difficult or impossible with ASM, it can be a routine that loads the image in BG0 and its respective routine to remove it. What I want to do is cinematic with frame sequences. I can not use the diploma hack because I need to make decisions by pressing the A, B and the arrow keys.

I tried this routine: FR - Vs. Bar Personalizable but it has no routine to remove the image so in the end I have to do a warp to refresh the screen and erase the image . Finally after 5
continuous frames the game freezes.

2) Load different dialogs in the presentation of Oak depending on the selected genre. What I want to do is a multi-language effect depending on gender. Example: Boy = Spanish, Girl = English.

Thanks for the help you can give me.

Here is the link to my current project:


Pokémon Terranova

PD: Sorry for my English

BluRose March 31st, 2017 8:27 AM

Quote:

Originally Posted by Compumax (Post 9606234)
Spoiler:
Request!

1) Load 240x160 static images into BG1 or BG2 using (image, palette, RAW) table and allow (if possible) use BG0 to load texts (as in the presentation of Oak, Pokédex, etc.) and objects like pokepic, Mugshots, etc. And their respective routine to remove the image. If it is very difficult or impossible with ASM, it can be a routine that loads the image in BG0 and its respective routine to remove it. What I want to do is cinematic with frame sequences. I can not use the diploma hack because I need to make decisions by pressing the A, B and the arrow keys.

I tried this routine: FR - Vs. Bar Personalizable but it has no routine to remove the image so in the end I have to do a warp to refresh the screen and erase the image . Finally after 5
continuous frames the game freezes.

2) Load different dialogs in the presentation of Oak depending on the selected genre. What I want to do is a multi-language effect depending on gender. Example: Boy = Spanish, Girl = English.

Thanks for the help you can give me.

Here is the link to my current project:


Pokémon Terranova

PD: Sorry for my English

for the first one, try this
for your second request, just use the checkgender command and branch accordingly. i believe it returns 0 for male and 1 for female

para tu primer, prueba esta rutina
para tu segundo, usa "checkgender" y haz lo que necesitas. creo que vuelve 0 si eres hombre y 1 si eres mujer

pd: doesn't use bg0. can switch it to any other bg easily tho, edit for text and lay an rbox above or something

mbcn10ww March 31st, 2017 8:43 AM

Quote:

Originally Posted by MWisBest (Post 9605943)
Change Daycare Cost [EM]

There's 2 versions of this routine.

The first is completely configurable (when you compile it), and the changes you need to make to do so are very simple and explained well in the code:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: C0 46 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here.
        @
        @ the original code:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        @ adjust the following code like so:
        @ mov r0, #BASE_PER_LEVEL_COST
        @ mov r1, #PER_LEVEL_COST_MULTIPLIER
        @ mov r2, #BASE_MINIMUM_COST
        @ mov r3, #MINIMUM_COST_MULTIPLIER
        mov r0, #100
        mov r1, #2
        mov r2, #100
        mov r3, #2

        mul r0, r1
        mul r2, r3

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r2 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        ldr r2, .continue_function
        bx r2

.align 2
.dword_806FEBC:
        .word 0x02021DC4
.continue_function:
        .word 0x0806FEA8|1




The second is a little different. Rather than a configurable multiplier, it uses the "XP per step" value as the multiplier, so if you're using this modification to adjust the XP per step amount it will scale the daycare cost accordingly, e.x. 2 XP per step will multiply the normal daycare cost by 2:
Spoiler:
Code:

.text
.align 2
.thumb

@ 0x6FE9E: C0 46 00 48 00 47 XX+1 XX XX XX (original: 64 20 44 43 64 34 05 48 21 1C)

main:
        @ at this point, r4 contains the "levels gained"
        @ when we're finished, r4 will contain the money amnt
        @ r0-r4 are all safe to use here.
        @
        @ the original code:
        @ mov r0, #100
        @ mul r4, r0
        @ add r4, #100

        mov r0, #100
        ldr r1, .xp_per_step
        ldrb r1, [r1]
        mul r0, r1

        mul r4, r0 @ cost = levels gained * per level cost
        add r4, r0 @ cost += minimum cost

        @ the following instructions were chopped off to insert jump to this routine
        ldr r0, .dword_806FEBC
        mov r1, r4

        @ resume execution of the original code
        ldr r2, .continue_function
        bx r2

.align 2
.xp_per_step:
        .word 0x08070AE8
.dword_806FEBC:
        .word 0x02021DC4
.continue_function:
        .word 0x0806FEA8|1






I am planning on porting the stuff I've done for Emerald to Fire Red soon. I just got back into playing the Gen III games a little while ago and decided to start with Emerald for some reason.

Thank you for the reply. You're doing a great work with your routines, I like the way you explain them, it becomes very easy to understand for people who haven't learned ASM (or are learning like me), nice work.

MWisBest March 31st, 2017 10:27 PM

Quote:

Originally Posted by mbcn10ww (Post 9606318)
Thank you for the reply. You're doing a great work with your routines, I like the way you explain them, it becomes very easy to understand for people who haven't learned ASM (or are learning like me), nice work.

Thanks, I appreciate hearing that. My code comments can be a little excessive, but with reverse-engineering stuff I like to make notes of anything relevant in case I revisit it later. Glad it's helpful for you too.

Compumax April 1st, 2017 7:36 PM

Quote:

Originally Posted by BluRose (Post 9606307)
for the first one, try this
for your second request, just use the checkgender command and branch accordingly. i believe it returns 0 for male and 1 for female

pd: doesn't use bg0. can switch it to any other bg easily tho, edit for text and lay an rbox above or something

Thanks for the prompt response!
1) I only need to load images (preferably compressed in LZ77) from a table through the control of a variable, in BG1 or BG2 to be able to use the BG0 text box. I think I can do it from the example you left me, although I assume that it does not work with compressed images. Really thank you very much. I am starting in ASM and would like to learn more. And of course how to erase that image, the rest would do with scripting controlling the variable. Finally what doo to do is a system of choice of the initial pokémon this way:


So I just need 2 routines. One that loads the image in with the following features preferably:

- That depends on the value of a variable (I can do it)
- Use a table (image) (pal) (raw) (I can do it)
- 16 colors (I can do it)
- Image compressed in LZ77 (since I need to insert many images)
- Use BG1 or BG2 to use the BG0 to load text boxes and OBJ

And another one that safely removes the image from said background

2) What I wanted was for the genre to be selected in Oak's presentation, immediately after selecting boy to show a text; And if you select girl it would show another different text. For example:

https://k60.kn3.net/B/C/B/5/0/9/5FC.gif

And here I need to know how to point to the next text depending on the gender selected.

Thank you in advance for the help you can give me.

PD: Gifs are not made since the rom, they were made with sequences of images obviously.

mbcn10ww April 3rd, 2017 9:09 AM

Hi everyone, does anyone knows how to remove the Field Moves options (like Flash, Dig, Fly...) from the Pokémon menu? Because I want to move them to some place but don't know how to make them never show up when I teach the respective move to a Pokémon. Thanks in advance.

MWisBest April 3rd, 2017 5:37 PM

Breeding: Same Offspring = Same Species [EM]

This is kind of a continuation of this post. To put it simply, if you put a Bulbasaur and an Ivysaur in the daycare, they produce fewer eggs than if you paired two Bulbasaurs or two Ivysaurs. This changes it so the Bulbasaur+Ivysaur pair produce the same amount of eggs as a Bulbasaur pair (meaning more than they used to).

Code:

.text
.align 2
.thumb
.thumb_func

@ 0x70D88: 00 48 00 47 XX+1 XX XX XX (original: 20 1C 0B 21 F9 F7 72 FC)

main:
        mov r0, r4  @ move pointer to pokemon to r0
        mov r1, #0xB @ req_species
        ldr r2, .pokemon_getattr_encrypted
        bl x_r2

        @ r0 now contains the species index, which the game *used* to use.
        @ instead, replace it with the offspring index, so different Pokemon
        @ from the same evolution chain are properly recognized as the same species
        @ (e.x. breeding a Charmander and Charizard works as well as 2 Charmanders does)
        ldr r2, .determine_offspring_from_species_index
        bl x_r2

        @ go back to where we came from. (this falls through to the bx r2 below)
        ldr r2, .resume_execution

x_r2:
        bx r2

.align 2
.pokemon_getattr_encrypted:
        .word 0x0806A674|1
.determine_offspring_from_species_index:
        .word 0x08070004|1
.resume_execution:
        .word 0x08070D90|1



NewDenverCity April 3rd, 2017 6:12 PM

Quote:

Originally Posted by tkim (Post 9609111)
I've been trying to study how to decrypt/encrypt a pokemon in party all day and I think the routine would be fairly short and simple but I just don't get how to set up the routine. This page shows a brief explanation and the offsets for decrypting/encrypting: http://www.romhack.me/database/23/fire-red-commonly-used-asm-rom-offsets/ . All I know is that there should be a 'mov r1, 0x#C' (held item) somewhere in the routine. Also are we supposed to decrypt a pokemon before encrypting?

Decrypt and encrypt is a misnomer, it actually should be something like get_attribute and set_attribute or something. To encrypt, or set an attribute, you need to have the pointer to the pokemon structure in r0. r1 is the attribute to set, and r2 must be the pointer to the thing you're setting. Here's an example.
Code:

.thumb

main:
    @get the address in r0
    mov r1, #0x24 @catch level
    mov r2, #0x10
    push {r2}
    mov r2, sp
    bl encrypt
    pop {r2}


This sets the catch level to 16. Now, I don't know why you'd want to set the catch level to something else, but you can do it. You can also just store the thing for r2 in some RAM address but I don't know an open word. And yes, the data must be stored as a word, so using var 0x8009 or whatever probably won't work.

AkameTheBulbasaur April 4th, 2017 11:48 AM

JPAN had as part of his engine a way to make wild Pokemon and Trainers have dynamic levels (you can set a variable to certain values to change the levels to your liking, for example: setting the variable to 0x100 makes Wild/Trainer Pokemon levels match your highest Pokemon.)

However I've noticed that this doesn't seem to work with scripted battles (aka setwildbattle). It just uses the level that you buffered regardless of the routine.

Is there a way to make scripted battles have levels that match your highest level Pokemon?

ghoulslash April 5th, 2017 5:26 AM

edit: figured it out!

MWisBest April 6th, 2017 11:22 AM

Quote:

Originally Posted by DizzyEgg (Post 9165010)
FR has different stat summary screen display from Emerald, so you can't really change offsets. You're in luck though, as I wrote a routine that does that in EM.
LeftStats color change:
Spoiler:

Code:

.text
.thumb
.thumb_func
.align 2

main:
    push {r5}
    sub sp, sp, #0x20
    ldr r0, [r4] @pokemon summary pointer
    add r0, #0xA3 @poke nature
    ldrb r1, [r0]
    ldr r0, nature_stat_table
    lsl r2, r1, #2
    add r2, r1, r2 @multiply by 5
    add r2, r2, r0 @r2 contains nature info
    ldr r3, left_stats_string
    mov r1, sp
    mov r5, #0

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

copy_string:
    ldr r0, displayed_string
    mov r1, sp
    ldr r2, special_f7_string_fct
    bl callvia_r2

return:
    mov r0, r9
    add sp, sp, #0x20
    pop {r5}
    ldr r2, =(0x081C37A8 + 1)
    b callvia_r2

blue_font: @FC 01 07
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #7 @color of the lowered stat
    strb r0, [r1]
    add r1, #1
    bx lr

red_font: @FC 01 05
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #5 @color of the raised stat
    strb r0, [r1]
    add r1, #1
    bx lr

default_font: @FC 01 01
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    strb r0, [r1]
    add r1, #1
    bx lr

callvia_r2:
    bx r2

.align 2

nature_stat_table: .word 0x0831E818
left_stats_string: .word 0x0861CE82
displayed_string: .word 0x02021FC4
special_f7_string_fct: .word 0x081AFC29

@at 0x1C379E insert: 00 00 00 4A 10 47 XX+1 XX XX 08 where XX is the address of the inserted routine



RightStats color change:
Spoiler:

Code:

.text
.thumb
.thumb_func
.align 2

main:
    push {r5}
    sub sp, sp, #0x20
    ldr r0, [r4] @pokemon summary pointer
    add r0, #0xA3 @poke nature
    ldrb r1, [r0]
    ldr r0, nature_stat_table
    lsl r2, r1, #2
    add r2, r1, r2 @multiply by 5
    add r2, r2, r0 @r2 contains nature info
    add r2, #3 @r2 contains beg of spatk stat
    ldr r3, right_stats_string
    mov r1, sp
    mov r5, #0

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
    add r3, #3
    add r1, #3

return:
    ldr r0, displayed_string
    mov r1, sp
    ldr r2, special_f7_string_fct
    bl callvia_r2
    add sp, sp, #0x20
    pop {r5}
    ldr r2, =(0x081C386C + 1)
    bx r2

blue_font: @FC 01 07
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #7 @color of the lowered stat
    strb r0, [r1]
    add r1, #1
    bx lr

red_font: @FC 01 05
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    mov r0, #5 @color of the raised stat
    strb r0, [r1]
    add r1, #1
    bx lr

default_font: @FC 01 01
    mov r0, #0xFC
    strb r0, [r1]
    add r1, #1
    mov r0, #1
    strb r0, [r1]
    add r1, #1
    strb r0, [r1]
    add r1, #1
    bx lr

callvia_r2:
    bx r2   

.align 2

nature_stat_table: .word 0x0831E818
right_stats_string: .word 0x0861CE8E
displayed_string: .word 0x02021FC4
special_f7_string_fct: .word 0x081AFC29

@at 0x1C3864 insert 00 4A 10 47 XX+1 XX XX 08



Image:

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



DizzyEgg April 7th, 2017 1:10 AM

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



Good job :). I was pretty lazy back then and just duplicated the font functions :D.

Seems you're quite proficient in ASM. Wonder if you use IDE?

MWisBest April 7th, 2017 7:04 AM

Quote:

Originally Posted by DizzyEgg (Post 9611696)
Good job :). I was pretty lazy back then and just duplicated the font functions :D.

Seems you're quite proficient in ASM. Wonder if you use IDE?

Thanks! Did you mean to ask if I use IDA? If so, yes. Been using it for years now, mainly with Android OS development (patching old closed-source libs to work on newer Android versions for example). This is my first time writing any substantial assembly though, just so happens that reading assembly the past few years translated well into writing it.

In a way, ARM assembly is really not that different from programming in high-level languages like C. I just look at all the opcodes like functions, registers are variables, etc. Just takes more steps to do a particular task.

I've also made use of the no$gba debugger, that's how I find tricks to save instructions, like r0 containing a return address and the usage of r9 to determine which code to run for the stat coloring merger.

Sorry, I tend to ramble on and talk a lot. :p

DizzyEgg April 7th, 2017 8:43 AM

Quote:

Originally Posted by MWisBest (Post 9611902)
Thanks! Did you mean to ask if I use IDA? If so, yes. Been using it for years now, mainly with Android OS development (patching old closed-source libs to work on newer Android versions for example). This is my first time writing any substantial assembly though, just so happens that reading assembly the past few years translated well into writing it.

In a way, ARM assembly is really not that different from programming in high-level languages like C. I just look at all the opcodes like functions, registers are variables, etc. Just takes more steps to do a particular task.

I've also made use of the no$gba debugger, that's how I find tricks to save instructions, like r0 containing a return address and the usage of r9 to determine which code to run for the stat coloring merger.

Sorry, I tend to ramble on and talk a lot. :p

Yeah I meant IDA, lol. I asked, because I've got an up-to-date Emerald IDB. I know Touched has one in its signature, but it has less stuff labeled. Here's the link: https://www.dropbox.com/s/mksltpeelzj1tmi/BPEE_updated2.idb?dl=0

And yeah I use no$gba debugger too, a pretty handy tool.

mbcn10ww April 17th, 2017 7:57 AM

Quote:

Originally Posted by MWisBest (Post 9604877)
Made another improvement to the reusable pokeballs: safari balls can now be reused as well!

Code:

.text
.align 2
.thumb

@ FE3AA - 00 21
@ 56818 - 00 48 00 47 XX+1 XX XX XX
@ 3F008 - 02 E0 C0 46 C0 46 C0 46 ! NEW
@ Optional: change initial safari ball count?: FC0E6 - XX 20, XX = initial count

main:
        @ if safari ball counter is not 0, then that's what we need to delete
        ldr r1, .safari_ball_count
        ldrb r0, [r1]
        cmp r0, #0x0
        bne delete_safari_ball

        @ ...otherwise, delete the last used item (if it's a pokeball)
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls delete_ball_in_bag
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq delete_ball_in_bag

        b finish

delete_safari_ball:
        @ r0 already contains current safari ball count, and
        @ r1 already contains safari ball count memory address
        sub r0, #1
        strb r0, [r1]
        b finish

delete_ball_in_bag:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bl x_r2
        b finish

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r2}
x_r2:
        bx r2

.align 2
.last_used_item:
        .word 0x0203CE7C
.bag_remove_item:
        .word 0x080D6AA4|1
.safari_ball_count:
        .word 0x0203A04C



Ported to Fire Red

Code:

.text
.align 2
.thumb

@ 0xA1E30 - 00 21
@ 0x2D924 - 00 48 00 47 XX+1 XX XX 08
@ 0x16AD8 - 02 E0 C0 46 C0 46 C0 46
@ Optional: change initial safari ball count?: 0xA0ED2 - XX 20, XX = initial count

main:
        @ if safari ball counter is not 0, then that's what we need to delete
        ldr r1, .safari_ball_count
        ldrb r0, [r1]
        cmp r0, #0x0
        bne delete_safari_ball

        @ ...otherwise, delete the last used item (if it's a pokeball)
        ldr r0, .last_used_item
        ldrh r0, [r0]
        @ checks that the item id is premier ball or lower
        cmp r0, #0xC
        bls delete_ball_in_bag
        @ support for custom pokeballs can be added like so:
        @ cmp r0, #CUSTOM_BALL_ID
        @ beq delete_ball_in_bag

        b finish

delete_safari_ball:
        @ r0 already contains current safari ball count, and
        @ r1 already contains safari ball count memory address
        sub r0, #1
        strb r0, [r1]
        b finish

delete_ball_in_bag:
        @ r0 already contains last_used_item.
        mov r1, #1
        ldr r2, .bag_remove_item
        bl x_r2
        b finish

x_r2:
        bx r2

finish:
        mov r9, r4
        mov r10, r5
        pop {r4-r7}
        pop {r0}
        bx r0

.align 2
.last_used_item:
        .word 0x0203AD30
.bag_remove_item:
        .word 0x0809A1D8|1
.safari_ball_count:
        .word 0x02039994



ASDBUDDY April 18th, 2017 8:47 AM

Quote:

Originally Posted by FBI (Post 8520099)
I think he wants to set a default name while skipping the intro. If you skip the intro via ASM, the default name is left as 0s aka blank.

Setting a static name to the player



Well, this is beyond simple, lol. I'll keep my post the same format though, because first post :3

How to insert:

Before you begin to insert the routine, there are a few steps. Firstly player names are limited to 8 characters with the eighth character = 0xFF.
Convert the static name you want from ascii to hex. For OP, he wanted Jesse and James which convert into:
C4 D9 E7 E7 D9 FF FF FF - Jesse
C4 D5 E1 D9 E7 FF FF FF -James
Note that if all eight bytes don't get used, you should pad them with "FF" in your hex editor.
Now insert the 8 byte names into some free space in your ROM via hex editor and write down the pointers.

Now copy the following routine into a text editor:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r2, lr}
        ldr r0, .Name
        ldr r0, [r0]
        add r1, r0, #0x1
        ldrb r1, [r1]
        cmp r1, #0x1 @girl
        beq Girl
        ldr r1, .CustomNameBoy
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

Girl:
        ldr r1, .CustomNameGirl
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

.align 2
.Name:
        .word 0x300500C

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name




You'll notice that I have the lines:
Code:

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name


Change the [email protected] text to 0x[offset you inserted]. No need to add one.
After you've done that compile and insert into free space.

Usage:
You must callasm to the routine, and depending on the Player's gender it will set their name. To have their name inserted before the player starts playing the game, create a level script which calls this routine. If you don't know how, ask in a relevant thread (not here).

Hi, well I did exactly what you said but now my gba file just shows a blank screen when loaded into the emulator. What should I do?

easyaspi314 April 19th, 2017 7:02 AM

Hey, IDK if it is possible, but could it be made so the battle text auto-advances when in battle (like Gen 4)?

So, instead of being required to press A during certain parts (example: challenge, faint, disable, level up, etc), after 1 second, the next line will load. But you can interrupt it with A as well

I can make it automatically skip by editing the hex, but it does it immediately.

linobigatti April 20th, 2017 5:13 AM

i can manipulate the mistery gifts in FR? how?

DarkPsychic April 20th, 2017 11:47 PM

Quote:

Originally Posted by FBI (Post 8517719)

Pokemon Storage (outside the PC)



Basically, in it's current state, this is effectively a storage system. It stores Pokemon and can be interacted with by the player to withdraw or deposit Pokemon. It's standalone from the PC storage system and is also much smaller (I've limited it to 6, but it can go upto 47). Some things that you will be able to do with this routine (and conjunction with some smaller ones) include:
- Extra Pokemon storage, you can possibly get a little over 1 box worth
- Flash back battles (complete swap between stored Pokemon and party Pokemon with capabilities to swap back)
- Carry a party of greater than 6 Pokemon (you can use the 2nd party for HM slaves, or whatever)
- Trade evolver guy! He will take your Pokemon and then when you come back it can be evolved! (silent evolution ftw!)
- Separate Daycare holding larger amount of Pokemon at once

I've tested it thoroughly and there doesn't seem to be any problems. I will be adding more and more features into this because I believe that it has the potential to become a very useful feature.
Currently planning to add:
- Party swap completely all in one go (this will actually be in the very near future..maybe today even :P)
- Partial swapping (believe it or not, this is hard because there's no graphical support)
- Suggest me more :D

How to insert:

Compile into free space the following routine:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
    push {r0, r4, lr}
    ldr r0, .FROM
    ldr r1, [r0]
    cmp r1, #0x0 @party
    beq addParty

addStorage:
    ldr r0, .STORAGE
    sub r0, r0, #0x1
    ldrb r1, [r0]
    cmp r1, #0x6 @limit of storage. Change depending on your space situation
    beq end
    add r0, r0, #0x1
    mov r2, #0x50
    cmp r1, #0x0
    beq skipline
    sub r1, r1, #0x1
    mul r1, r1, r2
    add r0, r0, r1 @destination
    ldr r1, =(0x20370C0)
    ldrb r1, [r1]
    ldr r2, .PARTY
    mov r3, #0x64
    mul r1, r1, r3
    add r1, r1, r2 @source
    mov r2, #0x50 @size
    ldr r3, =(0x8040B08 +1) @func
    bl linker
    @need to fix up Player's party slots
    ldr r1, =(0x20370C0)
    ldrb r1, [r1]
    cmp r1, #0x5
    beq writeLastZero
    mov r2, #0x5
    sub r2, r2, r1
    mov r3, #0x64
    mul r2, r2, r3 @size
    ldr r0, .PARTY
    mul r1, r1, r3
    add r0, r0, r1 @dest
    add r3, r3, r0
    mov r1, r3      @src
    ldr r3, =(0x8040B08 +1) @func
    bl linker

writeLastZero:
    ldr r0, =(0x2024478)
    mov r1, #0x0
    mov r2, #0x64
    ldr r3, =(0x81E5ED8 +1)
    bl linker

correctCounters:
    ldr r0, .STORAGE
    sub r0, r0, #0x1
    ldrb r2, [r0]  @pks in storage counter
    ldr r1, =(0x2024029)
    ldrb r3, [r1] @pks in party
    add r2, r2, #0x1
    strb r2, [r0]
    sub r3, r3, #0x1
    strb r3, [r1]
    b end

addParty:
    ldr r0, =(0x2024029)
    ldrb r0, [r0]
    cmp r0, #0x6
    beq end
    ldr r1, .PARTY
    mov r2, #0x64
    mul r0, r0, r2
    add r0, r0, r1 @destination
    mov r4, r0
    ldr r3, .STORAGE
    ldr r1, =(0x20370C0) @var 0x8004 determines which slot of storage to take from
    ldrb r1, [r1]
    mov r2, #0x50 @size
    mul r1, r1, r2
    add r1, r1, r3 @source
    ldr r3, =(0x8040B08 +1) @func
    bl linker
    @update stats
    mov r0, r4
    ldr r3, =(0x803E47C +1)
    bl linker
    @adjust the storage
    ldr r0, =(0x20370C0)
    ldrb r0, [r0]
    cmp r0, #0x5 @storage limit minus 1
    beq writeZero
    mov r2, #0x5
    sub r2, r2, r0
    mov r3, #0x50
    mul r2, r2, r3 @size
    ldr r1, .STORAGE
    mul r0, r0, r3
    add r0, r0, r1 @dest
    add r3, r3, r0
    mov r1, r3      @src
    ldr r3, =(0x8040B08 +1) @func
    bl linker

writeZero:
    ldr r0, .STORAGE
    mov r1, #0xC8
    lsl r1, r1, #0x1
    add r0, r0, r1
    mov r1, #0x0
    mov r2, #0x50
    ldr r3, =(0x81E5ED8 +1)
    bl linker

updateCounters:
    ldr r0, .STORAGE
    sub r0, r0, #0x1
    ldrb r2, [r0]
    ldr r1, =(0x2024029)
    ldrb r3, [r1]
    sub r2, r2, #0x1
    strb r2, [r0]
    add r3, r3, #0x1
    strb r3, [r1]

end:
    pop {r0-r4, pc}   

linker:
    bx r3   

.align 2

.FROM:
    .word 0x20270B8 + (0x8000 *2)

.STORAGE:
    .word 0x203C001 @storage location

.PARTY:
    .word 0x2024284 @player's party




Here's a compiled version:
Code:

11 B5 38 48 01 68 00 29 32 D0 37 48 01 38 01 78 06 29 65 D0 01 30 50 22 51 43 40 18 34 49 09 78 32 4A 64 23 59 43 89 18 50 22 32 4B 00 F0 59 F8 2F 49 09 78 05 29 0B D0 05 22 52 1A 64 23 5A 43 2A 48 59 43 40 18 1B 18 19 1C 2A 4B 00 F0 49 F8 29 48 00 21 64 22 29 4B 00 F0 43 F8 22 48 01 38 02 78 27 49 0B 78 01 32 02 70 01 3B 0B 70 37 E0 23 48 00 78 06 28 33 D0 1C 49 64 22 50 43 40 18 04 1C 19 4B 1A 49 09 78 50 22 51 43 C9 18 19 4B 00 F0 27 F8 20 1C 1B 4B 00 F0 23 F8 14 48 00 78 05 28 0B D0 05 22 12 1A 50 23 5A 43 0E 49 58 43 40 18 1B 18 19 1C 0F 4B 00 F0 13 F8 0A 48 C8 21 49 00 40 18 00 21 50 22 0C 4B 00 F0 0A F8 06 48 01 38 02 78 0A 49 0B 78 01 3A 02 70 01 33 0B 70 1F BD 18 47 B8 70 03 02 01 C0 03 02 84 42 02 02 C0 70 03 02 09 0B 04 08 78 44 02 02 D9 5E 1E 08 29 40 02 02 7D E4 03 08


Usage:

The routine itself manages party storage and storage extraction. What you need to do is determine which one it performs.
If you want to remove a Pokemon from the party and into storage, setvar 0x8000 anything but zero
if you want to remove a Pokemon from storage, setvar 0x8000 0x0
Which variable you used can be changed, as always, by editing the pointer at the bottom of the routine.
The next thing is variable 0x8004. I use this variable to determine the slot of extraction for both the Party and the Storage system.
If I wanted to take the 3rd Pokemon in the party and put it in storage:
setvar 0x8004 0x2
setvar 0x8000 0x1
callasm 0x[routine] +1

The reason for this is to support easy use of special 0x9F. Though you can use copyvar, I suppose.

Finally, the routine writes to RAM a counter, which keeps track of how many Pokemon are in the storage.
This is written at 0x203C000, and can be retrieved by using the "copybyte" scripting command. For example:
copybyte 0x20370D0 0x203C000 'puts the storage counter into variable 0x800D (lastresult).

I tried to keep it simple, and do the work inside the routine, hopefully that paid off.
Here's a very poor sample script. Poor because it handles all the cases, but it doesn't display the system's full potential :P

Spoiler:

PKSV script.
Code:

#dyn 0x740000
#org @start
lock
faceplayer
copybyte 0x20370D0 0x203C000 ' storage count into last result
compare LASTRESULT 0x0
if == jump @putOnly
msgbox @add
callstd MSG_YESNO 'want to take?
compare LASTRESULT 0x1
if == jump @addParty
jump @putOnly

#org @putOnly
countpokemon
copyvar 0x8000 0x800D
compare 0x8000 0x1
if <= jump @greetings
msgbox @put
callstd MSG_YESNO 'want to put?
compare LASTRESULT 0x1
if == jump @addStorage
msgbox @exit
callstd MSG_NORMAL
release
end

#org @addStorage
setvar 0x8000 0x1
special 0x9F
waitspecial
countpokemon
compare LASTRESULT 0x8004
if < jump @noSelection
callasm 0x[routine +1]
msgbox @gave
callstd MSG_NORMAL
release
end

#org @addParty
setvar 0x8000 0x0
countpokemon
compare LASTRESULT 0x6
if == jump @fullP
msgbox @store
callstd MSG_NORMAL
setvar 0x8004 0x0 'gotta rework this to work a better way
callasm 0x[routine +1]
fanfare 0x101
msgbox @complete
callstd MSG_NORMAL
release
end

#org @greetings
msgbox @hello
callstd MSG_NORMAL
release
end

#org @fullP
msgbox @full
callstd MSG_NORMAL
release
end

#org @noSelection
msgbox @exit
callstd MSG_NORMAL
release
end

#org @full
= You're party is full!

#org @hello
= Hi, I can't do anything\nyour slots are full or empty\lor mine are full while yours are\lfull[.]

#org @complete
= I gave it back.

#org @store
= Alright, I'll give it to you.

#org @gave
= Thanks for giving me this.

#org @exit
= Alright, next time then.

#org @add
= Want your Pokemon back?

#org @put
= Want to give me a pokemon?




That's it for now. Keep an eye out for "addons" for this routine in the future :)
Sorry for the double post. I like seperate posts for my routines to keep the first post's links neat :x


So for anyone who has used this they know that only the Pre-Compiled version works, and the routine given does not compile to match either and don't work at all for that matter.

Also the Pre-Compiled version does work but has a bug from using Special 0x9F(Choose Pokemon from party).
If the player says yes to storing a Pokemon then decides to either press "B" or "Cancel" then the game will jump to the overworld view, glitch out and freeze with a Black screen.

Now I worked on this all day and was able to rebuild the Pre-Compiled routine so we could actually have the working source.
FBI's - Pre-Compiled Storage System - Disassembled/Rebuilt Routine
Code:
Code:

.text
.align 2
.thumb
.thumb_func

main:
push {r0, r4, lr}
    ldr r0, .FROM
    ldr r1,[r0]
    cmp r1, #0x0              @party
    beq addParty

addStorage:
    ldr r0, .STORAGE
    sub r0, #0x1
    ldrb r1, [r0]
    cmp r1, #0x6              @limit of storage. Change depending on your space situation
    beq end
    add r0, #0x1
    mov r2, #0x50
    mul r1, r2
    add r0, r0, r1            @destination
    ldr r1, =(0x20370C0)      @ 2b Var_8004
    ldrb r1, [r1]
    ldr r2, .PARTY
    mov r3, #0x64
    mul r1, r3
    add r1, r1, r2            @source
    mov r2, #0x50              @size
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker
    ldr r1, =(0x20370C0)      @need to fix up Player's party slots @ 2b Var_8004
    ldrb r1, [r1]
    cmp r1, #0x5
    beq writeLastZero
    mov r2, #0x5
    sub r2, r2, r1
    mov r3, #0x64
    mul r2, r3                @size
    ldr r0, .PARTY
    mul r1, r3
    add r0, r0, r1            @dest
    add r3, r3, r0
    mov r1, r3                @src
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker

writeLastZero:
    ldr r0, =(0x2024478)      @ 100b    Party Pokemon 6
    mov r1, #0x0
    mov r2, #0x64
    ldr r3, =(0x81E5ED9)      @memset  'void __fastcall memset(char *dst, char pattern, int size)'
    bl linker

correctCounters:
    ldr r0, .STORAGE
    sub r0, #0x1
    ldrb r2, [r0]              @pks in storage counter
    ldr r1, =(0x2024029)      @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
    ldrb r3, [r1]              @pks in party
    add r2, #0x1
    strb r2,[r0]
    sub r3, #0x1
    strb r3, [r1]
    b end

addParty:
    ldr r0, =(0x2024029)      @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
    ldrb r0, [r0]
    cmp r0, #0x6
    beq end
    ldr r1, .PARTY
    mov r2, #0x64
    mul r0, r2
    add r0, r0, r1            @destination
    mov r4, r0
    ldr r3, .STORAGE
    ldr r1, =(0x20370C0)      @'var 0x8004 determines which slot of storage to take from'
    ldrb r1, [r1]
    mov r2, #0x50              @size
    mul r1, r2
    add r1, r1, r3            @source
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker
    mov r0, r4                @update stats
    ldr r3, =(0x803E47D)      @pokemon_calc_effective_stats
    bl linker
    ldr r0, =(0x20370C0)      @adjust the storage  @ 2b Var_8004
    ldrb r0, [r0]
    cmp r0, #0x5              @storage limit minus 1
    beq writeZero
    mov r2, #0x5
    sub r2, r2, r0
    mov r3, #0x50
    mul r2, r3                @size
    ldr r1, .STORAGE
    mul r0, r3
    add r0, r0, r1            @dest
    add r3, r3, r0
    mov r1, r3                @src
    ldr r3, =(0x8040B09)      @memcpy_pkm 'void __fastcall memcpy_pkm(void *dst, void *src, unsigned int size)'
    bl linker

writeZero:
    ldr r0, .STORAGE
    mov r1, #0xC8
    lsl r1, r1, #0x1
    add r0, r0, r1
    mov r1, #0x0
    mov r2, #0x50
    ldr r3, =(0x81E5ED9)      @memset  'void __fastcall memset(char *dst, char pattern, int size)'
    bl linker

updateCounters:
    ldr r0, .STORAGE
    sub r0, #0x1
    ldrb r2, [r0]
    ldr r1, =(0x2024029)      @ 1b    Repeattrainerbattle: Unknown. Loaded if battle type is 9.
    ldrb r3, [r1]
    sub r2, #0x1
    strb r2,[r0]
    add r3, #0x1
    strb r3, [r1]

end:
    pop {r0-r4, pc}

linker:
    bx r3

.align 2

.FROM:
    .word 0x20370B8            @var_8000

.STORAGE:
    .word 0x203C001            @storage location

.PARTY:
    .word 0x2024284            @player's party


And to go along with that is the XSE script.
Code:
Code:

#dynamic 0xFreeSpaceToStartFrom

//---------------
#org @start
lock
faceplayer
copybyte 0x20370D0 0x203C000
compare 0x800D 0x0
if 0x1 goto @snippet1
msgbox @string1 0x5 //"Want your Pokemon back?"
compare 0x800D 0x1
if 0x1 goto @snippet2
goto @snippet1

//---------------
#org @snippet1
countpokemon
copyvar 0x8000 0x800D
compare 0x8000 0x1
if 0x3 goto @snippet3
msgbox @string2 0x5 //"Want to give me a pokemon?"
compare 0x800D 0x1
if 0x1 goto @snippet4
msgbox @string3 0x6 //"Alright, next time then."
release
end

//---------------
#org @snippet2
setvar 0x8000 0x0
countpokemon
compare 0x800D 0x6
if 0x1 goto @snippet5
msgbox @string4 0x6 //"Alright, I'll give it to you."
setvar 0x8004 0x0
callasm 0xWhereYouPutYourTheRoutine+1
fanfare 0x101
msgbox @string5 0x6 //"I gave it back."
release
end

//---------------
#org @snippet3
msgbox @string6 0x6 //"Hi, I can't do anything\nyour slot..."
release
end

//---------------
#org @snippet4
setvar 0x8000 0x1
special 0x9F
waitstate
lockall
compare 0x8004 0x7
if 0x1 goto @snippet6
countpokemon
compare 0x800D 0x1
if 0x3 goto @snippet6
callasm 0xWhereYouPutYourTheRoutine+1
msgbox @string7 0x6 //"Thanks for giving me this."
release
end

//---------------
#org @snippet5
msgbox @string8 0x6 //"You're party is full!"
release
end

//---------------
#org @snippet6
msgbox @string3 0x6 //"Alright, next time then."
release
end

//---------
// Strings
//---------
#org @string1
= Want your Pokemon back?

#org @string2
= Want to give me a pokemon?

#org @string3
= Alright, next time then.

#org @string4
= Alright, I'll give it to you.

#org @string5
= I gave it back.

#org @string6
= Hi, I can't do anything\nyour slots are full or empty\lor mine are full while yours are\lfull[.]

#org @string7
= Thanks for giving me this.

#org @string8
= You're party is full!


Edit the orange text before compiling.


Hope this helps anyone.
When I get the time I will see what I can do about fixing the bug as well.


Edit_Two:
Found the bug!
Special 0x9F lets you choose any Pokemon as well as Eggs.
And,
Special 0xBC lets you choose any Pokemon beside Eggs(used for daycare)
When pressing B var 0x8004 is set to 0x07 so I simply added a compare to fix the script.

mbcn10ww April 24th, 2017 12:15 PM

Quote:

Originally Posted by FBI (Post 8520099)
I think he wants to set a default name while skipping the intro. If you skip the intro via ASM, the default name is left as 0s aka blank.

Setting a static name to the player



Well, this is beyond simple, lol. I'll keep my post the same format though, because first post :3

How to insert:

Before you begin to insert the routine, there are a few steps. Firstly player names are limited to 8 characters with the eighth character = 0xFF.
Convert the static name you want from ascii to hex. For OP, he wanted Jesse and James which convert into:
C4 D9 E7 E7 D9 FF FF FF - Jesse
C4 D5 E1 D9 E7 FF FF FF -James
Note that if all eight bytes don't get used, you should pad them with "FF" in your hex editor.
Now insert the 8 byte names into some free space in your ROM via hex editor and write down the pointers.

Now copy the following routine into a text editor:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r2, lr}
        ldr r0, .Name
        ldr r0, [r0]
        add r1, r0, #0x1
        ldrb r1, [r1]
        cmp r1, #0x1 @girl
        beq Girl
        ldr r1, .CustomNameBoy
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

Girl:
        ldr r1, .CustomNameGirl
        ldr r2, [r1]
        add r1, r1, #0x4
        ldr r1, [r1]
        str r2, [r0]
        add r0, r0, #0x4
        str r1, [r0]
        pop {r0-r2, pc}

.align 2
.Name:
        .word 0x300500C

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name




You'll notice that I have the lines:
Code:

.CustomNameBoy:
        .word [email protected] to boy name

.CustomNameGirl:
        .word [email protected] to girl name


Change the [email protected] text to 0x[offset you inserted]. No need to add one.
After you've done that compile and insert into free space.

Usage:
You must callasm to the routine, and depending on the Player's gender it will set their name. To have their name inserted before the player starts playing the game, create a level script which calls this routine. If you don't know how, ask in a relevant thread (not here).

It works, but the female player name becomes the same as the male.

Wesley FG April 25th, 2017 3:38 PM

Quote:

Originally Posted by DoesntKnowHowToPlay (Post 9043968)
I've noticed significant demand for working Dawn Stone evolutions, specifically ones that require the mon to be a specific gender. My bad if this is already posted somewhere but here y'all go:

Code:

.org 0x4318e
lsl r0, r0, #0x0
ldr r2, .MethodAddr
bx r2

.MethodAddr: .word 0x085B2521 #UPDATE THIS TO MAIN FUNCTION OFFSET+1

.org 0x5B2520 #UPDATE THIS TO MOST CONVENIENT FREE SPACE IN YOUR HACK
cmp r0, #0x7
beq StandardStone
cmp r0, #0x14 #UPDATE THIS
beq MaleStone
cmp r0, #0x15 #UPDATE THIS
beq FemaleStone
b NoEvo

MaleStone:
push {r1-r3}
mov r0, r7
mov r1, r8
ldr r1, [r1, #0x0]
bl DetermineGender
pop {r1-r3}
cmp r0, #0x0
beq StandardStone
b NoEvo

FemaleStone:
push {r1-r3}
mov r0, r7
mov r1, r8
ldr r1, [r1, #0x0]
bl DetermineGender
pop {r1-r3}
cmp r0, #0xFE
beq StandardStone
b NoEvo

StandardStone:
ldrh r0, [r1, #0x2]
cmp r0, r9
beq Finish

NoEvo:
ldr r2, .NoEvoReturn
bx r2

DetermineGender:
ldr r2, .DetermineGenderFunc
bx r2

Finish:
ldr r2, .EvoReturn
bx r2

.NoEvoReturn: .word 0x08043199
.EvoReturn: .word 0x0804317d
.DetermineGenderFunc: .word 0x0803f78d


Change the values in the lines marked UPDATE THIS to the indexes of male stone evos and female stone evos. Leave their entries blank in the general evolution table; stone evolutions function differently from level-up evolutions.

the value of "indexes of male stone" is the item value ?

will have two dawn stone, one work in male and one work in female, it is correct ?

i not understand it well

mbcn10ww April 25th, 2017 5:13 PM

Quote:

Originally Posted by Wesley FG (Post 9628943)
the value of "indexes of male stone" is the item value ?

will have two dawn stone, one work in male and one work in female, it is correct ?

i not understand it well

the indexes are your Evolution indexes, one for male stone evo and one for female stone evo, the item index will only be chosen on your editor (G3HS, G3T...)

tkim April 29th, 2017 9:57 AM

Quote:

Originally Posted by FBI (Post 8536952)
In response to this:

Setting a random Secret and Trainer ID



Requires the insertion of Random Number generator
So apparently TID isn't set if you skip the intro, and I'm sure SID is probably also not set. The following routine will randomize them for you!


To insert:

There's some orange text here, set it to be the pointer to where you inserted the random number generator routine +1 (keep the 0x8 prefix, but don't reverse the pointer).

After you've fixed the pointer, compile and insert into free space.

Spoiler:

[code]
.text
.align 2
.thumb
.thumb_func

main:
push (r0-r3, lr}
ldr r0, .random
ldr r1, =(0x20370B8) @generate first half of ID
mov r2, #0xFF
lsl r2, r2, #0x8
add r2, r2, #0xFF
strh r2, [r1]
bl linker
mov r3, r0
ldr r1, =(0x20370B8) @generate second half of ID
mov r2, #0xFF
lsl r2, r2, #0x8
add r2, r2, #0xFF
strh r2, [r1]
push {r3}
bl linker
pop {r3}
lsl r0, r0, #0x10
lsr r3, r3, #0x10
orr r3, r3, r0
ldr r0, =(0x300500C)
ldr r0, [r0]
add r0, r0, #0xA
ldr r1, =(0x20370BA)
ldrb r1, [r1]
add r0, r0, r1
strh r3, [r0] @set ID
cmp r1, #0x1
bne setRam
pop {r0-r3, pc}

setRam:
ldr r1, =(0x2020000) @set RAM Pointer to TID
strh r3, [r1]
pop {r0-r3, pc}


linker:
bx r0


.align 2

.random:
.word 0x8[random]
[code]



Usage:

setvar 0x8001 0x0
callasm 0x[this routine +1]
setvar 0x8001 0x2
callasm 0x[this routine +1]

Call it twice like I have, setting var 0x8001 to 0x0 and 0x2 respectively, it will generate a random PID and SID.

Heyo, I can't seem to compile this. May you fix it please?

Spherical Ice April 30th, 2017 2:14 PM

[FR] Complimentary Premier Ball for purchases of over 9 Poké Balls



Ever since RSE, the Poké Mart clerk has thrown in a bonus Premier Ball when the player purchases at least 10 Poké Balls. This feature was absent from FireRed, however, presumably for accuracy reasons for the remake factor of the game. To implement this feature, simply assemble the following routine and place a pointer (+1) at x9BF64.

Code:

.thumb @ pointer+1 at 0809BF64

main:
    push {r4,r5,lr}
    lsl r0, r0, #0x18
    lsr r4, r0, #0x18
    lsl r0, r4, #2
    add r0, r0, r4
    lsl r0, r0, #3
    ldr r1, =(0x03005098) @ tasks.args
    add r5, r0, r1
    ldr r0, =(0x030030F0) @ super
    ldrh r1, [r0, #0x2E]
    mov r0, #0x3
    and r0, r1
    cmp r0, #0
    beq end

continue:
    mov r0, #5
    ldr r3, =(0x080722CC|1) @ audio_play
    bl call_via_r3
    mov r1, #0xA
    ldrh r0, [r5, r1]
    cmp r0, #0x4 @ Poké Ball item ID
    bne no_premier_ball
    mov r1, #2
    ldrh r0, [r5, r1]
    cmp r0, #0x9 @ Maximum quantity of Poké Balls to not qualify for a Premier Ball
    ble no_premier_ball
    mov r0, #0xC @ Premier Ball item ID
    mov r1, #1 @ Quantity to give
    ldr r3, =(0x0809A084|1) @ bag_add_item
    bl call_via_r3
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    cmp r0, #1
    bne no_premier_ball
    ldr r1, =(0x08XXXXXX) @ Address of string: "I'll throw in a PREMIER BALL, too.[FC][09]"
    ldr r2, =(0x0809BF98|1)
    mov r0, r4
    ldr r3, =(0x0813F75C|1)
    bl call_via_r3
    b end

no_premier_ball:
    mov r0, r4
    ldr r3, =(0x0809BF98|1)
    bl call_via_r3

end:
    pop {r4,r5}
    pop {r0}
    bx r0

call_via_r3:
    bx r3


The routine specifies an address for the string "I'll throw in a PREMIER BALL, too." as 0x08XXXXXX. Replace this with the address at which you insert the following bytes:
Code:

C3 B4 E0 E0 00 E8 DC E6 E3 EB 00 DD E2 00 D5 00 CA CC BF C7 C3 BF CC 00 BC BB C6 C6 B8 00 E8 E3 E3 AD FC 09 FF


The same string, but with "PREMIER BALL" in title case (i.e. "Premier Ball"), has the following bytes:
Code:

C3 B4 E0 E0 00 E8 DC E6 E3 EB 00 DD E2 00 D5 00 CA E6 D9 E1 DD D9 E6 00 BC D5 E0 E0 B8 00 E8 E3 E3 AD FC 09 FF


As always with strings, it's recommended you place a byte after the FF delimiter at the end of the string to prevent tools which read FF bytes as free space from overwriting the string's delimiter and making the string bug.

Wesley FG May 5th, 2017 2:15 PM

Someone can convert this asm to EM
is a screen that display IV and EV screens is very usefull
https://www.pokecommunity.com/showpost.php?p=9229108&postcount=919
https://i869.photobucket.com/albums/ab256/jiangzhengwenjz/q_zpshnquzant.gif

tkim May 7th, 2017 9:09 PM

REQUEST for FR:

A 'givepokemon' routine that allows the user to set custom OT name and TID/SID. (useful for creating legal event pokemon)

tkim May 8th, 2017 2:43 PM

Quote:

Originally Posted by FBI (Post 8536952)
In response to this:

Setting a random Secret and Trainer ID



Requires the insertion of Random Number generator
So apparently TID isn't set if you skip the intro, and I'm sure SID is probably also not set. The following routine will randomize them for you!


To insert:

There's some orange text here, set it to be the pointer to where you inserted the random number generator routine +1 (keep the 0x8 prefix, but don't reverse the pointer).

After you've fixed the pointer, compile and insert into free space.

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func   

main:
    push (r0-r3, lr}
    ldr r0, .random
    ldr r1, =(0x20370B8) @generate first half of ID
    mov r2, #0xFF
    lsl r2, r2, #0x8
    add r2, r2, #0xFF
    strh r2, [r1]
    bl linker
    mov r3, r0
    ldr r1, =(0x20370B8) @generate second half of ID
    mov r2, #0xFF
    lsl r2, r2, #0x8
    add r2, r2, #0xFF
    strh r2, [r1]
    push {r3}
    bl linker
    pop {r3}
    lsl r0, r0, #0x10
    lsr r3, r3, #0x10
    orr r3, r3, r0
    ldr r0, =(0x300500C)
    ldr r0, [r0]
    add r0, r0, #0xA
    ldr r1, =(0x20370BA)
    ldrb r1, [r1]
    add r0, r0, r1
    strh r3, [r0] @set ID
    cmp r1, #0x1
    bne setRam
    pop {r0-r3, pc}

setRam:
    ldr r1, =(0x2020000) @set RAM Pointer to TID
    strh r3, [r1]
    pop {r0-r3, pc}

linker:
    bx r0

.align 2

.random:
    .word 0x8[random]





Usage:

setvar 0x8001 0x0
callasm 0x[this routine +1]
setvar 0x8001 0x2
callasm 0x[this routine +1]

Call it twice like I have, setting var 0x8001 to 0x0 and 0x2 respectively, it will generate a random PID and SID.

Can anyone confirm that this routine works? My game freezes when using this routine. His random number routine has been inserted. I changed the highlighted orange text from
Code:

.word 0x8[random]


to
Code:

.word 0x8800001



NewDenverCity May 9th, 2017 12:12 PM

Quote:

Originally Posted by tkim (Post 9641016)
Can anyone confirm that this routine works? My game freezes when using this routine. His random number routine has been inserted. I changed the highlighted orange text from
Code:

.word 0x8[random]


to
Code:

.word 0x8800001



Change [random] to 044EC8 + 1

tkim May 9th, 2017 2:46 PM

Quote:

Originally Posted by NewDenverCity (Post 9641956)
Change [random] to 044EC8 + 1

Tried it and didn't work. I think there's a problem with his routine.

Blah May 9th, 2017 3:51 PM

Eh, this routine is around the time when I first started. I'm currently very rusty on ASM and haven't tested the fix. Please try this:

Spoiler:

.thumb
.align 2

main:
push {r4-r5, lr}
ldr r5, =(0x300500C)
ldr r5, [r5]
ldr r4, rand
bl linker
strh r0, [r5, #0xC]
bl linker
strh r0, [r5, #0xA]
ldr r1, =(0x2020000)
strh r0, [r1]
pop {r4-r5, pc}

linker:
bx r4


.align 2
rand:
.word (0x08044EC8 + 1)



Untested, and may not compile as is. Post updates here please.

tkim May 9th, 2017 8:17 PM

Quote:

Originally Posted by FBI (Post 9642111)
Eh, this routine is around the time when I first started. I'm currently very rusty on ASM and haven't tested the fix. Please try this:

Spoiler:

.thumb
.align 2

main:
push {r4-r5, lr}
ldr r5, =(0x300500C)
ldr r5, [r5]
ldr r4, rand
bl linker
strh r0, [r5, #0xC]
bl linker
strh r0, [r5, #0xA]
ldr r1, =(0x2020000)
strh r0, [r1]
pop {r4-r5, pc}

linker:
bx r4


.align 2
rand:
.word (0x08044EC8 + 1)



Untested, and may not compile as is. Post updates here please.

Works well, thank you!

mbcn10ww May 10th, 2017 4:41 AM

Quote:

Originally Posted by FBI (Post 8547374)

Adjusting Shiny encounter chance



Pre-requisites:
- Shiny Pokemon Generator
- Random Number Generator


How to insert:

Before compiling the routine look at the last line. There is a .word 0x8[RANDOM +1]. Change the content after the 0x8 to be a pointer to where you inserted RANDOM +1.

Once you've done that, look for the line that says "mov r0, #0x1 @item ID". Change 0x1 to the Item ID for your Shiny charm item. If you don't have one implemented, delete these lines:
Code:

        mov r0, #0x1 @item ID
        mov r1, #0x1
        ldr r2, =(0x8099F40 +1)
        bl linker
        cmp r0, #0x0
        beq normal
        mov r0, #0xA
        lsl r0, r0, #0x7
        add r0, r0, #0x55 @1/1365 chance with shiny charm
        b calcChance


After you've done that, compile and insert the following routine into free space:

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r3}
        mov r0, #0x1 @item ID
        mov r1, #0x1
        ldr r2, =(0x8099F40 +1)
        bl linker
        cmp r0, #0x0
        beq normal
        mov r0, #0xA
        lsl r0, r0, #0x7
        add r0, r0, #0x55 @1/1365 chance with shiny charm
        b calcChance

normal:
        mov r0, #0x20
        lsl r0, r0, #0x7 @1/4096 chance normally

calcChance:
        ldr r1, =(0x20370B8)
        strh r0, [r1]
        ldr r2, .random
        bl linker
        cmp r0, #0xFF
        bne end
        ldr r1, =(0x20370BC)
        strh r0, [r1]
        ldr r1, =(0x20370B8)
        mov r0, #0x0
        strh r0, [r1]

end:
        pop {r0-r3}
        sub SP, SP, #0x20
        mov r7, r0
        ldr r4, [SP, #0x40]
        ldr r4, [SP, #0x48]
        mov r5, #0xE
        ldr r6, =(0x803DAD8 +1)
        bx r6

linker:
        bx r2

.align 2

.random:
        .word 0x8[RANDOM +1]




Now navigate to 0x3DACE and insert the following byte changes:
Code:

00 00 00 4F 38 47 XX XX XX 08


Where XX XX XX is the reverse hex pointer +1 to where you inserted this routine.


Usage:

It's Automagic, also happens to give the shiny chance to Pokemon in wild, trainer Pokemon, given Pokemon ect.

Right now encounter chance is 1/4096 without shiny charm, and 1/1356 with it.

There is a way to make it work only with wild and breeding and to make the shiny chance 1/2048?

tkim May 10th, 2017 1:18 PM

Quote:

Originally Posted by mbcn10ww (Post 9642663)
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

mbcn10ww May 10th, 2017 1:55 PM

Quote:

Originally Posted by tkim (Post 9643011)
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.

Koople May 14th, 2017 10:30 AM

updated routine

AtecainCorp. May 16th, 2017 12:01 AM

Quote:

Originally Posted by Koople (Post 9647246)
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:

Code:

.text
.align 2
.thumb
.thumb_func

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, .WildPoke
        mov r1, #0xB                        @species
        ldr r2, .GetAttr
        bl linker                                @r0 = species ID
        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, [r1, #0x3]
        mov r1, #0xA
        bl div_func                                        @r0 =  base speed / 10 (integer value)
        mov r3, #0x0
        mov r1, #0xD
        add r3, r0, r1                                @r3 = threshold value = 13 + spd/10  (~5-10% chance of dodging)
        bl rand_func
        lsr r0, r0, #0x8
        cmp r0, r3
        bls DodgeBall
        ldr r0, =(0x0802D6A8 +1)        @else, continue with pokeball 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 cant 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



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 May 16th, 2017 3:48 AM

Quote:

Originally Posted by Koople (Post 9647246)
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:

Code:

.text
.align 2
.thumb
.thumb_func

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, .WildPoke
    mov r1, #0xB            @species
    ldr r2, .GetAttr
    bl linker                @r0 = species ID
    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, [r1, #0x3]
    mov r1, #0xA
    bl div_func                    @r0 =  base speed / 10 (integer value)
    mov r3, #0x0
    mov r1, #0xD
    add r3, r0, r1                @r3 = threshold value = 13 + spd/10  (~5-10% chance of dodging)
    bl rand_func
    lsr r0, r0, #0x8
    cmp r0, r3
    bls DodgeBall
    ldr r0, =(0x0802D6A8 +1)    @else, continue with pokeball 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 cant 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



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 :-)

Koople May 16th, 2017 8:03 AM

out of date, see updated post

tkim May 16th, 2017 9:12 AM

[FR]: Get IVs of a selected POKEMON in PARTY
Spoiler:
This routine reads the IVs of a selected POKEMON whose slot is stored at var 0x8004 and stores them at vars 0x8005-0x800A. It also stores the total amount of the IVs at var 0x8004.
Code:

.text
.align 2
.thumb
.thumb_func
.global getiv

main:
    push {r4-r7, lr}
    ldr r0, var8004        @slot number should be in var8004
    ldrh r0, [r0]
    mov r1, #0x64
    mul r1, r1, r0
    ldr r0, =(0x2024284) @partyram
    add r5, r1, r0        @slotram loaded
    mov r6, #0x27
    mov r1, r6
    ldr r0, var8004
    add r7, r0, #0x2 @var8005
    mov r4, #0x0

loop:
    mov r0, r5
    ldr r2, =(0x803FBE8|1) @getattr
    bl linker
    strh r0, [r7]            @store IVs into var8005-800A
    add r4, r4, r0
    add r6, r6, #0x1
    cmp r6, #0x2D
    beq exit
    mov r1, r6
    add r7, r7, #0x2
    b loop

exit:
    ldr r1, var8004
    strh r4, [r1]    @store total in var8004
    pop {r4-r7, pc}

linker:
    bx r2

.align 2
var8004:
    .word 0x20370C0


Example script:
Code:

#dynamic 0x800000
'---------------
#org @start
lock
faceplayer
special 0x9f
waitstate
callasm 0x8[routine offset+1]
buffernumber 0x0 0x8004
msgbox @IV MSG_KEEPOPEN '"[buffer1]"
release
end

'---------
' Strings
'---------
#org @IV
= [buffer1]



Squeetz May 18th, 2017 1:24 PM

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:
Code:

.thumb

.global recalcparty

setup:
        push {r4-r6, lr}
        mov r6, #0x0
        ldr r4, party_player
        ldr r5, poke_quantity
        ldrb r5, [r5]
        cmp r5, #0x0                @failsafe
        beq end
        sub r5, r5, #0x1        @zero-index it
loop:
        mov r1, #0x64
        mul r1, r6
        add r0, r4, r1
        ldr r3, recalcadr
        bl linker
        cmp r5, r6
        beq end
        add r6, r6, #0x1
        b loop

linker:
        bx r3

end:
        pop {r4-r6}
        pop {r1}
        bx r1

.align 2
        poke_quantity:        .word 0x02024029
        party_player:        .word 0x02024284
        recalcadr:        .word 0x0803E47C|1



EddyHg80 May 19th, 2017 12:49 AM

Feature request [EM][FR if you want]


A hacked giveitem command combined with showpokepic to achieve this:

http://i.imgur.com/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

Spherical Ice May 19th, 2017 8:38 PM

[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:

.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."


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!

Koople May 21st, 2017 5:31 PM

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
Quote:

1. Insert custom 'dodging' message at 0xXXYYZZ (see below)
2. at 0x08XXXXXX: (Battle Script) Requires Jambo's setword battle command
Quote:

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 :)

mbcn10ww May 22nd, 2017 8:52 AM

Quote:

Originally Posted by Koople (Post 9653926)
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)

Koople May 22nd, 2017 10:23 AM

Quote:

Originally Posted by mbcn10ww (Post 9654457)
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.

Spherical Ice May 22nd, 2017 2:07 PM

Please give your feedback to potential changes for this thread at this thread: https://www.pokecommunity.com/showthread.php?t=393085

mbcn10ww May 22nd, 2017 2:41 PM

Quote:

Originally Posted by Koople (Post 9654524)
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.

Diego98 May 22nd, 2017 3:55 PM

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.

Koople May 22nd, 2017 5:08 PM

Quote:

Originally Posted by mbcn10ww (Post 9654710)
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.

mbcn10ww May 22nd, 2017 5:38 PM

Quote:

Originally Posted by Koople (Post 9654837)
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.

Koople May 22nd, 2017 6:34 PM

Quote:

Originally Posted by mbcn10ww (Post 9654854)
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 May 29th, 2017 2:21 AM

Quote:

Originally Posted by Pokemon_XY (Post 8942634)
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.



Rohink May 29th, 2017 7:27 PM

Hi i was thinking if it is possible to
Make a normal pokegear for fire red with having map,phone as as seen in liquid crystal

Squeetz May 30th, 2017 2:39 AM

[FR] Synchronize overworld effect
In Emerald and forward, if you have a Pokémon with Synchronize at the front of the party, you'd have a 50% chance of encountering a Pokémon of the same Nature. Here it is in Firered (albeit a bit messy):

Spoiler:
Code:

.thumb

.global synchronizeOWeffect

main:
        ldr r0, [sp, #0x2C]        @random nature
        lsl r0, r0, #0x18
        lsr r5, r0, #0x18
        lsl r1, r1, #0x10
        lsr r1, r1, #0x10
        mov r8, r1
        lsl r2, r2, #0x18
        lsr r7, r2, #0x18
        lsl r3, r3, #0x18
        lsr r6, r3, #0x18
        bl rand
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #127                @chance: the lower the number, the higher the chance of getting same nature
        bls end
synccheck:
        ldr r0, party_player
        mov r1, #0x2E        @ability bit
        mov r2, #0x0
        bl getattr
        mov r4, r0
        ldr r0, party_player
        mov r1, #0xB        @species
        mov r2, #0x0
        bl getattr
        ldr r2, base_stats
        ldr r2, [r2]
        mov r1, #0x1C        @entry length
        mul r0, r1                @r0 = species
        add r2, r0, r2
        cmp r4, #0x0        @r4 = ability bit
        beq ability0
ability1:
        ldrb r1, [r2, #0x17]
        b checkability

ability0:
        ldrb r1, [r2, #0x16]
checkability:
        cmp r1, #0x1C        @synchronize
        bne end
copynature:
        ldr r0, party_player
        mov r1, #0x0        @PID
        mov r2, #0x0
        bl getattr
        bl getnature
        lsl r0, r0, #0x18
        lsr r5, r0, #0x18
end:
        ldr r0, return                @r5 = nature
        bx r0

rand:
        ldr r3, =(0x08044EC8|1)
        bx r3

getattr:
        ldr r3, =(0x0803FBE8|1)
        bx r3

getnature:
        ldr r3, =(0x08042EB4|1)
        bx r3

.align 2
        base_stats:        .word 0x080001BC
        return:        .word 0x0803DDB8|1
        party_player:        .word 0x02024284

@at 0x3DDA4: 00 48 00 47 XX+1 XX XX 08



AkameTheBulbasaur May 31st, 2017 9:37 PM

Quote:

Originally Posted by Squeetz (Post 9661471)
[FR] Synchronize overworld effect
In Emerald and forward, if you have a Pokémon with Synchronize at the front of the party, you'd have a 50% chance of encountering a Pokémon of the same Nature. Here it is in Firered (albeit a bit messy):

Spoiler:
Code:

.thumb

.global synchronizeOWeffect

main:
    ldr r0, [sp, #0x2C]    @random nature
    lsl r0, r0, #0x18
    lsr r5, r0, #0x18
    lsl r1, r1, #0x10
    lsr r1, r1, #0x10
    mov r8, r1
    lsl r2, r2, #0x18
    lsr r7, r2, #0x18
    lsl r3, r3, #0x18
    lsr r6, r3, #0x18
    bl rand
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    cmp r0, #127        @chance: the lower the number, the higher the chance of getting same nature
    bls end
synccheck:
    ldr r0, party_player
    mov r1, #0x2E    @ability bit
    mov r2, #0x0
    bl getattr
    mov r4, r0
    ldr r0, party_player
    mov r1, #0xB    @species
    mov r2, #0x0
    bl getattr
    ldr r2, base_stats
    ldr r2, [r2]
    mov r1, #0x1C    @entry length
    mul r0, r1        @r0 = species
    add r2, r0, r2
    cmp r4, #0x0    @r4 = ability bit
    beq ability0
ability1:
    ldrb r1, [r2, #0x17]
    b checkability

ability0:
    ldrb r1, [r2, #0x16]
checkability:
    cmp r1, #0x1C    @synchronize
    bne end
copynature:
    ldr r0, party_player
    mov r1, #0x0    @PID
    mov r2, #0x0
    bl getattr
    bl getnature
    lsl r0, r0, #0x18
    lsr r5, r0, #0x18
end:
    ldr r0, return        @r5 = nature
    bx r0

rand:
    ldr r3, =(0x08044EC8|1)
    bx r3

getattr:
    ldr r3, =(0x0803FBE8|1)
    bx r3

getnature:
    ldr r3, =(0x08042EB4|1)
    bx r3

.align 2
    base_stats:    .word 0x080001BC
    return:    .word 0x0803DDB8|1
    party_player:    .word 0x02024284

@at 0x3DDA4: 00 48 00 47 XX+1 XX XX 08



(for some reason my text didn't save the first time)

I tried this and it checks the ability just fine, branches when it should, and gets the Synchronize Pokemon's nature, but when I battle and catch the Pokemon, the nature of the caught Pokemon isn't the same as Synchronize's when it should be (I even set 127 to 0 so it would happen 100% of the time).

Does it work on a clean ROM for you (or is it just me?)

Squeetz June 1st, 2017 2:19 AM

Quote:

Originally Posted by AkameTheBulbasaur (Post 9663173)
(for some reason my text didn't save the first time)

I tried this and it checks the ability just fine, branches when it should, and gets the Synchronize Pokemon's nature, but when I battle and catch the Pokemon, the nature of the caught Pokemon isn't the same as Synchronize's when it should be (I even set 127 to 0 so it would happen 100% of the time).

Does it work on a clean ROM for you (or is it just me?)

Not sure what to tell you, because it works for me.
Did you script a wild battle and test it that way? Iirc, the Pokémon generated from setwildbattle does not run through this function.

AkameTheBulbasaur June 1st, 2017 4:03 AM

Quote:

Originally Posted by Squeetz (Post 9663298)
Not sure what to tell you, because it works for me.
Did you script a wild battle and test it that way? Iirc, the Pokémon generated from setwildbattle does not run through this function.

I just used a normal wild encounter (ran through some grass and caught the first thing that appeared). I might test this some more when I get time and see if there's a specific thing I added which is conflicting because it might affect others who have the same feature.

At least it's not the routine itself, though.

NewDenverCity June 1st, 2017 5:38 AM

So some guy and I were bored and wanted pokemon to have their EVs get calculated after every battle so here it is for FR.
Code:

.thumb
@0000 0000 1100 1101
@0000 0001 1001 1010 0x19A

.macro get_attr
        bl 0x03FBE8
.endm

.macro load_deoxys_species
        mov r1, #0xCD
        lsl r1, #1
.endm

.org 0x044674
main:
        push {r4-r7, lr}
        mov r5, r0 @pokemon struct
        mov r6, r1 @which stat to update
        mov r1, #0xB @species, also r0 is still the same so it's ok
        mov r2, #0
        get_attr
        load_deoxys_species
        cmp r0, r1
        beq load_atk
        mov r1, #0x1C @size_of(pokemon_base)
        mul r0, r1 @multiply to get the right base
        ldr r1, pokemon_base
        add r0, r1
        mov r7, r0 @r7 is the correct pokemon base.
        b 0x0446A0 @end
load_atk:
        ldr r0, deoxys_atk_base_pointer
        mov r7, r0
        b 0x0446A0 @end

.align 2
pokemon_base: .word 0x08254784

.org 0x0446BA
        mov r2, r7
        lsl r1, r6, #1
        add r1, r2
        ldrb r1, [r1]

.org 0x0446FE
        pop {r4-r7} @you can change this to pop {r4-r7, pc}
                @that gives you 6 free bytes to work with if you
                @decompile the entire routine

.org 0x044704
deoxys_atk_base_pointer: .word deoxys_atk_base + 0x08000000

.org 0x25E026
deoxys_atk_base:
.byte 0x32, 0xB4, 0x14, 0x96, 0xB4, 0x14



AtecainCorp. June 4th, 2017 1:46 PM

Quote:

Originally Posted by Spherical Ice (Post 8881731)
Here's my Rock Climb script, just posting here for convenience. It's worth noting this script was made for FireRed, and uses JPAN's special 0x7F; of course, you can just compile the routine and replace special 0x7F with callasm instead.

For Emerald, I believe you need to change the pointer to evaluator to be 0x081A8D95, as well as changing the movement bytes and the animation (?). Special 0x8F isn't in Emerald afaik, so just replace instances of it with getplayerpos 0x8004 0x8005 (EDIT: it seems to not work if it isnt a special, so it's still easiest to replace one of the specials which point to a nop to point to the routine instead).

All instances of 0xA5 should be replaced with the Rock Climb behaviour byte, and all instances of 0x1AF with your attack ID for Rock Climb.

This works for any height of Rock Climb wall, provided each Rock Climb wall tile has the behaviour byte specified in this script. You should also assign this script to the behaviour byte, as well as for the field move, so it's multipurpose in that sense. The script could probably be far more efficient, the movement isn't ideal, the "Rock Climb can't be used here" isn't consistent with how trying to Surf where you cannot works, and (due to horizontal Rock Climbing being impossible / ugly with the Gen 3's 2D engine) horizontal movement doesn't work, but for all intents and purposes it's functional.

Code:

#dynamic 0x800000

'---------------
#org @start
lock
special 0x8F
comparefarbytetobyte 0x2036E50 0x11
if 0x1 call @snippet1
comparefarbytetobyte 0x2036E50 0x22
if 0x1 call @snippet2
special 0x7F
compare 0x8005 0xA5
if 0x1 goto @snippet3
goto @snippet4

'---------------
#org @snippet1
addvar 0x8005 0x1
return

'---------------
#org @snippet2
subvar 0x8005 0x1
return

'---------------
#org @snippet3
lock
special 0x8F
comparefarbytetobyte 0x2036E50 0x33
if 0x1 goto @snippet5
comparefarbytetobyte 0x2036E50 0x44
if 0x1 goto @snippet5
checkattack 0x1AF
compare LASTRESULT 0x6
if 0x1 goto @snippet5
setanimation 0x0 LASTRESULT
bufferpartypokemon 0x0 LASTRESULT
bufferattack 0x1 0x1AF
msgbox @string1 MSG_YESNO '"The wall is very rocky[.]\nWould y..."
compare LASTRESULT 0x0
if 0x1 goto @snippet6
msgbox @string2 MSG_KEEPOPEN '"[buffer1] used [buffer2]!"
closeonkeypress
doanimation 0x2
waitstate
special 0x8F
setvar 0x8006 0x0
copyvar 0x4001 0x8004
copyvar 0x4002 0x8005
comparefarbytetobyte 0x2036E50 0x11
if 0x1 goto @snippet7
comparefarbytetobyte 0x2036E50 0x22
if 0x1 goto @snippet8
goto @snippet4

'---------------
#org @snippet4
msgbox @string3 MSG_NORMAL '"Rock Climb can't be used here!"
release
end

'---------------
#org @snippet5
msgbox @string4 MSG_SIGN '"The wall is very rocky[.]\nWill a ..."
release
end

'---------------
#org @snippet6
closeonkeypress
release
end

'---------------
#org @snippet7
copyvar 0x8004 0x4001
addvar 0x4002 0x1
copyvar 0x8005 0x4002
addvar 0x8006 0x1
special 0x7F
compare 0x8005 0xA5
if 0x1 goto @snippet7
goto @snippet9

'---------------
#org @snippet8
copyvar 0x8004 0x4001
subvar 0x4002 0x1
copyvar 0x8005 0x4002
addvar 0x8006 0x1
special 0x7F
compare 0x8005 0xA5
if 0x1 goto @snippet8
goto @snippet9

'---------------
#org @snippet9
compare 0x8006 0x0
if 0x1 goto @snippet10
comparefarbytetobyte 0x2036E50 0x11
if 0x1 call @snippet11
comparefarbytetobyte 0x2036E50 0x22
if 0x1 call @snippet12
subvar 0x8006 0x1
goto @snippet9

'---------------
#org @snippet10
release
end

'---------------
#org @snippet11
applymovement MOVE_PLAYER @move1
waitmovement 0x0
return

'---------------
#org @snippet12
applymovement MOVE_PLAYER @move2
waitmovement 0x0
return

'---------
' Strings
'---------
#org @string1
= The wall is very rocky[.]\nWould you like to use [buffer2]?

#org @string2
= [buffer1] used [buffer2]!

#org @string3
= Rock Climb can't be used here!

#org @string4
= The wall is very rocky[.]\nWill a Pokémon's move scale it?

'-----------
' Movements
'-----------
#org @move1
#raw 0x35 'Slide Down (Normal)
#raw 0xFE 'End of Movements

#org @move2
#raw 0x36 'Slide Up (Normal)
#raw 0xFE 'End of Movements


Give credit, of course, to JPAN and FBI agent.

I tried using this on Pokemon RUby. And IDK why still it says me "You can't use Rock CLimb Here"

Enn June 5th, 2017 2:03 AM

1 Attachment(s)
Quote:

Originally Posted by pokemontutorialTV (Post 9665484)
Someone have the number input box downloaded?
http://www.pokecommunity.com/showpost.php?p=8910813&postcount=702
Cant download it.

I have it! Here ya go mate,

Diego98 June 5th, 2017 5:21 PM

Quote:

Originally Posted by Nisarg (Post 9666962)
I have it! Here ya go mate,

Do you know how to make it work??

Enn June 8th, 2017 5:14 AM

Quote:

Originally Posted by Diego98 (Post 9667874)
Do you know how to make it work??

All you need to do is insert the code at a free location, edit the pointer at code + 0x164 to (pointer to code + 0x0179) and then call it with the callASM command followed by a waitstate. You also need to be in a locked state, so use lockall or lock before callASM, and release/releaseall at the end of the script.
To change the location of where the box is located change X at code+2 and Y at code+4 and to change the width of the box change the byte at code+6.

Enn June 8th, 2017 7:27 AM

Quote:

Originally Posted by Nisarg (Post 9672208)
All you need to do is insert the code at a free location, edit the pointer at code + 0x164 to (pointer to code + 0x0179) and then call it with the callASM command followed by a waitstate. You also need to be in a locked state, so use lockall or lock before callASM, and release/releaseall at the end of the script.
To change the location of where the box is located change X at code+2 and Y at code+4 and to change the width of the box change the byte at code+6.

Also, .equ offset, is the offset where Uj wanna assemble that routine;)

Diego98 June 9th, 2017 10:04 AM

Quote:

Originally Posted by Nisarg (Post 9672208)
All you need to do is insert the code at a free location, edit the pointer at code + 0x164 to (pointer to code + 0x0179) and then call it with the callASM command followed by a waitstate. You also need to be in a locked state, so use lockall or lock before callASM, and release/releaseall at the end of the script.
To change the location of where the box is located change X at code+2 and Y at code+4 and to change the width of the box change the byte at code+6.

I don't know exactly what u mean when u say: "edit the pointer at code + 0x164 to (pointer to code + 0x0179)"
Also, the end of the routine says : update_addr: .word update_box + rom). What i'm supposed to do with this, I can't compile it without changing it.

Enn June 9th, 2017 9:33 PM

Quote:

Originally Posted by Diego98 (Post 9673696)
I don't know exactly what u mean when u say: "edit the pointer at code + 0x164 to (pointer to code + 0x0179)"
Also, the end of the routine says : update_addr: .word update_box + rom). What i'm supposed to do with this, I can't compile it without changing it.

Once u compile it, go to that offset in hxd, then goto that offset+0x164, change it to xxxxxx, where xxxxxx is offset where u compiled+0x179...
It's pretty self explanatory...

Diego98 June 10th, 2017 4:40 AM

Quote:

Originally Posted by Nisarg (Post 9674100)
Once u compile it, go to that offset in hxd, then goto that offset+0x164, change it to xxxxxx, where xxxxxx is offset where u compiled+0x179...
It's pretty self explanatory...

I did it before but it didn't work, so I thought I'm doing something wrong and I asked you. By the way, it still don't work for me, also the thumb compiler displays 2 errors at compiling: "failed to get real start of function: create_string" and "failed to get real start of function: get_max_digit"
Then it makes a file with a bunch of 00 bytes followed by the assembled code

Spherical Ice June 11th, 2017 6:31 AM

Does this version I rewrote a while back work better for you guys?

Code:

.thumb
.thumb_func

.equ start, 0x08XXXXXX @ Change this to the start offset of the insertion location

/*input:
0x8008: first 16bits of x
0x8009: second 16bits of x
where x = max value allowed

output: 0x8008: first 16bits of user input
0x8009: second 16bits of user input
0x800D: the digit A was pressed on (0x7f if B was pressed to cancel)*/

make_box:
    push {r4-r7,lr}
    mov r0, #0x12 /*X position of box, in characters*/
    mov r1, #0xA /*Y position of box, in characters*/
    mov r2, #0xA /*size of box, in characters*/
    mov r3, #0x2
    ldr r4, =(0x0809D654+1) @ draw_interior
    bl call_via_r4
    add r6, r0, #0x0
    mov r1, #0x0
    ldr r2, =(0x080F7750+1) @ draw_border
    bl call_via_r2

    mov r0, #0x0
    mov r1, #0x0
    add r2, r6, #0x0
    bl create_and_print_string

    sub SP, SP, #0xc
    mov r0, #0x10
    str r0, [SP]
    mov r0, #0x1
    str r0, [SP, #0x4]
    mov r0, #0x0
    str r0, [SP, #0x8]
    add r0, r6, #0x0
    mov r1, #0x2
    mov r2, #0x0
    mov r3, #0x2
    ldr r4, =(0x0810F7D8+1) @ func_10F7D8
    bl call_via_r4
    add SP, SP, #0xC

    mov r0, #0x0
    mov r1, #0x1
    add r2, r6, #0x0
    mov r3, #0xff
    bl set_update_function

    mov r0, #0x0
    ldr r1, =(0x080F67A4+1) @ set_ab58
    bl call_via_r1

    pop {r4-r7, pc}

/*This function creates the string representation of the
number box and places it on fcode_buffer2 1. The number contains
an arrow pointing at the currently selected digit, the number
to be printed and some padding zeros if the number has less
digits than the max value set at 0x8008/9 variables.
params
r0 = num to display
r1 = digit with arrow*/
.align 2
create_string:
    push {r4-r7, lr}
    add r6, r0, #0x0
    add r5, r1, #0x0
    bl get_max_digit
    add r4, r0, #0x0

    ldr r0, fcode_buffer2
    add r1, r6, #0x0
    mov r2, #0x0
    add r3, r4, #0x0
    push {r4}
    ldr r4, =(0x08008E78+1) @ int_to_str
    bl call_via_r4
    pop {r4}
    ldr r0, fcode_buffer2
    ldr r1, =(0x08008E08+1) @ str_len
    bl call_via_r1

    add r1, r4, #0x0
    ldr r2, fcode_buffer2
    add r3, r5, #0x0
    bl copy_and_pad_string
    pop {r4-r7, pc}

.align 2
get_max_digit:
    ldr r3, var_8008
    ldr r2, [r3]
    cmp r2, #0x0
    bne set_count_digits
    ldr r2, decimal_table
    mov r0, #0x9
    lsl r1, r0, #0x2
    add r1, r1, r2
    ldr r1, [r1]
    sub r1, #0x1
    str r1, [r3]
    mov pc, lr

set_count_digits:
    mov r0, #0x9
    ldr r3, decimal_table
count_digit_loop:
    lsl r1, r0, #0x2
    add r1, r3, r1
    ldr r1, [r1]
    cmp r1, r2
    bhi count_digit_loop_cont
    add r0, #0x1
    mov pc, lr
count_digit_loop_cont:
    sub r0, #0x1
    b count_digit_loop

copy_and_pad_string:
    push {r4-r7,lr}
    add r7, r2, #0x0
    add r6, r3, #0x0
    add r5, r1, #0x1
    sub r4, r0, #0x1

    mov r0, #0xff
    strb r0, [r7, r5]
    sub r5, #0x1

str_build_loop:
    cmp r6, #0x0
    beq add_arrow
    cmp r4, #0x0
    blt padd_with_zero

    ldrb r0, [r7, r4]
    strb r0, [r7, r5]

    b str_build_loop_dec
add_arrow:
    mov r0, #0x7B
    strb r0, [r7, r5]
    add r4, #0x1
    b str_build_loop_dec

padd_with_zero:
    mov r0, #0xA1
    strb r0, [r7, r5]

str_build_loop_dec:
    sub r6, #0x1
    sub r4, #0x1
    sub r5, #0x1
    cmp r5, #0x0
    bge str_build_loop
    pop {r4-r7, pc}

set_update_function:
    push {r4-r7, lr}
    add r4, r0, #0x0
    add r5, r1, #0x0
    add r6, r2, #0x0
    add r7, r3, #0x0
    ldr r0, update_addr
    mov r1, #0x50
    ldr r2, =(0x0807741C+1) @ task_add
    bl call_via_r2
    add r3, r0, #0x0
    lsl r0,r0, #0x2
    add r0, r0, r3
    lsl r0, r0, #0x3
    ldr r1, tasks
    add r1, r0, r1
    strb r4, [r1, #0x10]
    strb r5, [r1, #0x11]
    strb r6, [r1, #0x12]
    strb r7, [r1, #0x13]
    mov r0, #0x0
    str r0, [r1, #0x14]
    bl get_max_digit
    ldr r1, RAM_menu_addr
    strb r0, [r1, #0x4]
    mov r0, #0x0
    strb r0, [r1, #0x2]

    pop {r4-r7,pc}

/*r0 = function index in queue
function params
0x12 (byte) = box id
0x14 (word) = number counter*/

update_box:
    push {r4-r6,lr}
    add r6, r0, #0x0
    ldr r5, tasks
    lsl r0, r6, #0x2
    add r0, r0, r6
    lsl r0, r0, #0x3
    add r5, r0, r5
    ldr r4, RAM_menu_addr

    ldr r0, super
    ldrh r3, [r0, #0x2e]

    mov r0, #0x1
    and r0, r3
    cmp r0, #0x0
    bne pressed_a

    mov r0, #0x2
    and r0, r3
    cmp r0, #0x0
    bne pressed_b

    mov r0, #0x10
    and r0, r3
    cmp r0, #0x0
    bne pressed_right

    mov r0, #0x20
    and r0, r3
    cmp r0, #0x0
    bne pressed_left

    mov r0, #0x40
    and r0, r3
    cmp r0, #0x0
    bne pressed_up

    mov r0, #0x80
    and r0, r3
    cmp r0, #0x0
    bne pressed_down

    pop {r4-r6,pc}

pressed_a:
    ldr r1, var_8008
    ldr r0, [r5, #0x14]
    str r0, [r1]
    ldr r1, var_800D
    ldrb r0, [r4, #0x2]
    strh r0, [r1]
    b update_clean_function

pressed_b:
    ldr r1, var_800D
    mov r0, #0x7f
    strh r0, [r1]

update_clean_function:
    ldr r1, clean_addr
    ldrb r0, [r5, #0x12]
    mov pc, r1

pressed_left:
    ldrb r0, [r4, #0x2]
    add r0, #0x1
    ldrb r1, [r4, #0x4]
    cmp r0, r1
    blt set_direction
    mov r0, #0x0
    b set_direction

pressed_right:
    ldrb r0, [r4, #0x2]
    sub r0, #0x1
    cmp r0, #0x0
    bge set_direction
    ldrb r0, [r4, #0x4]
    sub r0, #0x1

set_direction:
    strb r0, [r4, #0x2]
    add r1, r0, #0x0
    ldr r0, [r5, #0x14]
    ldrb r2, [r5, #0x12]
    bl create_and_print_string
    pop {r4-r6,pc}

pressed_up:
    ldr r1, decimal_table
    ldrb r0, [r4, #0x2]
    lsl r0, r0, #0x2
    add r1, r0, r1
    ldr r1, [r1]
    ldr r0, [r5, #0x14]
    add r0, r1, r0
    b check_min

pressed_down:
    ldr r1, decimal_table
    ldrb r0, [r4, #0x2]
    lsl r0, r0, #0x2
    add r1, r0, r1
    ldr r1, [r1]
    ldr r0, [r5, #0x14]
    sub r0, r0, r1

check_min:
    cmp r0, #0x0
    bge check_max
    mov r0, #0x0

check_max:
    ldr r1, var_8008
    ldr r1, [r1]
    cmp r0, r1
    ble set_number
    add r0, r1, #0x0

set_number:
    str r0, [r5, #0x14]
    ldrb r1, [r4, #0x2]
    ldrb r2, [r5, #0x12]
    bl create_and_print_string
    pop {r4-r6,pc}

create_and_print_string:
    push {lr}
    push {r2}
    bl create_string

    pop {r0}
    sub SP, SP, #0xC
    mov r2, #0x2
    str r2, [SP]
    mov r2, #0x0
    str r2, [sp, #0x4]
    mov r2, #0x0
    str r2, [sp, #0x8]
    mov r1, #0x2
    ldr r2, fcode_buffer2
    mov r3, #0x8
    ldr r4, =(0x08002C48+1) @ print_string
    bl call_via_r4
    add SP, SP, #0xC
    pop {pc}

call_via_r1:
    bx r1

call_via_r2:
    bx r2

call_via_r4:
    bx r4   

.align 2
fcode_buffer2: .word 0x02021CD0
var_8008: .word 0x020370C8
var_800D: .word 0x020370D0
RAM_menu_addr: .word 0x0203ADE4
tasks: .word 0x03005090
super: .word 0x030030F0
clean_addr: .word 0x0809CD2E
decimal_table: .word 0x08231E3C
update_addr: .word (update_box + start +1)



Spherical Ice June 11th, 2017 7:31 AM

Quote:

Originally Posted by pokemontutorialTV (Post 9675566)
Im glad to see, that you fixed some bugs with the numberbox, with the other I had ingame some problems. Anyways I asked for your Abilitypill-Routine, which I'm dont be able get to work.
It stucks when I try to use it (Bag Sprite will be gone then).

Is your ROM BPRE?

Spherical Ice June 11th, 2017 8:23 AM

Quote:

Originally Posted by pokemontutorialTV (Post 9675628)
No, but of couse i used the offsets, which are the right ones for my rom, so they all point to the same functions ;)

Can you post your modified routine?

Spherical Ice June 11th, 2017 9:12 AM

Quote:

Originally Posted by pokemontutorialTV (Post 9675659)
Here you go.^^

Okay, the rom symbol is not 0x800001, it's 0x08000001. You never need to change it. Similarly, the location symbol doesn't need the start 08.

I think that is the only issue:

Code:

.thumb

.equ location,              0x1669F8
.equ rom,                  0x08000001

.equ ability_name_length,  0x0D
.equ base_stats_length,    0x1C
.equ pokemon_length,        0x64
.equ req_species,          0x0B
.equ req_ability,          0x2E
.equ ability1,              0x16
.equ ability2,              0x17

.org location
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_species
    ldr r3, get_attr
    bl call_via_r3

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:
    mov r0, #0
    strb r0, [r1]
    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_species
    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, 0x00, 0xC0, 0xF4, 0xDC, 0xDD, 0xDB, 0xDF, 0xD9, 0xDD, 0xE8, 0xFE, 0xF4, 0xE2, 0xD8, 0xD9, 0xE6, 0xE8, 0xD9, 0x00, 0xE7, 0xDD, 0xD7, 0xDC, 0x00, 0xEE, 0xE9, 0x00, 0xFD, 0x03, 0xAB, 0x09, 0xFF, 0xFC, 0x09, 0xFF

.align 2
    fcode_buffer2:          .word 0x02021CD0 @buffer2 ok
    fcode_buffer3:          .word 0x02021CF0
    displayed_string:      .word 0x02021D18 @string adress ok
    party_player:          .word 0x02024284 @ok
    var_800D:              .word 0x020370D0 @vars ok
    var_800E:              .word 0x0203AD30 @vars ok
    brm:                    .word 0x0203B0A0
    item_effectiveness:    .word 0x0203B0C0

    tasks:                  .word 0x03004FE0 @ENG: 0x03005090
    item_function_ptr:      .word 0x03005DE8 @ENG: 0x03005E98 @ok

    base_stats_ptr:        .word 0x080001BC @ENG gleich
    ability_names_ptr:      .word 0x080001C0 @ENG gleich
    strcpy_xFF_terminated:  .word 0x08008D04|1 @ENG: 0x08008D84|1 @ok
    fdecoder:              .word 0x08008F4C|1 @ENG: 0x08008FCC|1 @ok
    get_attr:              .word 0x0803FAE8|1 @ENG: 0x0803FBE8|1 @ok
    set_attr:              .word 0x0804027C|1 @ENG: 0x0804037C|1 @ok
    audio_play:            .word 0x08072230|1 @ENG: 0x080722CC|1 @ok
    bag_remove_item:        .word 0x0809A2BC|1 @ENG: 0x0809A1D8|1 @ok
    item_consume_maybe:    .word 0x080A17BC|1 @ENG: 0x080A16D0|1 @ok
    bgid_mark_for_sync:    .word 0x080F6A38|1 @ENG: 0x080F67A4|1 @ok
    buffer_pkmn_nick:      .word 0x08120314|1 @ENG: 0x081202E0|1 @ok
    item_menu_string:      .word 0x0812032C|1 @ENG: 0x081202F8|1 @ok
    item_use_animation:    .word 0x08124E10|1 @ENG: 0x08124DC0|1 @ok
    item_menu_callback:    .word 0x0812560C|1 @ENG: 0x081255BC|1 @ok
    no_effect_str:          .word 0x08416824 @ENG: 0x084169DC @ "Es wird keine Wirkung haben."



Diego98 June 11th, 2017 9:40 AM

Quote:

Originally Posted by Spherical Ice (Post 9675530)
Does this version I rewrote a while back work better for you guys?

Code:

.thumb
.thumb_func

.equ start, 0x08XXXXXX @ Change this to the start offset of the insertion location

/*input:
0x8008: first 16bits of x
0x8009: second 16bits of x
where x = max value allowed

output: 0x8008: first 16bits of user input
0x8009: second 16bits of user input
0x800D: the digit A was pressed on (0x7f if B was pressed to cancel)*/

make_box:
    push {r4-r7,lr}
    mov r0, #0x12 /*X position of box, in characters*/
    mov r1, #0xA /*Y position of box, in characters*/
    mov r2, #0xA /*size of box, in characters*/
    mov r3, #0x2
    ldr r4, =(0x0809D654+1) @ draw_interior
    bl call_via_r4
    add r6, r0, #0x0
    mov r1, #0x0
    ldr r2, =(0x080F7750+1) @ draw_border
    bl call_via_r2

    mov r0, #0x0
    mov r1, #0x0
    add r2, r6, #0x0
    bl create_and_print_string

    sub SP, SP, #0xc
    mov r0, #0x10
    str r0, [SP]
    mov r0, #0x1
    str r0, [SP, #0x4]
    mov r0, #0x0
    str r0, [SP, #0x8]
    add r0, r6, #0x0
    mov r1, #0x2
    mov r2, #0x0
    mov r3, #0x2
    ldr r4, =(0x0810F7D8+1) @ func_10F7D8
    bl call_via_r4
    add SP, SP, #0xC

    mov r0, #0x0
    mov r1, #0x1
    add r2, r6, #0x0
    mov r3, #0xff
    bl set_update_function

    mov r0, #0x0
    ldr r1, =(0x080F67A4+1) @ set_ab58
    bl call_via_r1

    pop {r4-r7, pc}

/*This function creates the string representation of the
number box and places it on fcode_buffer2 1. The number contains
an arrow pointing at the currently selected digit, the number
to be printed and some padding zeros if the number has less
digits than the max value set at 0x8008/9 variables.
params
r0 = num to display
r1 = digit with arrow*/
.align 2
create_string:
    push {r4-r7, lr}
    add r6, r0, #0x0
    add r5, r1, #0x0
    bl get_max_digit
    add r4, r0, #0x0

    ldr r0, fcode_buffer2
    add r1, r6, #0x0
    mov r2, #0x0
    add r3, r4, #0x0
    push {r4}
    ldr r4, =(0x08008E78+1) @ int_to_str
    bl call_via_r4
    pop {r4}
    ldr r0, fcode_buffer2
    ldr r1, =(0x08008E08+1) @ str_len
    bl call_via_r1

    add r1, r4, #0x0
    ldr r2, fcode_buffer2
    add r3, r5, #0x0
    bl copy_and_pad_string
    pop {r4-r7, pc}

.align 2
get_max_digit:
    ldr r3, var_8008
    ldr r2, [r3]
    cmp r2, #0x0
    bne set_count_digits
    ldr r2, decimal_table
    mov r0, #0x9
    lsl r1, r0, #0x2
    add r1, r1, r2
    ldr r1, [r1]
    sub r1, #0x1
    str r1, [r3]
    mov pc, lr

set_count_digits:
    mov r0, #0x9
    ldr r3, decimal_table
count_digit_loop:
    lsl r1, r0, #0x2
    add r1, r3, r1
    ldr r1, [r1]
    cmp r1, r2
    bhi count_digit_loop_cont
    add r0, #0x1
    mov pc, lr
count_digit_loop_cont:
    sub r0, #0x1
    b count_digit_loop

copy_and_pad_string:
    push {r4-r7,lr}
    add r7, r2, #0x0
    add r6, r3, #0x0
    add r5, r1, #0x1
    sub r4, r0, #0x1

    mov r0, #0xff
    strb r0, [r7, r5]
    sub r5, #0x1

str_build_loop:
    cmp r6, #0x0
    beq add_arrow
    cmp r4, #0x0
    blt padd_with_zero

    ldrb r0, [r7, r4]
    strb r0, [r7, r5]

    b str_build_loop_dec
add_arrow:
    mov r0, #0x7B
    strb r0, [r7, r5]
    add r4, #0x1
    b str_build_loop_dec

padd_with_zero:
    mov r0, #0xA1
    strb r0, [r7, r5]

str_build_loop_dec:
    sub r6, #0x1
    sub r4, #0x1
    sub r5, #0x1
    cmp r5, #0x0
    bge str_build_loop
    pop {r4-r7, pc}

set_update_function:
    push {r4-r7, lr}
    add r4, r0, #0x0
    add r5, r1, #0x0
    add r6, r2, #0x0
    add r7, r3, #0x0
    ldr r0, update_addr
    mov r1, #0x50
    ldr r2, =(0x0807741C+1) @ task_add
    bl call_via_r2
    add r3, r0, #0x0
    lsl r0,r0, #0x2
    add r0, r0, r3
    lsl r0, r0, #0x3
    ldr r1, tasks
    add r1, r0, r1
    strb r4, [r1, #0x10]
    strb r5, [r1, #0x11]
    strb r6, [r1, #0x12]
    strb r7, [r1, #0x13]
    mov r0, #0x0
    str r0, [r1, #0x14]
    bl get_max_digit
    ldr r1, RAM_menu_addr
    strb r0, [r1, #0x4]
    mov r0, #0x0
    strb r0, [r1, #0x2]

    pop {r4-r7,pc}

/*r0 = function index in queue
function params
0x12 (byte) = box id
0x14 (word) = number counter*/

update_box:
    push {r4-r6,lr}
    add r6, r0, #0x0
    ldr r5, tasks
    lsl r0, r6, #0x2
    add r0, r0, r6
    lsl r0, r0, #0x3
    add r5, r0, r5
    ldr r4, RAM_menu_addr

    ldr r0, super
    ldrh r3, [r0, #0x2e]

    mov r0, #0x1
    and r0, r3
    cmp r0, #0x0
    bne pressed_a

    mov r0, #0x2
    and r0, r3
    cmp r0, #0x0
    bne pressed_b

    mov r0, #0x10
    and r0, r3
    cmp r0, #0x0
    bne pressed_right

    mov r0, #0x20
    and r0, r3
    cmp r0, #0x0
    bne pressed_left

    mov r0, #0x40
    and r0, r3
    cmp r0, #0x0
    bne pressed_up

    mov r0, #0x80
    and r0, r3
    cmp r0, #0x0
    bne pressed_down

    pop {r4-r6,pc}

pressed_a:
    ldr r1, var_8008
    ldr r0, [r5, #0x14]
    str r0, [r1]
    ldr r1, var_800D
    ldrb r0, [r4, #0x2]
    strh r0, [r1]
    b update_clean_function

pressed_b:
    ldr r1, var_800D
    mov r0, #0x7f
    strh r0, [r1]

update_clean_function:
    ldr r1, clean_addr
    ldrb r0, [r5, #0x12]
    mov pc, r1

pressed_left:
    ldrb r0, [r4, #0x2]
    add r0, #0x1
    ldrb r1, [r4, #0x4]
    cmp r0, r1
    blt set_direction
    mov r0, #0x0
    b set_direction

pressed_right:
    ldrb r0, [r4, #0x2]
    sub r0, #0x1
    cmp r0, #0x0
    bge set_direction
    ldrb r0, [r4, #0x4]
    sub r0, #0x1

set_direction:
    strb r0, [r4, #0x2]
    add r1, r0, #0x0
    ldr r0, [r5, #0x14]
    ldrb r2, [r5, #0x12]
    bl create_and_print_string
    pop {r4-r6,pc}

pressed_up:
    ldr r1, decimal_table
    ldrb r0, [r4, #0x2]
    lsl r0, r0, #0x2
    add r1, r0, r1
    ldr r1, [r1]
    ldr r0, [r5, #0x14]
    add r0, r1, r0
    b check_min

pressed_down:
    ldr r1, decimal_table
    ldrb r0, [r4, #0x2]
    lsl r0, r0, #0x2
    add r1, r0, r1
    ldr r1, [r1]
    ldr r0, [r5, #0x14]
    sub r0, r0, r1

check_min:
    cmp r0, #0x0
    bge check_max
    mov r0, #0x0

check_max:
    ldr r1, var_8008
    ldr r1, [r1]
    cmp r0, r1
    ble set_number
    add r0, r1, #0x0

set_number:
    str r0, [r5, #0x14]
    ldrb r1, [r4, #0x2]
    ldrb r2, [r5, #0x12]
    bl create_and_print_string
    pop {r4-r6,pc}

create_and_print_string:
    push {lr}
    push {r2}
    bl create_string

    pop {r0}
    sub SP, SP, #0xC
    mov r2, #0x2
    str r2, [SP]
    mov r2, #0x0
    str r2, [sp, #0x4]
    mov r2, #0x0
    str r2, [sp, #0x8]
    mov r1, #0x2
    ldr r2, fcode_buffer2
    mov r3, #0x8
    ldr r4, =(0x08002C48+1) @ print_string
    bl call_via_r4
    add SP, SP, #0xC
    pop {pc}

call_via_r1:
    bx r1

call_via_r2:
    bx r2

call_via_r4:
    bx r4   

.align 2
fcode_buffer2: .word 0x02021CD0
var_8008: .word 0x020370C8
var_800D: .word 0x020370D0
RAM_menu_addr: .word 0x0203ADE4
tasks: .word 0x03005090
super: .word 0x030030F0
clean_addr: .word 0x0809CD2E
decimal_table: .word 0x08231E3C
update_addr: .word (update_box + start +1)



Finally it works!!!! Thank you.
In this new version is necessary to change the pointer at 0x164?
Now, the last thing, how can I use it in a script, I mean, how to store the numbers in variables?

Edit: I figured out how to use it but the use of variable 0x8009 is buggy, when i set the number I want it just make a bug and make impossible to use the number selector, so I only can use the variable 0x8008


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.