Add support for species unique eggs (#8557)

This commit is contained in:
hedara90 2025-12-17 16:10:02 +01:00 committed by GitHub
parent bf0e1b1a86
commit 773ca1fde8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 270 additions and 88 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

View File

@ -0,0 +1,12 @@
#ifndef GUARD_EGG_IDS_H
#define GUARD_EGG_IDS_H
// IDs for species with custom eggs
enum EggIds
{
EGG_ID_NONE,
EGG_ID_MANAPHY,
EGG_ID_COUNT
};
#endif // GUARD_EGG_IDS_H

View File

@ -209,6 +209,8 @@ extern const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT];
extern const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT];
extern const struct EggData gEggDatas[EGG_ID_COUNT];
// Follower text messages
extern const struct FollowerMsgInfo gFollowerHappyMessages[];
extern const struct FollowerMsgInfo gFollowerNeutralMessages[];

View File

@ -77,8 +77,10 @@ bool8 LoadCompressedSpriteSheetUsingHeap(const struct CompressedSpriteSheet *src
void DecompressPicFromTable(const struct CompressedSpriteSheet *src, void *buffer);
void HandleLoadSpecialPokePic(bool32 isFrontPic, void *dest, s32 species, u32 personality);
void HandleLoadSpecialPokePicIsEgg(bool32 isFrontPic, void *dest, s32 species, u32 personality, bool32 isEgg);
void LoadSpecialPokePic(void *dest, s32 species, u32 personality, bool8 isFrontPic);
void LoadSpecialPokePicIsEgg(void *dest, s32 species, u32 personality, bool8 isFrontPic, bool32 isEgg);
u32 GetDecompressedDataSize(const u32 *ptr);
bool32 IsCompressedData(const u32 *ptr);

View File

@ -5,6 +5,7 @@
#include "sprite.h"
#include "constants/battle.h"
#include "constants/cries.h"
#include "constants/egg_ids.h"
#include "constants/form_change_types.h"
#include "constants/hold_effects.h"
#include "constants/items.h"
@ -491,7 +492,7 @@ struct SpeciesInfo /*0xC4*/
s8 enemyShadowYOffset; // This determines the Y-offset for an enemy Pokémon's shadow during battle; negative values point up, positive values point down.
u16 enemyShadowSize:3; // This determines the size of the shadow sprite used for an enemy Pokémon's front sprite during battle.
u16 suppressEnemyShadow:1; // If set to true, then a shadow will not be drawn beneath an enemy Pokémon's front sprite during battle.
u16 padding5:12;
enum EggIds eggId:12;
// Move Data
const struct LevelUpMove *levelUpLearnset;
const u16 *teachableLearnset;
@ -515,6 +516,17 @@ struct SpeciesInfo /*0xC4*/
#endif //OW_POKEMON_OBJECT_EVENTS
};
struct EggData
{
const u8 *eggIcon;
const u32 *eggSprite;
const u16 *eggPalette;
const u32 *eggHatchGfx;
const u16 *eggHatchPal;
const u32 *eggShardsGfx;
const u8 eggIconPalIndex;
};
struct AbilityInfo
{
u8 name[ABILITY_NAME_LENGTH + 1];
@ -835,7 +847,9 @@ void PlayMapChosenOrBattleBGM(u16 songId);
void CreateTask_PlayMapChosenOrBattleBGM(u16 songId);
const u16 *GetMonFrontSpritePal(struct Pokemon *mon);
const u16 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, bool32 isShiny, u32 personality);
const u16 *GetMonSpritePalFromSpeciesAndPersonalityIsEgg(u16 species, bool32 isShiny, u32 personality, bool32 isEgg);
const u16 *GetMonSpritePalFromSpecies(u16 species, bool32 isShiny, bool32 isFemale);
const u16 *GetMonSpritePalFromSpeciesIsEgg(u16 species, bool32 isShiny, bool32 isFemale, bool32 isEgg);
bool32 IsMoveHM(u16 move);
bool32 CannotForgetMove(u16 move);
bool8 IsMonSpriteNotFlipped(u16 species);

View File

@ -4,9 +4,11 @@
extern const struct SpritePalette gMonIconPaletteTable[];
const u8 *GetMonIconTiles(u16 species, u32 personality);
const u8 *GetMonIconTilesIsEgg(u16 species, u32 personality, bool32 isEgg);
void TryLoadAllMonIconPalettesAtOffset(u16 offset);
u8 GetValidMonIconPalIndex(u16 species);
const u8 *GetMonIconPtr(u16 species, u32 personality);
const u8 *GetMonIconPtrIsEgg(u16 species, u32 personality, bool32 isEgg);
const u16 *GetValidMonIconPalettePtr(u16 species);
u16 GetIconSpecies(u16 species, u32 personality);
u16 GetUnownLetterByPersonality(u32 personality);
@ -15,9 +17,11 @@ void LoadMonIconPalettes(void);
void LoadMonIconPalette(u16 species);
void FreeMonIconPalettes(void);
u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority);
u8 CreateMonIconNoPersonalityIsEgg(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, bool32 isEgg);
void FreeMonIconPalette(u16 species);
void FreeAndDestroyMonIconSprite(struct Sprite *sprite);
u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality);
u8 CreateMonIconIsEgg(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool32 isEgg);
u8 UpdateMonIconFrame(struct Sprite *sprite);
void LoadMonIconPalette(u16 species);
void LoadMonIconPalettePersonality(u16 species, u32 personality);

View File

@ -15735,6 +15735,11 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
const u32 gMonBackPic_Manaphy[] = INCBIN_U32("graphics/pokemon/manaphy/back.4bpp.smol");
const u16 gMonShinyPalette_Manaphy[] = INCBIN_U16("graphics/pokemon/manaphy/shiny.gbapal");
const u8 gMonIcon_Manaphy[] = INCBIN_U8("graphics/pokemon/manaphy/icon.4bpp");
const u8 gMonEggIcon_Manaphy[] = INCBIN_U8("graphics/pokemon/manaphy/icon_egg.4bpp");
const u32 gMonEggGfx_Manaphy[] = INCBIN_U32("graphics/pokemon/manaphy/egg_sprite.4bpp.smol");
const u16 gMonEggPal_Manaphy[] = INCBIN_U16("graphics/pokemon/manaphy/egg_sprite.gbapal");
const u32 gMonHatchGfx_Manaphy[] = INCBIN_U32("graphics/pokemon/manaphy/hatch.4bpp.smol");
const u16 gMonHatchPal_Manaphy[] = INCBIN_U16("graphics/pokemon/manaphy/hatch.gbapal");
#if P_FOOTPRINTS
const u8 gMonFootprint_Manaphy[] = INCBIN_U8("graphics/pokemon/manaphy/footprint.1bpp");
#endif //P_FOOTPRINTS

View File

@ -0,0 +1,9 @@
[EGG_ID_MANAPHY] =
{
.eggIcon = gMonEggIcon_Manaphy,
.eggSprite = gMonEggGfx_Manaphy,
.eggPalette = gMonEggPal_Manaphy,
.eggHatchGfx = gMonHatchGfx_Manaphy,
.eggHatchPal = gMonHatchPal_Manaphy,
.eggIconPalIndex = 2,
},

View File

@ -246,3 +246,8 @@ const struct SpeciesInfo gSpeciesInfo[] =
},
*/
};
const struct EggData gEggDatas[EGG_ID_COUNT] =
{
#include "egg_data.h"
};

View File

@ -7176,6 +7176,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
.perfectIVCount = LEGENDARY_PERFECT_IV_COUNT,
.levelUpLearnset = sManaphyLevelUpLearnset,
.teachableLearnset = sManaphyTeachableLearnset,
.eggId = EGG_ID_MANAPHY,
},
#endif //P_FAMILY_MANAPHY

View File

