• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Trading Card Game 2 protagonist in the poll by clicking here.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Running a script via item [EM]

  • 794
    Posts
    11
    Years
    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:

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

    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.
     
    Last edited:
    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:

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

    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.
     
    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.
     
    Last edited:
    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?
     
    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.
     
    Back
    Top