Reusable Repel(Platinum)
Author: SpagoAsparago
Credits: SpagoAsparago (Implementation), BluRose (Help with ASM), brahulus (Repel AR Code)
This is a tutorial on how to implement the reusable repel in Platinum. When the repel runs out, a prompt will appear, from which the player can choose to use another repel:
The options only appear if the player has the appropriate repel item(s) in the bag
You'll need to use DSPRE and a Hex Editor. If you don't know how to hex edit, check out the Hex Editing Guide
This only works on the US Version of the game. Attempting to replace the same bytes on a different language game will not work.
Table of Contents
DSPRE
If you don't have one already, create a new project by loading your ROM in DSPRE. Then go to the Scripting tab.
Scripting
Go to Script 33
replace it with the following:
Script 33
Script 33:
PlayFanfare 1500
LockAll
CheckPlayerHasItem 79 1 0x800C
CompareVarValue 0x800C 1
JumpIf EQUAL Function#177
CheckPlayerHasItem 76 1 0x800C
CompareVarValue 0x800C 1
JumpIf EQUAL Function#177
CheckPlayerHasItem 77 1 0x800C
CompareVarValue 0x800C 1
JumpIf EQUAL Function#177
Message 79
WaitAB
CloseMessage
ReleaseAll
End
Next go to the Functions tab and add the following functions. If the functions 177+ already exist, adjust the new function IDs accordingly so that no functions are replaced.
Functions
Function 177:
Message 75
YesNoBox 0x800C
CompareVarValue 0x800C 0
JumpIf EQUAL Function#178
CloseMessage
ReleaseAll
End
Function 178:
CloseMessage
MultiStandardText 1 1 0 1 0x800C
CheckPlayerHasItem 79 1 0x8000
CompareVarValue 0x8000 1
CallIf EQUAL Function#179
CheckPlayerHasItem 76 1 0x8000
CompareVarValue 0x8000 1
CallIf EQUAL Function#180
CheckPlayerHasItem 77 1 0x8000
CompareVarValue 0x8000 1
CallIf EQUAL Function#181
ShowMulti
CompareVarValue 0x800C 0
JumpIf EQUAL Function#182
CompareVarValue 0x800C 1
JumpIf EQUAL Function#183
CompareVarValue 0x800C 2
JumpIf EQUAL Function#184
ReleaseAll
End
Function 179:
AddMultiOption 30 0
Return
Function 180:
AddMultiOption 31 1
Return
Function 181:
AddMultiOption 32 2
Return
Function 182:
AdrsValueSet 0x023DFF28 100
DummyTakeTrap
TakeItem 79 1 0x8000
TextPlayerName 0
TextItem 1 79
Message 72
WaitButton
CloseMessage
Return
Function 183:
AdrsValueSet 0x023DFF28 150
DummyTakeTrap
TakeItem 76 1 0x8000
TextPlayerName 0
TextItem 1 76
Message 72
WaitButton
CloseMessage
Return
Function 184:
AdrsValueSet 0x023DFF28 250
DummyTakeTrap
TakeItem 77 1 0x8000
TextPlayerName 0
TextItem 1 77
Message 72
WaitButton
CloseMessage
Return
Save the script file.
Text
Go to the Text Editor tab. Remember to save each Text Archive before moving on to the next one.
- Open
Text Archive 361
, and replace messages 30, 31 and 32 respectively with:- Repel
- Super Repel
- Max Repel
- Open
Text Archive 213
, and replace message 72 with:- Repel’s effect wore off...\nWould you like to use another one?
- Open
Text Archive 213
, and replace message 75 with:- \v0103ぁ\x0000\x0000 used the\n\v0108ぁ\x0001\x0000.\rWild Pokémon will be repelled.
Hex Editing
If you haven't already, you need to expand the arm9 trough DSPRE's ROM Toolbox. You can do so by clicking the Explorer Kit Icon in the top bar and applying the ARM9 Expansion patch.
In the folder where your ROM is located, DSPRE should have created a folder name yourROMname_DSPRE_Contents. Inside that you'll find a file called arm9.bin
, open it in your hex editor of choice.
Go to the offset 0x4EAE8
and replace all the bytes from this offset with the following sequence:
0B 48 01 68 0B 48 09 18 0B 48 02 78 0A 70 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 C0 46 70 47 40 1D 10 02 87 80 00 00 28 FF 3D 02
Do not add new bytes. In HxD you can paste without replacing with the Ctrl+B shortcut. Save the file.
Now you can load DSPRE again and save the ROM. Remember to not re-extract the contents, otherwise your hex editing will be lost!
The custom command works by setting the repel counter at the byte written at 15FEE in weather_sys_9.bin, so remember to don't write anything at this offset!
Detailed Explanation for the Custom Command and Repel Counter
The repel counter is a dynamic offset located at (Address at 0x02101D40) + (0x8087). This is only valid for the US version, hence my code won't work on other regions without writing a new custom command.
When the repel counter runs out, the game will automatically execute Script 33 in Script File 211.
After the scripting and hex edits performed, now Script 33 will:
- Check if the player has any repel item in their bag
- If they do, ask if they wants to use anothe repel
- If they want to, create a popup window containing all the available repel items
- Remove the repel item that has been chosen from the bag
- Use the
AdrsValueSet
command to write a byte at the offset 0x023DFF28, containing the number of steps of the selected repel - Trough the
DummyTakeTrap
, the repel counter is increased by the previously set value
The DummyTakeTrap
command is otherwise unused, so it's been replaced with a custom one in order to access the dynamic offset of the repel counter, and set the counter to the new value.
The custom command is necessary as there is no way to access the dynamic offset using only vanilla scripting commands.
This is the raw assembly code:
ASM Code
ldr r0, =0x02101D40
ldr r1, [r0]
ldr r0, =0x8087
add r1, r0
ldr r0, =0x023DDFEE
ldrb r2, [r0]
strb r2, [r1]
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bx lr
This part of the code:
ldr r0, =0x02101D40
ldr r1, [r0]
ldr r0, =0x8087
add r1, r0
Is used to calculate the dynamic offset by loading the address at 0x2101D40 and then adding 0x8087 to it, storing the repel counter offset in the R1 register.
The following part:
ldr r0, =0x023DDFEE
ldrb r2, [r0]
strb r2, [r1]
Is used to read the byte previously written at 0x023DDFEE by the AdrsValueSet
command, and updating the repel counter with it.
The 0x023DDFEE offset is at a region in the RAM otherwise unused, but costantly loaded trough the syntehtic overlay.
The remaining nop
commands are there to maintain the original command dimension and prevent the script command table from being read incorrectly.