• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Simple Modifications Directory

Subzero Eclipse

Because I say so.
24
Posts
6
Years
  • Age 31
  • Seen Mar 4, 2023

Back in July 2018, Sagiri made an implementation of Evolution Moves for Pokémon Fire Red via C Injection.
Not so long ago, UltimaSoul ported it to Pokeemerald.
Today I got their permission to drop over here a commit of mine, showing pretty quickly that implementation of Evolution Moves as an alternative to Buffel's.

It's nothing particularly complicated, just 3 simple changes and then it's a matter of setting the Evolution Moves in the src/data/pokemon/level_up_learnsets.h file.
https://github.com/LOuroboros/pokeemerald/commit/b67b5bdd1d5d893c1cbe26386658094a8d1f3f84

Quick demonstration:


And that's pretty much it.​

I'm having some troubles installing this one (which I see is on the pokeemerald wiki as well). Every time I use make, the compiler keeps giving me the error "request for member 'level' (and 'move') in something not a structure or union". What might be causing this? Thanks in advance
 

Lunos

Random Uruguayan User
3,114
Posts
15
Years
I'm having some troubles installing this one (which I see is on the pokeemerald wiki as well). Every time I use make, the compiler keeps giving me the error "request for member 'level' (and 'move') in something not a structure or union". What might be causing this? Thanks in advance
I can't apologize enough. This modification seems to be only working on DizzyEgg's battle_engine_v2 right now.
I'm not sure if I forgot to test it myself on a clean repository, or if there's been any changes since I posted it that were done to Pret's repository that affect its functioning.
Regardless, I'll look into it asap.

EDIT: Alrighty, it's ready. Thanks to ExpoSeed's help, I was able to get things to work in a clean copy of Pokeemerald.
Here's the relevant commit: https://github.com/LOuroboros/pokeemerald/commit/d5f48a1af85be80f01ff2c3adde121db924727d1

I'll add the link to it in my original post asap, and Expo will probably edit the article on the wiki very soon too, since that's about modifications to clean Pokeemerald.
 
Last edited:
16
Posts
10
Years
  • Seen Jul 18, 2021
Show Type Effectiveness In-Battle [EM]​

Now with Doubles, Flying Press/two-typed moves, and Inverse Battles support!

First thing you're going to want to do is to go into graphics\battle_interface, move text.pal to somewhere safe (I don't think the edits I made to this file harm anything, but better to be safe than sorry) and delete text.gbapal and text.gbapal.lz. Now, download the attached text.zip file, and move its contents (which is just a new text.pal) into the graphics\battle_interface folder.

Now, we get to the fun coding part!
Open up src\battle_message.c, search for sTextOnWindowsInfo_Normal, and add this to the bottom of this array:
Spoiler:


Now, open src\battle_bg.c, and add this to the bottom of gStandardBattleWindowTemplates (make sure you paste this before DUMMY_WIN_TEMPLATE, though):
Spoiler:


The final bit for this code belongs in src\battle_controller_player.c.
We're going to start by adding this define at the top of the file:
Code:
#include "event_data.h"
This is necessary for getting the Inverse Battle flag later on.

Next, define a new method at the top of the file. You can place it anywhere, but I searched for:
Code:
static void MoveSelectionDisplayMoveType(void);
And placed it above it. The method we are defining is:
Code:
static void MoveSelectionDisplayMoveTypeDoubles(u8 targetId);
The reason we're defining a whole new method for this here is because it's a bit easier than adding a 1 to every MoveSelectionDisplayMoveType call that happens in this file. If you wanted to, you could replace every MoveSelectionDisplayMoveType(); in the file to MoveSelectionDisplayMoveType(1); and replace the MoveSelectionDisplayMoveType method with the MoveSelectionDisplayMoveTypeDoubles method from later in this post and everything should work the same.

Now, we're going to be copying over the effectiveness table from src\battle_util.c of DizzyEgg's Battle Engine.
I placed this toward the top of the file, under "unknown unused data".
Spoiler:

(If you're not using DizzyEgg's Battle Engine for whatever reason, just eliminate the last line and the last column of this table to get rid of Fairy and it should work fine.)

Now, search for MoveSelectionDisplayMoveType(void), and add these three methods above it:
Spoiler:

Obviously, you can remove the whole two-type move check if you're not using DizzyEgg's Battle Engine.

And in MoveSelectionDisplayMoveType, change this line:
Code:
BattlePutTextOnWindow(gDisplayedStringBattle, 10);
To this:
Code:
BattlePutTextOnWindow(gDisplayedStringBattle, TypeEffectiveness(moveInfo, 1));

Now, we just need to add calls for MoveSelectionDisplayMoveTypeDoubles. Search for HandleInputChooseTarget(void) and find the two places that use this switch statement:
Code:
switch (GetBattlerPosition(gMultiUsePlayerCursor))
Immediately after these switch statements, add this line:
Code:
MoveSelectionDisplayMoveTypeDoubles(GetBattlerPosition(gMultiUsePlayerCursor));

And you should be good to go!
Thanks to DizzyEgg for his hard work on the Battle Engine upgrade. The type effectiveness table and the MulModifier method made things very easy once I figured out how the palettes worked. I for sure would not have been able to do this without those.

For me, there was a missing step in this really good tutorial. In one of the newly added functions, TypeEffectiveness, EFFECT_TWO_TYPED_MOVE was undeclared. This made it so that I could not compile the game after modifications. The solution I found was to include battle_move_effects.h in the battle_controller_player.c file. Additionally, event_data.h should be included towards the end of the include section. This was not clear in the tutorial, as you said to add it at the top. This may all be obvious for more experienced people in the community, but for me just starting out, it took a little while to track down. Thank you for this great tutorial, all of the resources posted here give a lot of inspiration for what can be accomplished.
 
1
Posts
3
Years
  • Age 27
  • Seen Mar 14, 2023
Fixing Battle Factory opponent IV Glitch
A little known glitch is in the Battle Factory, the IVs of the opponent are based off your progress in the Battle Tower instead of the Battle Factory, so for instance if you just got a gold medal in the Battle Tower then started in the Battle Factory, you would start off with pokemon that have IVs of 3 while your opponent would have IVs of 31, this is easily fixed.

Go into src\battle_tower.c

Go to the function, around line 1824 for me
Code:
static void FillFactoryFrontierTrainerParty(u16 trainerId, u8 firstMonId)
About 12 lines down down you should see
Code:
u8 challengeNum = gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][0] / 7;
change this to
Code:
u8 challengeNum = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] / 7;

And you're done, the IVs of the opponent pokemon should now match your progress within the Battle Factory correctly.
 
146
Posts
16
Years
  • Age 25
  • Seen today
For me, there was a missing step in this really good tutorial. In one of the newly added functions, TypeEffectiveness, EFFECT_TWO_TYPED_MOVE was undeclared. This made it so that I could not compile the game after modifications. The solution I found was to include battle_move_effects.h in the battle_controller_player.c file. Additionally, event_data.h should be included towards the end of the include section. This was not clear in the tutorial, as you said to add it at the top. This may all be obvious for more experienced people in the community, but for me just starting out, it took a little while to track down. Thank you for this great tutorial, all of the resources posted here give a lot of inspiration for what can be accomplished.

Oh huh, guess I totally forgot the battle_move_effects include. Thanks!
 
16
Posts
10
Years
  • Seen Jul 18, 2021
How to force the Battle style [Set|Shift] [EM]

This guide is for you when you want to force the player to play in set or shiftmode. For either the enteire game or just during important matches. ex: Always switch except during gyms matches were you force set.



Most changes are done in the option_menu.c file.

To dissable the user from change the setting we are going to remove this setting from the option menu. We'll start by commenting (or deleting) some lines.
Spoiler:


Then comment/delete the whole functions: BattleStyle_ProcessInput and BattleStyle_DrawChoices arround lines 470->491

Now the user can't change this setting anymore, but the options menu will look weird, what we now need to do is lower a few magic numbers.

Spoiler:



To set the default mode go to new_game.c

Spoiler:


To change this style from a script set a var and make a new function where you check the var value and update the setting accordingly. And then call that funciton from the script. I'll extend this tutorial to do that if requested.

Can I request that you update this tutorial? Some of the variables have been swapped around since the last update. The parts I am getting held up on start in the second spoiler section. The first section hasn't changed much other than line numbers. The changes are significant enough that I'm unable to figure out what to change myself in a timely manner, and so I would appreciate someone more experienced than myself explain what has changed.
 
50
Posts
6
Years
  • Age 25
  • Seen Oct 20, 2023
Can I request that you update this tutorial? Some of the variables have been swapped around since the last update. The parts I am getting held up on start in the second spoiler section. The first section hasn't changed much other than line numbers. The changes are significant enough that I'm unable to figure out what to change myself in a timely manner, and so I would appreciate someone more experienced than myself explain what has changed.

On second thought, the tutorial wasn't maybe a clear one. To answer your question: Since the numbers in the second spoiler were replaced with enum values, these values were actually automatically adjusted if the enum entry was removed. Here is the commit and this is the repo branch in case you want to merge.

I will put the link in the original post as well.
 

Lunos

Random Uruguayan User
3,114
Posts
15
Years
Does anyone know a way to preserve party order for trainers? I am using the Decomp Trainer Editor, and trying out various AI flags, but for whatever reason the trainer I am using as a test decides to send out their designated third (last) Pokemon second. This is problematic, as I am using the custom in-battle messages for plot points, which if the order is changed makes the messages not really make sense. Any help with understanding the AI flags and/or providing a solution to preserve party order will be very appreciated. Thanks in advance.
This is a thread to provide simple to understand modifications for Pret's Decompilation projects that are ready to use.
You're free to create a thread in the Decomp & Disassembly section to ask for help about anything unrelated to that.
 
16
Posts
10
Years
  • Seen Jul 18, 2021
Preserve Trainer Party Order​

If you, like me, want to preserve trainer party order when using the custom in-battle messages, then this modification should help. Redirect any criticisms, additions, etc. to the main thread here: https://www.pokecommunity.com/showthread.php?t=438395

Steps:

Spoiler:


Spoiler:


Spoiler:


And that's it. You can set the flags using the Decomp Trainer Editor, and see for yourself.
NOTE: Again, please send any bug reports, etc. to the thread I made. Also, some of the code uses ! rather than ~, I'm not too sure if it makes a difference or which would be correct. From my testing, though, it appears to work correctly.
EDIT: Bitwise appears to be the correct way. ! changed to ~. Thanks to mgriffin.
 
Last edited:
1,403
Posts
10
Years
  • Seen Apr 18, 2024
Also, some of the code uses ! rather than ~, I'm not too sure if it makes a difference or which would be correct. From my testing, though, it appears to work correctly.

AI_THINKING_STRUCT->aiFlags & !(AI_SCRIPT_DO_NOT_SWITCH | AI_SCRIPT_PRESERVE_ORDER)
This almost certainly should use ~. !(x) is either 0 or 1 (it's 0 if x is non-zero, and 1 if x is zero). ~ inverts all the bits. & is a bitwise and, so this is equivalent to false, because I'm pretty sure the thing in the parens will be non-zero, and anything &-ed with 0 is 0.

x & ~y, is like set difference.
 
16
Posts
10
Years
  • Seen Jul 18, 2021
AI_THINKING_STRUCT->aiFlags & !(AI_SCRIPT_DO_NOT_SWITCH | AI_SCRIPT_PRESERVE_ORDER)
This almost certainly should use ~. !(x) is either 0 or 1 (it's 0 if x is non-zero, and 1 if x is zero). ~ inverts all the bits. & is a bitwise and, so this is equivalent to false, because I'm pretty sure the thing in the parens will be non-zero, and anything &-ed with 0 is 0.

x & ~y, is like set difference.

Alrighty, I'll edit the posts in a bit here. I'm more well-versed in higher level languages (Java, JavaScript, Python), so haven't had much experience in bitwise operators. That's why I wasn't too sure if bitwise or logical was the correct one to use there.

EDIT: Actually, would !(AI_THINKING_STRUCT->aiFlags & (AI_SCRIPT_DO_NOT_SWITCH | AI_SCRIPT_PRESERVE_ORDER)) be more suitable?
EDIT2: It looks like either way works, so it's up to the person adding it in.
 
Last edited:

Jaizu

Average rom hacker
280
Posts
14
Years
Headbutt tree for Pokeemerald

Code:
EventScript_Headbutt::
	lockall
	checkpartymove MOVE_HEADBUTT
	compare VAR_RESULT, PARTY_SIZE
	goto_if_eq EventScript_CantHeadbutt
	setfieldeffectargument 0, VAR_RESULT
	bufferpartymonnick 0, VAR_RESULT
	buffermovename 1, MOVE_HEADBUTT
	msgbox Text_WantToHeadbutt, MSGBOX_YESNO
	compare VAR_RESULT, NO
	goto_if_eq EventScript_CancelHeadbutt
	msgbox Text_MonUsedFieldMove, MSGBOX_DEFAULT
	closemessage
	dofieldeffect FLDEFF_USE_STRENGTH
	waitstate
	delay 5
	playse SE_M_HEADBUTT
	waitse
	delay 16
	setvar VAR_0x8004, 0  @ vertical pan
	setvar VAR_0x8005, 2   @ horizontal pan
	setvar VAR_0x8006, 3  @ num shakes
	setvar VAR_0x8007, 1   @ shake delay
	special ShakeCamera
	waitstate
	delay 10
	special RockSmashWildEncounter
	compare VAR_RESULT, 0
	goto_if_eq EventScript_Headbutt_NoEncounter
	waitstate
	releaseall
	end

EventScript_CantHeadbutt::
	msgbox Text_CantHeadbutt, MSGBOX_DEFAULT
	releaseall
	end

EventScript_CancelHeadbutt::
	closemessage
	releaseall
	end

EventScript_Headbutt_NoEncounter::
	releaseall
	end

Text_WantToHeadbutt::
.string "A Pokémon could be in this tree.\n"
.string "Want to {COLOR RED}Headbutt{COLOR DARK_GREY} it?$"

Text_CantHeadbutt:
.string "A Pokémon could be in this tree.$"
 
Last edited:
50
Posts
6
Years
  • Age 25
  • Seen Oct 20, 2023
Code:
void DoHeadbuttShakingEffect(void)
{
    gTasks[taskId].data[1] = 1;
    gTasks[taskId].data[2] = 0;
    gTasks[taskId].data[4] = 1;
    gTasks[taskId].data[5] = 3;
    gTasks[taskId].data[6] = 4;
    SetCameraPanningCallback(0);
}

What is the purpose of the task magic if I may ask?
 
239
Posts
8
Years
  • Age 31
  • Seen Apr 15, 2024
[Pokeemerald] Coin Pokemarts

This feature creates a pokemart that uses Coins instead of money for casino prizes. Note that its limited to items. Pokemon prizes would need a separate system.

y4Atxsu.gif


Here's the repo.

How to add:
How to use:
  • a "coinPrice" element has been added to the item data structure. Give any prize item a coinPrice in src/data/items.h
  • use the script command "casinopokemart" followed by a pointer to your prize list just like the regular pokemart command:
    Code:
    EventScript_PrizeCounter::
         lock
         casinopokemart PrizeList
         release
         end
    .align 2
    PrizeList:
         .2byte ITEM_HP_UP
         .2byte ITEM_PROTEIN
         @ etc
         .2byte ITEM_NONE  @ must always be at the end
 
1,309
Posts
12
Years
  • Age 31
  • Seen Nov 24, 2023
Updated! Thanks to all who posted. I know lots of these modifications will be posted elsewhere such as each decomp's respective wiki, but it can't hurt to have them in more than one place :)
 
239
Posts
8
Years
  • Age 31
  • Seen Apr 15, 2024
[Pokeemerald] Ability Tutor

This feature adds a tutor for teaching a pokemon (potentially) any ability! The spoiler includes method more detail:
GXBBxiD.gif


Spoiler:


How to use:
  • Pull from my repo (details below)
  • The ability tutor code is handled in src/field_specials.c. Update "sAbilityList" to include the abilities you want your tutor to be able to teach.
  • Write a script (example below) to call "special AbilityTutor," and enjoy!
    Spoiler:

How to add:
 
Last edited:

Jaizu

Average rom hacker
280
Posts
14
Years
[Pokeemerald] Lower case after first input in the naming screen.
Y9TuT7d.gif

In src/naming_screen.c
We look for the function static bool8 KeyboardKeyHandler_Character(u8 input)

And we change it with this one
Code:
static bool8 KeyboardKeyHandler_Character(u8 input)
{
    TryStartButtonFlash(BUTTON_COUNT, FALSE, FALSE);
    if (input == INPUT_A_BUTTON)
    {
        bool8 textFull = AddTextCharacter();

        if (sNamingScreen ->currentPage == KBPAGE_LETTERS_UPPER && GetTextEntryPosition() == 1)
            MainState_StartPageSwap();

        SquishCursor();
        if (textFull)
        {
            SetInputState(INPUT_STATE_OVERRIDE);
            sNamingScreen->state = STATE_MOVE_TO_OK_BUTTON;
        }
    }
    return FALSE;
}

All I did was adding
Code:
        if (sNamingScreen ->currentPage == KBPAGE_LETTERS_UPPER && GetTextEntryPosition() == 1)
            MainState_StartPageSwap();
under
Code:
bool8 textFull = AddTextCharacter();

Make sure your repo is up to date, this file got updated not so long ago:
https://github.com/pret/pokeemerald...bbe1ee1#diff-138aab24ea0a6ec9cb8e839962b916f7
https://github.com/pret/pokeemerald...b61f9b6#diff-138aab24ea0a6ec9cb8e839962b916f7
 
5
Posts
6
Years
  • Age 28
  • Seen Feb 28, 2023
[PokeEmerald] Surfboard instead of HM Surf​
XbOXRXx.gif

Adds in a Surfboard that lets the player just walk into water.
No long, annoying animations~


How to use:
  • Add the code to your pokeemerald decomp as described below.
  • Give the player the item ITEM_SURFBOARD
  • Have the player walk into water
  • The player will now be surfing on the water

How to add:
 
Last edited:
Back
Top