Fixed givemon not respecting perfect IVs for species (#5873)

This commit is contained in:
Eduardo Quezada 2024-12-26 17:22:45 -03:00 committed by GitHub
parent 2c9352921c
commit 91c7bd9e53
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 91 additions and 29 deletions

View file

@ -891,6 +891,7 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg); u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method); bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove); u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
bool32 SpeciesHasGenderDifferences(u16 species); bool32 SpeciesHasGenderDifferences(u16 species);
bool32 TryFormChange(u32 monId, u32 side, u16 method); bool32 TryFormChange(u32 monId, u32 side, u16 method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method); void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);

View file

@ -590,27 +590,6 @@ static void UNUSED TriggerPendingDaycareMaleEgg(void)
_TriggerPendingDaycareMaleEgg(&gSaveBlock1Ptr->daycare); _TriggerPendingDaycareMaleEgg(&gSaveBlock1Ptr->daycare);
} }
// Removes the selected index from the given IV list and shifts the remaining
// elements to the left.
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];
}
}
static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare) static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare)
{ {
u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM); u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);

View file

@ -75,7 +75,6 @@ static void EncryptBoxMon(struct BoxPokemon *boxMon);
static void DecryptBoxMon(struct BoxPokemon *boxMon); static void DecryptBoxMon(struct BoxPokemon *boxMon);
static void Task_PlayMapChosenOrBattleBGM(u8 taskId); static void Task_PlayMapChosenOrBattleBGM(u8 taskId);
static bool8 ShouldSkipFriendshipChange(void); static bool8 ShouldSkipFriendshipChange(void);
static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
void TrySpecialOverworldEvo(); void TrySpecialOverworldEvo();
EWRAM_DATA static u8 sLearningMoveTableID = 0; EWRAM_DATA static u8 sLearningMoveTableID = 0;
@ -6659,7 +6658,9 @@ u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove)
return 0; return 0;
} }
static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) // Removes the selected index from the given IV list and shifts the remaining
// elements to the left.
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
{ {
s32 i, j; s32 i, j;
u8 temp[NUM_STATS]; u8 temp[NUM_STATS];

View file

@ -487,12 +487,49 @@ void ScrCmd_createmon(struct ScriptContext *ctx)
u8 speedEv = PARSE_FLAG(8, 0); u8 speedEv = PARSE_FLAG(8, 0);
u8 spAtkEv = PARSE_FLAG(9, 0); u8 spAtkEv = PARSE_FLAG(9, 0);
u8 spDefEv = PARSE_FLAG(10, 0); u8 spDefEv = PARSE_FLAG(10, 0);
u8 hpIv = PARSE_FLAG(11, Random() % (MAX_PER_STAT_IVS + 1)); u8 hpIv = Random() % (MAX_PER_STAT_IVS + 1);
u8 atkIv = PARSE_FLAG(12, Random() % (MAX_PER_STAT_IVS + 1)); u8 atkIv = Random() % (MAX_PER_STAT_IVS + 1);
u8 defIv = PARSE_FLAG(13, Random() % (MAX_PER_STAT_IVS + 1)); u8 defIv = Random() % (MAX_PER_STAT_IVS + 1);
u8 speedIv = PARSE_FLAG(14, Random() % (MAX_PER_STAT_IVS + 1)); u8 speedIv = Random() % (MAX_PER_STAT_IVS + 1);
u8 spAtkIv = PARSE_FLAG(15, Random() % (MAX_PER_STAT_IVS + 1)); u8 spAtkIv = Random() % (MAX_PER_STAT_IVS + 1);
u8 spDefIv = PARSE_FLAG(16, Random() % (MAX_PER_STAT_IVS + 1)); u8 spDefIv = Random() % (MAX_PER_STAT_IVS + 1);
// Perfect IV calculation
u32 i;
u8 availableIVs[NUM_STATS];
u8 selectedIvs[NUM_STATS];
if (gSpeciesInfo[species].perfectIVCount != 0)
{
// Initialize a list of IV indices.
for (i = 0; i < NUM_STATS; i++)
availableIVs[i] = i;
// Select the IVs that will be perfected.
for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++)
{
u8 index = Random() % (NUM_STATS - i);
selectedIvs[i] = availableIVs[index];
RemoveIVIndexFromList(availableIVs, index);
}
for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++)
{
switch (selectedIvs[i])
{
case STAT_HP: hpIv = MAX_PER_STAT_IVS; break;
case STAT_ATK: atkIv = MAX_PER_STAT_IVS; break;
case STAT_DEF: defIv = MAX_PER_STAT_IVS; break;
case STAT_SPEED: speedIv = MAX_PER_STAT_IVS; break;
case STAT_SPATK: spAtkIv = MAX_PER_STAT_IVS; break;
case STAT_SPDEF: spDefIv = MAX_PER_STAT_IVS; break;
}
}
}
hpIv = PARSE_FLAG(11, hpIv);
atkIv = PARSE_FLAG(12, atkIv);
defIv = PARSE_FLAG(13, defIv);
speedIv = PARSE_FLAG(14, speedIv);
spAtkIv = PARSE_FLAG(15, spAtkIv);
spDefIv = PARSE_FLAG(16, spDefIv);
u16 move1 = PARSE_FLAG(17, MOVE_NONE); u16 move1 = PARSE_FLAG(17, MOVE_NONE);
u16 move2 = PARSE_FLAG(18, MOVE_NONE); u16 move2 = PARSE_FLAG(18, MOVE_NONE);
u16 move3 = PARSE_FLAG(19, MOVE_NONE); u16 move3 = PARSE_FLAG(19, MOVE_NONE);

