Skip to content

Automatically reuse Repel

Rangi edited this page Feb 26, 2018 · 16 revisions

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
  2. Store the type when a Repel is used
  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
  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:

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:

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/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.

SuperRepelEffect: ; f462
	ld b, 200
	jr UseRepel
; f466

MaxRepelEffect: ; f466
	ld b, 250
	jr UseRepel
; f466

RepelEffect: ; 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, [wCurItem]
+	ld [wRepelType], a
	jp UseItemText


TextJump_RepelUsedEarlierIsStillInEffect: ; 0xf47d
	; The REPEL used earlier is still in effect.
	text_jump Text_RepelUsedEarlierIsStillInEffect
	db "@"
; 0xf482

3. Check if you have more of the last-used type when one wears off

Edit engine/events.asm:

DoRepelStep: ; 96bd7
	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
; 96beb

Note that UseAnotherRepelScript hasn't been defined yet, so we'll do that next.

4. Ask whether to use another Repel, and do so, if applicable

Edit engine/events/misc_scripts_2.asm:

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 the "Use another?" message

Edit data/text/common_1.asm:

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

Clone this wiki locally