From 8b1f4ac3ac907a7d58404bc57ca837462cab1767 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Sun, 29 Jan 2023 19:35:46 +0100 Subject: [PATCH 1/5] Implement Destiny Knot --- src/daycare.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/daycare.c b/src/daycare.c index 2a96ca7a91..1eec5e0428 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -537,13 +537,17 @@ static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) } } -static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare) +static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare, struct BoxPokemon *father, struct BoxPokemon *mother) { u8 i; - u8 selectedIvs[INHERITED_IV_COUNT]; + u8 selectedIvs[5]; u8 availableIVs[NUM_STATS]; - u8 whichParents[INHERITED_IV_COUNT]; + u8 whichParents[5]; u8 iv; + u8 howManyIVs = 3; + + if (GetBoxMonData(father, MON_DATA_HELD_ITEM) == ITEM_DESTINY_KNOT || GetBoxMonData(mother, MON_DATA_HELD_ITEM) == ITEM_DESTINY_KNOT) + howManyIVs = 5; // Initialize a list of IV indices. for (i = 0; i < NUM_STATS; i++) @@ -552,32 +556,20 @@ static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare) } // Select the 3 IVs that will be inherited. - for (i = 0; i < INHERITED_IV_COUNT; i++) + for (i = 0; i < howManyIVs; i++) { - // Randomly pick an IV from the available list and stop from being chosen again. - // BUG: Instead of removing the IV that was just picked, this - // removes position 0 (HP) then position 1 (DEF), then position 2. This is why HP and DEF - // have a lower chance to be inherited in Emerald and why the IV picked for inheritance can - // be repeated. Amusingly, FRLG and RS also got this wrong. They remove selectedIvs[i], which - // is not an index! This means that it can sometimes remove the wrong stat. - #ifndef BUGFIX selectedIvs[i] = availableIVs[Random() % (NUM_STATS - i)]; RemoveIVIndexFromList(availableIVs, i); - #else - u8 index = Random() % (NUM_STATS - i); - selectedIvs[i] = availableIVs[index]; - RemoveIVIndexFromList(availableIVs, index); - #endif } // Determine which parent each of the selected IVs should inherit from. - for (i = 0; i < INHERITED_IV_COUNT; i++) + for (i = 0; i < howManyIVs; i++) { whichParents[i] = Random() % DAYCARE_MON_COUNT; } // Set each of inherited IVs on the egg mon. - for (i = 0; i < INHERITED_IV_COUNT; i++) + for (i = 0; i < howManyIVs; i++) { switch (selectedIvs[i]) { @@ -898,7 +890,7 @@ static void _GiveEggFromDaycare(struct DayCare *daycare) AlterEggSpeciesWithIncenseItem(&species, daycare); #endif SetInitialEggData(&egg, species, daycare); - InheritIVs(&egg, daycare); + InheritIVs(&egg, daycare, &daycare->mons[parentSlots[1]].mon, &daycare->mons[parentSlots[0]].mon); InheritPokeball(&egg, &daycare->mons[parentSlots[1]].mon, &daycare->mons[parentSlots[0]].mon); BuildEggMoveset(&egg, &daycare->mons[parentSlots[1]].mon, &daycare->mons[parentSlots[0]].mon); From 267cf1e6f06d6cd931f9571ea95f05fa433b9a43 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Sun, 29 Jan 2023 19:45:43 +0100 Subject: [PATCH 2/5] Update comment --- src/daycare.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daycare.c b/src/daycare.c index 1eec5e0428..ea44f1577b 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -555,7 +555,7 @@ static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare, struct BoxP availableIVs[i] = i; } - // Select the 3 IVs that will be inherited. + // Select which IVs that will be inherited. for (i = 0; i < howManyIVs; i++) { selectedIvs[i] = availableIVs[Random() % (NUM_STATS - i)]; From 68ee9e5739c64c91a77a71a5b0260a1d99e36649 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Mon, 30 Jan 2023 13:57:59 +0100 Subject: [PATCH 3/5] Restore bugfix Ooopsie! --- src/daycare.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/daycare.c b/src/daycare.c index ea44f1577b..54a5e4c8f4 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -558,8 +558,20 @@ static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare, struct BoxP // Select which IVs that will be inherited. for (i = 0; i < howManyIVs; i++) { + // Randomly pick an IV from the available list and stop from being chosen again. + // BUG: Instead of removing the IV that was just picked, this + // removes position 0 (HP) then position 1 (DEF), then position 2. This is why HP and DEF + // have a lower chance to be inherited in Emerald and why the IV picked for inheritance can + // be repeated. Amusingly, FRLG and RS also got this wrong. They remove selectedIvs[i], which + // is not an index! This means that it can sometimes remove the wrong stat. + #ifndef BUGFIX selectedIvs[i] = availableIVs[Random() % (NUM_STATS - i)]; RemoveIVIndexFromList(availableIVs, i); + #else + u8 index = Random() % (NUM_STATS - i); + selectedIvs[i] = availableIVs[index]; + RemoveIVIndexFromList(availableIVs, index); + #endif } // Determine which parent each of the selected IVs should inherit from. From 424f457ec2abedf04848cdfdba54758b16bae3b9 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Tue, 31 Jan 2023 09:44:47 +0100 Subject: [PATCH 4/5] Remove unused INHERITED_IV_COUNT define --- include/constants/daycare.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/constants/daycare.h b/include/constants/daycare.h index ac48e4f716..782bbe9546 100644 --- a/include/constants/daycare.h +++ b/include/constants/daycare.h @@ -13,7 +13,6 @@ #define DAYCARE_ONE_MON 2 #define DAYCARE_TWO_MONS 3 -#define INHERITED_IV_COUNT 3 #if P_EGG_HATCH_LEVEL >= GEN_4 #define EGG_HATCH_LEVEL 1 #else From 767008427f6abb9a22a9a7d6dc9f23596f639523 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Tue, 31 Jan 2023 09:47:02 +0100 Subject: [PATCH 5/5] Don't pass down daycare like AlterEggSpeciesWithIncenseItem --- src/daycare.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/daycare.c b/src/daycare.c index 54a5e4c8f4..cabecc8ea5 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -537,8 +537,10 @@ static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) } } -static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare, struct BoxPokemon *father, struct BoxPokemon *mother) +static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare) { + u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM); + u16 fatherItem = GetBoxMonData(&daycare->mons[1].mon, MON_DATA_HELD_ITEM); u8 i; u8 selectedIvs[5]; u8 availableIVs[NUM_STATS]; @@ -546,7 +548,7 @@ static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare, struct BoxP u8 iv; u8 howManyIVs = 3; - if (GetBoxMonData(father, MON_DATA_HELD_ITEM) == ITEM_DESTINY_KNOT || GetBoxMonData(mother, MON_DATA_HELD_ITEM) == ITEM_DESTINY_KNOT) + if (motherItem == ITEM_DESTINY_KNOT || fatherItem == ITEM_DESTINY_KNOT) howManyIVs = 5; // Initialize a list of IV indices. @@ -902,7 +904,7 @@ static void _GiveEggFromDaycare(struct DayCare *daycare) AlterEggSpeciesWithIncenseItem(&species, daycare); #endif SetInitialEggData(&egg, species, daycare); - InheritIVs(&egg, daycare, &daycare->mons[parentSlots[1]].mon, &daycare->mons[parentSlots[0]].mon); + InheritIVs(&egg, daycare); InheritPokeball(&egg, &daycare->mons[parentSlots[1]].mon, &daycare->mons[parentSlots[0]].mon); BuildEggMoveset(&egg, &daycare->mons[parentSlots[1]].mon, &daycare->mons[parentSlots[0]].mon);