Merge pull request #997 from javierhimura/master

Gen3 WasEgg Pokemon in gen 4 or later, Gen 4 transfer encounter
This commit is contained in:
Kurt 2017-03-26 19:08:02 -07:00 committed by GitHub
commit 5b892eb7ec
10 changed files with 185 additions and 18 deletions

View file

@ -494,7 +494,7 @@ namespace PKHeX.Core
private CheckResult verifyEncounterEgg() private CheckResult verifyEncounterEgg()
{ {
// Check Species // Check Species
if (Legal.NoHatchFromEgg.Contains(pkm.Species)) if (Legal.NoHatchFromEgg.Contains(pkm.Species) && (pkm.GenNumber != 4 || pkm.Species == 490))
return new CheckResult(Severity.Invalid, V50, CheckIdentifier.Encounter); return new CheckResult(Severity.Invalid, V50, CheckIdentifier.Encounter);
switch (pkm.GenNumber) switch (pkm.GenNumber)
@ -659,6 +659,19 @@ namespace PKHeX.Core
{ {
var s = (EncounterStatic)EncounterMatch; var s = (EncounterStatic)EncounterMatch;
if (pkm.GenNumber == 3 && pkm.Species == 151 && s.Location == 201 && pkm.Language != 1)
{
return new CheckResult(Severity.Invalid, V353, CheckIdentifier.Encounter);
}
if (pkm.GenNumber == 4 && pkm.Species == 493 && s.Location == 086)
{
return new CheckResult(Severity.Invalid, V352, CheckIdentifier.Encounter);
}
if (pkm.GenNumber == 4 && pkm.Species == 492 && s.Location == 063 && pkm.Version != (int)GameVersion.Pt)
{
return new CheckResult(Severity.Invalid, V354, CheckIdentifier.Encounter);
}
// Re-parse relearn moves // Re-parse relearn moves
if (s.EggLocation != 60002 || vRelearn.Any(rl => !rl.Valid)) if (s.EggLocation != 60002 || vRelearn.Any(rl => !rl.Valid))
{ {
@ -722,6 +735,16 @@ namespace PKHeX.Core
if (pkm.WasLink) if (pkm.WasLink)
return verifyEncounterLink(); return verifyEncounterLink();
if (pkm.Gen3 && !pkm.HasOriginalMetLocation)
{
return verifyEncounterG3Transfer();
}
if (pkm.Gen4 && !pkm.HasOriginalMetLocation)
{
return verifyEncounterG4Transfer();
}
bool wasEvent = pkm.WasEvent || pkm.WasEventEgg; bool wasEvent = pkm.WasEvent || pkm.WasEventEgg;
if (wasEvent) if (wasEvent)
{ {
@ -755,6 +778,120 @@ namespace PKHeX.Core
? new CheckResult(Severity.Invalid, V78, CheckIdentifier.Encounter) ? new CheckResult(Severity.Invalid, V78, CheckIdentifier.Encounter)
: new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter); : new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
} }
private CheckResult verifyEncounterG3Transfer()
{
CheckResult InvalidTransferResult = null;
CheckResult EggResult = null;
CheckResult NonEggResult = null;
bool WasEgg = Legal.getWasEgg23(pkm) && !Legal.NoHatchFromEgg.Contains(pkm.Species);
if (WasEgg)
{
pkm.WasEgg = true;
EggResult = verifyEncounterEgg3Transfer();
if (pkm.IsEgg)
return EggResult;
}
if (pkm.Format == 4 && pkm.Met_Location != 0x37) // Pal Park
InvalidTransferResult = new CheckResult(Severity.Invalid, V60, CheckIdentifier.Encounter);
if (pkm.Format != 4 && pkm.Met_Location != 30001)
InvalidTransferResult = new CheckResult(Severity.Invalid, V61, CheckIdentifier.Encounter);
// TODO: Include also gen 3 events
if (null != (EncounterMatch = Legal.getValidStaticEncounter(pkm)))
{
NonEggResult = verifyEncounterStatic();
}
if (NonEggResult !=null)
{
EncounterMatch = null; // Reset Encounter Object, test for remaining encounters
if (null != (EncounterMatch = Legal.getValidWildEncounters(pkm)))
NonEggResult = verifyEncounterWild();
if (null != (EncounterMatch = Legal.getValidIngameTrade(pkm)))
NonEggResult = verifyEncounterTrade();
}
// InvalidTransferResult have preference, because is invalid that from the current generation
if (InvalidTransferResult != null)
return InvalidTransferResult;
// Even if EggResult is not returned WasEgg is keep true to check in verifymoves first the
// non egg encounter moves and after that egg encounter moves, because there is no way to tell
// what of the two encounters was the real origin
if (EggResult != null && NonEggResult!=null)
{
// InvalidTransferResult have preference, because is invalid data from the current generation
if (NonEggResult.Valid)
return NonEggResult;
if (EggResult.Valid)
return EggResult;
// if both are invalid returns non egg information, because
// there is more data in the pokemon to found normal encounter
return NonEggResult;
}
// No egg result then it can be from egg, no non egg result then return there is no valid encounter found
if (EggResult == null && NonEggResult == null)
{
return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
}
return NonEggResult ?? InvalidTransferResult;
}
private CheckResult verifyEncounterG4Transfer()
{
CheckResult Gen4Result = null;
CheckResult InvalidTransferResult = null;
var CrownLocation = -1;
var AllowCrownLocation = pkm.Gen4 && pkm.FatefulEncounter && Legal.CrownBeasts.Contains(pkm.Species);
if (AllowCrownLocation)
CrownLocation = pkm.Species == 251 ? 30010 : 30012; // Celebi : Beast
if (pkm.Met_Location != 30001 && (!AllowCrownLocation || pkm.Met_Location != CrownLocation))
InvalidTransferResult = new CheckResult(Severity.Invalid, AllowCrownLocation ? V351 : V61, CheckIdentifier.Encounter);
bool wasEvent = pkm.WasEvent || pkm.WasEventEgg;
if (wasEvent)
{
var result = verifyEncounterEvent();
if (result != null)
Gen4Result = result;
}
if (Gen4Result == null && null != (EncounterMatch = Legal.getValidStaticEncounter(pkm)))
{
var result = verifyEncounterStatic();
if (result != null)
return result.Valid && InvalidTransferResult != null ? InvalidTransferResult : result;
EncounterMatch = null; // Reset Encounter Object, test for remaining encounters
}
if (pkm.WasEgg) // Invalid transfer is already checked in encounter egg
return verifyEncounterEgg();
if (Gen4Result == null && null != (EncounterMatch = Legal.getValidFriendSafari(pkm)))
Gen4Result = verifyEncounterSafari();
if (Gen4Result == null && null != (EncounterMatch = Legal.getValidWildEncounters(pkm)))
Gen4Result = verifyEncounterWild();
if (Gen4Result == null && null != (EncounterMatch = Legal.getValidIngameTrade(pkm)))
Gen4Result = verifyEncounterTrade();
if (Gen4Result != null && InvalidTransferResult != null)
return Gen4Result.Valid ? InvalidTransferResult : Gen4Result;
if (Gen4Result != null || InvalidTransferResult != null)
return Gen4Result ?? InvalidTransferResult;
return wasEvent
? new CheckResult(Severity.Invalid, V78, CheckIdentifier.Encounter)
: new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
}
private CheckResult verifyVCEncounter(int baseSpecies) private CheckResult verifyVCEncounter(int baseSpecies)
{ {
// Sanitize Species to non-future species# // Sanitize Species to non-future species#
@ -2202,6 +2339,16 @@ namespace PKHeX.Core
{ {
CheckResult[] res = new CheckResult[4]; CheckResult[] res = new CheckResult[4];
if(pkm.GenNumber == 3 && !pkm.HasOriginalMetLocation && EncounterMatch !=null)
{
if (EventGiftMatch?.Count > 1) // Multiple possible Mystery Gifts matched, get the best match too
res = parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor);
else // Everything else
res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, new int[0], GameVersion.Any);
if (res.All(r => r.Valid)) // moves is satisfactory
return res;
}
// Some games can have different egg movepools. Have to check all situations. // Some games can have different egg movepools. Have to check all situations.
GameVersion[] Games = { }; GameVersion[] Games = { };
switch (pkm.GenNumber) switch (pkm.GenNumber)

View file

@ -1090,7 +1090,7 @@ namespace PKHeX.Core
} }
internal static Tuple<object, int, byte> getEncounter12(PKM pkm, bool gen2) internal static Tuple<object, int, byte> getEncounter12(PKM pkm, bool gen2)
{ {
var g1 = getEncounter12(pkm, GameVersion.RBY); var g1 = pkm.IsEgg ? null :getEncounter12(pkm, GameVersion.RBY);
var g2 = gen2 ? getEncounter12(pkm, GameVersion.GSC) : null; var g2 = gen2 ? getEncounter12(pkm, GameVersion.GSC) : null;
if (g1 == null || g2 == null) if (g1 == null || g2 == null)
@ -1139,15 +1139,22 @@ namespace PKHeX.Core
return slots.Any() ? slots.ToArray() : null; return slots.Any() ? slots.ToArray() : null;
} }
private static bool getWasEgg23(PKM pkm) internal static bool getWasEgg23(PKM pkm)
{ {
if (pkm.IsEgg)
return true;
if (pkm.Format > 2 && pkm.Ball != 4) if (pkm.Format > 2 && pkm.Ball != 4)
return false; return false;
if (pkm.Format == 3)
return pkm.WasEgg;
int lvl = pkm.CurrentLevel; int lvl = pkm.CurrentLevel;
if (lvl < 5) if (lvl < 5)
return false; return false;
if(pkm.Format > 3 && pkm.Met_Level <5)
return false;
return getEvolutionValid(pkm); return getEvolutionValid(pkm);
} }

View file

@ -336,7 +336,11 @@ namespace PKHeX.Core
public static string V347 {get; set;} = "Inherited move learned by Level-up.Not expected in an event egg."; public static string V347 {get; set;} = "Inherited move learned by Level-up.Not expected in an event egg.";
public static string V348 {get; set;} = "Inherited tutor move. Not expected in an event egg."; public static string V348 {get; set;} = "Inherited tutor move. Not expected in an event egg.";
public static string V350 {get; set;} = "Inherited TM/HM move. Not expected in an event egg."; public static string V350 {get; set;} = "Inherited TM/HM move. Not expected in an event egg.";
public static string V351 {get; set;} = "Invalid Met Location, expected Transporter or Crown."; // Invalid
public static string V352 {get; set;} = "Arceus from Hall of Origin. Unreleased event.";
public static string V353 {get; set;} = "Non japanese Mew from Faraway Island. Unreleased event.";
public static string V354 {get; set;} = "Non Platinum Shaymin from Flower Paradise. Unreleased event.";
#endregion #endregion
} }
} }

View file

@ -265,7 +265,7 @@ namespace PKHeX.Core
new EncounterStatic { Species = 384, Level = 70, Location = 085, }, // Rayquaza @ Sky Pillar new EncounterStatic { Species = 384, Level = 70, Location = 085, }, // Rayquaza @ Sky Pillar
// Event // Event
new EncounterStatic { Species = 151, Level = 30, Location = 201, Version = GameVersion.E, Fateful = true }, // Mew @ Faraway Island new EncounterStatic { Species = 151, Level = 30, Location = 201, Version = GameVersion.E, Fateful = true }, // Mew @ Faraway Island (Unreleased outside of Japan)
new EncounterStatic { Species = 249, Level = 70, Location = 211, Version = GameVersion.E, }, // Lugia @ Navel Rock new EncounterStatic { Species = 249, Level = 70, Location = 211, Version = GameVersion.E, }, // Lugia @ Navel Rock
new EncounterStatic { Species = 250, Level = 70, Location = 211, Version = GameVersion.E, }, // Ho-Oh @ Navel Rock new EncounterStatic { Species = 250, Level = 70, Location = 211, Version = GameVersion.E, }, // Ho-Oh @ Navel Rock
new EncounterStatic { Species = 386, Level = 30, Location = 200, Version = GameVersion.E, Form = 3, Fateful = true }, // Deoxys @ Birth Island new EncounterStatic { Species = 386, Level = 30, Location = 200, Version = GameVersion.E, Form = 3, Fateful = true }, // Deoxys @ Birth Island

View file

@ -441,8 +441,8 @@ namespace PKHeX.Core
new EncounterStatic { Species = 490, Level = 01, EggLocation = 3001, Fateful = true, Gift = true }, //Manaphy from Pokemon Ranger new EncounterStatic { Species = 490, Level = 01, EggLocation = 3001, Fateful = true, Gift = true }, //Manaphy from Pokemon Ranger
new EncounterStatic { Species = 491, Level = 40, Location = 079, Version = GameVersion.DP,}, //Darkrai @ Newmoon Island new EncounterStatic { Species = 491, Level = 40, Location = 079, Version = GameVersion.DP,}, //Darkrai @ Newmoon Island
new EncounterStatic { Species = 491, Level = 50, Location = 079, Version = GameVersion.Pt,}, //Darkrai @ Newmoon Island new EncounterStatic { Species = 491, Level = 50, Location = 079, Version = GameVersion.Pt,}, //Darkrai @ Newmoon Island
new EncounterStatic { Species = 492, Form = 0, Level = 30, Location = 063, Fateful = true,}, //Shaymin @ Flower Paradise new EncounterStatic { Species = 492, Form = 0, Level = 30, Location = 063, Fateful = true,}, //Shaymin @ Flower Paradise (Unreleased in Diamond and Pearl)
//new EncounterStatic { Species = 493, Level = 80, Location = 086,}, //Arceus @ Hall of Origin new EncounterStatic { Species = 493, Form = 0, Level = 80, Location = 086,}, //Arceus @ Hall of Origin (Unreleased)
}; };
internal static readonly EncounterStatic[] Encounter_DPPt = Encounter_DPPt_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_DPPt)).Concat(Encounter_DPPt_Regular).ToArray(); internal static readonly EncounterStatic[] Encounter_DPPt = Encounter_DPPt_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_DPPt)).Concat(Encounter_DPPt_Regular).ToArray();

