Announcements
7/23/18
Previous updates
Uncommon's FBI HM system patch
Hi everyone! This is my first public contribution to the world of ROM hacking. What I've got for you today is a patch for FireRed (English 1.0 BPRE) that changes the behavior of HMs in the overworld. This is heavily based on FBI's research on HM checks. All the credit for that research goes to FBI (along with knizz and touched), and I'll be referring to his thread throughout this post.
What is this?
What this patch does is change all the HM overworld use checks. Instead of needing certain badges and moves to use HM moves in the overworld, you need to have certain types in your party. The needed type is easily changeable, but the types I've chosen to start with are:
As described in FBI's post, the original inspiration was to match the show, in which Trainers can effectively Surf with any Water-type Pokemon, Fly with (almost) any Flying-type, etc. This also eliminates the need to carry around an HM slave, or overwrite good moves for useless ones like Flash.
How does it work?
I've hijacked the internal script for each HM and redirected it to a new script that checks the new condition - whether or not you have a Pokemon of the appropriate type in your party - and, if so, activates the HM's overworld effect. This check is accomplished with FBI's modified version of special 0x12b, also explained in his post. I've tested all the scripts thoroughly and I'm confident their text and sequence of events match their vanilla FR counterparts (if applicable). If you want to get a deeper understanding of how this works, read FBI's thread on changing the HM checks, and check out the script posted in the Advanced Usage section.
Usage
After patching, all of these are passive and don't require any editing to start using them right away, except for Flash. To apply the Flash hack, you need to add it as a level script to each Flash-able map in A-Map. Its offset is 0x760024. I recommend following diego's level script tutorial (starting at step 5, because the script is already done). For the flag variable in A-Map, use 4000. As FBI explained to me, this is a temporary variable that's reset whenever the map reloads, meaning it'll be ready to activate again each time you enter the map.
In the game
With the exception of now needing a type instead of a move and a badge, Surf, Waterfall, Cut, Rock Smash, and Strength work exactly how they normally do - press A to interact with an obstacle and follow the prompts.
If you have a Pokemon of the correct type (Fire by default), Flash will activate as soon as you enter a map with the level script applied.
To activate Fly, a new option has been added to the START menu: MAP. It shows you the town map, and if you have a Flying-type, lets you choose a location to Fly to. The MAP option shows up when you activate the POKEMON menu option (ie, when you get your first Pokemon).
Advanced Usage (optional)
Compatibility
Now, you'll notice I have used free space for these new scripts (from 760000-760704), which means this patch MIGHT NOT be compatible with hacks in progress. Since most people start at 800000, there's a good chance it IS compatible (for instance, this patch is 100% compatible with MrDollsteak's Attack and Decap Rombase!) but it's not guaranteed. If you really want to add this to a hack in progress, below are instructions for doing so.
Bugs
Credits
I intend to use this in my upcoming hack, and now you can, too! With permission from FBI, this patch is for public use. Feel free to use it as long as you credit the following people:
FBI - for the research and ASM development, plus help with fixing a bug with Fly
knizz - for helping in FBI's research on Fly
touched - for helping create FBI's modified special 0x12b
mbcn10ww - for discovering and fixing a bug with the wrong Pokemon being displayed
Uncommon - for writing the scripts, testing, and creating this patch
Downloads
and finally... the patch!
Version 1.1 - .zip file that includes both the full patch and a patch to upgrade from version 1.0 to 1.1, plus instructions in the ReadMe
Changelog
7/23/18
- Bugs section added to OP (there's only 1 tiny one, I promise!)
Previous updates
Spoiler:
1/1/17:
1/7/17:
Spoiler:
Happy New Year PC! I have a few bits of news to share about this project:.
- Version 1.1 released! mbcn10ww discovered and solved a bug with this hack. In Version 1.0, for all HMs except Flash, although checking for types was functionally correct, the animation and text always showed the first Pokémon in your party, not necessarily the one with the correct type. mbcn10ww came up with a simple fix, which I verified and applied to all HMs in Version 1.1, with help from FBI. The Downloads section of this post has been updated.
- I've added the source ASM for Fly into the Advanced section (originally I only had the compiled version there), so you can mess around with it if you want.
- Also, mbcn10ww has made his own fork of this hack. In addition to the aforementioned bug fix, his version also moves the hack out to offset 0x990000 to increase compatibility with hacks in progress and adds the ability to use more than one type per HM move (which is really cool!). Check out the thread here.
- I will continue to keep this thread maintained because I feel this base version is simpler and I can personally vouch for its stability, but feel free to check out mbcn10ww's version, too. I will still love you no matter which version you use <3
- The Advanced section of this post is still being updated to reflect the changes to Version 1.1, I'll try to have that finished in the next couple days and will post an announcement when done. All the other sections are already updated.
1/7/17:
Spoiler:
- The Advanced and Compatibility sections of the OP have been updated
- This whole post is now up-to-date for Version 1.1
Uncommon's FBI HM system patch
Hi everyone! This is my first public contribution to the world of ROM hacking. What I've got for you today is a patch for FireRed (English 1.0 BPRE) that changes the behavior of HMs in the overworld. This is heavily based on FBI's research on HM checks. All the credit for that research goes to FBI (along with knizz and touched), and I'll be referring to his thread throughout this post.
What is this?
What this patch does is change all the HM overworld use checks. Instead of needing certain badges and moves to use HM moves in the overworld, you need to have certain types in your party. The needed type is easily changeable, but the types I've chosen to start with are:
Code:
Surf - Water
Waterfall - Water
Cut - Grass
Rock Smash - Fighting
Strength - Fighting
Flash - Fire
Fly - Flying
As described in FBI's post, the original inspiration was to match the show, in which Trainers can effectively Surf with any Water-type Pokemon, Fly with (almost) any Flying-type, etc. This also eliminates the need to carry around an HM slave, or overwrite good moves for useless ones like Flash.
How does it work?
I've hijacked the internal script for each HM and redirected it to a new script that checks the new condition - whether or not you have a Pokemon of the appropriate type in your party - and, if so, activates the HM's overworld effect. This check is accomplished with FBI's modified version of special 0x12b, also explained in his post. I've tested all the scripts thoroughly and I'm confident their text and sequence of events match their vanilla FR counterparts (if applicable). If you want to get a deeper understanding of how this works, read FBI's thread on changing the HM checks, and check out the script posted in the Advanced Usage section.
Usage
After patching, all of these are passive and don't require any editing to start using them right away, except for Flash. To apply the Flash hack, you need to add it as a level script to each Flash-able map in A-Map. Its offset is 0x760024. I recommend following diego's level script tutorial (starting at step 5, because the script is already done). For the flag variable in A-Map, use 4000. As FBI explained to me, this is a temporary variable that's reset whenever the map reloads, meaning it'll be ready to activate again each time you enter the map.
In the game
With the exception of now needing a type instead of a move and a badge, Surf, Waterfall, Cut, Rock Smash, and Strength work exactly how they normally do - press A to interact with an obstacle and follow the prompts.
![[PokeCommunity.com] FBI's HM type-check hack [PokeCommunity.com] FBI's HM type-check hack](https://i.imgur.com/qGwnsbG.gif)
If you have a Pokemon of the correct type (Fire by default), Flash will activate as soon as you enter a map with the level script applied.
![[PokeCommunity.com] FBI's HM type-check hack [PokeCommunity.com] FBI's HM type-check hack](https://i.imgur.com/tcvMWHe.gif)
To activate Fly, a new option has been added to the START menu: MAP. It shows you the town map, and if you have a Flying-type, lets you choose a location to Fly to. The MAP option shows up when you activate the POKEMON menu option (ie, when you get your first Pokemon).
![[PokeCommunity.com] FBI's HM type-check hack [PokeCommunity.com] FBI's HM type-check hack](https://i.imgur.com/TYD4lbT.gif)
Advanced Usage (optional)
Spoiler:
Enable/disable flags
Each new HM script has two flag checks that allow you to enable/disable the HM with events in the game. First, there's a flag that controls whether or not the new HM check system itself is active. If this flag is cleared, the HMs will behave exactly as they do in vanilla FR. However, if you set the flag, they'll use the new system of checks instead. The flag I've used is 0x828, the flag for having the Pokemon option in the Start menu, which means as soon as you have any Pokemon, the new checks will be active. But you can change which flag controls this by editing the two reverse hex bytes at 0x760690, or by decompiling the script at 0x760414, editing the flag number, and recompiling (without changing the offset). If you change it to, say, flag 0x201 (so bytes 01 02 at 0x760690), the new checks would be disabled until you set flag 0x201 in a script.
Also, each script checks a second, individual flag beforehand, so you can make them dependent on badges as well if you want. I've set the flag for each one again to 0x828 so they're immediately active by default, but like the overall enable/disable flag above, this is easily changeable. If you want to use a different flag, simply go to each offset specified below and overwrite the existing two bytes with the reverse hex of the flag you want to check instead:
Changing types
Also, you can easily change which types are required for each HM. Navigate the the offsets specified below for each type and change the byte to the value of the type you want:
Values for each type (from FBI's thread about his modified special 0x12b):
New scripts
Decap
Spoiler:
Each new HM script has two flag checks that allow you to enable/disable the HM with events in the game. First, there's a flag that controls whether or not the new HM check system itself is active. If this flag is cleared, the HMs will behave exactly as they do in vanilla FR. However, if you set the flag, they'll use the new system of checks instead. The flag I've used is 0x828, the flag for having the Pokemon option in the Start menu, which means as soon as you have any Pokemon, the new checks will be active. But you can change which flag controls this by editing the two reverse hex bytes at 0x760690, or by decompiling the script at 0x760414, editing the flag number, and recompiling (without changing the offset). If you change it to, say, flag 0x201 (so bytes 01 02 at 0x760690), the new checks would be disabled until you set flag 0x201 in a script.
Also, each script checks a second, individual flag beforehand, so you can make them dependent on badges as well if you want. I've set the flag for each one again to 0x828 so they're immediately active by default, but like the overall enable/disable flag above, this is easily changeable. If you want to use a different flag, simply go to each offset specified below and overwrite the existing two bytes with the reverse hex of the flag you want to check instead:
Code:
Surf - 0x7602D8
Waterfall - 0x76038D
Cut - 0x7600DF
Rock Smash - 0x76016D
Strength - 0x7601FD
Flash - 0x760044
Fly - 0x7606F4
Changing types
Spoiler:
Also, you can easily change which types are required for each HM. Navigate the the offsets specified below for each type and change the byte to the value of the type you want:
Code:
Surf - 0x7602E3
Waterfall - 0x760398
Cut - 0x7600EA
Rock Smash - 0x760178
Strength - 0x760211
Flash - 0x760050
Fly - 0x7606BE
Values for each type (from FBI's thread about his modified special 0x12b):
Spoiler:
Normal 0x0
Fighting 0x1
Flying 0x2
Poison 0x3
Ground 0x4
Rock 0x5
Bug 0x6
Ghost 0x7
Steel 0x8
??? (egg) 0x9
Fire 0xA
Water 0xB
Grass 0xC
Electric 0xD
Psychic 0xE
Ice 0xF
Dragon 0x10
Dark 0x11
Fighting 0x1
Flying 0x2
Poison 0x3
Ground 0x4
Rock 0x5
Bug 0x6
Ghost 0x7
Steel 0x8
??? (egg) 0x9
Fire 0xA
Water 0xB
Grass 0xC
Electric 0xD
Psychic 0xE
Ice 0xF
Dragon 0x10
Dark 0x11
New scripts
Spoiler:
You could also make these changes by decompiling and editing the new scripts, which are at the offsets below:
The Fly check is done in ASM, here is the source code (commented):
These scripts are mostly independent, but they all reference one script for the overall enable/disable flag check, and also one script for a sort of initialization/check that the game does for each HM. I don't think it's necessary but I decided to leave it in just in case.
Code:
Surf - 0x7602C7
Waterfall - 0x76037C
Cut - 0x7600CD
Rock Smash - 0x76015B
Strength - 0x7601EB
Flash - 0x760024
Fly - 0x7606A0, but this one's ASM, so no easy decompiling.
The Fly check is done in ASM, here is the source code (commented):
Code:
.text
.align 2
.thumb
.thumb_func
main:
push {r0-r1, lr}
ldr r1, =(0x8760690) @location of master enable flag
ldrh r0, [r1]
ldr r1, =(0x806E6D0 +1) @flag check routine
bl CALLER
cmp r0, #0x0 @if the master flag is not set
beq NORMALMAP @open normal map
ldr r0, =(0x828) @set the individual (badge) flag number
ldr r1, =(0x806E6D0 +1) @flag check routine
bl CALLER
cmp r0, #0x0 @if the flag is not set
beq NORMALMAP @open normal map
ldr r0, .VAR @set paramaters for special
mov r1, #0x2 @type to check; #0x2 is Flying
strb r1, [r0]
ldr r1, =(0x80CA804 +1) @look for flying type
bl CALLER
cmp r0, #0x6 @check if there is a flying type
bge NORMALMAP @if no flying open normal map
ldr r1, .SLOT @bug fix for showing wrong Pokemon
strb r0, [r1] @write slot number of flying type to .SLOT
ldr r1, =(0x80C4EF8 +1) @open Fly map
bl CALLER
b END
NORMALMAP:
ldr r1, =(0x80A1CC0 +1)
bl CALLER
b END
CALLER:
bx r1
END:
pop {r0-r1,pc}
.align 2
.VAR:
.word 0x020270B8 + (0x8000 * 2)
.SLOT:
.word 0x0203B0A9
These scripts are mostly independent, but they all reference one script for the overall enable/disable flag check, and also one script for a sort of initialization/check that the game does for each HM. I don't think it's necessary but I decided to leave it in just in case.
Decap
Spoiler:
All the texts used are decap-agnostic because they dynamically load the names of Pokemon and attacks, except for the Fly menu change. Those are capitalized by default so that this patch can be applied to vanilla FR with no editing, but decapped versions of those texts are already included as well. To use them, navigate to the two offsets below and make these changes:
Spoiler:
At 0x3A735C, paste-write:
At 0x3A73A0, paste-write:
These will point the name and description for the menu text to the decapped versions instead.
Code:
2C 06 76
At 0x3A73A0, paste-write:
Code:
34 06 76
These will point the name and description for the menu text to the decapped versions instead.
Compatibility
Now, you'll notice I have used free space for these new scripts (from 760000-760704), which means this patch MIGHT NOT be compatible with hacks in progress. Since most people start at 800000, there's a good chance it IS compatible (for instance, this patch is 100% compatible with MrDollsteak's Attack and Decap Rombase!) but it's not guaranteed. If you really want to add this to a hack in progress, below are instructions for doing so.
Spoiler:
Tools required:
XSE ( v1.1.1 - older versions may not work)
A hex editor (I recommend HxD)
Advance Map (only needed for Flash)
There a a lot of steps. Gives you an idea of how long it took to develop this.
First, you'll need to insert FBI's modified special 0x12b. Here are instructions for doing so (quoted from FBI's thread):
Next, open up your ROM in XSE, copy and paste the script below into the XSE window, and compile. I've used dynamic offsets for all the new scripts, so this will NOT overwrite anything you've already done. The static offsets you see in the scripts are those for existing HM scripts, calls to scripts that end, release, etc., and the appropriate text strings. A fun note: because these scripts call existing text strings and dynamically pull the names of attacks, they're decap-agnostic! You'll note I have the dynamic start offset set to 0x760000; feel free to change that if you want. Note down the offset it gives you for @Flash, and for @flagcheck. You'll need to apply the Flash hack manually - see Usage above - and you'll need the @flagcheck offset to apply the Fly hack.
Looooong script:
Next, make the following edits in your hex editor:
Don't worry about bypassing the badge checks - my script has a badge check you can use if you want. We just need to bypasses this one to start the new check process.
Then, to apply the Fly hack, make these changes:
XSE ( v1.1.1 - older versions may not work)
A hex editor (I recommend HxD)
Advance Map (only needed for Flash)
There a a lot of steps. Gives you an idea of how long it took to develop this.
First, you'll need to insert FBI's modified special 0x12b. Here are instructions for doing so (quoted from FBI's thread):
Put into some free space (even ending):
Keep track of the offset you inserted this in.Code:06 4A 12 78 88 79 90 42 02 D0 C8 79 90 42 03 D1 28 1C 70 BC 02 BC 08 47 01 48 00 47 B8 70 03 02 59 A8 0C 08
Now go to 0xCA840, and insert:
Finally, for the next four bytes, you must do some reverse hex. Take the offset you inserted in, and prefix it with 08. Then insert the reverse hex version of the whole thing plus 1.Code:00 48 00 47
So if I inserted at 7266B0, then
7266B0 = 087266B0
087266B + 1 = 087266B1
087266B1 = B1 66 72 08 (you insert this after 00 48 00 47).
Finally we want to return 6, if there isn't a Pokemon in the party of the type we specified. Go to 0xCA862 and change 00 to 06. That's it!
Next, open up your ROM in XSE, copy and paste the script below into the XSE window, and compile. I've used dynamic offsets for all the new scripts, so this will NOT overwrite anything you've already done. The static offsets you see in the scripts are those for existing HM scripts, calls to scripts that end, release, etc., and the appropriate text strings. A fun note: because these scripts call existing text strings and dynamically pull the names of attacks, they're decap-agnostic! You'll note I have the dynamic start offset set to 0x760000; feel free to change that if you want. Note down the offset it gives you for @Flash, and for @flagcheck. You'll need to apply the Flash hack manually - see Usage above - and you'll need the @flagcheck offset to apply the Fly hack.
Looooong script:
Spoiler:
Code:
#dynamic 0x760000
'---------------
#org @flash
lock
setvar 0x4000 0x1 'set this to the flag variable in A-Map (can be 4000-4010 - temps)
checkflag 0x806 'flash active flag - do not change
if 0x1 goto 0x1A7AE0
call @init 'initialization check, from original
call @flagcheck 'check if new check system is enabled
if 0x0 goto 0x1A7AE0 'if not, release and end
checkflag 0x828 'set this to the new badge you want (828 is the pkmn menu)
if 0x0 goto 0x1A7AE0 'if not set, release and end
lockall
setvar 0x8000 0xA 'set this to the type you want (A is Fire)
special2 0x4001 0x12B 'these lines are the new check
compare 0x4001 0x6
if 0x4 goto 0x1A7AE0
bufferpartypokemon 0x0 0x4001
bufferattack 0x1 0x94
msgbox @question MSG_YESNO '"[buffer1] can light up the\ndarkne..."
compare LASTRESULT 0x0
if 0x1 goto 0x1A7AE0
msgbox 0x81BDFD7 MSG_KEEPOPEN '"[buffer1] used [buffer2]!"
setanimation 0x0 0x4001
doanimation 0x28
waitstate
lighten 0x0
darken 0x0
setflag 0x806
releaseall
end
'---------
' Strings
'---------
#org @question
= [buffer1] can light up the darkness\nwith [buffer2]. Use [buffer2]?
'---------------
#org 0x1BDF13
goto @newcut
'---------------
#org @newcut
call @init 'initialization check, from original
call @flagcheck 'check if new check system is enabled
if 0x0 goto @originalcut
lockall
checkflag 0x828 'set this to the new badge you want (828 is the pkmn menu)
if 0x0 goto 0x81BDF87
setvar 0x8000 0xC 'set this to the type you want (C is Grass)
special2 0x4001 0x12B
compare 0x4001 0x6
if 0x4 goto 0x81BDF87
'setvar 0x4001 LASTRESULT
goto @cutaction
'---------------
#org @originalcut
checkflag 0x821
if 0x0 goto 0x81BDF87
checkattack 0xF
compare LASTRESULT 0x6
if 0x1 goto 0x81BDF87
goto @cutaction
'---------------
#org @cutaction
setanimation 0x0 0x4001
bufferpartypokemon 0x0 0x4001
bufferattack 0x1 0xF
msgbox 0x81BDF94 MSG_YESNO '"This tree looks like it can be Cut..."
compare LASTRESULT 0x0
if 0x1 goto 0x81BDF91
msgbox 0x81BDFD7 MSG_KEEPOPEN '"[buffer1] used [buffer2]!"
closeonkeypress
doanimation 0x2
waitstate
goto 0x81BDF76
'---------------
#org 0x1BE00C
goto @newrocksmash
'---------------
#org @newrocksmash
call @init 'initialization check, from original
call @flagcheck 'check if new check system is enabled
if 0x0 goto @originalrocksmash
lockall
checkflag 0x828 'set this to the new badge you want (828 is the pkmn menu)
if 0x0 goto 0x81BE091
setvar 0x8000 0x1 'set this to the type you want (1 is Fighting)
special2 0x4001 0x12B
compare 0x4001 0x6
if 0x4 goto 0x81BE091
'setvar 0x4001 LASTRESULT
lockall
goto @rocksmashaction
'---------------
#org @originalrocksmash
lockall
checkflag 0x825
if 0x0 goto 0x81BE091
checkattack 0xF9
compare LASTRESULT 0x6
if 0x1 goto 0x81BE091
goto @rocksmashaction
'---------------
#org @rocksmashaction
setanimation 0x0 0x4001
bufferpartypokemon 0x0 0x4001
bufferattack 0x1 0xF9
msgbox 0x81BE09D MSG_YESNO '"This rock appears to be breakable...."
compare LASTRESULT 0x0
if 0x1 goto 0x81BE09A
msgbox 0x81BDFD7 MSG_KEEPOPEN '"[buffer1] used [buffer2]!"
closeonkeypress
doanimation 0x25
waitstate
goto 0x81BE06F
'---------------
#org 0x1BE11D
goto @newstrength
'---------------
#org @newstrength
call @init 'initialization check, from original
call @flagcheck 'check if new check system is enabled
if 0x0 goto @originalstrength
lockall
checkflag 0x828 'set this to the new badge you want (828 is the pkmn menu)
if 0x0 goto 0x81BE185
checkflag 0x805 'strength active flag - do not change
if 0x1 goto 0x81BE18E
setvar 0x8000 0x1 'set this to the type you want (1 is Fighting)
special2 0x4001 0x12B
compare 0x4001 0x6
if 0x4 goto 0x81BE185
'setvar 0x4001 LASTRESULT
goto @strengthaction
'---------------
#org @originalstrength
lockall
checkflag 0x823
if 0x0 goto 0x81BE185
checkflag 0x805
if 0x1 goto 0x81BE18E
checkattack 0x46
compare LASTRESULT 0x6
if 0x1 goto 0x81BE185
goto @strengthaction
'---------------
#org @strengthaction
bufferattack 0x1 0x46
setanimation 0x0 0x4001
msgbox 0x81BE19A MSG_YESNO '"It's a big boulder, but a Pokémon\..."
compare LASTRESULT 0x0
if 0x1 goto 0x81BE197
closeonkeypress
doanimation 0x28
waitstate
setflag 0x805
msgbox @strengthtext MSG_NORMAL '"[buffer1] used [buffer2]!\p[buffer..."
end
'---------
' Strings
'---------
#org @strengthtext
= [buffer1] used [buffer2]!\p[buffer1]'s [buffer2] made it\npossible to move boulders around!
'---------------
#org 0x1A6AC8
goto @newsurf
'---------------
#org @newsurf
call @init 'initialization check, from original
call @flagcheck 'check if new check system is enabled
if 0x0 goto @originalsurf
checkflag 0x828 'set this to the new badge you want (828 is the pkmn menu)
if 0x0 goto @nosurf
setvar 0x8000 0xB 'set this to the type you want (B is Water)
special2 0x4001 0x12B
compare 0x4001 0x6
if 0x4 goto @nosurf
'setvar 0x4001 LASTRESULT
goto @surfaction
'---------------
#org @originalsurf
checkflag 0x824
if 0x0 goto 0x1A6B0C
checkattack 0x39
compare LASTRESULT 0x6
if 0x1 goto 0x81A6B0C
goto @surfaction
'---------------
#org @surfaction
setanimation 0x0 0x4001
bufferpartypokemon 0x0 0x4001
lockall
bufferattack 0x1 0x39
msgbox 0x81A556E MSG_YESNO '"The water is dyed a deep blue[.]\n..."
compare LASTRESULT 0x0
if 0x1 goto 0x81A6B0B
msgbox 0x81BDFD7 MSG_KEEPOPEN '"[buffer1] used [buffer2]!"
doanimation 0x9
releaseall
end
'---------------
#org @nosurf
msgbox @nosurftext MSG_SIGN
releaseall
end
'---------
' Strings
'---------
#org @nosurftext
= The water is dyed a deep blue[.]
'---------------
#org 0x1BE2B7
goto @newwaterfall
'---------------
#org @newwaterfall
call @init 'initialization check, from original
call @flagcheck 'check if new check system is enabled
if 0x0 goto @originalwaterfall
checkflag 0x828 'set this to the new badge you want (828 is the pkmn menu)
if 0x0 goto 0x81BE300 'specific to waterfall
setvar 0x8000 0xB 'set this to the type you want (B is Water)
special2 0x4001 0x12B
compare 0x4001 0x6
if 0x4 goto 0x81BE300 'specific to waterfall
'setvar 0x4001 LASTRESULT
goto @waterfallaction
'---------------
#org @originalwaterfall
checkflag 0x826
if 0x0 goto 0x1A6B0C
lockall
checkattack 0x7F
compare LASTRESULT 0x6
if 0x1 goto 0x81BE300
goto @waterfallaction
'---------------
#org @waterfallaction
setanimation 0x0 0x4001
bufferpartypokemon 0x0 0x4001
lockall
bufferattack 0x1 0x7F
msgbox 0x81BE33F MSG_YESNO '"It's a large waterfall.\nWould you..."
compare LASTRESULT 0x0
if 0x1 goto 0x81BE308
msgbox 0x81BDFD7 MSG_KEEPOPEN '"[buffer1] used [buffer2]!"
doanimation 0x2B
goto 0x81BE308
'---------------
#org @init
special 0x187 'some error check that the game does for each HM
compare LASTRESULT 0x2
if 0x1 goto 0x81A7AE0
return
'---------------
#org @flagcheck
setvar 0x4001 0x0 'initialize variable - fixes a silly bug
setvar LASTRESULT 0x0 'initialize variable - fixes a silly bug
checkflag 0x828 'set this to the new flag to enable/disable the new checks
return
Next, make the following edits in your hex editor:
Code:
At 0x6D588, replace 0C D1 with 00 00 (this allows Surf to look outside its own check)
At 0x6D566, replace 03 D1 with 00 00 (this allows Waterfall to look outside its own check)
At 0x6D59C, replace 24 08 with 28 08 (bypasses game's Surf badge check)
At 0x6D5D0, replace 26 08 with 28 08 (bypasses game's Waterfall badge check)
Don't worry about bypassing the badge checks - my script has a badge check you can use if you want. We just need to bypasses this one to start the new check process.
Then, to apply the Fly hack, make these changes:
Spoiler:
At free space ending in a multiple of 4, paste-write:
where XX XX XX is a (reversed) pointer to [the offset of @flagcheck from the XSE script +0xB (hex)]. This is the offset where the actual number for the flag to check is written.
Note down the offset where you paste. This the Fly routine.
At 0x3A7344, paste-write:
This is the Start menu change.
At free space, paste-write:
This is the Map name text. If you want it decapped, paste-write this instead:
At free space, paste-write:
This is the Map description text. If you want it decapped, paste-write this instead:
At 0x3A7360 write in a pointer to the offset of the fly routine + 1.
At 0x3A735C, write in a pointer to the offset of the "name" text.
At 0x3A73A0, write in a pointer to the offset of the "description" text.
At free space ending in a multiple of 4, paste-write:
This is a bug fix for the menu.
At 0x6EDC6, write in 01 48 00 47 00 00 followed by a pointer to offset of the bug fix + 1.
At 0x6EDD0, paste-write:
This is a change to the order that the START menu options load.
All the ASM was written by FBI, except for a slight edit to the Fly routine done by me (to add in flag checks). For more info and the actual ASM, check out FBI's thread on changing the HM checks.
Code:
03 B5 12 49 08 88 12 49 00 F0 1A F8 00 28 13 D0 10 48 0F 49 00 F0 14 F8 00 28 0D D0 09 48 02 21 01 70 0D 49 00 F0 0C F8 06 28 05 DA 06 49 08 70 0A 49 00 F0 05 F8 04 E0 09 49 00 F0 01 F8 00 E0 08 47 03 BD B8 70 03 02 A9 B0 03 02 XX XX XX 08 D1 E6 06 08 28 08 00 00 05 A8 0C 08 F9 4E 0C 08 C1 1C 0A 08
where XX XX XX is a (reversed) pointer to [the offset of @flagcheck from the XSE script +0xB (hex)]. This is the offset where the actual number for the flag to check is written.
Note down the offset where you paste. This the Fly routine.
At 0x3A7344, paste-write:
Code:
7D 62 41 08 11 F4 06 08 66 5A 41 08 4D F4 06 08 85 62 41 08 81 F4 06 08 30 A4 71 08 51 A4 71 08 8E 62 41 08 B5 F4 06 08 96 62 41 08 FD F4 06 08 91 62 41 08 E9 F4 06 08 9D 62 41 08 41 F5 06 08 A2 62 41 08 55 F5 06 08 00 01 01 0A 04 0F 08 00 76 9F 41 08 BB 9F 41 08 01 A0 41 08 34 A4 71 08 49 A0 41 08 B7 A0 41 08 6F A0 41 08 11 A1 41 08 49 A0 41 08 F8 01 00 00 00 02 0F 1A 04 0F 98 01 FF 00 00 00 00 00 00 00 00 01 01 0E 09 0D 08 00 01 02 03 00 01 04 05 00 01 06 07 00 00 00 00 00 00 00 B0 BB 00 B0 BB AA 00 AB BA AA 00 AB 99 BB B0 BB 99 BA B0 AA AB BA B0 AA AB BB 00 00 00 00 00 00 00 00 0B 00 00 00 0B 00 00 00 BB B0 0B 00 AA AB BA 00 AA 99 AA 0B BB 99 BB 0B 00 BB B4 BB 00 44 44 4F 40 FD 4F F4 40 DF 4F 44 00 44 44 FD 00 FF D4 DF 00 00 F4 FD 00 00 40 44 AA BA AA 0B AB BA AA 0B B4 4B BB 00 F4 44 F4 0F 4F 44 44 FF 4F FF DF F4 F4 F4 FD 04 FF 4F 44 00 00 00 00 00 00 00 B0 0B 00 BB AB BA B0 AA AB BA B0 9A B9 BB BB 9B A9 BB AB BA AA AB AB BA BA AB 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B BB 00 00 BA AA 0B 00 9A A9 BA 00 B0 4B BB BB 00 44 44 AB 40 FD 4F BF 40 DF 4F 44 00 44 44 FD 00 FF D4 DF 00
This is the Start menu change.
At free space, paste-write:
Code:
C7 BB CA FF 00 FF
This is the Map name text. If you want it decapped, paste-write this instead:
Code:
C7 D5 E4 FF 00 FF
At free space, paste-write:
Code:
BD DC D9 D7 DF 00 ED E3 E9 E6 00 E4 E6 D9 E7 D9 E2 E8 00 E0 E3 D7 D5 E8 DD E3 E2 00 D5 E2 D8 00 D8 D9 D7 DD D8 D9 FE EB DC D9 E6 D9 00 E8 E3 00 C0 C6 D3 B8 00 DD DA 00 ED E3 E9 00 DC D5 EA D9 00 D5 00 C0 C6 D3 C3 C8 C1 AE CE D3 CA BF AD FF 00 FF
This is the Map description text. If you want it decapped, paste-write this instead:
Code:
BD DC D9 D7 DF 00 ED E3 E9 E6 00 E4 E6 D9 E7 D9 E2 E8 00 E0 E3 D7 D5 E8 DD E3 E2 00 D5 E2 D8 00 D8 D9 D7 DD D8 D9 FE EB DC D9 E6 D9 00 E8 E3 00 C0 E0 ED B8 00 DD DA 00 ED E3 E9 00 DC D5 EA D9 00 D5 00 C0 E0 ED DD E2 DB AE E8 ED E4 D9 AD FF 00 FF
At 0x3A7360 write in a pointer to the offset of the fly routine + 1.
At 0x3A735C, write in a pointer to the offset of the "name" text.
At 0x3A73A0, write in a pointer to the offset of the "description" text.
At free space ending in a multiple of 4, paste-write:
Code:
30 B4 0C 1C 13 48 14 49 00 F0 22 F8 00 06 00 0E 01 28 1A D1 01 20 11 49 00 F0 1A F8 02 20 0F 49 00 F0 16 F8 03 20 0D 49 00 F0 12 F8 04 20 0B 49 00 F0 0E F8 05 20 09 49 00 F0 0A F8 06 20 07 49 00 F0 06 F8 30 BC 01 BC 00 47 30 BC 04 48 00 47 08 47 C0 46 28 08 00 00 D1 E6 06 08 95 ED 06 08 DB ED 06 08
This is a bug fix for the menu.
At 0x6EDC6, write in 01 48 00 47 00 00 followed by a pointer to offset of the bug fix + 1.
At 0x6EDD0, paste-write:
Code:
01 28 02 D1 01 20 FF F7 DD FF 02 20 FF F7 DA FF 04 20 FF F7 D7 FF 05 20 FF F7 D4 FF 06 20 FF F7 D1 FF 06 20 00 00 00 00 01 BC 00 47 29 08 00 00
This is a change to the order that the START menu options load.
All the ASM was written by FBI, except for a slight edit to the Fly routine done by me (to add in flag checks). For more info and the actual ASM, check out FBI's thread on changing the HM checks.
Bugs
Spoiler:
When using HM moves in the overworld, the animation and text always show the first Pokémon in your party, not necessarily the one with the correct typeFIXED in Version 1.1 thanks to mbcn10ww and FBI- In the Safari Zone, the option to RETIRE from the START menu is gone. This is because this hack changes the START menu and the Safari Zone uses a different version of the START menu that I never bothered to check while building it. The issue is documented here. Since it's not game-breaking in any way (the only ill effect is that you lose the option to immediately "retire" from the Start menu and have to use up your steps instead), I don't plan on addressing it, but I have posted the relevant information in the linked thread in case you want to take a crack at it.
Credits
I intend to use this in my upcoming hack, and now you can, too! With permission from FBI, this patch is for public use. Feel free to use it as long as you credit the following people:
FBI - for the research and ASM development, plus help with fixing a bug with Fly
knizz - for helping in FBI's research on Fly
touched - for helping create FBI's modified special 0x12b
mbcn10ww - for discovering and fixing a bug with the wrong Pokemon being displayed
Uncommon - for writing the scripts, testing, and creating this patch
Downloads
and finally... the patch!
Version 1.1 - .zip file that includes both the full patch and a patch to upgrade from version 1.0 to 1.1, plus instructions in the ReadMe
Changelog
Spoiler:
12/2/15 - Version 1.0 released
1/1/17 - Version 1.1 released (fixes a bug where the animation and text always show the first Pokémon in your party, not necessarily the one with the correct type - credit to mbcn10ww and FBI)
1/1/17 - Version 1.1 released (fixes a bug where the animation and text always show the first Pokémon in your party, not necessarily the one with the correct type - credit to mbcn10ww and FBI)
Last edited: