Add more strict ball checks

Sport/Apricorn/Safari/Dream checked

Also snuck in encountertype tracking for readability/calcOnce
This commit is contained in:
Kaphotics 2016-03-27 22:05:51 -07:00
parent 908ff709c6
commit 65901f7f41
4 changed files with 104 additions and 19 deletions

View file

@ -8,6 +8,7 @@ namespace PKHeX
{
private readonly PK6 pk6;
private object EncounterMatch;
private Type EncounterType;
private LegalityCheck ECPID, Nickname, IDs, IVs, EVs, Encounter, Level, Ribbons, Ability, Ball, HandlerMemories;
public bool Valid = true;
@ -43,6 +44,7 @@ namespace PKHeX
private void updateChecks()
{
Encounter = verifyEncounter();
EncounterType = EncounterMatch?.GetType();
ECPID = verifyECPID();
Nickname = verifyNickname();
IDs = verifyID();

View file

@ -70,9 +70,8 @@ namespace PKHeX
if (pk6.Language > 8)
return new LegalityCheck(Severity.Indeterminate, "Language ID > 8.");
Type etype = EncounterMatch?.GetType();
if (etype == typeof(EncounterTrade))
if (EncounterType == typeof(EncounterTrade))
{
string[] validOT = new string[0];
int index = -1;
@ -303,7 +302,7 @@ namespace PKHeX
if (EventRib[i] ^ wc6rib[i]) // Mismatch
(wc6rib[i] ? missingRibbons : invalidRibbons).Add(EventRibName[i]);
}
else if (EncounterMatch?.GetType() == typeof(EncounterLink))
else if (EncounterType == typeof(EncounterLink))
{
// No Event Ribbons except Classic (unless otherwise specified, ie not for Demo)
for (int i = 0; i < EventRib.Length; i++)
@ -356,14 +355,13 @@ namespace PKHeX
if (EncounterMatch != null)
{
Type etype = EncounterMatch.GetType();
if (etype == typeof(EncounterStatic))
if (EncounterType == typeof(EncounterStatic))
if (pk6.AbilityNumber == 4 ^ ((EncounterStatic)EncounterMatch).Ability == 4)
return new LegalityCheck(Severity.Invalid, "Hidden Ability mismatch for static encounter.");
if (etype == typeof(EncounterTrade))
if (EncounterType == typeof(EncounterTrade))
if (pk6.AbilityNumber == 4 ^ ((EncounterTrade)EncounterMatch).Ability == 4)
return new LegalityCheck(Severity.Invalid, "Hidden Ability mismatch for ingame trade.");
if (etype == typeof (EncounterSlot[]) && pk6.AbilityNumber == 4)
if (EncounterType == typeof (EncounterSlot[]) && pk6.AbilityNumber == 4)
if (((EncounterSlot[]) EncounterMatch).All(slot => slot.Type != SlotType.FriendSafari) &&
((EncounterSlot[]) EncounterMatch).All(slot => slot.Type != SlotType.Horde))
return new LegalityCheck(Severity.Invalid, "Hidden Ability on non-horde/friend safari wild encounter.");
@ -388,29 +386,58 @@ namespace PKHeX
{
if (pk6.Ball == 0x01) // Master Ball
return new LegalityCheck(Severity.Invalid, "Master Ball on egg origin.");
if (pk6.Ball == 0x10) // Cherish
if (pk6.Ball == 0x10) // Cherish Ball
return new LegalityCheck(Severity.Invalid, "Cherish Ball on non-event.");
if (pk6.Ball == 0x05 && pk6.Species > 493) // Safari
return new LegalityCheck(Severity.Invalid, "Safari Ball on Gen5+ species.");
if (pk6.Gender == 2) // Genderless
return pk6.Ball != 0x04 // Must be Pokéball as ball can only pass via mother (not Ditto!)
? new LegalityCheck(Severity.Invalid, "Non-Pokéball on genderless egg.")
: new LegalityCheck(Severity.Valid, "Pokéball on genderless egg.");
if (Legal.BreedMaleOnly.Contains(pk6.Species))
return pk6.Ball != 0x04 // Must be Pokéball as ball can only pass via mother (not Ditto!)
? new LegalityCheck(Severity.Invalid, "Non-Pokéball on Male-Only egg.")
: new LegalityCheck(Severity.Valid, "Pokéball on Male-Only egg.");
if (pk6.AbilityNumber == 4 && 0x10 < pk6.Ball && pk6.Ball < 0x18) // Apricorn Ball
return new LegalityCheck(Severity.Invalid, "Apricorn Ball with Hidden Ability.");
if (pk6.Ball == 0x05) // Safari Ball
{
if (Legal.getLineage(pk6).All(e => !Legal.Inherit_Safari.Contains(e)))
return new LegalityCheck(Severity.Invalid, "Safari Ball not possible for species.");
if (pk6.AbilityNumber == 4)
return new LegalityCheck(Severity.Invalid, "Safari Ball with Hidden Ability.");
return new LegalityCheck(Severity.Valid, "Safari Ball possible for species.");
}
if (0x10 < pk6.Ball && pk6.Ball < 0x18) // Apricorn Ball
{
if (Legal.getLineage(pk6).All(e => !Legal.Inherit_Apricorn.Contains(e)))
return new LegalityCheck(Severity.Invalid, "Apricorn Ball not possible for species.");
if (pk6.AbilityNumber == 4)
return new LegalityCheck(Severity.Invalid, "Apricorn Ball with Hidden Ability.");
return new LegalityCheck(Severity.Valid, "Apricorn Ball possible for species.");
}
if (pk6.Ball == 0x18) // Sport Ball
{
if (Legal.getLineage(pk6).All(e => !Legal.Inherit_Sport.Contains(e)))
return new LegalityCheck(Severity.Invalid, "Sport Ball not possible for species.");
if (pk6.AbilityNumber == 4)
return new LegalityCheck(Severity.Invalid, "Sport Ball with Hidden Ability.");
return new LegalityCheck(Severity.Valid, "Sport Ball possible for species.");
}
if (pk6.Ball == 0x19) // Dream Ball
{
if (Legal.getLineage(pk6).All(e => !Legal.Inherit_Dream.Contains(e)))
return new LegalityCheck(Severity.Invalid, "Dream Ball not possible for species.");
return new LegalityCheck(Severity.Valid, "Dream Ball possible for species.");
}
if (pk6.Species > 650 && pk6.Species != 700) // Sylveon
return !Legal.WildPokeballs.Contains(pk6.Ball)
? new LegalityCheck(Severity.Invalid, "Unobtainable ball for Kalos origin.")
: new LegalityCheck(Severity.Valid, "Obtainable ball for Kalos origin.");
// Feel free to improve, there's a lot of very minor things to check for some species.
return new LegalityCheck(Severity.Valid, "Obtainable ball for past gen origin parent.");
}
@ -425,13 +452,12 @@ namespace PKHeX
? new LegalityCheck(Severity.Invalid, "Incorrect ball on Link gift.")
: new LegalityCheck(Severity.Valid, "Correct ball on Link gift.");
}
Type etype = EncounterMatch?.GetType();
if (etype == typeof(EncounterLink))
if (EncounterType == typeof(EncounterLink))
return ((EncounterLink)EncounterMatch).Ball != pk6.Ball
? new LegalityCheck(Severity.Invalid, "Incorrect ball on Link gift.")
: new LegalityCheck(Severity.Valid, "Correct ball on Link gift.");
if (etype == typeof(EncounterTrade))
if (EncounterType == typeof(EncounterTrade))
return pk6.Ball != 4 // Pokeball
? new LegalityCheck(Severity.Invalid, "Incorrect ball on ingame trade encounter.")
: new LegalityCheck(Severity.Valid, "Correct ball on ingame trade encounter.");
@ -580,7 +606,7 @@ namespace PKHeX
if (res.All(r => r.Valid))
{ EncounterMatch = wc; RelearnBase = moves; return res; }
}
EncounterMatch = null;
EncounterMatch = EncounterType = null;
goto noRelearn; // No WC match
}

View file

@ -351,6 +351,13 @@ namespace PKHeX
return false;
}
internal static IEnumerable<int> getLineage(PK6 pk6)
{
List<int> res = new List<int>();
for (int i = -1; i < 2; i++)
res.Add(getBaseSpecies(pk6, i));
return res.Distinct();
}
private static int getBaseSpecies(PK6 pk6, int skipOption = 0)
{

View file

@ -688,5 +688,55 @@
};
#endregion
#region Ball Table
internal static readonly int[] Inherit_Sport =
{
010, 013, 046, 048, 123, 127, 265, 290, 314, 401, 415,
313, // Via Illumise
};
internal static readonly int[] Inherit_Apricorn =
{
010, 013, 016, 019, 021, 023, 025, 027, 029, 035, 037, 039, 041,
043, 046, 048, 050, 052, 054, 056, 058, 060, 063, 066, 069, 072, 074, 077, 079, 083, 084, 086, 088, 090, 092,
095, 096, 098, 102, 104, 108, 109, 111, 113, 114, 115, 116, 118, 122, 124, 125, 126, 129, 131, 143, 147, 161,
163, 165, 167, 170, 177, 179, 183, 185, 187, 190, 191, 193, 194, 198, 200, 202, 203, 204, 206, 207, 209, 211,
213, 214, 215, 216, 218, 220, 222, 223, 225, 226, 227, 228, 231, 234, 235, 241, 246, 261, 263, 265, 273, 276,
278, 280, 285, 287, 293, 296, 302, 303, 307, 311, 312, 316, 322, 325, 327, 333, 340, 359, 366, 369, 370, 396,
399, 401, 403, 406, 412, 415, 418, 420, 427, 433, 441, 455,
032, // Via Nidoran-F
};
internal static readonly int[] Inherit_Safari =
{
016, 019, 020, 021, 022, 023, 024, 025, 027, 029, 035, 039, 041,
043, 046, 048, 050, 054, 055, 060, 063, 066, 069, 070, 074, 077, 079, 080, 083, 084, 088, 092, 095, 096, 098,
099, 102, 104, 108, 109, 111, 113, 114, 115, 118, 122, 123, 125, 126, 127, 129, 131, 147, 161, 163, 165, 167,
177, 179, 183, 187, 189, 190, 191, 193, 194, 198, 200, 202, 203, 204, 207, 209, 213, 214, 216, 223, 228, 229,
231, 234, 235, 241, 246, 263, 264, 270, 271, 273, 283, 284, 285, 286, 288, 298, 299, 304, 305, 307, 308, 309,
310, 314, 315, 316, 318, 324, 327, 328, 331, 332, 335, 336, 339, 341, 352, 353, 354, 355, 356, 357, 358, 363,
364, 371, 372, 397, 399, 400, 403, 404, 406, 417, 418, 419, 433, 443, 447, 449, 451, 453, 455,
032, // Via Nidoran-F
313, // Via Illumise
};
internal static readonly int[] Inherit_Dream =
{
012, 015, 016, 019, 021, 023, 027, 029, 037, 041, 043, 046, 048, 050, 052, 054, 056, 058, 060, 063, 066, 069,
072, 074, 077, 079, 083, 084, 086, 088, 090, 092, 095, 096, 098, 102, 104, 108, 109, 111, 113, 114, 115, 116,
118, 122, 123, 127, 129, 131, 133, 138, 140, 142, 143, 147, 161, 163, 165, 167, 170, 173, 174, 175, 177, 179,
183, 185, 187, 190, 191, 193, 194, 198, 200, 202, 203, 204, 206, 207, 209, 211, 213, 214, 215, 216, 218, 220,
222, 223, 225, 226, 227, 228, 231, 234, 235, 238, 239, 240, 241, 246, 261, 263, 265, 270, 273, 276, 278, 280,
283, 285, 287, 290, 293, 296, 299, 300, 302, 303, 304, 307, 309, 311, 312, 314, 315, 316, 318, 320, 322, 324,
325, 327, 328, 331, 333, 335, 336, 339, 341, 345, 347, 349, 351, 352, 353, 355, 357, 358, 359, 361, 363, 366,
369, 370, 371, 397, 399, 401, 403, 408, 410, 412, 415, 417, 418, 420, 422, 425, 427, 431, 434, 441, 442, 443,
447, 449, 451, 453, 455, 456, 459, 517, 519, 525, 529, 531, 533, 535, 545, 546, 548, 550, 553, 556, 558, 559,
561, 564, 578, 580, 583, 587, 588, 594, 596, 605, 610, 616, 618, 621, 624, 631, 632,
032, // Via Nidoran-F
313, // Via Illumise
};
#endregion
}
}