-
Notifications
You must be signed in to change notification settings - Fork 817
Show move names for TMs and HMs when receiving or buying
In Gen 2, acquiring a TM or HM would just say "PLAYER received TM##." when you're given one, or "PLAYER found TM##!" when you take an item ball or hidden item. Gen 3 made these messages more helpful by showing the name of the move that the TM/HM teaches. This tutorial will implement that little quality of life feature.
- Define a routine to append move names after TM/HM item names
- Use the new routine in all cases where you acquire an item
- Update the hard-coded TM13 and TM24 messages
- Define a new routine to show move names when buying TMs
Edit engine/overworld/scripting.asm:
+AppendTMHMMoveName::
+; a = item ID
+ ld a, [wNamedObjectIndex]
+ cp TM01
+ ret c
+; save item name buffer
+ push de
+; a = TM/HM number
+ ld c, a
+ farcall GetTMHMNumber
+ ld a, c
+; a = move ID
+ ld [wTempTMHM], a
+ predef GetTMHMMove
+ ld a, [wTempTMHM]
+; wStringBuffer1 = move name
+ ld [wNamedObjectIndex], a
+ call GetMoveName
+; hl = item name buffer
+ pop hl
+; append wStringBuffer1 to item name buffer
+ ld [hl], " "
+ inc hl
+ ld de, wStringBuffer1
+ jp CopyName2
This routine assumes that you've loaded the item ID in [wNamedObjectIndex]
, and the end of the item name buffer in de
. Then it converts the item ID to the corresponding TM/HM number, then converts that to the corresponding move ID, gets the name of the move, and appends that to the item name buffer (which is why we started with the end of the buffer).
(The move name is written to wStringBuffer1
, so you can't also use that for the TM/HM name. You'd end up with issues like TM01 being called "DYNADYNAMICPUNCH".)
Edit engine/overworld/scripting.asm again:
Script_verbosegiveitem:
; script command 0x9e
; parameters: item, quantity
call Script_giveitem
call CurItemName
ld de, wStringBuffer1
ld a, STRING_BUFFER_4
call CopyConvertedText
+ ld de, wStringBuffer4 + STRLEN("TM##")
+ call AppendTMHMMoveName
ld b, BANK(GiveItemScript)
ld de, GiveItemScript
jp ScriptCall
Script_verbosegiveitemvar:
; script command 0x9f
; parameters: item, var
call GetScriptByte
cp ITEM_FROM_MEM
jr nz, .ok
ld a, [wScriptVar]
.ok
ld [wCurItem], a
call GetScriptByte
call GetVarAction
ld a, [de]
ld [wItemQuantityChange], a
ld hl, wNumItems
call ReceiveItem
ld a, TRUE
jr c, .ok2
xor a
.ok2
ld [wScriptVar], a
call CurItemName
ld de, wStringBuffer1
ld a, STRING_BUFFER_4
call CopyConvertedText
+ ld de, wStringBuffer4 + STRLEN("TM##")
+ call AppendTMHMMoveName
ld b, BANK(GiveItemScript)
ld de, GiveItemScript
jp ScriptCall
Edit engine/events/misc_scripts.asm:
FindItemInBallScript::
callasm .TryReceiveItem
...
.TryReceiveItem:
xor a
ld [wScriptVar], a
ld a, [wItemBallItemID]
ld [wNamedObjectIndex], a
call GetItemName
ld hl, wStringBuffer3
call CopyName2
+ ld de, wStringBuffer3 + STRLEN("TM##")
+ farcall AppendTMHMMoveName
ld a, [wItemBallItemID]
ld [wCurItem], a
ld a, [wItemBallQuantity]
ld [wItemQuantityChange], a
ld hl, wNumItems
call ReceiveItem
ret nc
ld a, $1
ld [wScriptVar], a
ret
Edit engine/events/hidden_item.asm:
HiddenItemScript::
opentext
readmem wHiddenItemID
getitemname STRING_BUFFER_3, USE_SCRIPT_VAR
+ callasm .append_tmhm_move_name
writetext .found_text
giveitem ITEM_FROM_MEM
iffalse .bag_full
callasm SetMemEvent
specialsound
itemnotify
sjump .finish
.bag_full
buttonsound
writetext .no_room_text
waitbutton
.finish
closetext
end
+
+.append_tmhm_move_name
+ ld de, wStringBuffer3 + STRLEN("TM##")
+ farcall AppendTMHMMoveName
+ ret
Edit maps/Route39Farmhouse.asm:
Text_ReceivedTM13:
text "<PLAYER> received"
- line "TM13."
+ line "TM13 SNORE."
done
Edit maps/BlackthornGym1F.asm:
BlackthornGymText_ReceivedTM24:
text "<PLAYER> received"
- line "TM24."
+ line "TM24 DRAGONBREATH."
done
And edit maps/DragonsDenB1F.asm:
Text_ReceivedTM24:
text "<PLAYER> received"
- line "TM24."
+ line "TM24 DRAGONBREATH."
done
Now we'll see the move name along with the TM/HM number when it's first acquired.
Edit engine/menus/menu_2.asm:
call PlaceString
ret
+PlaceMartMenuItemName:
+ push de
+ ld a, [wMenuSelection]
+ ld [wNamedObjectIndex], a
+ call GetItemName
+ cp TM01
+ jr c, .place_string
+ ld hl, wStringBuffer1
+ ld de, wStringBuffer4
+ ld bc, STRING_BUFFER_LENGTH
+ call CopyBytes
+ ld de, wStringBuffer4 + STRLEN("TM##")
+ callfar AppendTMHMMoveName
+ ld de, wStringBuffer4
+.place_string:
+ pop hl
+ call PlaceString
+ ret
+
PlaceMenuItemQuantity:
push de
ld a, [wMenuSelection]
This routine applies the same exact logic as PlaceMenuItemName for non-TM/HM items. For TMs/HMs, however, it calls the previously defined AppendTMHMMoveName method to fetch the move name and add it to the TM## name the mart usually shows. Now that we have this method, we need to reference it when defining Mart menus.
Edit engine/items/mart.asm:
db 4, 8 ; rows, columns
db SCROLLINGMENU_ITEMS_NORMAL ; item format
dbw 0, wCurMartCount
- dba PlaceMenuItemName
+ dba PlaceMartMenuItemName
dba .PrintBCDPrices
dba UpdateItemDescription
In case you're wondering why we didn't just edit the existing PlaceMenuItemName function, it's because that function is used in the PC to draw item names, and the PC doesn't have enough room to write out move names in the same manner we've done here.
Now your Marts should show the names of moves!