• 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

POKEEMERALD: HOW TO CHANGE PLAYER SPRITES/INITIAL SPRITES

In order to change the initial sprites, you need to go to src/field_player_avatar, search for these pointers and change the OBJ_EVENT_GFX to the sprite you want.

Examples: Changing OBJ_EVENT_GFX_BRENDAN_NORMAL to OBJ_EVENT_GFX_SCHOOL_KID

static const u16 sRivalAvatarGfxIds[][2] =

Spoiler:


static const u16 sRivalAvatarGfxIds[][2] =

Spoiler:
 
Last edited:
POKEEMERALD: HOW TO CHANGE PLAYER SPRITES/INITIAL SPRITES

In order to change the initial sprites, you need to go to src/field_player_avatar, search for these pointers and change the OBJ_EVENT_GFX to the sprite you want.

Examples: Changing OBJ_EVENT_GFX_BRENDAN_NORMAL to OBJ_EVENT_GFX_SCHOOL_KID

static const u16 sRivalAvatarGfxIds[][2] =

Spoiler:


static const u16 sRivalAvatarGfxIds[][2] =

Spoiler:

Chance has it that I am working on this right now. This simple change, however, results in a buggy palette for the player overworld sprite. The correct overworld sprite is displayed, but it appears in blacks, reds and transparent colors. Did I miss something?

Edit: Actually, after a while, the sprites started displaying less weird colors. In fact, it seems to switch through a number of palettes, changing the colors of some details (hat, clothes) but not the color of the skin. The palette switches either at warp points or randomly in the middle of a map, there doesn't seem to be a pattern to it. I have implemented the dynamic overworld palette system, but I'm not sure if that matters.

Edit 2: Solution (as well as addition to the instructions of HackerL):

In pokeemerald\src\data\object_events\object_events_graphics_info.h, change the palette slot of the overworld sprite you want to use for the player to 0 (zero). The palette slot is the number that follows the width and height of the sprite, and precedes the sprite's shadow size. I the example below it is marked in bold, so you find it back easily. Most sprites have a palette slot between 2 and 6 or something. Change it to zero. This is the palette slot reserved for the player avatar. (Note that this will probably mean that the sprite cannot be used for regular NPCs anymore, so if you want to use the sprite for both, you may want to duplicate it. This is done in-game as well for the rival and player sprites of Brendan and May.)

This also applies if you have implemented the dynamic overworld palette system. If you change the sprite of the rival, make sure to change its (so of the new sprite you will use) palette slot to 10 (ten).

For example, I want to use the "artist" sprite as the player avatar:

In field_player_avatar.c :
Code:
static const u8 sRivalAvatarGfxIds[][2] =
{
    {[B]OBJ_EVENT_GFX_ARTIST[/B],     				 OBJ_EVENT_GFX_RIVAL_MAY_NORMAL},
    {OBJ_EVENT_GFX_RIVAL_BRENDAN_MACH_BIKE,  OBJ_EVENT_GFX_RIVAL_MAY_MACH_BIKE},
    {OBJ_EVENT_GFX_RIVAL_BRENDAN_ACRO_BIKE,  OBJ_EVENT_GFX_RIVAL_MAY_ACRO_BIKE},
    {OBJ_EVENT_GFX_RIVAL_BRENDAN_SURFING,    OBJ_EVENT_GFX_RIVAL_MAY_SURFING},
    {OBJ_EVENT_GFX_BRENDAN_UNDERWATER,       OBJ_EVENT_GFX_MAY_UNDERWATER},
    {OBJ_EVENT_GFX_RIVAL_BRENDAN_FIELD_MOVE, OBJ_EVENT_GFX_RIVAL_MAY_FIELD_MOVE},
    {OBJ_EVENT_GFX_BRENDAN_FISHING,          OBJ_EVENT_GFX_MAY_FISHING},
    {OBJ_EVENT_GFX_BRENDAN_WATERING,         OBJ_EVENT_GFX_MAY_WATERING}
};

static const u8 sPlayerAvatarGfxIds[][2] =
{
    {[B]OBJ_EVENT_GFX_ARTIST[/B],     		   OBJ_EVENT_GFX_MAY_NORMAL}, // edited
    {OBJ_EVENT_GFX_BRENDAN_MACH_BIKE,  OBJ_EVENT_GFX_MAY_MACH_BIKE},
    {OBJ_EVENT_GFX_BRENDAN_ACRO_BIKE,  OBJ_EVENT_GFX_MAY_ACRO_BIKE},
    {OBJ_EVENT_GFX_BRENDAN_SURFING,    OBJ_EVENT_GFX_MAY_SURFING},
    {OBJ_EVENT_GFX_BRENDAN_UNDERWATER, OBJ_EVENT_GFX_MAY_UNDERWATER},
    {OBJ_EVENT_GFX_BRENDAN_FIELD_MOVE, OBJ_EVENT_GFX_MAY_FIELD_MOVE},
    {OBJ_EVENT_GFX_BRENDAN_FISHING,    OBJ_EVENT_GFX_MAY_FISHING},
    {OBJ_EVENT_GFX_BRENDAN_WATERING,   OBJ_EVENT_GFX_MAY_WATERING},

In object_events_graphics_info.h :
Code:
const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Artist = {0xFFFF, OBJ_EVENT_PAL_TAG_3, OBJ_EVENT_PAL_TAG_NONE, 256, 16, 32, [B]0[/B], SHADOW_SIZE_M, FALSE, FALSE, TRACKS_FOOT, &gObjectEventBaseOam_16x32, gObjectEventSpriteOamTables_16x32, gObjectEventImageAnimTable_Standard, gObjectEventPicTable_Artist, gDummySpriteAffineAnimTable};
 
Last edited:
Berry Trees No Longer Disappear (Emerald)

Once fully grown, berry trees in Gen III and IV regrow a set number of times and then disappear forever. In XY this was changed so that once they have berries on them, they stay that way until the player picks them.
To implement this in pokeemerald, go to src/berry.c and make the following changes:

In function BerryTreeGrow, remove the entire BERRY_STAGE_BERRIES case:
Spoiler:

In function BerryTreeTimeUpdate, add another condition to the first if statement (shown in bold) and remove the if statement that checks how long ago the berry tree was planted.
Spoiler:
These changes can also be viewed as a commit here.
 
Make eggs hatch at level 1 instead of 5

I noticed no one posted this already, to do this go to 'include/constants/daycare.h'

Line 17:
Code:
#define EGG_HATCH_LEVEL 5

Fairly self-explanatory lol change the 5 to 1
 
[Pokefirered] Dive

A lot of the code already existed in FR and the rest could be copied from pokeem so I didn't think this deserved its own thread. However, gamefreak decided to be super dumb and make sPlayerAvatarGfxIds inconsistent with the player avatar flags, so I ended up changing almost all of the calls to GetPlayerAvatarGraphicsIdByStateId. So I won't be posting the code changes, instead just the repo

Here's a GIF:
[PokeCommunity.com] Simple Modifications Directory


How to Add

How to customize dive sprite:
The default dive sprite is the player surfing (with no surf blob). To change this, change the OBJ_EVENT_GFX defines next to PLAYER_AVATAR_STATE_UNDERWATER in sPlayerAvatarGfxIds, as well as the second OBJ_EVENT_GFX surf defines in sPlayerAvatarGfxToStateFlag. Both of these are found in src/field_player_avatar.c

Please report any problems. I tested most of the avatar flag related stuff to make sure it worked properly, but there could be a case I overlooked.
 
Allow specifying multi-choice options in scripts (Pokeemerald):

Not sure if anyone has posted something like this.

Code Modifications:
Spoiler:


Example usage:
Spoiler:
 
[EM] Always inherit nature when holding an Everstone​

Pretty simple. At src/daycare.c search for :
if (GetBoxMonData(&daycare->mons[parent].mon, MON_DATA_HELD_ITEM) != ITEM_EVERSTONE
|| Random() >= USHRT_MAX / 2)
Then delete " / 2"

It should look like this:
if (GetBoxMonData(&daycare->mons[parent].mon, MON_DATA_HELD_ITEM) != ITEM_EVERSTONE
|| Random() >= USHRT_MAX)

Now when a parent is holding an Everstone, the offspring will inherit its nature 100% of the time (only females or Ditto tough, I'm still trying to figure how to change that).
 
(only females or Ditto tough, I'm still trying to figure how to change that).
[EM] Always inherit nature when holding an Everstone​
That's because in vanilla code Emerald checks only if female parents or Dittos to hold everstones.

Code:
static u8 GetParentToInheritNature(struct DayCare *daycare)
{
    u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);
    u16 fatherItem = GetBoxMonData(&daycare->mons[1].mon, MON_DATA_HELD_ITEM);
    if(motherItem == ITEM_EVERSTONE && fatherItem == ITEM_EVERSTONE)
    {
    	if (Random() >= USHRT_MAX / 2)
            return 0;
        else
            return 1;
    }else
    {
    	if(motherItem == ITEM_EVERSTONE)
    	{
    		return 0;
    	}
    	if(fatherItem == ITEM_EVERSTONE)
    	{
    		return 1;
    	}
    }
    return 2;
}

I also changed the code to have it return u8 instead of s32, because I didn't find any reason for it to have that.
This means _TriggerPendingDaycareEgg has to be changed. Only two lines need to be changed.
Code:
static void _TriggerPendingDaycareEgg(struct DayCare *daycare)
{
    [COLOR="DarkRed"]u8 parent;[/COLOR]
    s32 natureTries = 0;

    SeedRng2(gMain.vblankCounter2);
    parent = GetParentToInheritNature(daycare);

    // don't inherit nature
    [COLOR="DarkRed"]if (parent > 1)[/COLOR]
    {
        daycare->offspringPersonality = (Random2() << 16) | ((Random() % 0xfffe) + 1);
    }
    // inherit nature
    else
    {
        u8 wantedNature = GetNatureFromPersonality(GetBoxMonData(&daycare->mons[parent].mon, MON_DATA_PERSONALITY, NULL));
        
        u32 personality;

        do
        {
            personality = (Random2() << 16) | (Random());
            if (wantedNature == GetNatureFromPersonality(personality) && personality != 0)
                break; // found a personality with the same nature

            natureTries++;
        } while (natureTries <= 2400);

        daycare->offspringPersonality = personality;
    }

    FlagSet(FLAG_PENDING_DAYCARE_EGG);
}
 
Last edited:
[Pokeemerald] New Movement Actions

This adds new scripting movements, including walking and jumping backwards. See asm/macros/movement.inc for the names to use in scripts. New diagonal movements were not added since some diagonal movements already exist in emerald. This should also be relatively easy to add to pokefirered, if there are interested parties.
[PokeCommunity.com] Simple Modifications Directory
[PokeCommunity.com] Simple Modifications Directory


Here is the repo.

How to Add:
Credits:
jiangzhengwenjzw for the source
 
IV Checker NPC [EM]
If there's a better way to do this, please let me know! I'm rather new to decomp stuff, but wanted to try this out.​

In data\scripts.inc, add these lines:
Code:
	def_special GetHpIV
	def_special GetAtkIV
	def_special GetDefIV
	def_special GetSpAtkIV
	def_special GetSpDefIV
	def_special GetSpeedIV

In src\pokemon.c (or any file in src that has access to pokemon.h), add these lines:
Code:
u16 GetHpIV(void)
{
	return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_HP_IV, NULL);
}
u16 GetAtkIV(void)
{
	return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_ATK_IV, NULL);
}
u16 GetDefIV(void)
{
	return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_DEF_IV, NULL);
}
u16 GetSpAtkIV(void)
{
	return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPATK_IV, NULL);
}
u16 GetSpDefIV(void)
{
	return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPDEF_IV, NULL);
}
u16 GetSpeedIV(void)
{
	return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPEED_IV, NULL);
}

