summaryrefslogtreecommitdiff
path: root/Automatically-reuse-Repel.md
blob: 456b2f2642cec2b04bc9c1063c6ed5a2a1cf3a6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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)