View file

@ -210,6 +210,50 @@ TEST("givemon [simple]")
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100); EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
} }
TEST("givemon respects perfectIVCount")
{
ZeroPlayerPartyMons();
u32 perfectIVs[6] = {0};
ASSUME(gSpeciesInfo[SPECIES_MEW].perfectIVCount == 3);
ASSUME(gSpeciesInfo[SPECIES_CELEBI].perfectIVCount == 3);
ASSUME(gSpeciesInfo[SPECIES_JIRACHI].perfectIVCount == 3);
ASSUME(gSpeciesInfo[SPECIES_MANAPHY].perfectIVCount == 3);
ASSUME(gSpeciesInfo[SPECIES_VICTINI].perfectIVCount == 3);
ASSUME(gSpeciesInfo[SPECIES_DIANCIE].perfectIVCount == 3);
RUN_OVERWORLD_SCRIPT(
givemon SPECIES_MEW, 100;
givemon SPECIES_CELEBI, 100;
givemon SPECIES_JIRACHI, 100;
givemon SPECIES_MANAPHY, 100;
givemon SPECIES_VICTINI, 100;
givemon SPECIES_DIANCIE, 100;
);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_MEW);
EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_SPECIES), SPECIES_CELEBI);
EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_SPECIES), SPECIES_JIRACHI);
EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_SPECIES), SPECIES_MANAPHY);
EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_SPECIES), SPECIES_VICTINI);
EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_SPECIES), SPECIES_DIANCIE);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_LEVEL), 100);
EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_LEVEL), 100);
EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_LEVEL), 100);
EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_LEVEL), 100);
EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_LEVEL), 100);
for (u32 j = 0; j < 6; j++)
{
for (u32 k = 0; k < NUM_STATS; k++)
{
if (GetMonData(&gPlayerParty[j], MON_DATA_HP_IV + k) == MAX_PER_STAT_IVS)
perfectIVs[j]++;
}
EXPECT_GE(perfectIVs[j], 3);
}
}
TEST("givemon [moves]") TEST("givemon [moves]")
{ {
ZeroPlayerPartyMons(); ZeroPlayerPartyMons();