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

Development: Changing how Surf works (using a modified special 0x12b)

Status
Not open for further replies.

Blah

Free supporter
1,924
Posts
11
Years

Surf and Special 0x12b Hack

(for Fire Red only)
Also see:
Changing Waterfall: http://www.pokecommunity.com/showpost.php?p=8496240&postcount=3
Changing Fly: http://www.pokecommunity.com/showpost.php?p=8505424&postcount=8
Changing Flash: http://www.pokecommunity.com/showpost.php?p=8505791&postcount=14

Goal and achievement:


My goal during the recent days was to mimic the anime in terms of how trainers commute in the water. I decided to try and make it so that if you have a water type Pokemon you can surf, regardless of move pool. As such, below is a semi-guide/resource to functionality of how you can implement such a feature yourself! You will also find my (and Touched's) implementation of a special that checks your party for a certain type of Pokemon.

Thought process and reasoning:


I've been trying to figure out how to remove the badge and HM requirement for surfing. I found
The script and removed the move requirement, but it seems I still can't bring up the surf script even with the badge. It seemed to keep checking if a Pokemon has learned surf before allowing me to activate the script. I wasn't quite sure where the second check is taking place, so I kinda backtracked..and landed on quite the peculiar structure.

Structure so far (forgive my formatting):
Code:
0806D548 - start
	- operations
0806D550 - tile behavior check (may be height check)
compare behavior 0x0 or 0x1 (waterfall vs surf ...I think)
B 0806D570 - if surf goes here, else keep going
BL to 0805C83C - nested for loop. Loops Pokemon and moves (using move decryption, this is for waterfall) 
compare move found (searches for waterfall I think)
	B 0806D570 - if move found goes here
	B 0806D5E2 - if not found goes here (a routine exit)
at 0806D570
	ldr r0, [0x806D59C]
	B 0806E6D0 (flag checker, the gym flag folks)
		Check to see if var is 0x1 (that is the gym flag is set)
		if not set B 0806D5A4
		else run function BL to 0805C83C - nested for loop. Loops Pokemon moves (this one is for SURF!)
			@ 0806d586 - checks for the surf (real check!)
			if surf found B 0805C8B0 - collision detection
			 check no collision, - Execute -
         And then a bunch of things we don't really care about.

So now you ask, how do we remove the HM requirement?! It's simple, you remove the else condition in the check. I.e pad it with 0s.

The solution to removing HM Surf from the picture:
At 0x6D588 - 0x6D589 change 0C D1 to 00 00.

Now what this exactly does is remove the check (outside of the script) for surf. However, surf is still checked for in the script itself.
You need to edit the script to whatever it is you wanted the surf condition to be, OR, you can use the edited version of special 0x12b I will talk about shortly.

Introduction to the special:

Thanks to Jpan's research on specials I found out that special 0x12b was a special which would tell you if your party had a grass Pokemon. Quite simple, and to be honest, very useless. However this special did do a few things internally that are actually worth using. It ran through your entire party and checked your Pokemon's type (and the check supported dual types, that is Pokemon like Venasaur would be flagged as grass too). So if we can modify the special to work for any type we specify would that be useful? What if we were also able to return the slot of the Pokemon who was of that type? Yes, please :P

The original (starts at 080CA804):
Spoiler:


I haven't explained some of the parts about getting Pokemon from part and looking it up in the table, but if you have questions I can answer.

The part of the code which we may be interested mostly by is the check part. It checks for 0xC (for grass) at the Pokemon's Type 1 and Type 2 slot. If you want you can change this statically to match a type of your choosing by simply modifying 0xC to a type you wanted to check.
Types are defined like this:
Spoiler:


However, Touched and I made this routine for the check part :
A)
Spoiler:


