• 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

650
Posts
6
Years
  • Temporarily disabling EXP gains from battle


    It was brought to my attention by some requesters that for their battle/tournament events they wouldn't want their Pokemon leveling up. This routine disables the exp gains in battle. Note that the player can still use stuff like Rare Candy to level. The fix to that is exactly the same as this, but with slight modifications. I hope you don't give the player a chance to rare candy in battle though or I will go to your hack's thread and severly criticize your lack of common sense :c


    How to insert:

    Compile and insert the following routine into free space:

    Spoiler:


    Now navigate to 0x21CFA and insert the following byte changes:
    Code:
    00 00 00 49 08 47 XX XX XX 08
    Where XX XX XX is the reverse hex pointer to where you inserted this routine +1.

    Usage:

    If flag 0x202 is set, the EXP gains will be disabled. Obviously, to re-enable just clear the flag.
    Currently the way I'm doing this is by making the game act like the player's party is already max level, so therefore they don't gain exp :)

    Is there a way to do this in Emerald? Also, is there a way to have a flag reduce experience gain by half in Emerald? I've implemented the gen VI exp share asm but that gives 100% to every pokemon, I would really like to have the amount be configurable!
     

    AkameTheBulbasaur

    Akame Marukawa of Iyotono
    409
    Posts
    10
    Years
  • Shiny ShowPokePic (For FireRed)

    If you use these two routines, then if you set Var 0x8003 to 0x1, before using the showpokepic command in an NPC script, then the Pokemon in the resulting picture will appear Shiny!

    Spoiler:


    Spoiler:


    e8dsgRM.png
    KRqGbo2.png


    (First picture is with 0x8003 = 0x1, second is without).
     

    ScizorBlade

    Sup Dogg
    39
    Posts
    4
    Years
  • Time Box triggered along with the Start Menu

    Preview: (Click to see the GIF animation)
    View attachment 77173
    The routines are only for FR. I haven't found any bugs in it. However, the CPU will run much more instructions so that it will be a bit (really?) slower when you open the 'pokemon', 'bag'..... menus.
    1) Insert the RTC routine via the tool 'DNS'.
    2) Insert these routines and do the byte changes:
    Routine I:
    Spoiler:
    Routine II:
    Spoiler:
    Routine III:
    Spoiler:

    In the byte change there are some XX XX XX, YY YY YY and ZZ ZZ ZZ. What are those?
     
    1
    Posts
    4
    Years
    • Seen Jun 9, 2020

    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.



    Did anyone ever make a fix for this? I'm trying to use it now and I can't control the level of the Pokemon.

    EDIT: It works if you change the Pokemon data location.
     
    Last edited:
    990
    Posts
    4
    Years
  • Greetings, everybody.

    Question:
    Has anybody got the Rival Naming Routine by Jambo51?
    I believe the post [link] has died. Any help would be appreciated, and I under stand if Jambo has prohibited from spreading it.
    This isn't a request, but a favour.


    Cheers.
     
    Last edited:

    Pekin

    Wigglytuff is and has always been on acid.
    282
    Posts
    15
    Years
  • Hey all, I have a question that I was hoping someone here could help me out with. Spherical Ice was kind enough to send me some scripts and routines for me to edit to implement the "Madam Celadon" NPC feature from the Let's Go games into my Fakemon FireRed hack - you know, an NPC you talk to which predicts the nature for future encounters, at least for a set amount of time - or, steps. The first two scripts and the first asm routine I don't have any trouble editing and inserting, but the second asm routine gives me some error messages that I don't really know how to tackle. I hope it's cool if I post everything here.

    The "Mrs. Nature" script is inserted at 3B1B44
    The "Nature manipulation" routine is inserted at 34F050
    The "Wore off" script is inserted at 3ADDD4
    And the "Pedometer" routine is supposed to be inserted at 3ADE14, but I can't convert it to a .bin file without getting these error messages:
    Code:
    pedometer.asm:30: Warning: Failed to find real start of function: call_via_r2
    pedometer.asm:39: Warning: Failed to find real start of function: call_via_r2
    pedometer.asm:51: Warning: Failed to find real start of function: call_via_r2
    pedometer.asm:58: Warning: Failed to find real start of function: call_via_r2
    pedometer.asm:61: Warning: Failed to find real start of function: call_via_r2
    pedometer.asm:28: Error: invalid offset, value too big (0xFFFFFFFC)

    I'm wondering if there's a different way I'm supposed to convert these, though, the only way I know is to put the .asm file in the same folder as thumb.bat, then navigate there with command prompt and type in "thumb routine.asm routine.bin" or something like that. I've noticed that this gives me some ridiculously long files with these routines - I can tell that it's because the new routine is generated at the specified offset, and the new pointer is included and everything, I'm just wondering if I'm supposed to be doing something different.

    Anyway, here's what I got from Spherical Ice, all credit goes to him. I hope it's okay to post this here, he was a little too busy himself. Everything is pretty much the way I've inserted it - I'll edit the dialogue later, but other than that, the offsets and everything should match the way I've been inserting these.

    Spoiler:
     

    Team Embrace

    Team Embrace Boss
    30
    Posts
    5
    Years
    • Seen Nov 14, 2022
    Hey everybody. First I would like to thank Andrea for successfully porting the physical/special split to Pokémon Ruby. Can someone take his ASM routine and update it to work with an expanded move table?
    Spoiler:


    In my modification the attack table starts at offset 0x900000. If more information is needed about my offsets I can provide that.
     
    Last edited:
    81
    Posts
    7
    Years
    • Seen yesterday
    Hey everybody. First I would like to thank Andrea for successfully porting the physical/special split to Pokémon Ruby. Can someone take his ASM routine and update it to work with an expanded move table?
    Spoiler:


    In my modification the attack table starts at offset 9000. If more information is needed about my offsets I can provide that.

    Change this for new table.

    AttackData=1FB12C
     

    Team Embrace

    Team Embrace Boss
    30
    Posts
    5
    Years
    • Seen Nov 14, 2022
    Change this for new table.
    AttackData=1FB12C
    Thanks for your reply Super Dark. I think my last post wasn't clear enough I am not talking about updating an editor's tool like PGE to support the expanded move table I've already done that. What I'm asking about is how to update Andrea's ASM routine to support the expanded move table in my ROM. Although I think were on the right track I wonder if change I posted below will work or do any other numbers need to be changed?
    Spoiler:
     

    Team Embrace

    Team Embrace Boss
    30
    Posts
    5
    Years
    • Seen Nov 14, 2022
    Greetings, everybody.

    Question:
    Has anybody got the Rival Naming Routine by Jambo51?
    I believe the post [link] has died. Any help would be appreciated, and I under stand if Jambo has prohibited from spreading it.
    This isn't a request, but a favour.


    Cheers.

    Naming the Rival from the Overworld:
    Spoiler:


    OG post by tajaros
     
    990
    Posts
    4
    Years
  • Naming the Rival from the Overworld:
    Spoiler:


    OG post by tajaros

    I am so sorry! I had found this routine and forgot to mention it here. Terribly sorry.
     

    AkameTheBulbasaur

    Akame Marukawa of Iyotono
    409
    Posts
    10
    Years
  • Var Mathematics For FireRed
    In NPC scripting, there exist commands to add/subtract an integer value to a variable (AddVar an SubtractVar). However, these commands may be a little bit limited. It may be that you want to multiply or divide a var, or add two vars together. In that case, you can use these:

    What To Do First
    First, you will want to find two half-words of free RAM. It does not need to be permanent RAM (RAM that is saved with the game). However, you will need to know what number var that RAM corresponds to. I recommend NOT using the 0x8000+ temp vars, since then you will be unable to manipulate values stored into them.

    These routines use the vars 0x4074 and 0x4075 by default, but these can be changed in the following way.

    1. Figure out the difference between the var you want to use and 0x4074. Keep in mind this is in hexadecimal.
    2. Multiply that value by two.
    3. Add (or subtract if your var is less than 0x4074) from 0x02026614. This is still in hexadecimal. You should then get the RAM address of the var you want to use.
    4. Repeat for the second var if desired.
    5. Change the addresses after .Var4074 and .Var4075.

    The Actual Routines
    The routines below perform the following operations:

    1. Addition
    2. Subtraction
    3. Multiplication
    4. Division
    5. AND
    6. OR

    For the AND and OR operations, I'll explain them a little for those who are not familiar with them. If you AND two binary numbers, the resulting number has the bit equal to one if the corresponding bits of the input numbers are the same, and zero if they were different. For example, 1011 AND 1100 = 1000.

    For the OR operation, if both bits of the input numbers are zero, it returns zero. Otherwise it returns one. In other words, if one OR the other number has a bit equal to one, the resulting number's bit is set equal to one. For example, 0010 OR 1000 = 1010.

    Add Vars
    Spoiler:


    Subtract Vars
    Spoiler:


    Multiply Vars
    Spoiler:


    Divide Vars
    Spoiler:


    AND Vars
    Spoiler:


    OR Vars
    Spoiler:


    How To Use Them
    These are meant to be used in NPC scripts. You use them as follows:

    #org @Script
    setvar 0x8000 0xAAAA ' Whatever value you want
    setvar 0x8001 0xBBBB ' Whatever value you want
    setvar 0x4074 0x8000
    setvar 0x4075 0x8001
    callasm 0x8AABBCC+1 ' AABBCC is the offset where you inserted the routine. Add one for THUMB.
    ...


    The result is stored into LASTRESULT. The original vars are not changed by the routine at all.
     
    Last edited:

    RichterSnipes

    Not even a nibble...
    513
    Posts
    12
    Years
  • Only Buy 1 TM From Shops [FR]

    If you've decided to make your TMs reusable in Fire Red, this routine will remove the option to buy more than one of each from shops. Credits to azurile13 for the first part (Main) of the code.The only thing that needs changing is the line ".equ offset".
    Spoiler:
    I've got a pretty big issue with this code. After inserting it, any time I try to purchase an item from a vendor they try to sell it for absurdly low prices at first. For example, if you try to buy a Great Ball from someone, they initially sell it at $3 instead of $600. And yes, that's how much it actually takes away from you, not the $600. If you change the quantity of item, the price goes back to what it normally should be per item.

    These super low prices that are offered for each item appear to actually be the internal item ID number for each thing, converted to decimal format. One Potion, for instance, costs $13. It's item ID value is 0xD.

    Anyone have any ideas what's going on here? Did I do something wrong?
     
    25
    Posts
    5
    Years
    • Seen Nov 24, 2023
    Can anyone please help me add the Everstone 100% chance nature inheriting mechanism to the IV inheriting posted by FBI ?

    Spoiler:
     
    2
    Posts
    3
    Years
  • Hi, there! I've been making Pokémon FireRed hack roms for some time now, but never got to understand ASM, so I have a few requests about problems I've been facing. First of all, I'm familiar with XSE scripts and hexadecial numbers and HxD (hex editor), but not with how ASM works. The furthest I've reached is executing my custom menus (normal XSE scripts) via a key item using the "use of select" option in complete item editor. However this only works in overworld mode... I've miserably failed to run anything custom in-battle. I know battle scripts are different than XSE scripts, and have also downloaded the battle script pro tool, but that's about it. I have the thumb ASM compiler too. Well, I should go to the point now.

    I'll start with the biggest issue. If flag 0x301 is set then receive all Pokémon from trainers upon trainer defeat (thief mode) Now I have a few questions here. Is there a way to call an ASM routine every time a trainer has been defeated? (or a battle ends, for that matter?) Trainer party data is located at ram offset 0x0202402C, is this data automatically cleared upon battle finish? I would need this data to be taken and then given to the player in the same way givepokemon works. What I mean by this is, first use the player's party slots then send the remaining Pokémon to the PC. In other words I need the party at said address to be given to the player as is (save maybe bug fixes?) If this being done automatically is not possible then I can script every single NPC in the game a callasm. That'd be more work, but it'd still be doable without having to manually script every single Pokémon from every single trainer in the game via givepokemon, special(s) and JPAN's hacks. That's a lot of work to do, you got the idea. Plus, in such a way it'd be impossible to replicate the IVs (and EVs as well?) from the stolen Pokémon, since I can't know their values during battle. Again, I know nothing of ASM but I guess just copying data from one ram location to another must not be too hard to script.

    But that's not my only concern. I also need a way to make battles against 1 Pokémon, fully customizable except for moves (default attacks), that you can't run away from, that you can't catch the Pokémon by any means and that you earn an also customizable amount of price money for. I'm unsure as to whether I can already do this with what's already on the internet. I used to "do this" by creating 386 new trainers with a single Pokémon each, but that's a lot of work to do and also "ugly" if you get my meaning. Unprofessional.

    Last but not least, we hear a lot about XSE scripts calling ASM, but what about it in reverse? Is it possible? (Guessing it is, since "virtually anything" is possible with ASM) I ask this because I want to change the exit option of the start menu to one that runs my XSE script with custom multichoice menus and submenus, instead of having to use a key item to be able to run the script from anywhere. Or even better, cancel button select "register" feature and call my script whenever select is pressed (without a custom item) Is it possible? Or even better, if I'm allowed to request, whenever you press the L and R buttons both at the same time in overworld mode (I have already disabled the annoying help system that takes priority over everything else, but had no luck with JPAN's key scripts nor walking scripts, changed default game settings as well)

    Thank you very much in advance for your help and please have a nice day ^^ If someone could lend me a hand with JPAN's key scripts and/or walking scripts, that would be a great plus.

    Edit: Oh, I almost forgot, JPAN's species changer leaves the name intact so I'd need code to set a Pokémon name to the default for its species, too.
    Edit2: Oh my God, I can't believe it but I managed to find the pointer to the script that runs when select is pressed and no item is registered, it's at offset 0x10ADA8!
     
    Last edited:
    2
    Posts
    3
    Years
  • It should have no problems with any other hacks; this check is quite standalone. I should also mention the Pokemon you captured from another trainer will act like a Pokemon who has been traded. If you don't have the badges to train it, it will disobey you.



    Thanks for that.



    Thanks. To my knowledge, the gameshark code still turns your Pokemon to a bad egg. This fixes the bad egg too!

    Anyways, I've finished all the requests which I'm willing to do. Keep shooting them at me guys :P

    EDIT:


    Toggling Capturability of Pokemon


    So it's quite likely that maybe you want a Pokemon to be uncapturable, and at the same time you don't want to diminish it's catch rate to 0 in your Pokemon editor. Or perhaps you used the "capture trainer Pokemon" hack and you don't want it to work for all trainers. No problem, this is the hack for you :P

    Basically it checks if variable 0x8000 is 0x1 or not. If it's 0x1, then any Pokemon you encounter (trainer or wild, via script or natural encounter) will become uncapturable even with the master ball. Simply set 0x8000 back to normal for the original game mechanics.
    Note: If you use this hack, to say make it so the player can only capture a certain trainer's Pokemon, you will need to set 0x8000 right before the encounter, and unset it after (which is quite simple)
    Note2: This hack won't let you capture trainer Pokemon, you need to have the capture trainer Pokemon hack from last time to create that effect.

    How to insert:

    First compile the following ASM code and insert into free space:
    Spoiler:


    Here is a compiled version:
    Code:
    05 48 01 68 03 4A 12 78 01 2A 01 D0 03 48 00 47 03 48 00 47 B8 70 03 02 4C 2B 02 02 91 D4 02 08 61 D4 02 08

    Now navigate to 0x2D452 and insert the following:
    Code:
    01 48 00 47 00 00 XX XX XX 08
    Where XX XX XX is the reverse hex pointer to where you inserted the above routine. That's it :)
    EDIT: Add one to the pointer.

    Here's a pesky Rattata:

    (Yes, the Pokeball animation is still there, this was taken after it.)

    Unfortunately, unlike the toggle run away code, this ASM isn't working with special 0x138...

    Edit: After some more testing I found out neither of them worked because I was using a variable under 0x8000..
     
    Last edited:

    AkameTheBulbasaur

    Akame Marukawa of Iyotono
    409
    Posts
    10
    Years
  • Nature Changing
    Before I begin, I should mention that this only works for FireRed at the moment. This is because it uses the Lustre stat, which in FireRed is unused but in Emerald is not. If you can find another stat to use, (or you don't have contests in your Emerald hack), then you can use this.

    Offsets listed here are for FireRed, though, so keep that in mind if you decide to port it.

    Anyway, without further ado, I present Nature Changing!

    How Does It Work?
    Skip this if you don't care about the behind the scenes stuff.

    Basically, this hijacks the GetNature function. It first checks the Lustre stat of the Pokemon in question. If it's equal to zero, then it gets the Nature form the PID as usual. If it's not zero, then it uses the Lustre value as the Nature, effectively changing the Pokemon's Nature without messing with the PID (and potentially messing up other stuff like the Pokemon's gender, Shininess, etc.).

    This does mean you can't set the Nature to Hardy, but this is not that big of a deal since there are other neutral Natures you can use.

    The Main Event
    I have written an instruction manual that explains how to use the hack in detail. It also contains links to download everything.

    The link presented below is the link to download the folder with the Instruction Manual and all the routines. Not every routine in the folder is one you need to insert, as there are a couple of optional add-ons to make changed Natures compatible with other hacks.

    Download: Here!
     
    Last edited:

    ssd1334

    ssd1334
    3
    Posts
    3
    Years
  • Getting IVs and EVs


    The routines are very similar so I ended up just combining the two routines into one. Basically given a slot number of a Pokemon in 0x8004, the routines will return the EVs or IVs, respectively, into the vars 0x8005-0x800A with 0x8003 as the IV/EV switch.


    How to insert:

    Compile and insert the following routine into free space:

    Spoiler:



    Usage:
    setvar 0x8003 0x[anything except 0 = IV, 0 = EV]
    setvar 0x8004 0x[slot number 0 to 5]
    callasm 0x[this routine +1]

    The variables will be:
    0x8005: HP IV/EV
    0x8006: Atk IV/EV
    0x8007: Def IV/EV
    0x8008: Spd IV/EV
    0x8009: S.atk IV/EV
    0x800A: S.def IV/EV

    see idk if im stupid or something, but i cant seem to figure out how to compile stuff in assembly
     

    AkameTheBulbasaur

    Akame Marukawa of Iyotono
    409
    Posts
    10
    Years
  • see idk if im stupid or something, but i cant seem to figure out how to compile stuff in assembly

    I recommend using this tool. It's easy to use and lets you assemble directly into the ROM. Just copy-paste the routine you want to assemble in there, click the button and go!

    A Timer System
    This is mainly for Fire Red, but it could also work for Emerald if you have enough Free RAM. More on that as we go.

    Anyway, this is a way to allow yourself to have timed events in Fire Red. As you may already know, FireRed does not have a Real Time Clock like Ruby/Sapphire/Emerald does. It does, however, have an internal clock that keeps track of how long you have been playing the game.

    You could, if you wanted, try to use it to have timed events. For example, if you wanted to have something occur every ten minutes, and you knew the RAM for where the time you've been playing is, then you could theoretically do something like this:

    1. Save the current time when the event starts.
    2. When the script is run again, check the time again.
    3. If it's StartingTime + LengthOfEvent, then the event is over.

    This is obnoxious for a variety of reasons. One, it kind depends on having a script run to end the event. Two, what happens if you've somehow been playing for 999 hours and 59 minutes. Then all your timed events break. Sure, that is a ridiculously long time, but still.

    Then, I came across a few hacks that other people had made, which when brought together, opened a whole new world for me.

    What You Need
    Before we get started, there are a few things that you will need to have in your game first.


    Now, you may be wondering, what on Earth is this dubious, unnamed patch and what on Earth is it doing to my ROM? The answer to that is is disables the "Previously On Your Quest" feature (the little slideshow that happens when you boot up the game). Now why would this be required for a Timer System?

    The answer is that it frees up a TON of RAM. Like seriously, a TON. Like sooooooooo many bytes of RAM it's ridiculous. The best part? This RAM is saved by the game. Basically, if you want to expand your bag size, you don't need to use JPAN's Save Block anymore.

    If you have a hack in progress, this is objectively the better way to free up RAM because now you don't need to restart any save files. In fact, I would just do this anyway, unless you REEEEEEALLY need the "Previously On Your Quest" thing for some reason.

    What To Do
    First, you will need to create a table. This table will have all the RAM Addresses of all the timers that you will want to use. You are really only limited by the amount of free RAM you can use for Vars. You could have one timer, or 100! I personally have 96.

    Each entry of the table is four bytes long and is simply a pointer to the RAM addresss. If you want some help with figuring out what RAM addresses to use, click on the spoiler. The table needs to be terminated with FF FF FF FF.

    Spoiler:


    If you are lazy and you applied the patch above, then you can use this table. It has 100 timers (you can use only part of it if you need less). It starts at 0x0202752C and ends at 0x020275F4. In Var terms, this is 0x4800 to 0x4864.

    Spoiler:


    The second table you will need to insert is a table that has the time limits for all your timers. Each entry is a half-word (two bytes long) and you will need one for each timer that you have in the previous table.

    There are two options you have for each entry. If you enter in a number other than 0xFFFE, then it will function as a typical timer. For example, if you set it to 0x5, then after five minutes, it will be reset.

    If you use 0xFFFE, then it turns your timer into a stopwatch. This will make the timer keep going until it reaches 0xFFFF minutes. How long is that? 0xFFFF = 65,535 minutes = 1092.25 hours = 45.5 days = long enough that you probably won't get to that point.

    Okay, now you're ready to insert this routine somewhere and then add a pointer to it in the Minute Routine table (see FBI's Minute Routine post). Add the addresses of the tables after where it says .VarRAMTable and .TimeLimits.

    Advance Timer Routine
    Spoiler:


    How To Use
    Now that we have it all inserted, how do we use it? In order to start a timer, just set the corresponding Var equal to 0x1. If it's a timer, the Var will reset itself when it reaches the limit. If it's a stopwatch, you will have to set it back to zero yourself.

    Here's an example script showing the basics. It uses the Subtract Var routine that I linked above. In the script, the player is asked if they want some Lemonade. If they accept, they are given a Lemonade item and the timer is set. They can come back after fifteen minutes and get another. If they talk to the NPC before 15 minutes have elapsed, the NPC will tell the player how long they have to wait.

    Note that this is fifteen minutes of in-game time. Turning off/pausing the game and coming back fifteen minutes later will not count.

    Spoiler:


    Ideas
    Here are some ideas of what you can use this for.

    • Berry Trees (Have berries grow after certain amount of time).
    • A lottery you can play once every X minutes.
    • A delivery system where you can get a package after X minutes.
    • Timing how long it takes you to beat a trainer.
    • A sale at a store that lasts for X minutes and occurs every Y minutes.
    • Anything you can think of!
     
    Last edited:
    Back
    Top