diff --git a/PKHeX.Core/Legality/Analysis.cs b/PKHeX.Core/Legality/Analysis.cs index bc251727f..1bb06aae3 100644 --- a/PKHeX.Core/Legality/Analysis.cs +++ b/PKHeX.Core/Legality/Analysis.cs @@ -9,20 +9,19 @@ namespace PKHeX.Core public partial class LegalityAnalysis { private PKM pkm; + private readonly bool Error; private readonly List Parse = new List(); private IEncounterable EncounterOriginalGB; - private IEncounterable EncounterMatch => info.EncounterMatch; + private IEncounterable EncounterMatch => Info.EncounterMatch; private Type Type; // Parent class when applicable (EncounterStatic / MysteryGift) private Type MatchedType; // Child class if applicable (WC6, PGF, etc) private string EncounterName => Legal.GetEncounterTypeName(EncounterOriginalGB ?? EncounterMatch) + $" ({SpeciesStrings[EncounterMatch.Species]})"; private CheckResult Encounter, History; - // private bool SecondaryChecked; - public readonly bool Parsed; - public readonly bool Valid; - public readonly bool Error; - public LegalInfo info; + public bool Parsed { get; } + public bool Valid { get; } + public LegalInfo Info { get; private set; } public bool ParsedValid => Parsed && Valid; public bool ParsedInvalid => Parsed && !Valid; public string Report(bool verbose = false) => verbose ? GetVerboseLegalityReport() : GetLegalityReport(); @@ -46,8 +45,8 @@ private IEnumerable AllSuggestedRelearnMoves if (Error || pkm == null || !pkm.IsOriginValid) return new int[4]; var gender = pkm.PersonalInfo.Gender; - var inheritLvlMoves = gender > 0 && gender < 255 || Legal.MixedGenderBreeding.Contains(info.EncounterMatch.Species); - return _allSuggestedRelearnMoves = Legal.GetValidRelearn(pkm, info.EncounterMatch.Species, inheritLvlMoves).ToArray(); + var inheritLvlMoves = gender > 0 && gender < 255 || Legal.MixedGenderBreeding.Contains(Info.EncounterMatch.Species); + return _allSuggestedRelearnMoves = Legal.GetValidRelearn(pkm, Info.EncounterMatch.Species, inheritLvlMoves).ToArray(); } } private int[] _allSuggestedMoves, _allSuggestedRelearnMoves; @@ -79,14 +78,14 @@ public LegalityAnalysis(PKM pk) { if (Parse.Any(chk => !chk.Valid)) Valid = false; - else if (info.Moves.Any(m => m.Valid != true)) + else if (Info.Moves.Any(m => m.Valid != true)) Valid = false; - else if (info.Relearn.Any(m => m.Valid != true)) + else if (Info.Relearn.Any(m => m.Valid != true)) Valid = false; else Valid = true; - if (pkm.FatefulEncounter && info.Relearn.Any(chk => !chk.Valid) && EncounterMatch == null) + if (pkm.FatefulEncounter && Info.Relearn.Any(chk => !chk.Valid) && EncounterMatch == null) AddLine(Severity.Indeterminate, V188, CheckIdentifier.Fateful); } } @@ -145,7 +144,7 @@ private void ParsePK3(PKM pk) if (pkm.Version == 15) VerifyCXD(); - if (info.EncounterMatch is WC3 z && z.NotDistributed) + if (Info.EncounterMatch is WC3 z && z.NotDistributed) AddLine(Severity.Invalid, V413, CheckIdentifier.Encounter); } private void ParsePK4(PKM pk) @@ -193,9 +192,9 @@ private void ParsePK7(PKM pk) private void UpdateInfo() { - info = EncounterFinder.FindVerifiedEncounter(pkm); - Encounter = info.Parse[0]; - Parse.AddRange(info.Parse); + Info = EncounterFinder.FindVerifiedEncounter(pkm); + Encounter = Info.Parse[0]; + Parse.AddRange(Info.Parse); } private void UpdateTradebackG12() @@ -259,9 +258,9 @@ private void UpdateTypeInfo() if (pkm.Format >= 7) { if (pkm.VC1) - info.EncounterMatch = EncounterGenerator.GetRBYStaticTransfer(pkm.Species); + Info.EncounterMatch = EncounterGenerator.GetRBYStaticTransfer(pkm.Species); else if (pkm.VC2) - info.EncounterMatch = EncounterGenerator.GetGSStaticTransfer(pkm.Species); + Info.EncounterMatch = EncounterGenerator.GetGSStaticTransfer(pkm.Species); } if (pkm.GenNumber <= 2 && pkm.TradebackStatus == TradebackType.Any && (EncounterMatch as GBEncounterData)?.Generation != pkm.GenNumber) @@ -310,8 +309,8 @@ private string GetLegalityReport() return V189; var lines = new List(); - var vMoves = info.Moves; - var vRelearn = info.Relearn; + var vMoves = Info.Moves; + var vRelearn = Info.Relearn; for (int i = 0; i < 4; i++) if (!vMoves[i].Valid) lines.Add(string.Format(V191, vMoves[i].Judgement.Description(), i + 1, vMoves[i].Comment)); @@ -344,8 +343,8 @@ private string GetVerboseLegalityReport() lines.AddRange(br); int rl = lines.Count; - var vMoves = info.Moves; - var vRelearn = info.Relearn; + var vMoves = Info.Moves; + var vRelearn = Info.Relearn; for (int i = 0; i < 4; i++) if (vMoves[i].Valid) lines.Add(string.Format(V191, vMoves[i].Judgement.Description(), i + 1, vMoves[i].Comment)); @@ -363,7 +362,7 @@ private string GetVerboseLegalityReport() lines.AddRange(br); lines.Add(string.Format(V195, EncounterName)); - var pidiv = info.PIDIV ?? MethodFinder.Analyze(pkm); + var pidiv = Info.PIDIV ?? MethodFinder.Analyze(pkm); if (pidiv != null) { if (!pidiv.NoSeed) @@ -376,14 +375,14 @@ private string GetVerboseLegalityReport() public int[] GetSuggestedRelearn() { - if (info.RelearnBase == null || pkm.GenNumber < 6 || !pkm.IsOriginValid) + if (Info.RelearnBase == null || pkm.GenNumber < 6 || !pkm.IsOriginValid) return new int[4]; if (!pkm.WasEgg) - return info.RelearnBase; + return Info.RelearnBase; - List window = new List(info.RelearnBase); - var vMoves = info.Moves; + List window = new List(Info.RelearnBase); + var vMoves = Info.Moves; window.AddRange(pkm.Moves.Where((v, i) => !vMoves[i].Valid || vMoves[i].Flag)); window = window.Distinct().ToList(); if (window.Count < 4) @@ -396,7 +395,7 @@ public int[] GetSuggestedMoves(bool tm, bool tutor, bool reminder) return null; if (!Parsed) return new int[4]; - return Legal.GetValidMoves(pkm, info.EvoChainsAllGens, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0 + return Legal.GetValidMoves(pkm, Info.EvoChainsAllGens, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0 } public EncounterStatic GetSuggestedMetInfo() diff --git a/PKHeX.Core/Legality/Checks.cs b/PKHeX.Core/Legality/Checks.cs index f8b654f7f..600fb1ec8 100644 --- a/PKHeX.Core/Legality/Checks.cs +++ b/PKHeX.Core/Legality/Checks.cs @@ -469,7 +469,7 @@ private void VerifyG1OT() AddLine(Severity.Invalid, V402, CheckIdentifier.Trainer); } - if (pkm.OT_Gender == 1 && (pkm.Format == 2 && pkm.Met_Location == 0 || !info.Game.Contains(GameVersion.C))) + if (pkm.OT_Gender == 1 && (pkm.Format == 2 && pkm.Met_Location == 0 || !Info.Game.Contains(GameVersion.C))) AddLine(Severity.Invalid, V408, CheckIdentifier.Trainer); } #endregion @@ -892,7 +892,7 @@ private void VerifyRibbonSet2(IRibbonSetEvent4 set2, object encounterContent, Li private void VerifyCXD() { if (EncounterMatch is EncounterStatic) - VerifyCXDStarterCorrelation(info.PIDIV); + VerifyCXDStarterCorrelation(Info.PIDIV); else if (pkm.WasEgg) // can't obtain eggs in CXD AddLine(Severity.Invalid, V80, CheckIdentifier.Encounter); // invalid encounter @@ -1008,7 +1008,7 @@ private bool VerifySetAbility(int? EncounterAbility, bool? AbilityUnchanged, int return false; // gen3Species will be zero for pokemon with illegal gen 3 encounters, like Infernape with gen 3 "origin" - var gen3Species = info.EvoChainsAllGens[3].FirstOrDefault()?.Species ?? 0; + var gen3Species = Info.EvoChainsAllGens[3].FirstOrDefault()?.Species ?? 0; if (gen3Species == 0) return true; @@ -1021,12 +1021,12 @@ private bool VerifySetAbility(int? EncounterAbility, bool? AbilityUnchanged, int if (abilities_g3.Length == 2) // Excluding Colosseum/XD, a gen3 pkm must match PID if it has 2 unique abilities return pkm.Version != (int)GameVersion.CXD; - int Species_g4 = info.EvoChainsAllGens[4].FirstOrDefault()?.Species ?? 0; - int Species_g5 = pkm.Format == 5 ? info.EvoChainsAllGens[5].FirstOrDefault()?.Species ?? 0 : 0; + int Species_g4 = Info.EvoChainsAllGens[4].FirstOrDefault()?.Species ?? 0; + int Species_g5 = pkm.Format == 5 ? Info.EvoChainsAllGens[5].FirstOrDefault()?.Species ?? 0 : 0; if (Math.Max(Species_g5, Species_g4) > Species_g3) // it has evolved in either gen 4 or gen 5; the ability must match PID return false; - var Evolutions_g45 = Math.Max(info.EvoChainsAllGens[4].Length, pkm.Format == 5 ? info.EvoChainsAllGens[5].Length : 0); + var Evolutions_g45 = Math.Max(Info.EvoChainsAllGens[4].Length, pkm.Format == 5 ? Info.EvoChainsAllGens[5].Length : 0); if (Evolutions_g45 > 1) { // Evolutions_g45 > 1 and Species_g45 = Species_g3 with means both options, evolve in gen 4-5 or not evolve, are possible @@ -1651,7 +1651,7 @@ private void VerifyOTMemory() if (Type == typeof(EncounterTrade)) { - switch (info.Generation) + switch (Info.Generation) { case 6: break; // Undocumented, uncommon, and insignificant -- don't bother. @@ -1885,7 +1885,7 @@ private void VerifyForm() int index = Array.IndexOf(pkm.Moves, 548); // Secret Sword bool noSword = index < 0; if (pkm.AltForm == 0 ^ noSword) // mismatch - info.Moves[noSword ? 0 : index] = new CheckMoveResult(info.Moves[noSword ? 0 : index], Severity.Invalid, V169, CheckIdentifier.Move); + Info.Moves[noSword ? 0 : index] = new CheckMoveResult(Info.Moves[noSword ? 0 : index], Severity.Invalid, V169, CheckIdentifier.Move); break; } case 649: // Genesect @@ -2045,7 +2045,7 @@ private void VerifyMiscG1() if (pkm.Species == 149 && catch_rate == PersonalTable.Y[149].CatchRate || Legal.Species_NotAvailable_CatchRate.Contains(pkm.Species) && catch_rate == PersonalTable.RB[pkm.Species].CatchRate) { AddLine(Severity.Invalid, V396, CheckIdentifier.Misc); } - else if (!info.EvoChainsAllGens[1].Any(e => catch_rate == PersonalTable.RB[e.Species].CatchRate || catch_rate == PersonalTable.Y[e.Species].CatchRate)) + else if (!Info.EvoChainsAllGens[1].Any(e => catch_rate == PersonalTable.RB[e.Species].CatchRate || catch_rate == PersonalTable.Y[e.Species].CatchRate)) { AddLine(Severity.Invalid, pkm.Gen1_NotTradeback? V397: V399, CheckIdentifier.Misc); } else { AddLine(Severity.Valid, V398, CheckIdentifier.Misc); } @@ -2110,8 +2110,8 @@ private void VerifyFatefulMysteryGift(MysteryGift g) { if (g is PGF p && p.IsShiny) { - info.PIDIV = MethodFinder.Analyze(pkm); - if (info.PIDIV.Type != PIDType.G5MGShiny) + Info.PIDIV = MethodFinder.Analyze(pkm); + if (Info.PIDIV.Type != PIDType.G5MGShiny) AddLine(Severity.Invalid, V411, CheckIdentifier.PID); } diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.Designer.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.Designer.cs index 091df2461..32c4ae17b 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.Designer.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.Designer.cs @@ -1328,7 +1328,7 @@ private void InitializeComponent() this.NUD_ShadowID.Location = new System.Drawing.Point(110, 1); this.NUD_ShadowID.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0); this.NUD_ShadowID.Maximum = new decimal(new int[] { - 72, + 127, 0, 0, 0}); diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs index 7fd7a0c98..02d342fc8 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs @@ -245,11 +245,11 @@ public void UpdateLegality(LegalityAnalysis la = null, bool skipMoveRepop = fals // Refresh Move Legality for (int i = 0; i < 4; i++) - movePB[i].Visible = !Legality.info?.Moves[i].Valid ?? false; + movePB[i].Visible = !Legality.Info?.Moves[i].Valid ?? false; if (pkm.Format >= 6) for (int i = 0; i < 4; i++) - relearnPB[i].Visible = !Legality.info?.Relearn[i].Valid ?? false; + relearnPB[i].Visible = !Legality.Info?.Relearn[i].Valid ?? false; if (skipMoveRepop) return; @@ -1728,65 +1728,75 @@ private void OpenHistory(object sender, EventArgs e) /// Refreshes the interface for the current PKM format. /// public bool ToggleInterface(SaveFile sav, PKM pk) + { + if (pk.GetType() != sav.PKMType || pkm.Format < 3) + pk = sav.BlankPKM; + pkm = pk; + + ToggleInterface(pkm.Format); + ToggleInterface(pkm.GetType()); + + return FinalizeInterface(sav); + } + private void ToggleInterface(Type t) + { + FLP_Purification.Visible = FLP_ShadowID.Visible = t == typeof(XK3) || t == typeof(CK3); + } + private void ToggleInterface(int gen) { Tip1.RemoveAll(); Tip2.RemoveAll(); Tip3.RemoveAll(); // TSV/PSV - FLP_Country.Visible = FLP_SubRegion.Visible = FLP_3DSRegion.Visible = pk.Format >= 6; - Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = pk.Format >= 6; - GB_nOT.Visible = GB_RelearnMoves.Visible = BTN_Medals.Visible = BTN_History.Visible = pk.Format >= 6; + FLP_Country.Visible = FLP_SubRegion.Visible = FLP_3DSRegion.Visible = gen >= 6; + Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = gen >= 6; + GB_nOT.Visible = GB_RelearnMoves.Visible = BTN_Medals.Visible = BTN_History.Visible = gen >= 6; - PB_MarkPentagon.Visible = pk.Format >= 6; - PB_MarkAlola.Visible = PB_MarkVC.Visible = PB_MarkHorohoro.Visible = pk.Format >= 7; + PB_MarkPentagon.Visible = gen >= 6; + PB_MarkAlola.Visible = PB_MarkVC.Visible = PB_MarkHorohoro.Visible = gen >= 7; - FLP_NSparkle.Visible = L_NSparkle.Visible = CHK_NSparkle.Visible = pk.Format == 5; + FLP_NSparkle.Visible = L_NSparkle.Visible = CHK_NSparkle.Visible = gen == 5; - CB_Form.Visible = Label_Form.Visible = CHK_AsEgg.Visible = GB_EggConditions.Visible = PB_Mark5.Visible = PB_Mark6.Visible = pk.Format >= 4; - FLP_ShinyLeaf.Visible = L_ShinyLeaf.Visible = ShinyLeaf.Visible = pk.Format == 4; + CB_Form.Visible = Label_Form.Visible = CHK_AsEgg.Visible = GB_EggConditions.Visible = PB_Mark5.Visible = PB_Mark6.Visible = gen >= 4; + FLP_ShinyLeaf.Visible = L_ShinyLeaf.Visible = ShinyLeaf.Visible = gen == 4; - DEV_Ability.Enabled = DEV_Ability.Visible = pk.Format > 3 && HaX; - CB_Ability.Visible = !DEV_Ability.Enabled && pk.Format >= 3; - FLP_Nature.Visible = pk.Format >= 3; - FLP_Ability.Visible = pk.Format >= 3; - FLP_Language.Visible = pk.Format >= 3; - GB_ExtraBytes.Visible = GB_ExtraBytes.Enabled = pk.Format >= 3; - GB_Markings.Visible = pk.Format >= 3; - BTN_Ribbons.Visible = pk.Format >= 3; - CB_HPType.Enabled = CB_Form.Enabled = pk.Format >= 3; - BTN_RerollPID.Visible = Label_PID.Visible = TB_PID.Visible = Label_SID.Visible = TB_SID.Visible = pk.Format >= 3; + DEV_Ability.Enabled = DEV_Ability.Visible = gen > 3 && HaX; + CB_Ability.Visible = !DEV_Ability.Enabled && gen >= 3; + FLP_Nature.Visible = gen >= 3; + FLP_Ability.Visible = gen >= 3; + FLP_Language.Visible = gen >= 3; + GB_ExtraBytes.Visible = GB_ExtraBytes.Enabled = gen >= 3; + GB_Markings.Visible = gen >= 3; + BTN_Ribbons.Visible = gen >= 3; + CB_HPType.Enabled = CB_Form.Enabled = gen >= 3; + BTN_RerollPID.Visible = Label_PID.Visible = TB_PID.Visible = Label_SID.Visible = TB_SID.Visible = gen >= 3; - FLP_FriendshipForm.Visible = pk.Format >= 2; - FLP_HeldItem.Visible = pk.Format >= 2; - CHK_IsEgg.Visible = Label_Gender.Visible = pk.Format >= 2; - FLP_PKRS.Visible = FLP_EggPKRSRight.Visible = pk.Format >= 2; - Label_OTGender.Visible = pk.Format >= 2; - - FLP_Purification.Visible = FLP_ShadowID.Visible = pk is XK3 || pk is CK3; - NUD_ShadowID.Maximum = 127; + FLP_FriendshipForm.Visible = gen >= 2; + FLP_HeldItem.Visible = gen >= 2; + CHK_IsEgg.Visible = Label_Gender.Visible = gen >= 2; + FLP_PKRS.Visible = FLP_EggPKRSRight.Visible = gen >= 2; + Label_OTGender.Visible = gen >= 2; // HaX override, needs to be after DEV_Ability enabled assignment. - TB_AbilityNumber.Visible = pk.Format >= 6 && DEV_Ability.Enabled; + TB_AbilityNumber.Visible = gen >= 6 && DEV_Ability.Enabled; // Met Tab - FLP_MetDate.Visible = pk.Format >= 4; - FLP_Fateful.Visible = FLP_Ball.Visible = FLP_OriginGame.Visible = pk.Format >= 3; - FLP_MetLocation.Visible = FLP_MetLevel.Visible = pk.Format >= 2; - FLP_TimeOfDay.Visible = pk.Format == 2; + FLP_MetDate.Visible = gen >= 4; + FLP_Fateful.Visible = FLP_Ball.Visible = FLP_OriginGame.Visible = gen >= 3; + FLP_MetLocation.Visible = FLP_MetLevel.Visible = gen >= 2; + FLP_TimeOfDay.Visible = gen == 2; // Stats - FLP_StatsTotal.Visible = pk.Format >= 3; - FLP_Characteristic.Visible = pk.Format >= 3; - FLP_HPType.Visible = pk.Format >= 2; + FLP_StatsTotal.Visible = gen >= 3; + FLP_Characteristic.Visible = gen >= 3; + FLP_HPType.Visible = gen >= 2; - PAN_Contest.Visible = pk.Format >= 3; + PAN_Contest.Visible = gen >= 3; - ToggleStats(pk); + ToggleStats(gen); CenterSubEditors(); - - return FinalizeInterface(sav, pk); } - private void ToggleStats(PKM pk) + private void ToggleStats(int gen) { - if (pk.Format == 1) + if (pkm.Format == 1) { FLP_SpD.Visible = false; Label_SPA.Visible = false; @@ -1799,7 +1809,7 @@ private void ToggleStats(PKM pk) ctrl.Size = Stat_HP.Size; } } - else if (pk.Format == 2) + else if (gen == 2) { FLP_SpD.Visible = true; Label_SPA.Visible = true; @@ -1828,17 +1838,13 @@ private void ToggleStats(PKM pk) } } } - private bool FinalizeInterface(SaveFile SAV, PKM pk) + private bool FinalizeInterface(SaveFile sav) { bool init = fieldsInitialized; fieldsInitialized = fieldsLoaded = false; - pkm = pk.GetType() != SAV.PKMType ? SAV.BlankPKM : pk; - if (pkm.Format < 3) - pkm = SAV.BlankPKM; - bool TranslationRequired = false; - PopulateFilteredDataSources(SAV); + PopulateFilteredDataSources(sav); PopulateFields(pkm); fieldsInitialized |= init; @@ -1972,7 +1978,7 @@ public void LoadShowdownSet(ShowdownSet Set) pkm = PreparePKM(); UpdateLegality(); - if (Legality.info.Relearn.Any(z => !z.Valid)) + if (Legality.Info.Relearn.Any(z => !z.Valid)) SetSuggestedRelearnMoves(silent: true); } public void ChangeLanguage(SaveFile sav, PKM pk) @@ -2018,7 +2024,7 @@ private void PopulateFilteredDataSources(SaveFile SAV) { GameInfo.SetItemDataSource(HaX, pkm.MaxItemID, SAV.HeldItems, pkm.Format, SAV.Version, GameInfo.Strings); if (pkm.Format > 1) - CB_HeldItem.DataSource = new BindingSource(GameInfo.ItemDataSource.Where(i => i.Value <= SAV.MaxItemID).ToList(), null); + CB_HeldItem.DataSource = new BindingSource(GameInfo.ItemDataSource.Where(i => i.Value <= pkm.MaxItemID).ToList(), null); var languages = Util.GetUnsortedCBList("languages"); if (pkm.Format < 7) @@ -2031,7 +2037,7 @@ private void PopulateFilteredDataSources(SaveFile SAV) CB_GameOrigin.DataSource = new BindingSource(GameInfo.VersionDataSource.Where(g => g.Value <= pkm.MaxGameID || pkm.Format >= 3 && g.Value == 15).ToList(), null); // Set the Move ComboBoxes too.. - GameInfo.MoveDataSource = (HaX ? GameInfo.HaXMoveDataSource : GameInfo.LegalMoveDataSource).Where(m => m.Value <= SAV.MaxMoveID).ToList(); // Filter Z-Moves if appropriate + GameInfo.MoveDataSource = (HaX ? GameInfo.HaXMoveDataSource : GameInfo.LegalMoveDataSource).Where(m => m.Value <= pkm.MaxMoveID).ToList(); // Filter Z-Moves if appropriate foreach (ComboBox cb in new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4, CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 }) { cb.DisplayMember = "Text"; cb.ValueMember = "Value";