mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-27 22:40:22 +00:00
Fix legality issues (#1055)
* Added method getBaseEggSpecies to get the base species when the pokemon was an egg, is needed because for format 1 pokemon with egg origin every time getBaseSpecies is called is returning the gen 1 base species obtaining invalid eggmoves and base egg moves Also getBaseEggSpecies was using Evolves1 when format = 1 even when asking for a gen2 egg base species, returning Pikachu egg moves (empty list) instead of Pichu egg moves * Fix ability checking for generation 3 pokemon, likea de Seadra from Issue #1011 pkm.AbilityNumber have a value assuming PID match ability like a generation 4 pokemon but the validation should be ignored if is a generation 3 pokemon with only one ability in generation 3 Also changed the validation for ingame trades with fixed abilities to check only with generation 3 abilities in the case the species has two abilities generation 3, if only one was possible any PID should be valid with the generation 3 ability Encounter Trades Also the check for evolution was wrong, the most evolved species is the first in the evochain, not the last * Fix evolution chains for gen 3 pokemon in format 4 * Fix ability for generation 3 trades. Ability could not change if there were 2 abilities in generation 3, that means it is irrelevant if the pokemon evolved in gen 4-5, the ability number must match the encounter
This commit is contained in:
parent
2f59710eee
commit
0af983547d
2 changed files with 40 additions and 19 deletions
|
@ -1242,8 +1242,9 @@ namespace PKHeX.Core
|
|||
return;
|
||||
}
|
||||
|
||||
if (EncounterMatch != null)
|
||||
if (EncounterMatch != null && (!pkm.Gen3 || pkm.Format ==3))
|
||||
{
|
||||
// Gen 3 transfered to 4 could change ability, defer to verifyAbilityPreCapsule
|
||||
// Check Ability Mismatches
|
||||
int? EncounterAbility = (EncounterMatch as EncounterStatic)?.Ability ??
|
||||
(EncounterMatch as EncounterTrade)?.Ability ??
|
||||
|
@ -1262,23 +1263,24 @@ namespace PKHeX.Core
|
|||
case 7: verifyAbility7(abilities); break;
|
||||
}
|
||||
}
|
||||
var AbilityMatchPID = true;
|
||||
if (3 <= pkm.Format && pkm.Format <= 5) // 3-5
|
||||
verifyAbilityPreCapsule(abilities, abilval);
|
||||
AbilityMatchPID = verifyAbilityPreCapsule(abilities, abilval);
|
||||
|
||||
if (3 <= pkm.GenNumber && pkm.GenNumber <= 4 && pkm.AbilityNumber == 4)
|
||||
AddLine(Severity.Invalid, V112, CheckIdentifier.Ability);
|
||||
else if (abilities[pkm.AbilityNumber >> 1] != pkm.Ability)
|
||||
else if (AbilityMatchPID && abilities[pkm.AbilityNumber >> 1] != pkm.Ability)
|
||||
AddLine(Severity.Invalid, V114, CheckIdentifier.Ability);
|
||||
else
|
||||
AddLine(Severity.Valid, V115, CheckIdentifier.Ability);
|
||||
}
|
||||
private void verifyAbilityPreCapsule(int[] abilities, int abilval)
|
||||
private bool verifyAbilityPreCapsule(int[] abilities, int abilval)
|
||||
{
|
||||
if (pkm.Version == (int)GameVersion.CXD)
|
||||
{
|
||||
// TODO for GameCube analysis
|
||||
AddLine(Severity.Valid, V115, CheckIdentifier.Ability);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
var abilities_count = abilities.Distinct().Count();
|
||||
|
@ -1288,7 +1290,7 @@ namespace PKHeX.Core
|
|||
// gen3Species will be zero for pokemon with illegal gen 3 encounters, like Infernape with gen 3 "origin"
|
||||
// Do not check for gen 3 pokemon that has evolved into gen 4 species,
|
||||
// those have evolved in generation 4 or 5 and ability must match PID, not need to check gen 3 data
|
||||
var gen3Species = EvoChainsAllGens[3].LastOrDefault()?.Species ?? 0;
|
||||
var gen3Species = EvoChainsAllGens[3].FirstOrDefault()?.Species ?? 0;
|
||||
if (gen3Species > 0)
|
||||
AbilityMatchPID = verifyAbilityGen3Transfer(abilities, abilval, gen3Species, abilities_count);
|
||||
}
|
||||
|
@ -1296,6 +1298,7 @@ namespace PKHeX.Core
|
|||
// Gen 4,5 pokemon or gen 3 pokemon evolved in gen 4,5 games, ability must match PID
|
||||
if (AbilityMatchPID && pkm.AbilityNumber != 1 << abilval)
|
||||
AddLine(Severity.Invalid, V113, CheckIdentifier.Ability);
|
||||
return AbilityMatchPID;
|
||||
}
|
||||
private bool verifyAbilityGen3Transfer(int[] abilities, int abilval, int Species_g3, int abilities_count)
|
||||
{
|
||||
|
@ -1305,11 +1308,17 @@ namespace PKHeX.Core
|
|||
var abilities_g3 = PersonalTable.E.getAbilities(Species_g3, pkm.AltForm).Where(a => a != 0).Distinct().ToArray();
|
||||
if (abilities_g3.Length == 2)
|
||||
{
|
||||
int? EncounterAbility = (EncounterMatch as EncounterTrade)?.Ability ?? null;
|
||||
// If there were two abilities in generation 3 then ability match PID in gen 3 (is impossible not to do it) and will be the same ability if evolved in gen 4-5
|
||||
if (EncounterAbility != null && EncounterAbility != 0 && pkm.AbilityNumber != EncounterAbility)
|
||||
{
|
||||
AddLine(Severity.Invalid, V223, CheckIdentifier.Ability);
|
||||
}
|
||||
// Shadow Colloseum pokemon could habe any PID without maching PID if has 2 abilities in generation 3
|
||||
// For non-GC, it has 2 abilities in gen 3, must match PID
|
||||
return pkm.Version != (int)GameVersion.CXD;
|
||||
}
|
||||
var Species_g45 = Math.Max(EvoChainsAllGens[4].LastOrDefault()?.Species ?? 0, pkm.Format == 5 ? EvoChainsAllGens[5].LastOrDefault()?.Species ?? 0 : 0);
|
||||
var Species_g45 = Math.Max(EvoChainsAllGens[4].FirstOrDefault()?.Species ?? 0, pkm.Format == 5 ? EvoChainsAllGens[5].FirstOrDefault()?.Species ?? 0 : 0);
|
||||
if (Species_g45 > Species_g3)
|
||||
// it have evolved in gen 4 or 5 games, ability must match PID
|
||||
return true;
|
||||
|
@ -2402,7 +2411,9 @@ namespace PKHeX.Core
|
|||
encounters.AddRange(EventGiftMatch.Where(x => (x as IMoveset)?.Moves != null));
|
||||
if (null != EncounterStaticMatch)
|
||||
encounters.AddRange(EncounterStaticMatch.Where(x => (x as IMoveset)?.Moves != null));
|
||||
if (null != (EncounterMatch as IMoveset)?.Moves)
|
||||
if (null != (EncounterMatch as EncounterTrade))
|
||||
encounters.Add(EncounterMatch);
|
||||
else if (null != (EncounterMatch as IMoveset)?.Moves)
|
||||
encounters.Add(EncounterMatch);
|
||||
|
||||
if (!pkm.IsEgg)
|
||||
|
@ -2576,7 +2587,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
for (int i = 0; i <= splitctr; i++)
|
||||
{
|
||||
var baseSpecies = Legal.getBaseSpecies(pkm, i);
|
||||
var baseSpecies = Legal.getBaseEggSpecies(pkm, i);
|
||||
if (baseSpecies != pkm.Species)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -958,7 +958,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
internal static IEnumerable<int> getBaseEggMoves(PKM pkm, int skipOption, GameVersion gameSource, int lvl)
|
||||
{
|
||||
int species = getBaseSpecies(pkm, skipOption);
|
||||
int species = getBaseEggSpecies(pkm, skipOption);
|
||||
|
||||
if (gameSource == GameVersion.Any)
|
||||
gameSource = (GameVersion) pkm.Version;
|
||||
|
@ -1049,7 +1049,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
internal static IEnumerable<int> getEggMoves(PKM pkm, int skipOption, GameVersion Version)
|
||||
{
|
||||
return getEggMoves(pkm, getBaseSpecies(pkm, skipOption), 0, Version);
|
||||
return getEggMoves(pkm, getBaseEggSpecies(pkm, skipOption), 0, Version);
|
||||
}
|
||||
internal static IEnumerable<EncounterStatic> getG3SpecialEggEncounter(PKM pkm)
|
||||
{
|
||||
|
@ -1606,7 +1606,7 @@ namespace PKHeX.Core
|
|||
if (t != null && t.TID != 0)
|
||||
return new GBEncounterData(pkm, 2, t); // gen2 trade
|
||||
if (WasEgg && new[] { sm, em, tm }.Min(a => a) >= 5)
|
||||
return new GBEncounterData(getBaseSpecies(pkm, maxSpeciesOrigin: MaxSpeciesID_2)); // gen2 egg
|
||||
return new GBEncounterData(getBaseEggSpecies(pkm)); // gen2 egg
|
||||
}
|
||||
if (em <= sm && em <= tm)
|
||||
return new GBEncounterData(pkm, gen, e.Where(slot => slot.Species == em).OrderBy(slot => slot.LevelMin).First());
|
||||
|
@ -1697,7 +1697,11 @@ namespace PKHeX.Core
|
|||
// Generation Specific Fetching
|
||||
private static EvolutionTree getEvolutionTable(PKM pkm)
|
||||
{
|
||||
switch (pkm.Format)
|
||||
return getEvolutionTable(pkm.Format);
|
||||
}
|
||||
private static EvolutionTree getEvolutionTable(int generation)
|
||||
{
|
||||
switch (generation)
|
||||
{
|
||||
case 1:
|
||||
return Evolves1;
|
||||
|
@ -2283,15 +2287,21 @@ namespace PKHeX.Core
|
|||
return true;
|
||||
return getValidMoves(pkm, version, getValidPreEvolutions(pkm).ToArray(), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
|
||||
}
|
||||
|
||||
internal static int getBaseSpecies(PKM pkm, int skipOption = 0, int maxSpeciesOrigin = -1)
|
||||
internal static int getBaseEggSpecies(PKM pkm, int skipOption = 0)
|
||||
{
|
||||
if (pkm.Format == 1)
|
||||
return getBaseSpecies(pkm, skipOption : skipOption, generation : 2);
|
||||
return getBaseSpecies(pkm, skipOption);
|
||||
}
|
||||
internal static int getBaseSpecies(PKM pkm, int skipOption = 0, int generation = -1)
|
||||
{
|
||||
if (pkm.Species == 292)
|
||||
return 290;
|
||||
if (pkm.Species == 242 && pkm.CurrentLevel < 3) // Never Cleffa
|
||||
return 113;
|
||||
|
||||
var table = getEvolutionTable(pkm);
|
||||
var table = generation != -1 ? getEvolutionTable(generation): getEvolutionTable(pkm);
|
||||
int maxSpeciesOrigin = generation != -1 ? getMaxSpeciesOrigin(generation) : - 1;
|
||||
var evos = table.getValidPreEvolutions(pkm, 100, maxSpeciesOrigin: maxSpeciesOrigin, skipChecks:true).ToArray();
|
||||
|
||||
switch (skipOption)
|
||||
|
@ -2350,7 +2360,7 @@ namespace PKHeX.Core
|
|||
if (pkm.Format <= 2)
|
||||
return 2;
|
||||
|
||||
if (!pkm.HasOriginalMetLocation)
|
||||
if (!pkm.HasOriginalMetLocation && generation != pkm.GenNumber)
|
||||
return pkm.Met_Level;
|
||||
|
||||
if (pkm.GenNumber <= 3)
|
||||
|
@ -2392,7 +2402,7 @@ namespace PKHeX.Core
|
|||
continue;
|
||||
if ((pkm.Gen2 || pkm.VC2) && 3 <= gen && gen <= 6)
|
||||
continue;
|
||||
if (!pkm.HasOriginalMetLocation && pkm.Format > 2 && gen <= 4 && lvl > pkm.Met_Level)
|
||||
if (!pkm.HasOriginalMetLocation && pkm.Format > 2 && gen < pkm.Format && gen <= 4 && lvl > pkm.Met_Level)
|
||||
{
|
||||
// Met location was lost at this point but it also means the pokemon existed in generations 1 to 4 with maximum level equals to met level
|
||||
lvl = pkm.Met_Level;
|
||||
|
@ -2430,7 +2440,7 @@ namespace PKHeX.Core
|
|||
//Remove previous evolutions bellow transfer level
|
||||
//For example a gen3 charizar in format 7 with current level 36 and met level 36
|
||||
//chain level for charmander is 35, is bellow met level
|
||||
GensEvoChains[gen] = GensEvoChains[gen].Where(e => e.Level >= lvl).ToArray();
|
||||
GensEvoChains[gen] = GensEvoChains[gen].Where(e => e.Level >= getMinLevelGeneration(pkm,gen)).ToArray();
|
||||
}
|
||||
return GensEvoChains;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue