From e7848a51d78d9b464188c948ba4755e721343c0d Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Mon, 19 Feb 2024 08:07:55 -0700 Subject: [PATCH 1/7] Sync mon data fields with `pokeemerald` --- payload/include/constants/pokemon.h | 90 --------- payload/include/pokemon.h | 273 +++++++++++++++++++--------- payload/src/all.c | 2 +- payload/src/pokemon.c | 50 ++--- 4 files changed, 216 insertions(+), 199 deletions(-) diff --git a/payload/include/constants/pokemon.h b/payload/include/constants/pokemon.h index d1cec44..93890d5 100644 --- a/payload/include/constants/pokemon.h +++ b/payload/include/constants/pokemon.h @@ -1,96 +1,6 @@ #ifndef GUARD_CONSTANTS_POKEMON_H #define GUARD_CONSTANTS_POKEMON_H -#define MON_DATA_PERSONALITY 0 -#define MON_DATA_OT_ID 1 -#define MON_DATA_NICKNAME 2 -#define MON_DATA_LANGUAGE 3 -#define MON_DATA_SANITY_BIT1 4 -#define MON_DATA_SANITY_BIT2 5 -#define MON_DATA_SANITY_BIT3 6 -#define MON_DATA_OT_NAME 7 -#define MON_DATA_MARKINGS 8 -#define MON_DATA_CHECKSUM 9 -#define MON_DATA_10 10 -#define MON_DATA_SPECIES 11 -#define MON_DATA_HELD_ITEM 12 -#define MON_DATA_MOVE1 13 -#define MON_DATA_MOVE2 14 -#define MON_DATA_MOVE3 15 -#define MON_DATA_MOVE4 16 -#define MON_DATA_PP1 17 -#define MON_DATA_PP2 18 -#define MON_DATA_PP3 19 -#define MON_DATA_PP4 20 -#define MON_DATA_PP_BONUSES 21 -#define MON_DATA_COOL 22 -#define MON_DATA_BEAUTY 23 -#define MON_DATA_CUTE 24 -#define MON_DATA_EXP 25 -#define MON_DATA_HP_EV 26 -#define MON_DATA_ATK_EV 27 -#define MON_DATA_DEF_EV 28 -#define MON_DATA_SPEED_EV 29 -#define MON_DATA_SPATK_EV 30 -#define MON_DATA_SPDEF_EV 31 -#define MON_DATA_FRIENDSHIP 32 -#define MON_DATA_SMART 33 -#define MON_DATA_POKERUS 34 -#define MON_DATA_MET_LOCATION 35 -#define MON_DATA_MET_LEVEL 36 -#define MON_DATA_MET_GAME 37 -#define MON_DATA_POKEBALL 38 -#define MON_DATA_HP_IV 39 -#define MON_DATA_ATK_IV 40 -#define MON_DATA_DEF_IV 41 -#define MON_DATA_SPEED_IV 42 -#define MON_DATA_SPATK_IV 43 -#define MON_DATA_SPDEF_IV 44 -#define MON_DATA_IS_EGG 45 -#define MON_DATA_ALT_ABILITY 46 -#define MON_DATA_TOUGH 47 -#define MON_DATA_SHEEN 48 -#define MON_DATA_OT_GENDER 49 -#define MON_DATA_COOL_RIBBON 50 -#define MON_DATA_BEAUTY_RIBBON 51 -#define MON_DATA_CUTE_RIBBON 52 -#define MON_DATA_SMART_RIBBON 53 -#define MON_DATA_TOUGH_RIBBON 54 -#define MON_DATA_STATUS 55 -#define MON_DATA_LEVEL 56 -#define MON_DATA_HP 57 -#define MON_DATA_MAX_HP 58 -#define MON_DATA_ATK 59 -#define MON_DATA_DEF 60 -#define MON_DATA_SPEED 61 -#define MON_DATA_SPATK 62 -#define MON_DATA_SPDEF 63 -#define MON_DATA_MAIL 64 -#define MON_DATA_SPECIES2 65 -#define MON_DATA_IVS 66 -#define MON_DATA_CHAMPION_RIBBON 67 -#define MON_DATA_WINNING_RIBBON 68 -#define MON_DATA_VICTORY_RIBBON 69 -#define MON_DATA_ARTIST_RIBBON 70 -#define MON_DATA_EFFORT_RIBBON 71 -#define MON_DATA_MARINE_RIBBON 72 -#define MON_DATA_LAND_RIBBON 73 -#define MON_DATA_SKY_RIBBON 74 -#define MON_DATA_COUNTRY_RIBBON 75 -#define MON_DATA_NATIONAL_RIBBON 76 -#define MON_DATA_EARTH_RIBBON 77 -#define MON_DATA_WORLD_RIBBON 78 -#define MON_DATA_EVENT_LEGAL 79 -#define MON_DATA_KNOWN_MOVES 80 -#define MON_DATA_RIBBON_COUNT 81 -#define MON_DATA_RIBBONS 82 -#define MON_DATA_83 83 -#define MON_DATA_ATK2 84 -#define MON_DATA_DEF2 85 -#define MON_DATA_SPEED2 86 -#define MON_DATA_SPATK2 87 -#define MON_DATA_SPDEF2 88 - #define MIN_LEVEL 1 #define MAX_LEVEL 100 diff --git a/payload/include/pokemon.h b/payload/include/pokemon.h index a9b9032..c167d6b 100644 --- a/payload/include/pokemon.h +++ b/payload/include/pokemon.h @@ -1,6 +1,99 @@ #ifndef GUARD_POKEMON_H #define GUARD_POKEMON_H +// Property labels for Get(Box)MonData / Set(Box)MonData +enum { + MON_DATA_PERSONALITY, + MON_DATA_OT_ID, + MON_DATA_NICKNAME, + MON_DATA_LANGUAGE, + MON_DATA_SANITY_IS_BAD_EGG, + MON_DATA_SANITY_HAS_SPECIES, + MON_DATA_SANITY_IS_EGG, + MON_DATA_OT_NAME, + MON_DATA_MARKINGS, + MON_DATA_CHECKSUM, + MON_DATA_ENCRYPT_SEPARATOR, + MON_DATA_SPECIES, + MON_DATA_HELD_ITEM, + MON_DATA_MOVE1, + MON_DATA_MOVE2, + MON_DATA_MOVE3, + MON_DATA_MOVE4, + MON_DATA_PP1, + MON_DATA_PP2, + MON_DATA_PP3, + MON_DATA_PP4, + MON_DATA_PP_BONUSES, + MON_DATA_COOL, + MON_DATA_BEAUTY, + MON_DATA_CUTE, + MON_DATA_EXP, + MON_DATA_HP_EV, + MON_DATA_ATK_EV, + MON_DATA_DEF_EV, + MON_DATA_SPEED_EV, + MON_DATA_SPATK_EV, + MON_DATA_SPDEF_EV, + MON_DATA_FRIENDSHIP, + MON_DATA_SMART, + MON_DATA_POKERUS, + MON_DATA_MET_LOCATION, + MON_DATA_MET_LEVEL, + MON_DATA_MET_GAME, + MON_DATA_POKEBALL, + MON_DATA_HP_IV, + MON_DATA_ATK_IV, + MON_DATA_DEF_IV, + MON_DATA_SPEED_IV, + MON_DATA_SPATK_IV, + MON_DATA_SPDEF_IV, + MON_DATA_IS_EGG, + MON_DATA_ABILITY_NUM, + MON_DATA_TOUGH, + MON_DATA_SHEEN, + MON_DATA_OT_GENDER, + MON_DATA_COOL_RIBBON, + MON_DATA_BEAUTY_RIBBON, + MON_DATA_CUTE_RIBBON, + MON_DATA_SMART_RIBBON, + MON_DATA_TOUGH_RIBBON, + MON_DATA_STATUS, + MON_DATA_LEVEL, + MON_DATA_HP, + MON_DATA_MAX_HP, + MON_DATA_ATK, + MON_DATA_DEF, + MON_DATA_SPEED, + MON_DATA_SPATK, + MON_DATA_SPDEF, + MON_DATA_MAIL, + MON_DATA_SPECIES_OR_EGG, + MON_DATA_IVS, + MON_DATA_CHAMPION_RIBBON, + MON_DATA_WINNING_RIBBON, + MON_DATA_VICTORY_RIBBON, + MON_DATA_ARTIST_RIBBON, + MON_DATA_EFFORT_RIBBON, + MON_DATA_MARINE_RIBBON, + MON_DATA_LAND_RIBBON, + MON_DATA_SKY_RIBBON, + MON_DATA_COUNTRY_RIBBON, + MON_DATA_NATIONAL_RIBBON, + MON_DATA_EARTH_RIBBON, + MON_DATA_WORLD_RIBBON, + MON_DATA_MODERN_FATEFUL_ENCOUNTER, + MON_DATA_KNOWN_MOVES, + MON_DATA_RIBBON_COUNT, + MON_DATA_RIBBONS, + MON_DATA_83, + MON_DATA_ATK2, + MON_DATA_DEF2, + MON_DATA_SPEED2, + MON_DATA_SPATK2, + MON_DATA_SPDEF2, +}; + struct PokemonSubstruct0 { u16 species; @@ -8,12 +101,13 @@ struct PokemonSubstruct0 u32 experience; u8 ppBonuses; u8 friendship; + u16 filler; }; struct PokemonSubstruct1 { - u16 moves[4]; - u8 pp[4]; + u16 moves[MAX_MON_MOVES]; + u8 pp[MAX_MON_MOVES]; }; struct PokemonSubstruct2 @@ -34,41 +128,52 @@ struct PokemonSubstruct2 struct PokemonSubstruct3 { - /*0x00*/ u8 pokerus; - /*0x01*/ u8 metLocation; - - /*0x02*/ u16 metLevel:7; - /*0x02*/ u16 metGame:4; - /*0x03*/ u16 pokeball:4; - /*0x03*/ u16 otGender:1; - - /*0x04*/ u32 hpIV:5; - /*0x04*/ u32 attackIV:5; - /*0x05*/ u32 defenseIV:5; - /*0x05*/ u32 speedIV:5; - /*0x05*/ u32 spAttackIV:5; - /*0x06*/ u32 spDefenseIV:5; - /*0x07*/ u32 isEgg:1; - /*0x07*/ u32 altAbility:1; - - /*0x08*/ u32 coolRibbon:3; - /*0x08*/ u32 beautyRibbon:3; - /*0x08*/ u32 cuteRibbon:3; - /*0x09*/ u32 smartRibbon:3; - /*0x09*/ u32 toughRibbon:3; - /*0x09*/ u32 championRibbon:1; - /*0x0A*/ u32 winningRibbon:1; - /*0x0A*/ u32 victoryRibbon:1; - /*0x0A*/ u32 artistRibbon:1; - /*0x0A*/ u32 effortRibbon:1; - /*0x0A*/ u32 marineRibbon:1; // never distributed - /*0x0A*/ u32 landRibbon:1; // never distributed - /*0x0A*/ u32 skyRibbon:1; // never distributed - /*0x0A*/ u32 countryRibbon:1; // distributed during Pokémon Festa '04 and '05 to tournament winners - /*0x0B*/ u32 nationalRibbon:1; - /*0x0B*/ u32 earthRibbon:1; - /*0x0B*/ u32 worldRibbon:1; // distributed during Pokémon Festa '04 and '05 to tournament winners - /*0x0B*/ u32 eventLegal:5; // high bit controls Mew & Deoxys obedience in FRLGE; if set, Pokémon is a fateful encounter in FRLG & Gen 4+ summary screens; set for in-game event island legendaries, some distributed events, and Pokémon from XD: Gale of Darkness. + u8 pokerus; + u8 metLocation; + + u16 metLevel:7; + u16 metGame:4; + u16 pokeball:4; + u16 otGender:1; + + u32 hpIV:5; + u32 attackIV:5; + u32 defenseIV:5; + u32 speedIV:5; + u32 spAttackIV:5; + u32 spDefenseIV:5; + u32 isEgg:1; + u32 abilityNum:1; + + u32 coolRibbon:3; // Stores the highest contest rank achieved in the Cool category. + u32 beautyRibbon:3; // Stores the highest contest rank achieved in the Beauty category. + u32 cuteRibbon:3; // Stores the highest contest rank achieved in the Cute category. + u32 smartRibbon:3; // Stores the highest contest rank achieved in the Smart category. + u32 toughRibbon:3; // Stores the highest contest rank achieved in the Tough category. + u32 championRibbon:1; // Given when defeating the Champion. Because both RSE and FRLG use it, later generations don't specify from which region it comes from. + u32 winningRibbon:1; // Given at the Battle Tower's Level 50 challenge by winning a set of seven battles that extends the current streak to 56 or more. + u32 victoryRibbon:1; // Given at the Battle Tower's Level 100 challenge by winning a set of seven battles that extends the current streak to 56 or more. + u32 artistRibbon:1; // Given at the Contest Hall by winning a Master Rank contest with at least 800 points, and agreeing to have the Pokémon's portrait placed in the museum after being offered. + u32 effortRibbon:1; // Given at Slateport's market to Pokémon with maximum EVs. + u32 marineRibbon:1; // Never distributed. + u32 landRibbon:1; // Never distributed. + u32 skyRibbon:1; // Never distributed. + u32 countryRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners. + u32 nationalRibbon:1; // Given to purified Shadow Pokémon in Colosseum/XD. + u32 earthRibbon:1; // Given to teams that have beaten Mt. Battle's 100-battle challenge in Colosseum/XD. + u32 worldRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners. + + u32 modernFatefulEncounter:5; + // Emerald's definition of these 5 bits are below: + //u32 unusedRibbons:4; // Discarded in Gen 4. + + // The functionality of this bit changed in FRLG: + // In RS, this bit does nothing, is never set, & is accidentally unset when hatching Eggs. + // In FRLG & Emerald, this controls Mew & Deoxys obedience and whether they can be traded. + // If set, a Pokémon is a fateful encounter in FRLG's summary screen if hatched & for all Pokémon in Gen 4+ summary screens. + // Set for in-game event island legendaries, events distributed after a certain date, & Pokémon from XD: Gale of Darkness. + // Not to be confused with METLOC_FATEFUL_ENCOUNTER. + //u32 modernFatefulEncounter:5; }; union PokemonSubstruct @@ -82,65 +187,67 @@ union PokemonSubstruct struct BoxPokemon { - /*0x00*/ u32 personality; - /*0x04*/ u32 otId; - /*0x08*/ u8 nickname[POKEMON_NAME_LENGTH]; - /*0x12*/ u8 language; - /*0x13*/ u8 isBadEgg:1; - u8 hasSpecies:1; - u8 isEgg:1; - /*0x14*/ u8 otName[PLAYER_NAME_LENGTH]; - /*0x1B*/ u8 markings; - /*0x1C*/ u16 checksum; - /*0x1E*/ u16 unknown; + u32 personality; + u32 otId; + u8 nickname[POKEMON_NAME_LENGTH]; + u8 language; + u8 isBadEgg:1; + u8 hasSpecies:1; + u8 isEgg:1; + u8 blockBoxRS:1; // Unused, but Pokémon Box Ruby & Sapphire will refuse to deposit a Pokémon with this flag set + u8 unused:4; + u8 otName[PLAYER_NAME_LENGTH]; + u8 markings; + u16 checksum; + u16 unknown; union { u32 raw[12]; union PokemonSubstruct substructs[4]; } secure; -}; /*size = 0x50*/ +}; struct Pokemon { - /*0x00*/ struct BoxPokemon box; - /*0x50*/ u32 status; - /*0x54*/ u8 level; - /*0x55*/ u8 mail; - /*0x56*/ u16 hp; - /*0x58*/ u16 maxHP; - /*0x5A*/ u16 attack; - /*0x5C*/ u16 defense; - /*0x5E*/ u16 speed; - /*0x60*/ u16 spAttack; - /*0x62*/ u16 spDefense; + struct BoxPokemon box; + u32 status; + u8 level; + u8 mail; + u16 hp; + u16 maxHP; + u16 attack; + u16 defense; + u16 speed; + u16 spAttack; + u16 spDefense; }; struct BattleTowerPokemon { - /*0x00*/u16 species; - /*0x02*/u16 heldItem; - /*0x04*/u16 moves[4]; - /*0x0C*/u8 level; - /*0x0D*/u8 ppBonuses; - /*0x0E*/u8 hpEV; - /*0x0F*/u8 attackEV; - /*0x10*/u8 defenseEV; - /*0x11*/u8 speedEV; - /*0x12*/u8 spAttackEV; - /*0x13*/u8 spDefenseEV; - /*0x14*/u32 otId; - /*0x18*/u32 hpIV:5; - /*0x18*/u32 attackIV:5; - /*0x19*/u32 defenseIV:5; - /*0x19*/u32 speedIV:5; - /*0x1A*/u32 spAttackIV:5; - /*0x1A*/u32 spDefenseIV:5; - /*0x1B*/u32 gap:1; - /*0x1B*/u32 altAbility:1; - /*0x1C*/u32 personality; - /*0x20*/u8 nickname[POKEMON_NAME_LENGTH + 1]; - /*0x2B*/u8 friendship; + u16 species; + u16 heldItem; + u16 moves[MAX_MON_MOVES]; + u8 level; + u8 ppBonuses; + u8 hpEV; + u8 attackEV; + u8 defenseEV; + u8 speedEV; + u8 spAttackEV; + u8 spDefenseEV; + u32 otId; + u32 hpIV:5; + u32 attackIV:5; + u32 defenseIV:5; + u32 speedIV:5; + u32 spAttackIV:5; + u32 spDefenseIV:5; + u32 gap:1; + u32 abilityNum:1; + u32 personality; + u8 nickname[POKEMON_NAME_LENGTH + 1]; + u8 friendship; }; struct SpeciesInfo diff --git a/payload/src/all.c b/payload/src/all.c index 8996e7d..7bb49ec 100644 --- a/payload/src/all.c +++ b/payload/src/all.c @@ -704,7 +704,7 @@ u32 sub_02000CA4(struct UnkSpriteMonIconStruct *a0, u32 monId, s32 x, s32 y) u32 personality; struct Sprite *sprite; - a0->species = GetMonData(&gPlayerPartyPtr[monId], MON_DATA_SPECIES2, NULL); + a0->species = GetMonData(&gPlayerPartyPtr[monId], MON_DATA_SPECIES_OR_EGG, NULL); if (a0->species == SPECIES_NONE) return SPECIES_NONE; diff --git a/payload/src/pokemon.c b/payload/src/pokemon.c index 4501d20..d13cb46 100644 --- a/payload/src/pokemon.c +++ b/payload/src/pokemon.c @@ -145,7 +145,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) struct PokemonSubstruct2 *substruct2 = NULL; struct PokemonSubstruct3 *substruct3 = NULL; - if (field > MON_DATA_10) + if (field > MON_DATA_ENCRYPT_SEPARATOR) { substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0); substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1); @@ -211,13 +211,13 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) case MON_DATA_LANGUAGE: retVal = boxMon->language; break; - case MON_DATA_SANITY_BIT1: + case MON_DATA_SANITY_IS_BAD_EGG: retVal = boxMon->isBadEgg; break; - case MON_DATA_SANITY_BIT2: + case MON_DATA_SANITY_HAS_SPECIES: retVal = boxMon->hasSpecies; break; - case MON_DATA_SANITY_BIT3: + case MON_DATA_SANITY_IS_EGG: retVal = boxMon->isEgg; break; case MON_DATA_OT_NAME: @@ -239,7 +239,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) case MON_DATA_CHECKSUM: retVal = boxMon->checksum; break; - case MON_DATA_10: + case MON_DATA_ENCRYPT_SEPARATOR: retVal = boxMon->unknown; break; case MON_DATA_SPECIES: @@ -344,8 +344,8 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) case MON_DATA_IS_EGG: retVal = substruct3->isEgg; break; - case MON_DATA_ALT_ABILITY: - retVal = substruct3->altAbility; + case MON_DATA_ABILITY_NUM: + retVal = substruct3->abilityNum; break; case MON_DATA_COOL_RIBBON: retVal = substruct3->coolRibbon; @@ -398,10 +398,10 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) case MON_DATA_WORLD_RIBBON: retVal = substruct3->worldRibbon; break; - case MON_DATA_EVENT_LEGAL: - retVal = substruct3->eventLegal; + case MON_DATA_MODERN_FATEFUL_ENCOUNTER: + retVal = substruct3->modernFatefulEncounter; break; - case MON_DATA_SPECIES2: + case MON_DATA_SPECIES_OR_EGG: retVal = substruct0->species; if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg)) retVal = SPECIES_EGG; @@ -477,7 +477,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) break; } - if (field > MON_DATA_10) + if (field > MON_DATA_ENCRYPT_SEPARATOR) EncryptBoxMon(boxMon); return retVal; @@ -522,7 +522,7 @@ const struct CompressedSpritePalette *GetBoxMonPalettePtr(u32 partyId) { u32 shinyValue = 0; - u16 species = GetMonDataInline(&gPlayerPartyPtr[partyId], MON_DATA_SPECIES2, NULL); + u16 species = GetMonDataInline(&gPlayerPartyPtr[partyId], MON_DATA_SPECIES_OR_EGG, NULL); u32 otId = GetMonDataInline(&gPlayerPartyPtr[partyId], MON_DATA_OT_ID, NULL); u32 personality = GetMonDataInline(&gPlayerPartyPtr[partyId], MON_DATA_PERSONALITY, NULL); @@ -541,7 +541,7 @@ u32 GetBoxMonAbility(struct BoxPokemon *boxMon) u32 ability; const struct SpeciesInfo *speciesInfo = gAgbPmRomParams->baseStats; u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL); - u32 abilityNum = GetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, NULL); + u32 abilityNum = GetBoxMonData(boxMon, MON_DATA_ABILITY_NUM, NULL); if (abilityNum == 0) ability = speciesInfo[species].abilities[0]; @@ -782,7 +782,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) struct PokemonSubstruct2 *substruct2 = NULL; struct PokemonSubstruct3 *substruct3 = NULL; - if (field > MON_DATA_10) + if (field > MON_DATA_ENCRYPT_SEPARATOR) { substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0); substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1); @@ -819,13 +819,13 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_LANGUAGE: SET8(boxMon->language); break; - case MON_DATA_SANITY_BIT1: + case MON_DATA_SANITY_IS_BAD_EGG: SET8(boxMon->isBadEgg); break; - case MON_DATA_SANITY_BIT2: + case MON_DATA_SANITY_HAS_SPECIES: SET8(boxMon->hasSpecies); break; - case MON_DATA_SANITY_BIT3: + case MON_DATA_SANITY_IS_EGG: SET8(boxMon->isEgg); break; case MON_DATA_OT_NAME: @@ -841,7 +841,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_CHECKSUM: SET16(boxMon->checksum); break; - case MON_DATA_10: + case MON_DATA_ENCRYPT_SEPARATOR: SET16(boxMon->unknown); break; case MON_DATA_SPECIES: @@ -966,8 +966,8 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) else boxMon->isEgg = 0; break; - case MON_DATA_ALT_ABILITY: - SET8(substruct3->altAbility); + case MON_DATA_ABILITY_NUM: + SET8(substruct3->abilityNum); break; case MON_DATA_COOL_RIBBON: SET8(substruct3->coolRibbon); @@ -1020,8 +1020,8 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_WORLD_RIBBON: SET8(substruct3->worldRibbon); break; - case MON_DATA_EVENT_LEGAL: - SET8(substruct3->eventLegal); + case MON_DATA_MODERN_FATEFUL_ENCOUNTER: + SET8(substruct3->modernFatefulEncounter); break; case MON_DATA_IVS: { @@ -1042,7 +1042,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) break; } - if (field > MON_DATA_10) + if (field > MON_DATA_ENCRYPT_SEPARATOR) { boxMon->checksum = CalculateBoxMonChecksum(boxMon); EncryptBoxMon(boxMon); @@ -1084,7 +1084,7 @@ void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg) case MON_DATA_MAIL: SET8(mon->mail); break; - case MON_DATA_SPECIES2: + case MON_DATA_SPECIES_OR_EGG: break; default: SetBoxMonData(&mon->box, field, data); @@ -1119,7 +1119,7 @@ void GiveGiftRibbonToParty(s32 index_, s32 ribbonId_) gGiftRibbonsPtr[index] = ribbonId; for (i = 0; i < PARTY_SIZE; i++) { - if (GetMonDataInline(&gPlayerPartyPtr[i], MON_DATA_SPECIES, NULL) != 0 && GetMonDataInline(&gPlayerPartyPtr[i], MON_DATA_SANITY_BIT3, NULL) == 0) + if (GetMonDataInline(&gPlayerPartyPtr[i], MON_DATA_SPECIES, NULL) != 0 && GetMonDataInline(&gPlayerPartyPtr[i], MON_DATA_SANITY_IS_EGG, NULL) == 0) gotRibbon = TRUE; } if (gotRibbon) From 17cff727bf956e71b3f204f3217ad809581cd69e Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Mon, 19 Feb 2024 08:31:04 -0700 Subject: [PATCH 2/7] Rename some stuff in `pokemon.c` --- payload/include/constants/moves.h | 2 +- payload/include/pokemon.h | 2 +- payload/src/all2.c | 2 +- payload/src/pokemon.c | 66 +++++++++++++++---------------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/payload/include/constants/moves.h b/payload/include/constants/moves.h index c48f78e..324bfb8 100644 --- a/payload/include/constants/moves.h +++ b/payload/include/constants/moves.h @@ -357,7 +357,7 @@ #define MOVE_DOOM_DESIRE 353 #define MOVE_PSYCHO_BOOST 354 -#define NUM_MOVES 355 +#define MOVES_COUNT 355 // Used for checks for moves affected by Disable, Mimic, etc. #define MOVE_UNAVAILABLE 0xFFFF diff --git a/payload/include/pokemon.h b/payload/include/pokemon.h index c167d6b..b4c4e1f 100644 --- a/payload/include/pokemon.h +++ b/payload/include/pokemon.h @@ -310,7 +310,7 @@ struct SpindaSpot u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data); const struct CompressedSpritePalette *GetBoxMonPalettePtr(u32 partyId); u32 GetBoxMonAbility(struct BoxPokemon *boxMon); -const u32 *BoxMonCaughtBallToItemId(struct BoxPokemon *boxMon); +const u32 *BoxMonGetCaughtBallItemSpriteSheet(struct BoxPokemon *boxMon); const u32 *BoxMonGetCaughtBallItemPalette(struct BoxPokemon *boxMon); u32 GetBoxMonMoveBySlot(struct BoxPokemon *boxMon, s32 slot); u32 GetBoxMonPPByMoveSlot(struct BoxPokemon *boxMon, u8 slot); diff --git a/payload/src/all2.c b/payload/src/all2.c index 31cb33e..0e89bcb 100644 --- a/payload/src/all2.c +++ b/payload/src/all2.c @@ -535,7 +535,7 @@ static void sub_02003D80(u32 monId, bool32 a1) if (gUnknown_02021990.unkC == NULL) gUnknown_02021990.unkC = AddSprite(0, 128, gUnknown_0201FA5C); SetSpritePaletteNum(gUnknown_02021990.unkC, 3); - LZ77UnCompVram(BoxMonCaughtBallToItemId(&mon->box), (void *)VRAM + 0x12800); + LZ77UnCompVram(BoxMonGetCaughtBallItemSpriteSheet(&mon->box), (void *)VRAM + 0x12800); LZ77UnCompVram(BoxMonGetCaughtBallItemPalette(&mon->box), (void *)PLTT + 0x260); primaryStatus = GetMonStatus(mon); if (primaryStatus != STATUS_PRIMARY_NONE) diff --git a/payload/src/pokemon.c b/payload/src/pokemon.c index d13cb46..7c1e7a9 100644 --- a/payload/src/pokemon.c +++ b/payload/src/pokemon.c @@ -102,16 +102,16 @@ static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon) union PokemonSubstruct *substruct3 = GetSubstruct(boxMon, boxMon->personality, 3); s32 i; - for (i = 0; i < 6; i++) + for (i = 0; i < (s32)NELEMS(substruct0->raw); i++) checksum += substruct0->raw[i]; - for (i = 0; i < 6; i++) + for (i = 0; i < (s32)NELEMS(substruct1->raw); i++) checksum += substruct1->raw[i]; - for (i = 0; i < 6; i++) + for (i = 0; i < (s32)NELEMS(substruct2->raw); i++) checksum += substruct2->raw[i]; - for (i = 0; i < 6; i++) + for (i = 0; i < (s32)NELEMS(substruct3->raw); i++) checksum += substruct3->raw[i]; return checksum; @@ -199,7 +199,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) if (language == LANGUAGE_JAPANESE) { text[0] = EXT_CTRL_CODE_BEGIN; - text[1] = 21; + text[1] = EXT_CTRL_CODE_JPN; StringCopy(text + 2, data); StringCopy(data, text); } @@ -415,7 +415,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) u16 *moves = (u16 *)data; s32 i = 0; - while (moves[i] != NUM_MOVES) + while (moves[i] != MOVES_COUNT) { u16 move = moves[i]; if (substruct1->moves[0] == move @@ -551,26 +551,26 @@ u32 GetBoxMonAbility(struct BoxPokemon *boxMon) return ability; } -const u32 *BoxMonCaughtBallToItemId(struct BoxPokemon *boxMon) +const u32 *BoxMonGetCaughtBallItemSpriteSheet(struct BoxPokemon *boxMon) { u32 id; u16 ball = GetBoxMonData(boxMon, MON_DATA_POKEBALL, NULL); switch (ball) { - case 1: id = 4; break; - case 2: id = 3; break; - case 3: id = 1; break; - case 4: id = 0; break; - case 5: id = 2; break; - case 6: id = 5; break; - case 7: id = 6; break; - case 8: id = 7; break; - case 9: id = 8; break; - case 10: id = 9; break; - case 11: id = 10; break; - case 12: id = 11; break; - default: id = 0; break; + case ITEM_MASTER_BALL: id = BALL_MASTER; break; + case ITEM_ULTRA_BALL: id = BALL_ULTRA; break; + case ITEM_GREAT_BALL: id = BALL_GREAT; break; + case ITEM_POKE_BALL: id = BALL_POKE; break; + case ITEM_SAFARI_BALL: id = BALL_SAFARI; break; + case ITEM_NET_BALL: id = BALL_NET; break; + case ITEM_DIVE_BALL: id = BALL_DIVE; break; + case ITEM_NEST_BALL: id = BALL_NEST; break; + case ITEM_REPEAT_BALL: id = BALL_REPEAT; break; + case ITEM_TIMER_BALL: id = BALL_TIMER; break; + case ITEM_LUXURY_BALL: id = BALL_LUXURY; break; + case ITEM_PREMIER_BALL: id = BALL_PREMIER; break; + default: id = BALL_POKE; break; } return gAgbPmRomParams->ballSpriteSheets[id].data; @@ -583,19 +583,19 @@ const u32 *BoxMonGetCaughtBallItemPalette(struct BoxPokemon *boxMon) switch (ball) { - case 1: id = 4; break; - case 2: id = 3; break; - case 3: id = 1; break; - case 4: id = 0; break; - case 5: id = 2; break; - case 6: id = 5; break; - case 7: id = 6; break; - case 8: id = 7; break; - case 9: id = 8; break; - case 10: id = 9; break; - case 11: id = 10; break; - case 12: id = 11; break; - default: id = 0; break; + case ITEM_MASTER_BALL: id = BALL_MASTER; break; + case ITEM_ULTRA_BALL: id = BALL_ULTRA; break; + case ITEM_GREAT_BALL: id = BALL_GREAT; break; + case ITEM_POKE_BALL: id = BALL_POKE; break; + case ITEM_SAFARI_BALL: id = BALL_SAFARI; break; + case ITEM_NET_BALL: id = BALL_NET; break; + case ITEM_DIVE_BALL: id = BALL_DIVE; break; + case ITEM_NEST_BALL: id = BALL_NEST; break; + case ITEM_REPEAT_BALL: id = BALL_REPEAT; break; + case ITEM_TIMER_BALL: id = BALL_TIMER; break; + case ITEM_LUXURY_BALL: id = BALL_LUXURY; break; + case ITEM_PREMIER_BALL: id = BALL_PREMIER; break; + default: id = BALL_POKE; break; } return gAgbPmRomParams->ballSpritePalettes[id].data; From 6f21623bf62112f2824d36c53c5234f12c226d0c Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Tue, 20 Feb 2024 20:09:56 -0700 Subject: [PATCH 3/7] Tidy up some newlines and replace `int` with `u32`/`s32` in `pokemon.c` --- payload/src/pokemon.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/payload/src/pokemon.c b/payload/src/pokemon.c index 7c1e7a9..9b5a3eb 100644 --- a/payload/src/pokemon.c +++ b/payload/src/pokemon.c @@ -120,6 +120,7 @@ static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon) static inline void EncryptBoxMon(struct BoxPokemon *boxMon) { u32 i; + for (i = 0; i < NELEMS(boxMon->secure.raw); i++) { boxMon->secure.raw[i] ^= boxMon->personality; @@ -130,6 +131,7 @@ static inline void EncryptBoxMon(struct BoxPokemon *boxMon) static inline void DecryptBoxMon(struct BoxPokemon *boxMon) { u32 i; + for (i = 0; i < NELEMS(boxMon->secure.raw); i++) { boxMon->secure.raw[i] ^= boxMon->otId; @@ -174,6 +176,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) { u32 language; u8 text[16]; + if (boxMon->isBadEgg) { StringCopy(data, gText_BadEgg); @@ -429,6 +432,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) break; case MON_DATA_RIBBON_COUNT: retVal = 0; + if (substruct0->species && !substruct3->isEgg) { retVal += substruct3->coolRibbon; @@ -452,6 +456,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) break; case MON_DATA_RIBBONS: retVal = 0; + if (substruct0->species && !substruct3->isEgg) { retVal = substruct3->championRibbon @@ -521,7 +526,6 @@ static inline u32 GetMonDataInline(struct Pokemon *mon, s32 attr, u8 *strbuf) const struct CompressedSpritePalette *GetBoxMonPalettePtr(u32 partyId) { u32 shinyValue = 0; - u16 species = GetMonDataInline(&gPlayerPartyPtr[partyId], MON_DATA_SPECIES_OR_EGG, NULL); u32 otId = GetMonDataInline(&gPlayerPartyPtr[partyId], MON_DATA_OT_ID, NULL); u32 personality = GetMonDataInline(&gPlayerPartyPtr[partyId], MON_DATA_PERSONALITY, NULL); @@ -530,6 +534,7 @@ const struct CompressedSpritePalette *GetBoxMonPalettePtr(u32 partyId) return &gAgbPmRomParams->monPaletteTable[SPECIES_NONE]; shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); + if (shinyValue > 7) return &gAgbPmRomParams->monPaletteTable[species]; else @@ -564,7 +569,7 @@ const u32 *BoxMonGetCaughtBallItemSpriteSheet(struct BoxPokemon *boxMon) case ITEM_POKE_BALL: id = BALL_POKE; break; case ITEM_SAFARI_BALL: id = BALL_SAFARI; break; case ITEM_NET_BALL: id = BALL_NET; break; - case ITEM_DIVE_BALL: id = BALL_DIVE; break; + case ITEM_DIVE_BALL: id = BALL_DIVE; break; case ITEM_NEST_BALL: id = BALL_NEST; break; case ITEM_REPEAT_BALL: id = BALL_REPEAT; break; case ITEM_TIMER_BALL: id = BALL_TIMER; break; @@ -589,7 +594,7 @@ const u32 *BoxMonGetCaughtBallItemPalette(struct BoxPokemon *boxMon) case ITEM_POKE_BALL: id = BALL_POKE; break; case ITEM_SAFARI_BALL: id = BALL_SAFARI; break; case ITEM_NET_BALL: id = BALL_NET; break; - case ITEM_DIVE_BALL: id = BALL_DIVE; break; + case ITEM_DIVE_BALL: id = BALL_DIVE; break; case ITEM_NEST_BALL: id = BALL_NEST; break; case ITEM_REPEAT_BALL: id = BALL_REPEAT; break; case ITEM_TIMER_BALL: id = BALL_TIMER; break; @@ -604,6 +609,7 @@ const u32 *BoxMonGetCaughtBallItemPalette(struct BoxPokemon *boxMon) u32 GetBoxMonMoveBySlot(struct BoxPokemon *boxMon, s32 slot) { u32 move; + switch (slot) { case 0: move = GetBoxMonData(boxMon, MON_DATA_MOVE1, NULL); break; @@ -618,6 +624,7 @@ u32 GetBoxMonMoveBySlot(struct BoxPokemon *boxMon, s32 slot) u32 GetBoxMonPPByMoveSlot(struct BoxPokemon *boxMon, u8 slot) { u32 pp; + switch (slot) { case 0: pp = GetBoxMonData(boxMon, MON_DATA_PP1, NULL); break; @@ -632,9 +639,9 @@ u32 GetBoxMonPPByMoveSlot(struct BoxPokemon *boxMon, u8 slot) u32 CheckPartyPokerus(struct Pokemon *party, u8 selection) { u32 retVal; + u32 partyIndex = 0; + u32 curBit = 1; - int partyIndex = 0; - unsigned curBit = 1; retVal = 0; if (selection) @@ -681,6 +688,7 @@ u32 GetMonStatus(struct Pokemon *mon) return STATUS_PRIMARY_FAINTED; statusAilment = GetPrimaryStatus(GetMonDataInline(mon, MON_DATA_STATUS, NULL)); + if (statusAilment == STATUS_PRIMARY_NONE) { if (!CheckPartyPokerus(mon, 0)) @@ -695,9 +703,9 @@ u32 GetMonStatus(struct Pokemon *mon) u32 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection) { u32 retVal; + u32 partyIndex = 0; + u32 curBit = 1; - int partyIndex = 0; - unsigned curBit = 1; retVal = 0; if (selection) @@ -724,7 +732,8 @@ void DrawSpindasSpots(u16 species, u32 personality, u8 *dest) { if (species == SPECIES_SPINDA) { - int i, j, k, var; + s32 i, j, k; + u32 var; if (gRomDetection_IsRubySapphire != FALSE) var = 0; @@ -776,7 +785,6 @@ void DrawSpindasSpots(u16 species, u32 personality, u8 *dest) void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) { const u8 *data = dataArg; - struct PokemonSubstruct0 *substruct0 = NULL; struct PokemonSubstruct1 *substruct1 = NULL; struct PokemonSubstruct2 *substruct2 = NULL; @@ -812,6 +820,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_NICKNAME: { s32 i; + for (i = 0; i < gAgbPmRomParams->pokemonNameLength_1; i++) boxMon->nickname[i] = data[i]; break; @@ -831,6 +840,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_OT_NAME: { s32 i; + for (i = 0; i < gAgbPmRomParams->playerNameLength; i++) boxMon->otName[i] = data[i]; break; @@ -926,6 +936,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_MET_LEVEL: { u8 metLevel = *data; + substruct3->metLevel = metLevel; break; } @@ -935,6 +946,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_POKEBALL: { u8 pokeball = *data; + substruct3->pokeball = pokeball; break; } @@ -961,6 +973,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) break; case MON_DATA_IS_EGG: SET8(substruct3->isEgg); + if (substruct3->isEgg) boxMon->isEgg = 1; else @@ -1030,6 +1043,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) #else u32 ivs = *data; // Bug: Only the HP IV and the lower 3 bits of the Attack IV are read. The rest become 0. #endif + substruct3->hpIV = ivs & 0x1F; substruct3->attackIV = (ivs >> 5) & 0x1F; substruct3->defenseIV = (ivs >> 10) & 0x1F; @@ -1052,6 +1066,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg) { const u8 *data = dataArg; + switch (field) { case MON_DATA_STATUS: @@ -1117,6 +1132,7 @@ void GiveGiftRibbonToParty(s32 index_, s32 ribbonId_) if (index < 11 && ribbonId < 65 && index < 7) { gGiftRibbonsPtr[index] = ribbonId; + for (i = 0; i < PARTY_SIZE; i++) { if (GetMonDataInline(&gPlayerPartyPtr[i], MON_DATA_SPECIES, NULL) != 0 && GetMonDataInline(&gPlayerPartyPtr[i], MON_DATA_SANITY_IS_EGG, NULL) == 0) @@ -1153,6 +1169,7 @@ u8 GetMonGender(struct Pokemon *mon) const struct SpeciesInfo *speciesInfo = gAgbPmRomParams->baseStats; u16 species = GetMonDataInline(mon, MON_DATA_SPECIES, NULL); u32 personality = GetMonDataInline(mon, MON_DATA_PERSONALITY, NULL); + return GetGenderFromSpeciesAndPersonality(species, personality, speciesInfo); } @@ -1164,6 +1181,7 @@ const struct CompressedSpritePalette *GetMonPalettePtrBySpeciesIdPersonality(u16 return &gAgbPmRomParams->monPaletteTable[SPECIES_NONE]; shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); + if (shinyValue <= 7) return &gAgbPmRomParams->monShinyPaletteTable[species]; else @@ -1242,12 +1260,14 @@ u32 GetMonSpritePaletteNumByBaseBlock(u32 id) const u8 *GetAbilityName(u32 ability) { const u8 (*abilityNames)[][ABILITY_NAME_LENGTH + 1] = gAgbPmRomParams->abilityNames; + return (*abilityNames)[ability]; } const u8 *GetAbilityDescription(u32 ability) { const u8 **desriptions = gAgbPmRomParams->abilityDescriptions; + return desriptions[ability]; } @@ -1255,6 +1275,7 @@ s32 CalculatePPWithBonus(u32 move, s32 ppBonuses, u32 moveIndex) { const struct BattleMove *moves = gAgbPmRomParams->battleMoves; s32 basePP = moves[move].pp; + return basePP + ((basePP * 20 * ((gPPUpReadMasks[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100); } From 3128bace4ccd486e12668d0e2c75d7ef63f69801 Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Sat, 24 Feb 2024 20:12:15 -0700 Subject: [PATCH 4/7] Sync Spinda dot drawing formatting from `pokeemerald` --- payload/src/pokemon.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/payload/src/pokemon.c b/payload/src/pokemon.c index 9b5a3eb..7dc0b14 100644 --- a/payload/src/pokemon.c +++ b/payload/src/pokemon.c @@ -728,11 +728,21 @@ u32 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection) return retVal; } +#define SPINDA_SPOT_HEIGHT 16 +#define SPINDA_SPOT_WIDTH 16 + +// Spots can be drawn on Spinda's color indexes 1, 2, or 3 +#define FIRST_SPOT_COLOR 1 +#define LAST_SPOT_COLOR 3 + +// To draw a spot pixel, add 4 to the color index +#define SPOT_COLOR_ADJUSTMENT 4 + void DrawSpindasSpots(u16 species, u32 personality, u8 *dest) { if (species == SPECIES_SPINDA) { - s32 i, j, k; + s32 i, row, column; u32 var; if (gRomDetection_IsRubySapphire != FALSE) @@ -745,29 +755,32 @@ void DrawSpindasSpots(u16 species, u32 personality, u8 *dest) u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8); u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8) - var; - for (j = 0; j < 16; j++) + for (row = 0; row < SPINDA_SPOT_HEIGHT; row++) { - s32 row = gSpindaSpotGraphics[i].image[j]; + s32 spotPixelRow = gSpindaSpotGraphics[i].image[row]; - for (k = x; k < x + 16; k++) + for (column = x; column < x + SPINDA_SPOT_WIDTH; column++) { - u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2); + u8 *destPixels = dest + ((column / 8) * TILE_SIZE_4BPP) + + ((column % 8) / 2) + + ((y / 8) * TILE_SIZE_4BPP * 8) + + ((y % 8) * 4); - if (row & 1) + if (spotPixelRow & 1) { - if (k & 1) + if (column & 1) { - if ((u8)((*val & 0xF0) - 0x10) <= 0x20) - *val += 0x40; + if ((u8)((*destPixels & 0xF0) - (FIRST_SPOT_COLOR << 4)) <= ((LAST_SPOT_COLOR - FIRST_SPOT_COLOR) << 4)) + *destPixels += (SPOT_COLOR_ADJUSTMENT << 4); } else { - if ((u8)((*val & 0xF) - 0x01) <= 0x02) - *val += 0x04; + if ((u8)((*destPixels & 0xF) - FIRST_SPOT_COLOR) <= (LAST_SPOT_COLOR - FIRST_SPOT_COLOR)) + *destPixels += SPOT_COLOR_ADJUSTMENT; } } - row >>= 1; + spotPixelRow >>= 1; } y++; @@ -1209,7 +1222,7 @@ u16 FixUnownSpecies(u16 species, u32 personality) else { if (species > SPECIES_EGG) - result = 260; + result = SPECIES_OLD_UNOWN_J; // ??? else result = species; } From 390972cec3dd095898ea7800a59a0427f5f120b2 Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Sun, 10 Mar 2024 11:36:36 -0600 Subject: [PATCH 5/7] Swap `NELEMS` for `ARRAY_COUNT` --- payload/include/global.h | 2 +- payload/src/pokemon.c | 12 ++++++------ payload/src/unk_200E344.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/payload/include/global.h b/payload/include/global.h index 9c3df43..77350e6 100644 --- a/payload/include/global.h +++ b/payload/include/global.h @@ -31,7 +31,7 @@ #include "constants/vars.h" #include "constants/flags.h" -#define NELEMS(arr) (sizeof(arr)/sizeof(*(arr))) +#define ARRAY_COUNT(array) (size_t)(sizeof(array) / sizeof((array)[0])) #define MOVE_NAME_LENGTH 12 #define POKEMON_NAME_LENGTH 10 diff --git a/payload/src/pokemon.c b/payload/src/pokemon.c index 7dc0b14..a6c847b 100644 --- a/payload/src/pokemon.c +++ b/payload/src/pokemon.c @@ -102,16 +102,16 @@ static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon) union PokemonSubstruct *substruct3 = GetSubstruct(boxMon, boxMon->personality, 3); s32 i; - for (i = 0; i < (s32)NELEMS(substruct0->raw); i++) + for (i = 0; i < (s32)ARRAY_COUNT(substruct0->raw); i++) checksum += substruct0->raw[i]; - for (i = 0; i < (s32)NELEMS(substruct1->raw); i++) + for (i = 0; i < (s32)ARRAY_COUNT(substruct1->raw); i++) checksum += substruct1->raw[i]; - for (i = 0; i < (s32)NELEMS(substruct2->raw); i++) + for (i = 0; i < (s32)ARRAY_COUNT(substruct2->raw); i++) checksum += substruct2->raw[i]; - for (i = 0; i < (s32)NELEMS(substruct3->raw); i++) + for (i = 0; i < (s32)ARRAY_COUNT(substruct3->raw); i++) checksum += substruct3->raw[i]; return checksum; @@ -121,7 +121,7 @@ static inline void EncryptBoxMon(struct BoxPokemon *boxMon) { u32 i; - for (i = 0; i < NELEMS(boxMon->secure.raw); i++) + for (i = 0; i < ARRAY_COUNT(boxMon->secure.raw); i++) { boxMon->secure.raw[i] ^= boxMon->personality; boxMon->secure.raw[i] ^= boxMon->otId; @@ -132,7 +132,7 @@ static inline void DecryptBoxMon(struct BoxPokemon *boxMon) { u32 i; - for (i = 0; i < NELEMS(boxMon->secure.raw); i++) + for (i = 0; i < ARRAY_COUNT(boxMon->secure.raw); i++) { boxMon->secure.raw[i] ^= boxMon->otId; boxMon->secure.raw[i] ^= boxMon->personality; diff --git a/payload/src/unk_200E344.c b/payload/src/unk_200E344.c index 7d14188..bcb69cb 100644 --- a/payload/src/unk_200E344.c +++ b/payload/src/unk_200E344.c @@ -72,7 +72,7 @@ s32 validate_rom_header_internal(void) languageCode = *(const u8 *)0x080000AF; version = *(const u8 *)0x080000BC; sp4 = -1; - for (i = 0; i < NELEMS(gUnknown_0201F298); i++) + for (i = 0; i < ARRAY_COUNT(gUnknown_0201F298); i++) { if (languageCode != gUnknown_0201F298[i][0]) { From 77b3791751698edc167afb823641aa1e9e0f4fe7 Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Sun, 10 Mar 2024 11:40:21 -0600 Subject: [PATCH 6/7] Address GriffinR's review --- payload/include/constants/species.h | 2 ++ payload/include/pokemon.h | 2 +- payload/src/pokemon.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/payload/include/constants/species.h b/payload/include/constants/species.h index ec60c14..0b2a87e 100644 --- a/payload/include/constants/species.h +++ b/payload/include/constants/species.h @@ -447,4 +447,6 @@ #define SPECIES_UNOWN_EMARK (SPECIES_UNOWN_B + 25) #define SPECIES_UNOWN_QMARK (SPECIES_UNOWN_B + 26) +#define INVALID_ICON_SPECIES SPECIES_OLD_UNOWN_J // Oddly specific, used when an icon should be a ?. Any of the 'old unown' would work + #endif // GUARD_CONSTANTS_SPECIES_H diff --git a/payload/include/pokemon.h b/payload/include/pokemon.h index b4c4e1f..a1b328a 100644 --- a/payload/include/pokemon.h +++ b/payload/include/pokemon.h @@ -173,7 +173,7 @@ struct PokemonSubstruct3 // If set, a Pokémon is a fateful encounter in FRLG's summary screen if hatched & for all Pokémon in Gen 4+ summary screens. // Set for in-game event island legendaries, events distributed after a certain date, & Pokémon from XD: Gale of Darkness. // Not to be confused with METLOC_FATEFUL_ENCOUNTER. - //u32 modernFatefulEncounter:5; + //u32 modernFatefulEncounter:1; }; union PokemonSubstruct diff --git a/payload/src/pokemon.c b/payload/src/pokemon.c index a6c847b..995dc1c 100644 --- a/payload/src/pokemon.c +++ b/payload/src/pokemon.c @@ -1222,7 +1222,7 @@ u16 FixUnownSpecies(u16 species, u32 personality) else { if (species > SPECIES_EGG) - result = SPECIES_OLD_UNOWN_J; // ??? + result = INVALID_ICON_SPECIES; // ??? else result = species; } From d6d4ea22fe4b08cc08267b97e1edfdd0232e6acc Mon Sep 17 00:00:00 2001 From: citrusbolt Date: Sun, 10 Mar 2024 11:41:02 -0600 Subject: [PATCH 7/7] Remove hanging `INVALID_ICON_SPECIES` comment --- payload/src/pokemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payload/src/pokemon.c b/payload/src/pokemon.c index 995dc1c..b9d52c8 100644 --- a/payload/src/pokemon.c +++ b/payload/src/pokemon.c @@ -1222,7 +1222,7 @@ u16 FixUnownSpecies(u16 species, u32 personality) else { if (species > SPECIES_EGG) - result = INVALID_ICON_SPECIES; // ??? + result = INVALID_ICON_SPECIES; else result = species; }