Egg Type Palettes by Lunos - pret/pokeemerald GitHub Wiki

Lunos' Egg Type Palettes:

This code comes from Lunos / LOuroboros, with a note of thanks to Citrus Bolt. I only updated a small part of the code to make it compatible with the latest pokeemerald code.
original commit

This code adds different color palettes to a Pokemon Egg dependant on the species type.

Abra egg Pichu egg Bulbasaur egg Charmander egg Squirtle egg

To use this with an up-to-date pokeemerald:

Pull Lunos' branch or manually input from the compare

git remote add lunos https://github.com/LOuroboros/pokeemerald.git
git pull lunos egg_type_pal

Then manually make the changes below or pull from my branch:

git remote add tenaya15 https://github.com/tenaya15/tenaya15emerald.git
git pull tenaya15 egg_palettes

quick notes:

1: gBaseStats is now called gSpeciesInfo
2: .type1 is now .types[0]
3: .type2 is now .types[1]
4: gflib/sprite.h is found at include/sprite.h on up-to-date pokeemerald 5: gflib/sprite.c is now found at src/sprite.c on up-to-date pokeemerald


src/crt0.s

add at line 5

	.4byte gEgg1PaletteTable
	.4byte gEgg2PaletteTable

-- Judicorn's note: I'm not sure if this is needed anymore, as the code from this file no longer has this kind of data.
the code compiles and appears to look fine when testing whether these lines are present or not.


src/data/graphics/pokemon.h

-- only change this file if you use INCGFX_* and no longer use the file spritesheet_rules.mk

change all the gMonPalette_Egg_* lines to

