diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index 1f90e5e5c..a75262358 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -715,8 +715,12 @@ private void openQuick(string path, bool force = false) byte[] input; try { input = File.ReadAllBytes(path); } catch (Exception e) { WinFormsUtil.Error("Unable to load file. It could be in use by another program.\nPath: " + path, e); return; } + #if DEBUG + openFile(input, path, ext); + #else try { openFile(input, path, ext); } catch (Exception e) { WinFormsUtil.Error("Unable to load file.\nPath: " + path, e); } + #endif } } private void openFile(byte[] input, string path, string ext) diff --git a/PKHeX.WinForms/Subforms/SAV_Database.cs b/PKHeX.WinForms/Subforms/SAV_Database.cs index 39b500abf..f62741eb8 100644 --- a/PKHeX.WinForms/Subforms/SAV_Database.cs +++ b/PKHeX.WinForms/Subforms/SAV_Database.cs @@ -481,10 +481,10 @@ private void B_Search_Click(object sender, EventArgs e) slotSelected = -1; // reset the slot last viewed - if (Menu_SearchLegal.Checked && !Menu_SearchIllegal.Checked) // Legal Only - res = res.Where(pk => pk.GenNumber >= 6 && new LegalityAnalysis(pk).Valid); - if (!Menu_SearchLegal.Checked && Menu_SearchIllegal.Checked) // Illegal Only - res = res.Where(pk => pk.GenNumber >= 6 && !new LegalityAnalysis(pk).Valid); + if (Menu_SearchLegal.Checked && !Menu_SearchIllegal.Checked) + res = res.Where(pk => new LegalityAnalysis(pk).ParsedValid); + if (!Menu_SearchLegal.Checked && Menu_SearchIllegal.Checked) + res = res.Where(pk => new LegalityAnalysis(pk).ParsedInvalid); if (RTB_Instructions.Lines.Any(line => line.Length > 0)) { diff --git a/PKHeX/Legality/Analysis.cs b/PKHeX/Legality/Analysis.cs index 2e1150a33..a715680f7 100644 --- a/PKHeX/Legality/Analysis.cs +++ b/PKHeX/Legality/Analysis.cs @@ -21,6 +21,8 @@ public partial class LegalityAnalysis public readonly bool Parsed; public readonly bool Valid; + public bool ParsedValid => Parsed && Valid; + public bool ParsedInvalid => Parsed && !Valid; public CheckResult[] vMoves = new CheckResult[4]; public CheckResult[] vRelearn = new CheckResult[4]; public string Report => getLegalityReport(); @@ -48,6 +50,9 @@ public LegalityAnalysis(PKM pk) if (!Parse.Any()) switch (pk.GenNumber) { + case 3: parsePK3(pk); break; + case 4: parsePK4(pk); break; + case 5: parsePK5(pk); break; case 6: parsePK6(pk); break; case 1: parsePK7(pk); break; @@ -59,7 +64,7 @@ public LegalityAnalysis(PKM pk) { if (Parse.Any(chk => !chk.Valid)) Valid = false; - if (vMoves.Any(m => m.Valid != true)) + else if (vMoves.Any(m => m.Valid != true)) Valid = false; else if (vRelearn.Any(m => m.Valid != true)) Valid = false; @@ -99,6 +104,39 @@ private void parsePK1(PKM pk) verifyG1OT(); verifyEggMoves(); } + private void parsePK3(PKM pk) + { + pkm = pk; + if (!pkm.IsOriginValid) + { AddLine(Severity.Invalid, "Species does not exist in origin game.", CheckIdentifier.None); return; } + + updateEncounterChain(); + updateMoveLegality(); + updateEncounterInfo(); + updateChecks(); + } + private void parsePK4(PKM pk) + { + pkm = pk; + if (!pkm.IsOriginValid) + { AddLine(Severity.Invalid, "Species does not exist in origin game.", CheckIdentifier.None); return; } + + updateEncounterChain(); + updateMoveLegality(); + updateEncounterInfo(); + updateChecks(); + } + private void parsePK5(PKM pk) + { + pkm = pk; + if (!pkm.IsOriginValid) + { AddLine(Severity.Invalid, "Species does not exist in origin game.", CheckIdentifier.None); return; } + + updateEncounterChain(); + updateMoveLegality(); + updateEncounterInfo(); + updateChecks(); + } private void parsePK6(PKM pk) { pkm = pk; @@ -156,29 +194,31 @@ private void updateEncounterInfo() } private void updateChecks() { - History = verifyHistory(); - AddLine(History); - verifyECPID(); verifyNickname(); verifyOT(); verifyIVs(); - verifyHyperTraining(); verifyEVs(); verifyLevel(); - verifyMedals(); verifyRibbons(); verifyAbility(); verifyBall(); - verifyOTMemory(); - verifyHTMemory(); verifyRegion(); verifyForm(); verifyMisc(); verifyGender(); verifyItem(); - if (pkm.GenNumber < 5) + if (pkm.Format >= 6) + { + History = verifyHistory(); + AddLine(History); + verifyOTMemory(); + verifyHTMemory(); + verifyHyperTraining(); + verifyMedals(); + } + if (pkm.GenNumber < 5 || pkm.VC) verifyEggMoves(); verifyVersionEvolution(); diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 40ff21eed..f5476f313 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -29,6 +29,36 @@ public static partial class Legal private static readonly EncounterArea[] SlotsGSC; private static readonly EncounterStatic[] StaticGSC; + // Gen 3 + private static readonly Learnset[] LevelUpE = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_e, "em")); + private static readonly Learnset[] LevelUpRS = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_rs, "rs")); + private static readonly Learnset[] LevelUpFR = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_fr, "fr")); + private static readonly Learnset[] LevelUpLG = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_lg, "lg")); + private static readonly EggMoves[] EggMovesRS = EggMoves6.getArray(Data.unpackMini(Resources.eggmove_rs, "rs")); + //private static readonly TMHMTutorMoves[] TutorsG3 = TMHMTutorMoves.getArray(Data.unpackMini(Properties.Resources.tutors_g3, "g3")); + //private static readonly TMHMTutorMoves[] HMTMG3 = TMHMTutorMoves.getArray(Data.unpackMini(Properties.Resources.hmtm_g3, "g3")); + private static readonly EvolutionTree Evolves3; + private static readonly EncounterArea[] SlotsR, SlotsS, SlotsE, SlotsFR, SlotsLG; + private static readonly EncounterStatic[] StaticR, StaticS, StaticE, StaticFR, StaticLG; + + // Gen 4 + private static readonly Learnset[] LevelUpDP = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_dp, "dp")); + private static readonly Learnset[] LevelUpPt = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_pt, "pt")); + private static readonly Learnset[] LevelUpHGSS = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_hgss, "hs")); + private static readonly EggMoves[] EggMovesDPPt = EggMoves6.getArray(Data.unpackMini(Resources.eggmove_dppt, "dp")); + private static readonly EggMoves[] EggMovesHGSS = EggMoves6.getArray(Data.unpackMini(Resources.eggmove_hgss, "hs")); + private static readonly EvolutionTree Evolves4; + private static readonly EncounterArea[] SlotsD, SlotsP, SlotsPt, SlotsHG, SlotsSS; + private static readonly EncounterStatic[] StaticD, StaticP, StaticPt, StaticHG, StaticSS; + + // Gen 5 + private static readonly Learnset[] LevelUpBW = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_bw, "51")); + private static readonly Learnset[] LevelUpB2W2 = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_b2w2, "52")); + private static readonly EggMoves[] EggMovesBW = EggMoves6.getArray(Data.unpackMini(Resources.eggmove_bw, "bw")); + private static readonly EvolutionTree Evolves5; + private static readonly EncounterArea[] SlotsB, SlotsW, SlotsB2, SlotsW2; + private static readonly EncounterStatic[] StaticB, StaticW, StaticB2, StaticW2; + // Gen 6 private static readonly EggMoves[] EggMovesXY = EggMoves6.getArray(Data.unpackMini(Resources.eggmove_xy, "xy")); private static readonly Learnset[] LevelUpXY = Learnset6.getArray(Data.unpackMini(Resources.lvlmove_xy, "xy")); @@ -56,6 +86,27 @@ private static EncounterStatic[] getStaticEncounters(GameVersion Game) case GameVersion.GSC: return Encounter_GSC; + case GameVersion.R: case GameVersion.S: case GameVersion.E: + table = Encounter_RSE; + break; + case GameVersion.FR: case GameVersion.LG: + table = Encounter_FRLG; + break; + + case GameVersion.D: case GameVersion.P: case GameVersion.Pt: + table = Encounter_DPPt; + break; + case GameVersion.HG: case GameVersion.SS: + table = Encounter_HGSS; + break; + + case GameVersion.B: case GameVersion.W: + table = Encounter_BW; + break; + case GameVersion.B2: case GameVersion.W2: + table = Encounter_B2W2; + break; + case GameVersion.X: case GameVersion.Y: table = Encounter_XY; break; @@ -102,7 +153,7 @@ private static EncounterArea[] getEncounterTables(GameVersion Game) break; } if (ident == null) - return null; + return new EncounterArea[0]; return getEncounterTables(tables, ident); } @@ -147,49 +198,113 @@ private static void MarkG7SMSlots(ref EncounterArea[] Areas) foreach (EncounterSlot s in Areas.SelectMany(area => area.Slots)) s.Type = SlotType.SOS; } + private static EncounterArea[] getTables1() + { + var red = EncounterArea.getArray1_GW(Resources.encounter_red); + var blu = EncounterArea.getArray1_GW(Resources.encounter_blue); + var ylw = EncounterArea.getArray1_GW(Resources.encounter_yellow); + var rb_fish = EncounterArea.getArray1_F(Resources.encounter_rb_f); + var ylw_fish = EncounterArea.getArray1_FY(Resources.encounter_yellow_f); + red = addExtraTableSlots(red, rb_fish); + blu = addExtraTableSlots(blu, rb_fish); + ylw = addExtraTableSlots(ylw, ylw_fish); + + var table = addExtraTableSlots(addExtraTableSlots(red, blu), ylw); + Array.Resize(ref table, table.Length + 1); + table[table.Length - 1] = FishOldGood_RBY; + + return table; + } + private static EncounterArea[] getTables2() + { + // Grass/Water + var g = EncounterArea.getArray2_GW(Resources.encounter_gold); + var s = EncounterArea.getArray2_GW(Resources.encounter_silver); + var c = EncounterArea.getArray2_GW(Resources.encounter_crystal); + // Fishing + var f = EncounterArea.getArray2_F(Resources.encounter_gsc_f); + // Headbutt/Rock Smash + var h_c = EncounterArea.getArray2_H(Resources.encounter_crystal_h); + var h_g = EncounterArea.getArray2_H(Resources.encounter_gold_h); + var h_s = EncounterArea.getArray2_H(Resources.encounter_silver_h); + var h = h_c.Concat(h_g).Concat(h_s); + + return addExtraTableSlots(g, s).Concat(c).Concat(f).Concat(h).ToArray(); + } static Legal() // Setup { // Gen 1 { StaticRBY = getStaticEncounters(GameVersion.RBY); - - var red = EncounterArea.getArray1_GW(Resources.encounter_red); - var blu = EncounterArea.getArray1_GW(Resources.encounter_blue); - var ylw = EncounterArea.getArray1_GW(Resources.encounter_yellow); - var rb_fish = EncounterArea.getArray1_F(Resources.encounter_rb_f); - var ylw_fish = EncounterArea.getArray1_FY(Resources.encounter_yellow_f); - - red = addExtraTableSlots(red, rb_fish); - blu = addExtraTableSlots(blu, rb_fish); - ylw = addExtraTableSlots(ylw, ylw_fish); - - SlotsRBY = addExtraTableSlots(addExtraTableSlots(red, blu), ylw); - Array.Resize(ref SlotsRBY, SlotsRBY.Length + 1); - SlotsRBY[SlotsRBY.Length - 1] = FishOldGood_RBY; - + SlotsRBY = getTables1(); Evolves1 = new EvolutionTree(new[] { Resources.evos_rby }, GameVersion.RBY, PersonalTable.Y, MaxSpeciesID_1); } // Gen 2 { StaticGSC = getStaticEncounters(GameVersion.GSC); - - // Grass/Water - var g = EncounterArea.getArray2_GW(Resources.encounter_gold); - var s = EncounterArea.getArray2_GW(Resources.encounter_silver); - var c = EncounterArea.getArray2_GW(Resources.encounter_crystal); - // Fishing - var f = EncounterArea.getArray2_F(Resources.encounter_gsc_f); - // Headbutt/Rock Smash - var h_c = EncounterArea.getArray2_H(Resources.encounter_crystal_h); - var h_g = EncounterArea.getArray2_H(Resources.encounter_gold_h); - var h_s = EncounterArea.getArray2_H(Resources.encounter_silver_h); - var h = h_c.Concat(h_g).Concat(h_s); - - SlotsGSC = addExtraTableSlots(g, s).Concat(c).Concat(f).Concat(h).ToArray(); - + SlotsGSC = getTables2(); Evolves2 = new EvolutionTree(new[] { Resources.evos_gsc }, GameVersion.GSC, PersonalTable.C, MaxSpeciesID_2); } + // Gen3 + { + StaticR = getStaticEncounters(GameVersion.R); + StaticS = getStaticEncounters(GameVersion.S); + StaticE = getStaticEncounters(GameVersion.E); + StaticFR = getStaticEncounters(GameVersion.FR); + StaticLG = getStaticEncounters(GameVersion.LG); + + SlotsR = getEncounterTables(GameVersion.R); + SlotsS = getEncounterTables(GameVersion.S); + SlotsE = getEncounterTables(GameVersion.E); + SlotsFR = getEncounterTables(GameVersion.FR); + SlotsLG = getEncounterTables(GameVersion.LG); + + //Evolves3 = new EvolutionTree(Data.unpackMini(Resources.evos_rs, "rs"), GameVersion.RS, PersonalTable.RS, MaxSpeciesID_3); + + // Update Personal Entries with TM/Tutor Data + var TMHM = Data.unpackMini(Resources.hmtm_g3, "g3"); + for (int i = 0; i <= MaxSpeciesID_3; i++) + PersonalTable.RS[i].AddTMHM(TMHM[i]); + var tutors = Data.unpackMini(Resources.tutors_g3, "g3"); + for (int i = 0; i <= MaxSpeciesID_3; i++) + PersonalTable.RS[i].AddTypeTutors(tutors[i]); + } + // Gen 4 + { + StaticD = getStaticEncounters(GameVersion.D); + StaticP = getStaticEncounters(GameVersion.P); + StaticPt = getStaticEncounters(GameVersion.Pt); + StaticHG = getStaticEncounters(GameVersion.HG); + StaticSS = getStaticEncounters(GameVersion.SS); + + SlotsD = getEncounterTables(GameVersion.D); + SlotsP = getEncounterTables(GameVersion.P); + SlotsPt = getEncounterTables(GameVersion.Pt); + SlotsHG = getEncounterTables(GameVersion.HG); + SlotsSS = getEncounterTables(GameVersion.SS); + + //Evolves4 = new EvolutionTree(Data.unpackMini(Resources.evos_dp, "dp"), GameVersion.DP, PersonalTable.DP, MaxSpeciesID_4); + + // Update Personal Entries with Tutor Data + var tutors = Data.unpackMini(Resources.tutors_g4, "g4"); + for (int i = 0; i <= MaxSpeciesID_4; i++) + PersonalTable.HGSS[i].AddTypeTutors(tutors[i]); + } + // Gen 5 + { + StaticB = getStaticEncounters(GameVersion.B); + StaticW = getStaticEncounters(GameVersion.W); + StaticB2 = getStaticEncounters(GameVersion.B2); + StaticW2 = getStaticEncounters(GameVersion.W2); + + SlotsB = getEncounterTables(GameVersion.B); + SlotsW = getEncounterTables(GameVersion.W); + SlotsB2 = getEncounterTables(GameVersion.B2); + SlotsW2 = getEncounterTables(GameVersion.W2); + + //Evolves5 = new EvolutionTree(Data.unpackMini(Resources.evos_bw, "bw"), GameVersion.BW, PersonalTable.BW, MaxSpeciesID_5); + } // Gen 6 { StaticX = getStaticEncounters(GameVersion.X); @@ -226,6 +341,10 @@ private static void MarkG7SMSlots(ref EncounterArea[] Areas) Evolves7 = new EvolutionTree(Data.unpackMini(Resources.evos_sm, "sm"), GameVersion.SM, PersonalTable.SM, MaxSpeciesID_7); } + + // Temp + + Evolves3 = Evolves4 = Evolves5 = Evolves6; } // Moves @@ -246,18 +365,18 @@ internal static IEnumerable getValidMoves(PKM pkm, DexLevel[] evoChain, int internal static IEnumerable getValidRelearn(PKM pkm, int skipOption) { List r = new List { 0 }; - if (pkm.GenNumber < 6) + if (pkm.GenNumber < 6 || pkm.VC) return r; int species = getBaseSpecies(pkm, skipOption); - r.AddRange(getLVLMoves(pkm, species, 1, pkm.AltForm)); + r.AddRange(getRelearnLVLMoves(pkm, species, 1, pkm.AltForm)); int form = pkm.AltForm; if (pkm.Format == 6 && pkm.Species != 678) form = 0; r.AddRange(getEggMoves(pkm, species, form)); - r.AddRange(getLVLMoves(pkm, species, 100, pkm.AltForm)); + r.AddRange(getRelearnLVLMoves(pkm, species, 100, pkm.AltForm)); return r.Distinct(); } internal static IEnumerable getBaseEggMoves(PKM pkm, int skipOption, GameVersion gameSource) @@ -269,6 +388,41 @@ internal static IEnumerable getBaseEggMoves(PKM pkm, int skipOption, GameVe switch (gameSource) { + case GameVersion.R: + case GameVersion.S: + case GameVersion.RS: + if (pkm.InhabitedGeneration(3)) + return LevelUpRS[species].getMoves(1); + break; + case GameVersion.E: + if (pkm.InhabitedGeneration(3)) + return LevelUpE[species].getMoves(1); + break; + case GameVersion.FR: + case GameVersion.LG: + case GameVersion.FRLG: + // only difference in FR/LG is deoxys which doesn't breed. + if (pkm.InhabitedGeneration(3)) + return LevelUpFR[species].getMoves(1); + break; + + case GameVersion.D: + case GameVersion.P: + case GameVersion.DP: + if (pkm.InhabitedGeneration(4)) + return LevelUpDP[species].getMoves(1); + break; + case GameVersion.Pt: + if (pkm.InhabitedGeneration(4)) + return LevelUpPt[species].getMoves(1); + break; + case GameVersion.HG: + case GameVersion.SS: + case GameVersion.HGSS: + if (pkm.InhabitedGeneration(4)) + return LevelUpHGSS[species].getMoves(1); + break; + case GameVersion.X: case GameVersion.Y: case GameVersion.XY: @@ -386,13 +540,7 @@ internal static EncounterTrade getValidIngameTrade(PKM pkm, GameVersion gameSour // Get valid pre-evolutions IEnumerable p = getValidPreEvolutions(pkm); - EncounterTrade[] table = null; - if (pkm.XY) - table = TradeGift_XY; - else if (pkm.AO) - table = TradeGift_AO; - else if (pkm.SM) - table = TradeGift_SM; + EncounterTrade[] table = getEncounterTradeTable(pkm); EncounterTrade z = table?.FirstOrDefault(f => p.Any(r => r.Species == f.Species)); @@ -409,12 +557,18 @@ internal static EncounterTrade getValidIngameTrade(PKM pkm, GameVersion gameSour return null; if (z.SID != pkm.SID) return null; - if (pkm.HasOriginalMetLocation && z.Location != pkm.Met_Location) - return null; - if (pkm.HasOriginalMetLocation && z.Level != lvl) - return null; - if (!pkm.HasOriginalMetLocation && z.Level > lvl) - return null; + if (pkm.HasOriginalMetLocation) + { + if (z.Location != pkm.Met_Location) + return null; + if (z.Level != lvl) + return null; + } + else + { + if (z.Level > lvl) + return null; + } if (z.Nature != Nature.Random && (int)z.Nature != pkm.Nature) return null; if (z.Gender != pkm.Gender) @@ -426,6 +580,23 @@ internal static EncounterTrade getValidIngameTrade(PKM pkm, GameVersion gameSour return z; } + private static EncounterTrade[] getEncounterTradeTable(PKM pkm) + { + switch (pkm.GenNumber) + { + case 3: + return pkm.FRLG ? TradeGift_FRLG : TradeGift_RSE; + case 4: + return pkm.HGSS ? TradeGift_HGSS : TradeGift_DPPt; + case 5: + return pkm.B2W2 ? TradeGift_B2W2 : TradeGift_BW; + case 6: + return pkm.XY ? TradeGift_XY : TradeGift_AO; + case 7: + return pkm.SM ? TradeGift_SM : null; + } + return null; + } private static EncounterTrade getValidEncounterTradeVC(PKM pkm, GameVersion gameSource) { var p = getValidPreEvolutions(pkm).ToArray(); @@ -593,12 +764,14 @@ private static EvolutionTree getEvolutionTable(PKM pkm) return Evolves1; case 2: return Evolves2; - + case 3: + return Evolves3; + case 4: + return Evolves4; + case 5: + return Evolves5; case 6: return Evolves6; - case 7: - return Evolves7; - default: return Evolves7; } @@ -608,6 +781,10 @@ internal static IEnumerable getValidGifts(PKM pkm) { switch (pkm.GenNumber) { + case 4: + return getMatchingPGT(pkm, MGDB_G4); + case 5: + return getMatchingPGF(pkm, MGDB_G5); case 6: return getMatchingWC6(pkm, MGDB_G6); case 7: @@ -616,6 +793,96 @@ internal static IEnumerable getValidGifts(PKM pkm) return new List(); } } + private static IEnumerable getMatchingPGT(PKM pkm, IEnumerable DB) + { + var validPGT = new List(); + if (DB == null) + return validPGT; + + // todo + var vs = getValidPreEvolutions(pkm).ToArray(); + foreach (PGT mg in DB.OfType().Where(wc => vs.Any(dl => dl.Species == wc.Species))) + { + var wc = mg.PK; + if (pkm.Egg_Location == 0) // Not Egg + { + if (wc.SID != pkm.SID) continue; + if (wc.TID != pkm.TID) continue; + if (wc.OT_Name != pkm.OT_Name) continue; + if (wc.OT_Gender != pkm.OT_Gender) continue; + if (wc.Version != 0 && wc.Version != pkm.Version) continue; + if (wc.Language != 0 && wc.Language != pkm.Language) continue; + } + if (wc.AltForm != pkm.AltForm && vs.All(dl => !getCanFormChange(pkm, dl.Species))) continue; + if (wc.Met_Location != pkm.Met_Location) continue; + if (wc.Egg_Location != pkm.Egg_Location) continue; + if (wc.CurrentLevel != pkm.Met_Level) continue; + if (wc.Ball != pkm.Ball) continue; + if (wc.OT_Gender < 3 && wc.OT_Gender != pkm.OT_Gender) continue; + if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) continue; + if (wc.Gender != 3 && wc.Gender != pkm.Gender) continue; + + if (wc.CNT_Cool > pkm.CNT_Cool) continue; + if (wc.CNT_Beauty > pkm.CNT_Beauty) continue; + if (wc.CNT_Cute > pkm.CNT_Cute) continue; + if (wc.CNT_Smart > pkm.CNT_Smart) continue; + if (wc.CNT_Tough > pkm.CNT_Tough) continue; + if (wc.CNT_Sheen > pkm.CNT_Sheen) continue; + + // Some checks are best performed separately as they are caused by users screwing up valid data. + // if (wc.Level > pkm.CurrentLevel) continue; // Defer to level legality + // RIBBONS: Defer to ribbon legality + + validPGT.Add(mg); + } + return validPGT; + } + private static IEnumerable getMatchingPGF(PKM pkm, IEnumerable DB) + { + var validPGF = new List(); + if (DB == null) + return validPGF; + + // todo + var vs = getValidPreEvolutions(pkm).ToArray(); + foreach (PGF wc in DB.OfType().Where(wc => vs.Any(dl => dl.Species == wc.Species))) + { + if (pkm.Egg_Location == 0) // Not Egg + { + if (wc.CardID != pkm.SID) continue; + if (wc.TID != pkm.TID) continue; + if (wc.OT != pkm.OT_Name) continue; + if (wc.OTGender != pkm.OT_Gender) continue; + if (wc.PIDType == 0 && pkm.PID != wc.PID) continue; + if (wc.PIDType == 2 && !pkm.IsShiny) continue; + if (wc.PIDType == 3 && pkm.IsShiny) continue; + if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) continue; + if (wc.Language != 0 && wc.Language != pkm.Language) continue; + } + if (wc.Form != pkm.AltForm && vs.All(dl => !getCanFormChange(pkm, dl.Species))) continue; + if (wc.MetLocation != pkm.Met_Location) continue; + if (wc.EggLocation != pkm.Egg_Location) continue; + if (wc.Level != pkm.Met_Level) continue; + if (wc.Ball != pkm.Ball) continue; + if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) continue; + if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) continue; + if (wc.Gender != 3 && wc.Gender != pkm.Gender) continue; + + if (wc.CNT_Cool > pkm.CNT_Cool) continue; + if (wc.CNT_Beauty > pkm.CNT_Beauty) continue; + if (wc.CNT_Cute > pkm.CNT_Cute) continue; + if (wc.CNT_Smart > pkm.CNT_Smart) continue; + if (wc.CNT_Tough > pkm.CNT_Tough) continue; + if (wc.CNT_Sheen > pkm.CNT_Sheen) continue; + + // Some checks are best performed separately as they are caused by users screwing up valid data. + // if (wc.Level > pkm.CurrentLevel) continue; // Defer to level legality + // RIBBONS: Defer to ribbon legality + + validPGF.Add(wc); + } + return validPGF; + } private static IEnumerable getMatchingWC6(PKM pkm, IEnumerable DB) { List validWC6 = new List(); @@ -924,9 +1191,7 @@ internal static bool getCanBeCaptured(int species, int gen, GameVersion version { switch (gen) { - case 1: - return getCanBeCaptured(species, SlotsRBY, StaticRBY); - + // Capture Memory only obtainable via Gen 6. case 6: switch (version) { @@ -943,24 +1208,8 @@ internal static bool getCanBeCaptured(int species, int gen, GameVersion version return getCanBeCaptured(species, SlotsA, StaticA); case GameVersion.OR: return getCanBeCaptured(species, SlotsO, StaticO); - - default: - return false; - } - case 7: - switch (version) - { - case GameVersion.Any: - return getCanBeCaptured(species, SlotsSN, StaticSN) - || getCanBeCaptured(species, SlotsMN, StaticMN); - case GameVersion.SN: - return getCanBeCaptured(species, SlotsSN, StaticSN); - case GameVersion.MN: - return getCanBeCaptured(species, SlotsMN, StaticMN); - - default: - return false; } + break; } return false; } @@ -1229,27 +1478,27 @@ private static IEnumerable getDexNavAreas(PKM pkm) return new EncounterArea[0]; } } - private static IEnumerable getLVLMoves(PKM pkm, int species, int lvl, int formnum) + private static IEnumerable getRelearnLVLMoves(PKM pkm, int species, int lvl, int formnum) { List moves = new List(); - if (pkm.InhabitedGeneration(1)) + switch (pkm.GenNumber) { - moves.AddRange(((PersonalInfoG1)PersonalTable.RB[species]).Moves); - moves.AddRange(((PersonalInfoG1)PersonalTable.Y[species]).Moves); - moves.AddRange(LevelUpRB[species].getMoves(lvl)); - moves.AddRange(LevelUpY[species].getMoves(lvl)); - } - if (pkm.InhabitedGeneration(6)) - { - int ind_XY = PersonalTable.XY.getFormeIndex(species, formnum); - moves.AddRange(LevelUpXY[ind_XY].getMoves(lvl)); - int ind_AO = PersonalTable.AO.getFormeIndex(species, formnum); - moves.AddRange(LevelUpAO[ind_AO].getMoves(lvl)); - } - if (pkm.InhabitedGeneration(7)) - { - int ind_SM = PersonalTable.SM.getFormeIndex(species, formnum); - moves.AddRange(LevelUpSM[ind_SM].getMoves(lvl)); + case 6: + if (pkm.InhabitedGeneration(6)) + { + int ind_XY = PersonalTable.XY.getFormeIndex(species, formnum); + moves.AddRange(LevelUpXY[ind_XY].getMoves(lvl)); + int ind_AO = PersonalTable.AO.getFormeIndex(species, formnum); + moves.AddRange(LevelUpAO[ind_AO].getMoves(lvl)); + } + break; + case 7: + if (pkm.InhabitedGeneration(7)) + { + int ind_SM = PersonalTable.SM.getFormeIndex(species, formnum); + moves.AddRange(LevelUpSM[ind_SM].getMoves(lvl)); + } + break; } return moves; } @@ -1270,6 +1519,37 @@ private static IEnumerable getEncounterSlots(PKM pkm, int lvl = - case GameVersion.C: return getSlots(pkm, SlotsGSC, lvl); + case GameVersion.R: + return getSlots(pkm, SlotsR, lvl); + case GameVersion.S: + return getSlots(pkm, SlotsS, lvl); + case GameVersion.E: + return getSlots(pkm, SlotsE, lvl); + case GameVersion.FR: + return getSlots(pkm, SlotsFR, lvl); + case GameVersion.LG: + return getSlots(pkm, SlotsLG, lvl); + + case GameVersion.D: + return getSlots(pkm, SlotsD, lvl); + case GameVersion.P: + return getSlots(pkm, SlotsP, lvl); + case GameVersion.Pt: + return getSlots(pkm, SlotsPt, lvl); + case GameVersion.HG: + return getSlots(pkm, SlotsHG, lvl); + case GameVersion.SS: + return getSlots(pkm, SlotsSS, lvl); + + case GameVersion.B: + return getSlots(pkm, SlotsB, lvl); + case GameVersion.W: + return getSlots(pkm, SlotsW, lvl); + case GameVersion.B2: + return getSlots(pkm, SlotsB2, lvl); + case GameVersion.W2: + return getSlots(pkm, SlotsW2, lvl); + case GameVersion.X: return getSlots(pkm, SlotsX, lvl); case GameVersion.Y: @@ -1303,6 +1583,37 @@ private static IEnumerable getStaticEncounters(PKM pkm, int lvl case GameVersion.C: return getStatic(pkm, StaticGSC, lvl); + case GameVersion.R: + return getStatic(pkm, StaticR, lvl); + case GameVersion.S: + return getStatic(pkm, StaticS, lvl); + case GameVersion.E: + return getStatic(pkm, StaticE, lvl); + case GameVersion.FR: + return getStatic(pkm, StaticFR, lvl); + case GameVersion.LG: + return getStatic(pkm, StaticLG, lvl); + + case GameVersion.D: + return getStatic(pkm, StaticD, lvl); + case GameVersion.P: + return getStatic(pkm, StaticP, lvl); + case GameVersion.Pt: + return getStatic(pkm, StaticPt, lvl); + case GameVersion.HG: + return getStatic(pkm, StaticHG, lvl); + case GameVersion.SS: + return getStatic(pkm, StaticSS, lvl); + + case GameVersion.B: + return getStatic(pkm, StaticB, lvl); + case GameVersion.W: + return getStatic(pkm, StaticW, lvl); + case GameVersion.B2: + return getStatic(pkm, StaticB2, lvl); + case GameVersion.W2: + return getStatic(pkm, StaticW2, lvl); + case GameVersion.X: return getStatic(pkm, StaticX, lvl); case GameVersion.Y: @@ -1542,12 +1853,13 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form int index = PersonalTable.RB.getFormeIndex(species, 0); if (index == 0) return r; + var pi_rb = (PersonalInfoG1)PersonalTable.RB[index]; var pi_y = (PersonalInfoG1)PersonalTable.Y[index]; + r.AddRange(pi_rb.Moves); + r.AddRange(pi_y.Moves); if (LVL) { - r.AddRange(pi_rb.Moves); - r.AddRange(pi_y.Moves); r.AddRange(LevelUpRB[index].getMoves(lvl)); r.AddRange(LevelUpY[index].getMoves(lvl)); } @@ -1563,7 +1875,8 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form case 2: { int index = PersonalTable.C.getFormeIndex(species, 0); - var pi_c = (PersonalInfoG2)PersonalTable.C[index]; + if (index == 0) + return r; if (LVL) { r.AddRange(LevelUpGS[index].getMoves(lvl)); @@ -1571,6 +1884,7 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form } if (Machine) { + var pi_c = (PersonalInfoG2)PersonalTable.C[index]; r.AddRange(TMHM_GSC.Where((t, m) => pi_c.TMHM[m])); } if (moveTutor) @@ -1579,6 +1893,68 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form r = r.Where(m => m <= MaxMoveID_1).ToList(); break; } + case 3: + { + int index = PersonalTable.RS.getFormeIndex(species, 0); + if (index == 0) + return r; + if (LVL) + { + r.AddRange(LevelUpRS[index].getMoves(lvl)); + r.AddRange(LevelUpE[index].getMoves(lvl)); + r.AddRange(LevelUpFR[index].getMoves(lvl)); + r.AddRange(LevelUpLG[index].getMoves(lvl)); + } + if (Machine) + { + var pi_c = PersonalTable.RS[index]; + r.AddRange(TM_3.Where((t, m) => pi_c.TMHM[m])); + if (pkm.Format == 3) // HM moves must be removed for 3->4, only give if current format. + r.AddRange(HM_3.Where((t, m) => pi_c.TMHM[m+50])); + } + if (moveTutor) + r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); + break; + } + case 4: + { + int index = PersonalTable.HGSS.getFormeIndex(species, 0); + if (index == 0) + return r; + if (LVL) + { + r.AddRange(LevelUpDP[index].getMoves(lvl)); + r.AddRange(LevelUpPt[index].getMoves(lvl)); + r.AddRange(LevelUpHGSS[index].getMoves(lvl)); + } + if (Machine) + { + var pi_c = PersonalTable.HGSS[index]; + r.AddRange(TM_3.Where((t, m) => pi_c.TMHM[m])); + } + if (moveTutor) + r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); + break; + } + case 5: + { + int index = PersonalTable.B2W2.getFormeIndex(species, 0); + if (index == 0) + return r; + if (LVL) + { + r.AddRange(LevelUpBW[index].getMoves(lvl)); + r.AddRange(LevelUpB2W2[index].getMoves(lvl)); + } + if (Machine) + { + var pi_c = PersonalTable.B2W2[index]; + r.AddRange(TM_3.Where((t, m) => pi_c.TMHM[m])); + } + if (moveTutor) + r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); + break; + } case 6: switch (ver) { @@ -1586,11 +1962,18 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form case GameVersion.X: case GameVersion.Y: case GameVersion.XY: { int index = PersonalTable.XY.getFormeIndex(species, form); - PersonalInfo pi = PersonalTable.XY[index]; + if (index == 0) + return r; - if (LVL) r.AddRange(LevelUpXY[index].getMoves(lvl)); - if (moveTutor) r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); - if (Machine) r.AddRange(TMHM_XY.Where((t, m) => pi.TMHM[m])); + if (LVL) + r.AddRange(LevelUpXY[index].getMoves(lvl)); + if (moveTutor) + r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); + if (Machine) + { + PersonalInfo pi = PersonalTable.XY[index]; + r.AddRange(TMHM_XY.Where((t, m) => pi.TMHM[m])); + } if (ver == GameVersion.Any) // Fall Through goto case GameVersion.ORAS; @@ -1600,11 +1983,18 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form case GameVersion.AS: case GameVersion.OR: case GameVersion.ORAS: { int index = PersonalTable.AO.getFormeIndex(species, form); - PersonalInfo pi = PersonalTable.AO[index]; + if (index == 0) + return r; - if (LVL) r.AddRange(LevelUpAO[index].getMoves(lvl)); - if (moveTutor) r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); - if (Machine) r.AddRange(TMHM_AO.Where((t, m) => pi.TMHM[m])); + if (LVL) + r.AddRange(LevelUpAO[index].getMoves(lvl)); + if (moveTutor) + r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); + if (Machine) + { + PersonalInfo pi = PersonalTable.AO[index]; + r.AddRange(TMHM_AO.Where((t, m) => pi.TMHM[m])); + } break; } } @@ -1616,13 +2006,18 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form case GameVersion.SN: case GameVersion.MN: case GameVersion.SM: { int index = PersonalTable.SM.getFormeIndex(species, form); - PersonalInfo pi = PersonalTable.SM.getFormeEntry(species, form); if (MoveReminder) lvl = 100; // Move reminder can teach any level in movepool now! - if (LVL) r.AddRange(LevelUpSM[index].getMoves(lvl)); - if (moveTutor) r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); - if (Machine) r.AddRange(TMHM_SM.Where((t, m) => pi.TMHM[m])); + if (LVL) + r.AddRange(LevelUpSM[index].getMoves(lvl)); + if (moveTutor) + r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation)); + if (Machine) + { + PersonalInfo pi = PersonalTable.SM.getFormeEntry(species, form); + r.AddRange(TMHM_SM.Where((t, m) => pi.TMHM[m])); + } break; } } @@ -1650,8 +2045,22 @@ private static IEnumerable getEggMoves(PKM pkm, int species, int formnum, G return EggMovesC[species].Moves; default: return new List(); - } + case 3: + return EggMovesRS[species].Moves; + case 4: + switch (Version) + { + case GameVersion.DP: + case GameVersion.Pt: + return EggMovesDPPt[species].Moves; + case GameVersion.HGSS: + return EggMovesHGSS[species].Moves; + default: + return new List(); + } + case 5: + return EggMovesBW[species].Moves; case 6: // entries per species return EggMovesAO[species].Moves.Concat(EggMovesXY[species].Moves); @@ -1671,23 +2080,45 @@ private static IEnumerable getTutorMoves(PKM pkm, int species, int form, bo PersonalInfo info; switch (generation) { + case 1: + if (AllowGBCartEra && pkm.Format < 3 && (pkm.Species == 25 || pkm.Species == 26)) // Surf Pikachu via Stadium + moves.Add(57); + break; case 2: moves.AddRange(Tutors_GSC.Where((t, i) => PersonalTable.C[species].TMHM[57 + i])); goto case 1; - case 1: - if (pkm.Format < 3 && (pkm.Species == 25 || pkm.Species == 26)) // Surf Pikachu via Stadium - moves.Add(57); + case 3: + // RS Tutors + moves.AddRange(TypeTutor3.Where((t, i) => PersonalTable.C[species].TMHM[58 + i])); + // E Tutors (Free) + + // E Tutors (BP) + + // FRLG Tutors + + // XD + + // XD (Mew) + if (species == 151) + moves.AddRange(Tutor_3Mew); + + break; + case 4: + info = PersonalTable.HGSS[species]; + moves.AddRange(Tutors_4.Where((t, i) => info.TypeTutors[i])); + break; + case 5: + info = PersonalTable.B2W2[species]; + moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i])); + if (pkm.InhabitedGeneration(5) && specialTutors) + { + PersonalInfo pi = PersonalTable.B2W2.getFormeEntry(species, form); + for (int i = 0; i < Tutors_B2W2.Length; i++) + for (int b = 0; b < Tutors_B2W2[i].Length; b++) + if (pi.SpecialTutors[i][b]) + moves.Add(Tutors_B2W2[i][b]); + } break; - //case 5: - // Varied Tutors - //if (pkm.InhabitedGeneration(5) && Tutors) - //{ - // //PersonalInfo pi = PersonalTable.B2W2.getFormeEntry(species, form); - // //for (int i = 0; i < Tutors_B2W2.Length; i++) - // // for (int b = 0; b < Tutors_B2W2[i].Length; b++) - // // if (pi.SpecialTutors[i][b]) - // // moves.Add(Tutors_B2W2[i][b]); - //} case 6: info = PersonalTable.AO[species]; moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i])); @@ -1705,7 +2136,6 @@ private static IEnumerable getTutorMoves(PKM pkm, int species, int form, bo moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i])); // No special tutors in G7 break; - } return moves.Distinct(); } diff --git a/PKHeX/Legality/Tables3.cs b/PKHeX/Legality/Tables3.cs index ac1ccbed4..5775ee0a1 100644 --- a/PKHeX/Legality/Tables3.cs +++ b/PKHeX/Legality/Tables3.cs @@ -99,6 +99,49 @@ public static partial class Legal // todo }; internal static readonly bool[] ReleasedHeldItems_3 = Enumerable.Range(0, MaxItemID_3+1).Select(i => HeldItems_RS.Contains((ushort)i) && !UnreleasedItems_3.Contains(i)).ToArray(); + internal static readonly int[] TM_3 = + { + 264, 337, 352, 347, 046, 092, 258, 339, 331, 237, + 241, 269, 058, 059, 063, 113, 182, 240, 202, 219, + 218, 076, 231, 085, 087, 089, 216, 091, 094, 247, + 280, 104, 115, 351, 053, 188, 201, 126, 317, 332, + 259, 263, 290, 156, 213, 168, 211, 285, 289, 315, + }; internal static readonly int[] HM_3 = {15, 19, 57, 70, 148, 249, 127, 291}; + internal static readonly int[] TypeTutor3 = {338, 307, 308}; + internal static readonly int[] Tutor_3Mew = + { + 185, // Feint Attack + 252, // Fake Out + 095, // Hypnosis + 101, // Night Shade + 272, // Role Play + 192, // Zap Cannon + }; + internal static readonly int[][] Tutor_Frontier = + { + new[] {135, 069, 138, 005, 025, 034, 157, 068, 086, 014}, + new[] {111, 173, 189, 129, 196, 203, 244, 008, 009, 007}, + }; + internal static readonly int[] Tutor_E = {038, 223, 153, 210, 118, 102, 205, 214, 164, 207}; + internal static readonly int[] Tutor_FRLG = {034, 068, 038, 138, 153, 025, 005, 118, 102, 157, 069, 135, 164, 014, 086}; + + internal static readonly EncounterStatic[] Encounter_RSE = + { + //todo + }; + internal static readonly EncounterStatic[] Encounter_FRLG = + { + //todo + }; + internal static readonly EncounterTrade[] TradeGift_RSE = + { + //todo + }; + internal static readonly EncounterTrade[] TradeGift_FRLG = + { + //todo + }; + } } diff --git a/PKHeX/Legality/Tables4.cs b/PKHeX/Legality/Tables4.cs index 5c22a0c3e..6f4e4cffa 100644 --- a/PKHeX/Legality/Tables4.cs +++ b/PKHeX/Legality/Tables4.cs @@ -141,5 +141,32 @@ public static partial class Legal }; internal static readonly bool[] ReleasedHeldItems_4 = Enumerable.Range(0, MaxItemID_4_HGSS+1).Select(i => HeldItems_HGSS.Contains((ushort)i) && !UnreleasedItems_4.Contains(i)).ToArray(); internal static readonly int[] CrownBeasts = {251, 243, 244, 245}; + + internal static readonly int[] Tutors_4 = + { + 291, 189, 210, 196, 205, 009, 007, 276, + 008, 442, 401, 466, 380, 173, 180, 314, + 270, 283, 200, 246, 235, 324, 428, 410, + 414, 441, 239, 402, 334, 393, 387, 340, + 271, 257, 282, 389, 129, 253, 162, 220, + 081, 366, 356, 388, 277, 272, 215, 067, + 143, 335, 450, + }; + internal static readonly EncounterStatic[] Encounter_DPPt = + { + //todo + }; + internal static readonly EncounterStatic[] Encounter_HGSS = + { + //todo + }; + internal static readonly EncounterTrade[] TradeGift_DPPt = + { + //todo + }; + internal static readonly EncounterTrade[] TradeGift_HGSS = + { + //todo + }; } } diff --git a/PKHeX/Legality/Tables5.cs b/PKHeX/Legality/Tables5.cs index 8e961fce3..5c30bbcfb 100644 --- a/PKHeX/Legality/Tables5.cs +++ b/PKHeX/Legality/Tables5.cs @@ -99,5 +99,29 @@ public static partial class Legal // todo }; internal static readonly bool[] ReleasedHeldItems_5 = Enumerable.Range(0, MaxItemID_5_B2W2+1).Select(i => HeldItems_BW.Contains((ushort)i) && !UnreleasedItems_5.Contains(i)).ToArray(); + internal static readonly int[][] Tutors_B2W2 = + { + new[] { 343, 450, 529, 340, 324, 442, 162, 253, 402, 530, 067, 441, 007, 009, 008 }, // Driftveil City + new[] { 387, 334, 393, 277, 335, 304, 527, 196, 231, 401, 414, 428, 492, 276, 356, 406, 399 }, // Lentimas Town + new[] { 020, 173, 215, 282, 235, 355, 143, 272, 257, 202, 409, 220, 366 }, // Humilau City + new[] { 388, 380, 270, 495, 478, 472, 180, 278, 271, 446, 200, 283, 214, 285, 289, } // Nacrene City + }; + + internal static readonly EncounterStatic[] Encounter_BW = + { + //todo + }; + internal static readonly EncounterStatic[] Encounter_B2W2 = + { + //todo + }; + internal static readonly EncounterTrade[] TradeGift_BW = + { + //todo + }; + internal static readonly EncounterTrade[] TradeGift_B2W2 = + { + //todo + }; } } diff --git a/PKHeX/PKHeX.Core.csproj b/PKHeX/PKHeX.Core.csproj index 2cbc189ee..255a24cbf 100644 --- a/PKHeX/PKHeX.Core.csproj +++ b/PKHeX/PKHeX.Core.csproj @@ -260,8 +260,12 @@ Settings.settings True + + + + @@ -286,15 +290,26 @@ + + + + + + + + + - + + + @@ -355,7 +370,6 @@ - diff --git a/PKHeX/PKM/PKM.cs b/PKHeX/PKM/PKM.cs index 79cd8446e..9fd45a1b3 100644 --- a/PKHeX/PKM/PKM.cs +++ b/PKHeX/PKM/PKM.cs @@ -263,11 +263,13 @@ public byte[] Write() public bool VC2 => Version >= 39 && Version <= 41; public bool VC1 => Version >= 35 && Version <= 38; public bool Horohoro => Version == 34; + public bool FRLG => Version == (int)GameVersion.FR || Version == (int)GameVersion.LG; + public bool HGSS => Version == (int)GameVersion.HG || Version == (int)GameVersion.SS; + public bool B2W2 => Version == (int)GameVersion.B2 || Version == (int)GameVersion.W2; public bool XY => Version == (int)GameVersion.X || Version == (int)GameVersion.Y; public bool AO => Version == (int)GameVersion.AS || Version == (int)GameVersion.OR; public bool SM => Version == (int)GameVersion.SN || Version == (int)GameVersion.MN; protected bool PtHGSS => GameVersion.Pt == (GameVersion)Version || HGSS; - public bool HGSS => new[] {GameVersion.HG, GameVersion.SS}.Contains((GameVersion)Version); public bool VC => VC1 || VC2; public bool Gen7 => Version >= 30 && Version <= 33; public bool Gen6 => Version >= 24 && Version <= 29; diff --git a/PKHeX/PersonalInfo/PersonalInfo.cs b/PKHeX/PersonalInfo/PersonalInfo.cs index 0f923cfb2..18eac1b1c 100644 --- a/PKHeX/PersonalInfo/PersonalInfo.cs +++ b/PKHeX/PersonalInfo/PersonalInfo.cs @@ -46,19 +46,22 @@ public abstract class PersonalInfo protected static bool[] getBits(byte[] data) { - bool[] r = new bool[8 * data.Length]; + bool[] r = new bool[data.Length<<3]; for (int i = 0; i < r.Length; i++) - r[i] = (data[i/8] >> (i&7) & 0x1) == 1; + r[i] = (data[i>>3] >> (i&7) & 0x1) == 1; return r; } protected static byte[] setBits(bool[] bits) { - byte[] data = new byte[bits.Length/8]; + byte[] data = new byte[bits.Length>>3]; for (int i = 0; i < bits.Length; i++) - data[i / 8] |= (byte)(bits[i] ? 1 << (i&0x7) : 0); + data[i>>3] |= (byte)(bits[i] ? 1 << (i&0x7) : 0); return data; } + public void AddTMHM(byte[] data) => TMHM = getBits(data); + public void AddTypeTutors(byte[] data) => TypeTutors = getBits(data); + // Data Manipulation public int FormeIndex(int species, int forme) { diff --git a/PKHeX/Properties/Resources.Designer.cs b/PKHeX/Properties/Resources.Designer.cs index 5f4fb9abb..d35db23b0 100644 --- a/PKHeX/Properties/Resources.Designer.cs +++ b/PKHeX/Properties/Resources.Designer.cs @@ -12324,15 +12324,15 @@ public class Resources { /// Looks up a localized string similar to PKHeX - By Kaphotics ///http://projectpokemon.org/pkhex /// - ///17/02/25 - New Update: + ///17/03/18 - New Update: /// - Legality: - /// - - Added: Legality checking for RBY Pokémon as pk1 and pk7+. - /// - - Fixed: More edge cases for legality checks. - /// - Batch Editor: - /// - - Added: Nickname clearing to batch editor (via .IsNicknamed=False). - /// - - Added: Legality filtering and bulk suggestions for Met Location, Current Moves & Relearn Moves. - /// - - - Use $suggest to use suggested result from the legality analysis. - /// - - Changed: Properties are now sort [rest of string was truncated]";. + /// - - Added: Heavy Ball legality check. Thanks SciresM! + /// - - Added: Loading Gen1 save file now asks if it is a Virtual Console save for separation of GenII legality. + /// - Fixed: Exporting boxes to folders now has the correct box names (was previously shifted by 1). Thanks RoC! + /// - Fixed: Colosseum/XD Purification value editing. Thanks ArcticLoveBunny! + /// - Fixed: Joyful Game Corner now editable by Emerald saves. + /// + /// [rest of string was truncated]";. /// public static string changelog { get { @@ -12432,6 +12432,16 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] eggmove_bw { + get { + object obj = ResourceManager.GetObject("eggmove_bw", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -12442,6 +12452,16 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] eggmove_dppt { + get { + object obj = ResourceManager.GetObject("eggmove_dppt", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -12452,6 +12472,26 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] eggmove_hgss { + get { + object obj = ResourceManager.GetObject("eggmove_hgss", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] eggmove_rs { + get { + object obj = ResourceManager.GetObject("eggmove_rs", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -12869,6 +12909,16 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] hmtm_g3 { + get { + object obj = ResourceManager.GetObject("hmtm_g3", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -17924,6 +17974,26 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_b2w2 { + get { + object obj = ResourceManager.GetObject("lvlmove_b2w2", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_bw { + get { + object obj = ResourceManager.GetObject("lvlmove_bw", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -17934,6 +18004,36 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_dp { + get { + object obj = ResourceManager.GetObject("lvlmove_dp", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_e { + get { + object obj = ResourceManager.GetObject("lvlmove_e", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_fr { + get { + object obj = ResourceManager.GetObject("lvlmove_fr", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -17944,6 +18044,36 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_hgss { + get { + object obj = ResourceManager.GetObject("lvlmove_hgss", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_lg { + get { + object obj = ResourceManager.GetObject("lvlmove_lg", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_pt { + get { + object obj = ResourceManager.GetObject("lvlmove_pt", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -17954,6 +18084,16 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] lvlmove_rs { + get { + object obj = ResourceManager.GetObject("lvlmove_rs", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// @@ -18205,7 +18345,7 @@ public class Resources { } /// - /// Looks up a localized string similar to 20170225. + /// Looks up a localized string similar to 20170318. /// public static string ProgramVersion { get { @@ -37701,6 +37841,26 @@ public class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] tutors_g3 { + get { + object obj = ResourceManager.GetObject("tutors_g3", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + public static byte[] tutors_g4 { + get { + object obj = ResourceManager.GetObject("tutors_g4", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/PKHeX/Properties/Resources.resx b/PKHeX/Properties/Resources.resx index d293e6966..b3d863fdc 100644 --- a/PKHeX/Properties/Resources.resx +++ b/PKHeX/Properties/Resources.resx @@ -7450,4 +7450,52 @@ ..\Resources\img\misc\rare_icon_alt.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - + + ..\Resources\byte\eggmove_bw.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\eggmove_dppt.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\eggmove_hgss.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\eggmove_rs.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\hmtm_g3.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_b2w2.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_bw.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_dp.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_e.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_fr.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_hgss.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_lg.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_pt.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\lvlmove_rs.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\tutors_g3.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\tutors_g4.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PKHeX/Resources/byte/eggmove_bw.pkl b/PKHeX/Resources/byte/eggmove_bw.pkl new file mode 100644 index 000000000..6e8ce761e Binary files /dev/null and b/PKHeX/Resources/byte/eggmove_bw.pkl differ diff --git a/PKHeX/Resources/byte/eggmove_dppt.pkl b/PKHeX/Resources/byte/eggmove_dppt.pkl new file mode 100644 index 000000000..29494529c Binary files /dev/null and b/PKHeX/Resources/byte/eggmove_dppt.pkl differ diff --git a/PKHeX/Resources/byte/eggmove_hgss.pkl b/PKHeX/Resources/byte/eggmove_hgss.pkl new file mode 100644 index 000000000..197954900 Binary files /dev/null and b/PKHeX/Resources/byte/eggmove_hgss.pkl differ diff --git a/PKHeX/Resources/byte/eggmove_rs.pkl b/PKHeX/Resources/byte/eggmove_rs.pkl new file mode 100644 index 000000000..dc1d0067a Binary files /dev/null and b/PKHeX/Resources/byte/eggmove_rs.pkl differ diff --git a/PKHeX/Resources/byte/hmtm_g3.pkl b/PKHeX/Resources/byte/hmtm_g3.pkl new file mode 100644 index 000000000..76a435faa Binary files /dev/null and b/PKHeX/Resources/byte/hmtm_g3.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_b2w2.pkl b/PKHeX/Resources/byte/lvlmove_b2w2.pkl new file mode 100644 index 000000000..44a2ff081 Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_b2w2.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_bw.pkl b/PKHeX/Resources/byte/lvlmove_bw.pkl new file mode 100644 index 000000000..19dc46322 Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_bw.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_dp.pkl b/PKHeX/Resources/byte/lvlmove_dp.pkl new file mode 100644 index 000000000..a3def988c Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_dp.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_e.pkl b/PKHeX/Resources/byte/lvlmove_e.pkl new file mode 100644 index 000000000..a303ffc20 Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_e.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_fr.pkl b/PKHeX/Resources/byte/lvlmove_fr.pkl new file mode 100644 index 000000000..ef6f779c2 Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_fr.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_hgss.pkl b/PKHeX/Resources/byte/lvlmove_hgss.pkl new file mode 100644 index 000000000..eba604ea7 Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_hgss.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_lg.pkl b/PKHeX/Resources/byte/lvlmove_lg.pkl new file mode 100644 index 000000000..3dfb213ca Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_lg.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_pt.pkl b/PKHeX/Resources/byte/lvlmove_pt.pkl new file mode 100644 index 000000000..9ce514774 Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_pt.pkl differ diff --git a/PKHeX/Resources/byte/lvlmove_rs.pkl b/PKHeX/Resources/byte/lvlmove_rs.pkl new file mode 100644 index 000000000..82a08774b Binary files /dev/null and b/PKHeX/Resources/byte/lvlmove_rs.pkl differ diff --git a/PKHeX/Resources/byte/tutors_g3.pkl b/PKHeX/Resources/byte/tutors_g3.pkl new file mode 100644 index 000000000..258da1310 Binary files /dev/null and b/PKHeX/Resources/byte/tutors_g3.pkl differ diff --git a/PKHeX/Resources/byte/tutors_g4.pkl b/PKHeX/Resources/byte/tutors_g4.pkl new file mode 100644 index 000000000..d18a9bb95 Binary files /dev/null and b/PKHeX/Resources/byte/tutors_g4.pkl differ diff --git a/PKHeX/Saves/SaveUtil.cs b/PKHeX/Saves/SaveUtil.cs index e7e56dd52..504bf6031 100644 --- a/PKHeX/Saves/SaveUtil.cs +++ b/PKHeX/Saves/SaveUtil.cs @@ -257,7 +257,7 @@ public static GameVersion getIsG3COLOSAV(byte[] data) int offset = data.Length - SIZE_G3COLO; for (int i = 0; i < 3; i++) { - var ident = data.Skip(0x6000 + offset + 0x1E000*i).Take(4).ToArray(); + var ident = data.Skip(0x6000 + offset + 0x1E000*i).Take(4); if (!ident.SequenceEqual(slotintroColo)) return GameVersion.Invalid; } @@ -276,7 +276,7 @@ public static GameVersion getIsG3XDSAV(byte[] data) int offset = data.Length - SIZE_G3XD; for (int i = 0; i < 2; i++) { - var ident = data.Skip(0x6000 + offset + 0x28000 * i).Take(4).ToArray(); + var ident = data.Skip(0x6000 + offset + 0x28000 * i).Take(4); if (!ident.SequenceEqual(slotintroXD)) return GameVersion.Invalid; }