@ -251,7 +251,12 @@ void DecompressPicFromTable(const struct CompressedSpriteSheet *src, void *buffe
void HandleLoadSpecialPokePic(bool32 isFrontPic, void *dest, s32 species, u32 personality)
{
LoadSpecialPokePic(dest, species, personality, isFrontPic);
LoadSpecialPokePicIsEgg(dest, species, personality, isFrontPic, FALSE);
}
void HandleLoadSpecialPokePicIsEgg(bool32 isFrontPic, void *dest, s32 species, u32 personality, bool32 isEgg)
{
LoadSpecialPokePicIsEgg(dest, species, personality, isFrontPic, isEgg);
}
// Wrapper function for all decompression calls using formats with headers
@ -1125,12 +1130,24 @@ static bool32 isModeSymDelta(enum CompressionMode mode)
}
void LoadSpecialPokePic(void *dest, s32 species, u32 personality, bool8 isFrontPic)
{
LoadSpecialPokePicIsEgg(dest, species, personality, isFrontPic, FALSE);
}
void LoadSpecialPokePicIsEgg(void *dest, s32 species, u32 personality, bool8 isFrontPic, bool32 isEgg)
{
species = SanitizeSpeciesId(species);
if (species == SPECIES_UNOWN)
species = GetUnownSpeciesId(personality);
if (isFrontPic)
if (isEgg)
{
if (gSpeciesInfo[species].eggId != EGG_ID_NONE)
DecompressDataWithHeaderWram(gEggDatas[gSpeciesInfo[species].eggId].eggSprite, dest);
else
DecompressDataWithHeaderWram(gSpeciesInfo[SPECIES_EGG].frontPic, dest);
}
else if (isFrontPic)
{
#if P_GENDER_DIFFERENCES
if (gSpeciesInfo[species].frontPicFemale != NULL && IsPersonalityFemale(species, personality))

View File

@ -440,9 +440,9 @@ static u8 EggHatchCreateMonSprite(u8 useAlt, u8 state, u8 partyId, u16 *speciesL
// Load mon sprite gfx
{
u32 pid = GetMonData(mon, MON_DATA_PERSONALITY);
HandleLoadSpecialPokePic(TRUE,
HandleLoadSpecialPokePicIsEgg(TRUE,
gMonSpritesGfxPtr->spritesGfx[(useAlt * 2) + B_POSITION_OPPONENT_LEFT],
species, pid);
species, pid, FALSE);
LoadSpritePaletteWithTag(GetMonFrontSpritePal(mon), species);
*speciesLoc = species;
}
@ -532,11 +532,43 @@ static void CB2_LoadEggHatch(void)
gMain.state++;
break;
case 3:
LoadSpriteSheet(&sEggHatch_Sheet);
LoadSpriteSheet(&sEggShards_Sheet);
LoadSpritePalette(&sEgg_SpritePalette);
{
u32 species = GetMonData(&gPlayerParty[sEggHatchData->eggPartyId], MON_DATA_SPECIES);
if (gSpeciesInfo[species].eggId != EGG_ID_NONE)
{
u32 *tempSprite = malloc_and_decompress(gEggDatas[gSpeciesInfo[species].eggId].eggHatchGfx, NULL);
struct SpriteSheet tempSheet;
tempSheet.data = tempSprite;
tempSheet.size = 2048;
tempSheet.tag = GFXTAG_EGG;
LoadSpriteSheet(&tempSheet);
Free(tempSprite);
struct SpritePalette tempPal;
tempPal.data = gEggDatas[gSpeciesInfo[species].eggId].eggHatchPal;
tempPal.tag = PALTAG_EGG;
LoadSpritePalette(&tempPal);
if (gEggDatas[gSpeciesInfo[species].eggId].eggShardsGfx != NULL)
{
tempSheet.data = gEggDatas[gSpeciesInfo[species].eggId].eggShardsGfx;
tempSheet.size = 128;
tempSheet.tag = GFXTAG_EGG_SHARD;
LoadSpriteSheet(&tempSheet);
}
else
{
LoadSpriteSheet(&sEggShards_Sheet);
}
}
else
{
LoadSpriteSheet(&sEggHatch_Sheet);
LoadSpriteSheet(&sEggShards_Sheet);
LoadSpritePalette(&sEgg_SpritePalette);
}
gMain.state++;
break;
}
case 4:
CopyBgTilemapBufferToVram(0);
AddHatchedMonToParty(sEggHatchData->eggPartyId);

View File

@ -1076,12 +1076,13 @@ void GetConditionMenuMonGfx(void *tilesDst, void *palDst, u16 boxId, u16 monId,
if (partyId != numMons)
{
u16 species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES_OR_EGG, NULL);
u16 species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES, NULL);
bool8 isShiny = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_SHINY, NULL);
u32 personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
bool32 isEgg = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_EGG, NULL);
LoadSpecialPokePic(tilesDst, species, personality, TRUE);
memcpy(palDst, GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), 32);
LoadSpecialPokePicIsEgg(tilesDst, species, personality, TRUE, isEgg);
memcpy(palDst, GetMonSpritePalFromSpeciesAndPersonalityIsEgg(species, isShiny, personality, isEgg), 32);
}
}

View File

@ -286,7 +286,7 @@ static void DisplayPartyPokemonGender(u8, u16, u8 *, struct PartyMenuBox *);
static void DisplayPartyPokemonHP(u16 hp, u16 maxHp, struct PartyMenuBox *menuBox);
static void DisplayPartyPokemonMaxHP(u16, struct PartyMenuBox *);
static void DisplayPartyPokemonHPBar(u16, u16, struct PartyMenuBox *);
static void CreatePartyMonIconSpriteParameterized(u16, u32, struct PartyMenuBox *, u8);
static void CreatePartyMonIconSpriteParameterized(u16 species, u32 pid, bool32 isEgg, struct PartyMenuBox *menuBox, u8 priority);
static void CreatePartyMonHeldItemSpriteParameterized(u16, u16, struct PartyMenuBox *);
static void CreatePartyMonPokeballSpriteParameterized(u16, struct PartyMenuBox *);
static void CreatePartyMonStatusSpriteParameterized(u16, u8, struct PartyMenuBox *);
@ -1232,7 +1232,7 @@ static void CreatePartyMonSprites(u8 slot)
if (gMultiPartnerParty[actualSlot].species != SPECIES_NONE)
{
CreatePartyMonIconSpriteParameterized(gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].personality, &sPartyMenuBoxes[slot], 0);
CreatePartyMonIconSpriteParameterized(gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].personality, FALSE, &sPartyMenuBoxes[slot], 0);
CreatePartyMonHeldItemSpriteParameterized(gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].heldItem, &sPartyMenuBoxes[slot]);
CreatePartyMonPokeballSpriteParameterized(gMultiPartnerParty[actualSlot].species, &sPartyMenuBoxes[slot]);
if (gMultiPartnerParty[actualSlot].hp == 0)
@ -4313,18 +4313,17 @@ bool32 SetUpFieldMove_Dive(void)
static void CreatePartyMonIconSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox, u32 slot)
{
u16 species2;
species2 = GetMonData(mon, MON_DATA_SPECIES_OR_EGG);
CreatePartyMonIconSpriteParameterized(species2, GetMonData(mon, MON_DATA_PERSONALITY), menuBox, 1);
u32 species = GetMonData(mon, MON_DATA_SPECIES);
bool32 isEgg = GetMonData(mon, MON_DATA_IS_EGG);
CreatePartyMonIconSpriteParameterized(species, GetMonData(mon, MON_DATA_PERSONALITY), isEgg, menuBox, 1);
UpdatePartyMonHPBar(menuBox->monSpriteId, mon);
}
static void CreatePartyMonIconSpriteParameterized(u16 species, u32 pid, struct PartyMenuBox *menuBox, u8 priority)
static void CreatePartyMonIconSpriteParameterized(u16 species, u32 pid, bool32 isEgg, struct PartyMenuBox *menuBox, u8 priority)
{
if (species != SPECIES_NONE)
{
menuBox->monSpriteId = CreateMonIcon(species, SpriteCB_MonIcon, menuBox->spriteCoords[0], menuBox->spriteCoords[1], 4, pid);
menuBox->monSpriteId = CreateMonIconIsEgg(species, SpriteCB_MonIcon, menuBox->spriteCoords[0], menuBox->spriteCoords[1], 4, pid, isEgg);
gSprites[menuBox->monSpriteId].oam.priority = priority;
}
}
@ -6702,7 +6701,7 @@ static void Task_TryItemUseFormChange(u8 taskId)
if (gTasks[taskId].tAnimWait == 0)
{
FreeAndDestroyMonIconSprite(icon);
CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), &sPartyMenuBoxes[gPartyMenu.slotId], 1);
CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), FALSE, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
icon->oam.mosaic = TRUE;
icon->data[0] = 10;
icon->data[1] = 1;
@ -6910,7 +6909,7 @@ void TryItemHoldFormChange(struct Pokemon *mon, s8 slotId)
PlayCry_NormalNoDucking(targetSpecies, 0, CRY_VOLUME_RS, CRY_VOLUME_RS);
SetMonData(mon, MON_DATA_SPECIES, &targetSpecies);
FreeAndDestroyMonIconSprite(&gSprites[sPartyMenuBoxes[slotId].monSpriteId]);
CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), &sPartyMenuBoxes[slotId], 1);
CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), FALSE, &sPartyMenuBoxes[slotId], 1);
CalculateMonStats(mon);
UpdatePartyMonHeldItemSprite(mon, &sPartyMenuBoxes[slotId]);
}