const u32 gMonPalette_Egg_Normal1[] = INCGFX_U32("graphics/pokemon/egg/types/normal1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Normal2[] = INCGFX_U32("graphics/pokemon/egg/types/normal2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Fighting1[] = INCGFX_U32("graphics/pokemon/egg/types/fighting1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Fighting2[] = INCGFX_U32("graphics/pokemon/egg/types/fighting2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Flying1[] = INCGFX_U32("graphics/pokemon/egg/types/flying1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Flying2[] = INCGFX_U32("graphics/pokemon/egg/types/flying2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Poison1[] = INCGFX_U32("graphics/pokemon/egg/types/poison1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Poison2[] = INCGFX_U32("graphics/pokemon/egg/types/poison2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Ground1[] = INCGFX_U32("graphics/pokemon/egg/types/ground1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Ground2[] = INCGFX_U32("graphics/pokemon/egg/types/ground2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Rock1[] = INCGFX_U32("graphics/pokemon/egg/types/rock1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Rock2[] = INCGFX_U32("graphics/pokemon/egg/types/rock2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Bug1[] = INCGFX_U32("graphics/pokemon/egg/types/bug1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Bug2[] = INCGFX_U32("graphics/pokemon/egg/types/bug2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Ghost1[] = INCGFX_U32("graphics/pokemon/egg/types/ghost1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Ghost2[] = INCGFX_U32("graphics/pokemon/egg/types/ghost2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Steel1[] = INCGFX_U32("graphics/pokemon/egg/types/steel1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Steel2[] = INCGFX_U32("graphics/pokemon/egg/types/steel2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Fire1[] = INCGFX_U32("graphics/pokemon/egg/types/fire1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Fire2[] = INCGFX_U32("graphics/pokemon/egg/types/fire2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Water1[] = INCGFX_U32("graphics/pokemon/egg/types/water1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Water2[] = INCGFX_U32("graphics/pokemon/egg/types/water2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Grass1[] = INCGFX_U32("graphics/pokemon/egg/types/grass1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Grass2[] = INCGFX_U32("graphics/pokemon/egg/types/grass2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Electric1[] = INCGFX_U32("graphics/pokemon/egg/types/electric1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Electric2[] = INCGFX_U32("graphics/pokemon/egg/types/electric2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Psychic1[] = INCGFX_U32("graphics/pokemon/egg/types/psychic1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Psychic2[] = INCGFX_U32("graphics/pokemon/egg/types/psychic2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Ice1[] = INCGFX_U32("graphics/pokemon/egg/types/ice1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Ice2[] = INCGFX_U32("graphics/pokemon/egg/types/ice2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Dragon1[] = INCGFX_U32("graphics/pokemon/egg/types/dragon1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Dragon2[] = INCGFX_U32("graphics/pokemon/egg/types/dragon2.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Dark1[] = INCGFX_U32("graphics/pokemon/egg/types/dark1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Dark2[] = INCGFX_U32("graphics/pokemon/egg/types/dark2.pal", ".gbapal.lz");

#ifdef TYPE_FAIRY
const u32 gMonPalette_Egg_Fairy1[] = INCGFX_U32("graphics/pokemon/egg/types/fairy1.pal", ".gbapal.lz");
const u32 gMonPalette_Egg_Fairy2[] = INCGFX_U32("graphics/pokemon/egg/types/fairy2.pal", ".gbapal.lz");
#endif

include/decompress.h

add after line 15 void LoadCompressedSpritePalette(const...):

void LoadCompressedEggSpritePalette(const struct CompressedSpritePalette *src1, const struct CompressedSpritePalette *src2);
void LoadCompressedEggHatchSpritePalette(const struct CompressedSpritePalette *src1, const struct CompressedSpritePalette *src2);

you should then have void LoadCompressedSpritePaletteOverrideBuffer(const... on the next line
so lines 15 to 19 should be:
void LoadCompressedSpritePalette(const struct CompressedSpritePalette *src);
void LoadCompressedEggSpritePalette(const struct CompressedSpritePalette *src1, const struct CompressedSpritePalette *src2);
void LoadCompressedEggHatchSpritePalette(const struct CompressedSpritePalette *src1, const struct CompressedSpritePalette *src2);
void LoadCompressedSpritePaletteOverrideBuffer(const struct CompressedSpritePalette *src, void *buffer);
bool8 LoadCompressedSpritePaletteUsingHeap(const struct CompressedSpritePalette *src);


src/decompress.c

add after section void LoadCompressedSpritePalette(const...

void LoadCompressedEggSpritePalette(const struct CompressedSpritePalette *src1, const struct CompressedSpritePalette *src2)
{
    struct SpritePalette dest1, dest2;
    u8 eggBuffer[0x2200]; // Originally 0x2000, but for whatever reason, that doesn't work well in vanilla.

    LZ77UnCompWram(src1->data, gDecompressionBuffer);
    dest1.data = (void*) gDecompressionBuffer;
    dest1.tag = src1->tag;
    LZ77UnCompWram(src2->data, eggBuffer);
    dest2.data = (void*) eggBuffer;
    dest2.tag = src2->tag;
    LoadEggSpritePalette(&dest1, &dest2);
}

void LoadCompressedEggHatchSpritePalette(const struct CompressedSpritePalette *src1, const struct CompressedSpritePalette *src2)
{
    struct SpritePalette dest1, dest2;
    u8 eggBuffer[0x2200]; // Originally 0x2000, but for whatever reason, that doesn't work well in vanilla.

    LZ77UnCompWram(src1->data, gDecompressionBuffer);
    dest1.data = (void*) gDecompressionBuffer;
    dest1.tag = 54321;
    LZ77UnCompWram(src2->data, eggBuffer);
    dest2.data = (void*) eggBuffer;
    dest2.tag = src2->tag;
    LoadEggSpritePalette(&dest1, &dest2);
}

(you should then have void LoadCompressedSpritePaletteOverrideBuffer(const... on the next line)


src/pokemon_summary_screen.c

in section static void SetMonTypeIcons(void)
replace the entire section with:

{
    struct PokeSummary *summary = &sMonSummaryScreen->summary;
        SetTypeSpritePosAndPal(gSpeciesInfo[summary->species].types[0], 120, 48, SPRITE_ARR_ID_TYPE);
        if (gSpeciesInfo[summary->species].types[0] != gSpeciesInfo[summary->species].types[1])
        {
            SetTypeSpritePosAndPal(gSpeciesInfo[summary->species].types[1], 160, 48, SPRITE_ARR_ID_TYPE + 1);
            SetSpriteInvisibility(SPRITE_ARR_ID_TYPE + 1, FALSE);
        }
        else
        {
            SetSpriteInvisibility(SPRITE_ARR_ID_TYPE + 1, TRUE);
        }
}

in section static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state)
replace the case 1: section (line 3947 if (!summary->isEgg) to line 3951 return 0xFF;) with:

        if (!summary->isEgg)
        {
            pal1 = GetMonSpritePalStructFromOtIdPersonality(summary->species2, summary->OTID, summary->pid);
            LoadCompressedSpritePalette(pal1);
        }
        else
        {
            pal1 = &gEgg1PaletteTable[gSpeciesInfo[summary->species].types[0]];
            pal2 = &gEgg2PaletteTable[gSpeciesInfo[summary->species].types[1]];
            LoadCompressedEggSpritePalette(pal1, pal2);
        }
        SetMultiuseSpriteTemplateToPokemon(pal1->tag, B_POSITION_OPPONENT_LEFT);
        (*state)++;
        return 0xFF;

gflib/sprite.c OR src/sprite.c

This part differs depending on if you use an older version of pokeemerald that still uses gflib or an updated version.

if your decomp has the folder gflib, input this to gflib/sprite.c
if you have an up-to-date version, input to src/sprite.c instead

OLD VERSION OF POKEEMERALD: gflib/sprite.c add around line 94 (after static void DoLoadSpritePalette(const...):

static void DoLoadSpriteShortPalette(const u16 *src, u16 paletteOffset);

(you should then have static void obj_update_pos2(struct... on the next line)

__

If you use an updated version of pokeemerald:
input to file src/sprite.c
add around line 94 (after static void DoLoadSpritePalette(const...):

static void DoLoadSpriteShortPalette(const u16 *src, u16 paletteOffset);
//NOT USED static void obj_update_pos2(struct Sprite* sprite, s32 a1, s32 a2); 

(you should then have static void UpdateSpriteMatrixAnchorPos(struct... on the next line)


src/egg_hatch.c

rename line 490: static void CB2_EggHatch_0(void) (around line 490) to:

static void CB2_LoadEggHatch(void)

__

in section static void CB2_LoadEggHatch(void), in case 3: (around line 540) replace all with:

        LoadSpriteSheet(&sEggHatch_Sheet);
        LoadSpriteSheet(&sEggShards_Sheet);
        //LoadSpritePalette(&sEgg_SpritePalette);
        pal1 = &gEgg1PaletteTable[gSpeciesInfo[GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES)].types[0]];
        pal2 = &gEgg2PaletteTable[gSpeciesInfo[GetMonData(&gPlayerParty[sEggHatchData->eggPartyID], MON_DATA_SPECIES)].types[1]];
        LoadCompressedEggHatchSpritePalette(pal1, pal2);
        gMain.state++;
        break; 

__

src/pokemon_storage_system.c

in section static void SetDisplayMonData(void *pokemon, u8 mode)
Around lines 6898 and 6899
change:

sStorage->filler2[0] = gBaseStats[GetMonData(mon, MON_DATA_SPECIES)].type1;
sStorage->filler2[1] = gBaseStats[GetMonData(mon, MON_DATA_SPECIES)].type2;
to:

            sStorage->filler2[0] = gSpeciesInfo[GetMonData(mon, MON_DATA_SPECIES)].types[0];
            sStorage->filler2[1] = gSpeciesInfo[GetMonData(mon, MON_DATA_SPECIES)].types[1];

then around lines 6924 and 6925
change:

sStorage->filler2[0] = gBaseStats[GetBoxMonData(boxMon, MON_DATA_SPECIES)].type1;
sStorage->filler2[1] = gBaseStats[GetBoxMonData(boxMon, MON_DATA_SPECIES)].type2;
to:

            sStorage->filler2[0] = gSpeciesInfo[GetBoxMonData(boxMon, MON_DATA_SPECIES)].types[0];
            sStorage->filler2[1] = gSpeciesInfo[GetBoxMonData(boxMon, MON_DATA_SPECIES)].types[1];