diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index 224a3f892a..ba9495158a 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -395,4 +395,6 @@ #define FLAG_GALARIAN_FORM (1 << 4) #define FLAG_GENDER_DIFFERENCE (1 << 5) +#define LEGENDARY_PERFECT_IV_COUNT 3 + #endif // GUARD_CONSTANTS_POKEMON_H diff --git a/include/constants/pokemon_config.h b/include/constants/pokemon_config.h index 257c06b7c0..aafa898d90 100644 --- a/include/constants/pokemon_config.h +++ b/include/constants/pokemon_config.h @@ -17,6 +17,7 @@ #define P_UPDATED_ABILITIES GEN_8 // Since Gen 6, certain Pokémon have their abilities changed. Requires BATTLE_ENGINE for Gen4+ abilities. #define P_UPDATED_EGG_GROUPS GEN_8 // Since Gen 8, certain Pokémon have gained new egg groups. #define P_SHEDINJA_BALL GEN_8 // Since Gen 4, Shedinja requires a Poké Ball for its evolution. In Gen 3, Shedinja inherits Nincada's Ball. +#define P_LEGENDARY_PERFECT_IVS GEN_8 // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs. #define P_ENABLE_DEBUG TRUE // Enables a debug menu for pokemon sprites and icons, accessed by pressing SELECT in the summary screen. diff --git a/src/pokemon.c b/src/pokemon.c index f654dcf52a..5af93106a0 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -65,6 +65,7 @@ static bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId); static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move); static bool8 ShouldSkipFriendshipChange(void); static u8 SendMonToPC(struct Pokemon* mon); +static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv); EWRAM_DATA static u8 sLearningMoveTableID = 0; EWRAM_DATA u8 gPlayerPartyCount = 0; @@ -3204,6 +3205,9 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u32 personality; u32 value; u16 checksum; + u8 i; + u8 availableIVs[NUM_STATS]; + u8 selectedIvs[LEGENDARY_PERFECT_IV_COUNT]; ZeroBoxMonData(boxMon); @@ -3286,6 +3290,52 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv); iv = (value & (MAX_IV_MASK << 10)) >> 10; SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv); + + #if P_LEGENDARY_PERFECT_IVS >= GEN_6 + if (gBaseStats[species].flags & (FLAG_LEGENDARY | FLAG_MYTHICAL | FLAG_ULTRA_BEAST)) + { + // Initialize a list of IV indices. + for (i = 0; i < NUM_STATS; i++) + { + availableIVs[i] = i; + } + + // Select the 3 IVs that will be perfected. + for (i = 0; i < LEGENDARY_PERFECT_IV_COUNT; i++) + { + u8 index = Random() % (NUM_STATS - i); + selectedIvs[i] = availableIVs[index]; + RemoveIVIndexFromList(availableIVs, index); + } + for (i = 0; i < LEGENDARY_PERFECT_IV_COUNT; i++) + { + switch (selectedIvs[i]) + { + case STAT_HP: + SetBoxMonData(boxMon, MON_DATA_HP_IV, MAX_PER_STAT_IVS); + //iv = GetBoxMonData(&daycare->mons[whichParents[i]].mon, MON_DATA_HP_IV); + //SetMonData(egg, MON_DATA_HP_IV, &iv); + break; + case STAT_ATK: + SetBoxMonData(boxMon, MON_DATA_ATK_IV, MAX_PER_STAT_IVS); + break; + case STAT_DEF: + SetBoxMonData(boxMon, MON_DATA_DEF_IV, MAX_PER_STAT_IVS); + break; + case STAT_SPEED: + SetBoxMonData(boxMon, MON_DATA_SPEED_IV, MAX_PER_STAT_IVS); + break; + case STAT_SPATK: + SetBoxMonData(boxMon, MON_DATA_SPATK_IV, MAX_PER_STAT_IVS); + break; + case STAT_SPDEF: + SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, MAX_PER_STAT_IVS); + break; + } + } + } + #endif + } if (gBaseStats[species].abilities[1]) @@ -8341,3 +8391,22 @@ u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove) } return 0; } + +static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) +{ + s32 i, j; + u8 temp[NUM_STATS]; + + ivs[selectedIv] = 0xFF; + for (i = 0; i < NUM_STATS; i++) + { + temp[i] = ivs[i]; + } + + j = 0; + for (i = 0; i < NUM_STATS; i++) + { + if (temp[i] != 0xFF) + ivs[j++] = temp[i]; + } +}