View File

@ -6184,22 +6184,40 @@ static void Task_PlayMapChosenOrBattleBGM(u8 taskId)
const u16 *GetMonFrontSpritePal(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, NULL);
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
bool32 isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL);
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
return GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality);
bool32 isEgg = GetMonData(mon, MON_DATA_IS_EGG, NULL);
return GetMonSpritePalFromSpeciesAndPersonalityIsEgg(species, isShiny, personality, isEgg);
}
const u16 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, bool32 isShiny, u32 personality)
{
return GetMonSpritePalFromSpecies(species, isShiny, IsPersonalityFemale(species, personality));
return GetMonSpritePalFromSpeciesIsEgg(species, isShiny, IsPersonalityFemale(species, personality), FALSE);
}
const u16 *GetMonSpritePalFromSpeciesAndPersonalityIsEgg(u16 species, bool32 isShiny, u32 personality, bool32 isEgg)
{
return GetMonSpritePalFromSpeciesIsEgg(species, isShiny, IsPersonalityFemale(species, personality), isEgg);
}
const u16 *GetMonSpritePalFromSpecies(u16 species, bool32 isShiny, bool32 isFemale)
{
return GetMonSpritePalFromSpeciesIsEgg(species, isShiny, isFemale, FALSE);
}
const u16 *GetMonSpritePalFromSpeciesIsEgg(u16 species, bool32 isShiny, bool32 isFemale, bool32 isEgg)
{
species = SanitizeSpeciesId(species);
if (isShiny)
if (isEgg)
{
if (gSpeciesInfo[species].eggId != EGG_ID_NONE)
return gEggDatas[gSpeciesInfo[species].eggId].eggPalette;
else
return gSpeciesInfo[SPECIES_EGG].palette;
}
else if (isShiny)
{
#if P_GENDER_DIFFERENCES
if (gSpeciesInfo[species].shinyPaletteFemale != NULL && isFemale)

View File

@ -135,12 +135,17 @@ static const u16 sSpriteImageSizes[3][4] =
};
u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality)
{
return CreateMonIconIsEgg(species, callback, x, y, subpriority, personality, FALSE);
}
u8 CreateMonIconIsEgg(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool32 isEgg)
{
u8 spriteId;
struct MonIconSpriteTemplate iconTemplate =
{
.oam = &sMonIconOamData,
.image = GetMonIconPtr(species, personality),
.image = GetMonIconPtrIsEgg(species, personality, isEgg),
.anims = sMonIconAnims,
.affineAnims = sMonIconAffineAnims,
.callback = callback,
@ -148,11 +153,22 @@ u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u
};
species = SanitizeSpeciesId(species);
if (species > NUM_SPECIES)
if (isEgg)
{
if (gSpeciesInfo[species].eggId != EGG_ID_NONE)
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gEggDatas[gSpeciesInfo[species].eggId].eggIconPalIndex;
else
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gSpeciesInfo[SPECIES_EGG].iconPalIndex;
}
else if (species > NUM_SPECIES)
{
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG;
}
#if P_GENDER_DIFFERENCES
else if (gSpeciesInfo[species].iconSpriteFemale != NULL && IsPersonalityFemale(species, personality))
{
iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG + gSpeciesInfo[species].iconPalIndexFemale;
}
#endif
spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
@ -164,6 +180,10 @@ u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u
u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority)
{
return CreateMonIconNoPersonalityIsEgg(species, callback, x, y, subpriority, FALSE);
}
u8 CreateMonIconNoPersonalityIsEgg(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, bool32 isEgg)
{
u8 spriteId;
struct MonIconSpriteTemplate iconTemplate =
@ -176,7 +196,7 @@ u8 CreateMonIconNoPersonality(u16 species, void (*callback)(struct Sprite *), s1
.paletteTag = POKE_ICON_BASE_PAL_TAG + gSpeciesInfo[species].iconPalIndex,
};
iconTemplate.image = GetMonIconTiles(species, 0);
iconTemplate.image = GetMonIconTilesIsEgg(species, 0, isEgg);
spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
UpdateMonIconFrame(&gSprites[spriteId]);
@ -211,7 +231,12 @@ u16 GetIconSpeciesNoPersonality(u16 species)
const u8 *GetMonIconPtr(u16 species, u32 personality)
{
return GetMonIconTiles(GetIconSpecies(species, personality), personality);
return GetMonIconPtrIsEgg(species, personality, FALSE);
}
const u8 *GetMonIconPtrIsEgg(u16 species, u32 personality, bool32 isEgg)
{
return GetMonIconTilesIsEgg(GetIconSpecies(species, personality), personality, isEgg);
}
void FreeAndDestroyMonIconSprite(struct Sprite *sprite)
@ -284,21 +309,36 @@ void SpriteCB_MonIcon(struct Sprite *sprite)
}
const u8 *GetMonIconTiles(u16 species, u32 personality)
{
return GetMonIconTilesIsEgg(species, personality, FALSE);
}
const u8 *GetMonIconTilesIsEgg(u16 species, u32 personality, bool32 isEgg)
{
const u8 *iconSprite;
if (species > NUM_SPECIES)
species = SPECIES_NONE;
if (isEgg)
{
if (gSpeciesInfo[species].eggId != EGG_ID_NONE)
iconSprite = gEggDatas[gSpeciesInfo[species].eggId].eggIcon;
else
iconSprite = gSpeciesInfo[SPECIES_EGG].iconSprite;
}
else
{
#if P_GENDER_DIFFERENCES
if (gSpeciesInfo[species].iconSpriteFemale != NULL && IsPersonalityFemale(species, personality))
iconSprite = gSpeciesInfo[species].iconSpriteFemale;
else
if (gSpeciesInfo[species].iconSpriteFemale != NULL && IsPersonalityFemale(species, personality))
iconSprite = gSpeciesInfo[species].iconSpriteFemale;
else
#endif
if (gSpeciesInfo[species].iconSprite != NULL)
iconSprite = gSpeciesInfo[species].iconSprite;
else
iconSprite = gSpeciesInfo[SPECIES_NONE].iconSprite;
if (gSpeciesInfo[species].iconSprite != NULL)
iconSprite = gSpeciesInfo[species].iconSprite;
else
iconSprite = gSpeciesInfo[SPECIES_NONE].iconSprite;
}
return iconSprite;
}

