PDA

View Full Version : Development: More TMs/HMs


ZodiacDaGreat
March 14th, 2010, 11:48 PM
Let's try to implement the way the 4th generation games have more than 50 TMs. Please post your findings here :D On Ruby version, I provide this two routines (Commented roughly so may have mistakes lol - a bit lazy today)


@ Routine 1 - TM data [AXVE]
@ -----------------------------------------------
0806f7b8 b500 push {lr}
0806f7ba 0400 lsl r0, r0, #0x10
0806f7bc 0c02 lsr r2, r0, #0x10
0806f7be 2100 mov r1, #0x0
0806f7c0 4b04 ldr r3, [$0806f7d4] (=$08376504) @ Pointer to TM data
0806f7c2 1c08 add r0, r1, #0x0
0806f7c4 3032 add r0, #0x32 @ 0x32 = 50 (50 TMs)
0806f7c6 0040 lsl r0, r0, #0x01 @ r0 = 0x64
0806f7c8 18c0 add r0, r0, r3 @ r0 becomes pointer to HM data
0806f7ca 8800 ldrh r0, [r0, #0x0]
0806f7cc 4290 cmp r0, r2
0806f7ce d103 bne $0806f7d8
0806f7d0 2001 mov r0, #0x1
0806f7d2 e007 b $0806f7e4

0806f7d4 6504 str r4, [r0, #0x50] @ Pointer bytes
0806f7d6 0837 lsr r7, r6, #0x00

0806f7d8 1c48 add r0, r1, #0x1
0806f7da 0600 lsl r0, r0, #0x18
0806f7dc 0e01 lsr r1, r0, #0x18
0806f7de 2907 cmp r1, #0x7
0806f7e0 d9ef bls $0806f7c2
0806f7e2 2000 mov r0, #0x0
0806f7e4 bc02 pop {r1}
0806f7e6 4708 bx r1

@ Routine 2 - TM/HM Routine [AXVE]
@ -----------------------------------------------
080c9e90 b510 push {r4,lr}
080c9e92 0600 lsl r0, r0, #0x18
080c9e94 0e04 lsr r4, r0, #0x18
080c9e96 2000 mov r0, #0x0
080c9e98 210d mov r1, #0xd
080c9e9a 220d mov r2, #0xd
080c9e9c 2314 mov r3, #0x14
080c9e9e f7a7 bl $08071e84 @ Message Box function?
080c9ea2 4806 ldr r0, [$080c9ebc] (=$0203855e) @ Contains TM/HM data
080c9ea4 8801 ldrh r1, [r0, #0x0] @ Loads TM/HM index number
080c9ea6 20a9 mov r0, #0xa9
080c9ea8 0040 lsl r0, r0, #0x01 @ r0 = 0x152 (TM 50 Index Number)*
080c9eaa 4281 cmp r1, r0
080c9eac d90c bls $080c9ec8 @ if less or equal call TM branch

HM Branch
080c9eae 4904 ldr r1, [$080c9ec0] (=$0840ea16) @ Pointer to HM Message
080c9eb0 4a04 ldr r2, [$080c9ec4] (=$080c9ee5)
080c9eb2 1c20 add r0, r4, #0x0
080c9eb4 2301 mov r3, #0x1
080c9eb6 f02f bl $080f90b8
080c9eba e00b b $080c9ed4
080c9ebc 855e strh r6, [r3, #0x2a]
080c9ebe 0203 lsl r3, r0, #0x08
080c9ec0 ea16 [ ??? ]
080c9ec2 0840 lsr r0, r0, #0x01
080c9ec4 9ee5 ldr r6, [sp, #0x394]
080c9ec6 080c lsr r4, r1, #0x00

TM Branch
080c9ec8 4904 ldr r1, [$080c9edc] (=$0840ea06) @ Pointer to TM Message
080c9eca 4a05 ldr r2, [$080c9ee0] (=$080c9ee5)
080c9ecc 1c20 add r0, r4, #0x0
080c9ece 2301 mov r3, #0x1
080c9ed0 f02f bl $080f90b8
080c9ed4 bc10 pop {r4}
080c9ed6 bc01 pop {r0}
080c9ed8 4700 bx r0


The first routine is the one that calls the TM/HM move data (The moves that it contain) The second routine is the Field Usage routine for TMs/HMs in the Item Structure - all TMs/HMs use this to calculate which TM/HM is which.

Basically what I've done so far
http://i39.tinypic.com/j8jink.png http://i39.tinypic.com/nwyg74.png http://i42.tinypic.com/epkt47.png
http://i40.tinypic.com/70w9he.png

I tried to create more TMs - as you can see in the Item editor image but they turned out to be HMs in the game what's more, its seems like only the first 8 HMs can be used to teach the moves while the other two when used will show that the Pokemon aren't able to learn it like in the image above. To sum it up, the two TMs I made became HMs and the two old HMs got shifted down and cannot be used.

So, I think there are more routines that limit the TM/HM amount and so on. Any thoughts or discoveries? Hehe, I'm a bit lazy this time XD

Gamer2020
March 15th, 2010, 12:08 PM
If I remember correctly there is a place in the ROM where you have to edit which Pokemon learn what TM/HM.
It's similar to the move tutors but longer.
Perhaps that is why the Pokemon won't learn the other moves.

ZodiacDaGreat
March 15th, 2010, 12:25 PM
If I remember correctly there is a place in the ROM where you have to edit which Pokemon learn what TM/HM.
It's similar to the move tutors but longer.
Perhaps that is why the Pokemon won't learn the other moves.
If you read what I typed and see the images, you'll know that most of the HMs are compatible with the Pokemon in the party. So, what you said is out of the question.

Prof. Briar
March 15th, 2010, 01:23 PM
Well, simple logic dictates that something must be declaring the number of TM/HMs. They seem to be stored in the same list, judging by the bleed over. Even so, the combined number doesn't add up to the maximum number of variables (forgive me for stating the obvious, I'm building a foundation for my hypothesis). It would seem from your test that there are two missing factors. One must define the highest numbered object that is a "TM", this being why anything beyond that value is automatically classed as a "HM". I think it likely that the other missing factor must relate to which badge is needed for which HM move to be taught in some way. Since you can only have eight badges, any "extra" HM would have no "badge check" to activate it. I don't know if that helps, and it's only a theory until tested, but it might give you an idea of what to be looking for.

Gamer2020
March 15th, 2010, 01:43 PM
If you read what I typed and see the images, you'll know that most of the HMs are compatible with the Pokemon in the party. So, what you said is out of the question.
"its seems like only the first 8 HMs can be used to teach the moves while the other two when used will show that the Pokemon aren't able to learn it like in"

Maybe I misread.
But still, the area would have to be edited still? To include the new TMs/HMs.

ZodiacDaGreat
March 15th, 2010, 02:25 PM
Well, simple logic dictates that something must be declaring the number of TM/HMs. They seem to be stored in the same list, judging by the bleed over. Even so, the combined number doesn't add up to the maximum number of variables (forgive me for stating the obvious, I'm building a foundation for my hypothesis). It would seem from your test that there are two missing factors. One must define the highest numbered object that is a "TM", this being why anything beyond that value is automatically classed as a "HM". I think it likely that the other missing factor must relate to which badge is needed for which HM move to be taught in some way. Since you can only have eight badges, any "extra" HM would have no "badge check" to activate it. I don't know if that helps, and it's only a theory until tested, but it might give you an idea of what to be looking for.
Exactly. That's the missing routines.

Lance32497
November 30th, 2014, 02:27 AM
can someone port it in Firered?

Lone Knight
November 30th, 2014, 07:21 AM
can someone port it in Firered?

No reason to reply to years old thread. You will not get anything here

Spherical Ice
November 30th, 2014, 08:17 AM
No reason to reply to years old thread. You will not get anything here

Actually, the thread revival rule does not apply here so he is well within his right to post here, as even if the OP isn't here, it's possible that other users may wish to help out. In future just report posts you feel are breaking the rules please.

longlostsoldier
November 30th, 2014, 04:03 PM
I have managed to _sort of_ do something like this; make a fake TM that isn't a TM (it's in misc items). If the goal is just to have more items that teach moves, this does that?

I used the Hacked Engine, and a simple normal item script that teaches you a move. My version has some problems (it teaches only the first pokemon in your party in the first slot a move), since I don't know the special to bring up the party screen and save that slot chosen to a var yet, if that even exists :(
It does not get used up when you use it. I consider that a bonus but people could easily add a deleteitem.
Also, any pokemon can learn, but that can be fixed simply by using special 12b to check pokemon type (by default that special just checks if grass, but there's a hacked version out there by FBI agent I think?), so you could get an item that teaches a move to, say, any water pokemon! You could also, if you just wanted only a few pokemon to learn it specifically, check for them instead.
I tried to use special DC to choose the slot, but it didn't seem to work, so I just use it to let you see the poke after.

here's my example, I hope this is useful (I'm kinda a newbie to hacking):

#dynamic 0x801250
#org @mymove
lock
bufferfirstpokemon 0x2
bufferattack 0x0 0x1
msgbox @teachmove 0x5
compare LASTRESULT 0x1
if 0x0 goto @end
setvar 0x8004 0x0
special 0x6
setvar 0x8006 0x1 '= attack number
setvar 0x8005 0x0 ' = attack slot,
special 0x17 'change poke move
special 0xdc
special 0x6
release
end
#org @end
release
end

#org @teachmove
= Teach [buffer3] [buffer1]?
You don't have to do any table repointing with this method, any hard stuff, just inset in some free space somewhere and change the use-item script pointer for one item. Just remember it goes in Misc. Items not TMs. Any, it seems really pretty nifty and cool- teach a move to a pokemon of a specific type! Although I have yet to actually try that type-specific part (it would be something like special2 0xvar tehtypespecial, compare var, if blah, I think?). It just always seemed a little weird to me there were, say, water type moves all water types couldn't learn.

I know this is kind of a sucky solution, since it isn't a 'real' TM, but I hope it helps someone and I'd like to see it in hacks.

EDIT: okay, I did some testing, here's a version that checks if the pokemon is the right type or not. Much more useful than the first given.
Also, I found it doesn't seem to like new hacked on moves past the originals. But still has potential.
Example:


#dynamic 0x801300
#org @mymove
lock
bufferfirstpokemon 0x2
bufferattack 0x0 0x0AC ' flame wheel
setvar 0x8000 0xA 'fire type.
special2 0x4001 0x12B 'the special, you will have to put in the patched version
compare 0x4001 0x1 'check the slot
if 0x0 goto @can
msgbox @donthave 0x2
release
end

#org @can
msgbox 0x8801286 MSG_YESNO '"Teach [buffer3] [buffer1] in 1st\n..."
msgbox @teachmove 0x5
compare LASTRESULT 0x1
if 0x0 goto @end
setvar 0x8004 0x0
setvar 0x8005 0x0
special 0x6
setvar 0x8006 0x0AC '= attack number
special 0x17 'change poke move
special 0x6
special 0xdc '0x8005 = attack slot
release
end

#org @teachmove
= Teach [buffer3] [buffer1] in 1st slot?

#org @donthave
= Your [buffer3] can't learn\n[buffer1], switch a diff. [PK][MN] to\l1st slot.

FBI agent
December 1st, 2014, 06:18 AM
I have managed to _sort of_ do something like this; make a fake TM that isn't a TM (it's in misc items). If the goal is just to have more items that teach moves, this does that?

I used the Hacked Engine, and a simple normal item script that teaches you a move. My version has some problems (it teaches only the first pokemon in your party in the first slot a move), since I don't know the special to bring up the party screen and save that slot chosen to a var yet, if that even exists :(
It does not get used up when you use it. I consider that a bonus but people could easily add a deleteitem.
Also, any pokemon can learn, but that can be fixed simply by using special 12b to check pokemon type (by default that special just checks if grass, but there's a hacked version out there by FBI agent I think?), so you could get an item that teaches a move to, say, any water pokemon! You could also, if you just wanted only a few pokemon to learn it specifically, check for them instead.
I tried to use special DC to choose the slot, but it didn't seem to work, so I just use it to let you see the poke after.

here's my example, I hope this is useful (I'm kinda a newbie to hacking):

#dynamic 0x801250
#org @mymove
lock
bufferfirstpokemon 0x2
bufferattack 0x0 0x1
msgbox @teachmove 0x5
compare LASTRESULT 0x1
if 0x0 goto @end
setvar 0x8004 0x0
special 0x6
setvar 0x8006 0x1 '= attack number
setvar 0x8005 0x0 ' = attack slot,
special 0x17 'change poke move
special 0xdc
special 0x6
release
end
#org @end
release
end

#org @teachmove
= Teach [buffer3] [buffer1]?
You don't have to do any table repointing with this method, any hard stuff, just inset in some free space somewhere and change the use-item script pointer for one item. Just remember it goes in Misc. Items not TMs. Any, it seems really pretty nifty and cool- teach a move to a pokemon of a specific type! Although I have yet to actually try that type-specific part (it would be something like special2 0xvar tehtypespecial, compare var, if blah, I think?). It just always seemed a little weird to me there were, say, water type moves all water types couldn't learn.

I know this is kind of a sucky solution, since it isn't a 'real' TM, but I hope it helps someone and I'd like to see it in hacks.

EDIT: okay, I did some testing, here's a version that checks if the pokemon is the right type or not. Much more useful than the first given.
Also, I found it doesn't seem to like new hacked on moves past the originals. But still has potential.
Example:


#dynamic 0x801300
#org @mymove
lock
bufferfirstpokemon 0x2
bufferattack 0x0 0x0AC ' flame wheel
setvar 0x8000 0xA 'fire type.
special2 0x4001 0x12B 'the special, you will have to put in the patched version
compare 0x4001 0x1 'check the slot
if 0x0 goto @can
msgbox @donthave 0x2
release
end

#org @can
msgbox 0x8801286 MSG_YESNO '"Teach [buffer3] [buffer1] in 1st\n..."
msgbox @teachmove 0x5
compare LASTRESULT 0x1
if 0x0 goto @end
setvar 0x8004 0x0
setvar 0x8005 0x0
special 0x6
setvar 0x8006 0x0AC '= attack number
special 0x17 'change poke move
special 0x6
special 0xdc '0x8005 = attack slot
release
end

#org @teachmove
= Teach [buffer3] [buffer1] in 1st slot?

#org @donthave
= Your [buffer3] can't learn\n[buffer1], switch a diff. [PK][MN] to\l1st slot.


This is the concept I would go with for "Expanding TMs". Just make another item that goes into the TMs pocket. Great thinking there longlostsoldier. You can change which pocket the item will appear in by modifying the pocket byte which is 0x1A.
As for the code, I would try to search for the TM use routine, and use it as a skeleton for a modified version of it for the new item.

longlostsoldier
December 1st, 2014, 02:57 PM
This is the concept I would go with for "Expanding TMs". Just make another item that goes into the TMs pocket. Great thinking there longlostsoldier. You can change which pocket the item will appear in by modifying the pocket byte which is 0x1A.
As for the code, I would try to search for the TM use routine, and use it as a skeleton for a modified version of it for the new item.

^_^ Yeah, I attempted to put it in TMs, but that caused the script not to work correctly, as it seemed to automatically interpret it as just another TM (Spit Up, in fact, which is odd). I probably should have mentioned that.

Alright, I found another version which doesn't use JPAN's hack, although it only allows for 16 more moves: one can use the Move Tutor special, which, well, acts a lot more like a normal tm as it automatically lets you choose a pokemon and a slot to teach it to.

Special 18D, just setflag 0x8005 to 0-F first to use in a script.

This also seems to cooperate with newer gen moves added to the engine (I used MrDollSteak for testing), so what one could do is add 16 new gen moves, put them in move tutor slots, and then simply use the other version of this to re-add the old move tutor moves and make them available. A pain in the butt, but, it does give 16+ more moves, which is pretty nifty. We've got some actual progress on adding new moves and new move tutoring items!

Edit: Oh yeah, I should mention, to alter the move tutor moves, the moves are two bytes each, starting from 0x459B60, from 0500 (mega punch?) to A400. 16 move tutor moves.
Using MrDollSteaks Decap and Fairy Type patch, I replaced several of them and tested out with these, 'altho I haven't actually tested each one it seems to work fine. One would still have to go in and manually change what pokemon can learn which move of course. Since the hexes for newer moves (especially in two byte form) don't seem to be listed anywhere, I thought I'd give them so other people could quick test too.

dark pulse 6f 01
rock climb 88 01
roost 8b 01
shadow claw 8d 01
xscissor 90 01
venoshock a6 01
dragon tail bc 01
giga impact! 78 01
flash cannon c1 01
dazzle d2 01
77 01 force palm

FBI agent
December 1st, 2014, 03:49 PM
^_^ Yeah, I attempted to put it in TMs, but that caused the script not to work correctly, as it seemed to automatically interpret it as just another TM (Spit Up, in fact, which is odd). I probably should have mentioned that.

Alright, I found another version which doesn't use JPAN's hack, although it only allows for 16 more moves: one can use the Move Tutor special, which, well, acts a lot more like a normal tm as it automatically lets you choose a pokemon and a slot to teach it to.

Special 18D, just setflag 0x8005 to 0-F first to use in a script.

This also seems to cooperate with newer gen moves added to the engine (I used MrDollSteak for testing), so what one could do is add 16 new gen moves, put them in move tutor slots, and then simply use the other version of this to re-add the old move tutor moves and make them available. A pain in the butt, but, it does give 16+ more moves, which is pretty nifty. We've got some actual progress on adding new moves and new move tutoring items!

Edit: Oh yeah, I should mention, to alter the move tutor moves, the moves are two bytes each, starting from 0x459B60, from 0500 (mega punch?) to A400. 16 move tutor moves.
Using MrDollSteaks Decap and Fairy Type patch, I replaced several of them and tested out with these, 'altho I haven't actually tested each one it seems to work fine. One would still have to go in and manually change what pokemon can learn which move of course. Since the hexes for newer moves (especially in two byte form) don't seem to be listed anywhere, I thought I'd give them so other people could quick test too.

dark pulse 6f 01
rock climb 88 01
roost 8b 01
shadow claw 8d 01
xscissor 90 01
venoshock a6 01
dragon tail bc 01
giga impact! 78 01
flash cannon c1 01
dazzle d2 01
77 01 force palm

Very good find. Actually you'll be pleased to know that I looked at the routine for special 0x18D and to my surprise there aren't ANY limiters. Literally none!
The code does a few things to get into the Pokemon selection menu, and checking if the Pokemon can learn the move or not. However, the pointer to the table is loaded directly into R0. Meaning if you can change that pointer you can have theoretically as many move tutor moves as you want!

The pointer to this is at: 0x120BE4

Well that solves the problem of expanding TMs. Good thinking Longlostsoldier!

MrDollSteak
December 1st, 2014, 07:29 PM
Very good find. Actually you'll be pleased to know that I looked at the routine for special 0x18D and to my surprise there aren't ANY limiters. Literally none!
The code does a few things to get into the Pokemon selection menu, and checking if the Pokemon can learn the move or not. However, the pointer to the table is loaded directly into R0. Meaning if you can change that pointer you can have theoretically as many move tutor moves as you want!

The pointer to this is at: 0x120BE4

Well that solves the problem of expanding TMs. Good thinking Longlostsoldier!

Well actually the problem with Move Tutor moves is that the Move Tutor Compatability is stored in a Bitmap, that means that you can only use 15 moves, so there's no need for a limiter as such. To make more moves you need to rewrite the compatibility table to work from a full word as opposed to a halfword.

I think it'd be more valuable to get more TMs by putting them in the bag. Also I think the reason it is so difficult to expand TMs is partially due to the TM compatability. That'll be why the extra two moves get pushed to the end and don't work, because they're now out of the array of the compatibility.

FBI agent
December 1st, 2014, 08:16 PM
Well actually the problem with Move Tutor moves is that the Move Tutor Compatability is stored in a Bitmap, that means that you can only use 15 moves, so there's no need for a limiter as such. To make more moves you need to rewrite the compatibility table to work from a full word as opposed to a halfword.

I think it'd be more valuable to get more TMs by putting them in the bag. Also I think the reason it is so difficult to expand TMs is partially due to the TM compatability. That'll be why the extra two moves get pushed to the end and don't work, because they're now out of the array of the compatibility.

You seem to be right about compatibility. I just tested on something outside and it failed to learn a compatible move. I fear that actual TM move learning is centered around this concept as well.
While you are allowed to have a large amount of moves, anything not supported is considered incompatible.

The only feasible way would be to extend the bit field to a larger size per Pokemon. Which is not something I'm interested in doing anymore :P

Dark Zeta
January 8th, 2015, 07:34 PM
So I was toying around with trying to make new TMs and looking through the tables for TMs and I have successfully made 2 learnable TMs. (Though they have the problem with graphically being loaded as an HM, and being deletable like a TM.)

With the way the game is currently setup, we are able to have up to 64 compatible TM/HMs with the way the compatibility table is setup. The max amount of compatible moves for an individual poke is FF FF FF FF FF FF FF FF.

If all TM/HMs in game are learn-able (Mew) , the value for the table is FF FF FF FF FF FF FF 03. This value will result in 58 compatible moves (the same amount of TM/HM). Every individual F is the equivalent of 4 consecutive moves (i.e. 1-4 is 0F and 1-8 is FF).

This may be well known knowledge already, but I decided to post this any way in hopes that extending the amount of TMs becomes better documented information.

Lost Heart
January 11th, 2015, 12:53 PM
So I was toying around with trying to make new TMs and looking through the tables for TMs and I have successfully made 2 learnable TMs. (Though they have the problem with graphically being loaded as an HM, and being deletable like a TM.)

With the way the game is currently setup, we are able to have up to 64 compatible TM/HMs with the way the compatibility table is setup. The max amount of compatible moves for an individual poke is FF FF FF FF FF FF FF FF.

If all TM/HMs in game are learn-able (Mew) , the value for the table is FF FF FF FF FF FF FF 03. This value will result in 58 compatible moves (the same amount of TM/HM). Every individual F is the equivalent of 4 consecutive moves (i.e. 1-4 is 0F and 1-8 is FF).

This may be well known knowledge already, but I decided to post this any way in hopes that extending the amount of TMs becomes better documented information.

This is because each compatibility entry within the table is 64 bits (8 bytes), with the first 58 bits being used to check for TM/HM compatibility. Each bit determines whether a certain TM works, 0 being not allowed and 1 being allowed (it's a bitmap).

So for TM01, bit 0 determines whether it is learnable, and for HM01, bit 50 determines its compatibility, and so on.

This means that with the data alone, there is theoretically space right now to add 8 more TMs to the table without needing to rewrite how the game reads from the table too much.

Leonhart54
January 11th, 2015, 09:27 PM
very interesting post! keep it up!!!!!

Dark Zeta
January 12th, 2015, 12:50 AM
This is because each compatibility entry within the table is 64 bits (8 bytes), with the first 58 bits being used to check for TM/HM compatibility. Each bit determines whether a certain TM works, 0 being not allowed and 1 being allowed (it's a bitmap).

So for TM01, bit 0 determines whether it is learnable, and for HM01, bit 50 determines its compatibility, and so on.

This means that with the data alone, there is theoretically space right now to add 8 more TMs to the table without needing to rewrite how the game reads from the table too much.

I understand the workings. However, the TM Bag will not allow more than 58 TM/HMs.

Taの境界
January 13th, 2015, 07:17 AM
I understand the workings. However, the TM Bag will not allow more than 58 TM/HMs.

Insert this asm at any place.

.text
.align 2
.thumb
.thumb_func
.global tm_slots_hack

main:
ldr r0, ram
str r0, [r1, #0x18]
mov r0, #0x6C
strb r0, [r1, #0x1c]
ldr r0, return
bx r0

.align
ram: .word 0x0203c000
return: .word 0x08099e74+1



Then goto 99E6A, insert
01 48 00 47 00 00 FF FF FF 08
FF FF FF 08 is the pointer of the asm location+1

You should also apply Jpan's saveblock hack to keep those data saved.
This enable you to have 108 TM&HM in the bag.

Edit: The previous save file will not work if apply this.

Taの境界
January 14th, 2015, 05:08 PM
[S-HIGHLIGHT]Notes: BUG found, so use this at your own risk.[/S-HIGHLIGHT]
Also this is for Fire Red
1.First you need to create new TM, but once you create one, you need to follow it with another one until all are added.
If you don't want to overlap the previous item, item extension should be consider.

To remove the limiter for item extension

0809a8ae = 00 00 00 00
08098998 = your total item number index


Then repoint the item data(3DB028) and image & palette pointer(3D4294) like what you did in pokemon expansion.

2.After that repoint the TM/HM table at 45A80C, it should be 0x74 bytes long.
Then add whatever move you want to have for new TM.

3.Fix the TM move index routine

.text
.align 2
.thumb
.thumb_func
.global TM_index

main:
mov r1, #0xBB @(new first TM item index-1) divide by two, if it is an even number change the bhi to bge
lsl r1, r1, #0x1
cmp r0, r1
bhi newtm

mov r1, #0x90
lsl r1, r1, #0x1
add r1, r1, #0x1
sub r0, r0 ,r1
lsl r0, r0, #0x1
b exit

newtm:
add r1, r1, #0x1
sub r0, r0, r1
lsl r0, r0, #0x1
add r0, r0, #0x74

exit:
ldr r1, tm_table
add r0, r0, r1
ldrh r0, [r0]
bx lr

.align
tm_table: .word 0x08EEEEEE

125A78: 00 49 08 47 FF FF FF 08, FF FF FF 08 = first asm location+1
tm_table is what you repoint at step 2.

4.Fix the No.# things

.text
.align 2
.thumb
.thumb_func
.global tm_name

main:
mov r0, #0xBB @(new first TM item index-1) divide by two, if it is an even number change the bhi to bge
lsl r0, r0, #0x1
cmp r6, r0
bhi new_tm

mov r0, #0xA9
lsl r0, r0, #0x1
cmp r6, r0
bls old_tm

ldr r1, temp
ldr r0, return1
bx r0

new_tm:
ldr r1, text_no
mov r0, r5
bl refresh

ldr r4, ram
ldr r0, value
ldr r1, return3
bx r1

old_tm:
ldr r1, return2
bx r1

refresh:
ldr r2, routine
bx r2

.align
text_no: .word 0x08416226
routine: .word 0x08008DA5
temp: .word 0x08463178
return1: .word 0x08131D65
return2: .word 0x08131DA5
ram: .word 0x02021CD0
value: .word 0xFFFFFEBC
return3: .word 0x08131DB1


131D5A: 01 48 00 47 00 00 FF FF FF 08, FF FF FF 08 = second asm location+1

5.Fix the compatibility

.text
.align 2
.thumb
.thumb_func
.global tm_compact_hack

main:
mov r3, r1
cmp r4, #0x56 @the number of item between last HM and new TM+ 0x3a
bge newtm

check:
cmp r4, #0x1f
bls first_32
cmp r4, #0x3f
bls first_64
cmp r4, #0x5f
bls first_96

after_96:
mov r0, r4
sub r0, #0x60
mov r2, #0x1
lsl r2, r0
ldr r0, table
lsl r1, r1, #0x4
add r0, #0xC

get_offset:
add r1, r1, r0
ldr r0, [r1]
and r0, r2
b exit

newtm:
sub r4, #0x1C @the number of item between last HM and new TM
b check

first_64:
mov r0, r4
sub r0, #0x20
mov r2, #0x1
lsl r2, r0
ldr r0, table
lsl r1, r1, #0x4
add r0, #0x4
b get_offset

first_96:
mov r0, r4
sub r0, #0x40
mov r2, #0x1
lsl r2, r0
ldr r0, table
lsl r1, r1, #0x4
add r0, #0x8
b get_offset

first_32:
mov r1, #0x1
lsl r1, r5
ldr r2, table
lsl r0, r3, #0x4
add r0, r0, r2
ldr r0, [r0]
and r0, r1

exit:
pop {r4-r5}
pop {r1}
bx r1

.align
table: .word 0x08DDDDDD


43C40: 00 48 00 47 FF FF FF 08, FF FF FF 08 = third asm location+1
table refer to your pokemon TM/HM compatibility table


Format:
It works exactly the same as vanilla fire red, but two more line added, so it supports up to 128 TM/HM.
Now each entry cost you 16 bytes, so the old compatibility table is dead.


Example:
If you want to learn TM 11,27,67,98.

Binary:
1-32:00000100000000000000010000000000
33-64:00000000000000000000000000000000
65-96:00000000000000000000010000000000
97-128:00000000000000000000001000000000

Then convert each line into hex,
Hex:[04 00 04 00] [00 00 00 00] [00 00 04 00] [00 00 02 00]



Every works fine but the animation when you forget move to learn new TM(thought it is pointless) will kill the game.
Also the sequence for the new TMs is not right.

Urobolos
January 14th, 2015, 06:01 PM
Is there any way to disable the animation on the overworld for learning TMs?
Also what do you mean by "Also the sequence for the new TMs is not right."?

Taの境界
January 14th, 2015, 09:41 PM
Is there any way to disable the animation on the overworld for learning TMs?
Also what do you mean by "Also the sequence for the new TMs is not right."?

Idk how to disable it, but good new is emerald doesnt have the animation.
The New TM is located between HM08 and TM01 in bag. There must be some routine that will auto arrange it.

Lance32497
January 15th, 2015, 04:52 AM
Can anyone port it in firered?

LCCoolJ95
January 15th, 2015, 05:12 AM
Hey Tara, is that whole little tutorial for Fire Red or for Emerald?

Taの境界
January 15th, 2015, 05:33 AM
Can anyone port it in firered?
Sorry sir, I should mention that is for fire red, so someone should port it in emerald.

Hey Tara, is that whole little tutorial for Fire Red or for Emerald?
Fire Red:)

daniilS
January 15th, 2015, 06:14 AM
[...]
Every works fine but the animation when you forget move to learn new TM(thought it is pointless) will kill the game.
[...]

So it works fine when you're not overwriting an existing move?

Taの境界
January 15th, 2015, 08:15 AM
So it works fine when you're not overwriting an existing move?

Yes, it works fine, without animation at the poke hp bar screen with message box shown: [pokemon] learned [move]!

HidoranBlaze
January 15th, 2015, 11:50 AM
[S-HIGHLIGHT]Notes: BUG found, so use this at your own risk.[/S-HIGHLIGHT]
Also this is for Fire Red
1.First you need to create new TM, but once you create one, you need to follow it with another one until all are added.
If you don't want to overlap the previous item, item extension should be consider.

To remove the limiter for item extension

0809a8ae = 00 00 00 00
08098998 = your total item number index


Then repoint the item data(3DB028) and image & palette pointer(3D4294) like what you did in pokemon expansion.

2.After that repoint the TM/HM table at 45A80C, it should be 0x74 bytes long.
Then add whatever move you want to have for new TM.

3.Fix the TM move index routine

.text
.align 2
.thumb
.thumb_func
.global TM_index

main:
mov r1, #0xBB @(new first TM item index-1) divide by two, if it is an even number change the bhi to bge
lsl r1, r1, #0x1
cmp r0, r1
bhi newtm

mov r1, #0x90
lsl r1, r1, #0x1
add r1, r1, #0x1
sub r0, r0 ,r1
lsl r0, r0, #0x1
b exit

newtm:
add r1, r1, #0x1
sub r0, r0, r1
lsl r0, r0, #0x1
add r0, r0, #0x74

exit:
ldr r1, tm_table
add r0, r0, r1
ldrh r0, [r0]
bx lr

.align
tm_table: .word 0x08EEEEEE

125A78: 00 49 08 47 FF FF FF 08, FF FF FF 08 = first asm location+1
tm_table is what you repoint at step 2.

4.Fix the No.# things

.text
.align 2
.thumb
.thumb_func
.global tm_name

main:
mov r0, #0xBB @(new first TM item index-1) divide by two, if it is an even number change the bhi to bge
lsl r0, r0, #0x1
cmp r6, r0
bhi new_tm

mov r0, #0xA9
lsl r0, r0, #0x1
cmp r6, r0
bls old_tm

ldr r1, temp
ldr r0, return1
bx r0

new_tm:
ldr r1, text_no
mov r0, r5
bl refresh

ldr r4, ram
ldr r0, value
ldr r1, return3
bx r1

old_tm:
ldr r1, return2
bx r1

refresh:
ldr r2, routine
bx r2

.align
text_no: .word 0x08416226
routine: .word 0x08008DA5
temp: .word 0x08463178
return1: .word 0x08131D65
return2: .word 0x08131DA5
ram: .word 0x02021CD0
value: .word 0xFFFFFEBC
return3: .word 0x08131DB1


131D5A: 01 48 00 47 00 00 FF FF FF 08, FF FF FF 08 = second asm location+1

5.Fix the compatibility

.text
.align 2
.thumb
.thumb_func
.global tm_compact_hack

main:
mov r3, r1
cmp r4, #0x56 @the number of item between last HM and new TM+ 0x3a
bge newtm

check:
cmp r4, #0x1f
bls first_32
cmp r4, #0x3f
bls first_64
cmp r4, #0x5f
bls first_96

after_96:
mov r0, r4
sub r0, #0x60
mov r2, #0x1
lsl r2, r0
ldr r0, table
lsl r1, r1, #0x4
add r0, #0xC

get_offset:
add r1, r1, r0
ldr r0, [r1]
and r0, r2
b exit

newtm:
sub r4, #0x1C @the number of item between last HM and new TM
b check

first_64:
mov r0, r4
sub r0, #0x20
mov r2, #0x1
lsl r2, r0
ldr r0, table
lsl r1, r1, #0x4
add r0, #0x4
b get_offset

first_96:
mov r0, r4
sub r0, #0x40
mov r2, #0x1
lsl r2, r0
ldr r0, table
lsl r1, r1, #0x4
add r0, #0x8
b get_offset

first_32:
mov r1, #0x1
lsl r1, r5
ldr r2, table
lsl r0, r3, #0x4
add r0, r0, r2
ldr r0, [r0]
and r0, r1

exit:
pop {r4-r5}
pop {r1}
bx r1

.align
table: .word 0x08DDDDDD


43C40: 00 48 00 47 FF FF FF 08, FF FF FF 08 = third asm location+1
table refer to your pokemon TM/HM compatibility table


Format:
It works exactly the same as vanilla fire red, but two more line added, so it supports up to 128 TM/HM.
Now each entry cost you 16 bytes, so the old compatibility table is dead.


Example:
If you want to learn TM 11,27,67,98.

Binary:
1-32:00000100000000000000010000000000
33-64:00000000000000000000000000000000
65-96:00000000000000000000010000000000
97-128:00000000000000000000001000000000

Then convert each line into hex,
Hex:[04 00 04 00] [00 00 00 00] [00 00 04 00] [00 00 02 00]



Every works fine but the animation when you forget move to learn new TM(thought it is pointless) will kill the game.
Also the sequence for the new TMs is not right. Nice work! I was actually working on TM expansion as well, but gave up due to lack of motivation and graphics bugs, so I'm glad someone decided to step up to the plate! I'll see what I can do about porting this to EM, but it'll probably take a while, since I have school and other fun stuff.

Taの境界
January 17th, 2015, 01:11 AM
Put 00 00 at 0x11CE6E will stop the animation to learn TM directly in fire red, instead of pushing b button.
Then put 00 F0 0E FA at 0x11CA2C to skip the whole set of animation directly.^^

Edit: Both must be done to disable it.

Lance32497
January 17th, 2015, 02:03 AM
Put 00 00 at 0x11CE6E will stop the animation to learn TM directly in fire red, instead of pushing b button.
Then put 00 F0 0E FA at 0x11CA2C to skip the whole set of animation directly.^^

Edit: Both must be done to disable it.

I hope Karatekid will add Expansion of TM function in his G3HS tool :v *hey! I'm so lazy!*

Taの境界
January 17th, 2015, 02:35 AM
I probably miss something out , this animation come out very randomly, fortunately not an issue:).
74186

Also when you use the old TM without overwrite a move, it will show something like this if you apply what I said in previous post.
74187
It ends very quickly, not a big issue, but I will take some time to fix it.
Edit: Put 00 00 00 00 00 00 00 00 00 00 00 00 44 E0 at 0x11CD9E to fix this.

AkimotoBubble
February 8th, 2015, 07:50 AM
I probably miss something out , this animation come out very randomly, fortunately not an issue:).
74186

Also when you use the old TM without overwrite a move, it will show something like this if you apply what I said in previous post.
74187
It ends very quickly, not a big issue, but I will take some time to fix it.
Edit: Put 00 00 00 00 00 00 00 00 00 00 00 00 44 E0 at 0x11CD9E to fix this.

This is nice,And if then put on Emerald what is code?

Dragonflye
July 7th, 2015, 06:11 PM
I have another problem, which I do not get solved.

I have expanded the items on 512. And my TMs have the same so made that direct the 128 piece all in consecutive order. But the problem is that the ASM hack is controlled so that it "skips" some areas. There are therefore only HMs from 60-117 displayed or so. In addition, no three-digit numbers are displayed.

I would be glad if you would help me or at least would document the ASM hack because there looks frankly no one through.

Otherwise, thank you for your trouble. http://ipv6.pokecommunity.com/images/templates/smilies/cerulean/11.%20wink.gif

Criminon
July 7th, 2015, 06:32 PM
I have another problem, which I do not get solved.

I have expanded the items on 512. And my TMs have the same so made that direct the 128 piece all in consecutive order. But the problem is that the ASM hack is controlled so that it "skips" some areas. There are therefore only HMs from 60-117 displayed or so. In addition, no three-digit numbers are displayed.

I would be glad if you would help me or at least would document the ASM hack because there looks frankly no one through.

Otherwise, thank you for your trouble. http://ipv6.pokecommunity.com/images/templates/smilies/cerulean/11.%20wink.gif

You might want to quote his post or private message him if you really want him to respond.