What it does is compares the type 1 and type 2 to a variable (in this case 0x8000). If a Pokemon of that type is found we return into 0x8000 the slot of that Pokemon from 0 to 5, returning a 6 if no Pokemon of that type was found. Note that the variable can be changed to another variable, though careful which you use (encrypted variables and 0x800D, 0x800E, 0x800F don't work since we'd never be able to check the last result without overwriting it and similar situations with the rest.


Inserting:


To insert this into your FR ROM, you need to assemble it into free space and call it.
We overwrite the line ldrb r0, [r1, #0x6] and whatever else we need with a bx.
That is:
Code:
	ldr r0, = Routine +1
	bx r0

To insert this, first assemble A). Put it into some free space (even ending). If you don't know how to assemble it's:
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
Keep track of the offset you inserted this in.

Now go to 0xCA840, and insert:
Code:
00 48 00 47
Finally, for the next for bytes, you must do some reverse hex. Take the offset you inserted A) in, and prefix it with 08. Then insert the reverse hex version of the whole thing plus 1.
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!

Sample Script:
PKSV
Spoiler:


XSE:
Spoiler:


Note: The Pokemon's slot number is stored in whichever variable you give it. You can feed it 0x8000 if you wanted to use only 1 variable.


Extras (Surf hack + Special in conjunction):


PKSV script
Spoiler:


XSE:
Spoiler:


End:

I hope you found the hacks/research, or at least the special useful :)
If you use either, please give credit to Touched. I don't particularly require credit, but if you want, please do give :P



...
 
Last edited:

Xela

Do you believe in yourself?
349
Posts
16
Years
  • Age 27
  • Seen Feb 18, 2024
This is a pretty cool function. I might even use this, actually. Great job on figuring it out! Maybe do something similar to Fly but add a check for species to prevent certain Pokémon from doing it?
 

Blah

Free supporter
1,924
Posts
11
Years
This is a pretty cool function. I might even use this, actually. Great job on figuring it out! Maybe do something similar to Fly but add a check for species to prevent certain Pokémon from doing it?

Fly is a little more complicated than surf. Unlike surf, there isn't really a script for me to use to back track (at least not an obvious one). I checked out the fail message, and l ended up finding myself in a table full of Pokemon Menu messages (I even found the "FLY" blue highlight on Pokemon able to use it), sadly I haven't been able to find the part of the code that utilizes it yet. Anyways, if I'm gonna end up doing it, I'll be doing it through hacking the Pokemon menu. Look forward to it :P

Slight Update (Waterfall):
I didn't really talk about it in the main post, but this is to those who want to give waterfall the surf treatment. Structurally the code that checks waterfall & surf are exactly the same, so the edit is also very similar...very similar :P
At 0x6D566, replace 03 D1 with 00 00

Also, you need to edit the waterfall script as well at 0x1BE2B7 (decompile in script editor)
Speaking of script locations, surf is at 0x1A6AC8
 
416
Posts
11
Years
  • Age 35
  • Seen Feb 10, 2024
do you think it would be too hard to use this info to edit it to make an item work with surf... so as long as you have the item you can surf...
 

Blah

Free supporter
1,924
Posts
11
Years
do you think it would be too hard to use this info to edit it to make an item work with surf... so as long as you have the item you can surf...

Yeah that would be very easy. There's already a tutorial on item creation + custom scripts on those items. Callasm to here, and remove the type check.
 
Last edited:

Xela

Do you believe in yourself?
349
Posts
16
Years
  • Age 27
  • Seen Feb 18, 2024
How's the progress on making "Fly" work similarly? I heard you talk about it in the IRC and thought you might have an update on it.
 

Blah

Free supporter
1,924
Posts
11
Years
How's the progress on making "Fly" work similarly? I heard you talk about it in the IRC and thought you might have an update on it.

Coincidental that you'd ask :P

Implementation of Fly HM02 using the Start menu and a modified special 0x12b!

(for Fire Red only)


Goal and achievements:


When I was changing HM Fly, the first idea was to change the bottom right Pokemon selection menu, however, that whole feature was a nested mess. I mean, it was impossible to locate functions that did anything specific, and the whole feature was just poorly coded with assumptions about things everywhere (I'm not gonna get into that anyways). It was then suggested by Alex that I just incorporate it into the start menu. So that's what I've done. Right now, what this hack achieves is it creates a menu option called "Map" and if you have a flying type it will allow you to fly to locations on the map, otherwise, it will just open the regular town map. By the way, if you don't care for the technical insertion/research process, there's a patch in the bottom of this post (uses space 71A430-71A4B4).


Manually inserting and Explanation of implementation

First step:

The main part of this hack is to utilize our edited special 0x12b to figure out if we have a flying type, then depending on the result, open the flying map or the regular town map. Thankfully that part, to code, wasn't hard. Finding the functions that opened each of them individually was the harder part. If you look at the normal Town map caller or HM Fly caller for example, it was a special kind of hell. Anyways, many credits to Knizz for spending hours of his time with me locating these functions (thanks buddy, would've taken ages without you!).

Now the code (which I didn't bother commenting too much because it is rather simple).
Spoiler:


You need to assemble this into free space somewhere in your ROM. Here is the assembled version:
Code:
00 B5 09 48 02 21 08 70 08 49 00 F0 0A F8 06 28 03 DA 07 49 00 F0 05 F8 04 E0 06 49 00 F0 01 F8 00 E0 08 47 00 BD C0 46 B4 70 03 02 05 A8 0C 08 F9 4E 0C 08 C1 1C 0A 08
Remember where you insert it (it becomes relevant soon).

You'll notice that I'm branching to (0x80C4EF8 +1) and (0x80CA804 +1) respectively. As you'd guess both of these functions are standalone for opening the townmap and "fly map" directly without the item/pokemon. Also note that this code assumes you've inserted my modified version of special 0x12b (the patch inserts this for you), to manually insert see the main post.


Hacking the Start Menu


The next step is calling this function through the start menu. I'm going to explain the process in case someone else is also planning to implement a similar feature into the start menu.

The first complication when inserting to the start menu comes when you realize that the start menu is limited to display 7 options at once. Trying to insert anymore will cause a crash (I haven't investigated the technicalities behind the crash, but it happens when we attempt to insert an eighth item). I should also mention that even if you insert an eight item, without changing box sizes, font size and the rest of that relevant material the menu will overlap and the description box and probably create a sad bug.
The second complication is that the "table" the start menu insertion code goes through is also not easily expandable. So on top of only showing 7 options, the table's items are accessed directly. For example you may see somewhere something that pulls the 4th item directly from the table by referencing the offset at the 4th index of the table (without a mathematical formula...just directly). To expand the table then, you'd need to re point all of these references too (which is really just a pain, and I wouldn't even bother).

Easy way out: Instead I decided to remove the "EXIT" option, which really achieved nothing special. It has the same functionality as pressing "b" in console.

So what I ended up doing is reorganizing the data table and the descriptions table (fixing minor pointer details). It currently looks like this:
ojikVyY.png

In this order and descriptions updated to match the order of appearance. I've also taken the time to remove "exit" from the normal menu in general for consistency.
The hex changes below are rather numerous, but that is because I changed the order items appeared on the menu. If you wanted to just overwrite "Exit" then get the hex version of the string you are trying to replace it with, put it into free space and fix the pointers (I will explain that shortly)
For this just ctrl + C this:
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
and ctrl+b at 0x3A7344. (basically you want to overwrite the bytes at 0x3A7344 with this)


If you plan to change some pointers here is the format (credits to knizz for his database):
Spoiler:


If you are manually inserting, then I hope you remember the offset you assembled the ASM script from before. You need to ctrl+f 30 A4 71 08 51 A4 71 08 from my hex paste above. The first half of that is a pointer to the string (my case was "Map" the second half is a pointer to the function i.e the one we assembled earlier. The function's pointer is in reverse hex +1 and the string pointer is just in reverse hex).


The Bug fix:


Alright, so far if you run the game, you'll get a program that pulls out a map menu somewhere along the lines, but you'll notice there are two occurrences of it, that and it's very buggy before and after you get a Pokemon in your party. Well, lets fix that.

Current code vs. my algorithm:
Spoiler:


The code to do this is simple, first compile this into free space:
Spoiler:


Now go to 0x6EDC6 and overwrite the bytes there with:
01 48 00 47 00 00
The next 4 bytes after these 6 is the pointer to the above assembled code + 1 in reverse hex.
What the above does is creates a branch from the initial flagcheck into our routine.

Finally we need to modify the order that the other menus come up pre-map availablity.
Go to 0x6EDD0 and ctrl+b this:
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


End:


I hope you find the above research/explanations useful. I tried to explain the start menu a little bit extra, even though it was slightly out of context, because I hope to see more hacks editing it.

Credits to knizz for helping me with the research and to Touched for helping with an alignment bug.
If you find any bugs please report them to me via this thread or PM :3

Uhh, oh right link to patch: http://www.mediafire.com/download/bzb2m5w6bzbdzyx/PFR.ips
 
Last edited:

Trainer 781

Guest
0
Posts
This is a really wonderful feature. Now, people who like using Hydro Pump on water Pokemon (or like keeping a physical one) and Brave Bird or Hurricane on Flying Pokemon will not be forced to use a HM Slave for Surf or Fly (unless they don't have a water or flying type).
A ton of likes for this!!
 

Blah

Free supporter
1,924
Posts
11
Years
This is a really wonderful feature. Now, people who like using Hydro Pump on water Pokemon (or like keeping a physical one) and Brave Bird or Hurricane on Flying Pokemon will not be forced to use a HM Slave for Surf or Fly (unless they don't have a water or flying type).
A ton of likes for this!!

Yeah that was the intention. I should also mention that the existing HM mechanisms still work. So if you have a Pokemon that's not a water type but has the move surf, you can still surf :)

I'm off to tackle the next HM, which happens to be Flash. Sadly, I don't know what to do for this. I can't really add another Start Menu option :/
 
416
Posts
11
Years
  • Age 35
  • Seen Feb 10, 2024
I got flash to work as a script, no asm... but its the circle around you not a full screen flash. And it goes away every battle or warp...

Spoiler:

scripted in PKSV

I got ALL the HMs except the ones youve outlined in this thread(Surf, fly, and waterfall) to work as items with only scripting. of course my flash item isnt perfect (as outlined above)
 
Last edited:
416
Posts
11
Years
  • Age 35
  • Seen Feb 10, 2024
How did you manage that without the move?
edit:

I have no idea what that does, mind explaining?

#raw is just a hex digit... pksv does not recognize that command... but 9A is a command that makes the light circle around the player larger.

the second #raw is the size... but its not direct 01 was nearly the full screen, 02 was half that... anything else seemed to crash the game, or do nothing (i did not test every digit, just several others).

it resets after each battle or warp but it makes a fine flashlight item... not as good as the HM but good enough.

in my mind, its perfect cause it punishes the player for not using the HM... (in my game you get both, the HM and the item). the HM clearly sucks wasting a move slot, and the item sucks cause you have to reuse it and its not complete full screen flash... BUT they both work and I personally would rather deal with pushing select after each battle for a couple caves than wasting amove... just sayin.

I have a similar delima for cut... the HM can actually cut grass, my item (a sickle) cannot... it only cuts trees... but honestly who cuts grass anyway.
 
Last edited:

Blah

Free supporter
1,924
Posts
11
Years
#raw is just a hex digit... pksv does not recognize that command... but 9A a command that makes the light circle around the player larger.

the second #raw is the size... but its not direct 01 was nearly the full screen, 02 was half that... anything else seemed to crash the game.

it resets after each battle or warp but it makes a fine flashlight item... not as good as the HM but good enough.

Thanks, but looks like this isn't even necessary.

I looked at the routine that handles flash and it seems to be very easy to replicate. Infact, you'll be relieved to hear you can do it in a script. Most of the routine handled checks, the size of the flash and other small complications. To flash the entire screen we just ignore these restrictions. The string of commands which PKSV recognizes as:
lightroom 0x0
darkenroom 0x0
and XSE recognizes as:
lighten 0x0
darken 0x0

darken 0x0, contrary to it's name, also seems to keep the room lit after wild battles. However, if you warp, the "flash" effect will wear off. So the game sets a special flag "0x806". It seems like if this flag is set then even if you warp, the cave will remain flashed :)

Insert this into a level script to have a functioning "FLASH" whenever you enter a flash-able cave. Right now it only does electric types, but with a little bit of editing it can be changed to include others (Fire perhaps?)
note: requires my edited special 0x12b

Spoiler:


EDIT: Oh so Locksmith for your flashlight you'd just have it do
Code:
lightenroom 0x0
darkenroom 0x0
setflag 0x806
msgbox @whatever
...

EDIT2: That concludes my HM crusade, I guess. I wasn't expecting Flash to be just done by a script :/
 
Last edited:
416
Posts
11
Years
  • Age 35
  • Seen Feb 10, 2024
thanks... thats y we have awesome ASM hackers, to find scripts us scripters cant find lol.

FYI: the above script is tested and works as an item.
Code:
lightroom 0x0
darkenroom 0x0
setflag 0x806
msgbox @whatever
...

except that its lightroom not lightenroom
 
Last edited:

pokemontutorialTV

TheGreatest
13
Posts
10
Years
  • Seen Apr 28, 2023
Could you modify the asm, so it checks a specific teamslot (or starts at slot X)? That would be so cool :) I want to make a feature, that poisions your Pokémon, if you go over toxic bushes.
I just need to check for poision and steel-type in my team.
 

Blah

Free supporter
1,924
Posts
11
Years
Could you modify the asm, so it checks a specific teamslot (or starts at slot X)? That would be so cool :) I want to make a feature, that poisions your Pokémon, if you go over toxic bushes.
I just need to check for poision and steel-type in my team.

Hi, this has nothing to do with HMs! For the feature that you're talking about, you would have to have a routine which runs on every step. Inside said routine, you would need to check the tile's behavior byte and dependently set an attribute to the Player's Pokemon. I see what you mean about making poison and steel types immune. I can tell you that all of the things I've mentioned can be done in a routing, though somewhat tediously.

Sadly, this isn't a request thread, and the ASM request thread doesn't take specific requests. Maybe if you ask kindly enough, the amazing person who runs the request thread will make an exception :P
 

pokemontutorialTV

TheGreatest
13
Posts
10
Years
  • Seen Apr 28, 2023
It has nothing to do with the surf-modification, i need the special modifikation, but i dont know how to do this. The other asm-routines to poison the pokemon, are already inside my hack. But the problem is, also Pokémon of Poision an d Steel Types can be poisioned, and i dont want that.
 

Blah

Free supporter
1,924
Posts
11
Years
It has nothing to do with the surf-modification, i need the special modifikation, but i dont know how to do this. The other asm-routines to poison the pokemon, are already inside my hack. But the problem is, also Pokémon of Poision an d Steel Types can be poisioned, and i dont want that.

I see, I would argue that it's easier to modify your Pokemon poisoning routine to not poison if the Pokemon is steel or poison type, rather than modifying this special.

Here's an ASM request thread where you can ask a kind soul to help you with your implementation:
http://www.pokecommunity.com/showthread.php?t=339153
 

pokemontutorialTV

TheGreatest
13
Posts
10
Years
  • Seen Apr 28, 2023
This isnt as easy as it seems, because it en- and decrpts all 100 bytes of Pokémondata in one Routine. Sadly the type isnt part of this structure...
 
Status
Not open for further replies.
Back
Top