View Single Post
Old January 21st, 2010 (6:14 PM). Edited May 31st, 2013 by Jambo51.
Jambo51's Avatar
Jambo51 Jambo51 is offline
Glory To Arstotzka
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Posts: 732
Hello! I am Jambo51, also known as TheJambo51 on Youtube and after playing around with my hack, Pokemon ThunderYellow, I managed to discover a beautifully simple way to add extra flight spots to a FireRed rom. While I know the locations for all FireRed roms, I'm still investigating Ruby and Emerald's flight data, as there is, rather bizarrely, a flight spot in the player's bedroom in both of these games.

This is based off of a tutorial on extending the sethealingplace table written by Linkandzelda.

LinkandZelda's Healing Place extension tutorial:

I am not going to explain step by step how to move a fly spot from one map to another. If you're looking at this tutorial, then you should already know how to do that. While the tutorial is written for the English version of the game, if you use the same searches as I did, you will find the data in your rom quite easily. I have also included the offsets for you lazier minded hackers in spoilers at the bottom of each relevant section.

Tools Required:
Advance Map 1.92
A Hex Editor (I personally use Hex Workshop 6)
Free Space Finder (For safety)

Part 1: Making the Rom recognise the extra flight spots that are to be added.
You have to go to the following offsets and change the bytes held there:

Credit goes to HackMew for these.

The flight loading routine (which loads the flight spots, healing places and which sprite to move when you white out in the Pokécentre) is located around 0xBFC70. While I don't know exactly where it starts, I know which pieces of data in here require modification in order to extend the flight table. This routine is common to all 3rd generation Pokémon games, with the only discernable difference being the number of flight spots loaded and the pointers to the tables.

Search for the following routine in the game, but replace the XX with the number of flight spots minus 1, in hex.

That is:
FireRed: XX = 13
Ruby: XX = 15
Emerald: XX = 15

Now we modify this routine so that the XX is higher. This is the first limiting byte. For the purposes of this tutorial, we're only gonna add 1 extra flight spot, but you can add as many as you like as long as you're willing to repoint enough data following the flight table for it to work.
FireRed: XX = 14
Ruby: XX = 16
Emerald: XX = 16

The same thing applies here. We want to add 1 extra spot to the game, so we up the number at XX by one. This is the second limiting byte in the game. Once these are both upped, the game will support extra flight spots, extra healing places and extra white out ID data.

However, in FireRed, because this data is all located right after each other in the rom, it will currently read the first 2 healing spots as flight data, the first 4 white out ID slots as a healing spot. This is not what we wanted is it?

Part 2a: Repointing the sethealingplace table and the White Out Person ID table in FireRed.
The sethealingplace table is right after the flight data table in a FireRed rom. So, you want to search for the sethealingplace data, which looks like this:

[map bank][filler][map number][filler]

So for the first healing place in a standard fire red rom, your mum's house, it would be map bank 4, map number 0:
Healing place entries take up a total of 4 bytes each.


Sadly, this is quite a common string in the rom, so we should also search for the second healing place at the same time.
The Viridian pokecentre is the second slot. Map Bank 5, Map Number 4.


Search for that hex string above (without the brackets) and you will be taken to the table.
As you can see above, a healing place entry takes up a total of 4 bytes. There are a total of 20 healing places in the game, just like flight spots.
So, 4*20 = 80 bytes.

So we want to copy 80 bytes from this location to another location. This new location MUST end in any of 0, 4, 8 or C. So 0x800000 or 0xA4215C would be suitable, while 0x800001 and 0xA4667D would not.
This is due to THUMB alignment, and it is VERY important that you DO NOT mess this up, or the rom will crash every time the table is used. Using Free Space Finder, search for at least 80 bytes of free space. However, I would recommend giving yourself space to extend the sethealingplace table as well. There has to be as many healing places as flight spots. So I would look for 80 + (8*4) = 112 bytes of free space.

