< >
Hello, guest! Please log in or register.

The PokéCommunity

Go Back     The PokéCommunity Forums > ROM Hacking > Tools, Tutorials & Resources Tutorial Running a script via item [EM]

Notices

Tools, Tutorials & Resources Various tools to help you develop your hacks can be found here.
New threads in this forum are to be approved by a moderator before they are displayed.

Reply Post Reply
 
Thread Tools
  #1    
Old March 19th, 2016 (6:06 AM). Edited March 21st, 2016 by DizzyEgg.
DizzyEgg's Avatar
DizzyEgg DizzyEgg is offline
 
Join Date: Feb 2014
Age: 18
Gender: Male
Nature: Quiet
Posts: 225
So if you ever wanted to run a script via item, here's how to do it in Emerald. I think FR already has a tut on it.
So first, you create a script you want your item to run.
Then you insert this routine and keep track of where you inserted it.
Spoiler:

Code:
.text
.thumb
.thumb_func
.align 2

main:
    push {r4, lr}
    mov r4, r0
    ldr r2, script_env2_enable
    bl callviar2
    ldr r0, script_to_run
    ldr r2, script_run
    bl callviar2
    mov r0, r4
    ldr r2, task_delete
    bl callviar2
    pop {r4}
    pop {r0}
    bx r0
    
callviar2:
    bx r2
    
.align 2
script_env2_enable: .word 0x08098E55
script_run: .word 0x08098EF9
script_to_run: .word 0x pointer to your script, do not +1!
task_delete: .word 0x080A909D


Then you assemble this routine. Save where you inserted it.
Spoiler:

Code:
.text
.thumb
.thumb_func
.align 2

main:
    push {lr}
    ldr r1, routine_to_run_after_graphics
    ldr r2, run_custom_script
    str r2, [r1]
    ldr r2, run_after_graphics
    bl callviar2
    pop {r0}
    bx r0
    
callviar2:
    bx r2
    
.align 2

routine_to_run_after_graphics: .word 0x0203A0F4
run_custom_script: .word 0x pointer to the run script routine + 1
run_after_graphics: .word 0x080FD0DD


Then you open Kurapika's GEN 3 tools and in the field script section of your item, you put the offset to the second routine + 1 and set item type to '2 Use of SELECT'.
Also, this is a different approach from the FR version, so you have to repeat the process of inserting those two routines for every item you'd like to run a custom script. The upside is, this method allows you to run both ASM and script.
Reply With Quote

Relevant Advertising!

  #2    
Old March 21st, 2016 (7:15 AM).
NewDenverCity's Avatar
NewDenverCity NewDenverCity is offline
 
Join Date: Apr 2014
Location: Antarctica
Gender: Male
Nature: Calm
Posts: 195
Quote:
Originally Posted by DizzyEgg View Post
So if you ever wanted to run a script via item, here's how to do it in Emerald. I think FR already has a tut on it.
So first, you create a script you want your item to run.
Then you insert this routine and keep track of where you inserted it.
Spoiler:

Code:
.text
.thumb
.thumb_func
.align 2

main:
    push {r4, lr}
    mov r4, r0
    ldr r2, script_env2_enable
    bl callviar2
    ldr r0, script_to_run
    ldr r2, script_run
    bl callviar2
    mov r0, r4
    ldr r2, task_delete
    bl callviar2
    pop {r4}
    pop {r0}
    bx r0
    
callviar2:
    bx r2
    
.align 2
script_env2_enable: .word 0x08098E55
script_run: .word 0x08098EF9
script_to_run: .word 0x pointer to your script, do not +1!
task_delete: .word 0x080A909D


Then you assemble this routine. Save where you inserted it.
Spoiler:

Code:
.text
.thumb
.thumb_func
.align 2

main:
    push {r4, lr}
    mov r4, r0
    ldr r1, routine_to_run_after_graphics
    ldr r0, run_custom_script
    str r0, [r1]
    ldr r2, run_after_graphics
    bl callviar2
    pop {r4}
    pop {r0}
    bx r0
    
callviar2:
    bx r2
    
.align 2

routine_to_run_after_graphics: .word 0x0203A0F4
run_custom_script: .word 0x pointer to the run script routine + 1
run_after_graphics: .word 0x080FD0DD


Then you open Kurapika's GEN 3 tools and in the field script section of your item, you put the offset to the second routine + 1 and set item type to '2 Use of SELECT'.
Also, this is a different approach from the FR version, so you have to repeat the process of inserting those two routines for every item you'd like to run a custom script. The upside is, this method allows you to run both ASM and script.
I'm going to call the first routine you posted routine A, and the second will be routine B.

There's some pretty large bugs with this. The screen will go black until you hit B twice, or hit the left and right stick once and then A. The reason being, you haven't left the bag area, you've just turned the screen black. Routine A doesn't get read until you've left the bag area.


In addition, this current method is really ineffective, and could be optimized a ton. Do what you need to do in order to make routine B work better, and then I have an idea for what you can do to optimize routine A so you don't need to insert routine A and B for each one.


First, know that 0x0203CE7C holds the item ID of the item you're using. That offset is in r5 at the beginning of both routines. Here's what I'd do in routine A to optimize it.
Code:
get_correct_script:
    ldrh r0, [r5]
    ldr r2, table_of_scripts
    mov r3, #0xFF
    lsl r3, #0x8
    add r3, #0xFF
loop_start:
    ldrh r1, [r2]
    cmp r0, r1
    beq continue
    cmp r1, r3
    beq abort
    add r2, #0x6
    b loop_start
