Starting in B2/W2, when a Repel, Super Repel, or Max Repel expires and you have another one of the same type, the "Repel's effect wore off…" message will be followed by the option to use another. Implementing this feature in Gen 2 is relatively simple, but unlike "adding a new X by editing constants/X_constants.asm and data/X/\*.asm", it involves a variety of different files, including asm, RAM, event scripts, and text. ## Contents 1. [Add space in WRAM and SRAM for the type of Repel used](#1-add-space-in-wram-and-sram-for-the-type-of-repel-used) 2. [Store the type when a Repel is used](#2-store-the-type-when-a-repel-is-used) 3. [Check if you have more of the last-used type when one wears off](#3-check-if-you-have-more-of-the-last-used-type-when-one-wears-off) 4. [Ask whether to use another Repel, and do so, if applicable](#4-ask-whether-to-use-another-repel-and-do-so-if-applicable) 5. [Define the "Use another?" message](#5-define-the-use-another-message) ## 1. Add space in WRAM and SRAM for the type of Repel used There's already this line in [wram.asm](../blob/master/wram.asm): ```asm wRepelEffect:: db ; If a Repel is in use, it contains the nr of steps it's still active ``` It's between the `wPlayerData` and `wPlayerDataEnd` labels. That means it's part of the saved data, so resetting the game will still remember how many Repel steps you have left. We need to add a `wRepelType` byte that works the same way. It's just one byte since it stores the item ID. There's free space nearby, so let's use that: ```diff wLuckyNumberShowFlag:: db ; dc9d - ds 1 +wRepelType:: db wLuckyIDNumber:: dw ; dc9f wRepelEffect:: db ; If a Repel is in use, it contains the nr of steps it's still active wBikeStep:: dw wKurtApricornQuantity:: db ``` ## 2. Store the type when a Repel is used The file that defines item effects is, predictably, [engine/items/item_effects.asm](../blob/master/engine/items/item_effects.asm). It turns out that Repel, Super Repel, and Max Repel all use the same code, so we don't have to write anything three times. ```diff SuperRepelEffect: ld b, 200 jr UseRepel MaxRepelEffect: ld b, 250 jr UseRepel RepelEffect: ld b, 100 UseRepel: ld a, [wRepelEffect] and a ld hl, TextJump_RepelUsedEarlierIsStillInEffect jp nz, PrintText ld a, b ld [wRepelEffect], a + ld a, [wCurItem] + ld [wRepelType], a jp UseItemText TextJump_RepelUsedEarlierIsStillInEffect: ; The REPEL used earlier is still in effect. text_far Text_RepelUsedEarlierIsStillInEffect text_end ``` ## 3. Check if you have more of the last-used type when one wears off Edit [engine/overworld/events.asm](../blob/master/engine/overworld/events.asm): ```diff DoRepelStep: ld a, [wRepelEffect] and a ret z dec a ld [wRepelEffect], a ret nz + ld a, [wRepelType] + ld [wCurItem], a + ld hl, wNumItems + call CheckItem ld a, BANK(RepelWoreOffScript) ld hl, RepelWoreOffScript + jr nc, .got_script + ld a, BANK(UseAnotherRepelScript) + ld hl, UseAnotherRepelScript +.got_script call CallScript scf ret ``` Note that `UseAnotherRepelScript` hasn't been defined yet, so we'll do that next. ## 4. Ask whether to use another Repel, and do so, if applicable Edit [engine/events/misc_scripts_2.asm](../blob/master/engine/events/misc_scripts_2.asm): ```diff RepelWoreOffScript:: opentext writetext .text waitbutton closetext end .text ; REPEL's effect wore off. text_far _RepelWoreOffText text_end +UseAnotherRepelScript:: + opentext + writetext .text + yesorno + iffalse .done + callasm DoItemEffect +.done + closetext + end + +.text: + text_far _UseAnotherRepelText + text_end ``` Again, we have not yet defined `_UseAnotherRepelText`, so let's finish up with that. ## 5. Define the "Use another?" message Edit [data/text/common_1.asm](../blob/master/data/text/common_1.asm): ```diff _RepelWoreOffText:: text "REPEL's effect" line "wore off." done +_UseAnotherRepelText:: + text "REPEL's effect" + line "wore off." + + para "Use another?" + done ``` Finally, the feature works! ![Screenshot](screenshots/use-another-repel.png)