I chose to copy the table to 0xA40000. Now, after we paste this new data to the location chosen, we must still repoint the table from the old one to the new one. This is fairly simple thankfully. You simply need to search for the sethealingplace table's old offset in reverse hex pointer form.
0x3EEC98 -> [0x][3E][EC][98] -> [98][EC][3E][08] -> 98EC3E08
So we search for the hex string of 98EC3E08 in the rom, and we find 2 matches at 0xBFD80 and 0xBFDA4.

Simply change these to match the new location of the sethealingplace table in reverse hex pointer form. In my case
0xA40000 -> [0x][A4][00][00] -> [00][00][A4][08] -> 0000A408
Now we have to repoint another small batch of data too. This table contains the sprite numbers for the white out routine to load when you white out.
That is, when you white out and get transported to a Pokecentre, it uses the sprite number contained in the relevant slot of this table to pass to the LASTTALKED variable, and then moves the sprite which has been loaded. Almost all Pokecentres have Nurse Joy as sprite number 0x1.

Since it's a bit horrible to find, I'll just tell you what to look for in the rom:


So we search for that hex string in the rom. It will take you to 0x3EECE8. Again, we must copy this data to a new location that ends with any of 0, 4, 8 or C.
So, once again, we boot up Free Space Finder and search for free space ending with 0. This table must also be extended. This table is much easier though, as it is literally a byte for each piece of data in the table.
So, in my case, I would be looking for 28 bytes of free space with an offset ending in 0. So, I chose 0xA40100 as my offset for this.

Then we simply paste the data in here and repoint again.
So we search for the hex string E8EC3E08 in the rom and we find matching data at 0xBFE14.
Once again, we modify this data so that it points to the new table and I've chosen to change this to 0xA40100.

0xA40100 -> [0x][A4][01][00] -> [00][01][A4][08] -> 0001A408
ie. Change the what's in the red boxes to the new values.

Now that we've repointed all the critical data that's located after the flight data table, we can start work on the actual flight spots.

Part 2b: Repointing the Flight Table
The flight table is actually very easily repointed. So, search for the following hex string in your rom:
This is the first entry of the flight spot table in FireRed. The search will take you to 0x3EEBF8. This is the start of what we would recognise as the flight spot table. However, the table actually contains another entry before this. The table starts at 0x3EEBF0.

So, starting from 0x3EEBF0, select 168 bytes of data. This is the entire flight table. Copy and paste the table to another location in the rom, again, leaving room for expansion.

This is the strange part. You need to do 2 separate repoints for this table.
The first repoint allows you to edit the flight spots in A-Map.
Replace this:
07 E0 00 00 F8 EB 3E 08 08 32 01 33 19
07 E0 00 00 XX XX XX 08 08 32 01 33 19
Where XXXXXX is your new offset in reverse hex format.

So, if I put the table at 0xA40200, then the pointer to this part of the table would be the location of the table plus 8 bytes:
Now the more important repoint, the one which the flight routine actually uses.
Replace both instances of:
03 E0 00 00 F0 EB 3E 08 00 20 02 BC 08 47 00 00
03 E0 00 00 XX XX XX 08 00 20 02 BC 08 47 00 00
Where XXXXXX is your new offset in reverse hex format.
This repoints the actual flight spot table, giving us plenty of free space to add flight spots. So the pointer would be

Part 3: Adding the extra flight spot to the game.
Now return to the end of your newly repointed flight table and add a new spot by putting in the data as follows:

[Map Bank][Map][X-Coordinate][Filler][Y-Coordinate][Filler][Filler][Filler]

Bear in mind, that every one of these values has to be in hex.
So, let's put it somewhere easy to find so that we can move it easily to a new map when needed by using advance map rather than hex editing.
So, because it makes it easy to test, and because it's easy to find, I've put it on Route 1, right below the signpost that is nearest to Pallet Town. So, add the string of hex bytes below to create the new flight spot exactly where I described. 1 step down from the signpost nearest Pallet Town.


