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

[Script] End of Battle scripts - is it possible?

8
Posts
7
Years
    • Seen Dec 26, 2016
    Hey! Sorry for multiple threads, I'm in the groove and I've been making a ton of progress on my FireRed mod (well, at least on the tools and techniques required to make it happen haha!)

    Anyways, my question is pretty simple. I want to insert a script at the end of EVERY battle, or whenever the map loads but the battle is over. I need this on wild pokemon, it'd be preferable not to have it on trainers (though I'm willing to compromise). Is this possible?

    I want to use the script to force the player into discarding all their pokeballs (and other various forms) at the end of a battle. This way they're forced to use the Pokeball in the battle or risk losing the chance to catch the pokemon.

    It's part of a Nuzlocke challenge script that I'm adding as an optional in my FireRed script. So far I have succeeded in making fainted pokemon get deleted when a zone is changed and locking players into a new route when they access it for the first time (if they're carrying a pokeball, they're not allowed to leave). I was thinking that when they end the battle, removing the pokeball would work.

    Alternatively, if there's a "Start of battle" area I can put my script into, that would work as well, I would just have to create a var that says at the start of battle, if the flag isn't set, they discard their pokeball. Then set the flag next, so that it doesn't discard their pokeball if it's the first battle. This would be fine.

    Any advice is welcome :) In the meantime... I'm going to continue trying to google a solution..


    edit: if this isn't possible, then I'm considering forcing a wild encounter on a new route whenever the player enters a new route. This I think is do-able and much easier since it would be a one-off event triggered by the player stepping on a scripting tile (which automatically gives them a pokeball, starts a wild encounter, and flags so you can't get the pokeball again). This is a workaround but I'm not partial to it, I really would like players to be able to go up and use their old rods so they can get water types or something like that.. which requires the 'discard at end of battle' problem I'm looking at above.

    edit2: I think I'm going to try the method I mentioned in the last edit. However, I might give the player the option to engage in a water or grass battle, on any routes after they have successfully obtained the Old Rod. This can allow players to get water pokemon from the zones without altering anything else in the game too much. Really, I'd still love to find a way to access the 'end of battle' region of scripting.

    Code:
    tile pseudoscript 1
    if flag is 0
    	Give pokeball
    	Engage in wild battle (water or grass?)
    	set flag to 1
    if flag is 1
    	Remove pokeball(s)
    	set flag to 2
    if flag is 2
    	release
    end
     
    Last edited:

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • .align 2
    .thumb

    @hook via r0 @08056568

    main:

    @if a script is running wait
    ldr r0, =(0x3000F9C)
    ldrb r0, [r0]
    cmp r0, #0x1
    beq noCrash

    @check if script should run
    ldr r0, =(0x20370CE)
    ldrh r1, [r0]
    cmp r1, #0x0
    bne loadScript

    noCrash:
    @hook cleanup
    ldrh r0, [r4, #0x2E]
    ldrh r1, [r4, #0x2C]
    ldr r2, c1_overworld_normal
    bl linker
    pop {r4}
    pop {r0}
    bx r0


    loadScript:
    @reset var value since this is run every frame almost
    mov r2, #0x0
    strh r2, [r0]

    @calculate script to run
    sub r1, r1, #0x1
    lsl r1, r1, #0x2
    ldr r0, ScriptTablePointer
    add r0, r0, r1
    ldr r0, [r0]

    @script executer
    ldr r2, =(0x8069AE4 +1)
    bl linker
    b noCrash

    linker:
    bx r2

    .align 2

    ScriptTablePointer:
    .word 0x8900000

    c1_overworld_normal:
    .word 0x805644C +1

    writing an index value to 0x20370CE, will execute a script in the script table at that index when next possible. You can use it for level scripts, executing scripts when another script finishes, or as you want to, execute after a battle.
     
    8
    Posts
    7
    Years
    • Seen Dec 26, 2016
    Cool thanks :) I'm learning how to insert these routines into the ROM, so this is a bit advanced for me, but I'm not opposed to learning. I thought I might need to learn how to insert ASM routines anyways, so this is just another level of improvement for me. (I also see you wrote a tutorial on how to insert them so my questions are done for now haha) Thanks FBI I'll try to figure out how to work these things and if I have any more questions I'll let you know :)
     
    8
    Posts
    7
    Years
    • Seen Dec 26, 2016
    @FBI

    I don't think I'm understanding this properly..

    I made a test script that is basically a msgbox "hello world"


    Code:
    #dynamic 0x900000
    
    #org @start
    msgbox @blah 0x6
    end
    
    #org @blah
    = Test.  End of battle?

    Let's say it compiles to pointer 800000..

    I should add your assembly routine to the game, but replace 0x20370CE with 0x800000? Or 0x010080?

    And if I do that properly, it will run that script at the end of battle?

    I'm sorry if my questions seem obvious or easily answered.. But I've been stuck on this for hours now, googling everything and trying to learn as much as possible.

    I've been using the following tutorials to get the ASM into my game:
    https://www.pokecommunity.com/showthread.php?t=313906
    https://www.pokecommunity.com/showthread.php?t=117917 ([TUT] Having fun with ASM section)
     
    8
    Posts
    7
    Years
    • Seen Dec 26, 2016
    I'm still not able to figure out how to get this to work.. Unfortunately getting the nuzlocke challenge to run properly really requires this end of battle script (to delete pokeball items from inventory at end of battle if the nuzlocke flag is set). I guess I could make a level script that runs on every step and that deletes pokeballs? But that might lag the game or freeze the player, seems like it won't work..
     

    Bonnox

    Time (wasting) Lord
    47
    Posts
    8
    Years
  • I didn't know this topic even existed, until someone in my country asked me how to insert that exact routine, so I'm sharing my (not tested) answer.



    I think all you have to do is the classic
    ldr r0, offset
    bl link

    link:
    bx r0
    where offset is the number in the first comment of FBI's code.

    the syntax of my code obviously is not correct to speed up the writing, but the overall semantic does.

    this came to my mind thanks to the use of the word "hook", which in this forum has de facto acquired the meaning of "personalized code injection". This theory is confirmed since in the original ROM, at that offset there are some operations, which are indeed carried out more or less at the middle of FBI's routine.

    dissecting my assembly, it would take 2+4+2+4 = 12 bytes, and if you open VBA disassembler, you see that we have 14 bytes, counting the moved operations (infact he moved them to make room for the call).

    tell me if it works ;)
     
    Last edited:

    Touched

    Resident ASMAGICIAN
    625
    Posts
    9
    Years
    • Age 122
    • Seen Feb 1, 2018
    I didn't know this topic even existed, until someone in my country asked me how to insert that exact routine, so I'm sharing my (not tested) answer.



    I think all you have to do is the classic

    where offset is the number in the first comment of FBI's code.

    the syntax of my code obviously is not correct to speed up the writing, but the overall semantic does.

    this came to my mind thanks to the use of the word "hook", which in this forum has de facto acquired the meaning of "personalized code injection". This theory is confirmed since in the original ROM, at that offset there are some operations, which are indeed carried out more or less at the middle of FBI's routine.

    dissecting my assembly, it would take 2+4+2+4 = 12 bytes, and if you open VBA disassembler, you see that we have 14 bytes, counting the moved operations (infact he moved them to make room for the call).

    tell me if it works ;)

    FBI said to "hook via r0 @08056568" at the top of the routine. That means you go to 08056568 and write:

    Code:
    ldr r0, =offset|1
    bx r0

    The routine FBI provided is not written as a function, so it cannot be called with BL. Besides, even if you were able to call it using the BL/BX combo it your code would not work since it would return and then immediately attempt to jump to the returned value.
     
    352
    Posts
    7
    Years
    • Seen Mar 10, 2022
    writing an index value to 0x20370CE, will execute a script in the script table at that index when next possible. You can use it for level scripts, executing scripts when another script finishes, or as you want to, execute after a battle.

    The routine works perfectly, but what about executing it at the end of the battle? We need to edit the battle script?
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • The routine works perfectly, but what about executing it at the end of the battle? We need to edit the battle script?

    It depends on what type of battle. If it's a scripted trainer/legendary/wild battle, you merely need to set the variable before the battle commences. However, for trainers(that walk up to you) and wild Pokemon, setting the variable during the battle is necessary (like in this nuzlocke idea for example). There are a lot of places where you can safely set the variable, so I'll leave that to you.


    also..
    Naksile, sorry dude I didn't receive a notification for your question. You need to quote me next time! :D
     
    352
    Posts
    7
    Years
    • Seen Mar 10, 2022
    It depends on what type of battle. If it's a scripted trainer/legendary/wild battle, you merely need to set the variable before the battle commences. However, for trainers(that walk up to you) and wild Pokemon, setting the variable during the battle is necessary (like in this nuzlocke idea for example). There are a lot of places where you can safely set the variable, so I'll leave that to you.

    Sorry, I haven't specified. In my case I need it for normal grass/water/fishing/special wild battles (not scripted), then I think it could be more difficult, because I need to run the script at the end of each normal wild battle, I will take a look at the routines of grass/water/fishing/special wild battles to see what I need to do to make it possible.

    Possible or not, this routine is simply awesome, and it can make a lot of things possible. ^^
     
    Last edited:

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • Sorry, I haven't specified. In my case I need it for normal grass/water/fishing/special wild battles (not scripted), then I think it could be more difficult, because I need to run the script at the end of each normal wild battle, I will take a look at the routines of grass/water/fishing/special wild battles to see what I need to do to make it possible.

    Possible or not, this routine is simply awesome, and it can make a lot of things possible. ^^

    Just hook after the wild pokemon rolling function and set the var.
     
    Back
    Top