Then, add these scripts to whatever map's scripts.inc that you want the IV Checker to be in.
Code:
Script_IVChecker::
	lock
	faceplayer
	bufferpartymonnick 0, 0
	msgbox Text_IVChecker_1, MSGBOX_DEFAULT
	specialvar VAR_RESULT, GetHpIV
	buffernumberstring 0, VAR_RESULT
	specialvar VAR_RESULT, GetAtkIV
	buffernumberstring 1, VAR_RESULT
	specialvar VAR_RESULT, GetDefIV
	buffernumberstring 2, VAR_RESULT
	msgbox Text_IVChecker_2, MSGBOX_DEFAULT
	specialvar VAR_RESULT, GetSpAtkIV
	buffernumberstring 0, VAR_RESULT
	specialvar VAR_RESULT, GetSpDefIV
	buffernumberstring 1, VAR_RESULT
	specialvar VAR_RESULT, GetSpeedIV
	buffernumberstring 2, VAR_RESULT
	msgbox Text_IVChecker_3, MSGBOX_DEFAULT
	release
	end

Text_IVChecker_1:
	.string "Your {STR_VAR_1}...$"

Text_IVChecker_2:
	.string "Its HP IV is {STR_VAR_1}.\p"
	.string "Its Attack IV is {STR_VAR_2}.\p"
	.string "Its Defense IV is {STR_VAR_3}.$"

Text_IVChecker_3:
	.string "Its Special Attack IV is {STR_VAR_1}.\p"
	.string "Its Special Defense IV is {STR_VAR_2}.\p"
	.string "Its Speed IV is {STR_VAR_3}.\n"
	.string "You're welcome.$"

Add Script_IVChecker to an NPC (I used PoryMap to do this), and talk to the NPC. Your result should look like this!

[PokeCommunity.com] Simple Modifications Directory
 