Now save your rom in the hex editor and open Advance Map. If you go to the map that you added the flight spot to, you should see the flight spot, exactly where you put it. So we go to Route 1, and sure enough, there's a flight spot sitting right below the signpost nearest Pallet Town. You can now move it around freely to whatever map you wish, and whatever co-ordinates you wish, but I would advise keeping it on Route 1 for testing purposes.

Part 4: Making the Game use the new flight spot.
This is where most people will fall flat in trying to get an extra flight spot working. The game needs the airport data, as I like to call it, to be able to fly to any new flight spots.
So open up Advance Map and open the world map editor. Now click on Pallet Town. You will see that under the flight data, there is a set of what looks like 6 random numbers, followed by the flight spot data for the map.


Now we look at Route 1 instead, and we expect to see.......
Hang on! Didn't we just add flight data to Route 1?? Yes and no. You see, according to the "airport data", the flight spot on Route 1 doesn't exist!
That's because the airport data doesn't have any record of the new flight spot in it yet. Kind of like a new airport opening and there being no flights to it because no-one knows it exists. So, we look again at Pallet Town's flight data.

It turns out that the 6 random numbers aren't so random, but they are actually pretty important to how it works!
So, I think we should examine them in a little more detail.

[03] - Map Bank of the map to fly to
[00] - Map ID of the map to fly to
[01] - Ah, this is the important part, this is the flight spot slot. So, this tells the game to look for the flight spot in the slot that is written here whenever you try to fly to it. Unlike most other tables in the game, where slot 1 is referred to as slot 0 by the game, the flight data uses 00 as no flight spot, and anything other than that as the slot on the flight data table.

If we compare this with Route 1's data, we find that Route 1's data is:


Ah, Route 1 isn't on the flight network!

So clearly we have to modify that data so that it is. But how do we find it when the data string 030001 is fairly common within the FireRed rom.
I know, just like before, we combine 2 airport data slots into 1 search.
Slot 0 on that table is Pallet Town, and slot 1 is Viridian City, so we search for BOTH of their airport data at once.


This will take you to the airport data table.
Now we look for the string 031300 from the start of this table and when you find it, you change it to 031315.

This is because we want the game to use flight spot 0x15 on (Map Bank, map ID) (0x3, 0x13). Now save and reopen Advance Map. Open up the World Map editor and click on Route 1. You will now see that in the flight data boxes, there is now flight data!
If you press the open map, flying position button, it'll take you to the map with the flight spot on it! Excellent!

The map is now primed to fly to.

BPRE (English) - 0x3F2EE0
BPRF (French/Français) - 0x3EB49C
BPRI (Italian/Italiano) - 0x3EA19C
BPRS (Spanish/Español) - 0x3ED1B4
BPRD (German/Deutsch) - 0x3F2738
BPRJ (Japanese) - 0x3B9A68

Part 5: Actually Using it in game.
Now all you have to do is change the worldmapflag using advance map, and then set the worldmapflag using a script in the game.

To change the worldmapflag, open the world map editor. Press the changeroutines button. Then go into the flying/display flag box. Change it to a free flag in the game. Absolutely any free flag will do.

Then press the "save flag" button, then "save map".

To make sure it works, move the cursor onto a different piece of the world map, then move it back. If the flag is still the same, then congrats!

Finally, use a script like this:
#dynamic 0x800000
#org @main
setworldmapflag 0x[Put Flag Here]
And put it into the game as a Header Script, type 3 (On entering map/not on menu close). As soon as you enter the map with that header, the flight spot will become available.

Obviously, you need HM02, the THUNDERBADGE and a pokemon capable of using fly to actually use it. But it's really as simple as that!

To add even more flight spots, simply repeat the process from part 1, skipping part 2, then continuing from part 3, changing the maps you put it in, as well as the airport data to the relevant slots.
For example, the next flight spot you would add would have 16 at the end rather than 15.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote