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

Code: ASM Resource Thread

Blah

Free supporter
1,924
Posts
11
Years
  • Field Moves


    This, I think, deserves it's own thread. However, since I'd have about 90 threads by now if I followed that logic, I'm just going to make a post. I hope to cover how to add any arbitrary field move in addition to some research notes on the matter. This requires a little bit of patience and some table repointing/hex work in order to do. I should say that it's nothing hard, the hardest thing would be repointing a table, which is relatively easy. If you don't know how to do those hex manipulations, ask at the quick question thread, and hopefully myself or someone else will answer.

    Research for Nerds:


    Hi, if you're a noob just passing through trying to insert this without caring about the technical details, you can skip this section. Here I will be explaining as much as I know about the BRM for those who want to improve it or are generally curious about how it works in general.

    The BRM menu is by far one of the more complicated data structures in the game. It's handled by several separate RAM and ROM data structures which I will attempt to explain. The first one is the BRM's RAM data structure. There are a few attributes which this structure contains, the main one, the one we care about in this case is the cursor's position. It's given in 0203B0A9 and changes depending on which Pokemon you're hovering over. In the case you're in a selection where there are more than one Pokemon to be selected, the byte next to it will hold the second selection. This byte is used (when the player presses the "A" button) to derive other menus and checks by using the simple formula: 0x2024284 + (0x64 * byte) to get the Pokemon.
    There are a few others which are used to determine other things, which I don't be explaining in detail, mainly due to lack of my remembering (did this more than a month ago).

    Once the Pokemon is selected using the "A" button, contrary to initial belief, the BRM is generated on the spot, then graphically generated right after. Initially when "A" is pressed, the game loops through the 0x0 terminated Move IDs table comparing each half-word represented move to each move the Pokemon selected has at the function 0x81229FC. If a move is found, then it will store it in a RAM data structure (same BRM structure) which works very similarly to the start menu. This routine handles Pokemon holding mail too.

    With the given data structure fully formed the BRM is graphically created. There are some other things that go into it to pull up the "summary, cancel, item" fields and such (byte toggled in the BRM) but I'm not going to go too deeply about that. Anyways, the BRM RAM structure then handles the browsing of this smaller menu. Once "A" is pressed, the BRM table is used to determine which function to execute. It's format is [string pointer][routine pointer]. The HMs are at the end of this table. 0x81245A4 handles teh case where the selected item in an HM. It does things from badge checking to calling the actual routine, specific to the HM.

    In general, you can edit the table for the BRM to change a function to execute a routine of your choosing. However, remember that you need to follow the correct procedures which including closing the BRM and exiting to Overworld ect. The graphics generation and such are left to you if you follow this method. Initially, this is the method I was using.

    With some research, and studying, I was able to determine how the BRM item selection worked for HMs which excited to the overworld and called a routine. From there I was able to call a routine which ran a script.

    Basically, there were other RAM locations allocated to hold routine pointers which were executed by the game at certain times. Cut for example, would first check the map, the tiles infront of the player (if they were grass), the coords infront of the player, ect. before executing. From there, there were two cases which executed differently. Believe it or not, cut does not always execute a script. The first method is that it sets the tiles infront of the player to plain grass (so it actually cuts wild grass, try it yourself by walking into a patch of grass and using CUT !), the second case it executed the script.

    I think it's better to read the rest of the tutorial to see how those things work, rather than listening to my kinda long explanations.


    Repointing some tables (noob friendly edition):


    Before we begin, there are a few tables which need repointing. Please write down the offsets to where you paste the hex I give you. For your sake, once again, please write down where you place these tables to.

    Table 1: Move IDs table:

    Copy and place into free space:
    Make sure the offset you copied this table to is half-word divisible (ends in 0, 2, 4, 6, 8, A, C, E)
    Code:
    94 00 0F 00 13 00 46 00 39 00 F9 00 7F 00 64 00 5B 00 D0 00 87 00 E6 00 0C 00


    Now navigate to 0x122A7C and change the reverse hex pointer to be the pointer where you copied the above hex table to.

    Table 2: Launch Pad routine table + properties

    Copy and place into free space:
    Make sure the free space offset is word divisible (ends in 0, 4, 8, C)
    Code:
    2D 9B 0C 08 0D 00 00 00 99 78 09 08 07 00 00 00 8D 4A 12 08 0D 00 00 00 ED 07 0D 08 0D 00 00 00 99 49 12 08 08 00 00 00 D9 99 0C 08 0D 00 00 00 F9 4A 12 08 0D 00 00 00 F1 66 0F 08 0D 00 00 00 79 9A 0C 08 0D 00 00 00 85 56 0E 08 10 00 00 00 85 56 0E 08 10 00 00 00 C9 E0 0D 08 0D 00 00 00
    Now navigate to 0x124614 and 0x124680 and change the reverse hex pointer to be the pointer where you copied the above hex table to.

    Table 3: BRM names + launcher

    Copy and place into free space:
    Make sure the free space offset is word divisible (ends in 0, 4, 8, C)
    Code:
    94 69 41 08 4D 2D 12 08 8D 69 41 08 01 2E 12 08 C1 61 41 08 41 36 12 08 D4 61 41 08 A1 36 12 08 B2 61 41 08 05 37 12 08 DE 61 41 08 39 3C 12 08 D9 61 41 08 F5 3C 12 08 B2 69 41 08 0D 3E 12 08 B7 69 41 08 59 3D 12 08 C1 61 41 08 65 40 12 08 7E 69 41 08 F5 40 12 08 84 69 41 08 F5 40 12 08 A3 69 41 08 55 41 12 08 A9 69 41 08 79 42 12 08 E3 61 41 08 55 43 12 08 F4 B6 41 08 85 43 12 08 BC 69 41 08 91 44 12 08 BC 69 41 08 A1 45 12 08 18 78 24 08 A5 45 12 08 57 71 24 08 A5 45 12 08 8B 71 24 08 A5 45 12 08 22 74 24 08 A5 45 12 08 79 73 24 08 A5 45 12 08 39 7D 24 08 A5 45 12 08 07 77 24 08 A5 45 12 08 A8 75 24 08 A5 45 12 08 33 75 24 08 A5 45 12 08 24 7B 24 08 A5 45 12 08 6F 77 24 08 A5 45 12 08 42 7C 24 08 A5 45 12 08
    Now navigate to 0x120F74, 0x121FB8, 0x122D18, 0x122D48 and change the reverse hex pointer to be the pointer where you copied the above hex table to.

    Table 4: Field move description pointers table

    Copy and place into free space:
    Make sure the free space offset is word divisible (ends in 0, 4, 8, C)
    Code:
    83 75 41 08 33 75 41 08 48 75 41 08 6E 75 41 08 5D 75 41 08 96 75 41 08 AE 75 41 08 FB 75 41 08 CC 75 41 08 F1 75 41 08 F1 75 41 08 DE 75 41 08
    Now navigate to 0x1221D0 and change the reverse hex pointer to be the pointer where you copied the above hex table to.

    That's all for table repointing. I hope you wrote down the offsets for them in some recognizable format. I.e:
    Table 1: Offset
    Table 2: Offset
    Table 3: Offset
    Table 4: Offset
    Because that's how I will refer to them AND we'll need them very soon.


    Making your move's script -> The fuel


    You are lucky. You are lucky I suffered many hours figuring this out so you can use scripts rather than routines and have an easy time setting up field moves. Anyways, the first step is to write out your script which you will be using. In this "tutorial/resource/research" thing I will be inserting Sunny Day in an attempt to give a relevant example of how to set things up.

    Here's my PKSV script:
    Spoiler:


    If you're lost at the script, or don't know how to make a script, then you'd better go learn! This script is admittedly, a little more complicated than what I'd expect people to use. Its because I'm using some scripting and ASM knowledge to determine whether or not we're indoors. It's a special case only relevant to weather effects. The rest of the script is normal. Note that your script can be pretty much anything, but please beware of the recursion limits (i.e calling callasm and that ASM calling a script...ect..).

    Once you've written the script, compile it to free space, and write down where you've compiled the script. Mine compiled to 0x740001 for example.


    Setting up our Phase 2 routine -> The Rocket


    Once you've compiled a suitable script, and tested the script individually to make sure it works, you're ready to set up your rocket. I call it Rocket because this routine will be the one calling the script.
    It will also be the routine which is called by our launchpad routine. Anyways, more on that later.

    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    
    main:
    	push {r4, lr}
    	ldr r0, =(0x203B0A0)@selected mon
    	ldrb r0, [r0, #0x9]
    	ldr r1, =(0x20386E0) @oe state
    	lsl r0, r0, #0x18
    	lsr r0, r0, #0x18
    	str r0, [r1]
    	ldr r0, =(0x8YYYYYY) @script pointer, don't +1
    	ldr r4, =(0x8069AE4 +1)
    	bl linker
    	pop {r4, pc}
    	
    linker:
    	bx r4
    	
    .align 2

    In the above routine, you will need to modify the script pointer line. Change the YYYYYY into the offset your script was compiled into. Once you've done that, simply compile the routine into free space.
    Once again, write down the offset in which you've compiled the routine into and make sure you've inserted this routine into a word aligned offset.


    Setting up our Phase 1 routine -> The Launchpad


    This routine is going to be our Phase 1 routine. This routine will do the initial checks we want and then call the rocket routine. Actually, this structure is a little weird, because you can just as easily fulfill it's functionalities within the second routine. I've yet to figure out the reason as to why this is, but it just is this way.

    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    
    main:
    	push {lr}
    	ldr r1, =(0x3005024) @Phase 1
    	ldr r0, =(0x81248B0 +1) @launch pase 2
    	str r0, [r1]
    	ldr r1, =(0x203B0C4) @Phase 2
    	ldr r0, =(0x8YYYYYY) @Rocket routine
    	str r0, [r1]
    	mov r0, #0x1
    	pop {r1}
    	bx r1
    	
    .align 2

    In the above routine, you will need to modify the Rocket routine line's "0x8YYYYYY" into a pointer to wherever you placed the Rocket 2 routine +1. Once you've done that compile this routine into free space. Make sure that this routine is compiled into a word aligned offset.

    String setup


    Our last task before modifying some tables is to set up the string descriptions which will be brought up when the move is hovered over. The first task is to create the string. My string will be,
    "Makes it Sunny outside!". This in Hex is "C7D5DFD9E700DDE800CDE9E2E2ED00E3E9E8E7DDD8D9AB". Lastly, the game doesn't know how long or when the string ends. It's required that we specify this by using the string terminating character.
    This in FireRed (and actually all ROMs in gen III) is 0xFF. So the string then becomes "C7D5DFD9E700DDE800CDE9E2E2ED00E3E9E8E7DDD8D9ABFF". If you're not sure how to convert an ASCII string to HEX without messing it up, then I'll tell you that there's a 1-1 correspondence between the two. Use this table to generate a string, or you can use this Python program I wrote (if you have Python).

    Remember that the size of the string is also limited. I don't recall how many characters will fit before overflow, but keep it about 20 Characters long max.

    Table:
    Spoiler:


    Python program:
    Spoiler:


    Paste your Hex string into some free space in the ROM.

    Next, we need to find our Move's name in hex. I recommend finding it in the Move name table at 0x247094. Here's a simple formula you can use to find it:
    Offset = 0x247094 + (0xD * MoveID)
    Where MoveID is the move index number. Pound is 0x1 for example. It should be noted that if you have expanded the move tables via MrDS's patch or on your own, that 0x247094 won't be the correct offset. Actually, I think his patch is bugged here because the BRM table uses points in the old table, which he couldn't possibly have repointed without knowing. Anyways, it doesn't prove a problem unless you plan to make one of the expanded move names to appear using the move name table. Write down the offset of your move name as well as the description pointer.

    Editing the tables


    Here are the important offsets you should have written:
    Table 1-4 locations
    Phase 1 routine: Launcher
    Move Description pointer
    Move Name pointer

    Firstly, we're going to handle Table 1 first. This is a table of reversed half-word move IDs. The game reads these ID numbers using ldrh (load half-word) which internally reverses them. ldr is the same functionality, that why we need to reverse hex our routine pointers and various other things. Anyways, I'm getting off topic, so I'm going to explain what to do to this table.

    The table itself is 0C 00 terminated, which is both weird and bad. Weird because 0xC is Guillotine, bad because someone may be interested in using Guillotine as a field move. So first of all, before we attempt anything, we'll be changing how the game reads this table, to terminate it upon reading 0x0 (which in the hex editor is 00 00 because it should be a half word), since 0x0 represents null move.

    To do this, navigate to 0x122A8C and change the byte from 0C to 00.

    Finally, edit your table to include the Move IDs of the field moves you want. My table for example looks like this right now:
    94 00 0F 00 13 00 46 00 39 00 F9 00 7F 00 64 00 5B 00 D0 00 87 00 E6 00 F0 00 59 00 57 00 C9 00 00 00

    I've added after E6 00 (which is ID 0xE6 sweet scent) F0 00 59 00 57 00 C9 00 F1 00 00 00
    F0: Rain dance, 59: Earthquake, 57: Thunder, C9: Sandstorm, F1: Sunny day. Then at the end I put in the "00 00" to show the end of the move detection table. Make sure your table is of similar format, except with the move IDs you want.

    After these edits go in game, and check if your game freezes upon pressing "a" on the selected Pokemon. If it does, then your table is messed up OR you've messed up something with these last few steps. The expected result is that you get weird characters (or no chars at all) in blue if your Pokemon has a move whose ID is in the table. We will be fixing these "glitched" names and such soon. Don't try using the move outside of battle yet, because you will crash your game.


    We're going to briefly skip table 2, and go onto table 3.
    This table is a little weird, because it's not terminated at all. It's browsed using an index number. Generally the moves are at the bottom, and each successive move in the move ID table is 1 entry past the last entry. So in short, for every move we add the the move ID table (table 1) we need to add an entry to this table (table 3).

    Table 3 is formatted: [4 bytes (Pointer to name)] [4 bytes (Pointer to Routine)]

    If you're doing to launch a routine instead of a script, the pointer to routine will be your routine's address +1. The chances are, you're going to use a script though. So farmat your entries like this:
    [Move name pointer (4 bytes)][081245A5 - BRM HM launching sequence].
    Navigate to the word aligned offset you placed table 3 in, and add the following 8 bytes:
    Code:
    XX XX XX 08 A5 45 12 08
    Where XX XX XX is a pointer to your moves name (which you should've written down prior). In my case, the hex was, "D1 C7 24 08 A5 45 12 08".

    After these edits, test it again. This time the blue gibberish should've turned into a move name. If it hasn't, you've messed up somewhere above.

    Now we'll edit table 2, this will make selecting the move actually do something.
    Table 2 consists of a routine pointer that is called by the routine 081245A4, as well as a mode. 95% of the time this mode is 0xD (the other mode is 0x10 used for Milkdrink and Softboiled). The routine pointer is simply going to be a pointer to Phase 1 routine: Launcher (which you should have written down). Like table 3, this is browsed by index and isn't terminated by a byte or sequence of bytes. So simply add to the end of the table, the following hex string:
    Code:
    XX XX XX 08 0D 00 00 00
    Where XX XX XX is a reverse hex pointer to Phase 1 routine: Launcher.

    After these edits, test your game again. This time, everything should be fully functional. Routine should be called, and the whole effect should happen. If it doesn't, you've done something wrong in the above steps.

    Finally, we're on the last step, it's to change the move description which pops up when the move is highlighted. The Move Description pointer which you should have written down is what I'm referring to.
    In Table 4, simply append the move description pointer. That's it, you've successfully added a new field move!

    My condition for using this hack

    Unlike most hacks, this is a little different. It's open source, and you're free to use it. However, I require you post the script you use for any of your moves. This is because I want people to keep anything regarding this hack public.
    Just post the script you use in your own thread, and that'll be it (like the Sunny Day script I used).
     
    Last edited:

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • Button detection in scripts



    Intro:
    There are a few hacks already existing which detect a button the player has pressed, but in my opinion they are a little over-complicated and unnecessary. There's a few RAM offsets which are allocated for I/O placed in the SuperState datastruture and keyinput bytes. However, reading these bytes in a script would give you the byte value in that specific frame. That's right, scripts run one command per frame (mostly. wait special, and other commands "pause" the cycle because the script pointer isn't updated). Anyways, inorder to do this, you'd need to write a task (which is also executed every frame) which detects a certain keypress. However, there already exists a command which pauses until a button is pressed. This command is the "waitbutton" command in PKSV or the "waitkeypress" command on XSE. We're going to be hacking this command to buffer the non-null button pressed into a variable.

    How to insert:

    First compile and insert into free space, the following routine
    Spoiler:


    Now navigate to 0x6B89A and do the following byte changes:
    Code:
     00 00 00 48 00 47 XX XX XX 08
    Where XX XX XX is the pointer to wherever you inserted this routine +1

    Usage:

    Basically you just call the waitbutton command and then read the variable 0x8000 to see which button was pressed. Here's an example script:

    Code:
    #dyn 0x740000
    #org @start
    lock
    faceplayer
    msgbox @exit
    callstd MSG_NORMAL
    jump @loop
    
    #org @loop
    waitbutton
    compare 0x8000 0x2
    if != jump @start
    msgbox @good
    calllstd MSG_NORMAL
    release
    end
    
    #org @exit
    = You can't leave without\npressing "B"!!!
    
    #org @good
    = Alright, now you can go.

    Here is what 0x8000 would yield depending on what was pressed.
    Code:
    Down: 0x80
    Up:  0x40
    Left: 0x20
    Right: 0x10
    A: 0x1
    B: 0x2
    Select: 0x4
    Start: 0x8
    Please note, if two keys are pressed at once or held at once, then 0x8000 will be the sum. I.e 0x8000 = 0x3 if A and B is pressed.
     

    leyn09

    Truant Trainer
    84
    Posts
    13
    Years
  • Battle Modes!


    Battle by turn:


    This routine will run all of it's referenced routines at the end of the turn (right before the turn counter in incremented.

    How to insert:
    Look at the routine below. The last line .table has an incomplete pointer. It says 0x[pointer to routine table]. Find enough free space (takes 4 byte per routine) in your ROM and set the pointer for .table to that. You do not add +1 to the pointer, nor is it in reverse hex. Once you've fixed the pointer, compile the routine into free space.
    Last entry in the table needs to be 00 00 00 00.

    Credits to daniilS for helping with optimization.
    Spoiler:


    Now navigate to 0x13CB0 and insert the following byte changes:
    Code:
    00 48 00 47 XX XX XX 08


    Usage:
    The routine is toggled by flag 0x2F8. Activate the flag to toggle routines called by this routine. To add routines into the list of called routines, navigate to the pointer of freespace you made .table point to. Insert into that table pointers in reverse hex +1 to wherever you compiled the addon routines make sure they have the 0x8 prefix. The structure of the table should be: [routine pointer in reverse hex +1 (4 bytes)] for each pointer in the table. I.e if I put the addon at 0x740000, the pointer would read 01 00 74 08.

    Battle by turn addons:


    Sleeping clause:
    Spoiler:


    Battle end by turn:
    Spoiler:

    I have a little problem with this sleep clause. As the post requires, I need to put battle by turn routine, the table pointer, and the sleep clause routine in my rom. So I put these in the following addresses:

    1. Battle by turn routine: 850000
    2. BbT table: 850040 (I already put at the first entry the sleep clause routine)
    3. Sleep clause routine: 800050
    Spoiler:


    Then I insert 00 48 00 47 41 00 85 08 to 0x13cb0
    Spoiler:


    So, I'm about to test it but I'm not able to because whenever I battle a trainer/wild encountered pokemon, it freezes or restarts after the first round. Also, there are some cases of resetting when I encounter wild pokemon.

    I direly in need of these sleeping clause. Btw, I used MrDollSteak Rom base and JPAN's fire red Hacked Engine.

    Thanks in advance!
     
    534
    Posts
    11
    Years
    • Age 26
    • Seen Jul 24, 2023

    HP Regeneration per step


    Intro:
    Basically a routine to regenerate a Pokemon's HP every step. In this routine it's set to 3 per step. You may want to modify the exact amount to a percentage or something (see the commented line).

    How to insert:

    First compile and insert the following routine into free space.

    Spoiler:

    Now in a hex editor navigate to 0x6D5F6. There you will need to insert the following byte changes:
    Code:
     01 4A 10 47 00 00 XX XX XX 08
    Where XX XX XX is the pointer to where you inserted the above routine +1.

    Usage:

    There isn't any usage. It's automatically done. You can change the amount generated by reading the line in the code which I've commented.

    I'm not sure why but I can't get this to compile. I get a message from the compiler like this:

    Code:
    Error: instruction not supported in Thumb16 mode -- 'lsls r0, r0, #0x18'
    Error: instruction not supported in Thumb16 mode -- 'lsrs r0, r0, #0x18'

    I don't know if that was a typo, or my compiler just came from the stone age. Please help.
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • I'm not sure why but I can't get this to compile. I get a message from the compiler like this:

    Code:
    Error: instruction not supported in Thumb16 mode -- 'lsls r0, r0, #0x18'
    Error: instruction not supported in Thumb16 mode -- 'lsrs r0, r0, #0x18'

    I don't know if that was a typo, or my compiler just came from the stone age. Please help.

    I've fixed it. My brain went IDA mode when I wrote that, so accidentally did lsls instead of lsl, ect. :P
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • I have a little problem with this sleep clause. As the post requires, I need to put battle by turn routine, the table pointer, and the sleep clause routine in my rom. So I put these in the following addresses:

    1. Battle by turn routine: 850000
    2. BbT table: 850040 (I already put at the first entry the sleep clause routine)
    3. Sleep clause routine: 800050
    Spoiler:


    Then I insert 00 48 00 47 41 00 85 08 to 0x13cb0
    Spoiler:


    So, I'm about to test it but I'm not able to because whenever I battle a trainer/wild encountered pokemon, it freezes or restarts after the first round. Also, there are some cases of resetting when I encounter wild pokemon.

    I direly in need of these sleeping clause. Btw, I used MrDollSteak Rom base and JPAN's fire red Hacked Engine.

    Thanks in advance!

    I think you forgot the 08 prefix in the BBT table when compiling the BBT routine.
     
    534
    Posts
    11
    Years
    • Age 26
    • Seen Jul 24, 2023
    I've fixed it. My brain went IDA mode when I wrote that, so accidentally did lsls instead of lsl, ect. :P

    Alright, now I don't know what I've done wrong. I just compiled your newly changed routine and for somewhat reason, the game freezes on my player's first step.

    These are what I did.

    Spoiler:


    And also, me too, I'm having problems with the BBT and HP Regen Addon for it.

    Spoiler:
     
    Last edited:

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • Alright, now I don't know what I've done wrong. I just compiled your newly changed routine and for somewhat reason, the game freezes on my player's first step.

    These are what I did.

    Spoiler:


    And also, me too, I'm having problems with the BBT and HP Regen Addon for it.

    Spoiler:

    I made a small edit to the original step based HP thing. Try it again. As for the battle by turn thing, there could be a lot of reasons. I can't check without first looking at your ROM. Anyways, I'm going to go take another look at the battle by turn routine (even though it was working for me) it seems I may have broken it during transfer. I'll look at it and get back to you.
     
    534
    Posts
    11
    Years
    • Age 26
    • Seen Jul 24, 2023
    I made a small edit to the original step based HP thing. Try it again. As for the battle by turn thing, there could be a lot of reasons. I can't check without first looking at your ROM. Anyways, I'm going to go take another look at the battle by turn routine (even though it was working for me) it seems I may have broken it during transfer. I'll look at it and get back to you.

    Did it, still to no avail. It freezes on the first step I take whenever I have a Pokemon with damaged HP. Also, I'm not sure if this helps in any way, but my compiler actually says this everytime I compile your HP Regen per Step, BBT and BBT Addon HP Regen routines:

    Code:
    Warning: end of the file not at end of the line; newline inserted

    P.S. Sorry for the trouble you're going through because of me and thank you for your hard work. :)
     

    GoGoJJTech

    (☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)
    2,475
    Posts
    11
    Years
  • Did it, still to no avail. It freezes on the first step I take whenever I have a Pokemon with damaged HP. Also, I'm not sure if this helps in any way, but my compiler actually says this everytime I compile your HP Regen per Step, BBT and BBT Addon HP Regen routines:

    Code:
    Warning: end of the file not at end of the line; newline inserted

    P.S. Sorry for the trouble you're going through because of me and thank you for your hard work. :)

    That warning just means there's no empty line at the end of the file. It doesn't stop compilation or anything, it's just something it looks for that you missed.
     
    132
    Posts
    9
    Years
    • Age 23
    • Seen May 11, 2024
    Alright, hopefully it's okay if I make a request here for FireRed? I'm not sure if this would be considered ASM, but would there be a way to change attacks as you gain more badges? I'm mostly thinking of making HMs more useful here, or making them less useful at first but better later for hacks where you need Surf early on or something. Basically what I'm asking is, would there be a way to change attacks the more badges you have?

    For example, let's take Rock Smash. If you have zero to two badges, it's standard- 40 power, 50% chance of lowering defense. If you have three to six badges, however, it becomes 70 power with a 30% chance to lower defense. From seven to eight badges, it's 90 power with a 10% chance of lowering defense. Would there be a way to do this?
     
    7
    Posts
    9
    Years
    • Seen Mar 7, 2021
    Hey, let me start this post by saying thanks! Awesome thread! I already found a bunch of things I will be adding to my game!

    I am trying to make a game that revolves around the starter pokémon. I was gonna do it with an Emerald ROM but there seems to be a lot more support for Fire Red so I guess I'll do it with Fire Red instead! There are some features I'd like to put in the game but I have no idea how to do it, so I am hereby humbly requesting help.

    The two most important ones are that the starter pokémon should not be able to be stored in the PC or daycare, and as soon as it loses all of its HP the battle should be lost.
    Are these two things possible to do?
    Then it'd also be cool if the starter pokémon was forced to always be the first to enter battle, as if it's always the first in the party.
    And if switching pokémon would be affected by the pokémons speed stat (so a pokémon can be attacked before it has the chance to switch out).

    And then there's also some other things I'd like to put in my game but I'll start by asking for just these :p Don't want to seem too demanding. And by the time I'm done experimenting with routines I might have learned how to do it myself (since they're kind of related to the ones I just requested).

    Thanks in advance!
     
    Last edited:

    MrDollSteak

    Formerly known as 11bayerf1
    858
    Posts
    15
    Years
  • Alright, hopefully it's okay if I make a request here for FireRed? I'm not sure if this would be considered ASM, but would there be a way to change attacks as you gain more badges? I'm mostly thinking of making HMs more useful here, or making them less useful at first but better later for hacks where you need Surf early on or something. Basically what I'm asking is, would there be a way to change attacks the more badges you have?

    For example, let's take Rock Smash. If you have zero to two badges, it's standard- 40 power, 50% chance of lowering defense. If you have three to six badges, however, it becomes 70 power with a 30% chance to lower defense. From seven to eight badges, it's 90 power with a 10% chance of lowering defense. Would there be a way to do this?

    There is definitely away to change the base power and effect accuracy in the battles themselves. You just need to add checks in the damage and effect roll routines, for the move, followed by a simple flag check.

    That being said, getting these changes to be reflected in the move descriptions would be more difficult.
     
    10,078
    Posts
    15
    Years
    • UK
    • Seen Oct 17, 2023
    Alright, hopefully it's okay if I make a request here for FireRed? I'm not sure if this would be considered ASM, but would there be a way to change attacks as you gain more badges? I'm mostly thinking of making HMs more useful here, or making them less useful at first but better later for hacks where you need Surf early on or something. Basically what I'm asking is, would there be a way to change attacks the more badges you have?

    For example, let's take Rock Smash. If you have zero to two badges, it's standard- 40 power, 50% chance of lowering defense. If you have three to six badges, however, it becomes 70 power with a 30% chance to lower defense. From seven to eight badges, it's 90 power with a 10% chance of lowering defense. Would there be a way to do this?

    If you had a stalk of my VM conversation with FBI you can pick out the bits of advice he gave me. I was trying to increase the power of Cut depending on the number of badges you had.

    I got it working in battle, but couldn't get the descriptions to update (and MrDollSteak mentioned). I don't actually know which routine I used in the end ;-; I got frustrated and threw them all in one folder with pretty lackluster names :P.
     
    6,355
    Posts
    18
    Years
    • Seen Apr 16, 2020
    If you had a stalk of my VM conversation with FBI you can pick out the bits of advice he gave me. I was trying to increase the power of Cut depending on the number of badges you had.

    I got it working in battle, but couldn't get the descriptions to update (and MrDollSteak mentioned). I don't actually know which routine I used in the end ;-; I got frustrated and threw them all in one folder with pretty lackluster names :P.

    You could have the power be "--" and the description include "power depends on number of badges" or something.
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • Did it, still to no avail. It freezes on the first step I take whenever I have a Pokemon with damaged HP. Also, I'm not sure if this helps in any way, but my compiler actually says this everytime I compile your HP Regen per Step, BBT and BBT Addon HP Regen routines:

    Code:
    Warning: end of the file not at end of the line; newline inserted

    P.S. Sorry for the trouble you're going through because of me and thank you for your hard work. :)

    At this point I'm not sure if it's the routine or a mistake on your part. I'll have to debug the whole thing soon, normally a test these things to make sure it's right. These days I've been getting quite cocky with myself and just posting them after a first attempt. I apologize about that!

    @the guy who was wondering about BBT: I'll look at it soon too

    Alright, hopefully it's okay if I make a request here for FireRed? I'm not sure if this would be considered ASM, but would there be a way to change attacks as you gain more badges? I'm mostly thinking of making HMs more useful here, or making them less useful at first but better later for hacks where you need Surf early on or something. Basically what I'm asking is, would there be a way to change attacks the more badges you have?

    For example, let's take Rock Smash. If you have zero to two badges, it's standard- 40 power, 50% chance of lowering defense. If you have three to six badges, however, it becomes 70 power with a 30% chance to lower defense. From seven to eight badges, it's 90 power with a 10% chance of lowering defense. Would there be a way to do this?

    The implementations would be kind of specific for each hack (in terms of what powers and such). Actually making it happen is a pretty simple hook. You should be able to do this after reading my ASM tutorial and upto 5/10-ish.

    I could post the routine, but it wouldn't be very scalable unless I complicated it.

    Hey, let me start this post by saying thanks! Awesome thread! I already found a bunch of things I will be adding to my game!

    I am trying to make a game that revolves around the starter pokémon. I was gonna do it with an Emerald ROM but there seems to be a lot more support for Fire Red so I guess I'll do it with Fire Red instead! There are some features I'd like to put in the game but I have no idea how to do it, so I am hereby humbly requesting help.

    The two most important ones are that the starter pokémon should not be able to be stored in the PC or daycare, and as soon as it loses all of its HP the battle should be lost.
    Are these two things possible to do?
    Then it'd also be cool if the starter pokémon was forced to always be the first to enter battle, as if it's always the first in the party.
    And if switching pokémon would be affected by the pokémons speed stat (so a pokémon can be attacked before it has the chance to switch out).

    And then there's also some other things I'd like to put in my game but I'll start by asking for just these :p Don't want to seem too demanding. And by the time I'm done experimenting with routines I might have learned how to do it myself (since they're kind of related to the ones I just requested).

    Thanks in advance!

    I've already done your first request, it's somewhere in this thread. I haven't been updating the first post because I've been putting it off :P

    Unfortunately, I don't really like doing battle routines :/
    The switching after being attacked may actually be a little hard, but if you ask someone who's worked on moves like baton pass, maybe they can help.


    There is definitely away to change the base power and effect accuracy in the battles themselves. You just need to add checks in the damage and effect roll routines, for the move, followed by a simple flag check.

    That being said, getting these changes to be reflected in the move descriptions would be more difficult.
    It's the same difficulty to set the move descriptions number shown :c
    The text for the damage number is still derived from the table in each instance, so if you hook after that derivation, you can adjust it in either case.

    If you had a stalk of my VM conversation with FBI you can pick out the bits of advice he gave me. I was trying to increase the power of Cut depending on the number of badges you had.

    I got it working in battle, but couldn't get the descriptions to update (and MrDollSteak mentioned). I don't actually know which routine I used in the end ;-; I got frustrated and threw them all in one folder with pretty lackluster names :P.

    Maybe after the workshops you can!

    You could have the power be "--" and the description include "power depends on number of badges" or something.
    maybe if ur hack sux
     

    jToTheAvacola

    Banned
    18
    Posts
    9
    Years
    • Seen Sep 4, 2016
    About that, I feel very bad shutting down all of your suggestions, but that seems like a lot of work for a feature that's not even that great. There's already a large amount of space in the PC, and I'm sure to expand it will take hours and hours of work :/

    Capturing Opponent's Pokemon:

    So I was working on making trainer's Pokemon capture-able, and it does this check to see if the Pokemon is capturable, and if it was it'd check to see if it's a trainer's Pokemon. Well, I disabled the check and was successful in capturing a Pokemon that didn't belong to me :P

    Sadly, the Pokemon turned into a bad egg the moment I caught it. The only solution to this was to edit the checksum so it'd make sense again, however that would be a lot of work, and honestly the checksum is calculated relatively frequently. So upon investigation (mostly by Shinyquagsire, thanks for the deduction detective!) we were able to determine the egg was turning bad because the checksum was no longer valid with the player's trainer ID. So, after diving through the code a bit I found the part of the code that overwrote the trainer ID with the player ID. Then it was a matter of disabling it!

    To insert:
    insert the following bytes at the following offsets:
    0x2D496: E0 E0
    0x40B36: 00 00 00 00 00

    To fix the Pokedex bug
    Follow the instructions in this link: https://www.pokecommunity.com/showpost.php?p=8536920&postcount=333

    Here's Brock's Onix :3

    ASM Resource Thread

    So there's no on/off switch for this routine? I want to mimic the pokemon coliseum feature of being able to catch trainer's shadow pokemon. If I can't make it specific to just the shadow pokemon that's fine, but I'd at least need to be able to only make trainer's pokemon catchable during the battles with trainers who have shadow pokemon.
     

    MrDollSteak

    Formerly known as 11bayerf1
    858
    Posts
    15
    Years
  • So there's no on/off switch for this routine? I want to mimic the pokemon coliseum feature of being able to catch trainer's shadow pokemon. If I can't make it specific to just the shadow pokemon that's fine, but I'd at least need to be able to only make trainer's pokemon catchable during the battles with trainers who have shadow pokemon.

    Heaps of ways to go about this, just think creatively. FBI's put up a snag ball routine, all you need to do is make the ball only activate on shadow pokemon. That can be done with comparing index numbers through a table etc.
     

    leyn09

    Truant Trainer
    84
    Posts
    13
    Years
  • I think you forgot the 08 prefix in the BBT table when compiling the BBT routine.

    Thanks! I've made it work but it seems to end the battle in the player's favor after putting two of the opp. pokemon to sleep? Was the code is purposed to behave that way?
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • Thanks! I've made it work but it seems to end the battle in the player's favor after putting two of the opp. pokemon to sleep? Was the code is purposed to behave that way?

    I had to end it in the player's favor, or it would result in a whiteout. What you can do is read the byte at 02023E8A and if it's 0x1 then the player won by fair means, else they lost/sleepclause happened.
     
    Back
    Top