Automatically reuse Repel - pret/pokecrystal GitHub Wiki
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
- Add space in WRAM and SRAM for the type of Repel used
- Store the type when a Repel is used
- Check if you have more of the last-used type when one wears off
- Ask whether to use another Repel, and do so, if applicable
- 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/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.
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:
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:
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:
_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!