Last edited:
[Pokeemerald] Auto-Run

Toggle an Auto-Run feature with the R-Button!
[PokeCommunity.com] Simple Modifications Directory


The repo.

Notes:
Spoiler:
 
Last edited:
in ButtonMode_DrawChoices, remove widthLA = GetStringWidth(1, gText_ButtonTypeLEqualsA, 0);, change xLR = (widthNormal - widthLR - widthLA) / 2 + 104; to xLR = (widthNormal - widthLR) / 2 + 104; (maybe? this is just an x position so you can play around with the 104 value).

I'd change it to
Code:
 DrawOptionMenuChoice(gText_ButtonTypeLR, GetStringRightAlignXOffset(1, gText_ButtonTypeLR, 198), YPOS_BUTTONMODE, styles[1]);
So that it is aligned at the right side of the screen like the rest of the options
 
Last edited:
DPPt Bike (a 2-in-1 Bike) [Em]
This is pretty nice and simple. It allows you to swap between the Mach Bike and the Acro Bike by pressing the R Button in the overworld.
The code was originally written by Blurose, so the credits go to him. I simply checked if it worked in Pokeemerald, and since it does, I decided to come and share it here with his permission.

Do note that the Mach Bike breaks with this implementation. The correct bike to use is the Acro Bike specifically.
Needless to say, things like the Sound Effect casted when swapping from a bike mode to the other or even the button you have to press to change modes can be changed as y'all see fit.

To incorporate this feature branch into your project execute the following commands:
Code:
git remote add lunos https://github.com/LOuroboros/pokeemerald
git pull lunos gen4_bike

Video:


And that's pretty much it.

Bugs:
-When entering a menu while riding a bike, the latter always resets to the Acro Bike (reported by Bidoof right here)
Fixed: https://github.com/LOuroboros/pokeemerald/commit/881b033603fa899d96e3bc9133a4afecc990f26a
 
Last edited:
Destiny Knot IV Inheritance Implementation[Em]

This should work with DizzyEgg's item_expansion repo, and should also work as long as you have ITEM_DESTINY_KNOT
All you need to edit is include/constants/daycare.h and have:
Code:
#define DESTINY_KNOT_INHERITED_IV_COUNT 5
And next, go to src/daycare.c and add this before u8 i on static void InheritIVs
Code:
    u32 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);
    u32 fatherItem = GetBoxMonData(&daycare->mons[1].mon, MON_DATA_HELD_ITEM);
    u8 inheritNum = (motherItem == ITEM_DESTINY_KNOT || fatherItem == ITEM_DESTINY_KNOT) ? DESTINY_KNOT_INHERITED_IV_COUNT: INHERITED_IV_COUNT;
Then change any instance of INHERITED_IV_COUNT in InheritIVs to inheritNum (after u8 i obviously)
That's about it. Here's the entire code for static void InheritIVs if it was difficult to follow.

Spoiler:

If someone could test this out I'd appreciate it.
 
Last edited:
If someone could test this out I'd appreciate it.
Funny enough, I was working on this last night with very similar code. For some reason, it was only inheriting 4 IVs instead of 5. I'll give your code a shot and see if it's any different.

EDIT: Tried your code instead of mine, it still only inherits 4 IVs.
Also, apologies for double-post, my first post wasn't showing. Second post is deleted.
 
Last edited:
Showing IVs/EVs in Summary Screen [EM]

All of the code for this belongs in src\pokemon_summary_screen.c.

Find sStatsLeftColumnLayout (line 773 for me) and paste this below it:
Code:
static const u8 sStatsLeftColumnLayoutIVEV[] = _("{DYNAMIC 0}\n{DYNAMIC 1}\n{DYNAMIC 2}");
This is pretty much just to get rid of the "/" in the HP value.

Old way, where the stats are shown based on holding L/R as the stats screen loads:
Spoiler:


New way, where pressing L/R/Start while on the stats screen changes the numbers to IVs/EVs/stats immediately (thanks to AkimotoBubble for their original code):
Spoiler:


If you'd like, you can use both the old and the new methods in tandem, as they don't conflict with each other. Thanks again to AkimotoBubble for their code.
 
Last edited:
Showing IVs/EVs in Summary Screen [EM]
I decided to give this a shot as I need it to showcase something, but I'm getting an error upon trying to build a ROM.
[PokeCommunity.com] Simple Modifications Directory


The branch I tried to insert the code on doesn't have Egg's nature-based colors, fwiw, so I used the respective versions of each function that you posted.

