summaryrefslogtreecommitdiff
path: root/Automatically-reuse-Repel.md
blob: 569e730fd0051f19f217e7042b515a96073f81f1 (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
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, .got_script
+	ld a, BANK(UseAnotherRepelScript)
+	ld hl, UseAnotherRepelScript
+.got_script
	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!

![Screenshot](screenshots/use-another-repel.png)