Repel QoL Improvements - pret/pokered GitHub Wiki

Introduction

This tutorial provides instructions to introduce two QoL improvements to Repels that are present in later generations:

  1. The player will be unable to use a new Repel until the previous one expires
  2. The player will be offered a chance to automatically use a follow-up Repel when the previous one expires

Let's get started!

Disallowing Repel Usage Before Previous One Expires

With this code the player will be unable to use any type of Repel while a previous one is still in effect; a message indicating this will also be displayed.

First, open up engine\items\item_effects.asm and search for the section ItemUseRepelCommon. You'll start by inserting these three lines:

ItemUseRepelCommon:
	ld a, [wIsInBattle]
	and a
	jp nz, ItemUseNotTime
+	ld a, [wRepelRemainingSteps]		; loads number of remaining Repel steps, if any, into 'a'
+	and a								; checks if 'a' is 0
+	jp nz, RepelStillInEffect			; if not, jump to RepelStillInEffect without using an item
	ld a, b
	ld [wRepelRemainingSteps], a
	jp PrintItemUseTextAndRemoveItem
...

Now we define RepelStillInEffect. Head way down (about 700 lines) until you find the section where all the cases of "ItemUseFailed" are handled. There are three more lines to insert here:

...
ItemUseNotYoursToUse:
	ld hl, ItemUseNotYoursToUseText
	jr ItemUseFailed

+RepelStillInEffect:
+	ld hl, RepelStillInEffectText
+	jr ItemUseFailed

ThrowBallAtTrainerMon:
...

Now go down just a bit further and insert... you guessed it! Three more lines:

...
ItemUseNoEffectText:
	text_far _ItemUseNoEffectText
	text_end

+RepelStillInEffectText:
+	text_far _RepelStillInEffectText
+	text_end

ThrowBallAtTrainerMonText1:
	text_far _ThrowBallAtTrainerMonText1
	text_end
...

Finally, go open data\text\text_4.asm and insert the following:

_RepelWoreOffText::
	text "REPEL's effect"
	line "wore off."
	done

+_RepelStillInEffectText::
+	text "A REPEL is still"
+	line "in effect."
+	prompt

_PokemartBuyingGreetingText::
	text "Take your time."
	done
...

That's all it takes to prevent wasted Repels!

Now, auto-using a follow-up Repel is slightly more complicated, as the code involved is considerably more extensive.

Note: Because of this, you will likely run into the issue of your HOME bank growing too large... but fear not! These tutorials will easily alleviate this problem:

https://github.com/pret/pokeyellow/wiki/Free-some-space-in-the-Home-BANK (yes, it says PokeYellow, but it works absolutely fine!) https://github.com/pret/pokered/wiki/Free-MORE-some-space-in-the-Home-BANK (just moving the CalcStats stuff will free up the needed space)

I would recommend visiting those tutorials first to ensure that HOME bank space limitations don't end up muddying the waters here. Now, on to the next section!

Using a Follow-Up Repel Without Opening the Inventory

With this code, when your current Repel expires, the game will first check whether the player has any more Repels in the bag. If not, the player is informed that there are no Repels remaining. If there are Repels left in the bag, the player has the option whether or not to automatically use another. If the player selects yes, the game will search for the highest quality Repel currently in the bag and automatically use it.

Open up home\text_script.asm and find DisplayRepelWoreOffText (conveniently found at the end of the file). Copy/Paste the following:

DisplayRepelWoreOffText::
	ld hl, RepelWoreOffText
	call PrintText