Btw, it's not something super important, but you seem to be mixing tabs and spaces for the indentation in your code. It's good practice to stick to one or the other :)
Usually, you should stick to whichever is used the most times in the file that is being modified. In the case of src/pokemon_summary_screen.c, that'd be 4 spaces.
You can check that stuff easily with something like Notepad++, by going to View > Show Symbol > Show White Space and TAB.
[PokeCommunity.com] Simple Modifications Directory


It may look just fine normally, but if you ever decide to jump to web services that make use of Git like GitHub or GitLab, you'll notice your code will look quite misaligned in your commits.
 
Last edited:
The branch I tried to insert the code on doesn't have Egg's nature-based colors, fwiw, so I used the respective versions of each function that you posted.
Oh, interesting, I have no idea where BufferStat comes from as pokemon_summary_screen.c uses something different by default. Must've been in some branch I added and I didn't notice. I'll edit the code ASAP.

EDIT: BufferStat comes from, you guessed it, the nature color mod. Code is now updated and should 100% work.

Btw, it's not something super important, but you seem to be mixing tabs and spaces for the indentation in your code. It's good practice to stick to one or the other :)
Totally didn't notice--that was caused by me jumping between Notepad++ (which is set up for spaces) and Visual Studio (tabs). I'll try to fix it next time around, thanks for pointing it out!
 
Last edited:
Setting a Pokémon's EVs with 6 Scripting Specials (Emerald/Fire Red)​
Note: This is just one of the many ways in which you can most likely implement a feature like this.

With these code changes, we'll add 6 new specials to use in a script.
What they do, is to take the values written in the Vars 0x8000, 0x8001, 0x8002, 0x8003, 0x8005 and 0x8006 and rewrite the EVs of the Pokémon stored in the var 0x8004 accordingly.
Each special uses one of these 6 vars, and each one of them affect a specific Pokémon's stat, as you can tell by looking at the code.

Without further ado:
https://github.com/LOuroboros/pokeemerald/commit/0d418ab3a1070e8f36c5ba3513bba8549f0571a8

For reference, I also decided to throw in a script that I wrote showing how do I use them.
https://github.com/LOuroboros/pokeemerald/commit/4f0efab900f03876c67775ff98d4d02366fc75b1

It can be called by adding call SetEVs in a script and it's pretty simple to understand how it works.
special ChoosePartyMon makes the Player select a Pokémon whose slot in the party gets stored in the var 0x8004, then I set the values of the vars 0x8000, 0x8001, 0x8002, 0x8003, 0x8005 and 0x8006 to 252, and then I proceed to call the 6 specials that will affect the EVs of the Pokémon in the party slot that was chosen according to the values of the aforementioned vars.
The script won't work if the Player decided to cancel while in the Choose Pokémon screen, or if they chose an Egg.
And naturally, y'all can change the amount of EVs that are being set as you see fit.

Here's a quick video showing it off, thanks to the feature written and posted above by PokemonCrazy.


And that's pretty much it.​
 
Last edited:
[Pokeemerald] Change Object Event Movement Type in Real Time

I was searching for a way to change NPCs movement type in a script, and found none, so I decided to write my own. Its pretty simple:
  • Add the following code to src/event_object_movement.c
    Code:
    void SetObjectMovementType(void)
    {
        struct ObjectEvent *objectEvent = &gObjectEvents[GetObjectEventIdByLocalId(gSpecialVar_0x8005)];
        u8 movementType = gSpecialVar_0x8006;
        
        objectEvent->movementType = movementType;
        objectEvent->directionSequenceIndex = 0;
        objectEvent->playerCopyableMovement = 0;
        gSprites[objectEvent->spriteId].callback = sMovementTypeCallbacks[movementType];
        gSprites[objectEvent->spriteId].data[1] = 0;
    }

    Then add the following to the end of data/specials.inc
    Code:
    def_special SetObjectMovementType

How to Use:
Code:
lock    @ lock and release are needed to get the movement types to work with applymovement. (Or ScriptMovement_UnfreezeObjectEvents(); in the function - credit to Disturbo for testing this)
setvar VAR_0x8005, "localId"   @the local Id of the object event in question ("event_object Id" field in porymap)
setvar VAR_0x8006, "movementType"   @the movement type to change to (eg. MOVEMENT_TYPE_WANDER_AROUND)
special  SetObjectMovementType
release

Here's a macro you can throw into events.inc, and you can just call setobjectnewmovementtype "localId", "movementType" to the same as above:
Code:
    .macro setobjectnewmovementtype localId:req, movementType:req
    setvar VAR_0x8005, \localId
    setvar VAR_0x8006, \movementType
    special SetObjectMovementType
    .endm
 
Last edited:
Back
Top