mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-28 13:26:30 -05:00
Handle baby->mother parent fetch
Need to fix something with volbeat/nido for inheritance still.
This commit is contained in:
@@ -51,13 +51,14 @@ public ReadOnlySpan<ushort> GetEggMoves(ushort species, byte form)
|
||||
}
|
||||
|
||||
// Present and not in Crystal:
|
||||
// 001 (Bulbasaur) += Charm
|
||||
// 016 (Pidgey) += SteelWing
|
||||
// 043 (Oddish) += Charm
|
||||
// 046 (Paras) += SweetScent
|
||||
// 083 (Farfetchd) += SteelWing
|
||||
// 120 (Staryu) += AuroraBeam, Barrier, Supersonic
|
||||
// 142 (Aerodactyl) += SteelWing
|
||||
// Inaccessible (no father in same egg group):
|
||||
// 001 (Bulbasaur) += Charm
|
||||
// 043 (Oddish) += Charm
|
||||
// 120 (Staryu) += AuroraBeam, Barrier, Supersonic
|
||||
// 143 (Snorlax) += Charm
|
||||
// 238 (Smoochum) += LovelyKiss
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ public static bool TryValidate(ushort species, byte form, GameVersion version, R
|
||||
// For male-only split breed species (Volbeat/Nidoran-M) in Gen 2-5, we need special validation:
|
||||
// All EGG moves must come from a single father.
|
||||
// Level-up moves don't need this restriction (can breed with Ditto).
|
||||
// No cases of chain breeding combinations, so we can just check if a single father can pass all egg moves.
|
||||
var isMaleSplit = IsMaleOnlySplitBreed(species);
|
||||
if (isMaleSplit)
|
||||
{
|
||||
@@ -239,18 +240,7 @@ private static bool CanSingleFatherPassAllMoves(ushort motherSpecies, byte mothe
|
||||
continue;
|
||||
|
||||
// Check if this father can learn ALL the moves
|
||||
bool canLearnAll = true;
|
||||
foreach (var move in moves)
|
||||
{
|
||||
if (move == 0)
|
||||
break;
|
||||
|
||||
// Father must be able to learn this move as an egg move or level-up move
|
||||
if (CanFatherLearnMoveForEgg(fatherSpecies, fatherForm, move, learn))
|
||||
continue;
|
||||
canLearnAll = false;
|
||||
break;
|
||||
}
|
||||
var canLearnAll = CanFatherLearnAll(moves, fatherSpecies, fatherForm, learn);
|
||||
if (!canLearnAll)
|
||||
continue;
|
||||
|
||||
@@ -262,6 +252,20 @@ private static bool CanSingleFatherPassAllMoves(ushort motherSpecies, byte mothe
|
||||
return false; // No single father can pass all moves
|
||||
}
|
||||
|
||||
private static bool CanFatherLearnAll(ReadOnlySpan<ushort> moves, ushort fatherSpecies, byte fatherForm, ILearnSource learn)
|
||||
{
|
||||
foreach (var move in moves)
|
||||
{
|
||||
if (move == 0)
|
||||
break;
|
||||
// Father must be able to learn this move as an egg move or level-up move
|
||||
if (CanFatherLearnMoveForEgg(fatherSpecies, fatherForm, move, learn))
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool CanMotherAndFatherPassAllMoves(ushort motherSpecies, byte motherForm, GameVersion version, ReadOnlySpan<ushort> moves, out ChainBreedSummary summary)
|
||||
{
|
||||
// For male-only split breed species in Gen 6-7:
|
||||
@@ -423,8 +427,7 @@ private static bool TryValidateBaseCounts(ushort eggSpecies, byte eggForm, GameV
|
||||
|
||||
var suffix = moves.Slice(baseCount, inheritedCount);
|
||||
var suffixFlags = flags.Slice(baseCount, inheritedCount);
|
||||
for (int i = 0; i < inheritedCount; i++)
|
||||
inheritedMoves[i] = suffix[i];
|
||||
suffix.CopyTo(inheritedMoves);
|
||||
|
||||
if (TryResolveInheritedSources(eggSpecies, eggForm, version, inheritedMoves[..inheritedCount], suffixFlags, 0, visited, depth + 1, out summary))
|
||||
return true;
|
||||
@@ -463,6 +466,8 @@ private static bool TryResolveFather(ushort eggSpecies, byte eggForm, GameVersio
|
||||
return false;
|
||||
|
||||
var mother = table[eggSpecies, eggForm];
|
||||
if (mother.EggGroup1 == (int)EggGroup.Undiscovered && TryGetEvolvedMother(eggSpecies, eggForm, version, out var newMother))
|
||||
mother = table[newMother.Species, newMother.Form];
|
||||
|
||||
// If the egg species can't breed (baby Pokemon like Tyrogue), check if its evolutions can act as fathers
|
||||
if (mother.Genderless || mother.OnlyMale || mother.EggGroup1 == (int)EggGroup.Undiscovered)
|
||||
@@ -496,9 +501,28 @@ private static bool TryResolveFather(ushort eggSpecies, byte eggForm, GameVersio
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryGetEvolvedMother(ushort eggSpecies, byte eggForm, GameVersion version, out (ushort Species, byte Form) newMother)
|
||||
{
|
||||
var tree = EvolutionTree.GetEvolutionTree(version.Context);
|
||||
var evos = tree.Forward.GetEvolutions(eggSpecies, eggForm);
|
||||
var pt = GameData.GetPersonal(version);
|
||||
|
||||
foreach (var (evoSpecies, evoForm) in evos)
|
||||
{
|
||||
var pi = pt[evoSpecies, evoForm];
|
||||
if (pi.EggGroup1 == (int)EggGroup.Undiscovered)
|
||||
continue;
|
||||
|
||||
newMother = (evoSpecies, evoForm);
|
||||
return true;
|
||||
|
||||
}
|
||||
newMother = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryResolveFatherViaEvolution(ushort eggSpecies, byte eggForm, GameVersion version, ReadOnlySpan<ushort> moves, Span<ChainQueryState> visited, int depth, out ChainBreedSummary summary)
|
||||
{
|
||||
summary = default;
|
||||
var tree = EvolutionTree.GetEvolutionTree(version.Context);
|
||||
var evos = tree.Forward.GetEvolutions(eggSpecies, eggForm);
|
||||
|
||||
@@ -511,6 +535,7 @@ private static bool TryResolveFatherViaEvolution(ushort eggSpecies, byte eggForm
|
||||
return true;
|
||||
}
|
||||
|
||||
summary = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ public void DetectsInvalidChains(GameVersion version, Species species, params Mo
|
||||
[InlineData(HGSS, Mankey, Encore, Meditate, SmellingSalts)]
|
||||
[InlineData(GS, Chansey, DoubleEdge)] // via Jigglypuff (Level 39)
|
||||
[InlineData(Pt, Shellder, RapidSpin, IcicleSpear)]
|
||||
[InlineData(R, Volbeat, HelpingHand)] // level up, breed with Illumise
|
||||
public void DetectsValidChains(GameVersion version, Species species, params Move[] movelist)
|
||||
=> ValidateSimple(version, species, 0, movelist);
|
||||
|
||||
@@ -60,6 +61,7 @@ private static void ValidateSimple(GameVersion version, Species species, byte fo
|
||||
|
||||
[Theory]
|
||||
[InlineData(HGSS, Mankey, 0, Smeargle, Encore, Meditate, SmellingSalts)]
|
||||
[InlineData(E, Pichu, 0, Smeargle, Reversal, Encore, Wish, Present)] // via Pikachu mother
|
||||
public void DetectsValidChainSmeargle(GameVersion version, Species species, byte form, Species father, params Move[] movelist)
|
||||
{
|
||||
var moves = GetMoves(movelist);
|
||||
|
||||
Reference in New Issue
Block a user