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)

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.