View File

@ -443,6 +443,7 @@ struct PokemonStorageSystemData
u16 iconSpeciesList[MAX_MON_ICONS];
u16 boxSpecies[IN_BOX_COUNT];
u32 boxPersonalities[IN_BOX_COUNT];
bool8 boxIsEgg[IN_BOX_COUNT];
u8 incomingBoxId;
u8 shiftTimer;
u8 numPartyToCompact;
@ -629,7 +630,7 @@ static void ReshowReleaseMon(void);
static bool8 ResetReleaseMonSpritePtr(void);
static void SetMovingMonPriority(u8);
static void SpriteCB_HeldMon(struct Sprite *);
static struct Sprite *CreateMonIconSprite(u16, u32, s16, s16, u8, u8);
static struct Sprite *CreateMonIconSprite(u16 species, u32 personality, s16 x, s16 y, u8 oamPriority, u8 subpriority, bool32 isEgg);
static void DestroyBoxMonIcon(struct Sprite *);
// Pokémon data
@ -831,7 +832,7 @@ static bool8 IsDisplayMosaicActive(void);
static void ShowYesNoWindow(s8);
static void UpdateCloseBoxButtonTilemap(bool8);
static void PrintMessage(u8 id);
static void LoadDisplayMonGfx(u16, u32);
static void LoadDisplayMonGfx(u16 species, u32 pid, bool32 isEgg);
static void SpriteCB_DisplayMonMosaic(struct Sprite *);
static void SetPartySlotTilemap(u8, bool8);
@ -3903,7 +3904,7 @@ static void CreateWaveformSprites(void)
static void RefreshDisplayMonData(void)
{
LoadDisplayMonGfx(sStorage->displayMonSpecies, sStorage->displayMonPersonality);
LoadDisplayMonGfx(sStorage->displayMonSpecies, sStorage->displayMonPersonality, sStorage->displayMonIsEgg);
PrintDisplayMonInfo();
UpdateWaveformAnimation();
ScheduleBgCopyTilemapToVram(0);
@ -3981,14 +3982,14 @@ static void CreateDisplayMonSprite(void)
}
}
static void LoadDisplayMonGfx(u16 species, u32 pid)
static void LoadDisplayMonGfx(u16 species, u32 pid, bool32 isEgg)
{
if (sStorage->displayMonSprite == NULL)
return;
if (species != SPECIES_NONE)
{
LoadSpecialPokePic(sStorage->tileBuffer, species, pid, TRUE);
LoadSpecialPokePicIsEgg(sStorage->tileBuffer, species, pid, TRUE, isEgg);
CpuCopy32(sStorage->tileBuffer, sStorage->displayMonTilePtr, MON_PIC_SIZE);
LoadPalette(sStorage->displayMonPalette, sStorage->displayMonPalOffset, PLTT_SIZE_4BPP);
sStorage->displayMonSprite->invisible = FALSE;
@ -4438,10 +4439,11 @@ static u8 GetMonIconPriorityByCursorPos(void)
static void CreateMovingMonIcon(void)
{
u32 personality = GetMonData(&sStorage->movingMon, MON_DATA_PERSONALITY);
u16 species = GetMonData(&sStorage->movingMon, MON_DATA_SPECIES_OR_EGG);
u16 species = GetMonData(&sStorage->movingMon, MON_DATA_SPECIES);
u8 priority = GetMonIconPriorityByCursorPos();
bool32 isEgg = GetMonData(&sStorage->movingMon, MON_DATA_IS_EGG);
sStorage->movingMonSprite = CreateMonIconSprite(species, personality, 0, 0, priority, 7);
sStorage->movingMonSprite = CreateMonIconSprite(species, personality, 0, 0, priority, 7, isEgg);
sStorage->movingMonSprite->callback = SpriteCB_HeldMon;
}
@ -4460,11 +4462,12 @@ static void InitBoxMonSprites(u8 boxId)
{
for (j = 0; j < IN_BOX_COLUMNS; j++)
{
species = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_SPECIES_OR_EGG);
species = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_SPECIES);
bool32 isEgg = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_IS_EGG);
if (species != SPECIES_NONE)
{
personality = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_PERSONALITY);
sStorage->boxMonsSprites[count] = CreateMonIconSprite(species, personality, 8 * (3 * j) + 100, 8 * (3 * i) + 44, 2, 19 - j);
sStorage->boxMonsSprites[count] = CreateMonIconSprite(species, personality, 8 * (3 * j) + 100, 8 * (3 * i) + 44, 2, 19 - j, isEgg);
}
else
{
@ -4488,7 +4491,8 @@ static void InitBoxMonSprites(u8 boxId)
static void CreateBoxMonIconAtPos(u8 boxPosition)
{
u16 species = GetCurrentBoxMonData(boxPosition, MON_DATA_SPECIES_OR_EGG);
u16 species = GetCurrentBoxMonData(boxPosition, MON_DATA_SPECIES);
bool32 isEgg = GetCurrentBoxMonData(boxPosition, MON_DATA_IS_EGG);
if (species != SPECIES_NONE)
{
@ -4496,7 +4500,7 @@ static void CreateBoxMonIconAtPos(u8 boxPosition)
s16 y = 8 * (3 * (boxPosition / IN_BOX_COLUMNS)) + 44;
u32 personality = GetCurrentBoxMonData(boxPosition, MON_DATA_PERSONALITY);
sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(species, personality, x, y, 2, 19 - (boxPosition % IN_BOX_COLUMNS));
sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(species, personality, x, y, 2, 19 - (boxPosition % IN_BOX_COLUMNS), isEgg);
if (sStorage->boxOption == OPTION_MOVE_ITEMS)
sStorage->boxMonsSprites[boxPosition]->oam.objMode = ST_OAM_OBJ_BLEND;
}
@ -4594,8 +4598,9 @@ static u8 CreateBoxMonIconsInColumn(u8 column, u16 distance, s16 speed)
if (sStorage->boxSpecies[boxPosition] != SPECIES_NONE)
{
sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(sStorage->boxSpecies[boxPosition],
sStorage->boxPersonalities[boxPosition],
x, y, 2, subpriority);
sStorage->boxPersonalities[boxPosition],
x, y, 2, subpriority,
sStorage->boxIsEgg[boxPosition]);
if (sStorage->boxMonsSprites[boxPosition] != NULL)
{
sStorage->boxMonsSprites[boxPosition]->sDistance = distance;
@ -4618,8 +4623,9 @@ static u8 CreateBoxMonIconsInColumn(u8 column, u16 distance, s16 speed)
if (sStorage->boxSpecies[boxPosition] != SPECIES_NONE)
{
sStorage->boxMonsSprites[boxPosition] = CreateMonIconSprite(sStorage->boxSpecies[boxPosition],
sStorage->boxPersonalities[boxPosition],
x, y, 2, subpriority);
sStorage->boxPersonalities[boxPosition],
x, y, 2, subpriority,
sStorage->boxIsEgg[boxPosition]);
if (sStorage->boxMonsSprites[boxPosition] != NULL)
{
sStorage->boxMonsSprites[boxPosition]->sDistance = distance;
@ -4721,7 +4727,8 @@ static void GetIncomingBoxMonData(u8 boxId)
{
for (j = 0; j < IN_BOX_COLUMNS; j++)
{
sStorage->boxSpecies[boxPosition] = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_SPECIES_OR_EGG);
sStorage->boxSpecies[boxPosition] = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_SPECIES);
sStorage->boxIsEgg[boxPosition] = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_IS_EGG);
if (sStorage->boxSpecies[boxPosition] != SPECIES_NONE)
sStorage->boxPersonalities[boxPosition] = GetBoxMonDataAt(boxId, boxPosition, MON_DATA_PERSONALITY);
boxPosition++;
@ -4749,18 +4756,20 @@ static void SetBoxMonIconObjMode(u8 boxPosition, u8 objMode)
static void CreatePartyMonsSprites(bool8 visible)
{
u16 i, count;
u16 species = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES_OR_EGG);
u16 species = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES);
bool32 isEgg = GetMonData(&gPlayerParty[0], MON_DATA_IS_EGG);
u32 personality = GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY);
sStorage->partySprites[0] = CreateMonIconSprite(species, personality, 104, 64, 1, 12);
sStorage->partySprites[0] = CreateMonIconSprite(species, personality, 104, 64, 1, 12, isEgg);
count = 1;
for (i = 1; i < PARTY_SIZE; i++)
{
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG);
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES);
isEgg = GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG);
if (species != SPECIES_NONE)
{
personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY);
sStorage->partySprites[i] = CreateMonIconSprite(species, personality, 152, 8 * (3 * (i - 1)) + 16, 1, 12);
sStorage->partySprites[i] = CreateMonIconSprite(species, personality, 152, 8 * (3 * (i - 1)) + 16, 1, 12, isEgg);
count++;
}
else
@ -5097,7 +5106,7 @@ static void SpriteCB_HeldMon(struct Sprite *sprite)
sprite->y = sStorage->cursorSprite->y + sStorage->cursorSprite->y2 + 4;
}
static u16 TryLoadMonIconTiles(u16 species, u32 personality)
static u16 TryLoadMonIconTiles(u16 species, u32 personality, bool32 isEgg)
{
u16 i, offset;
@ -5134,7 +5143,7 @@ static u16 TryLoadMonIconTiles(u16 species, u32 personality)
sStorage->numIconsPerSpecies[i]++;
offset = 16 * i;
species &= GENDER_MASK;
CpuCopy32(GetMonIconTiles(species, personality), (void *)(OBJ_VRAM0) + offset * TILE_SIZE_4BPP, 0x200);
CpuCopy32(GetMonIconTilesIsEgg(species, personality, isEgg), (void *)(OBJ_VRAM0) + offset * TILE_SIZE_4BPP, 0x200);
return offset;
}
@ -5164,25 +5173,32 @@ static void RemoveSpeciesFromIconList(u16 species)
}
}
static struct Sprite *CreateMonIconSprite(u16 species, u32 personality, s16 x, s16 y, u8 oamPriority, u8 subpriority)
static struct Sprite *CreateMonIconSprite(u16 species, u32 personality, s16 x, s16 y, u8 oamPriority, u8 subpriority, bool32 isEgg)
{
u16 tileNum;
u8 spriteId;
struct SpriteTemplate template = sSpriteTemplate_MonIcon;
species = GetIconSpecies(species, personality);
if (isEgg)
{
if (gSpeciesInfo[species].eggId != EGG_ID_NONE)
template.paletteTag = PALTAG_MON_ICON_0 + gEggDatas[gSpeciesInfo[species].eggId].eggIconPalIndex;
else
template.paletteTag = PALTAG_MON_ICON_0 + gSpeciesInfo[SPECIES_EGG].iconPalIndex;
}
#if P_GENDER_DIFFERENCES
if (gSpeciesInfo[species].iconSpriteFemale != NULL && IsPersonalityFemale(species, personality))
else if (gSpeciesInfo[species].iconSpriteFemale != NULL && IsPersonalityFemale(species, personality))
{
template.paletteTag = PALTAG_MON_ICON_0 + gSpeciesInfo[species].iconPalIndexFemale;
}
else
#endif
else
{
template.paletteTag = PALTAG_MON_ICON_0 + gSpeciesInfo[species].iconPalIndex;
}
tileNum = TryLoadMonIconTiles(species, personality);
tileNum = TryLoadMonIconTiles(species, personality, isEgg);
if (tileNum == 0xFFFF)
return NULL;
@ -6943,7 +6959,7 @@ static void SetDisplayMonData(void *pokemon, u8 mode)
{
struct Pokemon *mon = (struct Pokemon *)pokemon;
sStorage->displayMonSpecies = GetMonData(mon, MON_DATA_SPECIES_OR_EGG);
sStorage->displayMonSpecies = GetMonData(mon, MON_DATA_SPECIES);
if (sStorage->displayMonSpecies != SPECIES_NONE)
{
sanityIsBadEgg = GetMonData(mon, MON_DATA_SANITY_IS_BAD_EGG);
@ -6982,7 +6998,8 @@ static void SetDisplayMonData(void *pokemon, u8 mode)
sStorage->displayMonLevel = GetLevelFromBoxMonExp(boxMon);
sStorage->displayMonMarkings = GetBoxMonData(boxMon, MON_DATA_MARKINGS);
sStorage->displayMonPersonality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY);
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(sStorage->displayMonSpecies, isShiny, sStorage->displayMonPersonality);
sStorage->displayMonIsEgg = GetBoxMonData(boxMon, MON_DATA_IS_EGG);
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonalityIsEgg(sStorage->displayMonSpecies, isShiny, sStorage->displayMonPersonality, sStorage->displayMonIsEgg);
gender = GetGenderFromSpeciesAndPersonality(sStorage->displayMonSpecies, sStorage->displayMonPersonality);
sStorage->displayMonItemId = GetBoxMonData(boxMon, MON_DATA_HELD_ITEM);
}
@ -8523,12 +8540,13 @@ static void MultiMove_DeselectRow(u8 row, u8 minColumn, u8 maxColumn)
static void MultiMove_SetIconToBg(u8 x, u8 y)
{
u8 position = x + (IN_BOX_COLUMNS * y);
u16 species = GetCurrentBoxMonData(position, MON_DATA_SPECIES_OR_EGG);
u16 species = GetCurrentBoxMonData(position, MON_DATA_SPECIES);
u32 personality = GetCurrentBoxMonData(position, MON_DATA_PERSONALITY);
bool32 isEgg = GetCurrentBoxMonData(position, MON_DATA_IS_EGG);
if (species != SPECIES_NONE)
{
const u8 *iconGfx = GetMonIconPtr(species, personality);
const u8 *iconGfx = GetMonIconPtrIsEgg(species, personality, isEgg);
u8 index = GetValidMonIconPalIndex(species) + 8;
BlitBitmapRectToWindow4BitTo8Bit(sStorage->multiMoveWindowId,
@ -10078,15 +10096,17 @@ void UpdateSpeciesSpritePSS(struct BoxPokemon *boxMon)
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES);
bool8 isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY);
u32 pid = GetBoxMonData(boxMon, MON_DATA_PERSONALITY);
bool32 isEgg = GetBoxMonData(boxMon, MON_DATA_IS_EGG);
// Update front sprite
sStorage->displayMonSpecies = species;
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, pid);
sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonalityIsEgg(species, isShiny, pid, isEgg);
sStorage->displayMonIsEgg = isEgg;
if (!sJustOpenedBag)
{
if (sRefreshDisplayMonGfx)
{
LoadDisplayMonGfx(species, pid);
LoadDisplayMonGfx(species, pid, isEgg);
StartDisplayMonMosaicEffect();
sRefreshDisplayMonGfx = FALSE;
}

View File

@ -4525,32 +4525,35 @@ static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state)
case 0:
if (gMain.inBattle)
{
HandleLoadSpecialPokePic(TRUE,
HandleLoadSpecialPokePicIsEgg(TRUE,
gMonSpritesGfxPtr->spritesGfx[B_POSITION_OPPONENT_LEFT],
summary->species2,
summary->pid);
summary->species,
summary->pid,
summary->isEgg);
}
else
{
if (gMonSpritesGfxPtr != NULL)
{
HandleLoadSpecialPokePic(TRUE,
HandleLoadSpecialPokePicIsEgg(TRUE,
gMonSpritesGfxPtr->spritesGfx[B_POSITION_OPPONENT_LEFT],
summary->species2,
summary->pid);
summary->species,
summary->pid,
summary->isEgg);
}
else
{
HandleLoadSpecialPokePic(TRUE,
HandleLoadSpecialPokePicIsEgg(TRUE,
MonSpritesGfxManager_GetSpritePtr(MON_SPR_GFX_MANAGER_A, B_POSITION_OPPONENT_LEFT),
summary->species2,
summary->pid);
summary->species,
summary->pid,
summary->isEgg);
}
}
(*state)++;
return 0xFF;
case 1:
LoadSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(summary->species2, summary->isShiny, summary->pid), summary->species2);
LoadSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonalityIsEgg(summary->species, summary->isShiny, summary->pid, summary->isEgg), summary->species2);
SetMultiuseSpriteTemplateToPokemon(summary->species2, B_POSITION_OPPONENT_LEFT);
(*state)++;
return 0xFF;

