summaryrefslogtreecommitdiff
path: root/Automatically-reuse-Repel.md
diff options
context:
space:
mode:
Diffstat (limited to 'Automatically-reuse-Repel.md')
-rw-r--r--Automatically-reuse-Repel.md164
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!
+
+![](https://github.com/pret/pokecrystal/wiki/screenshots/use-another-repel.png)