diff --git a/PKHeX.Core/Saves/SAV7.cs b/PKHeX.Core/Saves/SAV7.cs index 9e061bead..696b17fd4 100644 --- a/PKHeX.Core/Saves/SAV7.cs +++ b/PKHeX.Core/Saves/SAV7.cs @@ -1037,7 +1037,7 @@ protected override void SetDex(PKM pkm) int formstart = pkm.AltForm; int formend = pkm.AltForm; - bool reset = SanitizeFormsToIterate(pkm.Species, out int fs, out int fe, formstart); + bool reset = SanitizeFormsToIterate(pkm.Species, out int fs, out int fe, formstart, USUM); if (reset) { formstart = fs; @@ -1092,57 +1092,58 @@ protected override void SetPartyValues(PKM pkm, bool isParty) ((PK7)pkm).FormDuration = duration; } - private bool SanitizeFormsToIterate(int species, out int formStart, out int formEnd, int formIn) + public static bool SanitizeFormsToIterate(int species, out int formStart, out int formEnd, int formIn, bool USUM) { // 004AA370 in Moon // Simplified in terms of usage -- only overrides to give all the battle forms for a pkm - formStart = 0; - formEnd = 0; switch (species) { case 351: // Castform - case 778 when USUM: // Mimikyu formStart = 0; formEnd = 3; return true; case 020: // Raticate - case 105 when USUM: // Marowak + case 105: // Marowak formStart = 0; - formEnd = 2; + formEnd = 1; return true; + case 735: // Gumshoos + case 758: // Salazzle + case 754: // Lurantis + case 738: // Vikavolt + case 784: // Kommo-o + case 752: // Araquanid + case 777: // Togedemaru + case 743: // Ribombee + case 744: // Rockruff + break; + case 421: // Cherrim case 555: // Darmanitan case 648: // Meloetta case 746: // Wishiwashi case 778: // Mimikyu - case 743 when USUM: // Ribombee - case 744 when USUM: // Rockruff - case 752 when USUM: // Araquanid - case 777 when USUM: // Togedemaru formStart = 0; formEnd = 1; return true; - case 774: // Minior + case 774 when formIn > 6: // Minior // Cores forms are after Meteor forms, so the game iterator would give all meteor forms (NO!) // So the game so the game chooses to only award entries for Core forms after they appear in battle. - return formIn > 6; // resets to 0/0 if an invalid request is made (non-form entry) - - case 718: - if (formIn == 3) // complete - return true; // 0/0 - if (formIn != 2) // give - return false; + break; // resets to 0/0 if an invalid request is made (non-form entry) - // Apparently form 2 is invalid (50% core-ability), set to 10%'s form - formStart = 1; - formEnd = 1; - return true; + case 718 when formIn > 1: + break; default: - return false; + int count = USUM ? SaveUtil.GetDexFormCountUSUM(species) : SaveUtil.GetDexFormCountSM(species); + formStart = formEnd = 0; + return count < formIn; } + formStart = 0; + formEnd = 0; + return true; } private void SetDexFlags(int index, int gender, int shiny, int baseSpecies) { diff --git a/PKHeX.Core/Saves/SaveUtil.cs b/PKHeX.Core/Saves/SaveUtil.cs index a05470357..011b8f29a 100644 --- a/PKHeX.Core/Saves/SaveUtil.cs +++ b/PKHeX.Core/Saves/SaveUtil.cs @@ -777,6 +777,13 @@ private static int GetDexFormBitIndex(int species, int formct, int start, IReadO return -1; return formindex; } + private static int GetDexFormCount(int species, IReadOnlyList formtable) + { + for (int i = 0; i < formtable.Count; i += 2) + if (formtable[i] == species) + return formtable[i + 1]; + return 0; + } public static int GetDexFormIndexBW(int species, int formct) { if (formct < 1 || species < 0) @@ -897,6 +904,8 @@ public static int GetDexFormIndexORAS(int species, int formct) } public static int GetDexFormIndexSM(int species, int formct, int start) => GetDexFormBitIndex(species, formct, start, formtable_SM); public static int GetDexFormIndexUSUM(int species, int formct, int start) => GetDexFormBitIndex(species, formct, start, formtable_USUM); + public static int GetDexFormCountSM(int species) => GetDexFormCount(species, formtable_SM); + public static int GetDexFormCountUSUM(int species) => GetDexFormCount(species, formtable_USUM); public static int GetCXDVersionID(int gen3version) { diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_PokedexSM.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_PokedexSM.cs index 414b9a152..a8ff9a636 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_PokedexSM.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_PokedexSM.cs @@ -142,7 +142,7 @@ private bool FillLBForms() var ds = PKX.GetFormList(bspecies, GameInfo.Strings.types, GameInfo.Strings.forms, Main.GenderSymbols, SAV.Generation).ToList(); if (ds.Count == 1 && string.IsNullOrEmpty(ds[0])) { - // empty (Alolan Totems) + // empty LB_Forms.Enabled = false; return false; } @@ -369,84 +369,45 @@ private void ModifyAll(object sender, EventArgs e) { allModifying = true; LB_Forms.Enabled = LB_Forms.Visible = false; - + bool USUM = SAV.USUM; int lang = SAV.Language; if (lang > 5) lang -= 1; lang -= 1; - int[] totem = { 811, 1018, 1019, 1025, 1026, 1058, 1059, 1060 }; - // 1024 is used by Wishiwashi school form. - if (sender == mnuSeenNone || sender == mnuSeenAll || sender == mnuComplete) - for (int i = 0; i < LB_Species.Items.Count; i++) - { - LB_Species.SelectedIndex = i; - int gt = GetBaseSpeciesGender(LB_Species.SelectedIndex); - foreach (CheckBox t in new[] { CHK_P2, CHK_P3, CHK_P4, CHK_P5 }) - t.Checked = mnuSeenNone != sender && t.Enabled; - - if (mnuSeenNone != sender && !totem.Contains(i+1)) - { - // ensure at least one Displayed except for formes - if (i >= CB_Species.Items.Count) - continue; - if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) - (gt != 254 ? CHK_P6 : CHK_P7).Checked = true; - } - else - { - foreach (CheckBox t in CP) - t.Checked = false; - } - - if (!CHK_P1.Checked) - foreach (CheckBox t in CL) - t.Checked = false; - } - - if (sender == mnuCaughtNone || sender == mnuCaughtAll || sender == mnuComplete) + for (int i = 0; i < SAV.MaxSpeciesID; i++) { - for (int i = 0; i < LB_Species.Items.Count; i++) + int spec = i + 1; + var pi = SAV.Personal[spec]; + var gt = pi.Gender; + var c = pi.FormeCount; + + // Set base species flags + LB_Species.SelectedIndex = i; + SetSeen(sender, gt, false); + SetCaught(sender, gt, lang, false); + + // Set forme flags + for (int j = 1; j < c; j++) { - int gt = GetBaseSpeciesGender(LB_Species.SelectedIndex); - LB_Species.SelectedIndex = i; - foreach (CheckBox t in new[] { CHK_P1 }) - t.Checked = mnuCaughtNone != sender; - for (int j = 0; j < CL.Length; j++) - CL[j].Checked = CL[j].Enabled && (sender == mnuComplete || (mnuCaughtNone != sender && j == lang)); - - // Don't modify totem entries - if (totem.Contains(i+1)) - continue; - - if (mnuCaughtNone == sender) + int start = j; + int end = j; + if (SAV7.SanitizeFormsToIterate(spec, out int s, out int n, j, USUM)) { - if (i >= CB_Species.Items.Count) + start = s; + end = n; + } + for (int f = start; f <= end; f++) + { + if (f == 0) + continue; // already set + int x = SAV.USUM ? SaveUtil.GetDexFormIndexUSUM(spec, c, f) : SaveUtil.GetDexFormIndexSM(spec, c, f); + if (x < 0) continue; - if (!(CHK_P2.Checked || CHK_P3.Checked || CHK_P4.Checked || CHK_P5.Checked)) // if seen - if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) // not displayed - (gt != 254 ? CHK_P6 : CHK_P7).Checked = true; // check one - - continue; + bool isForm = f != 0; + LB_Species.SelectedIndex = SAV.MaxSpeciesID - 1 + x; + SetSeen(sender, gt, isForm); + SetCaught(sender, gt, lang, isForm); } - - if (mnuComplete == sender) - { - // Seen All - foreach (var chk in new[] { CHK_P2, CHK_P3, CHK_P4, CHK_P5 }) - chk.Checked = chk.Enabled; - } - else - { - // ensure at least one SEEN - if (!(CHK_P2.Checked || CHK_P3.Checked || CHK_P4.Checked || CHK_P5.Checked)) - (gt != 254 ? CHK_P2 : CHK_P3).Checked = true; - } - - // ensure at least one Displayed except for formes - if (i >= CB_Species.Items.Count) - continue; - if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) - (gt != 254 ? CHK_P6 : CHK_P7).Checked = CHK_P1.Enabled; } } @@ -458,5 +419,67 @@ private void ModifyAll(object sender, EventArgs e) LB_Forms.Enabled = LB_Forms.Visible = true; LB_Species.SelectedIndex = 0; } + + private void SetCaught(object sender, int gt, int lang, bool isForm) + { + foreach (CheckBox t in new[] {CHK_P1}) + t.Checked = mnuCaughtNone != sender; + for (int j = 0; j < CL.Length; j++) + CL[j].Checked = CL[j].Enabled && (sender == mnuComplete || (mnuCaughtNone != sender && j == lang)); + + if (mnuCaughtNone == sender) + { + if (isForm) + return; + if (!(CHK_P2.Checked || CHK_P3.Checked || CHK_P4.Checked || CHK_P5.Checked)) // if seen + if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) // not displayed + (gt != 254 ? CHK_P6 : CHK_P7).Checked = true; // check one + + return; + } + + if (mnuComplete == sender) + { + // Seen All + foreach (var chk in new[] {CHK_P2, CHK_P3, CHK_P4, CHK_P5}) + chk.Checked = chk.Enabled; + } + else + { + // ensure at least one SEEN + if (!(CHK_P2.Checked || CHK_P3.Checked || CHK_P4.Checked || CHK_P5.Checked)) + (gt != 254 ? CHK_P2 : CHK_P3).Checked = true; + } + + // ensure at least one Displayed except for formes + if (isForm) + return; + if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) + (gt != 254 ? CHK_P6 : CHK_P7).Checked = CHK_P1.Enabled; + } + + private void SetSeen(object sender, int gt, bool isForm) + { + foreach (CheckBox t in new[] {CHK_P2, CHK_P3, CHK_P4, CHK_P5}) + t.Checked = mnuSeenNone != sender && t.Enabled; + + if (mnuSeenNone != sender) + { + // ensure at least one Displayed except for formes + if (isForm) + return; + if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) + (gt != 254 ? CHK_P6 : CHK_P7).Checked = true; + } + else + { + foreach (CheckBox t in CP) + t.Checked = false; + } + + if (!CHK_P1.Checked) + foreach (CheckBox t in CL) + t.Checked = false; + } } }