diff options
Diffstat (limited to 'Automatically-reuse-Repel.md')
-rw-r--r-- | Automatically-reuse-Repel.md | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/Automatically-reuse-Repel.md b/Automatically-reuse-Repel.md new file mode 100644 index 0000000..456b2f2 --- /dev/null +++ b/Automatically-reuse-Repel.md @@ -0,0 +1,164 @@ +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 of the same type, and do so, if applicable + +Edit [engine/events/repel.asm](../blob/master/engine/events/repel.asm): + +```diff + RepelWoreOffScript:: + opentext + writetext .text + waitbutton + closetext + end + + .text + ; REPEL's effect wore off. + text_far _RepelWoreOffText + text_end + ++UseAnotherRepelScript:: ++ opentext ++ readmem wRepelType ++ getitemname STRING_BUFFER_3, USE_SCRIPT_VAR ++ 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 "@" ++ text_ram wStringBuffer3 ++ text "'s" ++ line "wore off." ++ ++ para "Use another?" ++ done +``` + +Finally, the feature works! + + |