PKHeX/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_PokedexSV.cs
Kurt 88830e0d00
Update from .NET Framework 4.6 to .NET 7 (#3729)
Updates from net46->net7, dropping support for mono in favor of using the latest runtime (along with the performance/API improvements). Releases will be posted as 64bit only for now.

Refactors a good amount of internal API methods to be more performant and more customizable for future updates & fixes.

Adds functionality for Batch Editor commands to `>`, `<` and <=/>=

TID/SID properties renamed to TID16/SID16 for clarity; other properties exposed for Gen7 / display variants.

Main window has a new layout to account for DPI scaling (8 point grid)

Fixed: Tatsugiri and Paldean Tauros now output Showdown form names as Showdown expects
Changed: Gen9 species now interact based on the confirmed National Dex IDs (closes #3724)
Fixed: Pokedex set all no longer clears species with unavailable non-base forms (closes #3720)
Changed: Hyper Training suggestions now apply for level 50 in SV. (closes #3714)
Fixed: B2/W2 hatched egg met locations exclusive to specific versions are now explicitly checked (closes #3691)
Added: Properties for ribbon/mark count (closes #3659)
Fixed: Traded SV eggs are now checked correctly (closes #3692)
2023-01-21 20:02:33 -08:00

280 lines
9.2 KiB
C#

using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using PKHeX.Core;
namespace PKHeX.WinForms;
public partial class SAV_PokedexSV : Form
{
private readonly SAV9SV Origin;
private readonly SAV9SV SAV;
private readonly Zukan9 Dex;
private int lastIndex;
private readonly bool CanSave;
private readonly bool Loading;
public SAV_PokedexSV(SAV9SV sav)
{
InitializeComponent();
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
SAV = (SAV9SV)(Origin = sav).Clone();
Dex = SAV.Blocks.Zukan;
Loading = true;
// Clear Listbox and ComboBox
LB_Species.Items.Clear();
CB_Species.Items.Clear();
// Fill List
CB_Species.InitializeBinding();
var species = GameInfo.SpeciesDataSource.Where(z => SAV.Personal.IsSpeciesInGame((ushort)z.Value)).ToArray();
CB_Species.DataSource = new BindingSource(species, null);
var list = species
.Select(z => new DexMap(z))
.OrderBy(z => z.DexIndex).ToArray();
var lbi = LB_Species.Items;
for (var i = 0; i < list.Length; i++)
{
var n = list[i];
var display = n.DexIndex == int.MaxValue ? "***" : n.DexIndex.ToString("000");
lbi.Add($"{display} - {n.Name}");
n.ListIndex = i;
}
ListBoxToSpecies = list;
LB_Species.SelectedIndex = 0;
CB_Species.KeyDown += WinFormsUtil.RemoveDropCB;
Loading = false;
CanSave = true;
lastIndex = 0;
GetEntry(0);
}
private record DexMap
{
public ushort Species { get; }
public int DexIndex { get; }
public string Name { get; }
public int ListIndex { get; set; }
public DexMap(ComboItem c)
{
Species = (ushort)c.Value;
Name = c.Text;
DexIndex = GetDexIndex(Species);
}
private static int GetDexIndex(ushort species)
{
var entry = PersonalTable.SV.GetFormEntry(species, 0);
if (entry.DexIndex != 0)
return entry.DexIndex;
for (byte i = 1; i < entry.FormCount; i++)
{
entry = PersonalTable.SV.GetFormEntry(species, i);
if (entry.DexIndex != 0)
return entry.DexIndex;
}
return int.MaxValue;
}
}
private DexMap[] ListBoxToSpecies { get; }
private ushort GetSpecies(int listBoxIndex) => Array.Find(ListBoxToSpecies, z => z.ListIndex == listBoxIndex)?.Species ?? 0;
private int GetIndex(ushort species) => Array.Find(ListBoxToSpecies, z => z.Species == species)?.ListIndex ?? 0;
private void ChangeCBSpecies(object sender, EventArgs e)
{
if (Loading)
return;
var species = (ushort)WinFormsUtil.GetIndex(CB_Species);
var index = GetIndex(species);
if (LB_Species.SelectedIndex != index)
LB_Species.SelectedIndex = index; // trigger event
}
private void ChangeLBSpecies(object sender, EventArgs e)
{
if (Loading || LB_Species.SelectedIndex < 0)
return;
SetEntry(lastIndex);
lastIndex = LB_Species.SelectedIndex;
GetEntry(lastIndex);
}
private void GetEntry(int index)
{
if (!CanSave || Loading || index < 0)
return;
var species = GetSpecies(index);
GetEntry(species);
}
private void GetEntry(ushort species)
{
var entry = SAV.Zukan.Get(species);
var forms = GetFormList(species);
if (forms[0].Length == 0)
forms[0] = GameInfo.Strings.Types[0];
CB_State.SelectedIndex = (int)entry.GetState();
CHK_IsNew.Checked = entry.GetDisplayIsNew();
CHK_SeenMale.Checked = entry.GetIsGenderSeen(0);
CHK_SeenFemale.Checked = entry.GetIsGenderSeen(1);
CHK_SeenGenderless.Checked = entry.GetIsGenderSeen(2);
CHK_SeenShiny.Checked = entry.GetSeenIsShiny();
CLB_FormSeen.Items.Clear();
for (byte i = 0; i < forms.Length; i++)
CLB_FormSeen.Items.Add(forms[i], entry.GetIsFormSeen(i));
CB_DisplayForm.Items.Clear();
CB_DisplayForm.Items.AddRange(forms);
CB_Gender.SelectedIndex = (int)entry.GetDisplayGender();
CHK_DisplayShiny.Checked = entry.GetDisplayIsShiny();
CHK_G.Checked = entry.GetDisplayGenderIsDifferent();
CB_DisplayForm.SelectedIndex = (int)entry.GetDisplayForm();
CHK_LangJPN.Checked = entry.GetLanguageFlag((int)LanguageID.Japanese);
CHK_LangENG.Checked = entry.GetLanguageFlag((int)LanguageID.English);
CHK_LangFRE.Checked = entry.GetLanguageFlag((int)LanguageID.French);
CHK_LangITA.Checked = entry.GetLanguageFlag((int)LanguageID.Italian);
CHK_LangGER.Checked = entry.GetLanguageFlag((int)LanguageID.German);
CHK_LangSPA.Checked = entry.GetLanguageFlag((int)LanguageID.Spanish);
CHK_LangKOR.Checked = entry.GetLanguageFlag((int)LanguageID.Korean);
CHK_LangCHS.Checked = entry.GetLanguageFlag((int)LanguageID.ChineseS);
CHK_LangCHT.Checked = entry.GetLanguageFlag((int)LanguageID.ChineseT);
}
private static string[] GetFormList(in ushort species)
{
var s = GameInfo.Strings;
if (species == (int)Species.Alcremie)
return FormConverter.GetAlcremieFormList(s.forms);
return FormConverter.GetFormList(species, s.Types, s.forms, GameInfo.GenderSymbolASCII, EntityContext.Gen9).ToArray();
}
private void SetEntry(int index)
{
if (!CanSave || Loading || index < 0)
return;
var species = GetSpecies(index);
SetEntry(species);
}
private void SetEntry(ushort species)
{
var entry = SAV.Zukan.Get(species);
entry.SetState((uint)CB_State.SelectedIndex);
entry.SetDisplayIsNew(CHK_IsNew.Checked);
entry.SetIsGenderSeen(0, CHK_SeenMale.Checked);
entry.SetIsGenderSeen(1, CHK_SeenFemale.Checked);
entry.SetIsGenderSeen(2, CHK_SeenGenderless.Checked);
entry.SetSeenIsShiny(CHK_SeenShiny.Checked);
for (byte i = 0; i < CLB_FormSeen.Items.Count; i++)
entry.SetIsFormSeen(i, CLB_FormSeen.GetItemChecked(i));
entry.SetDisplayGender(CB_Gender.SelectedIndex);
entry.SetDisplayIsShiny(CHK_DisplayShiny.Checked);
entry.SetDisplayGenderIsDifferent(CHK_G.Checked);
entry.SetDisplayForm((uint)CB_DisplayForm.SelectedIndex);
entry.SetLanguageFlag((int)LanguageID.Japanese, CHK_LangJPN.Checked);
entry.SetLanguageFlag((int)LanguageID.English, CHK_LangENG.Checked);
entry.SetLanguageFlag((int)LanguageID.French, CHK_LangFRE.Checked);
entry.SetLanguageFlag((int)LanguageID.Italian, CHK_LangITA.Checked);
entry.SetLanguageFlag((int)LanguageID.German, CHK_LangGER.Checked);
entry.SetLanguageFlag((int)LanguageID.Spanish, CHK_LangSPA.Checked);
entry.SetLanguageFlag((int)LanguageID.Korean, CHK_LangKOR.Checked);
entry.SetLanguageFlag((int)LanguageID.ChineseS, CHK_LangCHS.Checked);
entry.SetLanguageFlag((int)LanguageID.ChineseT, CHK_LangCHT.Checked);
}
private void B_Cancel_Click(object sender, EventArgs e)
{
Close();
}
private void B_Save_Click(object sender, EventArgs e)
{
SetEntry(lastIndex);
Origin.CopyChangesFrom(SAV);
Close();
}
private void B_GiveAll_Click(object sender, EventArgs e)
{
SetEntry(lastIndex);
bool shiny = ModifierKeys == Keys.Shift;
var species = GetSpecies(lastIndex);
Dex.SetDexEntryAll(species, shiny);
System.Media.SystemSounds.Asterisk.Play();
GetEntry(species);
}
private void B_Modify_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
modifyMenu.Show(btn.PointToScreen(new Point(0, btn.Height)));
}
private void SeenNone(object sender, EventArgs e)
{
var species = GetSpecies(lastIndex);
SetEntry(species);
Dex.SeenNone();
System.Media.SystemSounds.Asterisk.Play();
GetEntry(species);
}
private void SeenAll(object sender, EventArgs e)
{
var species = GetSpecies(lastIndex);
SetEntry(species);
bool shiny = ModifierKeys == Keys.Shift;
Dex.SeenAll(shiny);
System.Media.SystemSounds.Asterisk.Play();
GetEntry(species);
}
private void CaughtNone(object sender, EventArgs e)
{
var species = GetSpecies(lastIndex);
SetEntry(species);
Dex.CaughtNone();
System.Media.SystemSounds.Asterisk.Play();
GetEntry(species);
}
private void CaughtAll(object sender, EventArgs e)
{
var species = GetSpecies(lastIndex);
SetEntry(species);
bool shiny = ModifierKeys == Keys.Shift;
Dex.CaughtAll(shiny);
System.Media.SystemSounds.Asterisk.Play();
GetEntry(species);
}
private void CompleteDex(object sender, EventArgs e)
{
var species = GetSpecies(lastIndex);
SetEntry(species);
bool shiny = ModifierKeys == Keys.Shift;
Dex.CompleteDex(shiny);
System.Media.SystemSounds.Asterisk.Play();
GetEntry(species);
}
}