From b05b66810c77db18ae86a0bed828fb5dfd35fdf6 Mon Sep 17 00:00:00 2001 From: Kaphotics Date: Mon, 21 Mar 2016 08:01:08 -0700 Subject: [PATCH] Add Ball/Ability checks & wc6 PID check Probably am going to move the WC6 fetch logic out --- Legality/Analysis.cs | 6 +++-- Legality/Checks.cs | 55 ++++++++++++++++++++++++++++++++++++++++++-- Legality/Tables.cs | 1 + 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Legality/Analysis.cs b/Legality/Analysis.cs index bb411c92e..a529ac223 100644 --- a/Legality/Analysis.cs +++ b/Legality/Analysis.cs @@ -8,7 +8,7 @@ public partial class LegalityAnalysis private readonly PK6 pk6; private WC6 MatchedWC6; private object EncounterMatch; - private LegalityCheck ECPID, Nickname, IDs, IVs, EVs, Encounter, Level, Ribbons; + private LegalityCheck ECPID, Nickname, IDs, IVs, EVs, Encounter, Level, Ribbons, Ability, Ball; public bool Valid = true; public bool SecondaryChecked; @@ -48,6 +48,8 @@ private void updateChecks() EVs = verifyEVs(); Level = verifyLevel(); Ribbons = verifyRibbons(); + Ability = verifyAbility(); + Ball = verifyBall(); SecondaryChecked = true; } private string getLegalityReport() @@ -55,7 +57,7 @@ private string getLegalityReport() if (!pk6.Gen6) return "Analysis only available for Pokémon that originate from X/Y & OR/AS."; - var chks = new[] { ECPID, Nickname, IVs, EVs, IDs, Encounter, Level, Ribbons }; + var chks = new[] { ECPID, Nickname, IVs, EVs, IDs, Encounter, Level, Ribbons, Ability, Ball }; string r = ""; for (int i = 0; i < 4; i++) diff --git a/Legality/Checks.cs b/Legality/Checks.cs index d432f451d..57214d348 100644 --- a/Legality/Checks.cs +++ b/Legality/Checks.cs @@ -248,7 +248,7 @@ private LegalityCheck verifyRibbons() "Premier", "Event", "Birthday", "Special", "Souvenir", "Wishing", "Battle Champ", "Regional Champ", "National Champ", "World Champ" }; - if (MatchedWC6 != null) // Wondercard + if (MatchedWC6 != null) // Wonder Card { bool[] wc6rib = { @@ -295,6 +295,54 @@ private LegalityCheck verifyRibbons() result[1] = "Invalid Ribbons: " + string.Join(", ", invalidRibbons); return new LegalityCheck(Severity.Invalid, string.Join(Environment.NewLine, result.Where(s=>!string.IsNullOrEmpty(s)))); } + private LegalityCheck verifyAbility() + { + int index = Legal.PersonalAO[pk6.Species].FormeIndex(pk6.Species, pk6.AltForm); + byte[] abilities = Legal.PersonalAO[index].Abilities; + int abilval = Array.IndexOf(abilities, (byte)pk6.Ability); + if (abilval < 0) + return new LegalityCheck(Severity.Invalid, "Ability is not valid for species/form"); + + return abilities[pk6.AbilityNumber >> 1] != pk6.Ability + ? new LegalityCheck(Severity.Invalid, "Ability does not match ability number.") + : new LegalityCheck(Severity.Valid, "Ability matches ability number."); + } + + private LegalityCheck verifyBall() + { + if (MatchedWC6 != null) + return pk6.Ball != MatchedWC6.Pokéball + ? new LegalityCheck(Severity.Invalid, "Ball does not match specified Wonder Card Ball.") + : new LegalityCheck(Severity.Valid, "Ball matches Wonder Card."); + + if (pk6.WasEgg) + { + if (pk6.Species > 650) + return !Legal.WildPokeballs.Contains(pk6.Ball) + ? new LegalityCheck(Severity.Invalid, "Unobtainable ball for Kalos origin.") + : new LegalityCheck(Severity.Valid, "Obtainable ball for Kalos origin."); + + if (pk6.Ball == 0x10) // Cherish + return new LegalityCheck(Severity.Invalid, "Cherish Ball on non-event."); + if (pk6.Ball == 5 && pk6.Species > 493) // Gen5 + return new LegalityCheck(Severity.Invalid, "Safari Ball on GenV species."); + + // Feel free to improve, there's a lot of very minor things to check for some species. + } + if (EncounterMatch == null) + { + // Wild Encounter + return !Legal.WildPokeballs.Contains(pk6.Ball) + ? new LegalityCheck(Severity.Invalid, "Unobtainable ball on captured encounter.") + : new LegalityCheck(Severity.Valid, "Obtainable ball on captured encounter."); + } + if (EncounterMatch.GetType() == 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."); + + return new LegalityCheck(Severity.Indeterminate, "Unable to verify Ball"); + } private LegalityCheck[] verifyMoves() { int[] Moves = pk6.Moves; @@ -325,7 +373,7 @@ private LegalityCheck[] verifyMoves() else if (RelearnMoves.Contains(Moves[i])) res[i] = new LegalityCheck(Severity.Valid, "Relearn Move."); else if (WC6Moves.Contains(Moves[i])) - res[i] = new LegalityCheck(Severity.Valid, "Wondercard Non-Relearn Move."); + res[i] = new LegalityCheck(Severity.Valid, "Wonder Card Non-Relearn Move."); else res[i] = new LegalityCheck(Severity.Invalid, "Invalid Move."); } @@ -367,6 +415,9 @@ private LegalityCheck[] verifyRelearn() IEnumerable vwc6 = Legal.getValidWC6s(pk6); foreach (var wc in vwc6) { + if (wc.PIDType == 0 && pk6.PID != wc.PID) continue; + if (wc.PIDType == 2 && !pk6.IsShiny) continue; + if (wc.PIDType == 3 && pk6.IsShiny) continue; int[] moves = wc.RelearnMoves; for (int i = 0; i < 4; i++) res[i] = moves[i] != Moves[i] diff --git a/Legality/Tables.cs b/Legality/Tables.cs index 5d62260a3..2d0cb04cf 100644 --- a/Legality/Tables.cs +++ b/Legality/Tables.cs @@ -410,5 +410,6 @@ public static partial class Legal }; internal static readonly int[] RotomMoves = { 0, 315, 056, 059, 403, 437 }; internal static readonly int[] PikachuMoves = { 0, 309, 556, 577, 604, 560 }; + internal static readonly int[] WildPokeballs = { 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; } }