This tutorial is for how to add a new Poké Mart. As an example, we'll add an evolution stone merchant to Goldenrod Dept. Store. ## Contents 1. [Define a mart constant](#1-define-a-mart-constant) 2. [Give it an inventory](#2-give-it-an-inventory) 3. [Use it in a map script](#3-use-it-in-a-map-script) 4. [Add a new type of Mart](#4-add-a-new-type-of-mart) 5. [Sell more than 10 items per Mart](#5-sell-more-than-10-items-per-mart) ## 1. Define a mart constant Edit [constants/mart_constants.asm](../blob/master/constants/mart_constants.asm) (or [constants/item_data_constants.asm](../blob/master/constants/item_data_constants.asm) in older versions of pokecrystal): ```diff ; Marts indexes (see data/items/marts.asm) const_def const MART_CHERRYGROVE const MART_CHERRYGROVE_DEX const MART_VIOLET const MART_AZALEA const MART_CIANWOOD const MART_GOLDENROD_2F_1 const MART_GOLDENROD_2F_2 const MART_GOLDENROD_3F + const MART_GOLDENROD_3F_2 const MART_GOLDENROD_4F const MART_GOLDENROD_5F_1 const MART_GOLDENROD_5F_2 const MART_GOLDENROD_5F_3 const MART_GOLDENROD_5F_4 ... ``` ## 2. Give it an inventory Edit [data/items/marts.asm](../blob/master/data/items/marts.asm): ```diff Marts: ; entries correspond to MART_* constants dw MartCherrygrove dw MartCherrygroveDex dw MartViolet dw MartAzalea dw MartCianwood dw MartGoldenrod2F1 dw MartGoldenrod2F2 dw MartGoldenrod3F + dw MartGoldenrod3F2 dw MartGoldenrod4F dw MartGoldenrod5F1 dw MartGoldenrod5F2 dw MartGoldenrod5F3 dw MartGoldenrod5F4 ... .End ... MartGoldenrod3F: db 7 ; # items db X_SPEED db X_SPECIAL db X_DEFEND db X_ATTACK db DIRE_HIT db GUARD_SPEC db X_ACCURACY db -1 ; end + +MartGoldenrod3F2: + db 6 ; # items + db FIRE_STONE + db THUNDERSTONE + db WATER_STONE + db LEAF_STONE + db MOON_STONE + db SUN_STONE + db -1 ; end ``` A Mart can sell up to 10 items. ## 3. Use it in a map script The core idea here is to use the `pokemart` script command, passing it a mart type and the new `MART_GOLDENROD_3F_2` inventory constant. Edit [maps/GoldenrodDeptStore3F.asm](../blob/master/maps/GoldenrodDeptStore3F.asm): ```diff object_const_def const GOLDENRODDEPTSTORE3F_CLERK + const GOLDENRODDEPTSTORE3F_CLERK2 const GOLDENRODDEPTSTORE3F_SUPER_NERD const GOLDENRODDEPTSTORE3F_ROCKER ... GoldenrodDeptStore3FClerkScript: faceplayer opentext pokemart MARTTYPE_STANDARD, MART_GOLDENROD_3F closetext end + +GoldenrodDeptStore3FClerk2Script: + faceplayer + opentext + pokemart MARTTYPE_STANDARD, MART_GOLDENROD_3F_2 + closetext + end ... def_object_events object_event 6, 1, SPRITE_CLERK, SPRITEMOVEDATA_STANDING_DOWN, 0, 0, -1, -1, 0, OBJECTTYPE_SCRIPT, 0, GoldenrodDeptStore3FClerkScript, -1 + object_event 7, 1, SPRITE_CLERK, SPRITEMOVEDATA_STANDING_DOWN, 0, 0, -1, -1, 0, OBJECTTYPE_SCRIPT, 0, GoldenrodDeptStore3FClerk2Script, -1 object_event 12, 5, SPRITE_SUPER_NERD, SPRITEMOVEDATA_SPINRANDOM_FAST, 0, 1, -1, -1, PAL_NPC_RED, OBJECTTYPE_SCRIPT, 0, GoldenrodDeptStore3FSuperNerdScript, -1 object_event 2, 5, SPRITE_ROCKER, SPRITEMOVEDATA_WALK_UP_DOWN, 0, 1, -1, -1, 0, OBJECTTYPE_SCRIPT, 0, GoldenrodDeptStore3FRockerScript, -1 ``` That's it! ![Screenshot](screenshots/evo-stone-mart.png) ## 4. Add a new type of Mart We used `MARTTYPE_STANDARD` before because that's what typical Mart clerks use. But there are other types: - `MARTTYPE_BITTER`: Uses unique phrases for the bitter herb merchant in Goldenrod Underground. - `MARTTYPE_PHARMACY`: Uses unique phrases for the pharmacist in Cianwood City. - `MARTTYPE_BARGAIN`: Has a special inventory and behavior for the bargain merchant in Goldenrod Underground. (Items are half-price but only sells one of each; see [data/items/bargain_shop.asm](../blob/master/data/items/bargain_shop.asm).) - `MARTTYPE_ROOFTOP`: Has a special inventory and behavior for the rooftop sale merchant in Goldenrod Dept. Store. (Items are low-price; see [data/items/rooftop_sale.asm](../blob/master/data/items/rooftop_sale.asm).) Adding custom behavior like `MARTTYPE_BARGAIN` or `MARTTYPE_ROOFTOP` is beyond the scope of this tutorial, but it isn't hard to add a type that just has different phrases. We'll add a "shady" mart that sells suspicious items. Edit [constants/mart_constants.asm](../blob/master/constants/mart_constants.asm): ```diff ; mart types (see engine/items/mart.asm) const_def const MARTTYPE_STANDARD const MARTTYPE_BITTER const MARTTYPE_BARGAIN const MARTTYPE_PHARMACY const MARTTYPE_ROOFTOP + const MARTTYPE_SHADY ``` Edit [engine/items/mart.asm](../blob/master/engine/items/mart.asm): ```diff OpenMartDialog:: ... .dialogs dw MartDialog dw HerbShop dw BargainShop dw Pharmacist dw RooftopSale + dw ShadyShop ... Pharmacist: call FarReadMart call LoadStandardMenuHeader ld hl, Text_Pharmacist_Intro call MartTextbox call BuyMenu ld hl, Text_Pharmacist_ComeAgain call MartTextbox ret + +ShadyShop: + call FarReadMart + call LoadStandardMenuHeader + ld hl, Text_ShadyShop_Intro + call MartTextbox + call BuyMenu + ld hl, Text_ShadyShop_ComeAgain + jp MartTextbox ... GetMartDialogGroup: ... .MartTextFunctionPointers: dwb .StandardMartPointers, 0 dwb .HerbShopPointers, 0 dwb .BargainShopPointers, 1 dwb .PharmacyPointers, 0 dwb .StandardMartPointers, 2 + dwb .ShadyPointers, 0 ... .PharmacyPointers: dw Text_Pharmacy_HowMany dw Text_Pharmacy_CostsThisMuch dw Text_Pharmacy_InsufficientFunds dw Text_Pharmacy_BagFull dw Text_Pharmacy_HereYouGo dw BuyMenuLoop + +.ShadyPointers: + dw Text_ShadyShop_HowMany + dw Text_ShadyShop_CostsThisMuch + dw Text_ShadyShop_InsufficientFunds + dw Text_ShadyShop_BagFull + dw Text_ShadyShop_HereYouGo + dw BuyMenuLoop ... + +Text_ShadyShop_Intro: + text_far ShadyShop_IntroText + text_end + +Text_ShadyShop_ComeAgain: + text_far ShadyShop_ComeAgainText + text_end + +Text_ShadyShop_HowMany: + text_far ShadyShop_HowManyText + text_end + +Text_ShadyShop_CostsThisMuch: + text_far ShadyShop_CostsThisMuchText + text_end + +Text_ShadyShop_InsufficientFunds: + text_far ShadyShop_InsufficientFundsText + text_end + +Text_ShadyShop_BagFull: + text_far ShadyShop_BagFullText + text_end + +Text_ShadyShop_HereYouGo: + text_far ShadyShop_HereYouGoText + text_end ``` And edit [data/text/common_3.asm](../blob/master/data/text/common_3.asm): ```diff +ShadyShop_IntroText:: + text "Hello, kiddo!" + + para "Wanna buy any of" + line "my goods?" + + para "They fell off the" + line "back of a truck!" + cont "Hehehe…" + done + +ShadyShop_ComeAgainText:: + text "See ya, kid!" + done + +ShadyShop_HowManyText:: + text "How many you" + line "need?" + done + +ShadyShop_CostsThisMuchText:: + text "That'll cost ya" + line "¥@" + text_decimal hMoneyTemp, 3, 6 + text ". 'Kay?" + done + +ShadyShop_InsufficientFundsText:: + text "That ain't enough!" + done + +ShadyShop_BagFullText:: + text "Hehe, you can't" + line "carry it!" + done + +ShadyShop_HereYouGoText:: + text "Cha-ching!" + done ``` This new Mart type is appropriate for the Team Rocket merchant in Mahogany Town. So edit [maps/MahoganyMart1F.asm](../blob/master/maps/MahoganyMart1F.asm): ```diff MahogayMart1FPharmacistScript: faceplayer opentext checkevent EVENT_DECIDED_TO_HELP_LANCE iftrue .LanceEntered - pokemart MARTTYPE_STANDARD, MART_MAHOGANY_1 + pokemart MARTTYPE_SHADY, MART_MAHOGANY_1 closetext end ``` And it works! ![Screenshot](screenshots/marttype_shady.png) ## 5. Sell more than 10 items per Mart This is a simple improvement. Edit [wram.asm](../blob/master/wram.asm): ```diff SECTION UNION "Miscellaneous WRAM 1", WRAMX ; mart items wMartItem1BCD:: ds 3 wMartItem2BCD:: ds 3 wMartItem3BCD:: ds 3 wMartItem4BCD:: ds 3 wMartItem5BCD:: ds 3 wMartItem6BCD:: ds 3 wMartItem7BCD:: ds 3 wMartItem8BCD:: ds 3 wMartItem9BCD:: ds 3 wMartItem10BCD:: ds 3 +wMartItem11BCD:: ds 3 +wMartItem12BCD:: ds 3 +wMartItem13BCD:: ds 3 +wMartItem14BCD:: ds 3 +wMartItem15BCD:: ds 3 +wMartItem16BCD:: ds 3 +wMartItem17BCD:: ds 3 +wMartItem18BCD:: ds 3 +wMartItem19BCD:: ds 3 +wMartItem20BCD:: ds 3 ... UNION ; mart data wCurMartCount:: db -wCurMartItems:: ds 15 +wCurMartItems:: ds 21 ``` `wCurMartItems` stores the inventory from [data/items/marts.asm](../blob/master/data/items/marts.asm), including the count and the ending −1. So with 21 bytes, a Mart can sell 20 items. Then there just has to be enough space to store 20 prices.