View file

@ -383,7 +383,9 @@ namespace PKHeX.Core
return pm6stat * 5 + maxIV % 5; return pm6stat * 5 + maxIV % 5;
} }
} }
// Legality Extensions
public override bool WasEgg => GenNumber < 4 ? base.WasEgg : Egg_Location > 0;
public override bool WasEvent => Met_Location >= 3000 && Met_Location <= 3076 || FatefulEncounter && Species != 386;
// Methods // Methods
public override byte[] Encrypt() public override byte[] Encrypt()
{ {

View file

@ -300,6 +300,9 @@ namespace PKHeX.Core
} }
} }
// Legality Extensions
public override bool WasEgg => GenNumber < 4 ? base.WasEgg : GenNumber == 4 ? Egg_Location > 0 : Legal.EggLocations.Contains(Egg_Location);
// Methods // Methods
public override byte[] Encrypt() public override byte[] Encrypt()
{ {

View file

@ -584,11 +584,11 @@ namespace PKHeX.Core
// Legality Properties // Legality Properties
public override bool WasLink => Met_Location == 30011; public override bool WasLink => Met_Location == 30011;
public override bool WasEgg => Legal.EggLocations.Contains(Egg_Location); public override bool WasEgg => GenNumber < 4 ? base.WasEgg : GenNumber == 4 ? Egg_Location > 0 : Legal.EggLocations.Contains(Egg_Location);
public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386; public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386;
public override bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1; public override bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1;
public override bool WasTradedEgg => Egg_Location == 30002; public override bool WasTradedEgg => Egg_Location == 30002 || GenNumber == 4 && Egg_Location == 2002;
public override bool WasIngameTrade => Met_Location == 30001; public override bool WasIngameTrade => Met_Location == 30001 || GenNumber == 4 && Egg_Location == 2001;
public PK7 convertToPK7() public PK7 convertToPK7()
{ {

View file

@ -621,10 +621,10 @@ namespace PKHeX.Core
// Legality Properties // Legality Properties
public override bool WasLink => Met_Location == 30011; public override bool WasLink => Met_Location == 30011;
public override bool WasEgg => Legal.EggLocations.Contains(Egg_Location); public override bool WasEgg => GenNumber < 4 ? base.WasEgg : GenNumber == 4 ? Egg_Location > 0 : Legal.EggLocations.Contains(Egg_Location);
public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386; public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386;
public override bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1; public override bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1;
public override bool WasTradedEgg => Egg_Location == 30002; public override bool WasTradedEgg => Egg_Location == 30002 || GenNumber == 4 && Egg_Location == 2002;
public override bool WasIngameTrade => Met_Location == 30001; public override bool WasIngameTrade => Met_Location == 30001 || GenNumber == 4 && Egg_Location == 2001;
} }
} }

View file

@ -271,3 +271,7 @@ V343 = Expected the following Moves: {0}
V347 = Inherited move learned by Level-up. Not expected in an event egg. V347 = Inherited move learned by Level-up. Not expected in an event egg.
V348 = Inherited tutor move. Not expected in an event egg. V348 = Inherited tutor move. Not expected in an event egg.
V350 = Inherited TM/HM move. Not expected in an event egg. V350 = Inherited TM/HM move. Not expected in an event egg.
V351 = Invalid Met Location, expected Transporter or Crown.
V352 = Arceus from Hall of Origin. Unreleased event.
V353 = Non japanese Mew from Faraway Island. Unreleased event.
V354 = Non Platinum Shaymin from Flower Paradise. Unreleased event.