From d73252076223cb28bf2f3c5e45a6f6d02b0b202b Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 3 Aug 2025 14:24:22 -0500 Subject: [PATCH] Rewrite Gen5 dex editor & backend Closes #4533 --- .../Saves/Access/SaveBlockAccessor5B2W2.cs | 2 +- .../Saves/Access/SaveBlockAccessor5BW.cs | 2 +- .../Saves/Substructures/PokeDex/Zukan5.cs | 521 +++++++++++++----- .../Gen5/SAV_Pokedex5.Designer.cs | 121 ++-- .../Save Editors/Gen5/SAV_Pokedex5.cs | 215 +++----- Tests/PKHeX.Core.Tests/Saves/PokeDex.cs | 6 +- 6 files changed, 544 insertions(+), 323 deletions(-) diff --git a/PKHeX.Core/Saves/Access/SaveBlockAccessor5B2W2.cs b/PKHeX.Core/Saves/Access/SaveBlockAccessor5B2W2.cs index ed14cf2eb..b882674cd 100644 --- a/PKHeX.Core/Saves/Access/SaveBlockAccessor5B2W2.cs +++ b/PKHeX.Core/Saves/Access/SaveBlockAccessor5B2W2.cs @@ -107,7 +107,7 @@ public sealed class SaveBlockAccessor5B2W2(SAV5B2W2 sav) public Daycare5 Daycare { get; } = new(sav, Block(sav, 50)); public Misc5B2W2 Misc { get; } = new(sav, Block(sav, 52)); public Entralink5B2W2 Entralink { get; } = new(sav, Block(sav, 53)); - public Zukan5 Zukan { get; } = new(sav, Block(sav, 54), 0x328); // form flags size is + 8 from B/W with new forms (Therians) + public Zukan5 Zukan { get; } = new Zukan5B2W2(Block(sav, 54)); public Encount5B2W2 Encount { get; } = new(sav, Block(sav, 55)); public BattleSubwayPlay5 BattleSubwayPlay { get; } = new(sav, Block(sav, 56)); public BattleSubway5 BattleSubway { get; } = new(sav, Block(sav, 57)); diff --git a/PKHeX.Core/Saves/Access/SaveBlockAccessor5BW.cs b/PKHeX.Core/Saves/Access/SaveBlockAccessor5BW.cs index cf3de08be..7095cb08a 100644 --- a/PKHeX.Core/Saves/Access/SaveBlockAccessor5BW.cs +++ b/PKHeX.Core/Saves/Access/SaveBlockAccessor5BW.cs @@ -102,7 +102,7 @@ public sealed class SaveBlockAccessor5BW(SAV5BW sav) : ISaveBlockAccessor dex) : Zukan5(dex) +{ + protected override int FormLen => 9; + public override (byte Index, byte Count) GetFormIndex(ushort species) => GetFormIndexBW(species); + + public static (byte Index, byte Count) GetFormIndexBW(ushort species) => species switch + { + 201 => (000, 28), // 28 Unown + 386 => (028, 4), // 4 Deoxys + 492 => (032, 2), // 2 Shaymin + 487 => (034, 2), // 2 Giratina + 479 => (036, 6), // 6 Rotom + 422 => (042, 2), // 2 Shellos + 423 => (044, 2), // 2 Gastrodon + 412 => (046, 3), // 3 Burmy + 413 => (049, 3), // 3 Wormadam + 351 => (052, 4), // 4 Castform + 421 => (056, 2), // 2 Cherrim + 585 => (058, 4), // 4 Deerling + 586 => (062, 4), // 4 Sawsbuck + 648 => (066, 2), // 2 Meloetta + 555 => (068, 2), // 2 Darmanitan + 550 => (070, 2), // 2 Basculin + _ => default, + }; +} + +public sealed class Zukan5B2W2(Memory dex) : Zukan5(dex) +{ + protected override int FormLen => 11; // form flags size is + 11 from B/W with new forms (Therians) and Kyurem forms + public override (byte Index, byte Count) GetFormIndex(ushort species) => GetFormIndexB2W2(species); + + public static (byte Index, byte Count) GetFormIndexB2W2(ushort species) => species switch + { + 646 => (072, 3), // 3 Kyurem + 647 => (075, 2), // 2 Keldeo + 642 => (077, 2), // 2 Thundurus + 641 => (079, 2), // 2 Tornadus + 645 => (081, 2), // 2 Landorus + _ => Zukan5BW.GetFormIndexBW(species), // B2/W2 is just appended to BW forms + }; +} + /// /// Pokédex structure used for Generation 5 games. /// -public sealed class Zukan5 : Zukan +public abstract class Zukan5(Memory raw) { - protected override int OFS_SEEN => OFS_CAUGHT + BitSeenSize; - protected override int OFS_CAUGHT => 0x8; - protected override int BitSeenSize => 0x54; - protected override int DexLangFlagByteCount => 7; - protected override int DexLangIDCount => 7; + public Span Data => raw.Span; + private const int BitSeenSize = 0x54; + private const int DexLangIDCount = 7; - public Zukan5(SAV5B2W2 sav, Memory dex, int langflag) : base(sav, dex, langflag) + public uint Magic { get => ReadUInt32LittleEndian(Data); set => WriteUInt32LittleEndian(Data, value); } + public uint Packed { get => ReadUInt32LittleEndian(Data[4..]); set => WriteUInt32LittleEndian(Data[4..], value); } + + public bool IsNationalDexUnlocked { get => (Packed & 1) == 1; set => Packed = (Packed & ~1u) | (value ? 1u : 0u); } // bit 0 + public uint Flags { get => (Packed >> 1) & 0x3FF; set => Packed = (Packed & ~0x7FEu) | ((value & 0x3FF) << 1); } // bit 1-10 + public bool IsNationalDexMode { get => (Packed & 0x800u) != 0; set => Packed = (Packed & ~0x800u) | (value ? 0x800u : 0u); } // bit 11 + public ushort InitialSpecies { get => (ushort)((Packed >> 12) & 0x3FF); set => Packed = (Packed & ~0x3FF000u) | ((uint)value << 12); } // bit 12-21 + // remaining 10 bits are unused + + private const int OFS_CAUGHT = 0x8; + private const int OFS_SEEN = OFS_CAUGHT + BitSeenSize; // 0x5C + private const int OFS_DISP = OFS_SEEN + (BitSeenSize * 4); // 0x1AC + private const int FormDex = OFS_DISP + (BitSeenSize * 4); // 0x2FC + protected abstract int FormLen { get; } // byte count + + private int OFS_LANG => FormDex + (FormLen * 4); // 0x2FC + (0xB * 4) = 0x328 for B2/W2, 0x2FC + (0x9 * 4) = 0x320 for BW + private int OFS_SPINDA => OFS_LANG + 431; // ((DexLangIDCount * Legal.MaxSpeciesID_4) / 8), rounded up to 432 bytes + + public uint Spinda { - DexFormIndexFetcher = DexFormUtil.GetDexFormIndexB2W2; + get => ReadUInt32LittleEndian(Data[OFS_SPINDA..]); + set => WriteUInt32LittleEndian(Data[OFS_SPINDA..], value); } - public Zukan5(SAV5BW sav, Memory dex, int langflag) : base(sav, dex, langflag) + private bool GetFlag(int ofs, int bitIndex) => FlagUtil.GetFlag(Data, ofs + (bitIndex >> 3), bitIndex); + private void SetFlag(int ofs, int bitIndex, bool value = true) => FlagUtil.SetFlag(Data, ofs + (bitIndex >> 3), bitIndex, value); + private static int GetRegion(byte gender, bool isShiny) => (isShiny ? 2 : 0) | (gender & 1); + public abstract (byte Index, byte Count) GetFormIndex(ushort species); + + public bool GetSeen(ushort species, byte gender, bool isShiny) { - DexFormIndexFetcher = DexFormUtil.GetDexFormIndexBW; + var region = GetRegion(gender, isShiny); + return GetSeen(species, region); } - public readonly Func DexFormIndexFetcher; - - protected override int GetDexLangFlag(int lang) + public bool GetSeen(ushort species, int region) { - lang--; - if (lang > 5) - lang--; // 0-6 language values - if ((uint)lang > 5) - return -1; - return lang; + if (species is 0 or > Legal.MaxSpeciesID_5) + return false; + int bit = species - 1; + return GetFlag(OFS_SEEN + (region * BitSeenSize), bit); } - protected override bool GetSaneFormsToIterate(ushort species, out int formStart, out int formEnd, int formIn) + public void SetSeen(ushort species, byte gender, bool isShiny, bool value = true) { - formStart = 0; - formEnd = 0; + var region = GetRegion(gender, isShiny); + SetSeen(species, region, value); + } + + public void SetSeen(ushort species, int region, bool value = true) + { + if (species is 0 or > Legal.MaxSpeciesID_5) + return; + int bit = species - 1; + SetFlag(OFS_SEEN + (region * BitSeenSize), bit, value); + } + + public bool GetSeen(ushort species) + { + if (species is 0 or > Legal.MaxSpeciesID_5) + return false; + int bit = species - 1; + for (int i = 0; i < 4; i++) + { + if (GetFlag(OFS_SEEN + (i * BitSeenSize), bit)) + return true; // already seen in any region + } return false; } - protected override void SetSpindaDexData(PKM pk, bool alreadySeen) + public void ClearSeen(ushort species) { - } - - protected override void SetAllDexFlagsLanguage(int bit, int lang, bool value = true) - { - lang = GetDexLangFlag(lang); - if (lang < 0) + if (species is 0 or > Legal.MaxSpeciesID_5) return; - - // Set the Language - int lbit = (bit * DexLangIDCount) + lang; - if (bit < 493) // shifted by 1, Gen5 species do not have international language bits - SetFlag(PokeDexLanguageFlags, lbit, value); + int bit = species - 1; + for (int i = 0; i < 4; i++) + SetFlag(OFS_SEEN + (i * BitSeenSize), bit, false); } - protected override void SetAllDexSeenFlags(int baseBit, byte form, byte gender, bool isShiny, bool value = true) + public bool GetCaught(ushort species) { - var shiny = isShiny ? 1 : 0; - SetDexFlags(baseBit, baseBit, gender, shiny); - SetFormFlags((ushort)(baseBit + 1), form, shiny, value); + if (species is 0 or > Legal.MaxSpeciesID_5) + return false; + int bit = species - 1; + return GetFlag(OFS_CAUGHT, bit); } - public override void SetDex(PKM pk) + public void SetCaught(ushort species, bool value = true) + { + if (species is 0 or > Legal.MaxSpeciesID_5) + return; + int bit = species - 1; + SetFlag(OFS_CAUGHT, bit, value); + } + + public bool GetDisplayed(ushort species, byte gender, bool isShiny) + { + var region = GetRegion(gender, isShiny); + return GetDisplayed(species, region); + } + + public bool GetDisplayed(ushort species, int region) + { + if (species is 0 or > Legal.MaxSpeciesID_5) + return false; + int bit = species - 1; + return GetFlag(OFS_DISP + (region * BitSeenSize), bit); + } + + public bool GetDisplayedAny(ushort species) + { + if (species is 0 or > Legal.MaxSpeciesID_5) + return false; + // Check Displayed Status for base form + int bit = species - 1; + for (int i = 0; i < 4; i++) + { + if (GetFlag(OFS_DISP + (i * BitSeenSize), bit)) + return true; + } + return false; + } + + public void SetDisplayed(ushort species, byte gender, bool isShiny, bool value = true) + { + var region = GetRegion(gender, isShiny); + SetDisplayed(species, region, value); + } + + public void SetDisplayed(ushort species, int region, bool value = true) + { + if (species is 0 or > Legal.MaxSpeciesID_5) + return; + int bit = species - 1; + SetFlag(OFS_DISP + (region * BitSeenSize), bit, value); + } + + public void ClearDisplayed(ushort species) + { + if (species is 0 or > Legal.MaxSpeciesID_5) + return; + int bit = species - 1; + for (int i = 0; i < 4; i++) + SetFlag(OFS_DISP + (i * BitSeenSize), bit, false); + } + + public bool GetLanguageFlag(ushort species, LanguageID language) + { + int langIndex = GetLanguageIndex(language); + if (langIndex < 0) + return false; // invalid language index + return GetLanguageFlag(species, langIndex); + } + + public bool GetLanguageFlag(ushort species, int langIndex) + { + if (species is 0 or > Legal.MaxSpeciesID_4) // no Gen5 + return false; + int bit = species - 1; + int lbit = (bit * DexLangIDCount) + langIndex; + return GetFlag(OFS_LANG, lbit); + } + + public void SetLanguageFlag(ushort species, LanguageID langIndex, bool isLanguageSet = true) + { + int index = GetLanguageIndex(langIndex); + if (index < 0) + return; // invalid language index + SetLanguageFlag(species, index, isLanguageSet); + } + + public void SetLanguageFlag(ushort species, int index, bool isLanguageSet) + { + if (species is 0 or > Legal.MaxSpeciesID_4) // no Gen5 + return; + int bit = species - 1; + int lbit = (bit * DexLangIDCount) + index; + SetFlag(OFS_LANG, lbit, isLanguageSet); + } + + public void SetAllLanguage(ushort species, bool isLanguageSet = true) + { + if (species is 0 or > Legal.MaxSpeciesID_4) // no Gen5 + return; + int bit = species - 1; + for (int i = 0; i < DexLangIDCount; i++) + { + int lbit = (bit * DexLangIDCount) + i; + SetFlag(OFS_LANG, lbit, isLanguageSet); + } + } + + public bool GetFormSeen(int formIndex, bool isShiny) + { + int region = isShiny ? 1 : 0; // 0 = non-shiny, 1 = shiny + return GetFormFlag(formIndex, region); + } + + public bool GetFormFlag(int formIndex, int region) + { + if (formIndex < 0 || formIndex >= FormLen * 8) + return false; // invalid form index + return GetFlag(FormDex + (region * FormLen), formIndex); + } + + public void SetFormSeen(int formIndex, bool isShiny, bool value = true) + { + int region = isShiny ? 1 : 0; // 0 = non-shiny, 1 = shiny + SetFormFlag(formIndex, region, value); + } + + public void SetFormFlag(int formIndex, int region, bool value) + { + if (formIndex < 0 || formIndex >= FormLen * 8) + return; + SetFlag(FormDex + (region * FormLen), formIndex, value); + } + + public bool GetFormDisplayed(int formIndex0, int formCount) + { + if (formIndex0 < 0 || formCount <= 1 || formIndex0 + formCount >= FormLen * 8) + return false; // invalid form index or count + for (int i = 0; i < formCount; i++) + { + int formIndex = formIndex0 + i; + if (GetFlag(FormDex + (2 * FormLen), formIndex)) // Nonshiny + return true; // already set + if (GetFlag(FormDex + (2 * FormLen), formIndex)) // Shiny + return true; // already set + } + return false; + } + + public void SetFormDisplayed(int formIndex, bool isShiny, bool value = true) + { + if (formIndex < 0 || formIndex >= FormLen * 8) + return; // invalid form index + int region = isShiny ? 1 : 0; // 0 = non-shiny, 1 = shiny + SetFlag(FormDex + (2 * FormLen) + (region * FormLen), formIndex, value); + } + + public void SetDex(PKM pk) { if (pk.Species is 0 or > Legal.MaxSpeciesID_5) return; if (pk.IsEgg) // do not add return; - int bit = pk.Species - 1; - SetCaughtFlag(bit); - - // Set the [Species/Gender/Shiny] Seen Flag - SetAllDexSeenFlags(bit, pk.Form, pk.Gender, pk.IsShiny); - SetAllDexFlagsLanguage(bit, pk.Language); - SetFormFlags(pk); - } - - private void SetCaughtFlag(int bit) => SetFlag(OFS_CAUGHT, bit); - - protected override void SetDisplayedFlag(int baseBit, int formBit, bool value, int shift) - { - if (!value) - { - SetDisplayed(baseBit, shift, false); - return; - } - - bool displayed = GetIsSpeciesAnyDisplayed(baseBit); - if (displayed) - return; // no need to set another bit - - SetDisplayed(baseBit, shift, true); - } - - private bool GetIsSpeciesAnyDisplayed(int baseBit) - { - // Check Displayed Status for base form - for (int i = 0; i < 4; i++) - { - if (GetDisplayed(baseBit, i)) - return true; - } - return false; - } - - private int FormLen => SAV is SAV5B2W2 ? 0xB : 0x9; - private int FormDex => 0x8 + (BitSeenSize * 9); - - private void SetFormFlags(PKM pk) - { var species = pk.Species; + if (species == (int)Species.Spinda && !GetSeen(species)) + Spinda = pk.EncryptionConstant; + + var gender = pk.Gender; + var isShiny = pk.IsShiny; + SetSeen(species, gender, isShiny); + SetCaught(species); + if (!GetDisplayedAny(species)) + SetDisplayed(species, gender, isShiny); + + if (species <= Legal.MaxSpeciesID_4) + SetLanguageFlag(species, (LanguageID)pk.Language); + + var (formIndex, count) = GetFormIndex(species); + if (count == 0) + return; // no forms + + // Set the Form Seen Flag + SetFormSeen(formIndex, isShiny); + if (GetFormDisplayed(formIndex, count)) + return; // already displayed var form = pk.Form; - var shiny = pk.IsShiny ? 1 : 0; - SetFormFlags(species, form, shiny); + if (form >= count) + return; // invalid form index + // Set the Form Displayed Flag + var index = formIndex + form; + SetFormDisplayed(index, isShiny); } - private void SetFormFlags(ushort species, byte form, int shiny, bool value = true) + /// + /// Gets the bit index for the language. + /// + /// Entry language ID. + private static int GetLanguageIndex(LanguageID language) { - var fc = SAV.Personal[species].FormCount; - int f = DexFormIndexFetcher(species, fc); - if (f < 0) + var index = (int)language - 1; // LanguageID starts at 1 + if (index > 5) + index--; // 0-6 language values + if ((uint)index > 5) + return -1; // Invalid language index + return index; + } + + public void GiveAll(ushort species, bool state, bool shinyToo, LanguageID language, bool allLanguages) + { + if (!state) + { + ClearSeen(species); return; - - var bit = f + form; - - // Set Form Seen Flag - SetFormFlag(bit, shiny, value); - - // Set Displayed Flag if necessary, check all flags - if (!value || !GetIsFormDisplayed(f, fc)) - SetFormFlag(bit, 2 + shiny, value); - } - - public bool GetFormFlag(int formIndex, int flagRegion) => GetFlag(FormDex + (FormLen * flagRegion), formIndex); - public void SetFormFlag(int formIndex, int flagRegion, bool value = true) => SetFlag(FormDex + (FormLen * flagRegion), formIndex, value); - - private bool GetIsFormDisplayed(int f, byte formCount) - { - for (byte i = 0; i < formCount; i++) - { - var index = f + i; - if (GetFormFlag(index, 2)) // Nonshiny - return true; // already set - if (GetFormFlag(index, 3)) // Shiny - return true; // already set } - return false; + + var pi = PersonalTable.BW[species]; // only need for Gender info + CompleteSeen(species, shinyToo, pi); + CompleteObtained(species, language, allLanguages); } - public bool[] GetLanguageBitflags(ushort species) + public void CompleteObtained(ushort species, LanguageID language, bool allLanguages) { - var result = new bool[DexLangIDCount]; - int bit = species - 1; - for (int i = 0; i < DexLangIDCount; i++) + SetCaught(species); + if (allLanguages) + SetAllLanguage(species); + else + SetLanguageFlag(species, language); + } + + public void CompleteSeen(ushort species, bool shinyToo, T pi) where T : IGenderDetail + { + if (!pi.OnlyFemale) { - int lbit = (bit * DexLangIDCount) + i; - result[i] = GetFlag(PokeDexLanguageFlags, lbit); + SetSeen(species, 0); // non-shiny + if (shinyToo) + SetSeen(species, 2); // shiny } - return result; + if (pi is { OnlyMale: false, Genderless: false }) + { + SetSeen(species, 1); // non-shiny + if (shinyToo) + SetSeen(species, 3); // shiny + } + if (!GetDisplayedAny(species)) + SetDisplayed(species, pi.OnlyFemale ? 1 : 0); // 0 = non-shiny, 1 = shiny + + CompleteForms(species, shinyToo); } - public void SetLanguageBitflags(ushort species, ReadOnlySpan value) + public void CompleteForms(ushort species, bool shinyToo, bool firstFormOnly = false) { - int bit = species - 1; - for (int i = 0; i < DexLangIDCount; i++) + var (index, count) = GetFormIndex(species); + if (count == 0) + return; // no forms + if (firstFormOnly) + count = 1; + for (int i = 0; i < count; i++) { - int lbit = (bit * DexLangIDCount) + i; - SetFlag(PokeDexLanguageFlags, lbit, value[i]); + int formIndex = index + i; + SetFormSeen(formIndex, false); // non-shiny + if (shinyToo) + SetFormSeen(formIndex, true); // shiny + } + if (!GetFormDisplayed(index, count)) + SetFormDisplayed(index, false); // non-shiny + } + + public void SeenNone() + { + for (ushort species = 1; species <= Legal.MaxSpeciesID_5; species++) + ClearSeen(species); + } + + public void SeenAll(bool shinyToo) + { + for (ushort species = 1; species <= Legal.MaxSpeciesID_5; species++) + { + var pi = PersonalTable.BW[species]; // only need for Gender info + CompleteSeen(species, shinyToo, pi); } } - public void ToggleLanguageFlagsAll(bool value) + public void CaughtAll(LanguageID language, bool allLanguages) { - var arr = GetBlankLanguageBits(value); - for (ushort i = 1; i <= SAV.MaxSpeciesID; i++) - SetLanguageBitflags(i, arr); + for (ushort species = 1; species <= Legal.MaxSpeciesID_5; species++) + CompleteObtained(species, language, allLanguages); } - public void ToggleLanguageFlagsSingle(ushort species, bool value) + public void CaughtNone() { - var arr = GetBlankLanguageBits(value); - SetLanguageBitflags(species, arr); + for (ushort species = 1; species <= Legal.MaxSpeciesID_5; species++) + { + SetCaught(species, false); + SetAllLanguage(species, false); + } } - private bool[] GetBlankLanguageBits(bool value) + public void ClearFormSeen() => Data.Slice(FormDex, FormLen * 4).Clear(); + + public void SetFormsSeen1(bool shinyToo) => SetFormsSeen(shinyToo, true); + + public void SetFormsSeen(bool shinyToo, bool firstFormOnly = false) { - var result = new bool[DexLangIDCount]; - for (int i = 0; i < DexLangIDCount; i++) - result[i] = value; - return result; + for (ushort species = 1; species <= Legal.MaxSpeciesID_5; species++) + CompleteForms(species, shinyToo, firstFormOnly); } } diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.Designer.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.Designer.cs index 8cc45f92b..ecff49e6c 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.Designer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.Designer.cs @@ -1,4 +1,4 @@ -namespace PKHeX.WinForms +namespace PKHeX.WinForms { partial class SAV_Pokedex5 { @@ -71,6 +71,10 @@ private void InitializeComponent() mnuFormNone = new System.Windows.Forms.ToolStripMenuItem(); mnuForm1 = new System.Windows.Forms.ToolStripMenuItem(); mnuFormAll = new System.Windows.Forms.ToolStripMenuItem(); + CHK_NationalDexUnlocked = new System.Windows.Forms.CheckBox(); + TB_PID = new System.Windows.Forms.TextBox(); + L_Spinda = new System.Windows.Forms.Label(); + CHK_NationalDexActive = new System.Windows.Forms.CheckBox(); GB_Language.SuspendLayout(); GB_Encountered.SuspendLayout(); GB_Owned.SuspendLayout(); @@ -95,11 +99,10 @@ private void InitializeComponent() // LB_Species.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left; LB_Species.FormattingEnabled = true; - LB_Species.ItemHeight = 15; LB_Species.Location = new System.Drawing.Point(14, 46); LB_Species.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); LB_Species.Name = "LB_Species"; - LB_Species.Size = new System.Drawing.Size(151, 229); + LB_Species.Size = new System.Drawing.Size(151, 225); LB_Species.TabIndex = 2; LB_Species.SelectedIndexChanged += ChangeLBSpecies; // @@ -109,7 +112,7 @@ private void InitializeComponent() CHK_P1.Location = new System.Drawing.Point(7, 16); CHK_P1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P1.Name = "CHK_P1"; - CHK_P1.Size = new System.Drawing.Size(64, 19); + CHK_P1.Size = new System.Drawing.Size(68, 21); CHK_P1.TabIndex = 3; CHK_P1.Text = "Owned"; CHK_P1.UseVisualStyleBackColor = true; @@ -120,7 +123,7 @@ private void InitializeComponent() CHK_P2.Location = new System.Drawing.Point(7, 17); CHK_P2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P2.Name = "CHK_P2"; - CHK_P2.Size = new System.Drawing.Size(52, 19); + CHK_P2.Size = new System.Drawing.Size(56, 21); CHK_P2.TabIndex = 4; CHK_P2.Text = "Male"; CHK_P2.UseVisualStyleBackColor = true; @@ -132,7 +135,7 @@ private void InitializeComponent() CHK_P3.Location = new System.Drawing.Point(7, 33); CHK_P3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P3.Name = "CHK_P3"; - CHK_P3.Size = new System.Drawing.Size(64, 19); + CHK_P3.Size = new System.Drawing.Size(68, 21); CHK_P3.TabIndex = 5; CHK_P3.Text = "Female"; CHK_P3.UseVisualStyleBackColor = true; @@ -144,7 +147,7 @@ private void InitializeComponent() CHK_P4.Location = new System.Drawing.Point(7, 50); CHK_P4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P4.Name = "CHK_P4"; - CHK_P4.Size = new System.Drawing.Size(84, 19); + CHK_P4.Size = new System.Drawing.Size(90, 21); CHK_P4.TabIndex = 6; CHK_P4.Text = "Shiny Male"; CHK_P4.UseVisualStyleBackColor = true; @@ -156,7 +159,7 @@ private void InitializeComponent() CHK_P5.Location = new System.Drawing.Point(7, 66); CHK_P5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P5.Name = "CHK_P5"; - CHK_P5.Size = new System.Drawing.Size(96, 19); + CHK_P5.Size = new System.Drawing.Size(102, 21); CHK_P5.TabIndex = 7; CHK_P5.Text = "Shiny Female"; CHK_P5.UseVisualStyleBackColor = true; @@ -168,7 +171,7 @@ private void InitializeComponent() CHK_P6.Location = new System.Drawing.Point(6, 16); CHK_P6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P6.Name = "CHK_P6"; - CHK_P6.Size = new System.Drawing.Size(52, 19); + CHK_P6.Size = new System.Drawing.Size(56, 21); CHK_P6.TabIndex = 8; CHK_P6.Text = "Male"; CHK_P6.UseVisualStyleBackColor = true; @@ -180,7 +183,7 @@ private void InitializeComponent() CHK_P7.Location = new System.Drawing.Point(6, 32); CHK_P7.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P7.Name = "CHK_P7"; - CHK_P7.Size = new System.Drawing.Size(64, 19); + CHK_P7.Size = new System.Drawing.Size(68, 21); CHK_P7.TabIndex = 9; CHK_P7.Text = "Female"; CHK_P7.UseVisualStyleBackColor = true; @@ -192,7 +195,7 @@ private void InitializeComponent() CHK_P8.Location = new System.Drawing.Point(6, 48); CHK_P8.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P8.Name = "CHK_P8"; - CHK_P8.Size = new System.Drawing.Size(84, 19); + CHK_P8.Size = new System.Drawing.Size(90, 21); CHK_P8.TabIndex = 10; CHK_P8.Text = "Shiny Male"; CHK_P8.UseVisualStyleBackColor = true; @@ -204,7 +207,7 @@ private void InitializeComponent() CHK_P9.Location = new System.Drawing.Point(6, 65); CHK_P9.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_P9.Name = "CHK_P9"; - CHK_P9.Size = new System.Drawing.Size(96, 19); + CHK_P9.Size = new System.Drawing.Size(102, 21); CHK_P9.TabIndex = 11; CHK_P9.Text = "Shiny Female"; CHK_P9.UseVisualStyleBackColor = true; @@ -216,7 +219,7 @@ private void InitializeComponent() CHK_L7.Location = new System.Drawing.Point(21, 144); CHK_L7.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_L7.Name = "CHK_L7"; - CHK_L7.Size = new System.Drawing.Size(63, 19); + CHK_L7.Size = new System.Drawing.Size(69, 21); CHK_L7.TabIndex = 19; CHK_L7.Text = "Korean"; CHK_L7.UseVisualStyleBackColor = true; @@ -227,7 +230,7 @@ private void InitializeComponent() CHK_L6.Location = new System.Drawing.Point(21, 125); CHK_L6.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_L6.Name = "CHK_L6"; - CHK_L6.Size = new System.Drawing.Size(67, 19); + CHK_L6.Size = new System.Drawing.Size(72, 21); CHK_L6.TabIndex = 18; CHK_L6.Text = "Spanish"; CHK_L6.UseVisualStyleBackColor = true; @@ -238,7 +241,7 @@ private void InitializeComponent() CHK_L5.Location = new System.Drawing.Point(21, 105); CHK_L5.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_L5.Name = "CHK_L5"; - CHK_L5.Size = new System.Drawing.Size(68, 19); + CHK_L5.Size = new System.Drawing.Size(73, 21); CHK_L5.TabIndex = 17; CHK_L5.Text = "German"; CHK_L5.UseVisualStyleBackColor = true; @@ -249,7 +252,7 @@ private void InitializeComponent() CHK_L4.Location = new System.Drawing.Point(21, 85); CHK_L4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_L4.Name = "CHK_L4"; - CHK_L4.Size = new System.Drawing.Size(58, 19); + CHK_L4.Size = new System.Drawing.Size(61, 21); CHK_L4.TabIndex = 16; CHK_L4.Text = "Italian"; CHK_L4.UseVisualStyleBackColor = true; @@ -260,7 +263,7 @@ private void InitializeComponent() CHK_L3.Location = new System.Drawing.Point(21, 66); CHK_L3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_L3.Name = "CHK_L3"; - CHK_L3.Size = new System.Drawing.Size(62, 19); + CHK_L3.Size = new System.Drawing.Size(65, 21); CHK_L3.TabIndex = 15; CHK_L3.Text = "French"; CHK_L3.UseVisualStyleBackColor = true; @@ -271,7 +274,7 @@ private void InitializeComponent() CHK_L2.Location = new System.Drawing.Point(21, 46); CHK_L2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_L2.Name = "CHK_L2"; - CHK_L2.Size = new System.Drawing.Size(64, 19); + CHK_L2.Size = new System.Drawing.Size(68, 21); CHK_L2.TabIndex = 14; CHK_L2.Text = "English"; CHK_L2.UseVisualStyleBackColor = true; @@ -282,7 +285,7 @@ private void InitializeComponent() CHK_L1.Location = new System.Drawing.Point(21, 27); CHK_L1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CHK_L1.Name = "CHK_L1"; - CHK_L1.Size = new System.Drawing.Size(73, 19); + CHK_L1.Size = new System.Drawing.Size(81, 21); CHK_L1.TabIndex = 13; CHK_L1.Text = "Japanese"; CHK_L1.UseVisualStyleBackColor = true; @@ -293,7 +296,7 @@ private void InitializeComponent() L_goto.Location = new System.Drawing.Point(14, 18); L_goto.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); L_goto.Name = "L_goto"; - L_goto.Size = new System.Drawing.Size(35, 15); + L_goto.Size = new System.Drawing.Size(39, 17); L_goto.TabIndex = 20; L_goto.Text = "goto:"; // @@ -307,7 +310,7 @@ private void InitializeComponent() CB_Species.Location = new System.Drawing.Point(58, 15); CB_Species.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CB_Species.Name = "CB_Species"; - CB_Species.Size = new System.Drawing.Size(107, 23); + CB_Species.Size = new System.Drawing.Size(107, 25); CB_Species.TabIndex = 21; CB_Species.SelectedIndexChanged += ChangeCBSpecies; CB_Species.SelectedValueChanged += ChangeCBSpecies; @@ -410,40 +413,40 @@ private void InitializeComponent() // modifyMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuSeenNone, mnuSeenAll, mnuCaughtNone, mnuCaughtAll, mnuComplete }); modifyMenu.Name = "modifyMenu"; - modifyMenu.Size = new System.Drawing.Size(150, 114); + modifyMenu.Size = new System.Drawing.Size(159, 114); // // mnuSeenNone // mnuSeenNone.Name = "mnuSeenNone"; - mnuSeenNone.Size = new System.Drawing.Size(149, 22); + mnuSeenNone.Size = new System.Drawing.Size(158, 22); mnuSeenNone.Text = "Seen none"; mnuSeenNone.Click += ModifyAll; // // mnuSeenAll // mnuSeenAll.Name = "mnuSeenAll"; - mnuSeenAll.Size = new System.Drawing.Size(149, 22); + mnuSeenAll.Size = new System.Drawing.Size(158, 22); mnuSeenAll.Text = "Seen all"; mnuSeenAll.Click += ModifyAll; // // mnuCaughtNone // mnuCaughtNone.Name = "mnuCaughtNone"; - mnuCaughtNone.Size = new System.Drawing.Size(149, 22); + mnuCaughtNone.Size = new System.Drawing.Size(158, 22); mnuCaughtNone.Text = "Caught none"; mnuCaughtNone.Click += ModifyAll; // // mnuCaughtAll // mnuCaughtAll.Name = "mnuCaughtAll"; - mnuCaughtAll.Size = new System.Drawing.Size(149, 22); + mnuCaughtAll.Size = new System.Drawing.Size(158, 22); mnuCaughtAll.Text = "Caught all"; mnuCaughtAll.Click += ModifyAll; // // mnuComplete // mnuComplete.Name = "mnuComplete"; - mnuComplete.Size = new System.Drawing.Size(149, 22); + mnuComplete.Size = new System.Drawing.Size(158, 22); mnuComplete.Text = "Complete Dex"; mnuComplete.Click += ModifyAll; // @@ -475,7 +478,7 @@ private void InitializeComponent() CLB_FormDisplayed.Location = new System.Drawing.Point(593, 70); CLB_FormDisplayed.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CLB_FormDisplayed.Name = "CLB_FormDisplayed"; - CLB_FormDisplayed.Size = new System.Drawing.Size(138, 148); + CLB_FormDisplayed.Size = new System.Drawing.Size(138, 144); CLB_FormDisplayed.TabIndex = 41; CLB_FormDisplayed.ItemCheck += UpdateDisplayedForm; // @@ -496,40 +499,88 @@ private void InitializeComponent() CLB_FormsSeen.Location = new System.Drawing.Point(447, 70); CLB_FormsSeen.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CLB_FormsSeen.Name = "CLB_FormsSeen"; - CLB_FormsSeen.Size = new System.Drawing.Size(138, 148); + CLB_FormsSeen.Size = new System.Drawing.Size(138, 144); CLB_FormsSeen.TabIndex = 39; // // modifyMenuForms // modifyMenuForms.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuFormNone, mnuForm1, mnuFormAll }); modifyMenuForms.Name = "modifyMenu"; - modifyMenuForms.Size = new System.Drawing.Size(130, 70); + modifyMenuForms.Size = new System.Drawing.Size(138, 70); // // mnuFormNone // mnuFormNone.Name = "mnuFormNone"; - mnuFormNone.Size = new System.Drawing.Size(129, 22); + mnuFormNone.Size = new System.Drawing.Size(137, 22); mnuFormNone.Text = "Seen none"; mnuFormNone.Click += ModifyAllForms; // // mnuForm1 // mnuForm1.Name = "mnuForm1"; - mnuForm1.Size = new System.Drawing.Size(129, 22); + mnuForm1.Size = new System.Drawing.Size(137, 22); mnuForm1.Text = "Seen one"; mnuForm1.Click += ModifyAllForms; // // mnuFormAll // mnuFormAll.Name = "mnuFormAll"; - mnuFormAll.Size = new System.Drawing.Size(129, 22); + mnuFormAll.Size = new System.Drawing.Size(137, 22); mnuFormAll.Text = "Seen all"; mnuFormAll.Click += ModifyAllForms; // + // CHK_NationalDexUnlocked + // + CHK_NationalDexUnlocked.AutoSize = true; + CHK_NationalDexUnlocked.Location = new System.Drawing.Point(335, 229); + CHK_NationalDexUnlocked.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + CHK_NationalDexUnlocked.Name = "CHK_NationalDexUnlocked"; + CHK_NationalDexUnlocked.Size = new System.Drawing.Size(173, 21); + CHK_NationalDexUnlocked.TabIndex = 20; + CHK_NationalDexUnlocked.Text = "National Mode Unlocked"; + CHK_NationalDexUnlocked.UseVisualStyleBackColor = true; + // + // TB_PID + // + TB_PID.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper; + TB_PID.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + TB_PID.Location = new System.Drawing.Point(664, 224); + TB_PID.MaxLength = 8; + TB_PID.Name = "TB_PID"; + TB_PID.Size = new System.Drawing.Size(68, 20); + TB_PID.TabIndex = 44; + TB_PID.Text = "00000000"; + TB_PID.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // L_Spinda + // + L_Spinda.Location = new System.Drawing.Point(589, 220); + L_Spinda.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + L_Spinda.Name = "L_Spinda"; + L_Spinda.Size = new System.Drawing.Size(79, 24); + L_Spinda.TabIndex = 45; + L_Spinda.Text = "Spinda:"; + L_Spinda.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // CHK_NationalDexActive + // + CHK_NationalDexActive.AutoSize = true; + CHK_NationalDexActive.Location = new System.Drawing.Point(335, 248); + CHK_NationalDexActive.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + CHK_NationalDexActive.Name = "CHK_NationalDexActive"; + CHK_NationalDexActive.Size = new System.Drawing.Size(153, 21); + CHK_NationalDexActive.TabIndex = 46; + CHK_NationalDexActive.Text = "National Mode Active"; + CHK_NationalDexActive.UseVisualStyleBackColor = true; + // // SAV_Pokedex5 // AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; ClientSize = new System.Drawing.Size(740, 285); + Controls.Add(CHK_NationalDexActive); + Controls.Add(L_Spinda); + Controls.Add(TB_PID); + Controls.Add(CHK_NationalDexUnlocked); Controls.Add(B_ModifyForms); Controls.Add(L_FormDisplayed); Controls.Add(CLB_FormDisplayed); @@ -612,5 +663,9 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem mnuFormNone; private System.Windows.Forms.ToolStripMenuItem mnuForm1; private System.Windows.Forms.ToolStripMenuItem mnuFormAll; + private System.Windows.Forms.CheckBox CHK_NationalDexUnlocked; + private System.Windows.Forms.TextBox TB_PID; + private System.Windows.Forms.Label L_Spinda; + private System.Windows.Forms.CheckBox CHK_NationalDexActive; } } diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.cs index bfdf75cc2..00a706a9c 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_Pokedex5.cs @@ -10,12 +10,14 @@ public partial class SAV_Pokedex5 : Form { private readonly SaveFile Origin; private readonly SAV5 SAV; + private readonly Zukan5 Dex; public SAV_Pokedex5(SAV5 sav) { InitializeComponent(); WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage); SAV = (SAV5)(Origin = sav).Clone(); + Dex = SAV.Zukan; CP = [CHK_P1, CHK_P2, CHK_P3, CHK_P4, CHK_P5, CHK_P6, CHK_P7, CHK_P8, CHK_P9]; CL = [CHK_L1, CHK_L2, CHK_L3, CHK_L4, CHK_L5, CHK_L6, CHK_L7]; @@ -31,8 +33,16 @@ public SAV_Pokedex5(SAV5 sav) for (int i = 1; i < SAV.MaxSpeciesID + 1; i++) LB_Species.Items.Add($"{i:000} - {GameInfo.Strings.Species[i]}"); + CHK_NationalDexUnlocked.Checked = Dex.IsNationalDexUnlocked; + CHK_NationalDexActive.Checked = Dex.IsNationalDexMode; + CHK_NationalDexUnlocked.CheckedChanged += (_, _) => CHK_NationalDexActive.Checked = CHK_NationalDexUnlocked.Checked; + TB_PID.Text = Dex.Spinda.ToString("X8"); + editing = false; - LB_Species.SelectedIndex = 0; + if (Dex.InitialSpecies is not (0 or > 693)) + CB_Species.SelectedValue = (int)Dex.InitialSpecies; + else + LB_Species.SelectedIndex = 0; CB_Species.KeyDown += WinFormsUtil.RemoveDropCB; } @@ -103,19 +113,18 @@ private void ChangeEncountered(object sender, EventArgs e) } } - private void GetEntry() + private void GetEntry(bool skipFormRepop = false) { // Load Bools for the data int pk = species; // Load Partitions - var Dex = SAV.Zukan; CP[0].Checked = Dex.GetCaught(species); for (int i = 0; i < 4; i++) CP[i + 1].Checked = Dex.GetSeen(species, i); for (int i = 0; i < 4; i++) - CP[i + 5].Checked = Dex.GetDisplayed(species - 1, i); + CP[i + 5].Checked = Dex.GetDisplayed(species, i); if (species > 493) { @@ -126,7 +135,7 @@ private void GetEntry() else { for (int i = 0; i < 7; i++) - CL[i].Checked = SAV.Zukan.GetLanguageFlag(species - 1, i); + CL[i].Checked = SAV.Zukan.GetLanguageFlag(species, i); GB_Language.Enabled = true; } @@ -135,6 +144,22 @@ private void GetEntry() CHK_P2.Enabled = CHK_P4.Enabled = CHK_P6.Enabled = CHK_P8.Enabled = !pi.OnlyFemale; CHK_P3.Enabled = CHK_P5.Enabled = CHK_P7.Enabled = CHK_P9.Enabled = !(pi.OnlyMale || pi.Genderless); + if (skipFormRepop) + { + // Just re-load without changing the text. + var (index, count) = Dex.GetFormIndex(species); + if (count == 0) + return; + for (int i = 0; i < count; i++) + { + CLB_FormsSeen.SetItemChecked(i, Dex.GetFormFlag(index + i, 0)); + CLB_FormsSeen.SetItemChecked(i + count, Dex.GetFormFlag(index + i, 1)); + CLB_FormDisplayed.SetItemChecked(i, Dex.GetFormFlag(index + i, 2)); + CLB_FormDisplayed.SetItemChecked(i + count, Dex.GetFormFlag(index + i, 3)); + } + return; + } + CLB_FormsSeen.Items.Clear(); CLB_FormDisplayed.Items.Clear(); @@ -162,18 +187,17 @@ private void SetEntry() if (species > 649) return; - var Dex = SAV.Zukan; Dex.SetCaught(species, CP[0].Checked); for (int i = 0; i < 4; i++) Dex.SetSeen(species, i, CP[i + 1].Checked); for (int i = 0; i < 4; i++) - Dex.SetDisplayed(species - 1, i, CP[i + 5].Checked); + Dex.SetDisplayed(species, i, CP[i + 5].Checked); if (species <= 493) { for (int i = 0; i < 7; i++) - Dex.SetLanguageFlag(species - 1, i, CL[i].Checked); + Dex.SetLanguageFlag(species, i, CL[i].Checked); } var fc = SAV.Personal[species].FormCount; @@ -202,133 +226,46 @@ private void B_Cancel_Click(object sender, EventArgs e) private void B_Save_Click(object sender, EventArgs e) { SetEntry(); + + if (species is not 0) + Dex.InitialSpecies = species; + Dex.IsNationalDexUnlocked = CHK_NationalDexUnlocked.Checked; + Dex.IsNationalDexMode = CHK_NationalDexActive.Checked; + Dex.Spinda = Util.GetHexValue(TB_PID.Text); + Origin.CopyChangesFrom(SAV); Close(); } private void B_GiveAll_Click(object sender, EventArgs e) { - if (CHK_L1.Enabled) - { - CHK_L1.Checked = - CHK_L2.Checked = - CHK_L3.Checked = - CHK_L4.Checked = - CHK_L5.Checked = - CHK_L6.Checked = - CHK_L7.Checked = ModifierKeys != Keys.Control; - } - if (CHK_P1.Enabled) - { - CHK_P1.Checked = ModifierKeys != Keys.Control; - } - int index = LB_Species.SelectedIndex + 1; - byte gt = SAV.Personal[index].Gender; - - bool canBeMale = gt != PersonalInfo.RatioMagicFemale; - bool canBeFemale = gt is not (PersonalInfo.RatioMagicMale or PersonalInfo.RatioMagicGenderless); - CHK_P2.Checked = CHK_P4.Checked = canBeMale && ModifierKeys != Keys.Control; - CHK_P3.Checked = CHK_P5.Checked = canBeFemale && ModifierKeys != Keys.Control; - - if (ModifierKeys == Keys.Control) - { - foreach (var chk in new[] { CHK_P6, CHK_P7, CHK_P8, CHK_P9 }) - chk.Checked = false; - } - else if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) - { - (gt != PersonalInfo.RatioMagicFemale ? CHK_P6 : CHK_P7).Checked = true; - } + SetEntry(); + var language = (LanguageID)SAV.Language; + Dex.GiveAll(species, ModifierKeys != Keys.Alt, ModifierKeys.HasFlag(Keys.Shift), language, ModifierKeys.HasFlag(Keys.Control)); + GetEntry(skipFormRepop: true); + System.Media.SystemSounds.Asterisk.Play(); } private void B_Modify_Click(object sender, EventArgs e) { - Button btn = (Button)sender; + var btn = (Button)sender; modifyMenu.Show(btn.PointToScreen(new Point(0, btn.Height))); } private void ModifyAll(object sender, EventArgs e) { - int lang = SAV.Language; - if (lang > 5) lang--; - lang--; - - if (sender == mnuSeenNone || sender == mnuSeenAll || sender == mnuComplete) - { - for (int i = 0; i < LB_Species.Items.Count; i++) - { - byte gt = SAV.Personal[i + 1].Gender; - LB_Species.SelectedIndex = i; - foreach (CheckBox t in new[] { CHK_P2, CHK_P3, CHK_P4, CHK_P5 }) - t.Checked = mnuSeenNone != sender && t.Enabled; - - if (mnuSeenNone != sender) - { - // if seen ensure at least one Displayed - if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) - (gt != PersonalInfo.RatioMagicFemale ? 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 < CB_Species.Items.Count; i++) - { - byte gt = SAV.Personal[i + 1].Gender; - LB_Species.SelectedIndex = i; - foreach (CheckBox t in new[] { CHK_P1 }) - t.Checked = mnuCaughtNone != sender; - for (int j = 0; j < CL.Length; j++) - { - bool yes = sender == mnuComplete || (mnuCaughtNone != sender && j == lang); - CL[j].Checked = i < 493 && yes; - } - - if (mnuCaughtNone == sender) - { - 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 != PersonalInfo.RatioMagicFemale ? CHK_P6 : CHK_P7).Checked = true; // check one - } - } - if (mnuCaughtNone != sender) - { - if (mnuComplete == sender) - { - bool canBeMale = gt != PersonalInfo.RatioMagicFemale; - bool canBeFemale = gt is not (PersonalInfo.RatioMagicMale or PersonalInfo.RatioMagicGenderless); - CHK_P2.Checked = CHK_P4.Checked = canBeMale; - CHK_P3.Checked = CHK_P5.Checked = canBeFemale; - } - else - { - // ensure at least one SEEN - if (!(CHK_P2.Checked || CHK_P3.Checked || CHK_P4.Checked || CHK_P5.Checked)) - (gt != PersonalInfo.RatioMagicFemale ? CHK_P2 : CHK_P3).Checked = true; - } - - // ensure at least one Displayed - if (!(CHK_P6.Checked || CHK_P7.Checked || CHK_P8.Checked || CHK_P9.Checked)) - (gt != PersonalInfo.RatioMagicFemale ? CHK_P6 : CHK_P7).Checked = true; - } - } - } - SetEntry(); - GetEntry(); + var language = (LanguageID)SAV.Language; + if (sender == mnuSeenNone) + Dex.SeenNone(); + if (sender == mnuSeenAll || sender == mnuComplete) + Dex.SeenAll(shinyToo: ModifierKeys.HasFlag(Keys.Shift)); + if (sender == mnuCaughtNone) + Dex.CaughtNone(); + if (sender == mnuCaughtAll || sender == mnuComplete) + Dex.CaughtAll(language, allLanguages: ModifierKeys.HasFlag(Keys.Control)); + GetEntry(skipFormRepop: true); + System.Media.SystemSounds.Asterisk.Play(); } private void UpdateDisplayedForm(object sender, ItemCheckEventArgs e) @@ -351,40 +288,20 @@ private void UpdateDisplayedForm(object sender, ItemCheckEventArgs e) private void B_ModifyForms_Click(object sender, EventArgs e) { - Button btn = (Button)sender; + var btn = (Button)sender; modifyMenuForms.Show(btn.PointToScreen(new Point(0, btn.Height))); } private void ModifyAllForms(object sender, EventArgs e) { - for (int i = 0; i < CB_Species.Items.Count; i++) - { - LB_Species.SelectedIndex = i; - if (CLB_FormsSeen.Items.Count == 0) - continue; - - if (sender == mnuForm1) - { - if (CLB_FormsSeen.CheckedItems.Count == 0) - CLB_FormsSeen.SetItemChecked(0, true); - - if (CLB_FormDisplayed.CheckedItems.Count == 0) - CLB_FormDisplayed.SetItemChecked(0, true); - } - else if (sender == mnuFormAll) - { - for (int f = 0; f < CLB_FormsSeen.Items.Count; f++) - CLB_FormsSeen.SetItemChecked(f, true); - if (CLB_FormDisplayed.CheckedItems.Count == 0) - CLB_FormDisplayed.SetItemChecked(0, true); - } - else // none - { - for (int f = 0; f < CLB_FormsSeen.Items.Count; f++) - CLB_FormsSeen.SetItemChecked(f, false); - for (int f = 0; f < CLB_FormDisplayed.Items.Count; f++) - CLB_FormDisplayed.SetItemChecked(f, false); - } - } + SetEntry(); + if (sender == mnuFormNone) + Dex.ClearFormSeen(); + else if (sender == mnuForm1) + Dex.SetFormsSeen1(shinyToo: ModifierKeys.HasFlag(Keys.Shift)); + else if (sender == mnuFormAll) + Dex.SetFormsSeen(shinyToo: ModifierKeys.HasFlag(Keys.Shift)); + GetEntry(skipFormRepop: true); + System.Media.SystemSounds.Asterisk.Play(); } } diff --git a/Tests/PKHeX.Core.Tests/Saves/PokeDex.cs b/Tests/PKHeX.Core.Tests/Saves/PokeDex.cs index df9075cab..4b44635d9 100644 --- a/Tests/PKHeX.Core.Tests/Saves/PokeDex.cs +++ b/Tests/PKHeX.Core.Tests/Saves/PokeDex.cs @@ -55,10 +55,8 @@ private static void CheckDexFlags5(SAV5B2W2 sav, ushort species, byte form, int var dex = sav.Blocks.Zukan; var data = dex.Data; - var fc = sav.Personal[species].FormCount; - var bit = sav.Zukan.DexFormIndexFetcher(species, fc); - if (bit < 0) - return; + var (bit, count) = sav.Zukan.GetFormIndex(species); + count.Should().NotBe(0, "should have forms tracked"); bit += form; var value = (byte)(1 << (bit & 7)); var offset = bit >> 3;