continue:
    ldr r0, [r2, #0x2]
table_of_scripts is a table, obviously. It's structured like so; [item id, hword] [corresponding script offset, word]. This way, we'll scan down the table and check to see which script to use with the loop. r0 would hold the correct script's offset after the ldr r0, [r2, #0x2]. r3 would contain FFFF, which'd be the end of the table, and you'd have to find some way to leave the routine if there's no script to run. You can get rid of the r3 parts, but then the game would definitely crash every time there's not a correct entry for that item. This method is a LOT smaller than 88 bytes per item with a script attached.
Reply With Quote
  #3    
Old March 21st, 2016 (8:25 AM). Edited March 21st, 2016 by DizzyEgg.
DizzyEgg's Avatar
DizzyEgg DizzyEgg is offline
 
Join Date: Feb 2014
Age: 18
Gender: Male
Nature: Quiet
Posts: 225
Quote:
Originally Posted by NewDenverCity View Post
I'm going to call the first routine you posted routine A, and the second will be routine B.

There's some pretty large bugs with this. The screen will go black until you hit B twice, or hit the left and right stick once and then A. The reason being, you haven't left the bag area, you've just turned the screen black. Routine A doesn't get read until you've left the bag area.


In addition, this current method is really ineffective, and could be optimized a ton. Do what you need to do in order to make routine B work better, and then I have an idea for what you can do to optimize routine A so you don't need to insert routine A and B for each one.


First, know that 0x0203CE7C holds the item ID of the item you're using. That offset is in r5 at the beginning of both routines. Here's what I'd do in routine A to optimize it.
Code:
get_correct_script:
    ldrh r0, [r5]
    ldr r2, table_of_scripts
    mov r3, #0xFF
    lsl r3, #0x8
    add r3, #0xFF
loop_start:
    ldrh r1, [r2]
    cmp r0, r1
    beq continue
    cmp r1, r3
    beq abort
    add r2, #0x6
    b loop_start
continue:
    ldr r0, [r2, #0x2]
table_of_scripts is a table, obviously. It's structured like so; [item id, hword] [corresponding script offset, word]. This way, we'll scan down the table and check to see which script to use with the loop. r0 would hold the correct script's offset after the ldr r0, [r2, #0x2]. r3 would contain FFFF, which'd be the end of the table, and you'd have to find some way to leave the routine if there's no script to run. You can get rid of the r3 parts, but then the game would definitely crash every time there's not a correct entry for that item. This method is a LOT smaller than 88 bytes per item with a script attached.
I've no idea what bugs you're talking about, I tested it and it works well. Upon using the item, the bag closes, screen fades and you're back in overworld when the script will run. Make sure, you inserted everything correctly.

I don't like the idea of reading from a table, because as I said, this method allows you to run script as well as ASM code. My method is also exactly how the game does it as it's a copy of the wailmer pail routine. Besides 88 bytes isn't a lot at all.

EDIT: Found the bug, try it out now.
Reply With Quote
  #4    
Old March 21st, 2016 (9:13 AM).
NewDenverCity's Avatar
NewDenverCity NewDenverCity is offline
 
Join Date: Apr 2014
Location: Antarctica
Gender: Male
Nature: Calm
Posts: 195
Quote:
Originally Posted by DizzyEgg View Post
I've no idea what bugs you're talking about, I tested it and it works well. Upon using the item, the bag closes, screen fades and you're back in overworld when the script will run. Make sure, you inserted everything correctly.

I don't like the idea of reading from a table, because as I said, this method allows you to run script as well as ASM code. My method is also exactly how the game does it as it's a copy of the wailmer pail routine. Besides 88 bytes isn't a lot at all.

EDIT: Found the bug, try it out now.
Tested, it's fixed now, thanks.


I don't agree though, having 88 bytes for every instance of that seems wasteful. Also, if you want to use ASM, then you can check for that item's ID after you'd loaded the ID from r5, and skip the loop. Am I wrong?
Reply With Quote
  #5    
Old March 21st, 2016 (9:42 AM).
C me's Avatar
C me C me is online now
Creator of Pokemon League Of Legends
 
Join Date: Jan 2014
Age: 19
Gender: Male
Posts: 486
What's wrong with this version? It's the one I've used.
Reply With Quote
  #6    
Old March 21st, 2016 (10:06 AM).
DizzyEgg's Avatar
DizzyEgg DizzyEgg is offline
 
Join Date: Feb 2014
Age: 18
Gender: Male
Nature: Quiet
Posts: 225
Quote:
Originally Posted by C me View Post
What's wrong with this version? It's the one I've used.
It's basically the same as my routines, but it's shorter. I wasn't aware there already existed a routine for EM, so I made mine.
Reply With Quote
  #7    
Old March 29th, 2016 (6:04 PM).
i0Bjhansen0 i0Bjhansen0 is offline
 
Join Date: Mar 2016
Gender: Male
Posts: 32
Hey, I'm trying to make a new item that uses HackMew's Shinyzer code that, on use, will make the next wild Pokemon shiny.
I tried doing a simple
Code:
#dynamic (offset)

#org @start
setvar 0x8003 0x1
msgbox @active 0x6
end

#org @active
= Next [PO][MN] is shiny.
Had the offset given put into the field section for the item in G3T.

I used the item and it restarted the ROM. Now I'm completely new to scripting so any help would be appreciated. I don't need it to exit the item menu, just a simple message box like the one that pops up when you can't use the item. And I didn't know what offset to go to on XSE to see what other items do so I could copy and alter to the new item.
Reply With Quote
Reply Post Reply
Quick Reply

Sponsored Links
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


  All times are GMT -8. The time now is 4:24 PM.


Contact Us Archive Privacy Statement Terms of Service Top