-	jp AfterDisplayingTextID
+	ld b, REPEL							; loads REPEL into 'b'
+	call IsItemInBag					; is REPEL in bag?
+	jr nz, .OfferAutoUseRepelText		; if so, jump to OfferAutoUseRepel
+	ld b, SUPER_REPEL					; otherwise, load SUPER_REPEL into 'b'
+	call IsItemInBag					; is SUPER_REPEL in bag?
+	jr nz, .OfferAutoUseRepelText		; if so, jump to OfferAutoUseRepel
+	ld b, MAX_REPEL						; otherwise, load MAX_REPEL into 'b'
+	call IsItemInBag					; is MAX_REPEL in bag?
+	jr nz, .OfferAutoUseRepelText		; if so, jump to OfferAutoUseRepel
+.NoRepelsLeftText
+	ld hl, NoRepelsLeftText				; if no REPEL-type items were found, display NoRepelsLeftText
+	call PrintText
+	jp AfterDisplayingTextID			; text ends
+.OfferAutoUseRepelText
+	ld hl, OfferAutoUseRepelText		; if REPEL-type item was found, automatically offer follow-up REPEL use
+	call PrintText
+	call YesNoChoice					; displays YES/NO box
+	ld a, [wCurrentMenuItem]
+	and a
+	jr z, .PlayerSelectedAutoUseRepel	; if player selects YES, search bag for highest quality of REPEL available
+	jp CloseTextDisplay					; if player selects NO, text ends
+.PlayerSelectedAutoUseRepel
+	ld b, MAX_REPEL						; first checks bag for MAX_REPEL
+	call IsItemInBag
+	jr nz, .AutoUseMaxRepel				; if MAX_REPEL is found, automatically use it
+	ld b, SUPER_REPEL					; if no MAX_REPEL, next search for SUPER_REPEL
+	call IsItemInBag
+	jr nz, .AutoUseSuperRepel			; if SUPER_REPEL is found, automatically use it
+	ld a, 100							; if no SUPER_REPEL, initiate process for using REPEL
+	ld [wRepelRemainingSteps], a		; loads 100 Repel steps remaining
+	ld hl, AutoUsedRepelText
+	call PrintText
+	ld a, REPEL							; prepares to remove REPEL from bag
+	jr .AutoRemoveRepelFromBag			; jump to removal
+.AutoUseMaxRepel
+	ld a, 250							; # of steps for MAX_REPEL
+	ld [wRepelRemainingSteps], a		; loads 250 Repel steps remaining
+	ld hl, AutoUsedMaxRepelText
+	call PrintText
+	ld a, MAX_REPEL						; prepares to remove MAX_REPEL from bag
+	jr .AutoRemoveRepelFromBag			; jump to removal
+.AutoUseSuperRepel
+	ld a, 200							; # of steps for SUPER_REPEL
+	ld [wRepelRemainingSteps], a		; loads 200 Repel steps remaining
+	ld hl, AutoUsedSuperRepelText
+	call PrintText
+	ld a, SUPER_REPEL					; prepares to remove SUPER_REPEL from bag
+.AutoRemoveRepelFromBag
+	ldh [hItemToRemoveID], a
+	farcall RemoveItemByID				; removes used REPEL-type item from bag
+	ld a, SFX_HEAL_AILMENT
+	call PlaySound						; plays item sound
+	call WaitForTextScrollButtonPress
+	jp CloseTextDisplay					; text ends

RepelWoreOffText::
	text_far _RepelWoreOffText
	text_end

Next we define some of the new text that is being referenced in this new code. At the very end, Copy/Paste the following:

RepelWoreOffText::
	text_far _RepelWoreOffText
	text_end

+NoRepelsLeftText::
+	text_far _NoRepelsLeftText
+	text_end
+
+OfferAutoUseRepelText::
+	text_far _OfferAutoUseRepelText
+	text_end
+
+AutoUsedMaxRepelText:
+	text_far _AutoUsedMaxRepelText
+	text_end
+
+AutoUsedSuperRepelText:
+	text_far _AutoUsedSuperRepelText
+	text_end
+
+AutoUsedRepelText:
+	text_far _AutoUsedRepelText
+	text_end
+

Lastly, go to data\text\text_4.asm and create the text to be displayed:

_RepelWoreOffText::
	text "REPEL's effect"
	line "wore off."
-	done
+	prompt

+_NoRepelsLeftText::
+	text "There are no"
+	line "REPELs left."
+	done
+
+_OfferAutoUseRepelText::
+	text "Would you like to"
+	line "use another?"
+	done
+
+_AutoUsedMaxRepelText::
+	text "<PLAYER> used"
+	line "MAX REPEL!"
+	done
+
+_AutoUsedSuperRepelText::
+	text "<PLAYER> used"
+	line "SUPER REPEL!"
+	done
+
+_AutoUsedRepelText::
+	text "<PLAYER> used"
+	line "REPEL!"
+	done
...

And that should do it. Repels should now be a bit more user-friendly!

⚠️ **GitHub.com Fallback** ⚠️