diff options
-rw-r--r-- | Automatically-reuse-Repel.md | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/Automatically-reuse-Repel.md b/Automatically-reuse-Repel.md new file mode 100644 index 0000000..43d9846 --- /dev/null +++ b/Automatically-reuse-Repel.md @@ -0,0 +1,161 @@ +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 does involve a number of different areas: + +- WRAM and SRAM need space to save the type of Repel +- The Repel item effect needs to save its type +- The script that notifies when a Repel wears off needs to check if you have another one and let you choose to reuse it +- There needs to be an alternative notification message including the "Use another?" question text + + +## 1. Add space in RAM for `wRepelType` + +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 `wRepelType` when a Repel is used + +The file that defines item effects is, predictably, [engine/item_effects.asm](../blob/master/engine/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 +SuperRepel: ; f462 + ld b, 200 + jr UseRepel +; f466 + +MaxRepel: ; f466 + ld b, 250 + jr UseRepel +; f466 + +Repel: ; f46a + ld b, 100 +; f46c + +UseRepel: ; f46c + ld a, [wRepelEffect] + and a + ld hl, TextJump_RepelUsedEarlierIsStillInEffect + jp nz, PrintText + + ld a, b + ld [wRepelEffect], a ++ ld a, [CurItem] ++ ld [wRepelType], a + jp UseItemText + + +TextJump_RepelUsedEarlierIsStillInEffect: ; 0xf47d + ; The REPEL used earlier is still in effect. + text_jump Text_RepelUsedEarlierIsStillInEffect + db "@" +; 0xf482 +``` + + +## 3. Ask whether to reuse Repel + +Edit [engine/events.asm](../blob/master/engine/events.asm): + +```diff +DoRepelStep: ; 96bd7 + ld a, [wRepelEffect] + and a + ret z + + dec a + ld [wRepelEffect], a + ret nz + ++ ld a, [wRepelType] ++ ld [CurItem], a ++ ld hl, NumItems ++ call CheckItem + ld a, BANK(RepelWoreOffScript) + ld hl, RepelWoreOffScript + jr nc, .okay ++ ld a, BANK(UseAnotherRepelScript) ++ ld hl, UseAnotherRepelScript ++.okay + call CallScript + scf + ret +; 96beb +``` + +Note that `UseAnotherRepelScript` hasn't been defined yet, so we'll do that next. + + +## 4. Define `UseAnotherRepelScript` + +Edit [engine/events/misc_scripts_2.asm](../blob/master/engine/events/misc_scripts_2.asm): + +```diff +RepelWoreOffScript:: ; 0x13619 + opentext + writetext .text + waitbutton + closetext + end + +.text ; 0x13620 + ; REPEL's effect wore off. + text_jump UnknownText_0x1bd308 + db "@" + ++UseAnotherRepelScript:: ++ opentext ++ writetext .text ++ yesorno ++ iffalse .done ++ callasm DoItemEffect ++.done ++ closetext ++ end ++ ++.text: ++ text_jump UseAnotherRepelText ++ db "@" +``` + +Again, we have not yet defined `UseAnotherRepelText`, so let's finish up with that. + + +## 5. Define `UseAnotherRepelText` + +Edit [data/text/common_1.asm](../blob/master/data/text/common_1.asm): + +```diff +UnknownText_0x1bd308:: + text "REPEL's effect" + line "wore off." + done + ++UseAnotherRepelText:: ++ text "REPEL's effect" ++ line "wore off." ++ ++ para "Use another?" ++ done +``` + +Finally, the feature works! |