View File

@ -528,22 +528,20 @@ static void GetMonConditionGraphData(s16 listId, u8 loadId)
static void ConditionGraphDrawMonPic(s16 listId, u8 loadId)
{
u16 boxId, monId, species;
u32 personality;
bool8 isShiny;
struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU);
struct PokenavMonList *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST);
if (listId == (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1))
return;
boxId = monListPtr->monData[listId].boxId;
monId = monListPtr->monData[listId].monId;
species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES_OR_EGG, NULL);
isShiny = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_SHINY, NULL);
personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
LoadSpecialPokePic(menu->monPicGfx[loadId], species, personality, TRUE);
memcpy(&menu->monPal[loadId], GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), 32);
u32 boxId = monListPtr->monData[listId].boxId;
u32 monId = monListPtr->monData[listId].monId;
u32 species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES, NULL);
bool32 isShiny = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_SHINY, NULL);
u32 personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL);
bool32 isEgg = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_EGG, NULL);
LoadSpecialPokePicIsEgg(menu->monPicGfx[loadId], species, personality, TRUE, isEgg);
memcpy(&menu->monPal[loadId], GetMonSpritePalFromSpeciesAndPersonalityIsEgg(species, isShiny, personality, isEgg), 32);
}
u16 GetMonListCount(void)