Pokemon Gen 4 Code Injection Patcher
This is a small thing ive written up to easily distribute .asm patches for code injecting things such as EV+IV-checking and Portable PC routines, because i was tired of explaining and writing out every patch separately.
This program is purely cli. It prompts you to select an unpacked ROM folder (such as one generated by DSPRE), then one of the included patches, then checks for:
- Is the patch compatible with your game? (by comparing game header with patch name, so if you want to contribute your own patches, make sure to label your patches corrrectly)
- Can you even inject the patch, i.e. is your arm9 expanded?
- Is there free space in the synthOverlay and where is said space
After checking these things, it adjusts the patch file with the corrected injection address and runs the patch through armips.
An armips binary is bundled into the release, so no need to install anything!
1. Usage:
- Download the latest release
- Run G4Patcher
- Select your unpacked ROM folder
- Select the patch
- If everything is fine, youll get a confirmation message, if not, you'll get a message telling you what the issue is
- Press Enter to close
2. Limitations:
- The program doesn't check if the patch is already applied, so if you apply a patch twice, it will duplicate the previous one. The patch will still work, but more space in your synthOverlay will be used up.
- The program doesnt check compression either (yet), so make sure that the hook overlay required by the patch is not compressed.
3. Included patches:
3.1 EV+IV Checker (HG/SS/PLAT)
When applied, holding R while opening the summary/switching to a pokemon in the summary screen will display IVs instead of stats. L for EVs.
3.2 ButtonScript (HG/SS/PLAT)
ATTENTION: this patch requires you to have an uncompressed overlay (0001 for HG/SS, 0005 for Plat)!
When applied, a given button (default: Start) will execute a script when pressed in the overworld. This is usually used to implement a portable PC, but can be used with other scripts as well.
In HG/SS, the script is set to CommonScript 2072 (Script 73 in Script file 3), in Platinum it is set to CommonScript 2058 (Script 59 in Script file 211).
Neither of these scripts exist in the base game, so you will have to create them yourself. This is intentional, so that you can write a PC script that suppresses animations when called through the button.
You can change the button and the script in the patch before applying.
3.3 Dynamic Encounters and Weather (HG/SS/PLAT)
This patch overwrites an unused scripting command allowing for dynamic encounters and weather.
- In Platinum the overwritten command is
DummySetWeather(commandCMD_0x09C). - In HG/SS the overwritten command is
DummyTrainerBattle(commandCMD_0x0DF). - The command uses variables defined at the top of the patch file. By default:
| Variable | Default Value | Purpose |
|---------------------|---------------|-------------------------------------------------------------------------|
| `ScriptVar_Param1` | `0x4015` | Mode: `0` = encounters, `>=1` = weather |
| `ScriptVar_Param2` | `0x4016` | Encounter bank or weather type |
| `ScriptVar_Param3` | `0x4017` | Weather animation: `0` = skip, `1` = play (unused for encounters) |
Important: In HG/SS you will need to edit the patch file to set the encounter bank.
3.4 Apply a Status Condition to a Pokemon in the Party from the Overworld (HG/SS/PLAT)
This patch repurposes an unused scripting command to allow setting status conditions on Pokémon in the party from the overworld.
- Platinum: The unused command is
DummyUndergroundorCMD_335. This command is actually used once in the game, so it will need to be removed from the script it is used in. - HeartGold/SoulSilver: The unused command is
CMD_228 [2B]. The two-byte parameter is required for DSPRE but unused.
The command uses the following variables:
0x8004: Stores the party slot.0x8005: Stores the status condition.
The command will:
- Apply the specified status condition to the Pokémon in the given party slot.
- Not apply status to Pokémon already affected by a status condition.
- Not avoid burning Fire-types or poisoning Poison-types. Additional scripting is required to prevent these cases if needed.
| Status Condition | Value | Decimal |
|---|---|---|
| NONE | 0 | 0 |
| SLEEP_COUNTER_0 | (1 << 0) | 1 |
| SLEEP_COUNTER_1 | (1 << 1) | 2 |
| SLEEP_COUNTER_2 | (1 << 2) | 4 |
| POISON | (1 << 3) | 8 |
| BURN | (1 << 4) | 16 |
| FREEZE | (1 << 5) | 32 |
| PARALYSIS | (1 << 6) | 64 |
| TOXIC | (1 << 7) | 128 |
| TOXIC_COUNTER_0 | (1 << 8) | 256 |
| TOXIC_COUNTER_1 | (1 << 9) | 512 |
| TOXIC_COUNTER_2 | (1 << 10) | 1024 |
| TOXIC_COUNTER_3 | (1 << 11) | 2048 |
3.5 Preventing the player from using items in trainer battles (PLAT)
This patch will prevent the player from using any items from the bag in a trainer battle. The message shown will be the same as when you try to use items in a link battle.
3.6 AI Item use fix (PLAT)
Have you ever noticed that the AI uses items in battle in a weird way? This is actually because the AI routine that is supposed to determine what item a trainer should use is bugged. Under certain (common) conditions, the AI will use up all of its items at once.
3.7 Force wild encounters to be shiny (PLAT)
When a certain flag is set (Flag 2570 by default), this patch will force all wild encounters to be shiny, regardless of the player's ID or SID. You can change the flag in the patch file before applying.
3.8 Level Caps (PLAT)
A certain variable (16422 by default) dictates if Pokémon can gain EXP. If the Pokémon's level is higher than the cap it won't gain any EXP anymore. (The Daycare is an exception to this)
(more to come)
4. Contributing:
If you want to contribute your own patches, you can use the included ones as templates as to what yours are supposed to look like.
Make sure that:
- The patch name is clearly labeled with the ROM it is to be applied to (such as "_HG")
- The patch includes a:
INJECT_ADDR equ 0x023C8750
.org INJECT_ADDR
so that the script is able to adjust the injection address