diff options
-rw-r--r-- | Infinite-TM-usage.md | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/Infinite-TM-usage.md b/Infinite-TM-usage.md index 11f2a1a..9ec7aa4 100644 --- a/Infinite-TM-usage.md +++ b/Infinite-TM-usage.md @@ -5,6 +5,7 @@ This tutorial will make all TMs infinitely reusable, unholdable by Pokemon, unse ## Contents 1. [Don't consume TMs on use](#1-dont-consumes-tms-on-use) 2. [Treat TMs as HMs in the bag](#2-treat-tms-as-hms-in-the-bag) +3. [Don't allow TM selling and rebuying](#3-dont-allow-tm-selling-and-rebuying) ## 1. Don't consume TMs on use Normally, the game checks if the item used was a TM or an HM, and consumes the item if it was a TM. We can just simply remove this check. @@ -52,9 +53,64 @@ Edit [src/data/items.h](../blob/master/src/data/items.h): ``` You will need to repeat the above for every TM. +But there is still an issue: TMs can still be sold. This will be addressed in the next step. + +## 3. Don't allow TM selling and rebuying + +If you were to see what determines if an item can be sold, you will find that any item with a price of 0 cannot be sold. So it's as simple as setting the TM prices to 0, right? Wrong. Setting the item price to 0 also means that the buying price will also be 0! + +In order to avoid this, we will need to modify the logic that checks for whether an item can be sold. All we need to do is check if the item ID is a TM. Edit the `Task_ItemContext_Sell` function of [src/item_menu.c](../blob/master/src/item_menu.c): +```diff +- if (ItemId_GetPrice(gSpecialVar_ItemId) == 0) ++ if (ItemId_GetPrice(gSpecialVar_ItemId) == 0) + { + CopyItemName(gSpecialVar_ItemId, gStringVar2); + StringExpandPlaceholders(gStringVar4, gText_CantBuyKeyItem); + DisplayItemMessage(taskId, 1, gStringVar4, BagMenu_InitListsMenu); + } +``` +The last issue to take care of is that TMs that the player already has can be bought again for no effect. This step is technically optional, but it is nice to have that bit of polish. + +We will first need to add a new string. Edit [include/strings.h](../blob/master/include/strings.h): +```diff + extern const u8 gText_InBagVar1[]; + extern const u8 gText_Var1AndYouWantedVar2[]; + extern const u8 gText_HereYouGoThankYou[]; + extern const u8 gText_NoMoreRoomForThis[]; ++extern const u8 gText_YouAlreadyHaveThis[]; + extern const u8 gText_ThankYouIllSendItHome[]; + extern const u8 gText_ThanksIllSendItHome[]; + extern const u8 gText_SpaceForVar1Full[]; + extern const u8 gText_ThrowInPremierBall[]; +``` +Edit [src/strings.c](..blob/master/src/strings.c): +```diff + const u8 gText_ThanksIllSendItHome[] = _("Thanks!\nI'll send it to your PC at home."); + const u8 gText_YouDontHaveMoney[] = _("You don't have enough money.{PAUSE_UNTIL_PRESS}"); + const u8 gText_NoMoreRoomForThis[] = _("You have no more room for this\nitem.{PAUSE_UNTIL_PRESS}"); ++const u8 gText_YouAlreadyHaveThis[] = _("You already have this item.{PAUSE_UNTIL_PRESS}"); + const u8 gText_SpaceForVar1Full[] = _("The space for {STR_VAR_1} is full.{PAUSE_UNTIL_PRESS}"); + const u8 gText_AnythingElseICanHelp[] = _("Is there anything else I can help\nyou with?"); + const u8 gText_CanIHelpWithAnythingElse[] = _("Can I help you with anything else?"); +``` +Now to add the code that prevents the rebuying. Edit the `Task_BuyMenu` function of [src/shop.c](../blob/master/src/shop.c): +```diff + if (!IsEnoughMoney(&gSaveBlock1Ptr->money, gShopDataPtr->totalCost)) + { + BuyMenuDisplayMessage(taskId, gText_YouDontHaveMoney, BuyMenuReturnToItemList); + } ++ else if (ItemId_GetPocket(itemId) == POCKET_TM_HM && CheckBagHasItem(itemId, 1)) ++ { ++ BuyMenuDisplayMessage(taskId, gText_YouAlreadyHaveThis, BuyMenuReturnToItemList); ++ } + else + { +``` And that's it!  + + Notes: Pokemon will replenish their PP if a TM move is forgotten and relearned. |